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

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

Add NestedDraggable.Controller.autoStopNestedDrags

This CL adds a new autoStopNestedDrags flag to
NestedDraggable.Controller to automatically stop a nested drag as soon
as it does not consume some amount of scroll. This will be used by the
media player to implement the "swipe to gear icon" behavior.

Bug: 397989775
Test: atest NestedDraggableTest
Flag: EXEMPT new unused API
Change-Id: If4441298d18a8c7fa9e4a84bdfb3e86a5dc426a1
parent 6b7574f3
Loading
Loading
Loading
Loading
+17 −2
Original line number Diff line number Diff line
@@ -111,6 +111,14 @@ interface NestedDraggable {
    fun shouldConsumeNestedPreScroll(sign: Float): Boolean = false

    interface Controller {
        /**
         * Whether drags that were started from nested scrolls should be automatically
         * [stopped][onDragStopped] as soon as they don't consume the entire `delta` passed to
         * [onDrag].
         */
        val autoStopNestedDrags: Boolean
            get() = false

        /**
         * Drag by [delta] pixels.
         *
@@ -609,8 +617,15 @@ private class NestedDraggableNode(
    }

    private fun scrollWithOverscroll(controller: NestedScrollController, offset: Offset): Offset {
        return scrollWithOverscroll(offset) {
            controller.controller.onDrag(it.toFloat()).toOffset()
        return scrollWithOverscroll(offset) { delta ->
            val available = delta.toFloat()
            val consumed = controller.controller.onDrag(available)
            if (controller.controller.autoStopNestedDrags && consumed != available) {
                controller.ensureOnDragStoppedIsCalled()
                this.nestedScrollController = null
            }

            consumed.toOffset()
        }
    }

+36 −0
Original line number Diff line number Diff line
@@ -1000,6 +1000,39 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw
        assertThat(draggable.onDragStartedCalled).isTrue()
    }

    @Test
    fun autoStopNestedDrags() {
        var consumeScrolls by mutableStateOf(true)
        val draggable =
            TestDraggable(autoStopNestedDrags = true, onDrag = { if (consumeScrolls) it else 0f })

        val touchSlop =
            rule.setContentWithTouchSlop {
                Box(
                    Modifier.fillMaxSize()
                        .nestedDraggable(draggable, orientation)
                        .scrollable(rememberScrollableState { 0f }, orientation)
                )
            }

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

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

        rule.onRoot().performTouchInput { moveBy(50f.toOffset()) }

        assertThat(draggable.onDragStoppedCalled).isFalse()

        consumeScrolls = false
        rule.onRoot().performTouchInput { moveBy(1f.toOffset()) }

        assertThat(draggable.onDragStoppedCalled).isTrue()
    }

    private fun ComposeContentTestRule.setContentWithTouchSlop(
        content: @Composable () -> Unit
    ): Float {
@@ -1027,6 +1060,7 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw
            },
        private val shouldConsumeNestedPostScroll: (Float) -> Boolean = { true },
        private val shouldConsumeNestedPreScroll: (Float) -> Boolean = { false },
        private val autoStopNestedDrags: Boolean = false,
    ) : NestedDraggable {
        var shouldStartDrag = true
        var onDragStartedCalled = false
@@ -1056,6 +1090,8 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw

            onDragStarted.invoke(position, sign)
            return object : NestedDraggable.Controller {
                override val autoStopNestedDrags: Boolean = this@TestDraggable.autoStopNestedDrags

                override fun onDrag(delta: Float): Float {
                    onDragCalled = true
                    onDragDelta += delta