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

Commit f743c078 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "STL: Add ProgressConverter class [1/2]" into main

parents 78e5497b 21b36280
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1106,7 +1106,7 @@ private inline fun <T> computeValue(
            val directionSign = if (transition.isUpOrLeft) -1 else 1
            val isToContent = overscroll.scene == transition.toContent
            val linearProgress = transition.progress.let { if (isToContent) it - 1f else it }
            val progress = directionSign * overscroll.progressConverter(linearProgress)
            val progress = directionSign * overscroll.progressConverter.convert(linearProgress)
            val rangeProgress = propertySpec.range?.progress(progress) ?: progress

            // Interpolate between the value at rest and the over scrolled value.
+2 −2
Original line number Diff line number Diff line
@@ -282,14 +282,14 @@ interface OverscrollSpec {
     * - 1, the user overscrolled by exactly the [OverscrollBuilder.distance].
     * - Greater than 1, the user overscrolled more than the [OverscrollBuilder.distance].
     */
    val progressConverter: (Float) -> Float
    val progressConverter: ProgressConverter
}

internal class OverscrollSpecImpl(
    override val scene: SceneKey,
    override val orientation: Orientation,
    override val transformationSpec: TransformationSpecImpl,
    override val progressConverter: (Float) -> Float,
    override val progressConverter: ProgressConverter,
) : OverscrollSpec

/**
+34 −1
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.android.compose.animation.scene.content.state.ContentState
import kotlin.math.tanh

/** Define the [transitions][SceneTransitions] to be used with a [SceneTransitionLayout]. */
fun transitions(builder: SceneTransitionsBuilder.() -> Unit): SceneTransitions {
@@ -216,7 +217,7 @@ interface OverscrollBuilder : BaseTransitionBuilder {
     * - 1, the user overscrolled by exactly the [distance].
     * - Greater than 1, the user overscrolled more than the [distance].
     */
    var progressConverter: (Float) -> Float
    var progressConverter: ProgressConverter

    /** Translate the element(s) matching [matcher] by ([x], [y]) pixels. */
    fun translate(
@@ -510,3 +511,35 @@ interface PropertyTransformationBuilder {
        anchorHeight: Boolean = true,
    )
}

/** This converter lets you change a linear progress into a function of your choice. */
fun interface ProgressConverter {
    fun convert(progress: Float): Float

    companion object {
        /** Keeps scrolling linearly */
        val Default = linear()

        /**
         * The scroll stays linear, with [factor] you can control how much resistance there is.
         *
         * @param factor If you choose a value between 0f and 1f, the progress will grow more
         *   slowly, like there's resistance. A value of 1f means there's no resistance.
         */
        fun linear(factor: Float = 1f) = ProgressConverter { it * factor }

        /**
         * This function starts linear and slowly approaches [maxProgress].
         *
         * See a [visual representation](https://www.desmos.com/calculator/usgvvf0z1u) of this
         * function.
         *
         * @param maxProgress is the maximum progress value.
         * @param tilt behaves similarly to the factor in the [linear] function, and allows you to
         *   control how quickly you get to the [maxProgress].
         */
        fun tanh(maxProgress: Float, tilt: Float = 1f) = ProgressConverter {
            maxProgress * tanh(x = it / (maxProgress * tilt))
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -271,7 +271,7 @@ internal class TransitionBuilderImpl : BaseTransitionBuilderImpl(), TransitionBu
}

internal open class OverscrollBuilderImpl : BaseTransitionBuilderImpl(), OverscrollBuilder {
    override var progressConverter: (Float) -> Float = { it }
    override var progressConverter: ProgressConverter = ProgressConverter.Default

    override fun translate(
        matcher: ElementMatcher,
+1 −1
Original line number Diff line number Diff line
@@ -972,7 +972,7 @@ class ElementTest {
                sceneTransitions = {
                    overscroll(SceneB, Orientation.Vertical) {
                        // Overscroll progress will be halved
                        progressConverter = { it / 2f }
                        progressConverter = ProgressConverter { it / 2f }

                        // On overscroll 100% -> Foo should translate by layoutHeight
                        translate(TestElements.Foo, y = { absoluteDistance })