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

Commit 3a08e285 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "STL NestedScrollHandler uses the current Content" into main

parents 589f1f09 0f6fd445
Loading
Loading
Loading
Loading
+6 −35
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.round
import androidx.compose.ui.util.fastCoerceIn
import com.android.compose.animation.scene.content.Content
import com.android.compose.animation.scene.content.state.TransitionState
import com.android.compose.animation.scene.content.state.TransitionState.HasOverscrollProperties.Companion.DistanceUnspecified
import com.android.compose.nestedscroll.OnStopScope
import com.android.compose.nestedscroll.PriorityNestedScrollConnection
@@ -543,19 +542,6 @@ internal class NestedScrollHandlerImpl(

    val connection: PriorityNestedScrollConnection = nestedScrollConnection()

    private fun resolveSwipe(
        isUpOrLeft: Boolean,
        pointersDown: PointersInfo.PointersDown?,
    ): Swipe.Resolved {
        return resolveSwipe(
            orientation = draggableHandler.orientation,
            isUpOrLeft = isUpOrLeft,
            pointersDown = pointersDown,
            fromSource =
                pointersDown?.let { draggableHandler.resolveSwipeSource(it.startedPosition) },
        )
    }

    private fun nestedScrollConnection(): PriorityNestedScrollConnection {
        // If we performed a long gesture before entering priority mode, we would have to avoid
        // moving on to the next scene.
@@ -563,23 +549,8 @@ internal class NestedScrollHandlerImpl(

        var lastPointersDown: PointersInfo.PointersDown? = null

        fun hasNextScene(amount: Float): Boolean {
            val transitionState = layoutState.transitionState
            val scene = transitionState.currentScene
            val fromScene = layoutImpl.scene(scene)
            val resolvedSwipe =
                when {
                    amount < 0f -> resolveSwipe(isUpOrLeft = true, lastPointersDown)
                    amount > 0f -> resolveSwipe(isUpOrLeft = false, lastPointersDown)
                    else -> null
                }
            val nextScene = resolvedSwipe?.let { fromScene.findActionResultBestMatch(it) }
            if (nextScene != null) return true

            if (transitionState !is TransitionState.Idle) return false

            val overscrollSpec = layoutImpl.state.transitions.overscrollSpec(scene, orientation)
            return overscrollSpec != null
        fun shouldEnableSwipes(): Boolean {
            return layoutImpl.contentForUserActions().shouldEnableSwipes(orientation)
        }

        var isIntercepting = false
@@ -650,17 +621,17 @@ internal class NestedScrollHandlerImpl(
                    when (behavior) {
                        NestedScrollBehavior.EdgeNoPreview -> {
                            canChangeScene = isZeroOffset
                            isZeroOffset && hasNextScene(offsetAvailable)
                            isZeroOffset && shouldEnableSwipes()
                        }

                        NestedScrollBehavior.EdgeWithPreview -> {
                            canChangeScene = isZeroOffset
                            hasNextScene(offsetAvailable)
                            shouldEnableSwipes()
                        }

                        NestedScrollBehavior.EdgeAlways -> {
                            canChangeScene = true
                            hasNextScene(offsetAvailable)
                            shouldEnableSwipes()
                        }
                    }

@@ -693,7 +664,7 @@ internal class NestedScrollHandlerImpl(
                    }
                lastPointersDown = pointersDown

                val canStart = behavior.canStartOnPostFling && hasNextScene(velocityAvailable)
                val canStart = behavior.canStartOnPostFling && shouldEnableSwipes()
                if (canStart) {
                    isIntercepting = false
                }
+1 −1
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ private fun DraggableHandlerImpl.contentForSwipes(): Content {
}

/** Whether swipe should be enabled in the given [orientation]. */
private fun Content.shouldEnableSwipes(orientation: Orientation): Boolean {
internal fun Content.shouldEnableSwipes(orientation: Orientation): Boolean {
    if (userActions.isEmpty()) {
        return false
    }
+29 −0
Original line number Diff line number Diff line
@@ -1676,4 +1676,33 @@ class DraggableHandlerTest {
        assertThat(layoutState.transitionState).hasCurrentScene(SceneA)
        assertThat(layoutState.transitionState).hasCurrentOverlays(OverlayB)
    }

    @Test
    fun replaceOverlayNestedScroll() = runGestureTest {
        layoutState.showOverlay(OverlayA, animationScope = testScope)
        advanceUntilIdle()

        // Initial state.
        assertThat(layoutState.transitionState).isIdle()
        assertThat(layoutState.transitionState).hasCurrentScene(SceneA)
        assertThat(layoutState.transitionState).hasCurrentOverlays(OverlayA)

        // Swipe down to replace overlay A by overlay B.

        val nestedScroll = nestedScrollConnection(nestedScrollBehavior = EdgeWithPreview)
        nestedScroll.scroll(downOffset(0.1f))
        val transition = assertThat(layoutState.transitionState).isReplaceOverlayTransition()
        assertThat(transition).hasCurrentScene(SceneA)
        assertThat(transition).hasFromOverlay(OverlayA)
        assertThat(transition).hasToOverlay(OverlayB)
        assertThat(transition).hasCurrentOverlays(OverlayA)
        assertThat(transition).hasProgress(0.1f)

        nestedScroll.preFling(Velocity(0f, velocityThreshold))
        advanceUntilIdle()
        // Commit the gesture. The overlays are instantly swapped in the set of current overlays.
        assertThat(layoutState.transitionState).isIdle()
        assertThat(layoutState.transitionState).hasCurrentScene(SceneA)
        assertThat(layoutState.transitionState).hasCurrentOverlays(OverlayB)
    }
}