Loading packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt +1 −1 Original line number Diff line number Diff line Loading @@ -168,7 +168,7 @@ private fun StandardLayout(viewModel: BouncerSceneContentViewModel, modifier: Mo LocalWindowSizeClass.current.heightSizeClass == WindowHeightSizeClass.Expanded FoldAware( modifier = modifier.padding(start = 32.dp, top = 92.dp, end = 32.dp, bottom = 48.dp), modifier = modifier.padding(top = 92.dp, bottom = 48.dp), viewModel = viewModel, aboveFold = { Column( Loading packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt +128 −100 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import androidx.compose.foundation.Canvas import androidx.compose.foundation.gestures.awaitEachGesture import androidx.compose.foundation.gestures.awaitFirstDown import androidx.compose.foundation.gestures.detectDragGestures import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.width import androidx.compose.material3.MaterialTheme Loading @@ -35,6 +37,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clipToBounds import androidx.compose.ui.geometry.Offset Loading @@ -45,6 +48,7 @@ import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalView import androidx.compose.ui.res.integerResource import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.animation.Easings Loading Loading @@ -212,23 +216,27 @@ fun PatternBouncer( var gridCoordinates: LayoutCoordinates? by remember { mutableStateOf(null) } var offset: Offset by remember { mutableStateOf(Offset.Zero) } var scale: Float by remember { mutableStateOf(1f) } Canvas( modifier .sysuiResTag("bouncer_pattern_root") // This is the size of the drawing area, in dips. val dotDrawingArea = remember(colCount, rowCount) { DpSize( // Because the width also includes spacing to the left and right of the leftmost and // rightmost dots in the grid and because UX mocks specify the width without that // spacing, the actual width needs to be defined slightly bigger than the UX mock width. .width((262 * colCount / 2).dp) // Because the height also includes spacing above and below the topmost and bottommost // dots in the grid and because UX mocks specify the height without that spacing, the // spacing, the actual width needs to be defined slightly bigger than the UX mock // width. width = (262 * colCount / 2).dp, // Because the height also includes spacing above and below the topmost and // bottommost // dots in the grid and because UX mocks specify the height without that spacing, // the // actual height needs to be defined slightly bigger than the UX mock height. .height((262 * rowCount / 2).dp) // Need to clip to bounds to make sure that the lines don't follow the input pointer // when it leaves the bounds of the dot grid. .clipToBounds() .onGloballyPositioned { coordinates -> gridCoordinates = coordinates } .thenIf(isInputEnabled) { height = (262 * rowCount / 2).dp, ) } Box( modifier = modifier.fillMaxWidth().thenIf(isInputEnabled) { Modifier.pointerInput(Unit) { awaitEachGesture { awaitFirstDown() Loading Loading @@ -257,14 +265,26 @@ fun PatternBouncer( inputPosition = change.position change.position.minus(offset).div(scale).let { viewModel.onDrag( xPx = it.x, xPx = it.x - ((size.width - dotDrawingArea.width.roundToPx()) / 2), yPx = it.y, containerSizePx = size.width, containerSizePx = dotDrawingArea.width.roundToPx(), ) } } } } ) { Canvas( Modifier.sysuiResTag("bouncer_pattern_root") .width(dotDrawingArea.width) .height(dotDrawingArea.height) // Need to clip to bounds to make sure that the lines don't follow the input pointer // when it leaves the bounds of the dot grid. .clipToBounds() .align(Alignment.Center) .onGloballyPositioned { coordinates -> gridCoordinates = coordinates } .motionTestValues { entryAnimationCompleted exportAs entryCompleted dotAppearFadeInAnimatables.map { it.value.value } exportAs dotAppearFadeIn Loading Loading @@ -351,15 +371,23 @@ fun PatternBouncer( (1 - checkNotNull(dotAppearMoveUpAnimatables[dot]).value) * initialOffset drawCircle( center = pixelOffset(dot, spacing, horizontalOffset, verticalOffset + appearOffset), pixelOffset( dot, spacing, horizontalOffset, verticalOffset + appearOffset, ), color = dotColor.copy(alpha = checkNotNull(dotAppearFadeInAnimatables[dot]).value), dotColor.copy( alpha = checkNotNull(dotAppearFadeInAnimatables[dot]).value ), radius = dotRadius * checkNotNull(dotScalingAnimatables[dot]).value, ) } } } } } private suspend fun showEntryAnimation( dotAppearFadeInAnimatables: Map<PatternDotViewModel, Animatable<Float, AnimationVector1D>>, Loading Loading
packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt +1 −1 Original line number Diff line number Diff line Loading @@ -168,7 +168,7 @@ private fun StandardLayout(viewModel: BouncerSceneContentViewModel, modifier: Mo LocalWindowSizeClass.current.heightSizeClass == WindowHeightSizeClass.Expanded FoldAware( modifier = modifier.padding(start = 32.dp, top = 92.dp, end = 32.dp, bottom = 48.dp), modifier = modifier.padding(top = 92.dp, bottom = 48.dp), viewModel = viewModel, aboveFold = { Column( Loading
packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt +128 −100 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import androidx.compose.foundation.Canvas import androidx.compose.foundation.gestures.awaitEachGesture import androidx.compose.foundation.gestures.awaitFirstDown import androidx.compose.foundation.gestures.detectDragGestures import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.width import androidx.compose.material3.MaterialTheme Loading @@ -35,6 +37,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clipToBounds import androidx.compose.ui.geometry.Offset Loading @@ -45,6 +48,7 @@ import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalView import androidx.compose.ui.res.integerResource import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.animation.Easings Loading Loading @@ -212,23 +216,27 @@ fun PatternBouncer( var gridCoordinates: LayoutCoordinates? by remember { mutableStateOf(null) } var offset: Offset by remember { mutableStateOf(Offset.Zero) } var scale: Float by remember { mutableStateOf(1f) } Canvas( modifier .sysuiResTag("bouncer_pattern_root") // This is the size of the drawing area, in dips. val dotDrawingArea = remember(colCount, rowCount) { DpSize( // Because the width also includes spacing to the left and right of the leftmost and // rightmost dots in the grid and because UX mocks specify the width without that // spacing, the actual width needs to be defined slightly bigger than the UX mock width. .width((262 * colCount / 2).dp) // Because the height also includes spacing above and below the topmost and bottommost // dots in the grid and because UX mocks specify the height without that spacing, the // spacing, the actual width needs to be defined slightly bigger than the UX mock // width. width = (262 * colCount / 2).dp, // Because the height also includes spacing above and below the topmost and // bottommost // dots in the grid and because UX mocks specify the height without that spacing, // the // actual height needs to be defined slightly bigger than the UX mock height. .height((262 * rowCount / 2).dp) // Need to clip to bounds to make sure that the lines don't follow the input pointer // when it leaves the bounds of the dot grid. .clipToBounds() .onGloballyPositioned { coordinates -> gridCoordinates = coordinates } .thenIf(isInputEnabled) { height = (262 * rowCount / 2).dp, ) } Box( modifier = modifier.fillMaxWidth().thenIf(isInputEnabled) { Modifier.pointerInput(Unit) { awaitEachGesture { awaitFirstDown() Loading Loading @@ -257,14 +265,26 @@ fun PatternBouncer( inputPosition = change.position change.position.minus(offset).div(scale).let { viewModel.onDrag( xPx = it.x, xPx = it.x - ((size.width - dotDrawingArea.width.roundToPx()) / 2), yPx = it.y, containerSizePx = size.width, containerSizePx = dotDrawingArea.width.roundToPx(), ) } } } } ) { Canvas( Modifier.sysuiResTag("bouncer_pattern_root") .width(dotDrawingArea.width) .height(dotDrawingArea.height) // Need to clip to bounds to make sure that the lines don't follow the input pointer // when it leaves the bounds of the dot grid. .clipToBounds() .align(Alignment.Center) .onGloballyPositioned { coordinates -> gridCoordinates = coordinates } .motionTestValues { entryAnimationCompleted exportAs entryCompleted dotAppearFadeInAnimatables.map { it.value.value } exportAs dotAppearFadeIn Loading Loading @@ -351,15 +371,23 @@ fun PatternBouncer( (1 - checkNotNull(dotAppearMoveUpAnimatables[dot]).value) * initialOffset drawCircle( center = pixelOffset(dot, spacing, horizontalOffset, verticalOffset + appearOffset), pixelOffset( dot, spacing, horizontalOffset, verticalOffset + appearOffset, ), color = dotColor.copy(alpha = checkNotNull(dotAppearFadeInAnimatables[dot]).value), dotColor.copy( alpha = checkNotNull(dotAppearFadeInAnimatables[dot]).value ), radius = dotRadius * checkNotNull(dotScalingAnimatables[dot]).value, ) } } } } } private suspend fun showEntryAnimation( dotAppearFadeInAnimatables: Map<PatternDotViewModel, Animatable<Float, AnimationVector1D>>, Loading