Add enabled parameter to Modifier.nestedDraggable()
Bug: 378470603
Test: atest NestedDraggableTest
Flag: EXEMPT new API not used anywhere yet
Change-Id: I975c6eac3951880e2c3196a0e0baad2677501a73
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt b/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt
index 58b8836..9fe85b7 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt
@@ -111,22 +111,24 @@
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 var draggable: NestedDraggable,
override var orientation: Orientation,
private var overscrollEffect: OverscrollEffect?,
+ private var enabled: Boolean,
) :
DelegatingNode(),
PointerInputModifierNode,
@@ -179,14 +182,22 @@
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 @@
pass: PointerEventPass,
bounds: IntSize,
) {
+ if (!enabled) return
+
if (trackDownPositionDelegate == null) {
check(detectDragsDelegate == null)
trackDownPositionDelegate = SuspendingPointerInputModifierNode { trackDownPosition() }
diff --git a/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt b/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt
index f8561b8..fd3902f 100644
--- a/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt
+++ b/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt
@@ -344,6 +344,45 @@
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 {