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

Commit 5020a6ff authored by Fabian Kozynski's avatar Fabian Kozynski Committed by Android (Google) Code Review
Browse files

Merge changes Ie66b64b0,I55c0edf2 into main

* changes:
  Use approachLayout for squishiness
  Properly animate second page collapse
parents 6049f564 9fdd961e
Loading
Loading
Loading
Loading
+27 −3
Original line number Diff line number Diff line
@@ -52,8 +52,8 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.approachLayout
import androidx.compose.ui.layout.onPlaced
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.layout.positionInRoot
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.dimensionResource
@@ -66,6 +66,9 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.android.compose.animation.scene.ContentKey
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.ElementMatcher
import com.android.compose.animation.scene.MutableSceneTransitionLayoutState
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.SceneScope
@@ -288,7 +291,7 @@ constructor(
                transitions =
                    transitions {
                        from(QuickQuickSettings, QuickSettings) {
                            quickQuickSettingsToQuickSettings()
                            quickQuickSettingsToQuickSettings(viewModel::inFirstPage::get)
                        }
                    },
            )
@@ -533,6 +536,10 @@ constructor(

            onDispose { qqsVisible.value = false }
        }
        val squishiness by
            viewModel.containerViewModel.quickQuickSettingsViewModel.squishinessViewModel
                .squishiness
                .collectAsStateWithLifecycle()
        Column(modifier = Modifier.sysuiResTag("quick_qs_panel")) {
            Box(
                modifier =
@@ -546,7 +553,16 @@ constructor(
                                topFromRoot + coordinates.size.height,
                            )
                        }
                        .onSizeChanged { size -> qqsHeight.value = size.height }
                        // Use an approach layout to determien the height without squishiness, as
                        // that's the value that NPVC and QuickSettingsController care about
                        // (measured height).
                        .approachLayout(isMeasurementApproachInProgress = { squishiness < 1f }) {
                            measurable,
                            constraints ->
                            qqsHeight.value = lookaheadSize.height
                            val placeable = measurable.measure(constraints)
                            layout(placeable.width, placeable.height) { placeable.place(0, 0) }
                        }
                        .padding(top = { qqsPadding }, bottom = { bottomPadding.roundToPx() })
            ) {
                val qsEnabled by viewModel.qsEnabled.collectAsStateWithLifecycle()
@@ -704,6 +720,14 @@ object SceneKeys {
            else -> QuickSettings
        }
    }

    val QqsTileElementMatcher =
        object : ElementMatcher {
            override fun matches(key: ElementKey, content: ContentKey): Boolean {
                return content == SceneKeys.QuickQuickSettings &&
                    ElementKeys.TileElementMatcher.matches(key, content)
            }
        }
}

suspend fun synchronizeQsState(state: MutableSceneTransitionLayoutState, expansion: Flow<Float>) {
+11 −1
Original line number Diff line number Diff line
@@ -17,13 +17,23 @@
package com.android.systemui.qs.composefragment.ui

import com.android.compose.animation.scene.TransitionBuilder
import com.android.systemui.qs.composefragment.SceneKeys
import com.android.systemui.qs.shared.ui.ElementKeys

fun TransitionBuilder.quickQuickSettingsToQuickSettings() {
fun TransitionBuilder.quickQuickSettingsToQuickSettings(inFirstPage: () -> Boolean = { true }) {

    fractionRange(start = 0.5f) { fade(ElementKeys.QuickSettingsContent) }

    fractionRange(start = 0.9f) { fade(ElementKeys.FooterActions) }

    anchoredTranslate(ElementKeys.QuickSettingsContent, ElementKeys.GridAnchor)

    sharedElement(ElementKeys.TileElementMatcher, enabled = inFirstPage())

    // This will animate between 0f (QQS) and 0.6, fading in the QQS tiles when coming back
    // from non first page QS. The QS content ends fading out at 0.5f, so there's a brief
    // overlap, but because they are really faint, it looks better than complete black without
    // overlap.
    fractionRange(end = 0.6f) { fade(SceneKeys.QqsTileElementMatcher) }
    anchoredTranslate(SceneKeys.QqsTileElementMatcher, ElementKeys.GridAnchor)
}
+5 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import com.android.systemui.qs.FooterActionsController
import com.android.systemui.qs.composefragment.viewmodel.QSFragmentComposeViewModel.QSExpansionState
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
import com.android.systemui.qs.panels.domain.interactor.TileSquishinessInteractor
import com.android.systemui.qs.panels.ui.viewmodel.PaginatedGridViewModel
import com.android.systemui.qs.ui.viewmodel.QuickSettingsContainerViewModel
import com.android.systemui.shade.LargeScreenHeaderHelper
import com.android.systemui.shade.transition.LargeScreenShadeInterpolator
@@ -71,6 +72,7 @@ constructor(
    private val configurationInteractor: ConfigurationInteractor,
    private val largeScreenHeaderHelper: LargeScreenHeaderHelper,
    private val squishinessInteractor: TileSquishinessInteractor,
    private val paginatedGridViewModel: PaginatedGridViewModel,
    @Assisted private val lifecycleScope: LifecycleCoroutineScope,
) : Dumpable, ExclusiveActivatable() {
    val footerActionsViewModel =
@@ -292,6 +294,9 @@ constructor(
     */
    var collapseExpandAccessibilityAction: Runnable? = null

    val inFirstPage: Boolean
        get() = paginatedGridViewModel.inFirstPage

    override suspend fun onActivated(): Nothing {
        hydrateSquishinessInteractor()
    }
+7 −0
Original line number Diff line number Diff line
@@ -31,8 +31,10 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@@ -76,6 +78,11 @@ constructor(

        val pagerState = rememberPagerState(0) { pages.size }

        // Used to track if this is currently in the first page or not, for animations
        LaunchedEffect(key1 = pagerState) {
            snapshotFlow { pagerState.currentPage == 0 }.collect { viewModel.inFirstPage = it }
        }

        Column {
            HorizontalPager(
                state = pagerState,
+14 −9
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@
package com.android.systemui.qs.panels.ui.compose.infinitegrid

import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.layout
import androidx.compose.ui.layout.approachLayout
import kotlin.math.roundToInt

/**
@@ -27,17 +27,22 @@ import kotlin.math.roundToInt
 * [squishiness] on the measure/layout pass.
 *
 * The squished composable will be center aligned.
 *
 * Use an [approachLayout] to indicate that this should be measured in the lookahead step without
 * using squishiness. If a parent of this node needs to determine unsquished height, they should
 * also use an approachLayout tracking the squishiness.
 */
fun Modifier.verticalSquish(squishiness: () -> Float): Modifier {
    return layout { measurable, constraints ->
        val placeable = measurable.measure(constraints)
        val actualHeight = placeable.height
        val squishedHeight = actualHeight * squishiness()
    return approachLayout(isMeasurementApproachInProgress = { squishiness() < 1 }) { measurable, _
        ->
        val squishinessValue = squishiness()
        val expectedHeight = lookaheadSize.height

        val placeable = measurable.measure(lookaheadConstraints)
        val squishedHeight = (expectedHeight * squishinessValue).roundToInt()
        // Center the content by moving it UP (squishedHeight < actualHeight)
        val scroll = (squishedHeight - actualHeight) / 2
        val scroll = (squishedHeight - expectedHeight) / 2

        layout(placeable.width, squishedHeight.roundToInt()) {
            placeable.place(0, scroll.roundToInt())
        }
        layout(placeable.width, squishedHeight) { placeable.place(0, scroll) }
    }
}
Loading