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

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

Merge "Migrate Element to ApproachLayoutModifierNode" into main

parents 8ba3cbca 81f95711
Loading
Loading
Loading
Loading
+37 −22
Original line number Diff line number Diff line
@@ -29,13 +29,17 @@ import androidx.compose.ui.geometry.lerp
import androidx.compose.ui.graphics.CompositingStrategy
import androidx.compose.ui.graphics.drawscope.ContentDrawScope
import androidx.compose.ui.graphics.drawscope.scale
import androidx.compose.ui.layout.IntermediateMeasureScope
import androidx.compose.ui.layout.ApproachLayoutModifierNode
import androidx.compose.ui.layout.ApproachMeasureScope
import androidx.compose.ui.layout.LayoutCoordinates
import androidx.compose.ui.layout.LookaheadScope
import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.MeasureResult
import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.layout.intermediateLayout
import androidx.compose.ui.node.DrawModifierNode
import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.testTag
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.round
@@ -91,23 +95,7 @@ internal fun Modifier.element(
    layoutImpl: SceneTransitionLayoutImpl,
    scene: Scene,
    key: ElementKey,
): Modifier {
    return this.then(ElementModifier(layoutImpl, scene, key))
        // TODO(b/311132415): Move this into ElementNode once we can create a delegate
        // IntermediateLayoutModifierNode.
        .intermediateLayout { measurable, constraints ->
            // TODO(b/311132415): No need to fetch the element and sceneState from the map anymore
            // once this is merged into ElementNode.
            val element = layoutImpl.elements.getValue(key)
            val sceneState = element.sceneStates.getValue(scene.key)

            val placeable = measure(layoutImpl, scene, element, sceneState, measurable, constraints)
            layout(placeable.width, placeable.height) {
                place(layoutImpl, scene, element, sceneState, placeable, placementScope = this)
            }
        }
        .testTag(key.testTag)
}
): Modifier = this.then(ElementModifier(layoutImpl, scene, key)).testTag(key.testTag)

/**
 * An element associated to [ElementNode]. Note that this element does not support updates as its
@@ -129,7 +117,7 @@ internal class ElementNode(
    private var layoutImpl: SceneTransitionLayoutImpl,
    private var scene: Scene,
    private var key: ElementKey,
) : Modifier.Node(), DrawModifierNode {
) : Modifier.Node(), DrawModifierNode, ApproachLayoutModifierNode {
    private var _element: Element? = null
    private val element: Element
        get() = _element!!
@@ -197,6 +185,31 @@ internal class ElementNode(
        maybePruneMaps(layoutImpl, prevElement, prevSceneState)
    }

    override fun isMeasurementApproachComplete(lookaheadSize: IntSize): Boolean {
        // TODO(b/324191441): Investigate whether making this check more complex (checking if this
        // element is shared or transformed) would lead to better performance.
        return layoutImpl.state.currentTransition == null
    }

    override fun Placeable.PlacementScope.isPlacementApproachComplete(
        lookaheadCoordinates: LayoutCoordinates
    ): Boolean {
        // TODO(b/324191441): Investigate whether making this check more complex (checking if this
        // element is shared or transformed) would lead to better performance.
        return layoutImpl.state.currentTransition == null
    }

    @ExperimentalComposeUiApi
    override fun ApproachMeasureScope.approachMeasure(
        measurable: Measurable,
        constraints: Constraints,
    ): MeasureResult {
        val placeable = measure(layoutImpl, scene, element, sceneState, measurable, constraints)
        return layout(placeable.width, placeable.height) {
            place(layoutImpl, scene, element, sceneState, placeable, placementScope = this)
        }
    }

    override fun ContentDrawScope.draw() {
        val drawScale = getDrawScale(layoutImpl, element, scene)
        if (drawScale == Scale.Default) {
@@ -368,7 +381,7 @@ private fun elementAlpha(
}

@OptIn(ExperimentalComposeUiApi::class)
private fun IntermediateMeasureScope.measure(
private fun ApproachMeasureScope.measure(
    layoutImpl: SceneTransitionLayoutImpl,
    scene: Scene,
    element: Element,
@@ -431,7 +444,7 @@ private fun getDrawScale(
}

@OptIn(ExperimentalComposeUiApi::class)
private fun IntermediateMeasureScope.place(
private fun ApproachMeasureScope.place(
    layoutImpl: SceneTransitionLayoutImpl,
    scene: Scene,
    element: Element,
@@ -439,6 +452,8 @@ private fun IntermediateMeasureScope.place(
    placeable: Placeable,
    placementScope: Placeable.PlacementScope,
) {
    this as LookaheadScope

    with(placementScope) {
        // Update the offset (relative to the SceneTransitionLayout) this element has in this scene
        // when idle.