Loading packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt +3 −3 Original line number Diff line number Diff line Loading @@ -913,9 +913,9 @@ private class Swipes( internal class NestedScrollHandlerImpl( private val layoutImpl: SceneTransitionLayoutImpl, private val orientation: Orientation, private val topOrLeftBehavior: NestedScrollBehavior, private val bottomOrRightBehavior: NestedScrollBehavior, private val isExternalOverscrollGesture: () -> Boolean, internal var topOrLeftBehavior: NestedScrollBehavior, internal var bottomOrRightBehavior: NestedScrollBehavior, internal var isExternalOverscrollGesture: () -> Boolean, private val pointersInfoOwner: PointersInfoOwner, ) { private val layoutState = layoutImpl.state Loading packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt +1 −6 Original line number Diff line number Diff line Loading @@ -41,7 +41,6 @@ import androidx.compose.ui.node.DelegatingNode import androidx.compose.ui.node.ModifierNodeElement import androidx.compose.ui.node.ObserverModifierNode import androidx.compose.ui.node.PointerInputModifierNode import androidx.compose.ui.node.TraversableNode import androidx.compose.ui.node.currentValueOf import androidx.compose.ui.node.findNearestAncestor import androidx.compose.ui.node.observeReads Loading Loading @@ -139,16 +138,12 @@ internal class MultiPointerDraggableNode( DelegatingNode(), PointerInputModifierNode, CompositionLocalConsumerModifierNode, TraversableNode, PointersInfoOwner, ObserverModifierNode { private val pointerInputHandler: suspend PointerInputScope.() -> Unit = { pointerInput() } private val delegate = delegate(SuspendingPointerInputModifierNode(pointerInputHandler)) private val velocityTracker = VelocityTracker() private var previousEnabled: Boolean = false override val traverseKey: Any = TRAVERSE_KEY var enabled: () -> Boolean = enabled set(value) { // Reset the pointer input whenever enabled changed. Loading Loading @@ -208,7 +203,7 @@ internal class MultiPointerDraggableNode( private var startedPosition: Offset? = null private var pointersDown: Int = 0 override fun pointersInfo(): PointersInfo { internal fun pointersInfo(): PointersInfo { return PointersInfo( startedPosition = startedPosition, // Note: We could have 0 pointers during fling or for other reasons. Loading packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/NestedScrollToScene.kt +8 −72 Original line number Diff line number Diff line Loading @@ -22,11 +22,9 @@ import androidx.compose.ui.geometry.Offset import androidx.compose.ui.input.nestedscroll.NestedScrollConnection import androidx.compose.ui.input.nestedscroll.NestedScrollSource import androidx.compose.ui.input.nestedscroll.nestedScrollModifierNode import androidx.compose.ui.node.DelegatableNode import androidx.compose.ui.node.DelegatingNode import androidx.compose.ui.node.ModifierNodeElement import androidx.compose.ui.platform.InspectorInfo import com.android.compose.nestedscroll.PriorityNestedScrollConnection /** * Defines the behavior of the [SceneTransitionLayout] when a scrollable component is scrolled. Loading Loading @@ -70,7 +68,11 @@ enum class NestedScrollBehavior(val canStartOnPostFling: Boolean) { * In addition, during scene transitions, scroll events are consumed by the * [SceneTransitionLayout] instead of the scrollable component. */ EdgeAlways(canStartOnPostFling = true), EdgeAlways(canStartOnPostFling = true); companion object { val Default = EdgeNoPreview } } internal fun Modifier.nestedScrollToScene( Loading Loading @@ -131,7 +133,6 @@ private class NestedScrollToSceneNode( private var bottomOrRightBehavior: NestedScrollBehavior, private var isExternalOverscrollGesture: () -> Boolean, ) : DelegatingNode() { lateinit var pointersInfoOwner: PointersInfoOwner private var scrollBehaviorOwner: ScrollBehaviorOwner? = null private fun requireScrollBehaviorOwner(): ScrollBehaviorOwner { Loading @@ -143,7 +144,7 @@ private class NestedScrollToSceneNode( return behaviorOwner } val updateScrollBehaviorsConnection = private val updateScrollBehaviorsConnection = object : NestedScrollConnection { /** * When using [NestedScrollConnection.onPostScroll], we can specify the desired behavior Loading Loading @@ -174,37 +175,11 @@ private class NestedScrollToSceneNode( } } private var priorityNestedScrollConnection: PriorityNestedScrollConnection = scenePriorityNestedScrollConnection( layoutImpl = layoutImpl, orientation = orientation, topOrLeftBehavior = topOrLeftBehavior, bottomOrRightBehavior = bottomOrRightBehavior, isExternalOverscrollGesture = isExternalOverscrollGesture, pointersInfoOwner = { pointersInfoOwner.pointersInfo() } ) private var nestedScrollNode: DelegatableNode = nestedScrollModifierNode( connection = priorityNestedScrollConnection, dispatcher = null, ) private var updateScrollBehaviorsNestedScrollNode: DelegatableNode = nestedScrollModifierNode( connection = updateScrollBehaviorsConnection, dispatcher = null, ) override fun onAttach() { pointersInfoOwner = requireAncestorPointersInfoOwner() delegate(nestedScrollNode) delegate(updateScrollBehaviorsNestedScrollNode) init { delegate(nestedScrollModifierNode(updateScrollBehaviorsConnection, dispatcher = null)) } override fun onDetach() { // Make sure we reset the scroll connection when this modifier is removed from composition priorityNestedScrollConnection.reset() scrollBehaviorOwner = null } Loading @@ -220,44 +195,5 @@ private class NestedScrollToSceneNode( this.topOrLeftBehavior = topOrLeftBehavior this.bottomOrRightBehavior = bottomOrRightBehavior this.isExternalOverscrollGesture = isExternalOverscrollGesture // Clean up the old nested scroll connection priorityNestedScrollConnection.reset() undelegate(nestedScrollNode) // Create a new nested scroll connection priorityNestedScrollConnection = scenePriorityNestedScrollConnection( layoutImpl = layoutImpl, orientation = orientation, topOrLeftBehavior = topOrLeftBehavior, bottomOrRightBehavior = bottomOrRightBehavior, isExternalOverscrollGesture = isExternalOverscrollGesture, pointersInfoOwner = pointersInfoOwner, ) nestedScrollNode = nestedScrollModifierNode( connection = priorityNestedScrollConnection, dispatcher = null, ) delegate(nestedScrollNode) } } private fun scenePriorityNestedScrollConnection( layoutImpl: SceneTransitionLayoutImpl, orientation: Orientation, topOrLeftBehavior: NestedScrollBehavior, bottomOrRightBehavior: NestedScrollBehavior, isExternalOverscrollGesture: () -> Boolean, pointersInfoOwner: PointersInfoOwner, ) = NestedScrollHandlerImpl( layoutImpl = layoutImpl, orientation = orientation, topOrLeftBehavior = topOrLeftBehavior, bottomOrRightBehavior = bottomOrRightBehavior, isExternalOverscrollGesture = isExternalOverscrollGesture, pointersInfoOwner = pointersInfoOwner, ) .connection packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt +4 −4 Original line number Diff line number Diff line Loading @@ -207,8 +207,8 @@ interface BaseSceneScope : ElementStateScope { * @param rightBehavior when we should perform the overscroll animation at the right. */ fun Modifier.horizontalNestedScrollToScene( leftBehavior: NestedScrollBehavior = NestedScrollBehavior.EdgeNoPreview, rightBehavior: NestedScrollBehavior = NestedScrollBehavior.EdgeNoPreview, leftBehavior: NestedScrollBehavior = NestedScrollBehavior.Default, rightBehavior: NestedScrollBehavior = NestedScrollBehavior.Default, isExternalOverscrollGesture: () -> Boolean = { false }, ): Modifier Loading @@ -220,8 +220,8 @@ interface BaseSceneScope : ElementStateScope { * @param bottomBehavior when we should perform the overscroll animation at the bottom. */ fun Modifier.verticalNestedScrollToScene( topBehavior: NestedScrollBehavior = NestedScrollBehavior.EdgeNoPreview, bottomBehavior: NestedScrollBehavior = NestedScrollBehavior.EdgeNoPreview, topBehavior: NestedScrollBehavior = NestedScrollBehavior.Default, bottomBehavior: NestedScrollBehavior = NestedScrollBehavior.Default, isExternalOverscrollGesture: () -> Boolean = { false }, ): Modifier Loading packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt +26 −5 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import androidx.compose.foundation.gestures.Orientation import androidx.compose.runtime.Stable import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.input.nestedscroll.nestedScrollModifierNode import androidx.compose.ui.input.pointer.PointerEvent import androidx.compose.ui.input.pointer.PointerEventPass import androidx.compose.ui.node.DelegatableNode Loading Loading @@ -81,8 +82,24 @@ private class SwipeToSceneNode( } } override fun onAttach() { delegate(ScrollBehaviorOwnerNode(draggableHandler.nestedScrollKey)) private val nestedScrollHandlerImpl = NestedScrollHandlerImpl( layoutImpl = draggableHandler.layoutImpl, orientation = draggableHandler.orientation, topOrLeftBehavior = NestedScrollBehavior.Default, bottomOrRightBehavior = NestedScrollBehavior.Default, isExternalOverscrollGesture = { false }, pointersInfoOwner = { multiPointerDraggableNode.pointersInfo() }, ) init { delegate(nestedScrollModifierNode(nestedScrollHandlerImpl.connection, dispatcher = null)) delegate(ScrollBehaviorOwnerNode(draggableHandler.nestedScrollKey, nestedScrollHandlerImpl)) } override fun onDetach() { // Make sure we reset the scroll connection when this modifier is removed from composition nestedScrollHandlerImpl.connection.reset() } override fun onPointerEvent( Loading Loading @@ -151,13 +168,17 @@ internal fun interface ScrollBehaviorOwner { * * TODO(b/353234530) move this logic into [SwipeToSceneNode] */ private class ScrollBehaviorOwnerNode(override val traverseKey: Any) : Modifier.Node(), TraversableNode, ScrollBehaviorOwner { private class ScrollBehaviorOwnerNode( override val traverseKey: Any, val nestedScrollHandlerImpl: NestedScrollHandlerImpl ) : Modifier.Node(), TraversableNode, ScrollBehaviorOwner { override fun updateScrollBehaviors( topOrLeftBehavior: NestedScrollBehavior, bottomOrRightBehavior: NestedScrollBehavior, isExternalOverscrollGesture: () -> Boolean ) { // This method will be used to update the desired behavior in a following CL. nestedScrollHandlerImpl.topOrLeftBehavior = topOrLeftBehavior nestedScrollHandlerImpl.bottomOrRightBehavior = bottomOrRightBehavior nestedScrollHandlerImpl.isExternalOverscrollGesture = isExternalOverscrollGesture } } Loading
packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt +3 −3 Original line number Diff line number Diff line Loading @@ -913,9 +913,9 @@ private class Swipes( internal class NestedScrollHandlerImpl( private val layoutImpl: SceneTransitionLayoutImpl, private val orientation: Orientation, private val topOrLeftBehavior: NestedScrollBehavior, private val bottomOrRightBehavior: NestedScrollBehavior, private val isExternalOverscrollGesture: () -> Boolean, internal var topOrLeftBehavior: NestedScrollBehavior, internal var bottomOrRightBehavior: NestedScrollBehavior, internal var isExternalOverscrollGesture: () -> Boolean, private val pointersInfoOwner: PointersInfoOwner, ) { private val layoutState = layoutImpl.state Loading
packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt +1 −6 Original line number Diff line number Diff line Loading @@ -41,7 +41,6 @@ import androidx.compose.ui.node.DelegatingNode import androidx.compose.ui.node.ModifierNodeElement import androidx.compose.ui.node.ObserverModifierNode import androidx.compose.ui.node.PointerInputModifierNode import androidx.compose.ui.node.TraversableNode import androidx.compose.ui.node.currentValueOf import androidx.compose.ui.node.findNearestAncestor import androidx.compose.ui.node.observeReads Loading Loading @@ -139,16 +138,12 @@ internal class MultiPointerDraggableNode( DelegatingNode(), PointerInputModifierNode, CompositionLocalConsumerModifierNode, TraversableNode, PointersInfoOwner, ObserverModifierNode { private val pointerInputHandler: suspend PointerInputScope.() -> Unit = { pointerInput() } private val delegate = delegate(SuspendingPointerInputModifierNode(pointerInputHandler)) private val velocityTracker = VelocityTracker() private var previousEnabled: Boolean = false override val traverseKey: Any = TRAVERSE_KEY var enabled: () -> Boolean = enabled set(value) { // Reset the pointer input whenever enabled changed. Loading Loading @@ -208,7 +203,7 @@ internal class MultiPointerDraggableNode( private var startedPosition: Offset? = null private var pointersDown: Int = 0 override fun pointersInfo(): PointersInfo { internal fun pointersInfo(): PointersInfo { return PointersInfo( startedPosition = startedPosition, // Note: We could have 0 pointers during fling or for other reasons. Loading
packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/NestedScrollToScene.kt +8 −72 Original line number Diff line number Diff line Loading @@ -22,11 +22,9 @@ import androidx.compose.ui.geometry.Offset import androidx.compose.ui.input.nestedscroll.NestedScrollConnection import androidx.compose.ui.input.nestedscroll.NestedScrollSource import androidx.compose.ui.input.nestedscroll.nestedScrollModifierNode import androidx.compose.ui.node.DelegatableNode import androidx.compose.ui.node.DelegatingNode import androidx.compose.ui.node.ModifierNodeElement import androidx.compose.ui.platform.InspectorInfo import com.android.compose.nestedscroll.PriorityNestedScrollConnection /** * Defines the behavior of the [SceneTransitionLayout] when a scrollable component is scrolled. Loading Loading @@ -70,7 +68,11 @@ enum class NestedScrollBehavior(val canStartOnPostFling: Boolean) { * In addition, during scene transitions, scroll events are consumed by the * [SceneTransitionLayout] instead of the scrollable component. */ EdgeAlways(canStartOnPostFling = true), EdgeAlways(canStartOnPostFling = true); companion object { val Default = EdgeNoPreview } } internal fun Modifier.nestedScrollToScene( Loading Loading @@ -131,7 +133,6 @@ private class NestedScrollToSceneNode( private var bottomOrRightBehavior: NestedScrollBehavior, private var isExternalOverscrollGesture: () -> Boolean, ) : DelegatingNode() { lateinit var pointersInfoOwner: PointersInfoOwner private var scrollBehaviorOwner: ScrollBehaviorOwner? = null private fun requireScrollBehaviorOwner(): ScrollBehaviorOwner { Loading @@ -143,7 +144,7 @@ private class NestedScrollToSceneNode( return behaviorOwner } val updateScrollBehaviorsConnection = private val updateScrollBehaviorsConnection = object : NestedScrollConnection { /** * When using [NestedScrollConnection.onPostScroll], we can specify the desired behavior Loading Loading @@ -174,37 +175,11 @@ private class NestedScrollToSceneNode( } } private var priorityNestedScrollConnection: PriorityNestedScrollConnection = scenePriorityNestedScrollConnection( layoutImpl = layoutImpl, orientation = orientation, topOrLeftBehavior = topOrLeftBehavior, bottomOrRightBehavior = bottomOrRightBehavior, isExternalOverscrollGesture = isExternalOverscrollGesture, pointersInfoOwner = { pointersInfoOwner.pointersInfo() } ) private var nestedScrollNode: DelegatableNode = nestedScrollModifierNode( connection = priorityNestedScrollConnection, dispatcher = null, ) private var updateScrollBehaviorsNestedScrollNode: DelegatableNode = nestedScrollModifierNode( connection = updateScrollBehaviorsConnection, dispatcher = null, ) override fun onAttach() { pointersInfoOwner = requireAncestorPointersInfoOwner() delegate(nestedScrollNode) delegate(updateScrollBehaviorsNestedScrollNode) init { delegate(nestedScrollModifierNode(updateScrollBehaviorsConnection, dispatcher = null)) } override fun onDetach() { // Make sure we reset the scroll connection when this modifier is removed from composition priorityNestedScrollConnection.reset() scrollBehaviorOwner = null } Loading @@ -220,44 +195,5 @@ private class NestedScrollToSceneNode( this.topOrLeftBehavior = topOrLeftBehavior this.bottomOrRightBehavior = bottomOrRightBehavior this.isExternalOverscrollGesture = isExternalOverscrollGesture // Clean up the old nested scroll connection priorityNestedScrollConnection.reset() undelegate(nestedScrollNode) // Create a new nested scroll connection priorityNestedScrollConnection = scenePriorityNestedScrollConnection( layoutImpl = layoutImpl, orientation = orientation, topOrLeftBehavior = topOrLeftBehavior, bottomOrRightBehavior = bottomOrRightBehavior, isExternalOverscrollGesture = isExternalOverscrollGesture, pointersInfoOwner = pointersInfoOwner, ) nestedScrollNode = nestedScrollModifierNode( connection = priorityNestedScrollConnection, dispatcher = null, ) delegate(nestedScrollNode) } } private fun scenePriorityNestedScrollConnection( layoutImpl: SceneTransitionLayoutImpl, orientation: Orientation, topOrLeftBehavior: NestedScrollBehavior, bottomOrRightBehavior: NestedScrollBehavior, isExternalOverscrollGesture: () -> Boolean, pointersInfoOwner: PointersInfoOwner, ) = NestedScrollHandlerImpl( layoutImpl = layoutImpl, orientation = orientation, topOrLeftBehavior = topOrLeftBehavior, bottomOrRightBehavior = bottomOrRightBehavior, isExternalOverscrollGesture = isExternalOverscrollGesture, pointersInfoOwner = pointersInfoOwner, ) .connection
packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt +4 −4 Original line number Diff line number Diff line Loading @@ -207,8 +207,8 @@ interface BaseSceneScope : ElementStateScope { * @param rightBehavior when we should perform the overscroll animation at the right. */ fun Modifier.horizontalNestedScrollToScene( leftBehavior: NestedScrollBehavior = NestedScrollBehavior.EdgeNoPreview, rightBehavior: NestedScrollBehavior = NestedScrollBehavior.EdgeNoPreview, leftBehavior: NestedScrollBehavior = NestedScrollBehavior.Default, rightBehavior: NestedScrollBehavior = NestedScrollBehavior.Default, isExternalOverscrollGesture: () -> Boolean = { false }, ): Modifier Loading @@ -220,8 +220,8 @@ interface BaseSceneScope : ElementStateScope { * @param bottomBehavior when we should perform the overscroll animation at the bottom. */ fun Modifier.verticalNestedScrollToScene( topBehavior: NestedScrollBehavior = NestedScrollBehavior.EdgeNoPreview, bottomBehavior: NestedScrollBehavior = NestedScrollBehavior.EdgeNoPreview, topBehavior: NestedScrollBehavior = NestedScrollBehavior.Default, bottomBehavior: NestedScrollBehavior = NestedScrollBehavior.Default, isExternalOverscrollGesture: () -> Boolean = { false }, ): Modifier Loading
packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt +26 −5 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import androidx.compose.foundation.gestures.Orientation import androidx.compose.runtime.Stable import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.input.nestedscroll.nestedScrollModifierNode import androidx.compose.ui.input.pointer.PointerEvent import androidx.compose.ui.input.pointer.PointerEventPass import androidx.compose.ui.node.DelegatableNode Loading Loading @@ -81,8 +82,24 @@ private class SwipeToSceneNode( } } override fun onAttach() { delegate(ScrollBehaviorOwnerNode(draggableHandler.nestedScrollKey)) private val nestedScrollHandlerImpl = NestedScrollHandlerImpl( layoutImpl = draggableHandler.layoutImpl, orientation = draggableHandler.orientation, topOrLeftBehavior = NestedScrollBehavior.Default, bottomOrRightBehavior = NestedScrollBehavior.Default, isExternalOverscrollGesture = { false }, pointersInfoOwner = { multiPointerDraggableNode.pointersInfo() }, ) init { delegate(nestedScrollModifierNode(nestedScrollHandlerImpl.connection, dispatcher = null)) delegate(ScrollBehaviorOwnerNode(draggableHandler.nestedScrollKey, nestedScrollHandlerImpl)) } override fun onDetach() { // Make sure we reset the scroll connection when this modifier is removed from composition nestedScrollHandlerImpl.connection.reset() } override fun onPointerEvent( Loading Loading @@ -151,13 +168,17 @@ internal fun interface ScrollBehaviorOwner { * * TODO(b/353234530) move this logic into [SwipeToSceneNode] */ private class ScrollBehaviorOwnerNode(override val traverseKey: Any) : Modifier.Node(), TraversableNode, ScrollBehaviorOwner { private class ScrollBehaviorOwnerNode( override val traverseKey: Any, val nestedScrollHandlerImpl: NestedScrollHandlerImpl ) : Modifier.Node(), TraversableNode, ScrollBehaviorOwner { override fun updateScrollBehaviors( topOrLeftBehavior: NestedScrollBehavior, bottomOrRightBehavior: NestedScrollBehavior, isExternalOverscrollGesture: () -> Boolean ) { // This method will be used to update the desired behavior in a following CL. nestedScrollHandlerImpl.topOrLeftBehavior = topOrLeftBehavior nestedScrollHandlerImpl.bottomOrRightBehavior = bottomOrRightBehavior nestedScrollHandlerImpl.isExternalOverscrollGesture = isExternalOverscrollGesture } }