Loading packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt +13 −15 Original line number Diff line number Diff line Loading @@ -27,20 +27,17 @@ import com.android.systemui.battery.BatteryMeterViewController import com.android.systemui.dagger.SysUISingleton import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeOverlayActionsViewModel import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeOverlayContentViewModel import com.android.systemui.scene.session.ui.composable.SaveableSession import com.android.systemui.scene.shared.model.Overlays import com.android.systemui.scene.ui.composable.Overlay import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.shade.ui.composable.ExpandedShadeHeader import com.android.systemui.shade.ui.composable.OverlayShade import com.android.systemui.shade.ui.viewmodel.OverlayShadeViewModel import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import com.android.systemui.statusbar.phone.ui.StatusBarIconController import com.android.systemui.statusbar.phone.ui.TintedIconManager import dagger.Lazy import java.util.Optional import javax.inject.Inject @SysUISingleton Loading @@ -48,9 +45,7 @@ class NotificationsShadeOverlay @Inject constructor( private val actionsViewModelFactory: NotificationsShadeOverlayActionsViewModel.Factory, private val overlayShadeViewModelFactory: OverlayShadeViewModel.Factory, private val shadeHeaderViewModelFactory: ShadeHeaderViewModel.Factory, private val notificationsPlaceholderViewModelFactory: NotificationsPlaceholderViewModel.Factory, private val contentViewModelFactory: NotificationsShadeOverlayContentViewModel.Factory, private val tintedIconManagerFactory: TintedIconManager.Factory, private val batteryMeterViewControllerFactory: BatteryMeterViewController.Factory, private val statusBarIconController: StatusBarIconController, Loading @@ -72,19 +67,22 @@ constructor( override fun ContentScope.Content( modifier: Modifier, ) { val viewModel = rememberViewModel("NotificationsShadeOverlay-viewModel") { contentViewModelFactory.create() } val placeholderViewModel = rememberViewModel("NotificationsShadeOverlay-notifPlaceholderViewModel") { viewModel.notificationsPlaceholderViewModelFactory.create() } OverlayShade( modifier = modifier, viewModelFactory = overlayShadeViewModelFactory, lockscreenContent = { Optional.empty() }, onScrimClicked = viewModel::onScrimClicked, ) { Column { val placeholderViewModel = rememberViewModel("NotificationsShadeOverlay") { notificationsPlaceholderViewModelFactory.create() } ExpandedShadeHeader( viewModelFactory = shadeHeaderViewModelFactory, viewModelFactory = viewModel.shadeHeaderViewModelFactory, createTintedIconManager = tintedIconManagerFactory::create, createBatteryMeterViewController = batteryMeterViewControllerFactory::create, statusBarIconController = statusBarIconController, Loading packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeScene.kt +1 −7 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult import com.android.systemui.battery.BatteryMeterViewController import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.ui.composable.LockscreenContent import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeSceneActionsViewModel Loading @@ -37,14 +36,12 @@ import com.android.systemui.scene.ui.composable.ComposableScene import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.shade.ui.composable.ExpandedShadeHeader import com.android.systemui.shade.ui.composable.OverlayShade import com.android.systemui.shade.ui.viewmodel.OverlayShadeViewModel import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import com.android.systemui.statusbar.phone.ui.StatusBarIconController import com.android.systemui.statusbar.phone.ui.TintedIconManager import dagger.Lazy import java.util.Optional import javax.inject.Inject import kotlinx.coroutines.flow.Flow Loading @@ -53,7 +50,6 @@ class NotificationsShadeScene @Inject constructor( private val actionsViewModelFactory: NotificationsShadeSceneActionsViewModel.Factory, private val overlayShadeViewModelFactory: OverlayShadeViewModel.Factory, private val shadeHeaderViewModelFactory: ShadeHeaderViewModel.Factory, private val notificationsPlaceholderViewModelFactory: NotificationsPlaceholderViewModel.Factory, private val tintedIconManagerFactory: TintedIconManager.Factory, Loading @@ -61,7 +57,6 @@ constructor( private val statusBarIconController: StatusBarIconController, private val shadeSession: SaveableSession, private val stackScrollView: Lazy<NotificationScrollView>, private val lockscreenContent: Lazy<Optional<LockscreenContent>>, ) : ExclusiveActivatable(), ComposableScene { override val key = Scenes.NotificationsShade Loading @@ -88,8 +83,7 @@ constructor( OverlayShade( modifier = modifier, viewModelFactory = overlayShadeViewModelFactory, lockscreenContent = lockscreenContent, onScrimClicked = {}, ) { Column { ExpandedShadeHeader( Loading packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt +78 −3 Original line number Diff line number Diff line Loading @@ -16,14 +16,32 @@ package com.android.systemui.qs.ui.composable import androidx.compose.animation.AnimatedContent 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.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.animation.scene.ContentScope import com.android.systemui.battery.BatteryMeterViewController import com.android.systemui.brightness.ui.compose.BrightnessSliderContainer import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.dagger.SysUISingleton import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.qs.panels.ui.compose.EditMode import com.android.systemui.qs.panels.ui.compose.TileGrid import com.android.systemui.qs.ui.viewmodel.QuickSettingsContainerViewModel import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeOverlayActionsViewModel import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeOverlayContentViewModel import com.android.systemui.scene.shared.model.Overlays Loading @@ -32,7 +50,6 @@ import com.android.systemui.shade.ui.composable.ExpandedShadeHeader import com.android.systemui.shade.ui.composable.OverlayShade import com.android.systemui.statusbar.phone.ui.StatusBarIconController import com.android.systemui.statusbar.phone.ui.TintedIconManager import java.util.Optional import javax.inject.Inject @SysUISingleton Loading Loading @@ -62,10 +79,10 @@ constructor( ) { val viewModel = rememberViewModel("QuickSettingsShadeOverlay") { contentViewModelFactory.create() } OverlayShade( modifier = modifier, viewModelFactory = viewModel.overlayShadeViewModelFactory, lockscreenContent = { Optional.empty() }, onScrimClicked = viewModel::onScrimClicked, ) { Column { ExpandedShadeHeader( Loading @@ -83,3 +100,61 @@ constructor( } } } @Composable fun ShadeBody( viewModel: QuickSettingsContainerViewModel, ) { val isEditing by viewModel.editModeViewModel.isEditing.collectAsStateWithLifecycle() AnimatedContent( targetState = isEditing, transitionSpec = { fadeIn(tween(500)) togetherWith fadeOut(tween(500)) } ) { editing -> if (editing) { EditMode( viewModel = viewModel.editModeViewModel, modifier = Modifier.fillMaxWidth().padding(QuickSettingsShade.Dimensions.Padding) ) } else { QuickSettingsLayout( viewModel = viewModel, modifier = Modifier.sysuiResTag("quick_settings_panel") ) } } } @Composable private fun QuickSettingsLayout( viewModel: QuickSettingsContainerViewModel, modifier: Modifier = Modifier, ) { Column( verticalArrangement = Arrangement.spacedBy(QuickSettingsShade.Dimensions.Padding), horizontalAlignment = Alignment.CenterHorizontally, modifier = modifier.fillMaxWidth().padding(QuickSettingsShade.Dimensions.Padding), ) { BrightnessSliderContainer( viewModel = viewModel.brightnessSliderViewModel, modifier = Modifier.fillMaxWidth() .height(QuickSettingsShade.Dimensions.BrightnessSliderHeight), ) TileGrid( viewModel = viewModel.tileGridViewModel, modifier = Modifier.fillMaxWidth().heightIn(max = QuickSettingsShade.Dimensions.GridMaxHeight), viewModel.editModeViewModel::startEditing, ) } } object QuickSettingsShade { object Dimensions { val Padding = 16.dp val BrightnessSliderHeight = 64.dp val GridMaxHeight = 800.dp } } packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt +2 −92 Original line number Diff line number Diff line Loading @@ -16,40 +16,18 @@ package com.android.systemui.qs.ui.composable import androidx.compose.animation.AnimatedContent import androidx.compose.animation.EnterTransition import androidx.compose.animation.ExitTransition 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.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.animation.scene.SceneScope import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult import com.android.systemui.battery.BatteryMeterViewController import com.android.systemui.brightness.ui.compose.BrightnessSliderContainer import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.ui.composable.LockscreenContent import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.qs.panels.ui.compose.EditMode import com.android.systemui.qs.panels.ui.compose.TileGrid import com.android.systemui.qs.ui.composable.QuickSettingsShade.Transitions.QuickSettingsLayoutEnter import com.android.systemui.qs.ui.composable.QuickSettingsShade.Transitions.QuickSettingsLayoutExit import com.android.systemui.qs.ui.viewmodel.QuickSettingsContainerViewModel import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeSceneActionsViewModel import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeSceneContentViewModel import com.android.systemui.scene.shared.model.Scenes Loading @@ -59,8 +37,6 @@ import com.android.systemui.shade.ui.composable.OverlayShade import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel import com.android.systemui.statusbar.phone.ui.StatusBarIconController import com.android.systemui.statusbar.phone.ui.TintedIconManager import dagger.Lazy import java.util.Optional import javax.inject.Inject import kotlinx.coroutines.flow.Flow Loading @@ -70,7 +46,6 @@ class QuickSettingsShadeScene constructor( private val actionsViewModelFactory: QuickSettingsShadeSceneActionsViewModel.Factory, private val contentViewModelFactory: QuickSettingsShadeSceneContentViewModel.Factory, private val lockscreenContent: Lazy<Optional<LockscreenContent>>, private val shadeHeaderViewModelFactory: ShadeHeaderViewModel.Factory, private val tintedIconManagerFactory: TintedIconManager.Factory, private val batteryMeterViewControllerFactory: BatteryMeterViewController.Factory, Loading @@ -96,10 +71,10 @@ constructor( ) { val viewModel = rememberViewModel("QuickSettingsShadeScene") { contentViewModelFactory.create() } OverlayShade( viewModelFactory = viewModel.overlayShadeViewModelFactory, lockscreenContent = lockscreenContent, modifier = modifier, onScrimClicked = {}, ) { Column { ExpandedShadeHeader( Loading @@ -117,68 +92,3 @@ constructor( } } } @Composable fun ShadeBody( viewModel: QuickSettingsContainerViewModel, ) { val isEditing by viewModel.editModeViewModel.isEditing.collectAsStateWithLifecycle() AnimatedContent( targetState = isEditing, transitionSpec = { QuickSettingsLayoutEnter togetherWith QuickSettingsLayoutExit } ) { editing -> if (editing) { EditMode( viewModel = viewModel.editModeViewModel, modifier = Modifier.fillMaxWidth().padding(QuickSettingsShade.Dimensions.Padding) ) } else { QuickSettingsLayout( viewModel = viewModel, modifier = Modifier.sysuiResTag("quick_settings_panel") ) } } } @Composable private fun QuickSettingsLayout( viewModel: QuickSettingsContainerViewModel, modifier: Modifier = Modifier, ) { Column( verticalArrangement = Arrangement.spacedBy(QuickSettingsShade.Dimensions.Padding), horizontalAlignment = Alignment.CenterHorizontally, modifier = modifier.fillMaxWidth().padding(QuickSettingsShade.Dimensions.Padding), ) { BrightnessSliderContainer( viewModel = viewModel.brightnessSliderViewModel, modifier = Modifier.fillMaxWidth() .height(QuickSettingsShade.Dimensions.BrightnessSliderHeight), ) TileGrid( viewModel = viewModel.tileGridViewModel, modifier = Modifier.fillMaxWidth().heightIn(max = QuickSettingsShade.Dimensions.GridMaxHeight), viewModel.editModeViewModel::startEditing, ) } } object QuickSettingsShade { object Dimensions { val Padding = 16.dp val BrightnessSliderHeight = 64.dp val GridMaxHeight = 800.dp } object Transitions { val QuickSettingsLayoutEnter: EnterTransition = fadeIn(tween(500)) val QuickSettingsLayoutExit: ExitTransition = fadeOut(tween(500)) val QuickSettingsEditorEnter: EnterTransition = fadeIn(tween(500)) val QuickSettingsEditorExit: ExitTransition = fadeOut(tween(500)) } } packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/OverlayShade.kt +4 −24 Original line number Diff line number Diff line Loading @@ -40,46 +40,26 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass import androidx.compose.runtime.Composable import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.animation.scene.ElementKey import com.android.compose.animation.scene.LowestZIndexContentPicker import com.android.compose.animation.scene.SceneScope import com.android.compose.windowsizeclass.LocalWindowSizeClass import com.android.systemui.keyguard.ui.composable.LockscreenContent import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.shade.ui.viewmodel.OverlayShadeViewModel import com.android.systemui.util.kotlin.getOrNull import dagger.Lazy import java.util.Optional /** The overlay shade renders a lightweight shade UI container on top of a background scene. */ /** Renders a lightweight shade UI container, as an overlay. */ @Composable fun SceneScope.OverlayShade( viewModelFactory: OverlayShadeViewModel.Factory, lockscreenContent: Lazy<Optional<LockscreenContent>>, onScrimClicked: () -> Unit, modifier: Modifier = Modifier, content: @Composable () -> Unit, ) { val viewModel = rememberViewModel("OverlayShade") { viewModelFactory.create() } val backgroundScene by viewModel.backgroundScene.collectAsStateWithLifecycle() Box(modifier) { if (backgroundScene == Scenes.Lockscreen) { // Lockscreen content is optionally injected, because variants of System UI without a // lockscreen cannot provide it. val lockscreenContentOrNull = lockscreenContent.get().getOrNull() lockscreenContentOrNull?.apply { Content(Modifier.fillMaxSize()) } } Scrim(onClicked = viewModel::onScrimClicked) Scrim(onClicked = onScrimClicked) Box( modifier = Modifier.fillMaxSize().panelPadding(), Loading Loading
packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt +13 −15 Original line number Diff line number Diff line Loading @@ -27,20 +27,17 @@ import com.android.systemui.battery.BatteryMeterViewController import com.android.systemui.dagger.SysUISingleton import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeOverlayActionsViewModel import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeOverlayContentViewModel import com.android.systemui.scene.session.ui.composable.SaveableSession import com.android.systemui.scene.shared.model.Overlays import com.android.systemui.scene.ui.composable.Overlay import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.shade.ui.composable.ExpandedShadeHeader import com.android.systemui.shade.ui.composable.OverlayShade import com.android.systemui.shade.ui.viewmodel.OverlayShadeViewModel import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import com.android.systemui.statusbar.phone.ui.StatusBarIconController import com.android.systemui.statusbar.phone.ui.TintedIconManager import dagger.Lazy import java.util.Optional import javax.inject.Inject @SysUISingleton Loading @@ -48,9 +45,7 @@ class NotificationsShadeOverlay @Inject constructor( private val actionsViewModelFactory: NotificationsShadeOverlayActionsViewModel.Factory, private val overlayShadeViewModelFactory: OverlayShadeViewModel.Factory, private val shadeHeaderViewModelFactory: ShadeHeaderViewModel.Factory, private val notificationsPlaceholderViewModelFactory: NotificationsPlaceholderViewModel.Factory, private val contentViewModelFactory: NotificationsShadeOverlayContentViewModel.Factory, private val tintedIconManagerFactory: TintedIconManager.Factory, private val batteryMeterViewControllerFactory: BatteryMeterViewController.Factory, private val statusBarIconController: StatusBarIconController, Loading @@ -72,19 +67,22 @@ constructor( override fun ContentScope.Content( modifier: Modifier, ) { val viewModel = rememberViewModel("NotificationsShadeOverlay-viewModel") { contentViewModelFactory.create() } val placeholderViewModel = rememberViewModel("NotificationsShadeOverlay-notifPlaceholderViewModel") { viewModel.notificationsPlaceholderViewModelFactory.create() } OverlayShade( modifier = modifier, viewModelFactory = overlayShadeViewModelFactory, lockscreenContent = { Optional.empty() }, onScrimClicked = viewModel::onScrimClicked, ) { Column { val placeholderViewModel = rememberViewModel("NotificationsShadeOverlay") { notificationsPlaceholderViewModelFactory.create() } ExpandedShadeHeader( viewModelFactory = shadeHeaderViewModelFactory, viewModelFactory = viewModel.shadeHeaderViewModelFactory, createTintedIconManager = tintedIconManagerFactory::create, createBatteryMeterViewController = batteryMeterViewControllerFactory::create, statusBarIconController = statusBarIconController, Loading
packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeScene.kt +1 −7 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult import com.android.systemui.battery.BatteryMeterViewController import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.ui.composable.LockscreenContent import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeSceneActionsViewModel Loading @@ -37,14 +36,12 @@ import com.android.systemui.scene.ui.composable.ComposableScene import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.shade.ui.composable.ExpandedShadeHeader import com.android.systemui.shade.ui.composable.OverlayShade import com.android.systemui.shade.ui.viewmodel.OverlayShadeViewModel import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import com.android.systemui.statusbar.phone.ui.StatusBarIconController import com.android.systemui.statusbar.phone.ui.TintedIconManager import dagger.Lazy import java.util.Optional import javax.inject.Inject import kotlinx.coroutines.flow.Flow Loading @@ -53,7 +50,6 @@ class NotificationsShadeScene @Inject constructor( private val actionsViewModelFactory: NotificationsShadeSceneActionsViewModel.Factory, private val overlayShadeViewModelFactory: OverlayShadeViewModel.Factory, private val shadeHeaderViewModelFactory: ShadeHeaderViewModel.Factory, private val notificationsPlaceholderViewModelFactory: NotificationsPlaceholderViewModel.Factory, private val tintedIconManagerFactory: TintedIconManager.Factory, Loading @@ -61,7 +57,6 @@ constructor( private val statusBarIconController: StatusBarIconController, private val shadeSession: SaveableSession, private val stackScrollView: Lazy<NotificationScrollView>, private val lockscreenContent: Lazy<Optional<LockscreenContent>>, ) : ExclusiveActivatable(), ComposableScene { override val key = Scenes.NotificationsShade Loading @@ -88,8 +83,7 @@ constructor( OverlayShade( modifier = modifier, viewModelFactory = overlayShadeViewModelFactory, lockscreenContent = lockscreenContent, onScrimClicked = {}, ) { Column { ExpandedShadeHeader( Loading
packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt +78 −3 Original line number Diff line number Diff line Loading @@ -16,14 +16,32 @@ package com.android.systemui.qs.ui.composable import androidx.compose.animation.AnimatedContent 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.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.animation.scene.ContentScope import com.android.systemui.battery.BatteryMeterViewController import com.android.systemui.brightness.ui.compose.BrightnessSliderContainer import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.dagger.SysUISingleton import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.qs.panels.ui.compose.EditMode import com.android.systemui.qs.panels.ui.compose.TileGrid import com.android.systemui.qs.ui.viewmodel.QuickSettingsContainerViewModel import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeOverlayActionsViewModel import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeOverlayContentViewModel import com.android.systemui.scene.shared.model.Overlays Loading @@ -32,7 +50,6 @@ import com.android.systemui.shade.ui.composable.ExpandedShadeHeader import com.android.systemui.shade.ui.composable.OverlayShade import com.android.systemui.statusbar.phone.ui.StatusBarIconController import com.android.systemui.statusbar.phone.ui.TintedIconManager import java.util.Optional import javax.inject.Inject @SysUISingleton Loading Loading @@ -62,10 +79,10 @@ constructor( ) { val viewModel = rememberViewModel("QuickSettingsShadeOverlay") { contentViewModelFactory.create() } OverlayShade( modifier = modifier, viewModelFactory = viewModel.overlayShadeViewModelFactory, lockscreenContent = { Optional.empty() }, onScrimClicked = viewModel::onScrimClicked, ) { Column { ExpandedShadeHeader( Loading @@ -83,3 +100,61 @@ constructor( } } } @Composable fun ShadeBody( viewModel: QuickSettingsContainerViewModel, ) { val isEditing by viewModel.editModeViewModel.isEditing.collectAsStateWithLifecycle() AnimatedContent( targetState = isEditing, transitionSpec = { fadeIn(tween(500)) togetherWith fadeOut(tween(500)) } ) { editing -> if (editing) { EditMode( viewModel = viewModel.editModeViewModel, modifier = Modifier.fillMaxWidth().padding(QuickSettingsShade.Dimensions.Padding) ) } else { QuickSettingsLayout( viewModel = viewModel, modifier = Modifier.sysuiResTag("quick_settings_panel") ) } } } @Composable private fun QuickSettingsLayout( viewModel: QuickSettingsContainerViewModel, modifier: Modifier = Modifier, ) { Column( verticalArrangement = Arrangement.spacedBy(QuickSettingsShade.Dimensions.Padding), horizontalAlignment = Alignment.CenterHorizontally, modifier = modifier.fillMaxWidth().padding(QuickSettingsShade.Dimensions.Padding), ) { BrightnessSliderContainer( viewModel = viewModel.brightnessSliderViewModel, modifier = Modifier.fillMaxWidth() .height(QuickSettingsShade.Dimensions.BrightnessSliderHeight), ) TileGrid( viewModel = viewModel.tileGridViewModel, modifier = Modifier.fillMaxWidth().heightIn(max = QuickSettingsShade.Dimensions.GridMaxHeight), viewModel.editModeViewModel::startEditing, ) } } object QuickSettingsShade { object Dimensions { val Padding = 16.dp val BrightnessSliderHeight = 64.dp val GridMaxHeight = 800.dp } }
packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt +2 −92 Original line number Diff line number Diff line Loading @@ -16,40 +16,18 @@ package com.android.systemui.qs.ui.composable import androidx.compose.animation.AnimatedContent import androidx.compose.animation.EnterTransition import androidx.compose.animation.ExitTransition 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.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.animation.scene.SceneScope import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult import com.android.systemui.battery.BatteryMeterViewController import com.android.systemui.brightness.ui.compose.BrightnessSliderContainer import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.ui.composable.LockscreenContent import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.qs.panels.ui.compose.EditMode import com.android.systemui.qs.panels.ui.compose.TileGrid import com.android.systemui.qs.ui.composable.QuickSettingsShade.Transitions.QuickSettingsLayoutEnter import com.android.systemui.qs.ui.composable.QuickSettingsShade.Transitions.QuickSettingsLayoutExit import com.android.systemui.qs.ui.viewmodel.QuickSettingsContainerViewModel import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeSceneActionsViewModel import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeSceneContentViewModel import com.android.systemui.scene.shared.model.Scenes Loading @@ -59,8 +37,6 @@ import com.android.systemui.shade.ui.composable.OverlayShade import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel import com.android.systemui.statusbar.phone.ui.StatusBarIconController import com.android.systemui.statusbar.phone.ui.TintedIconManager import dagger.Lazy import java.util.Optional import javax.inject.Inject import kotlinx.coroutines.flow.Flow Loading @@ -70,7 +46,6 @@ class QuickSettingsShadeScene constructor( private val actionsViewModelFactory: QuickSettingsShadeSceneActionsViewModel.Factory, private val contentViewModelFactory: QuickSettingsShadeSceneContentViewModel.Factory, private val lockscreenContent: Lazy<Optional<LockscreenContent>>, private val shadeHeaderViewModelFactory: ShadeHeaderViewModel.Factory, private val tintedIconManagerFactory: TintedIconManager.Factory, private val batteryMeterViewControllerFactory: BatteryMeterViewController.Factory, Loading @@ -96,10 +71,10 @@ constructor( ) { val viewModel = rememberViewModel("QuickSettingsShadeScene") { contentViewModelFactory.create() } OverlayShade( viewModelFactory = viewModel.overlayShadeViewModelFactory, lockscreenContent = lockscreenContent, modifier = modifier, onScrimClicked = {}, ) { Column { ExpandedShadeHeader( Loading @@ -117,68 +92,3 @@ constructor( } } } @Composable fun ShadeBody( viewModel: QuickSettingsContainerViewModel, ) { val isEditing by viewModel.editModeViewModel.isEditing.collectAsStateWithLifecycle() AnimatedContent( targetState = isEditing, transitionSpec = { QuickSettingsLayoutEnter togetherWith QuickSettingsLayoutExit } ) { editing -> if (editing) { EditMode( viewModel = viewModel.editModeViewModel, modifier = Modifier.fillMaxWidth().padding(QuickSettingsShade.Dimensions.Padding) ) } else { QuickSettingsLayout( viewModel = viewModel, modifier = Modifier.sysuiResTag("quick_settings_panel") ) } } } @Composable private fun QuickSettingsLayout( viewModel: QuickSettingsContainerViewModel, modifier: Modifier = Modifier, ) { Column( verticalArrangement = Arrangement.spacedBy(QuickSettingsShade.Dimensions.Padding), horizontalAlignment = Alignment.CenterHorizontally, modifier = modifier.fillMaxWidth().padding(QuickSettingsShade.Dimensions.Padding), ) { BrightnessSliderContainer( viewModel = viewModel.brightnessSliderViewModel, modifier = Modifier.fillMaxWidth() .height(QuickSettingsShade.Dimensions.BrightnessSliderHeight), ) TileGrid( viewModel = viewModel.tileGridViewModel, modifier = Modifier.fillMaxWidth().heightIn(max = QuickSettingsShade.Dimensions.GridMaxHeight), viewModel.editModeViewModel::startEditing, ) } } object QuickSettingsShade { object Dimensions { val Padding = 16.dp val BrightnessSliderHeight = 64.dp val GridMaxHeight = 800.dp } object Transitions { val QuickSettingsLayoutEnter: EnterTransition = fadeIn(tween(500)) val QuickSettingsLayoutExit: ExitTransition = fadeOut(tween(500)) val QuickSettingsEditorEnter: EnterTransition = fadeIn(tween(500)) val QuickSettingsEditorExit: ExitTransition = fadeOut(tween(500)) } }
packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/OverlayShade.kt +4 −24 Original line number Diff line number Diff line Loading @@ -40,46 +40,26 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass import androidx.compose.runtime.Composable import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.animation.scene.ElementKey import com.android.compose.animation.scene.LowestZIndexContentPicker import com.android.compose.animation.scene.SceneScope import com.android.compose.windowsizeclass.LocalWindowSizeClass import com.android.systemui.keyguard.ui.composable.LockscreenContent import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.shade.ui.viewmodel.OverlayShadeViewModel import com.android.systemui.util.kotlin.getOrNull import dagger.Lazy import java.util.Optional /** The overlay shade renders a lightweight shade UI container on top of a background scene. */ /** Renders a lightweight shade UI container, as an overlay. */ @Composable fun SceneScope.OverlayShade( viewModelFactory: OverlayShadeViewModel.Factory, lockscreenContent: Lazy<Optional<LockscreenContent>>, onScrimClicked: () -> Unit, modifier: Modifier = Modifier, content: @Composable () -> Unit, ) { val viewModel = rememberViewModel("OverlayShade") { viewModelFactory.create() } val backgroundScene by viewModel.backgroundScene.collectAsStateWithLifecycle() Box(modifier) { if (backgroundScene == Scenes.Lockscreen) { // Lockscreen content is optionally injected, because variants of System UI without a // lockscreen cannot provide it. val lockscreenContentOrNull = lockscreenContent.get().getOrNull() lockscreenContentOrNull?.apply { Content(Modifier.fillMaxSize()) } } Scrim(onClicked = viewModel::onScrimClicked) Scrim(onClicked = onScrimClicked) Box( modifier = Modifier.fillMaxSize().panelPadding(), Loading