Loading packages/SystemUI/compose/features/src/com/android/systemui/ribbon/ui/composable/Ribbon.kt +25 −1 Original line number Diff line number Diff line Loading @@ -20,8 +20,12 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawWithCache import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.ColorMatrix import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.layer.drawLayer import androidx.compose.ui.layout.layout import com.android.compose.modifiers.thenIf import kotlin.math.PI Loading @@ -39,6 +43,9 @@ import kotlin.math.tan * The background color of the strip can be modified by passing a value to the [backgroundColor] or * `null` to remove the strip background. * * The [colorSaturation] is a function that returns that amount of color saturation to apply to the * entire ribbon. If it's `1`, the full color will be used, if it's `0` it will be greyscale. * * Note: this function assumes that it's been placed at the bottom right of its parent by its * caller. It's the caller's responsibility to meet that assumption by actually placing this * composable element at the bottom right. Loading @@ -49,6 +56,7 @@ fun BottomRightCornerRibbon( modifier: Modifier = Modifier, degrees: Int = 45, alpha: Float = 0.6f, colorSaturation: () -> Float = { 1f }, backgroundColor: Color? = Color.Red, ) { check(degrees in 1..89) Loading @@ -73,6 +81,22 @@ fun BottomRightCornerRibbon( translationY = (h - w * sine + h * cosine) / 2f rotationZ = 360f - degrees } .drawWithCache { val layer = obtainGraphicsLayer().apply { record { colorFilter = ColorFilter.colorMatrix( colorMatrix = ColorMatrix().apply { setToSaturation(colorSaturation()) } ) drawContent() } } onDrawWithContent { drawLayer(layer) } } .thenIf(backgroundColor != null) { Modifier.background(backgroundColor!!) } .layout { measurable, constraints -> val placeable = measurable.measure(constraints) Loading @@ -87,6 +111,6 @@ fun BottomRightCornerRibbon( ) { placeable.place(leftPadding, 0) } } }, ) } packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt +1 −0 Original line number Diff line number Diff line Loading @@ -232,6 +232,7 @@ fun SceneContainer( BottomRightCornerRibbon( content = { Text(text = "flexi\uD83E\uDD43", color = Color.White) }, colorSaturation = { viewModel.ribbonColorSaturation }, modifier = Modifier.align(Alignment.BottomEnd), ) } Loading packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt +10 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult import com.android.systemui.classifier.Classifier import com.android.systemui.classifier.domain.interactor.FalsingInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.Hydrator Loading Loading @@ -66,6 +67,7 @@ constructor( hapticsViewModelFactory: SceneContainerHapticsViewModel.Factory, val lightRevealScrim: LightRevealScrimViewModel, val wallpaperViewModel: WallpaperViewModel, keyguardInteractor: KeyguardInteractor, @Assisted view: View, @Assisted private val motionEventHandlerReceiver: (MotionEventHandler?) -> Unit, ) : ExclusiveActivatable() { Loading Loading @@ -96,6 +98,14 @@ constructor( }, ) /** Amount of color saturation for the Flexi🥃 ribbon. */ val ribbonColorSaturation: Float by hydrator.hydratedStateOf( traceName = "ribbonColorSaturation", source = keyguardInteractor.dozeAmount.map { 1 - it }, initialValue = 1f, ) override suspend fun onActivated(): Nothing { try { // Sends a MotionEventHandler to the owner of the view-model so they can report Loading packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneKosmos.kt +2 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import android.view.View import com.android.compose.animation.scene.ObservableTransitionState import com.android.systemui.classifier.domain.interactor.falsingInteractor import com.android.systemui.haptics.msdl.msdlPlayer import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.ui.viewmodel.lightRevealScrimViewModel import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture Loading Loading @@ -100,6 +101,7 @@ val Kosmos.sceneContainerViewModelFactory by Fixture { motionEventHandlerReceiver = motionEventHandlerReceiver, lightRevealScrim = lightRevealScrimViewModel, wallpaperViewModel = wallpaperViewModel, keyguardInteractor = keyguardInteractor, ) } } Loading Loading
packages/SystemUI/compose/features/src/com/android/systemui/ribbon/ui/composable/Ribbon.kt +25 −1 Original line number Diff line number Diff line Loading @@ -20,8 +20,12 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawWithCache import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.ColorMatrix import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.layer.drawLayer import androidx.compose.ui.layout.layout import com.android.compose.modifiers.thenIf import kotlin.math.PI Loading @@ -39,6 +43,9 @@ import kotlin.math.tan * The background color of the strip can be modified by passing a value to the [backgroundColor] or * `null` to remove the strip background. * * The [colorSaturation] is a function that returns that amount of color saturation to apply to the * entire ribbon. If it's `1`, the full color will be used, if it's `0` it will be greyscale. * * Note: this function assumes that it's been placed at the bottom right of its parent by its * caller. It's the caller's responsibility to meet that assumption by actually placing this * composable element at the bottom right. Loading @@ -49,6 +56,7 @@ fun BottomRightCornerRibbon( modifier: Modifier = Modifier, degrees: Int = 45, alpha: Float = 0.6f, colorSaturation: () -> Float = { 1f }, backgroundColor: Color? = Color.Red, ) { check(degrees in 1..89) Loading @@ -73,6 +81,22 @@ fun BottomRightCornerRibbon( translationY = (h - w * sine + h * cosine) / 2f rotationZ = 360f - degrees } .drawWithCache { val layer = obtainGraphicsLayer().apply { record { colorFilter = ColorFilter.colorMatrix( colorMatrix = ColorMatrix().apply { setToSaturation(colorSaturation()) } ) drawContent() } } onDrawWithContent { drawLayer(layer) } } .thenIf(backgroundColor != null) { Modifier.background(backgroundColor!!) } .layout { measurable, constraints -> val placeable = measurable.measure(constraints) Loading @@ -87,6 +111,6 @@ fun BottomRightCornerRibbon( ) { placeable.place(leftPadding, 0) } } }, ) }
packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt +1 −0 Original line number Diff line number Diff line Loading @@ -232,6 +232,7 @@ fun SceneContainer( BottomRightCornerRibbon( content = { Text(text = "flexi\uD83E\uDD43", color = Color.White) }, colorSaturation = { viewModel.ribbonColorSaturation }, modifier = Modifier.align(Alignment.BottomEnd), ) } Loading
packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt +10 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult import com.android.systemui.classifier.Classifier import com.android.systemui.classifier.domain.interactor.FalsingInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.Hydrator Loading Loading @@ -66,6 +67,7 @@ constructor( hapticsViewModelFactory: SceneContainerHapticsViewModel.Factory, val lightRevealScrim: LightRevealScrimViewModel, val wallpaperViewModel: WallpaperViewModel, keyguardInteractor: KeyguardInteractor, @Assisted view: View, @Assisted private val motionEventHandlerReceiver: (MotionEventHandler?) -> Unit, ) : ExclusiveActivatable() { Loading Loading @@ -96,6 +98,14 @@ constructor( }, ) /** Amount of color saturation for the Flexi🥃 ribbon. */ val ribbonColorSaturation: Float by hydrator.hydratedStateOf( traceName = "ribbonColorSaturation", source = keyguardInteractor.dozeAmount.map { 1 - it }, initialValue = 1f, ) override suspend fun onActivated(): Nothing { try { // Sends a MotionEventHandler to the owner of the view-model so they can report Loading
packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneKosmos.kt +2 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import android.view.View import com.android.compose.animation.scene.ObservableTransitionState import com.android.systemui.classifier.domain.interactor.falsingInteractor import com.android.systemui.haptics.msdl.msdlPlayer import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.ui.viewmodel.lightRevealScrimViewModel import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture Loading Loading @@ -100,6 +101,7 @@ val Kosmos.sceneContainerViewModelFactory by Fixture { motionEventHandlerReceiver = motionEventHandlerReceiver, lightRevealScrim = lightRevealScrimViewModel, wallpaperViewModel = wallpaperViewModel, keyguardInteractor = keyguardInteractor, ) } } Loading