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

Commit 21b36280 authored by omarmt's avatar omarmt
Browse files

STL: Add ProgressConverter class [1/2]

This new class will make it easier to create new progress value
converters, and it will provide better support from the IDE during
autocomplete.

Added two functions (linear and tanh) to generate these converter and a
default value.

Test: Just a refactor
Bug: 336710600
Flag: com.android.systemui.scene_container
Change-Id: If72a6d31de2709680ec596e36e526b9bb06e0c6f
parent 5e3c0c44
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 })