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

Commit c55504e1 authored by Ale Nijamkin's avatar Ale Nijamkin Committed by Android (Google) Code Review
Browse files

Merge "[flexiglass] Adds gestureFilter lambda to STL" into main

parents c27648b8 f9a01533
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -123,6 +123,10 @@ internal class DraggableHandlerImpl(
        overSlop: Float,
        pointersDown: Int,
    ): DragController {
        if (startedPosition != null && layoutImpl.gestureFilter(startedPosition)) {
            return NoOpDragController
        }

        if (overSlop == 0f) {
            val oldDragController = dragController
            check(oldDragController != null && oldDragController.isDrivingTransition) {
+7 −0
Original line number Diff line number Diff line
@@ -47,6 +47,9 @@ import androidx.compose.ui.unit.LayoutDirection
 * @param state the state of this layout.
 * @param swipeSourceDetector the edge detector used to detect which edge a swipe is started from,
 *   if any.
 * @param gestureFilter decides whether a drag gesture that started at the given start position
 *   should be filtered. If the lambda returns `true`, the drag gesture will be ignored. If it
 *   returns `false`, the drag gesture will be handled.
 * @param transitionInterceptionThreshold used during a scene transition. For the scene to be
 *   intercepted, the progress value must be above the threshold, and below (1 - threshold).
 * @param builder the configuration of the different scenes and overlays of this layout.
@@ -57,6 +60,7 @@ fun SceneTransitionLayout(
    modifier: Modifier = Modifier,
    swipeSourceDetector: SwipeSourceDetector = DefaultEdgeDetector,
    swipeDetector: SwipeDetector = DefaultSwipeDetector,
    gestureFilter: (startedPosition: Offset) -> Boolean = DefaultGestureFilter,
    @FloatRange(from = 0.0, to = 0.5) transitionInterceptionThreshold: Float = 0.05f,
    builder: SceneTransitionLayoutScope.() -> Unit,
) {
@@ -65,6 +69,7 @@ fun SceneTransitionLayout(
        modifier,
        swipeSourceDetector,
        swipeDetector,
        gestureFilter,
        transitionInterceptionThreshold,
        onLayoutImpl = null,
        builder,
@@ -616,6 +621,7 @@ internal fun SceneTransitionLayoutForTesting(
    modifier: Modifier = Modifier,
    swipeSourceDetector: SwipeSourceDetector = DefaultEdgeDetector,
    swipeDetector: SwipeDetector = DefaultSwipeDetector,
    gestureFilter: (startedPosition: Offset) -> Boolean = DefaultGestureFilter,
    transitionInterceptionThreshold: Float = 0f,
    onLayoutImpl: ((SceneTransitionLayoutImpl) -> Unit)? = null,
    builder: SceneTransitionLayoutScope.() -> Unit,
@@ -632,6 +638,7 @@ internal fun SceneTransitionLayoutForTesting(
                transitionInterceptionThreshold = transitionInterceptionThreshold,
                builder = builder,
                animationScope = animationScope,
                gestureFilter = gestureFilter,
            )
            .also { onLayoutImpl?.invoke(it) }
    }
+2 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import androidx.compose.runtime.snapshots.SnapshotStateMap
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.layout.ApproachLayoutModifierNode
import androidx.compose.ui.layout.ApproachMeasureScope
import androidx.compose.ui.layout.LookaheadScope
@@ -70,6 +71,7 @@ internal class SceneTransitionLayoutImpl(
     * animations.
     */
    internal val animationScope: CoroutineScope,
    internal val gestureFilter: (startedPosition: Offset) -> Boolean,
) {
    /**
     * The map of [Scene]s.
+3 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.compose.animation.scene

import androidx.compose.runtime.Stable
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.pointer.PointerInputChange

/** {@link SwipeDetector} helps determine whether a swipe gestured has occurred. */
@@ -31,6 +32,8 @@ interface SwipeDetector {

val DefaultSwipeDetector = PassthroughSwipeDetector()

val DefaultGestureFilter = { _: Offset -> false }

/** An {@link SwipeDetector} implementation that recognizes a swipe on any input. */
class PassthroughSwipeDetector : SwipeDetector {
    override fun detectSwipe(change: PointerInputChange): Boolean {
+10 −0
Original line number Diff line number Diff line
@@ -108,6 +108,8 @@ class DraggableHandlerTest {

        val transitionInterceptionThreshold = 0.05f

        var gestureFilter: (startedPosition: Offset) -> Boolean = DefaultGestureFilter

        private val layoutImpl =
            SceneTransitionLayoutImpl(
                    state = layoutState,
@@ -120,6 +122,7 @@ class DraggableHandlerTest {
                    // Use testScope and not backgroundScope here because backgroundScope does not
                    // work well with advanceUntilIdle(), which is used by some tests.
                    animationScope = testScope,
                    gestureFilter = { startedPosition -> gestureFilter.invoke(startedPosition) },
                )
                .apply { setContentsAndLayoutTargetSizeForTest(LAYOUT_SIZE) }

@@ -316,6 +319,13 @@ class DraggableHandlerTest {
        assertTransition(currentScene = SceneA)
    }

    @Test
    fun onDragStarted_doesNotStartTransition_whenGestureFiltered() = runGestureTest {
        gestureFilter = { _ -> true }
        onDragStarted(overSlop = down(fractionOfScreen = 0.1f), expectedConsumedOverSlop = 0f)
        assertIdle(currentScene = SceneA)
    }

    @Test
    fun afterSceneTransitionIsStarted_interceptDragEvents() = runGestureTest {
        val dragController = onDragStarted(overSlop = down(fractionOfScreen = 0.1f))