1 package com.android.systemui.navigationbar.gestural
2
3 import android.content.res.Resources
4 import android.util.TypedValue
5 import androidx.core.animation.Interpolator
6 import androidx.core.animation.PathInterpolator
7 import androidx.dynamicanimation.animation.SpringForce
8 import com.android.systemui.res.R
9
10 data class EdgePanelParams(private var resources: Resources) {
11
12 data class ArrowDimens(
13 val length: Float? = 0f,
14 val height: Float? = 0f,
15 val alpha: Float = 0f,
16 val heightSpring: SpringForce? = null,
17 val lengthSpring: SpringForce? = null,
18 var alphaSpring: Step<SpringForce>? = null,
19 var alphaInterpolator: Step<Float>? = null
20 )
21
22 data class BackgroundDimens(
23 val width: Float? = 0f,
24 val height: Float = 0f,
25 val edgeCornerRadius: Float = 0f,
26 val farCornerRadius: Float = 0f,
27 val alpha: Float = 0f,
28 val widthSpring: SpringForce? = null,
29 val heightSpring: SpringForce? = null,
30 val farCornerRadiusSpring: SpringForce? = null,
31 val edgeCornerRadiusSpring: SpringForce? = null,
32 val alphaSpring: SpringForce? = null,
33 )
34
35 data class BackIndicatorDimens(
36 val horizontalTranslation: Float? = 0f,
37 val scale: Float = 0f,
38 val scalePivotX: Float? = null,
39 val arrowDimens: ArrowDimens,
40 val backgroundDimens: BackgroundDimens,
41 val verticalTranslationSpring: SpringForce? = null,
42 val horizontalTranslationSpring: SpringForce? = null,
43 val scaleSpring: SpringForce? = null,
44 )
45
46 lateinit var entryIndicator: BackIndicatorDimens
47 private set
48
49 lateinit var activeIndicator: BackIndicatorDimens
50 private set
51
52 lateinit var cancelledIndicator: BackIndicatorDimens
53 private set
54
55 lateinit var flungIndicator: BackIndicatorDimens
56 private set
57
58 lateinit var committedIndicator: BackIndicatorDimens
59 private set
60
61 lateinit var preThresholdIndicator: BackIndicatorDimens
62 private set
63
64 lateinit var fullyStretchedIndicator: BackIndicatorDimens
65 private set
66
67 // navigation bar edge constants
68 var arrowPaddingEnd: Int = 0
69 private set
70
71 var arrowThickness: Float = 0f
72 private set
73
74 // The closest to y
75 var minArrowYPosition: Int = 0
76 private set
77
78 var fingerOffset: Int = 0
79 private set
80
81 var staticTriggerThreshold: Float = 0f
82 private set
83
84 var reactivationTriggerThreshold: Float = 0f
85 private set
86
87 var deactivationTriggerThreshold: Float = 0f
88 get() = -field
89 private set
90
91 lateinit var dynamicTriggerThresholdRange: ClosedRange<Float>
92 private set
93
94 var swipeProgressThreshold: Float = 0f
95 private set
96
97 lateinit var entryWidthInterpolator: Interpolator
98 private set
99
100 lateinit var entryWidthTowardsEdgeInterpolator: Interpolator
101 private set
102
103 lateinit var activeWidthInterpolator: Interpolator
104 private set
105
106 lateinit var arrowAngleInterpolator: Interpolator
107 private set
108
109 lateinit var horizontalTranslationInterpolator: Interpolator
110 private set
111
112 lateinit var verticalTranslationInterpolator: Interpolator
113 private set
114
115 lateinit var farCornerInterpolator: Interpolator
116 private set
117
118 lateinit var edgeCornerInterpolator: Interpolator
119 private set
120
121 lateinit var heightInterpolator: Interpolator
122 private set
123
124 init {
125 update(resources)
126 }
127
getDimennull128 private fun getDimen(id: Int): Float {
129 return resources.getDimension(id)
130 }
131
getDimenFloatnull132 private fun getDimenFloat(id: Int): Float {
133 return TypedValue().run {
134 resources.getValue(id, this, true)
135 float
136 }
137 }
138
getPxnull139 private fun getPx(id: Int): Int {
140 return resources.getDimensionPixelSize(id)
141 }
142
updatenull143 fun update(resources: Resources) {
144 this.resources = resources
145 arrowThickness = getDimen(R.dimen.navigation_edge_arrow_thickness)
146 arrowPaddingEnd = getPx(R.dimen.navigation_edge_panel_padding)
147 minArrowYPosition = getPx(R.dimen.navigation_edge_arrow_min_y)
148 fingerOffset = getPx(R.dimen.navigation_edge_finger_offset)
149 staticTriggerThreshold = getDimen(R.dimen.navigation_edge_action_drag_threshold)
150 reactivationTriggerThreshold =
151 getDimen(R.dimen.navigation_edge_action_reactivation_drag_threshold)
152 deactivationTriggerThreshold =
153 getDimen(R.dimen.navigation_edge_action_deactivation_drag_threshold)
154 dynamicTriggerThresholdRange = reactivationTriggerThreshold..deactivationTriggerThreshold
155 swipeProgressThreshold = getDimen(R.dimen.navigation_edge_action_progress_threshold)
156
157 entryWidthInterpolator = PathInterpolator(.19f, 1.27f, .71f, .86f)
158 entryWidthTowardsEdgeInterpolator = PathInterpolator(1f, -3f, 1f, 1.2f)
159 activeWidthInterpolator = PathInterpolator(.7f, -0.24f, .48f, 1.21f)
160 arrowAngleInterpolator = entryWidthInterpolator
161 horizontalTranslationInterpolator = PathInterpolator(0.2f, 1.0f, 1.0f, 1.0f)
162 verticalTranslationInterpolator = PathInterpolator(.5f, 1.15f, .41f, .94f)
163 farCornerInterpolator = PathInterpolator(.03f, .19f, .14f, 1.09f)
164 edgeCornerInterpolator = PathInterpolator(0f, 1.11f, .85f, .84f)
165 heightInterpolator = PathInterpolator(1f, .05f, .9f, -0.29f)
166
167 val activeCommittedArrowLengthSpring = createSpring(1500f, 0.29f)
168 val activeCommittedArrowHeightSpring = createSpring(1500f, 0.29f)
169 val flungCommittedEdgeCornerSpring = createSpring(10000f, 1f)
170 val flungCommittedFarCornerSpring = createSpring(10000f, 1f)
171 val flungCommittedWidthSpring = createSpring(10000f, 1f)
172 val flungCommittedHeightSpring = createSpring(10000f, 1f)
173
174 val commonArrowDimensAlphaThreshold = .165f
175 val commonArrowDimensAlphaFactor = 1.05f
176 val commonArrowDimensAlphaSpring =
177 Step(
178 threshold = commonArrowDimensAlphaThreshold,
179 factor = commonArrowDimensAlphaFactor,
180 postThreshold = createSpring(180f, 0.9f),
181 preThreshold = createSpring(2000f, 0.6f)
182 )
183 val commonArrowDimensAlphaSpringInterpolator =
184 Step(
185 threshold = commonArrowDimensAlphaThreshold,
186 factor = commonArrowDimensAlphaFactor,
187 postThreshold = 1f,
188 preThreshold = 0f
189 )
190
191 entryIndicator =
192 BackIndicatorDimens(
193 horizontalTranslation = getDimen(R.dimen.navigation_edge_entry_margin),
194 scale = getDimenFloat(R.dimen.navigation_edge_entry_scale),
195 scalePivotX = getDimen(R.dimen.navigation_edge_pre_threshold_background_width),
196 horizontalTranslationSpring = createSpring(800f, 0.76f),
197 verticalTranslationSpring = createSpring(30000f, 1f),
198 scaleSpring = createSpring(120f, 0.8f),
199 arrowDimens =
200 ArrowDimens(
201 length = getDimen(R.dimen.navigation_edge_entry_arrow_length),
202 height = getDimen(R.dimen.navigation_edge_entry_arrow_height),
203 alpha = 0f,
204 lengthSpring = createSpring(600f, 0.4f),
205 heightSpring = createSpring(600f, 0.4f),
206 alphaSpring = commonArrowDimensAlphaSpring,
207 alphaInterpolator = commonArrowDimensAlphaSpringInterpolator
208 ),
209 backgroundDimens =
210 BackgroundDimens(
211 alpha = 1f,
212 width = getDimen(R.dimen.navigation_edge_entry_background_width),
213 height = getDimen(R.dimen.navigation_edge_entry_background_height),
214 edgeCornerRadius = getDimen(R.dimen.navigation_edge_entry_edge_corners),
215 farCornerRadius = getDimen(R.dimen.navigation_edge_entry_far_corners),
216 widthSpring = createSpring(450f, 0.65f),
217 heightSpring = createSpring(1500f, 0.45f),
218 farCornerRadiusSpring = createSpring(300f, 0.5f),
219 edgeCornerRadiusSpring = createSpring(150f, 0.5f),
220 )
221 )
222
223 activeIndicator =
224 BackIndicatorDimens(
225 horizontalTranslation = getDimen(R.dimen.navigation_edge_active_margin),
226 scale = getDimenFloat(R.dimen.navigation_edge_active_scale),
227 horizontalTranslationSpring = createSpring(1000f, 0.8f),
228 scaleSpring = createSpring(325f, 0.55f),
229 scalePivotX = getDimen(R.dimen.navigation_edge_active_background_width),
230 arrowDimens =
231 ArrowDimens(
232 length = getDimen(R.dimen.navigation_edge_active_arrow_length),
233 height = getDimen(R.dimen.navigation_edge_active_arrow_height),
234 alpha = 1f,
235 lengthSpring = activeCommittedArrowLengthSpring,
236 heightSpring = activeCommittedArrowHeightSpring,
237 alphaSpring = commonArrowDimensAlphaSpring,
238 alphaInterpolator = commonArrowDimensAlphaSpringInterpolator
239 ),
240 backgroundDimens =
241 BackgroundDimens(
242 alpha = 1f,
243 width = getDimen(R.dimen.navigation_edge_active_background_width),
244 height = getDimen(R.dimen.navigation_edge_active_background_height),
245 edgeCornerRadius = getDimen(R.dimen.navigation_edge_active_edge_corners),
246 farCornerRadius = getDimen(R.dimen.navigation_edge_active_far_corners),
247 widthSpring = createSpring(850f, 0.75f),
248 heightSpring = createSpring(10000f, 1f),
249 edgeCornerRadiusSpring = createSpring(2600f, 0.855f),
250 farCornerRadiusSpring = createSpring(1200f, 0.30f),
251 )
252 )
253
254 preThresholdIndicator =
255 BackIndicatorDimens(
256 horizontalTranslation = getDimen(R.dimen.navigation_edge_pre_threshold_margin),
257 scale = getDimenFloat(R.dimen.navigation_edge_pre_threshold_scale),
258 scalePivotX = getDimen(R.dimen.navigation_edge_pre_threshold_background_width),
259 scaleSpring = createSpring(120f, 0.8f),
260 horizontalTranslationSpring = createSpring(6000f, 1f),
261 arrowDimens =
262 ArrowDimens(
263 length = getDimen(R.dimen.navigation_edge_pre_threshold_arrow_length),
264 height = getDimen(R.dimen.navigation_edge_pre_threshold_arrow_height),
265 alpha = 1f,
266 lengthSpring = createSpring(100f, 0.6f),
267 heightSpring = createSpring(100f, 0.6f),
268 alphaSpring = commonArrowDimensAlphaSpring,
269 alphaInterpolator = commonArrowDimensAlphaSpringInterpolator
270 ),
271 backgroundDimens =
272 BackgroundDimens(
273 alpha = 1f,
274 width = getDimen(R.dimen.navigation_edge_pre_threshold_background_width),
275 height = getDimen(R.dimen.navigation_edge_pre_threshold_background_height),
276 edgeCornerRadius =
277 getDimen(R.dimen.navigation_edge_pre_threshold_edge_corners),
278 farCornerRadius =
279 getDimen(R.dimen.navigation_edge_pre_threshold_far_corners),
280 widthSpring = createSpring(650f, 1f),
281 heightSpring = createSpring(1500f, 0.45f),
282 farCornerRadiusSpring = createSpring(300f, 1f),
283 edgeCornerRadiusSpring = createSpring(250f, 0.5f),
284 )
285 )
286
287 committedIndicator =
288 activeIndicator.copy(
289 horizontalTranslation = null,
290 scalePivotX = null,
291 arrowDimens =
292 activeIndicator.arrowDimens.copy(
293 lengthSpring = activeCommittedArrowLengthSpring,
294 heightSpring = activeCommittedArrowHeightSpring,
295 length = null,
296 height = null,
297 ),
298 backgroundDimens =
299 activeIndicator.backgroundDimens.copy(
300 alpha = 0f,
301 // explicitly set to null to preserve previous width upon state change
302 width = null,
303 widthSpring = flungCommittedWidthSpring,
304 heightSpring = flungCommittedHeightSpring,
305 edgeCornerRadiusSpring = flungCommittedEdgeCornerSpring,
306 farCornerRadiusSpring = flungCommittedFarCornerSpring,
307 alphaSpring = createSpring(1400f, 1f),
308 ),
309 scale = 0.86f,
310 scaleSpring = createSpring(5700f, 1f),
311 )
312
313 flungIndicator =
314 committedIndicator.copy(
315 arrowDimens =
316 committedIndicator.arrowDimens.copy(
317 lengthSpring = createSpring(850f, 0.46f),
318 heightSpring = createSpring(850f, 0.46f),
319 length = activeIndicator.arrowDimens.length,
320 height = activeIndicator.arrowDimens.height
321 ),
322 backgroundDimens =
323 committedIndicator.backgroundDimens.copy(
324 widthSpring = flungCommittedWidthSpring,
325 heightSpring = flungCommittedHeightSpring,
326 edgeCornerRadiusSpring = flungCommittedEdgeCornerSpring,
327 farCornerRadiusSpring = flungCommittedFarCornerSpring,
328 )
329 )
330
331 cancelledIndicator =
332 entryIndicator.copy(
333 backgroundDimens =
334 entryIndicator.backgroundDimens.copy(
335 width = 0f,
336 alpha = 0f,
337 alphaSpring = createSpring(450f, 1f)
338 )
339 )
340
341 fullyStretchedIndicator =
342 BackIndicatorDimens(
343 horizontalTranslation = getDimen(R.dimen.navigation_edge_stretch_margin),
344 scale = getDimenFloat(R.dimen.navigation_edge_stretch_scale),
345 horizontalTranslationSpring = null,
346 verticalTranslationSpring = null,
347 scaleSpring = null,
348 arrowDimens =
349 ArrowDimens(
350 length = getDimen(R.dimen.navigation_edge_stretched_arrow_length),
351 height = getDimen(R.dimen.navigation_edge_stretched_arrow_height),
352 alpha = 1f,
353 alphaSpring = null,
354 heightSpring = null,
355 lengthSpring = null,
356 ),
357 backgroundDimens =
358 BackgroundDimens(
359 alpha = 1f,
360 width = getDimen(R.dimen.navigation_edge_stretch_background_width),
361 height = getDimen(R.dimen.navigation_edge_stretch_background_height),
362 edgeCornerRadius = getDimen(R.dimen.navigation_edge_stretch_edge_corners),
363 farCornerRadius = getDimen(R.dimen.navigation_edge_stretch_far_corners),
364 alphaSpring = null,
365 widthSpring = null,
366 heightSpring = null,
367 edgeCornerRadiusSpring = null,
368 farCornerRadiusSpring = null,
369 )
370 )
371 }
372 }
373
createSpringnull374 fun createSpring(stiffness: Float, dampingRatio: Float): SpringForce {
375 return SpringForce().setStiffness(stiffness).setDampingRatio(dampingRatio)
376 }
377