Loading packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt +38 −77 Original line number Original line Diff line number Diff line Loading @@ -371,96 +371,57 @@ private fun prepareInterruption( transition: TransitionState.Transition, transition: TransitionState.Transition, previousTransition: TransitionState.Transition, previousTransition: TransitionState.Transition, ) { ) { val previousUniqueState = reconcileStates(element, previousTransition) val sceneStates = element.sceneStates if (previousUniqueState == null) { sceneStates[previousTransition.fromScene]?.selfUpdateValuesBeforeInterruption() reconcileStates(element, transition) sceneStates[previousTransition.toScene]?.selfUpdateValuesBeforeInterruption() return sceneStates[transition.fromScene]?.selfUpdateValuesBeforeInterruption() } sceneStates[transition.toScene]?.selfUpdateValuesBeforeInterruption() val fromSceneState = element.sceneStates[transition.fromScene] val toSceneState = element.sceneStates[transition.toScene] if ( reconcileStates(element, previousTransition) fromSceneState == null || reconcileStates(element, transition) toSceneState == null || sharedElementTransformation(element.key, transition)?.enabled != false ) { // If there is only one copy of the element or if the element is shared, animate deltas in // both scenes. fromSceneState?.updateValuesBeforeInterruption(previousUniqueState) toSceneState?.updateValuesBeforeInterruption(previousUniqueState) } } } /** /** * Reconcile the state of [element] in the fromScene and toScene of [transition] so that the values * Reconcile the state of [element] in the fromScene and toScene of [transition] so that the values * before interruption have their expected values, taking shared transitions into account. * before interruption have their expected values, taking shared transitions into account. * * If the element had a unique state, i.e. it is shared in [transition] or it is only present in one * of the scenes, return it. */ */ private fun reconcileStates( private fun reconcileStates( element: Element, element: Element, transition: TransitionState.Transition, transition: TransitionState.Transition, ): Element.SceneState? { ) { val fromSceneState = element.sceneStates[transition.fromScene] val fromSceneState = element.sceneStates[transition.fromScene] ?: return val toSceneState = element.sceneStates[transition.toScene] val toSceneState = element.sceneStates[transition.toScene] ?: return when { if (!isSharedElementEnabled(element.key, transition)) { // Element is in both scenes. return fromSceneState != null && toSceneState != null -> { val isSharedTransformationDisabled = sharedElementTransformation(element.key, transition)?.enabled == false when { // Element shared transition is disabled so the element is placed in both scenes. isSharedTransformationDisabled -> { fromSceneState.updateValuesBeforeInterruption(fromSceneState) toSceneState.updateValuesBeforeInterruption(toSceneState) return null } } if ( fromSceneState.offsetBeforeInterruption != Offset.Unspecified && toSceneState.offsetBeforeInterruption == Offset.Unspecified ) { // Element is shared and placed in fromScene only. // Element is shared and placed in fromScene only. fromSceneState.lastOffset != Offset.Unspecified -> { fromSceneState.updateValuesBeforeInterruption(fromSceneState) toSceneState.updateValuesBeforeInterruption(fromSceneState) toSceneState.updateValuesBeforeInterruption(fromSceneState) return fromSceneState } else if ( } toSceneState.offsetBeforeInterruption != Offset.Unspecified && fromSceneState.offsetBeforeInterruption == Offset.Unspecified ) { // Element is shared and placed in toScene only. // Element is shared and placed in toScene only. toSceneState.lastOffset != Offset.Unspecified -> { fromSceneState.updateValuesBeforeInterruption(toSceneState) fromSceneState.updateValuesBeforeInterruption(toSceneState) toSceneState.updateValuesBeforeInterruption(toSceneState) return toSceneState } // Element is in none of the scenes. else -> { fromSceneState.updateValuesBeforeInterruption(null) toSceneState.updateValuesBeforeInterruption(null) return null } } } } // Element is only in fromScene. fromSceneState != null -> { fromSceneState.updateValuesBeforeInterruption(fromSceneState) return fromSceneState } } // Element is only in toScene. private fun Element.SceneState.selfUpdateValuesBeforeInterruption() { toSceneState != null -> { offsetBeforeInterruption = lastOffset toSceneState.updateValuesBeforeInterruption(toSceneState) sizeBeforeInterruption = lastSize return toSceneState scaleBeforeInterruption = lastScale } alphaBeforeInterruption = lastAlpha else -> return null } } } private fun Element.SceneState.updateValuesBeforeInterruption(lastState: Element.SceneState?) { private fun Element.SceneState.updateValuesBeforeInterruption(lastState: Element.SceneState) { offsetBeforeInterruption = lastState?.lastOffset ?: Offset.Unspecified offsetBeforeInterruption = lastState.offsetBeforeInterruption sizeBeforeInterruption = lastState?.lastSize ?: Element.SizeUnspecified sizeBeforeInterruption = lastState.sizeBeforeInterruption scaleBeforeInterruption = lastState?.lastScale ?: Scale.Unspecified scaleBeforeInterruption = lastState.scaleBeforeInterruption alphaBeforeInterruption = lastState?.lastAlpha ?: Element.AlphaUnspecified alphaBeforeInterruption = lastState.alphaBeforeInterruption clearInterruptionDeltas() clearInterruptionDeltas() } } Loading Loading
packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt +38 −77 Original line number Original line Diff line number Diff line Loading @@ -371,96 +371,57 @@ private fun prepareInterruption( transition: TransitionState.Transition, transition: TransitionState.Transition, previousTransition: TransitionState.Transition, previousTransition: TransitionState.Transition, ) { ) { val previousUniqueState = reconcileStates(element, previousTransition) val sceneStates = element.sceneStates if (previousUniqueState == null) { sceneStates[previousTransition.fromScene]?.selfUpdateValuesBeforeInterruption() reconcileStates(element, transition) sceneStates[previousTransition.toScene]?.selfUpdateValuesBeforeInterruption() return sceneStates[transition.fromScene]?.selfUpdateValuesBeforeInterruption() } sceneStates[transition.toScene]?.selfUpdateValuesBeforeInterruption() val fromSceneState = element.sceneStates[transition.fromScene] val toSceneState = element.sceneStates[transition.toScene] if ( reconcileStates(element, previousTransition) fromSceneState == null || reconcileStates(element, transition) toSceneState == null || sharedElementTransformation(element.key, transition)?.enabled != false ) { // If there is only one copy of the element or if the element is shared, animate deltas in // both scenes. fromSceneState?.updateValuesBeforeInterruption(previousUniqueState) toSceneState?.updateValuesBeforeInterruption(previousUniqueState) } } } /** /** * Reconcile the state of [element] in the fromScene and toScene of [transition] so that the values * Reconcile the state of [element] in the fromScene and toScene of [transition] so that the values * before interruption have their expected values, taking shared transitions into account. * before interruption have their expected values, taking shared transitions into account. * * If the element had a unique state, i.e. it is shared in [transition] or it is only present in one * of the scenes, return it. */ */ private fun reconcileStates( private fun reconcileStates( element: Element, element: Element, transition: TransitionState.Transition, transition: TransitionState.Transition, ): Element.SceneState? { ) { val fromSceneState = element.sceneStates[transition.fromScene] val fromSceneState = element.sceneStates[transition.fromScene] ?: return val toSceneState = element.sceneStates[transition.toScene] val toSceneState = element.sceneStates[transition.toScene] ?: return when { if (!isSharedElementEnabled(element.key, transition)) { // Element is in both scenes. return fromSceneState != null && toSceneState != null -> { val isSharedTransformationDisabled = sharedElementTransformation(element.key, transition)?.enabled == false when { // Element shared transition is disabled so the element is placed in both scenes. isSharedTransformationDisabled -> { fromSceneState.updateValuesBeforeInterruption(fromSceneState) toSceneState.updateValuesBeforeInterruption(toSceneState) return null } } if ( fromSceneState.offsetBeforeInterruption != Offset.Unspecified && toSceneState.offsetBeforeInterruption == Offset.Unspecified ) { // Element is shared and placed in fromScene only. // Element is shared and placed in fromScene only. fromSceneState.lastOffset != Offset.Unspecified -> { fromSceneState.updateValuesBeforeInterruption(fromSceneState) toSceneState.updateValuesBeforeInterruption(fromSceneState) toSceneState.updateValuesBeforeInterruption(fromSceneState) return fromSceneState } else if ( } toSceneState.offsetBeforeInterruption != Offset.Unspecified && fromSceneState.offsetBeforeInterruption == Offset.Unspecified ) { // Element is shared and placed in toScene only. // Element is shared and placed in toScene only. toSceneState.lastOffset != Offset.Unspecified -> { fromSceneState.updateValuesBeforeInterruption(toSceneState) fromSceneState.updateValuesBeforeInterruption(toSceneState) toSceneState.updateValuesBeforeInterruption(toSceneState) return toSceneState } // Element is in none of the scenes. else -> { fromSceneState.updateValuesBeforeInterruption(null) toSceneState.updateValuesBeforeInterruption(null) return null } } } } // Element is only in fromScene. fromSceneState != null -> { fromSceneState.updateValuesBeforeInterruption(fromSceneState) return fromSceneState } } // Element is only in toScene. private fun Element.SceneState.selfUpdateValuesBeforeInterruption() { toSceneState != null -> { offsetBeforeInterruption = lastOffset toSceneState.updateValuesBeforeInterruption(toSceneState) sizeBeforeInterruption = lastSize return toSceneState scaleBeforeInterruption = lastScale } alphaBeforeInterruption = lastAlpha else -> return null } } } private fun Element.SceneState.updateValuesBeforeInterruption(lastState: Element.SceneState?) { private fun Element.SceneState.updateValuesBeforeInterruption(lastState: Element.SceneState) { offsetBeforeInterruption = lastState?.lastOffset ?: Offset.Unspecified offsetBeforeInterruption = lastState.offsetBeforeInterruption sizeBeforeInterruption = lastState?.lastSize ?: Element.SizeUnspecified sizeBeforeInterruption = lastState.sizeBeforeInterruption scaleBeforeInterruption = lastState?.lastScale ?: Scale.Unspecified scaleBeforeInterruption = lastState.scaleBeforeInterruption alphaBeforeInterruption = lastState?.lastAlpha ?: Element.AlphaUnspecified alphaBeforeInterruption = lastState.alphaBeforeInterruption clearInterruptionDeltas() clearInterruptionDeltas() } } Loading