From 8e5da82a77e96f68b60d1365a168d25ce9ec5347 Mon Sep 17 00:00:00 2001 From: Fabián Kozynski Date: Fri, 20 Sep 2024 13:38:48 -0400 Subject: Move Edit mode to be top level in QS That way, it doesn't need a GridAnchor. Even if we added a GridAnchor to EditMode, the problem is that AnimatedContent ends up composing both at the same time when swapping and STL crashes because there are two elements with the same name. Test: manual Bug: 353254353 Flag: com.android.systemui.qs_ui_refactor_compose_fragment Change-Id: I71735183f28221b69e4220991b6865b2ae8fbffb --- .../qs/ui/composable/QuickSettingsShadeOverlay.kt | 3 +- .../qs/composefragment/QSFragmentCompose.kt | 101 +++++++++++++++------ 2 files changed, 75 insertions(+), 29 deletions(-) diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt index 8e6cb3fe9fb9..54497f621c73 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt @@ -124,8 +124,9 @@ fun SceneScope.ShadeBody(viewModel: QuickSettingsContainerViewModel) { } } +/** Column containing Brightness and QS tiles. */ @Composable -private fun SceneScope.QuickSettingsLayout( +fun SceneScope.QuickSettingsLayout( viewModel: QuickSettingsContainerViewModel, modifier: Modifier = Modifier, ) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt index c174038aafe4..c8079600e980 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt @@ -26,7 +26,12 @@ import android.view.ViewGroup import androidx.activity.OnBackPressedDispatcher import androidx.activity.OnBackPressedDispatcherOwner import androidx.activity.setViewTreeOnBackPressedDispatcherOwner +import androidx.compose.animation.AnimatedContent import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.togetherWith import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -88,11 +93,12 @@ import com.android.systemui.qs.composefragment.ui.quickQuickSettingsToQuickSetti import com.android.systemui.qs.composefragment.viewmodel.QSFragmentComposeViewModel import com.android.systemui.qs.flags.QSComposeFragment import com.android.systemui.qs.footer.ui.compose.FooterActions +import com.android.systemui.qs.panels.ui.compose.EditMode import com.android.systemui.qs.panels.ui.compose.QuickQuickSettings import com.android.systemui.qs.shared.ui.ElementKeys +import com.android.systemui.qs.ui.composable.QuickSettingsLayout import com.android.systemui.qs.ui.composable.QuickSettingsShade import com.android.systemui.qs.ui.composable.QuickSettingsTheme -import com.android.systemui.qs.ui.composable.ShadeBody import com.android.systemui.res.R import com.android.systemui.util.LifecycleFragment import com.android.systemui.util.asIndenting @@ -200,36 +206,70 @@ constructor( } .graphicsLayer { elevation = 4.dp.toPx() }, ) { - val sceneState = remember { - MutableSceneTransitionLayoutState( - viewModel.expansionState.value.toIdleSceneKey(), - transitions = - transitions { - from(QuickQuickSettings, QuickSettings) { - quickQuickSettingsToQuickSettings() - } - }, - ) + val isEditing by + viewModel.containerViewModel.editModeViewModel.isEditing + .collectAsStateWithLifecycle() + val animationSpecEditMode = tween(EDIT_MODE_TIME_MILLIS) + AnimatedContent( + targetState = isEditing, + transitionSpec = { + fadeIn(animationSpecEditMode) togetherWith + fadeOut(animationSpecEditMode) + }, + label = "EditModeAnimatedContent", + ) { editing -> + if (editing) { + val qqsPadding by + viewModel.qqsHeaderHeight.collectAsStateWithLifecycle() + EditMode( + viewModel = viewModel.containerViewModel.editModeViewModel, + modifier = + Modifier.fillMaxWidth() + .padding(top = { qqsPadding }) + .padding( + horizontal = { + QuickSettingsShade.Dimensions.Padding + .roundToPx() + } + ), + ) + } else { + CollapsableQuickSettingsSTL() + } } + } + } + } + } + } - LaunchedEffect(Unit) { - synchronizeQsState( - sceneState, - viewModel.expansionState.map { it.progress }, - ) + /** + * STL that contains both QQS (tiles) and QS (brightness, tiles, footer actions), but no Edit + * mode. It tracks [QSFragmentComposeViewModel.expansionState] to drive the transition between + * [SceneKeys.QuickQuickSettings] and [SceneKeys.QuickSettings]. + */ + @Composable + private fun CollapsableQuickSettingsSTL() { + val sceneState = remember { + MutableSceneTransitionLayoutState( + viewModel.expansionState.value.toIdleSceneKey(), + transitions = + transitions { + from(QuickQuickSettings, QuickSettings) { + quickQuickSettingsToQuickSettings() } + }, + ) + } - SceneTransitionLayout( - state = sceneState, - modifier = Modifier.fillMaxSize(), - ) { - scene(QuickSettings) { QuickSettingsElement() } + LaunchedEffect(Unit) { + synchronizeQsState(sceneState, viewModel.expansionState.map { it.progress }) + } - scene(QuickQuickSettings) { QuickQuickSettingsElement() } - } - } - } - } + SceneTransitionLayout(state = sceneState, modifier = Modifier.fillMaxSize()) { + scene(QuickSettings) { QuickSettingsElement() } + + scene(QuickQuickSettings) { QuickQuickSettingsElement() } } } @@ -445,7 +485,7 @@ constructor( qsContainerController, viewModel.containerViewModel.editModeViewModel.isEditing, ) { - setCustomizerShowing(it) + setCustomizerShowing(it, EDIT_MODE_TIME_MILLIS.toLong()) } } } @@ -519,7 +559,10 @@ constructor( Spacer( modifier = Modifier.height { qqsPadding + qsExtraPadding.roundToPx() } ) - ShadeBody(viewModel = viewModel.containerViewModel) + QuickSettingsLayout( + viewModel = viewModel.containerViewModel, + modifier = Modifier.sysuiResTag("quick_settings_panel"), + ) } } QuickSettingsTheme { @@ -717,3 +760,5 @@ private class ExpansionTransition(currentProgress: Float) : finishCompletable.complete(Unit) } } + +private const val EDIT_MODE_TIME_MILLIS = 500 -- cgit v1.2.3-59-g8ed1b