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

Commit 4e6342e1 authored by Jordan Demeulenaere's avatar Jordan Demeulenaere
Browse files

Add ElementKey.placeAllCopies

This CL introduce ElementKey.placeAllCopies that makes an element place
all its copies during transitions, even when it is shared. This can be
useful for container elements that can have different contents in
different scenes/overlays (like in the dual shade case) but for which
the size and position should still be shared.

Bug: 353679003
Test: atest ElementTest
Flag: com.android.systemui.scene_container
Change-Id: I17675ea0abd3972a7f5c54bed63414f09b2c9b3a
parent 37cd9ee7
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -813,6 +813,10 @@ private fun shouldPlaceElement(
    element: Element,
    elementState: TransitionState,
): Boolean {
    if (element.key.placeAllCopies) {
        return true
    }

    val transition =
        when (elementState) {
            is TransitionState.Idle -> {
+10 −0
Original line number Diff line number Diff line
@@ -79,6 +79,16 @@ open class ElementKey(
     * or compose MovableElements.
     */
    open val contentPicker: ElementContentPicker = DefaultElementContentPicker,

    /**
     * Whether we should place all copies of this element when it is shared.
     *
     * This should usually be false, but it can be useful when sharing a container that has a
     * different content in different scenes/overlays. That way the container will have the same
     * size and position in all scenes/overlays but all different contents will be placed and
     * visible on screen.
     */
    val placeAllCopies: Boolean = false,
) : Key(debugName, identity), ElementMatcher {
    @VisibleForTesting
    // TODO(b/240432457): Make internal once PlatformComposeSceneTransitionLayoutTestsUtils can
+61 −0
Original line number Diff line number Diff line
@@ -2519,4 +2519,65 @@ class ElementTest {
            .onNode(hasTestTag(contentTestTag) and hasParent(isElement(movable)))
            .assertSizeIsEqualTo(40.dp)
    }

    @Test
    fun placeAllCopies() {
        val foo = ElementKey("Foo", placeAllCopies = true)

        @Composable
        fun SceneScope.Foo(size: Dp, modifier: Modifier = Modifier) {
            Box(modifier.element(foo).size(size))
        }

        rule.testTransition(
            fromSceneContent = { Box(Modifier.size(100.dp)) { Foo(size = 10.dp) } },
            toSceneContent = {
                Box(Modifier.size(100.dp)) {
                    Foo(size = 50.dp, Modifier.align(Alignment.BottomEnd))
                }
            },
            transition = { spec = tween(4 * 16, easing = LinearEasing) },
        ) {
            before {
                onElement(foo, SceneA)
                    .assertSizeIsEqualTo(10.dp)
                    .assertPositionInRootIsEqualTo(0.dp, 0.dp)
                onElement(foo, SceneB).assertDoesNotExist()
            }

            at(16) {
                onElement(foo, SceneA)
                    .assertSizeIsEqualTo(20.dp)
                    .assertPositionInRootIsEqualTo(12.5.dp, 12.5.dp)
                onElement(foo, SceneB)
                    .assertSizeIsEqualTo(20.dp)
                    .assertPositionInRootIsEqualTo(12.5.dp, 12.5.dp)
            }

            at(32) {
                onElement(foo, SceneA)
                    .assertSizeIsEqualTo(30.dp)
                    .assertPositionInRootIsEqualTo(25.dp, 25.dp)
                onElement(foo, SceneB)
                    .assertSizeIsEqualTo(30.dp)
                    .assertPositionInRootIsEqualTo(25.dp, 25.dp)
            }

            at(48) {
                onElement(foo, SceneA)
                    .assertSizeIsEqualTo(40.dp)
                    .assertPositionInRootIsEqualTo(37.5.dp, 37.5.dp)
                onElement(foo, SceneB)
                    .assertSizeIsEqualTo(40.dp)
                    .assertPositionInRootIsEqualTo(37.5.dp, 37.5.dp)
            }

            after {
                onElement(foo, SceneA).assertDoesNotExist()
                onElement(foo, SceneB)
                    .assertSizeIsEqualTo(50.dp)
                    .assertPositionInRootIsEqualTo(50.dp, 50.dp)
            }
        }
    }
}