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

Commit 99a000c3 authored by Jordan Demeulenaere's avatar Jordan Demeulenaere
Browse files

Move TransformationRange outside of Transformation

This CL is a small refactoring that moves TransformationRange outside of
the Transformation interface. Ranges are defined outside transformations
and not inside, so it does not make sense to have it in Transformation.

Bug: 376438969
Test: atest PlatformComposeSceneTransitionLayoutTests
Flag: com.android.systemui.scene_container
Change-Id: Ib58305cdeff11d6e4af588be7c9f74c092a89753
parent 9392f149
Loading
Loading
Loading
Loading
+10 −8
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import com.android.compose.animation.scene.content.Content
import com.android.compose.animation.scene.content.state.TransitionState
import com.android.compose.animation.scene.transformation.PropertyTransformation
import com.android.compose.animation.scene.transformation.SharedElementTransformation
import com.android.compose.animation.scene.transformation.TransformationWithRange
import com.android.compose.modifiers.thenIf
import com.android.compose.ui.graphics.drawInContainer
import com.android.compose.ui.util.lerp
@@ -187,6 +188,7 @@ private fun Modifier.maybeElevateInContent(
                state.transformationSpec
                    .transformations(key, content.key)
                    .shared
                    ?.transformation
                    ?.elevateInContent == content.key &&
                isSharedElement(stateByContent, state) &&
                isSharedElementEnabled(key, state) &&
@@ -901,7 +903,7 @@ private fun shouldPlaceElement(
    }

    val sharedTransformation = sharedElementTransformation(element.key, transition)
    if (sharedTransformation?.enabled == false) {
    if (sharedTransformation?.transformation?.enabled == false) {
        return true
    }

@@ -954,13 +956,13 @@ private fun isSharedElementEnabled(
    element: ElementKey,
    transition: TransitionState.Transition,
): Boolean {
    return sharedElementTransformation(element, transition)?.enabled ?: true
    return sharedElementTransformation(element, transition)?.transformation?.enabled ?: true
}

internal fun sharedElementTransformation(
    element: ElementKey,
    transition: TransitionState.Transition,
): SharedElementTransformation? {
): TransformationWithRange<SharedElementTransformation>? {
    val transformationSpec = transition.transformationSpec
    val sharedInFromContent =
        transformationSpec.transformations(element, transition.fromContent).shared
@@ -1244,7 +1246,7 @@ private inline fun <T> computeValue(
    element: Element,
    transition: TransitionState.Transition?,
    contentValue: (Element.State) -> T,
    transformation: (ElementTransformations) -> PropertyTransformation<T>?,
    transformation: (ElementTransformations) -> TransformationWithRange<PropertyTransformation<T>>?,
    currentValue: () -> T,
    isSpecified: (T) -> Boolean,
    lerp: (T, T, Float) -> T,
@@ -1280,7 +1282,7 @@ private inline fun <T> computeValue(
                checkNotNull(if (currentContent == toContent) toState else fromState)
            val idleValue = contentValue(overscrollState)
            val targetValue =
                with(propertySpec) {
                with(propertySpec.transformation) {
                    layoutImpl.propertyTransformationScope.transform(
                        currentContent,
                        element.key,
@@ -1375,7 +1377,7 @@ private inline fun <T> computeValue(
        val idleValue = contentValue(contentState)
        val isEntering = content == toContent
        val previewTargetValue =
            with(previewTransformation) {
            with(previewTransformation.transformation) {
                layoutImpl.propertyTransformationScope.transform(
                    content,
                    element.key,
@@ -1386,7 +1388,7 @@ private inline fun <T> computeValue(

        val targetValueOrNull =
            transformation?.let { transformation ->
                with(transformation) {
                with(transformation.transformation) {
                    layoutImpl.propertyTransformationScope.transform(
                        content,
                        element.key,
@@ -1461,7 +1463,7 @@ private inline fun <T> computeValue(

    val idleValue = contentValue(contentState)
    val targetValue =
        with(transformation) {
        with(transformation.transformation) {
            layoutImpl.propertyTransformationScope.transform(
                content,
                element.key,
+2 −1
Original line number Diff line number Diff line
@@ -764,7 +764,8 @@ internal class MutableSceneTransitionLayoutStateImpl(
                    return@fastForEach
                }

                state.transformationSpec.transformations.fastForEach { transformation ->
                state.transformationSpec.transformations.fastForEach { transformationWithRange ->
                    val transformation = transformationWithRange.transformation
                    if (
                        transformation is SharedElementTransformation &&
                            transformation.elevateInContent != null
+45 −39
Original line number Diff line number Diff line
@@ -33,10 +33,10 @@ 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
import com.android.compose.animation.scene.transformation.SharedElementTransformation
import com.android.compose.animation.scene.transformation.Transformation
import com.android.compose.animation.scene.transformation.TransformationWithRange
import com.android.compose.animation.scene.transformation.Translate

/** The transitions configuration of a [SceneTransitionLayout]. */
@@ -233,7 +233,7 @@ interface TransformationSpec {
    val distance: UserActionDistance?

    /** The list of [Transformation] applied to elements during this transition. */
    val transformations: List<Transformation>
    val transformations: List<TransformationWithRange<*>>

    companion object {
        internal val Empty =
@@ -325,7 +325,7 @@ internal class TransformationSpecImpl(
    override val progressSpec: AnimationSpec<Float>,
    override val swipeSpec: SpringSpec<Float>?,
    override val distance: UserActionDistance?,
    override val transformations: List<Transformation>,
    override val transformations: List<TransformationWithRange<*>>,
) : TransformationSpec {
    private val cache = mutableMapOf<ElementKey, MutableMap<ContentKey, ElementTransformations>>()

@@ -340,59 +340,65 @@ internal class TransformationSpecImpl(
        element: ElementKey,
        content: ContentKey,
    ): ElementTransformations {
        var shared: SharedElementTransformation? = null
        var offset: PropertyTransformation<Offset>? = null
        var size: PropertyTransformation<IntSize>? = null
        var drawScale: PropertyTransformation<Scale>? = null
        var alpha: PropertyTransformation<Float>? = null

        fun <T> onPropertyTransformation(
            root: PropertyTransformation<T>,
            current: PropertyTransformation<T> = root,
        ) {
            when (current) {
        var shared: TransformationWithRange<SharedElementTransformation>? = null
        var offset: TransformationWithRange<PropertyTransformation<Offset>>? = null
        var size: TransformationWithRange<PropertyTransformation<IntSize>>? = null
        var drawScale: TransformationWithRange<PropertyTransformation<Scale>>? = null
        var alpha: TransformationWithRange<PropertyTransformation<Float>>? = null

        transformations.fastForEach { transformationWithRange ->
            val transformation = transformationWithRange.transformation
            if (!transformation.matcher.matches(element, content)) {
                return@fastForEach
            }

            when (transformation) {
                is SharedElementTransformation -> {
                    throwIfNotNull(shared, element, name = "shared")
                    shared =
                        transformationWithRange
                            as TransformationWithRange<SharedElementTransformation>
                }
                is Translate,
                is OverscrollTranslate,
                is EdgeTranslate,
                is AnchoredTranslate -> {
                    throwIfNotNull(offset, element, name = "offset")
                    offset = root as PropertyTransformation<Offset>
                    offset =
                        transformationWithRange
                            as TransformationWithRange<PropertyTransformation<Offset>>
                }
                is ScaleSize,
                is AnchoredSize -> {
                    throwIfNotNull(size, element, name = "size")
                    size = root as PropertyTransformation<IntSize>
                    size =
                        transformationWithRange
                            as TransformationWithRange<PropertyTransformation<IntSize>>
                }
                is DrawScale -> {
                    throwIfNotNull(drawScale, element, name = "drawScale")
                    drawScale = root as PropertyTransformation<Scale>
                    drawScale =
                        transformationWithRange
                            as TransformationWithRange<PropertyTransformation<Scale>>
                }
                is Fade -> {
                    throwIfNotNull(alpha, element, name = "alpha")
                    alpha = root as PropertyTransformation<Float>
                }
                is RangedPropertyTransformation -> onPropertyTransformation(root, current.delegate)
            }
                    alpha =
                        transformationWithRange
                            as TransformationWithRange<PropertyTransformation<Float>>
                }

        transformations.fastForEach { transformation ->
            if (!transformation.matcher.matches(element, content)) {
                return@fastForEach
            }

            when (transformation) {
                is SharedElementTransformation -> {
                    throwIfNotNull(shared, element, name = "shared")
                    shared = transformation
                }
                is PropertyTransformation<*> -> onPropertyTransformation(transformation)
                else -> error("Unknown transformation: $transformation")
            }
        }

        return ElementTransformations(shared, offset, size, drawScale, alpha)
    }

    private fun throwIfNotNull(previous: Transformation?, element: ElementKey, name: String) {
    private fun throwIfNotNull(
        previous: TransformationWithRange<*>?,
        element: ElementKey,
        name: String,
    ) {
        if (previous != null) {
            error("$element has multiple $name transformations")
        }
@@ -401,9 +407,9 @@ internal class TransformationSpecImpl(

/** The transformations of an element during a transition. */
internal class ElementTransformations(
    val shared: SharedElementTransformation?,
    val offset: PropertyTransformation<Offset>?,
    val size: PropertyTransformation<IntSize>?,
    val drawScale: PropertyTransformation<Scale>?,
    val alpha: PropertyTransformation<Float>?,
    val shared: TransformationWithRange<SharedElementTransformation>?,
    val offset: TransformationWithRange<PropertyTransformation<Offset>>?,
    val size: TransformationWithRange<PropertyTransformation<IntSize>>?,
    val drawScale: TransformationWithRange<PropertyTransformation<Scale>>?,
    val alpha: TransformationWithRange<PropertyTransformation<Float>>?,
)
+7 −14
Original line number Diff line number Diff line
@@ -34,12 +34,11 @@ 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
import com.android.compose.animation.scene.transformation.SharedElementTransformation
import com.android.compose.animation.scene.transformation.Transformation
import com.android.compose.animation.scene.transformation.TransformationRange
import com.android.compose.animation.scene.transformation.TransformationWithRange
import com.android.compose.animation.scene.transformation.Translate

internal fun transitionsImpl(builder: SceneTransitionsBuilder.() -> Unit): SceneTransitions {
@@ -158,7 +157,7 @@ private class SceneTransitionsBuilderImpl : SceneTransitionsBuilder {
}

internal abstract class BaseTransitionBuilderImpl : BaseTransitionBuilder {
    val transformations = mutableListOf<Transformation>()
    val transformations = mutableListOf<TransformationWithRange<*>>()
    private var range: TransformationRange? = null
    protected var reversed = false
    override var distance: UserActionDistance? = null
@@ -174,19 +173,13 @@ internal abstract class BaseTransitionBuilderImpl : BaseTransitionBuilder {
        range = null
    }

    protected fun transformation(transformation: PropertyTransformation<*>) {
        val transformation =
            if (range != null) {
                RangedPropertyTransformation(transformation, range!!)
            } else {
                transformation
            }

    protected fun transformation(transformation: Transformation) {
        val transformationWithRange = TransformationWithRange(transformation, range)
        transformations.add(
            if (reversed) {
                transformation.reversed()
                transformationWithRange.reversed()
            } else {
                transformation
                transformationWithRange
            }
        )
    }
@@ -264,7 +257,7 @@ internal class TransitionBuilderImpl(override val transition: TransitionState.Tr
                "(${transition.toContent.debugName})"
        }

        transformations.add(SharedElementTransformation(matcher, enabled, elevateInContent))
        transformation(SharedElementTransformation(matcher, enabled, elevateInContent))
    }

    override fun timestampRange(
+0 −1
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@ internal class DrawScale(
    private val scaleY: Float,
    private val pivot: Offset = Offset.Unspecified,
) : PropertyTransformation<Scale> {

    override fun PropertyTransformationScope.transform(
        content: ContentKey,
        element: ElementKey,
Loading