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

Commit 1d967cdc authored by omarmt's avatar omarmt
Browse files

Make SwipeTransition an implementation detail of SceneGestureHandler

In this refactor the class has been extracted and made private.

Test: atest SceneGestureHandlerTest
Bug: 317063114
Flag: NA
Change-Id: Ia6a610eeee36d1b2d0e72846250f14808c8022eb
parent 2c47d801
Loading
Loading
Loading
Loading
+159 −130
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ internal class SceneGestureHandler(
    val draggable: DraggableHandler = SceneDraggableHandler(this)

    private var _swipeTransition: SwipeTransition? = null
    internal var swipeTransition: SwipeTransition
    private var swipeTransition: SwipeTransition
        get() = _swipeTransition ?: error("SwipeTransition needs to be initialized")
        set(value) {
            _swipeTransition = value
@@ -149,7 +149,17 @@ internal class SceneGestureHandler(
        val result =
            findUserActionResult(fromScene, directionOffset = overSlop, updateSwipesResults = true)
                ?: return
        updateTransition(SwipeTransition(fromScene, result), force = true)
        val newSwipeTransition =
            SwipeTransition(
                fromScene = fromScene,
                result = result,
                upOrLeftResult = upOrLeftResult,
                downOrRightResult = downOrRightResult,
                layoutImpl = layoutImpl,
                orientation = orientation
            )

        updateTransition(newSwipeTransition, force = true)
    }

    private fun updateSwipes(fromScene: Scene, startedPosition: Offset?, pointersDown: Int) {
@@ -242,11 +252,18 @@ internal class SceneGestureHandler(
                result.toScene != swipeTransition.toScene ||
                result.transitionKey != swipeTransition.key
        ) {
            updateTransition(
                SwipeTransition(fromScene, result).apply {
                    this.dragOffset = swipeTransition.dragOffset
                }
            val newSwipeTransition =
                SwipeTransition(
                        fromScene = fromScene,
                        result = result,
                        upOrLeftResult = upOrLeftResult,
                        downOrRightResult = downOrRightResult,
                        layoutImpl = layoutImpl,
                        orientation = orientation
                    )
                    .apply { dragOffset = swipeTransition.dragOffset }

            updateTransition(newSwipeTransition)
        }
    }

@@ -354,18 +371,6 @@ internal class SceneGestureHandler(
        }
    }

    private fun computeAbsoluteDistance(
        fromScene: Scene,
        result: UserActionResult,
    ): Float {
        return if (result == upOrLeftResult) {
            -fromScene.getAbsoluteDistance(result.distance)
        } else {
            check(result == downOrRightResult)
            fromScene.getAbsoluteDistance(result.distance)
        }
    }

    internal fun onDragStopped(velocity: Float, canChangeScene: Boolean) {
        // The state was changed since the drag started; don't do anything.
        if (!isDrivingTransition) {
@@ -438,11 +443,18 @@ internal class SceneGestureHandler(
                            return
                        }

                updateTransition(
                    SwipeTransition(fromScene, result).apply {
                        _currentScene = swipeTransition._currentScene
                    }
                val newSwipeTransition =
                    SwipeTransition(
                            fromScene = fromScene,
                            result = result,
                            upOrLeftResult = upOrLeftResult,
                            downOrRightResult = downOrRightResult,
                            layoutImpl = layoutImpl,
                            orientation = orientation
                        )
                        .apply { _currentScene = swipeTransition._currentScene }

                updateTransition(newSwipeTransition)
                animateTo(targetScene = fromScene, targetOffset = 0f)
            } else {
                // We were between two scenes: animate to the initial scene.
@@ -486,22 +498,45 @@ internal class SceneGestureHandler(
        }
    }

    private fun SwipeTransition(fromScene: Scene, result: UserActionResult): SwipeTransition {
    companion object {
        private const val TAG = "SceneGestureHandler"
    }
}

private fun SwipeTransition(
    fromScene: Scene,
    result: UserActionResult,
    upOrLeftResult: UserActionResult?,
    downOrRightResult: UserActionResult?,
    layoutImpl: SceneTransitionLayoutImpl,
    orientation: Orientation,
): SwipeTransition {
    val userActionDistance = result.distance ?: DefaultSwipeDistance
    val absoluteDistance =
        with(userActionDistance) {
            layoutImpl.density.absoluteDistance(fromScene.targetSize, orientation)
        }

    return SwipeTransition(
            result.transitionKey,
            fromScene,
            layoutImpl.scene(result.toScene),
            computeAbsoluteDistance(fromScene, result),
        key = result.transitionKey,
        _fromScene = fromScene,
        _toScene = layoutImpl.scene(result.toScene),
        distance =
            when (result) {
                upOrLeftResult -> -absoluteDistance
                downOrRightResult -> absoluteDistance
                else -> error("Unknown result $result ($upOrLeftResult $downOrRightResult)")
            },
    )
}

    internal class SwipeTransition(
private class SwipeTransition(
    val key: TransitionKey?,
    val _fromScene: Scene,
    val _toScene: Scene,
    /**
         * The signed distance between [fromScene] and [toScene]. It is negative if [fromScene] is
         * above or to the left of [toScene].
     * The signed distance between [fromScene] and [toScene]. It is negative if [fromScene] is above
     * or to the left of [toScene]
     */
    val distance: Float,
) : TransitionState.Transition(_fromScene.key, _toScene.key) {
@@ -521,8 +556,7 @@ internal class SceneGestureHandler(
    var dragOffset by mutableFloatStateOf(0f)

    /**
         * Whether the offset is animated (the user lifted their finger) or if it is driven by
         * gesture.
     * Whether the offset is animated (the user lifted their finger) or if it is driven by gesture.
     */
    var isAnimatingOffset by mutableStateOf(false)

@@ -591,10 +625,6 @@ internal class SceneGestureHandler(
    }
}

    companion object {
        private const val TAG = "SceneGestureHandler"
    }

private object DefaultSwipeDistance : UserActionDistance {
    override fun Density.absoluteDistance(
        fromSceneSize: IntSize,
@@ -614,7 +644,6 @@ internal class SceneGestureHandler(
    val upOrLeftNoSource: Swipe?,
    val downOrRightNoSource: Swipe?,
)
}

private class SceneDraggableHandler(
    private val gestureHandler: SceneGestureHandler,
+5 −3
Original line number Diff line number Diff line
@@ -127,6 +127,9 @@ class SceneGestureHandlerTest {
        val progress: Float
            get() = (transitionState as Transition).progress

        val isUserInputOngoing: Boolean
            get() = (transitionState as Transition).isUserInputOngoing

        fun advanceUntilIdle() {
            testScope.testScheduler.advanceUntilIdle()
        }
@@ -538,12 +541,11 @@ class SceneGestureHandlerTest {
        onDragStopped(velocity = velocityThreshold)

        assertTransition(currentScene = SceneC)
        assertThat(sceneGestureHandler.isDrivingTransition).isTrue()
        assertThat(sceneGestureHandler.swipeTransition.isAnimatingOffset).isTrue()
        assertThat(isUserInputOngoing).isFalse()

        // Start a new gesture while the offset is animating
        onDragStartedImmediately()
        assertThat(sceneGestureHandler.swipeTransition.isAnimatingOffset).isFalse()
        assertThat(isUserInputOngoing).isTrue()
    }

    @Test