Loading packages/SystemUI/compose/core/src/com/android/compose/gesture/OverscrollToDismiss.kt +32 −14 Original line number Diff line number Diff line Loading @@ -17,6 +17,10 @@ package com.android.compose.gesture import androidx.compose.foundation.gestures.Orientation import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.input.pointer.PointerType Loading Loading @@ -106,11 +110,34 @@ private class OverscrollToDismissNode( private val gestureContext = DistanceGestureContext(0f, InputDirection.Max, directionChangeSlop = 1f) private var dragState: DragState by mutableStateOf(DragState.Idle) enum class DragState { Idle, Dragging, Dismissed, } private val spec = derivedStateOf { with(motionBuilderContext) { when (dragState) { DragState.Idle -> fixedSpatialValueSpec(0f, SnapBackSpring) DragState.Dragging -> spatialMotionSpec { after(0f, MagneticDetach()) } DragState.Dismissed -> fixedSpatialValueSpec( contentBoxWidth.toFloat(), SnapBackSpring, listOf(isDismissedState with true), ) } } } private val motionValue = MotionValue( gestureContext::dragOffset, gestureContext, motionBuilderContext.fixedSpatialValueSpec(0f), input = { gestureContext.dragOffset }, gestureContext = gestureContext, spec = spec::value, ) private var delegateNode = Loading Loading @@ -161,7 +188,7 @@ private class OverscrollToDismissNode( ): NestedDraggable.Controller { overscrollSign = sign gestureContext.reset(dragOffset = motionValue.output, direction = InputDirection.Max) motionValue.spec = motionBuilderContext.spatialMotionSpec { after(0f, MagneticDetach()) } dragState = DragState.Dragging return this } Loading @@ -187,16 +214,7 @@ private class OverscrollToDismissNode( currentState == MagneticDetach.State.Attached || (currentState == MagneticDetach.State.Detached && isFlingInOppositeDirection) motionValue.spec = if (settleAttached) { motionBuilderContext.fixedSpatialValueSpec(0f, SnapBackSpring) } else { motionBuilderContext.fixedSpatialValueSpec( contentBoxWidth.toFloat(), SnapBackSpring, listOf(isDismissedState with true), ) } dragState = if (settleAttached) DragState.Idle else DragState.Dismissed } return velocity } Loading packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/mechanics/TransitionScopedMechanicsAdapter.kt +21 −9 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.compose.animation.scene.mechanics import androidx.annotation.VisibleForTesting import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.mutableFloatStateOf import com.android.compose.animation.scene.ContentKey import com.android.compose.animation.scene.ElementKey Loading Loading @@ -51,11 +52,13 @@ internal class TransitionScopedMechanicsAdapter( private val computeInput: MotionValueInput = { progress, _, _ -> progress }, private val stableThreshold: Float = MotionValue.StableThresholdEffect, private val label: String? = null, private val createSpec: SpecFactory, private val getSpec: SpecFactory, ) { private val input = mutableFloatStateOf(0f) private var motionValue: MotionValue? = null private var transformationContent: ContentKey? = null private var transformationElement: ElementKey? = null fun PropertyTransformationScope.update( content: ContentKey, Loading @@ -68,23 +71,32 @@ internal class TransitionScopedMechanicsAdapter( var motionValue = motionValue if (motionValue == null) { transformationContent = content transformationElement = element motionValue = MotionValue( input::floatValue, input = { input.floatValue }, gestureContext = transition.gestureContext ?: ProvidedGestureContext( 0f, appearDirection(content, element, transition), ), createSpec(content, element), stableThreshold = stableThreshold, spec = derivedStateOf { getSpec(content, element) }::value, label = label, stableThreshold = stableThreshold, ) this@TransitionScopedMechanicsAdapter.motionValue = motionValue transitionScope.launch { motionValue.keepRunningWhile { !transition.isProgressStable || !isStable } } } else { check(content == transformationContent && element == transformationElement) { "update received ($content, $element), " + "instead of ($transformationContent, $transformationElement)" } } return motionValue.output Loading packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/mechanics/TransitionScopedMechanicsAdapterTest.kt +1 −1 Original line number Diff line number Diff line Loading @@ -447,7 +447,7 @@ class TransitionScopedMechanicsAdapterTest { override val property = PropertyTransformation.Property.Offset val motionValue = TransitionScopedMechanicsAdapter(createSpec = specFactory, stableThreshold = 1f) TransitionScopedMechanicsAdapter(getSpec = specFactory, stableThreshold = 1f) override fun PropertyTransformationScope.transform( content: ContentKey, Loading Loading
packages/SystemUI/compose/core/src/com/android/compose/gesture/OverscrollToDismiss.kt +32 −14 Original line number Diff line number Diff line Loading @@ -17,6 +17,10 @@ package com.android.compose.gesture import androidx.compose.foundation.gestures.Orientation import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.input.pointer.PointerType Loading Loading @@ -106,11 +110,34 @@ private class OverscrollToDismissNode( private val gestureContext = DistanceGestureContext(0f, InputDirection.Max, directionChangeSlop = 1f) private var dragState: DragState by mutableStateOf(DragState.Idle) enum class DragState { Idle, Dragging, Dismissed, } private val spec = derivedStateOf { with(motionBuilderContext) { when (dragState) { DragState.Idle -> fixedSpatialValueSpec(0f, SnapBackSpring) DragState.Dragging -> spatialMotionSpec { after(0f, MagneticDetach()) } DragState.Dismissed -> fixedSpatialValueSpec( contentBoxWidth.toFloat(), SnapBackSpring, listOf(isDismissedState with true), ) } } } private val motionValue = MotionValue( gestureContext::dragOffset, gestureContext, motionBuilderContext.fixedSpatialValueSpec(0f), input = { gestureContext.dragOffset }, gestureContext = gestureContext, spec = spec::value, ) private var delegateNode = Loading Loading @@ -161,7 +188,7 @@ private class OverscrollToDismissNode( ): NestedDraggable.Controller { overscrollSign = sign gestureContext.reset(dragOffset = motionValue.output, direction = InputDirection.Max) motionValue.spec = motionBuilderContext.spatialMotionSpec { after(0f, MagneticDetach()) } dragState = DragState.Dragging return this } Loading @@ -187,16 +214,7 @@ private class OverscrollToDismissNode( currentState == MagneticDetach.State.Attached || (currentState == MagneticDetach.State.Detached && isFlingInOppositeDirection) motionValue.spec = if (settleAttached) { motionBuilderContext.fixedSpatialValueSpec(0f, SnapBackSpring) } else { motionBuilderContext.fixedSpatialValueSpec( contentBoxWidth.toFloat(), SnapBackSpring, listOf(isDismissedState with true), ) } dragState = if (settleAttached) DragState.Idle else DragState.Dismissed } return velocity } Loading
packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/mechanics/TransitionScopedMechanicsAdapter.kt +21 −9 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.compose.animation.scene.mechanics import androidx.annotation.VisibleForTesting import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.mutableFloatStateOf import com.android.compose.animation.scene.ContentKey import com.android.compose.animation.scene.ElementKey Loading Loading @@ -51,11 +52,13 @@ internal class TransitionScopedMechanicsAdapter( private val computeInput: MotionValueInput = { progress, _, _ -> progress }, private val stableThreshold: Float = MotionValue.StableThresholdEffect, private val label: String? = null, private val createSpec: SpecFactory, private val getSpec: SpecFactory, ) { private val input = mutableFloatStateOf(0f) private var motionValue: MotionValue? = null private var transformationContent: ContentKey? = null private var transformationElement: ElementKey? = null fun PropertyTransformationScope.update( content: ContentKey, Loading @@ -68,23 +71,32 @@ internal class TransitionScopedMechanicsAdapter( var motionValue = motionValue if (motionValue == null) { transformationContent = content transformationElement = element motionValue = MotionValue( input::floatValue, input = { input.floatValue }, gestureContext = transition.gestureContext ?: ProvidedGestureContext( 0f, appearDirection(content, element, transition), ), createSpec(content, element), stableThreshold = stableThreshold, spec = derivedStateOf { getSpec(content, element) }::value, label = label, stableThreshold = stableThreshold, ) this@TransitionScopedMechanicsAdapter.motionValue = motionValue transitionScope.launch { motionValue.keepRunningWhile { !transition.isProgressStable || !isStable } } } else { check(content == transformationContent && element == transformationElement) { "update received ($content, $element), " + "instead of ($transformationContent, $transformationElement)" } } return motionValue.output Loading
packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/mechanics/TransitionScopedMechanicsAdapterTest.kt +1 −1 Original line number Diff line number Diff line Loading @@ -447,7 +447,7 @@ class TransitionScopedMechanicsAdapterTest { override val property = PropertyTransformation.Property.Offset val motionValue = TransitionScopedMechanicsAdapter(createSpec = specFactory, stableThreshold = 1f) TransitionScopedMechanicsAdapter(getSpec = specFactory, stableThreshold = 1f) override fun PropertyTransformationScope.transform( content: ContentKey, Loading