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

Commit a3116a93 authored by Jordan Demeulenaere's avatar Jordan Demeulenaere
Browse files

Add enabled parameter to Modifier.nestedDraggable()

Bug: 378470603
Test: atest NestedDraggableTest
Flag: EXEMPT new API not used anywhere yet
Change-Id: I975c6eac3951880e2c3196a0e0baad2677501a73
parent 69c57057
Loading
Loading
Loading
Loading
+16 −3
Original line number Diff line number Diff line
@@ -111,22 +111,24 @@ fun Modifier.nestedDraggable(
    draggable: NestedDraggable,
    orientation: Orientation,
    overscrollEffect: OverscrollEffect? = null,
    enabled: Boolean = true,
): Modifier {
    return this.thenIf(overscrollEffect != null) { Modifier.overscroll(overscrollEffect) }
        .then(NestedDraggableElement(draggable, orientation, overscrollEffect))
        .then(NestedDraggableElement(draggable, orientation, overscrollEffect, enabled))
}

private data class NestedDraggableElement(
    private val draggable: NestedDraggable,
    private val orientation: Orientation,
    private val overscrollEffect: OverscrollEffect?,
    private val enabled: Boolean,
) : ModifierNodeElement<NestedDraggableNode>() {
    override fun create(): NestedDraggableNode {
        return NestedDraggableNode(draggable, orientation, overscrollEffect)
        return NestedDraggableNode(draggable, orientation, overscrollEffect, enabled)
    }

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

@@ -134,6 +136,7 @@ private class NestedDraggableNode(
    private var draggable: NestedDraggable,
    override var orientation: Orientation,
    private var overscrollEffect: OverscrollEffect?,
    private var enabled: Boolean,
) :
    DelegatingNode(),
    PointerInputModifierNode,
@@ -179,14 +182,22 @@ private class NestedDraggableNode(
        draggable: NestedDraggable,
        orientation: Orientation,
        overscrollEffect: OverscrollEffect?,
        enabled: Boolean,
    ) {
        this.draggable = draggable
        this.orientation = orientation
        this.overscrollEffect = overscrollEffect
        this.enabled = enabled

        trackDownPositionDelegate?.resetPointerInputHandler()
        detectDragsDelegate?.resetPointerInputHandler()
        nestedScrollController?.ensureOnDragStoppedIsCalled()

        if (!enabled && trackDownPositionDelegate != null) {
            check(detectDragsDelegate != null)
            trackDownPositionDelegate = null
            detectDragsDelegate = null
        }
    }

    override fun onPointerEvent(
@@ -194,6 +205,8 @@ private class NestedDraggableNode(
        pass: PointerEventPass,
        bounds: IntSize,
    ) {
        if (!enabled) return

        if (trackDownPositionDelegate == null) {
            check(detectDragsDelegate == null)
            trackDownPositionDelegate = SuspendingPointerInputModifierNode { trackDownPosition() }
+39 −0
Original line number Diff line number Diff line
@@ -344,6 +344,45 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw
        assertThat(draggable.onDragStoppedCalled).isTrue()
    }

    @Test
    fun enabled() {
        val draggable = TestDraggable()
        var enabled by mutableStateOf(false)
        val touchSlop =
            rule.setContentWithTouchSlop {
                Box(
                    Modifier.fillMaxSize()
                        .nestedDraggable(draggable, orientation, enabled = enabled)
                )
            }

        assertThat(draggable.onDragStartedCalled).isFalse()

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

        assertThat(draggable.onDragStartedCalled).isFalse()
        assertThat(draggable.onDragStoppedCalled).isFalse()

        enabled = true
        rule.onRoot().performTouchInput {
            // Release previously up finger.
            up()

            down(center)
            moveBy(touchSlop.toOffset())
        }

        assertThat(draggable.onDragStartedCalled).isTrue()
        assertThat(draggable.onDragStoppedCalled).isFalse()

        enabled = false
        rule.waitForIdle()
        assertThat(draggable.onDragStoppedCalled).isTrue()
    }

    private fun ComposeContentTestRule.setContentWithTouchSlop(
        content: @Composable () -> Unit
    ): Float {