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

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

Merge "Disable nested drag only in disableSwipesWhenScrolling()" into main

parents b52b31fe 880ef4fa
Loading
Loading
Loading
Loading
+33 −16
Original line number Original line Diff line number Diff line
@@ -137,9 +137,18 @@ fun Modifier.nestedDraggable(
    orientation: Orientation,
    orientation: Orientation,
    overscrollEffect: OverscrollEffect? = null,
    overscrollEffect: OverscrollEffect? = null,
    enabled: Boolean = true,
    enabled: Boolean = true,
    nestedDragsEnabled: Boolean = true,
): Modifier {
): Modifier {
    return this.thenIf(overscrollEffect != null) { Modifier.overscroll(overscrollEffect) }
    return this.thenIf(overscrollEffect != null) { Modifier.overscroll(overscrollEffect) }
        .then(NestedDraggableElement(draggable, orientation, overscrollEffect, enabled))
        .then(
            NestedDraggableElement(
                draggable,
                orientation,
                overscrollEffect,
                enabled,
                nestedDragsEnabled,
            )
        )
}
}


private data class NestedDraggableElement(
private data class NestedDraggableElement(
@@ -147,13 +156,20 @@ private data class NestedDraggableElement(
    private val orientation: Orientation,
    private val orientation: Orientation,
    private val overscrollEffect: OverscrollEffect?,
    private val overscrollEffect: OverscrollEffect?,
    private val enabled: Boolean,
    private val enabled: Boolean,
    private val nestedDragsEnabled: Boolean,
) : ModifierNodeElement<NestedDraggableRootNode>() {
) : ModifierNodeElement<NestedDraggableRootNode>() {
    override fun create(): NestedDraggableRootNode {
    override fun create(): NestedDraggableRootNode {
        return NestedDraggableRootNode(draggable, orientation, overscrollEffect, enabled)
        return NestedDraggableRootNode(
            draggable,
            orientation,
            overscrollEffect,
            enabled,
            nestedDragsEnabled,
        )
    }
    }


    override fun update(node: NestedDraggableRootNode) {
    override fun update(node: NestedDraggableRootNode) {
        node.update(draggable, orientation, overscrollEffect, enabled)
        node.update(draggable, orientation, overscrollEffect, enabled, nestedDragsEnabled)
    }
    }
}
}


@@ -166,15 +182,17 @@ private class NestedDraggableRootNode(
    orientation: Orientation,
    orientation: Orientation,
    overscrollEffect: OverscrollEffect?,
    overscrollEffect: OverscrollEffect?,
    enabled: Boolean,
    enabled: Boolean,
    nestedDragsEnabled: Boolean,
) : DelegatingNode() {
) : DelegatingNode() {
    private var delegateNode =
    private var delegateNode =
        if (enabled) create(draggable, orientation, overscrollEffect) else null
        if (enabled) create(draggable, orientation, overscrollEffect, nestedDragsEnabled) else null


    fun update(
    fun update(
        draggable: NestedDraggable,
        draggable: NestedDraggable,
        orientation: Orientation,
        orientation: Orientation,
        overscrollEffect: OverscrollEffect?,
        overscrollEffect: OverscrollEffect?,
        enabled: Boolean,
        enabled: Boolean,
        nestedDragsEnabled: Boolean,
    ) {
    ) {
        // Disabled.
        // Disabled.
        if (!enabled) {
        if (!enabled) {
@@ -186,20 +204,23 @@ private class NestedDraggableRootNode(
        // Disabled => Enabled.
        // Disabled => Enabled.
        val nullableDelegate = delegateNode
        val nullableDelegate = delegateNode
        if (nullableDelegate == null) {
        if (nullableDelegate == null) {
            delegateNode = create(draggable, orientation, overscrollEffect)
            delegateNode = create(draggable, orientation, overscrollEffect, nestedDragsEnabled)
            return
            return
        }
        }


        // Enabled => Enabled (update).
        // Enabled => Enabled (update).
        nullableDelegate.update(draggable, orientation, overscrollEffect)
        nullableDelegate.update(draggable, orientation, overscrollEffect, nestedDragsEnabled)
    }
    }


    private fun create(
    private fun create(
        draggable: NestedDraggable,
        draggable: NestedDraggable,
        orientation: Orientation,
        orientation: Orientation,
        overscrollEffect: OverscrollEffect?,
        overscrollEffect: OverscrollEffect?,
        nestedDragsEnabled: Boolean,
    ): NestedDraggableNode {
    ): NestedDraggableNode {
        return delegate(NestedDraggableNode(draggable, orientation, overscrollEffect))
        return delegate(
            NestedDraggableNode(draggable, orientation, overscrollEffect, nestedDragsEnabled)
        )
    }
    }
}
}


@@ -207,6 +228,7 @@ private class NestedDraggableNode(
    private var draggable: NestedDraggable,
    private var draggable: NestedDraggable,
    override var orientation: Orientation,
    override var orientation: Orientation,
    private var overscrollEffect: OverscrollEffect?,
    private var overscrollEffect: OverscrollEffect?,
    private var nestedDragsEnabled: Boolean,
) :
) :
    DelegatingNode(),
    DelegatingNode(),
    PointerInputModifierNode,
    PointerInputModifierNode,
@@ -247,18 +269,12 @@ private class NestedDraggableNode(
        draggable: NestedDraggable,
        draggable: NestedDraggable,
        orientation: Orientation,
        orientation: Orientation,
        overscrollEffect: OverscrollEffect?,
        overscrollEffect: OverscrollEffect?,
        nestedDragsEnabled: Boolean,
    ) {
    ) {
        if (
            draggable == this.draggable &&
                orientation == this.orientation &&
                overscrollEffect == this.overscrollEffect
        ) {
            return
        }

        this.draggable = draggable
        this.draggable = draggable
        this.orientation = orientation
        this.orientation = orientation
        this.overscrollEffect = overscrollEffect
        this.overscrollEffect = overscrollEffect
        this.nestedDragsEnabled = nestedDragsEnabled


        trackWheelScroll.resetPointerInputHandler()
        trackWheelScroll.resetPointerInputHandler()
        trackDownPositionDelegate.resetPointerInputHandler()
        trackDownPositionDelegate.resetPointerInputHandler()
@@ -545,6 +561,7 @@ private class NestedDraggableNode(


        val sign = offset.sign
        val sign = offset.sign
        if (
        if (
            nestedDragsEnabled &&
                nestedScrollController == null &&
                nestedScrollController == null &&
                // TODO(b/388231324): Remove this.
                // TODO(b/388231324): Remove this.
                !lastEventWasScrollWheel &&
                !lastEventWasScrollWheel &&
+21 −0
Original line number Original line Diff line number Diff line
@@ -172,6 +172,27 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw
        assertThat(effect.applyToFlingDone).isTrue()
        assertThat(effect.applyToFlingDone).isTrue()
    }
    }


    @Test
    fun nestedScrollable_disabled() {
        val draggable = TestDraggable()
        val effect = TestOverscrollEffect(orientation) { 0f }
        val touchSlop =
            rule.setContentWithTouchSlop {
                Box(
                    Modifier.fillMaxSize()
                        .nestedDraggable(draggable, orientation, effect, nestedDragsEnabled = false)
                        .nestedScrollable(rememberScrollState())
                )
            }

        rule.onRoot().performTouchInput {
            down(center)
            moveBy((-touchSlop - 10f).toOffset())
        }

        assertThat(draggable.onDragStartedCalled).isFalse()
    }

    @Test
    @Test
    fun onDragStoppedIsCalledWhenDraggableIsUpdatedAndReset() {
    fun onDragStoppedIsCalledWhenDraggableIsUpdatedAndReset() {
        val draggable = TestDraggable()
        val draggable = TestDraggable()
+0 −4
Original line number Original line Diff line number Diff line
@@ -458,10 +458,6 @@ internal class Swipes(val upOrLeft: Swipe.Resolved, val downOrRight: Swipe.Resol
     * @return The best matching [UserActionResult], or `null` if no match is found.
     * @return The best matching [UserActionResult], or `null` if no match is found.
     */
     */
    private fun Content.findActionResultBestMatch(swipe: Swipe.Resolved): UserActionResult? {
    private fun Content.findActionResultBestMatch(swipe: Swipe.Resolved): UserActionResult? {
        if (!areSwipesAllowed()) {
            return null
        }

        var bestPoints = Int.MIN_VALUE
        var bestPoints = Int.MIN_VALUE
        var bestMatch: UserActionResult? = null
        var bestMatch: UserActionResult? = null
        userActions.forEach { (actionSwipe, actionResult) ->
        userActions.forEach { (actionSwipe, actionResult) ->
+7 −4
Original line number Original line Diff line number Diff line
@@ -27,16 +27,19 @@ import com.android.compose.gesture.nestedDraggable
 */
 */
@Stable
@Stable
internal fun Modifier.swipeToScene(draggableHandler: DraggableHandler): Modifier {
internal fun Modifier.swipeToScene(draggableHandler: DraggableHandler): Modifier {
    val contentForSwipes = draggableHandler.contentForSwipes()
    val enabled = draggableHandler.enabled(contentForSwipes)
    return this.nestedDraggable(
    return this.nestedDraggable(
        draggable = draggableHandler,
        draggable = draggableHandler,
        orientation = draggableHandler.orientation,
        orientation = draggableHandler.orientation,
        overscrollEffect = draggableHandler.overscrollEffect,
        overscrollEffect = draggableHandler.overscrollEffect,
        enabled = draggableHandler.enabled(),
        enabled = enabled,
        nestedDragsEnabled = enabled && contentForSwipes.areNestedSwipesAllowed(),
    )
    )
}
}


internal fun DraggableHandler.enabled(): Boolean {
internal fun DraggableHandler.enabled(contentForSwipes: Content = contentForSwipes()): Boolean {
    return isDrivingTransition || contentForSwipes().shouldEnableSwipes(orientation)
    return isDrivingTransition || contentForSwipes.shouldEnableSwipes(orientation)
}
}


private fun DraggableHandler.contentForSwipes(): Content {
private fun DraggableHandler.contentForSwipes(): Content {
@@ -45,7 +48,7 @@ private fun DraggableHandler.contentForSwipes(): Content {


/** Whether swipe should be enabled in the given [orientation]. */
/** Whether swipe should be enabled in the given [orientation]. */
private fun Content.shouldEnableSwipes(orientation: Orientation): Boolean {
private fun Content.shouldEnableSwipes(orientation: Orientation): Boolean {
    if (userActions.isEmpty() || !areSwipesAllowed()) {
    if (userActions.isEmpty()) {
        return false
        return false
    }
    }


+1 −1
Original line number Original line Diff line number Diff line
@@ -179,7 +179,7 @@ internal sealed class Content(
        }
        }
    }
    }


    fun areSwipesAllowed(): Boolean = nestedScrollControlState.isOuterScrollAllowed
    fun areNestedSwipesAllowed(): Boolean = nestedScrollControlState.isOuterScrollAllowed


    fun maybeUpdateEffects(effectFactory: OverscrollFactory) {
    fun maybeUpdateEffects(effectFactory: OverscrollFactory) {
        if (effectFactory != lastFactory) {
        if (effectFactory != lastFactory) {
Loading