@@ -63,40 +63,85 @@ fun Slider(
63
63
enabled : Boolean = true,
64
64
valueRange : ClosedFloatingPointRange <Float > = 0f..1f,
65
65
steps : Int = 0,
66
+ snap : Boolean = steps != 0,
67
+ showTickMark : Boolean = steps != 0,
66
68
onValueChangeFinished : ((Float ) -> Unit )? = null,
69
+ tooltipContent : @Composable (SliderState ) -> Unit = { SliderDefaults .Tooltip (it, snap = snap) },
67
70
interactionSource : MutableInteractionSource = remember { MutableInteractionSource () },
68
71
) {
69
- Slider (
72
+ BasicSlider (
70
73
value = value,
71
74
onValueChange = onValueChange,
72
75
modifier = modifier,
73
76
enabled = enabled,
74
77
valueRange = valueRange,
75
78
steps = steps,
79
+ snap = snap,
76
80
onValueChangeFinished = onValueChangeFinished,
77
81
interactionSource = interactionSource,
78
- rail = { state -> SliderDefaults .Rail (state, enabled = enabled) },
79
- track = { state -> SliderDefaults .Track (state, enabled = enabled) },
80
- thumb = { state -> SliderDefaults .Thumb (state, enabled = enabled) }
82
+ rail = { state ->
83
+ SliderDefaults .Rail (
84
+ state = state,
85
+ enabled = enabled,
86
+ showTick = showTickMark
87
+ )
88
+ },
89
+ track = { state ->
90
+ SliderDefaults .Track (state, enabled = enabled)
91
+ },
92
+ thumb = { state ->
93
+ SliderDefaults .Thumb (state, enabled = enabled, label = tooltipContent)
94
+ }
81
95
)
82
96
}
83
97
84
98
@Composable
85
99
fun Slider (
100
+ state : SliderState ,
101
+ modifier : Modifier = Modifier ,
102
+ enabled : Boolean = true,
103
+ showTickMark : Boolean = state.steps != 0,
104
+ tooltipContent : @Composable (SliderState ) -> Unit = { SliderDefaults .Tooltip (it, snap = state.snap) },
105
+ interactionSource : MutableInteractionSource = remember { MutableInteractionSource () },
106
+ ) {
107
+ BasicSlider (
108
+ state = state,
109
+ modifier = modifier,
110
+ enabled = enabled,
111
+ interactionSource = interactionSource,
112
+ rail = { state ->
113
+ SliderDefaults .Rail (
114
+ state = state,
115
+ enabled = enabled,
116
+ showTick = showTickMark
117
+ )
118
+ },
119
+ track = { state ->
120
+ SliderDefaults .Track (state, enabled = enabled)
121
+ },
122
+ thumb = { state ->
123
+ SliderDefaults .Thumb (state, enabled = enabled, label = tooltipContent)
124
+ }
125
+ )
126
+ }
127
+
128
+ @Composable
129
+ fun BasicSlider (
86
130
value : Float ,
87
131
onValueChange : (Float ) -> Unit ,
88
132
modifier : Modifier = Modifier ,
89
133
enabled : Boolean = true,
90
134
valueRange : ClosedFloatingPointRange <Float > = 0f..1f,
91
135
steps : Int = 0,
136
+ snap : Boolean = steps != 0,
92
137
onValueChangeFinished : ((Float ) -> Unit )? = null,
93
138
interactionSource : MutableInteractionSource = remember { MutableInteractionSource () },
94
139
rail : @Composable (SliderState ) -> Unit ,
95
140
track : @Composable (SliderState ) -> Unit ,
96
141
thumb : @Composable (SliderState ) -> Unit ,
97
142
) {
98
143
val state =
99
- remember(steps, valueRange) { SliderState (value, steps, onValueChangeFinished, valueRange) }
144
+ remember(steps, valueRange) { SliderState (value, steps, snap, onValueChangeFinished, valueRange) }
100
145
state.value = value
101
146
state.onValueChangeFinished = onValueChangeFinished
102
147
state.onValueChange = onValueChange
@@ -113,25 +158,7 @@ fun Slider(
113
158
}
114
159
115
160
@Composable
116
- fun Slider (
117
- state : SliderState ,
118
- modifier : Modifier = Modifier ,
119
- enabled : Boolean = true,
120
- interactionSource : MutableInteractionSource = remember { MutableInteractionSource () }
121
- ) {
122
- SliderImpl (
123
- modifier = modifier,
124
- state = state,
125
- enabled = enabled,
126
- interactionSource = interactionSource,
127
- rail = { state -> SliderDefaults .Rail (state, enabled = enabled) },
128
- track = { state -> SliderDefaults .Track (state, enabled = enabled) },
129
- thumb = { state -> SliderDefaults .Thumb (state, enabled = enabled) }
130
- )
131
- }
132
-
133
- @Composable
134
- fun Slider (
161
+ fun BasicSlider (
135
162
state : SliderState ,
136
163
modifier : Modifier = Modifier ,
137
164
enabled : Boolean = true,
@@ -233,6 +260,7 @@ private fun SliderImpl(
233
260
class SliderState (
234
261
value : Float = 0f ,
235
262
val steps : Int = 0 ,
263
+ val snap : Boolean = steps != 0 ,
236
264
var onValueChangeFinished : ((Float ) -> Unit )? = null ,
237
265
val valueRange : ClosedFloatingPointRange <Float >
238
266
) {
@@ -301,10 +329,15 @@ class SliderState(
301
329
// Snap
302
330
// TODO: Add snap animation, maybe we should use anchoredDraggable?
303
331
val currentValue = this .value
304
- val nearestValue = snapToNearestTickValue(currentValue)
305
- val fraction = valueToFraction(nearestValue, this .valueRange)
306
- this .value = nearestValue
307
- setRawFraction(fraction, width, density)
332
+ if (this .snap) {
333
+ val nearestValue = snapToNearestTickValue(currentValue)
334
+ val fraction = valueToFraction(nearestValue, this .valueRange)
335
+ this .value = nearestValue
336
+ setRawFraction(fraction, width, density)
337
+ } else {
338
+ val fraction = valueToFraction(currentValue, this .valueRange)
339
+ setRawFraction(fraction, width, density)
340
+ }
308
341
}
309
342
310
343
this .onValueChangeFinished?.invoke(this .value)
@@ -316,6 +349,12 @@ class SliderState(
316
349
.map { lerp(this .valueRange.start, this .valueRange.endInclusive, it) }
317
350
.minBy { abs(it - value) }
318
351
}
352
+
353
+ fun nearestValue (): Float {
354
+ return this .stepFractions
355
+ .map { lerp(this .valueRange.start, this .valueRange.endInclusive, it) }
356
+ .minBy { abs(it - value) }
357
+ }
319
358
}
320
359
321
360
private fun getStepFractions (steps : Int ): FloatArray {
@@ -561,7 +600,7 @@ object SliderDefaults {
561
600
}
562
601
563
602
@Composable
564
- fun Tooltip (state : SliderState , snap : Boolean = state.steps != 0 ) {
603
+ fun Tooltip (state : SliderState , snap : Boolean = state.snap ) {
565
604
Text (
566
605
if (snap) state.snapToNearestTickValue(state.value).toString()
567
606
else state.value.toString()
0 commit comments