Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d341f29 authored by Alejandro Nijamkin's avatar Alejandro Nijamkin
Browse files

[flexiglass] Bouncer scene adaptive layout improvements.

1. Better breakdown into "layout" and "area" functions.
2. Broke down the dependency on "StandardLayout" where all layouts
   eventually called "StandardLayout". Now each layout arranges its own
   "area" element functions directly.
3. Cleaned up foldability functionality, which is still used by both
   "standard" and "beside user switcher" layouts.
4. Better naming sceheme for layouts: "stacked" renamed to "below user
   switcher" and "side-by-side" renamed to "beside user switcher".

Bug: 300677757
Test: manually verified on 4 physical devices: phone, foldables, taller
foldable, and tablet.
Flag: ACONFIG com.android.systemui.scene_container DEVELOPMENT

Change-Id: I4d21f7acf0acef64bad335ff2d045753a66ed7d0
parent 42f9b0d5
Loading
Loading
Loading
Loading
+505 −443

File changed.

Preview size limit exceeded, changes collapsed.

+2 −2
Original line number Diff line number Diff line
@@ -26,8 +26,8 @@ import com.android.systemui.bouncer.ui.helper.calculateLayoutInternal

/**
 * Returns the [BouncerSceneLayout] that should be used by the bouncer scene. If
 * [isSideBySideSupported] is `false`, then [BouncerSceneLayout.SIDE_BY_SIDE] is replaced by
 * [BouncerSceneLayout.STANDARD].
 * [isSideBySideSupported] is `false`, then [BouncerSceneLayout.BESIDE_USER_SWITCHER] is replaced by
 * [BouncerSceneLayout.STANDARD_BOUNCER].
 */
@Composable
fun calculateLayout(
+31 −37
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.systemui.bouncer.ui.composable

import android.view.ViewTreeObserver
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.LocalTextStyle
@@ -31,7 +30,6 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.focus.FocusRequester
@@ -81,10 +79,6 @@ internal fun PasswordBouncer(
        }
    }

    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = modifier,
    ) {
    val color = MaterialTheme.colorScheme.onSurfaceVariant
    val lineWidthPx = with(LocalDensity.current) { 2.dp.toPx() }

@@ -105,7 +99,8 @@ internal fun PasswordBouncer(
                onDone = { viewModel.onAuthenticateKeyPressed() },
            ),
        modifier =
                Modifier.focusRequester(focusRequester)
            modifier
                .focusRequester(focusRequester)
                .onFocusChanged { viewModel.onTextFieldFocusChanged(it.isFocused) }
                .drawBehind {
                    drawLine(
@@ -117,7 +112,6 @@ internal fun PasswordBouncer(
                },
    )
}
}

/** Returns a [State] with `true` when the IME/keyboard is visible and `false` when it's not. */
@Composable
+15 −7
Original line number Diff line number Diff line
@@ -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.height
import androidx.compose.foundation.layout.width
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
@@ -48,7 +50,6 @@ import androidx.compose.ui.unit.dp
import com.android.compose.animation.Easings
import com.android.compose.modifiers.thenIf
import com.android.internal.R
import com.android.systemui.bouncer.ui.helper.BouncerSceneLayout
import com.android.systemui.bouncer.ui.viewmodel.PatternBouncerViewModel
import com.android.systemui.bouncer.ui.viewmodel.PatternDotViewModel
import kotlin.math.min
@@ -61,11 +62,14 @@ import kotlinx.coroutines.launch
 * UI for the input part of a pattern-requiring version of the bouncer.
 *
 * The user can press, hold, and drag their pointer to select dots along a grid of dots.
 *
 * If [centerDotsVertically] is `true`, the dots should be centered along the axis of interest; if
 * `false`, the dots will be pushed towards the end/bottom of the axis.
 */
@Composable
internal fun PatternBouncer(
    viewModel: PatternBouncerViewModel,
    layout: BouncerSceneLayout,
    centerDotsVertically: Boolean,
    modifier: Modifier = Modifier,
) {
    DisposableEffect(Unit) {
@@ -197,6 +201,14 @@ internal fun PatternBouncer(

    Canvas(
        modifier
            // 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
            // 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()
@@ -260,7 +272,7 @@ internal fun PatternBouncer(
                    availableSize = containerSize.height,
                    spacingPerDot = spacing,
                    dotCount = rowCount,
                    isCentered = layout.isCenteredVertically,
                    isCentered = centerDotsVertically,
                )
            offset = Offset(horizontalOffset, verticalOffset)
            scale = (colCount * spacing) / containerSize.width
@@ -423,10 +435,6 @@ private fun offset(
    }
}

/** Whether the UI should be centered vertically. */
private val BouncerSceneLayout.isCenteredVertically: Boolean
    get() = this == BouncerSceneLayout.SPLIT

private const val DOT_DIAMETER_DP = 16
private const val SELECTED_DOT_DIAMETER_DP = 24
private const val SELECTED_DOT_REACTION_ANIMATION_DURATION_MS = 83
+3 −12
Original line number Diff line number Diff line
@@ -52,7 +52,6 @@ import androidx.compose.ui.unit.dp
import com.android.compose.animation.Easings
import com.android.compose.grid.VerticalGrid
import com.android.compose.modifiers.thenIf
import com.android.systemui.bouncer.ui.helper.BouncerSceneLayout
import com.android.systemui.bouncer.ui.viewmodel.ActionButtonAppearance
import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel
import com.android.systemui.common.shared.model.ContentDescription
@@ -70,7 +69,7 @@ import kotlinx.coroutines.launch
@Composable
fun PinPad(
    viewModel: PinBouncerViewModel,
    layout: BouncerSceneLayout,
    verticalSpacing: Dp,
    modifier: Modifier = Modifier,
) {
    DisposableEffect(Unit) {
@@ -96,8 +95,8 @@ fun PinPad(

    VerticalGrid(
        columns = columns,
        verticalSpacing = layout.verticalSpacing,
        horizontalSpacing = calculateHorizontalSpacingBetweenColumns(layout.gridWidth),
        verticalSpacing = verticalSpacing,
        horizontalSpacing = calculateHorizontalSpacingBetweenColumns(gridWidth = 300.dp),
        modifier = modifier,
    ) {
        repeat(9) { index ->
@@ -355,14 +354,6 @@ private fun calculateHorizontalSpacingBetweenColumns(
    return (gridWidth - (pinButtonMaxSize * columns)) / (columns - 1)
}

/** The width of the grid of PIN pad buttons, in dips. */
private val BouncerSceneLayout.gridWidth: Dp
    get() = if (isUseCompactSize) 292.dp else 300.dp

/** The spacing between rows of PIN pad buttons, in dips. */
private val BouncerSceneLayout.verticalSpacing: Dp
    get() = if (isUseCompactSize) 8.dp else 12.dp

/** Number of columns in the PIN pad grid. */
private const val columns = 3
/** Maximum size (width and height) of each PIN pad button. */
Loading