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

Commit 2b870922 authored by Omar Miatello's avatar Omar Miatello Committed by Android (Google) Code Review
Browse files

Merge "Overscroll DSL exposes the current OverscrollScope (1/2)" into main

parents 5c96d2c1 4739ecf6
Loading
Loading
Loading
Loading
+11 −11
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.round
import com.android.compose.animation.scene.TransitionState.HasOverscrollProperties.Companion.DistanceUnspecified
import com.android.compose.nestedscroll.PriorityNestedScrollConnection
import kotlin.math.absoluteValue
import kotlinx.coroutines.CoroutineScope
@@ -353,10 +354,7 @@ private class DragControllerImpl(

        // If the swipe was not committed or if the swipe distance is not computed yet, don't do
        // anything.
        if (
            swipeTransition._currentScene != toScene ||
                distance == SwipeTransition.DistanceUnspecified
        ) {
        if (swipeTransition._currentScene != toScene || distance == DistanceUnspecified) {
            return fromScene to 0f
        }

@@ -418,7 +416,7 @@ private class DragControllerImpl(
            var targetScene: Scene
            var targetOffset: Float
            if (
                distance != SwipeTransition.DistanceUnspecified &&
                distance != DistanceUnspecified &&
                    shouldCommitSwipe(
                        offset,
                        distance,
@@ -444,8 +442,8 @@ private class DragControllerImpl(
                    if (targetScene == fromScene) {
                        0f
                    } else {
                        check(distance != SwipeTransition.DistanceUnspecified) {
                            "distance is equal to ${SwipeTransition.DistanceUnspecified}"
                        check(distance != DistanceUnspecified) {
                            "distance is equal to $DistanceUnspecified"
                        }
                        distance
                    }
@@ -628,6 +626,12 @@ private class SwipeTransition(
    /** The spec to use when animating this transition to either [fromScene] or [toScene]. */
    lateinit var swipeSpec: SpringSpec<Float>

    override val overscrollScope: OverscrollScope =
        object : OverscrollScope {
            override val absoluteDistance: Float
                get() = distance().absoluteValue
        }

    private var lastDistance = DistanceUnspecified

    /** Whether [TransitionState.Transition.finish] was called on this transition. */
@@ -753,10 +757,6 @@ private class SwipeTransition(
        /** The job in which [animatable] is animated. */
        val job: Job,
    )

    companion object {
        const val DistanceUnspecified = 0f
    }
}

private object DefaultSwipeDistance : UserActionDistance {
+12 −3
Original line number Diff line number Diff line
@@ -236,19 +236,28 @@ sealed interface TransitionState {

    interface HasOverscrollProperties {
        /**
         * The position of the [TransitionState.Transition.toScene].
         * The position of the [Transition.toScene].
         *
         * Used to understand the direction of the overscroll.
         */
        val isUpOrLeft: Boolean

        /**
         * The relative orientation between [TransitionState.Transition.fromScene] and
         * [TransitionState.Transition.toScene].
         * The relative orientation between [Transition.fromScene] and [Transition.toScene].
         *
         * Used to understand the orientation of the overscroll.
         */
        val orientation: Orientation

        /**
         * Scope which can be used in the Overscroll DSL to define a transformation based on the
         * distance between [Transition.fromScene] and [Transition.toScene].
         */
        val overscrollScope: OverscrollScope

        companion object {
            const val DistanceUnspecified = 0f
        }
    }
}

+3 −1
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import com.android.compose.animation.scene.transformation.AnchoredTranslate
import com.android.compose.animation.scene.transformation.DrawScale
import com.android.compose.animation.scene.transformation.EdgeTranslate
import com.android.compose.animation.scene.transformation.Fade
import com.android.compose.animation.scene.transformation.OverscrollTranslate
import com.android.compose.animation.scene.transformation.PropertyTransformation
import com.android.compose.animation.scene.transformation.RangedPropertyTransformation
import com.android.compose.animation.scene.transformation.ScaleSize
@@ -124,7 +125,7 @@ internal constructor(
        overscrollSpecs.fastForEach { spec ->
            if (spec.orientation == orientation && filter(spec)) {
                if (match != null) {
                    error("Found multiple transition specs for transition $scene")
                    error("Found multiple overscroll specs for overscroll $scene")
                }
                match = spec
            }
@@ -297,6 +298,7 @@ internal class TransformationSpecImpl(
        ) {
            when (current) {
                is Translate,
                is OverscrollTranslate,
                is EdgeTranslate,
                is AnchoredTranslate -> {
                    throwIfNotNull(offset, element, name = "offset")
+21 −3
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import androidx.compose.foundation.gestures.Orientation
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.android.compose.animation.scene.TransitionState.HasOverscrollProperties.Companion.DistanceUnspecified

/** Define the [transitions][SceneTransitions] to be used with a [SceneTransitionLayout]. */
fun transitions(builder: SceneTransitionsBuilder.() -> Unit): SceneTransitions {
@@ -88,8 +89,7 @@ interface SceneTransitionsBuilder {
    ): OverscrollSpec
}

@TransitionDsl
interface OverscrollBuilder : PropertyTransformationBuilder {
interface BaseTransitionBuilder : PropertyTransformationBuilder {
    /**
     * The distance it takes for this transition to animate from 0% to 100% when it is driven by a
     * [UserAction].
@@ -120,7 +120,7 @@ interface OverscrollBuilder : PropertyTransformationBuilder {
}

@TransitionDsl
interface TransitionBuilder : OverscrollBuilder, PropertyTransformationBuilder {
interface TransitionBuilder : BaseTransitionBuilder {
    /**
     * The [AnimationSpec] used to animate the associated transition progress from `0` to `1` when
     * the transition is triggered (i.e. it is not gesture-based).
@@ -176,6 +176,24 @@ interface TransitionBuilder : OverscrollBuilder, PropertyTransformationBuilder {
    fun reversed(builder: TransitionBuilder.() -> Unit)
}

@TransitionDsl
interface OverscrollBuilder : BaseTransitionBuilder {
    /** Translate the element(s) matching [matcher] by ([x], [y]) pixels. */
    fun translate(
        matcher: ElementMatcher,
        x: OverscrollScope.() -> Float = { 0f },
        y: OverscrollScope.() -> Float = { 0f },
    )
}

interface OverscrollScope {
    /**
     * Return the absolute distance between fromScene and toScene, if available, otherwise
     * [DistanceUnspecified].
     */
    val absoluteDistance: Float
}

/**
 * An interface to decide where we should draw shared Elements or compose MovableElements.
 *
+14 −3
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import com.android.compose.animation.scene.transformation.AnchoredTranslate
import com.android.compose.animation.scene.transformation.DrawScale
import com.android.compose.animation.scene.transformation.EdgeTranslate
import com.android.compose.animation.scene.transformation.Fade
import com.android.compose.animation.scene.transformation.OverscrollTranslate
import com.android.compose.animation.scene.transformation.PropertyTransformation
import com.android.compose.animation.scene.transformation.RangedPropertyTransformation
import com.android.compose.animation.scene.transformation.ScaleSize
@@ -114,7 +115,7 @@ private class SceneTransitionsBuilderImpl : SceneTransitionsBuilder {
    }
}

internal open class OverscrollBuilderImpl : OverscrollBuilder {
internal abstract class BaseTransitionBuilderImpl : BaseTransitionBuilder {
    val transformations = mutableListOf<Transformation>()
    private var range: TransformationRange? = null
    protected var reversed = false
@@ -130,7 +131,7 @@ internal open class OverscrollBuilderImpl : OverscrollBuilder {
        range = null
    }

    private fun transformation(transformation: PropertyTransformation<*>) {
    protected fun transformation(transformation: PropertyTransformation<*>) {
        val transformation =
            if (range != null) {
                RangedPropertyTransformation(transformation, range!!)
@@ -185,7 +186,7 @@ internal open class OverscrollBuilderImpl : OverscrollBuilder {
    }
}

internal class TransitionBuilderImpl : OverscrollBuilderImpl(), TransitionBuilder {
internal class TransitionBuilderImpl : BaseTransitionBuilderImpl(), TransitionBuilder {
    override var spec: AnimationSpec<Float> = spring(stiffness = Spring.StiffnessLow)
    override var swipeSpec: SpringSpec<Float>? = null
    override var distance: UserActionDistance? = null
@@ -226,3 +227,13 @@ internal class TransitionBuilderImpl : OverscrollBuilderImpl(), TransitionBuilde
        fractionRange(start, end, builder)
    }
}

internal open class OverscrollBuilderImpl : BaseTransitionBuilderImpl(), OverscrollBuilder {
    override fun translate(
        matcher: ElementMatcher,
        x: OverscrollScope.() -> Float,
        y: OverscrollScope.() -> Float
    ) {
        transformation(OverscrollTranslate(matcher, x, y))
    }
}
Loading