Loading packages/SystemUI/src/com/android/systemui/screencapture/record/smallscreen/ui/compose/SmallScreenCaptureRecordContent.kt +96 −30 Original line number Diff line number Diff line Loading @@ -17,11 +17,16 @@ package com.android.systemui.screencapture.record.smallscreen.ui.compose import androidx.compose.animation.AnimatedContent import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.animateContentSize import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.togetherWith import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row Loading @@ -34,6 +39,7 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.only import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.safeContent import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.layout.windowInsetsPadding Loading @@ -41,18 +47,22 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.FloatingToolbarDefaults import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.LocalContentColor import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.android.compose.PlatformIconButton import com.android.compose.modifiers.thenIf import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.res.R import com.android.systemui.screencapture.common.ScreenCaptureUiScope import com.android.systemui.screencapture.common.ui.compose.LoadingIcon import com.android.systemui.screencapture.common.ui.compose.PrimaryButton import com.android.systemui.screencapture.common.ui.compose.ScreenCaptureContent import com.android.systemui.screencapture.common.ui.compose.loadIcon Loading Loading @@ -106,6 +116,24 @@ constructor(private val viewModelFactory: SmallScreenCaptureRecordViewModel.Fact ), iconResource = R.drawable.ic_close, ) AnimatedVisibility(visible = viewModel.shouldShowSettingsButton) { ToggleToolbarButton( checked = viewModel.shouldShowDetails, onCheckedChanged = { viewModel.shouldShowSettings(it) }, icon = { LoadingIcon( icon = loadIcon( viewModel = viewModel, resId = R.drawable.ic_settings, contentDescription = null, ) .value, modifier = Modifier.size(24.dp), ) }, ) } Spacer(Modifier.width(12.dp)) val recordIcon by loadIcon( Loading @@ -124,6 +152,11 @@ constructor(private val viewModelFactory: SmallScreenCaptureRecordViewModel.Fact } } AnimatedVisibility( visible = viewModel.shouldShowDetails, enter = fadeIn(), exit = fadeOut(), ) { Surface( color = MaterialTheme.colorScheme.surface, shape = RoundedCornerShape(28.dp), Loading @@ -138,22 +171,22 @@ constructor(private val viewModelFactory: SmallScreenCaptureRecordViewModel.Fact ) { currentPopup -> val contentModifier = Modifier.fillMaxWidth() when (currentPopup) { RecordDetailsPopupType.Empty -> { /* show nothing */ } RecordDetailsPopupType.Settings -> RecordDetailsSettings( parametersViewModel = viewModel.recordDetailsParametersViewModel, parametersViewModel = viewModel.recordDetailsParametersViewModel, targetViewModel = viewModel.recordDetailsTargetViewModel, drawableLoaderViewModel = viewModel, modifier = contentModifier, ) RecordDetailsPopupType.AppSelector -> RecordDetailsAppSelector( viewModel = viewModel.recordDetailsAppSelectorViewModel, onBackPressed = { viewModel.showSettings() }, modifier = contentModifier, ) RecordDetailsPopupType.MarkupColorSelector -> RecordDetailsMarkupColorSelector(modifier = contentModifier) } Loading @@ -162,3 +195,36 @@ constructor(private val viewModelFactory: SmallScreenCaptureRecordViewModel.Fact } } } } @Composable private fun ToggleToolbarButton( checked: Boolean, onCheckedChanged: (Boolean) -> Unit, icon: @Composable BoxScope.() -> Unit, modifier: Modifier = Modifier, ) { val secondaryColor = MaterialTheme.colorScheme.secondary Box( contentAlignment = Alignment.Center, modifier = modifier .size(48.dp) .padding(6.dp) .thenIf(checked) { Modifier.background(color = secondaryColor, shape = RoundedCornerShape(12.dp)) } .clickable(onClick = { onCheckedChanged(!checked) }), ) { CompositionLocalProvider( LocalContentColor provides if (checked) { MaterialTheme.colorScheme.onSecondary } else { MaterialTheme.colorScheme.onSurface } ) { icon() } } } packages/SystemUI/src/com/android/systemui/screencapture/record/smallscreen/ui/viewmodel/RecordDetailsPopupType.kt +0 −1 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package com.android.systemui.screencapture.record.smallscreen.ui.viewmodel enum class RecordDetailsPopupType { Empty, Settings, AppSelector, MarkupColorSelector, Loading packages/SystemUI/src/com/android/systemui/screencapture/record/smallscreen/ui/viewmodel/SmallScreenCaptureRecordViewModel.kt +30 −0 Original line number Diff line number Diff line Loading @@ -29,9 +29,11 @@ import com.android.systemui.screencapture.domain.interactor.ScreenCaptureUiInter import com.android.systemui.screencapture.record.ui.viewmodel.ScreenCaptureRecordParametersViewModel import com.android.systemui.screenrecord.domain.ScreenRecordingParameters import com.android.systemui.screenrecord.domain.interactor.ScreenRecordingServiceInteractor import com.android.systemui.screenrecord.domain.interactor.Status import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.map class SmallScreenCaptureRecordViewModel @AssistedInject Loading @@ -54,6 +56,25 @@ constructor( var detailsPopup: RecordDetailsPopupType by mutableStateOf(RecordDetailsPopupType.Settings) private set var shouldShowDetails: Boolean by mutableStateOf(!screenRecordingServiceInteractor.status.value.isRecording) private set val shouldShowSettingsButton: Boolean by screenRecordingServiceInteractor.status .map { status -> if (status.isRecording) { true } else { shouldShowDetails = true false } } .hydratedStateOf( traceName = "SmallScreenCaptureRecordViewModel#shouldShowSettingsButton", initialValue = !screenRecordingServiceInteractor.status.value.isRecording, ) override suspend fun onActivated() { coroutineScope { launchTraced("SmallScreenCaptureRecordViewModel#recordDetailsAppSelectorViewModel") { Loading Loading @@ -101,9 +122,18 @@ constructor( dismiss() } fun shouldShowSettings(visible: Boolean) { if (shouldShowSettingsButton) { shouldShowDetails = visible } } @AssistedFactory @ScreenCaptureUiScope interface Factory { fun create(): SmallScreenCaptureRecordViewModel } } private val Status.isRecording get() = this is Status.Started Loading
packages/SystemUI/src/com/android/systemui/screencapture/record/smallscreen/ui/compose/SmallScreenCaptureRecordContent.kt +96 −30 Original line number Diff line number Diff line Loading @@ -17,11 +17,16 @@ package com.android.systemui.screencapture.record.smallscreen.ui.compose import androidx.compose.animation.AnimatedContent import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.animateContentSize import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.togetherWith import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row Loading @@ -34,6 +39,7 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.only import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.safeContent import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.layout.windowInsetsPadding Loading @@ -41,18 +47,22 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.FloatingToolbarDefaults import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.LocalContentColor import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.android.compose.PlatformIconButton import com.android.compose.modifiers.thenIf import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.res.R import com.android.systemui.screencapture.common.ScreenCaptureUiScope import com.android.systemui.screencapture.common.ui.compose.LoadingIcon import com.android.systemui.screencapture.common.ui.compose.PrimaryButton import com.android.systemui.screencapture.common.ui.compose.ScreenCaptureContent import com.android.systemui.screencapture.common.ui.compose.loadIcon Loading Loading @@ -106,6 +116,24 @@ constructor(private val viewModelFactory: SmallScreenCaptureRecordViewModel.Fact ), iconResource = R.drawable.ic_close, ) AnimatedVisibility(visible = viewModel.shouldShowSettingsButton) { ToggleToolbarButton( checked = viewModel.shouldShowDetails, onCheckedChanged = { viewModel.shouldShowSettings(it) }, icon = { LoadingIcon( icon = loadIcon( viewModel = viewModel, resId = R.drawable.ic_settings, contentDescription = null, ) .value, modifier = Modifier.size(24.dp), ) }, ) } Spacer(Modifier.width(12.dp)) val recordIcon by loadIcon( Loading @@ -124,6 +152,11 @@ constructor(private val viewModelFactory: SmallScreenCaptureRecordViewModel.Fact } } AnimatedVisibility( visible = viewModel.shouldShowDetails, enter = fadeIn(), exit = fadeOut(), ) { Surface( color = MaterialTheme.colorScheme.surface, shape = RoundedCornerShape(28.dp), Loading @@ -138,22 +171,22 @@ constructor(private val viewModelFactory: SmallScreenCaptureRecordViewModel.Fact ) { currentPopup -> val contentModifier = Modifier.fillMaxWidth() when (currentPopup) { RecordDetailsPopupType.Empty -> { /* show nothing */ } RecordDetailsPopupType.Settings -> RecordDetailsSettings( parametersViewModel = viewModel.recordDetailsParametersViewModel, parametersViewModel = viewModel.recordDetailsParametersViewModel, targetViewModel = viewModel.recordDetailsTargetViewModel, drawableLoaderViewModel = viewModel, modifier = contentModifier, ) RecordDetailsPopupType.AppSelector -> RecordDetailsAppSelector( viewModel = viewModel.recordDetailsAppSelectorViewModel, onBackPressed = { viewModel.showSettings() }, modifier = contentModifier, ) RecordDetailsPopupType.MarkupColorSelector -> RecordDetailsMarkupColorSelector(modifier = contentModifier) } Loading @@ -162,3 +195,36 @@ constructor(private val viewModelFactory: SmallScreenCaptureRecordViewModel.Fact } } } } @Composable private fun ToggleToolbarButton( checked: Boolean, onCheckedChanged: (Boolean) -> Unit, icon: @Composable BoxScope.() -> Unit, modifier: Modifier = Modifier, ) { val secondaryColor = MaterialTheme.colorScheme.secondary Box( contentAlignment = Alignment.Center, modifier = modifier .size(48.dp) .padding(6.dp) .thenIf(checked) { Modifier.background(color = secondaryColor, shape = RoundedCornerShape(12.dp)) } .clickable(onClick = { onCheckedChanged(!checked) }), ) { CompositionLocalProvider( LocalContentColor provides if (checked) { MaterialTheme.colorScheme.onSecondary } else { MaterialTheme.colorScheme.onSurface } ) { icon() } } }
packages/SystemUI/src/com/android/systemui/screencapture/record/smallscreen/ui/viewmodel/RecordDetailsPopupType.kt +0 −1 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package com.android.systemui.screencapture.record.smallscreen.ui.viewmodel enum class RecordDetailsPopupType { Empty, Settings, AppSelector, MarkupColorSelector, Loading
packages/SystemUI/src/com/android/systemui/screencapture/record/smallscreen/ui/viewmodel/SmallScreenCaptureRecordViewModel.kt +30 −0 Original line number Diff line number Diff line Loading @@ -29,9 +29,11 @@ import com.android.systemui.screencapture.domain.interactor.ScreenCaptureUiInter import com.android.systemui.screencapture.record.ui.viewmodel.ScreenCaptureRecordParametersViewModel import com.android.systemui.screenrecord.domain.ScreenRecordingParameters import com.android.systemui.screenrecord.domain.interactor.ScreenRecordingServiceInteractor import com.android.systemui.screenrecord.domain.interactor.Status import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.map class SmallScreenCaptureRecordViewModel @AssistedInject Loading @@ -54,6 +56,25 @@ constructor( var detailsPopup: RecordDetailsPopupType by mutableStateOf(RecordDetailsPopupType.Settings) private set var shouldShowDetails: Boolean by mutableStateOf(!screenRecordingServiceInteractor.status.value.isRecording) private set val shouldShowSettingsButton: Boolean by screenRecordingServiceInteractor.status .map { status -> if (status.isRecording) { true } else { shouldShowDetails = true false } } .hydratedStateOf( traceName = "SmallScreenCaptureRecordViewModel#shouldShowSettingsButton", initialValue = !screenRecordingServiceInteractor.status.value.isRecording, ) override suspend fun onActivated() { coroutineScope { launchTraced("SmallScreenCaptureRecordViewModel#recordDetailsAppSelectorViewModel") { Loading Loading @@ -101,9 +122,18 @@ constructor( dismiss() } fun shouldShowSettings(visible: Boolean) { if (shouldShowSettingsButton) { shouldShowDetails = visible } } @AssistedFactory @ScreenCaptureUiScope interface Factory { fun create(): SmallScreenCaptureRecordViewModel } } private val Status.isRecording get() = this is Status.Started