• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.mechanics.demo.staging
18 
19 import androidx.compose.runtime.Composable
20 import androidx.compose.runtime.LaunchedEffect
21 import androidx.compose.runtime.SideEffect
22 import androidx.compose.runtime.remember
23 import androidx.compose.ui.platform.LocalViewConfiguration
24 import com.android.mechanics.DistanceGestureContext
25 import com.android.mechanics.GestureContext
26 import com.android.mechanics.MotionValue
27 import com.android.mechanics.spec.InputDirection
28 import com.android.mechanics.spec.MotionSpec
29 
30 @Composable
rememberMotionValuenull31 fun rememberMotionValue(
32     input: () -> Float,
33     spec: () -> MotionSpec,
34     gestureContext: GestureContext,
35     stableThreshold: Float = 0.01f,
36     label: String? = null,
37 ): MotionValue {
38     val motionValue =
39         remember(input) {
40             MotionValue(
41                 input,
42                 gestureContext,
43                 initialSpec = spec(),
44                 label = label,
45                 stableThreshold = stableThreshold,
46             )
47         }
48 
49     val currentSpec = spec()
50     SideEffect {
51         // New spec is intentionally only applied after recomposition.
52         motionValue.spec = currentSpec
53     }
54 
55     LaunchedEffect(motionValue) { motionValue.keepRunning() }
56     return motionValue
57 }
58 
59 @Composable
rememberDerivedMotionValuenull60 fun rememberDerivedMotionValue(
61     input: MotionValue,
62     spec: () -> MotionSpec,
63     stableThreshold: Float = 0.01f,
64     label: String? = null,
65 ): MotionValue {
66     val motionValue =
67         remember(input) {
68             MotionValue.createDerived(
69                 input,
70                 initialSpec = spec(),
71                 label = label,
72                 stableThreshold = stableThreshold,
73             )
74         }
75 
76     val currentSpec = spec()
77     SideEffect {
78         // New spec is intentionally only applied after recomposition.
79         motionValue.spec = currentSpec
80     }
81 
82     LaunchedEffect(motionValue) { motionValue.keepRunning() }
83     return motionValue
84 }
85 
86 @Composable
rememberDistanceGestureContextnull87 fun rememberDistanceGestureContext(
88     initDistance: Float = 0f,
89     initialDirection: InputDirection = InputDirection.Max,
90 ): DistanceGestureContext {
91     val touchSlop = LocalViewConfiguration.current.touchSlop
92     val gestureContext = remember {
93         DistanceGestureContext(initDistance, initialDirection, touchSlop)
94     }
95 
96     return gestureContext
97 }
98