@@ -27,14 +27,12 @@ import androidx.compose.ui.graphics.Brush
2727import androidx.compose.ui.graphics.Color
2828import androidx.compose.ui.graphics.TileMode
2929import androidx.compose.ui.graphics.drawscope.DrawScope
30- import androidx.compose.ui.hapticfeedback.HapticFeedbackType
3130import androidx.compose.ui.input.pointer.pointerInput
3231import androidx.compose.ui.layout.onGloballyPositioned
3332import androidx.compose.ui.platform.LocalDensity
3433import androidx.compose.ui.platform.LocalHapticFeedback
3534import androidx.compose.ui.unit.Dp
3635import androidx.compose.ui.unit.dp
37- import top.yukonga.miuix.kmp.theme.MiuixTheme
3836import top.yukonga.miuix.kmp.utils.ColorUtils
3937import top.yukonga.miuix.kmp.utils.SmoothRoundedCornerShape
4038
@@ -44,15 +42,15 @@ import top.yukonga.miuix.kmp.utils.SmoothRoundedCornerShape
4442 * @param initialColor The initial color of the picker.
4543 * @param onColorChanged The callback to be called when the color changes.
4644 * @param showPreview Whether to show the color preview.
47- * @param enableHapticEffect Whether to enable haptic feedback .
45+ * @param hapticEffect The haptic effect of the [ColorSlider] .
4846 * @param modifier The modifier to be applied to the color picker.
4947 */
5048@Composable
5149fun ColorPicker (
52- initialColor : Color = MiuixTheme .colorScheme.primary ,
53- onColorChanged : (Color ) -> Unit = {} ,
50+ initialColor : Color ,
51+ onColorChanged : (Color ) -> Unit ,
5452 showPreview : Boolean = true,
55- enableHapticEffect : Boolean = true ,
53+ hapticEffect : SliderDefaults . SliderHapticEffect = SliderDefaults . DefaultHapticEffect ,
5654 modifier : Modifier = Modifier
5755) {
5856 var initialSetup by remember { mutableStateOf(true ) }
@@ -107,7 +105,7 @@ fun ColorPicker(
107105 HueSlider (
108106 currentHue = currentHue,
109107 onHueChanged = { newHue -> currentHue = newHue * 360f },
110- enableHapticEffect = enableHapticEffect
108+ hapticEffect = hapticEffect
111109 )
112110
113111 Spacer (modifier = Modifier .height(12 .dp))
@@ -117,7 +115,7 @@ fun ColorPicker(
117115 currentHue = currentHue,
118116 currentSaturation = currentSaturation,
119117 onSaturationChanged = { currentSaturation = it },
120- enableHapticEffect = enableHapticEffect
118+ hapticEffect = hapticEffect
121119 )
122120
123121 Spacer (modifier = Modifier .height(12 .dp))
@@ -128,7 +126,7 @@ fun ColorPicker(
128126 currentSaturation = currentSaturation,
129127 currentValue = currentValue,
130128 onValueChanged = { currentValue = it },
131- enableHapticEffect = enableHapticEffect
129+ hapticEffect = hapticEffect
132130 )
133131
134132 Spacer (modifier = Modifier .height(12 .dp))
@@ -140,7 +138,7 @@ fun ColorPicker(
140138 currentValue = currentValue,
141139 currentAlpha = currentAlpha,
142140 onAlphaChanged = { currentAlpha = it },
143- enableHapticEffect = enableHapticEffect
141+ hapticEffect = hapticEffect
144142 )
145143}
146144
@@ -149,21 +147,21 @@ fun ColorPicker(
149147 *
150148 * @param currentHue The current hue value.
151149 * @param onHueChanged The callback to be called when the hue changes.
152- * @param enableHapticEffect Whether to enable haptic feedback .
150+ * @param hapticEffect The haptic effect of the [HueSlider] .
153151 */
154152@Composable
155153fun HueSlider (
156154 currentHue : Float ,
157155 onHueChanged : (Float ) -> Unit ,
158- enableHapticEffect : Boolean = true
156+ hapticEffect : SliderDefaults . SliderHapticEffect = SliderDefaults . DefaultHapticEffect
159157) {
160158 val hueColors = List (36 ) { i -> Color .hsv(i * 10f , 1f , 1f ) }
161159 ColorSlider (
162160 value = currentHue / 360f ,
163161 onValueChanged = onHueChanged,
164162 drawBrushColors = hueColors,
165163 modifier = Modifier .fillMaxWidth(),
166- enableHapticEffect = enableHapticEffect
164+ hapticEffect = hapticEffect
167165 )
168166}
169167
@@ -173,21 +171,21 @@ fun HueSlider(
173171 * @param currentHue The current hue value.
174172 * @param currentSaturation The current saturation value.
175173 * @param onSaturationChanged The callback to be called when the saturation changes.
176- * @param enableHapticEffect Whether to enable haptic feedback .
174+ * @param hapticEffect The haptic effect of the [SaturationSlider] .
177175 */
178176@Composable
179177fun SaturationSlider (
180178 currentHue : Float ,
181179 currentSaturation : Float ,
182180 onSaturationChanged : (Float ) -> Unit ,
183- enableHapticEffect : Boolean = true
181+ hapticEffect : SliderDefaults . SliderHapticEffect = SliderDefaults . DefaultHapticEffect
184182) {
185183 ColorSlider (
186184 value = currentSaturation,
187185 onValueChanged = onSaturationChanged,
188186 drawBrushColors = listOf (Color .hsv(currentHue, 0f , 1f , 1f ), Color .hsv(currentHue, 1f , 1f , 1f )),
189187 modifier = Modifier .fillMaxWidth(),
190- enableHapticEffect = enableHapticEffect
188+ hapticEffect = hapticEffect
191189 )
192190}
193191
@@ -199,22 +197,22 @@ fun SaturationSlider(
199197 * @param currentSaturation The current saturation value.
200198 * @param currentValue The current value value.
201199 * @param onValueChanged The callback to be called when the value changes.
202- * @param enableHapticEffect Whether to enable haptic feedback .
200+ * @param hapticEffect The haptic effect of the [ValueSlider] .
203201 */
204202@Composable
205203fun ValueSlider (
206204 currentHue : Float ,
207205 currentSaturation : Float ,
208206 currentValue : Float ,
209207 onValueChanged : (Float ) -> Unit ,
210- enableHapticEffect : Boolean = true
208+ hapticEffect : SliderDefaults . SliderHapticEffect = SliderDefaults . DefaultHapticEffect
211209) {
212210 ColorSlider (
213211 value = currentValue,
214212 onValueChanged = onValueChanged,
215213 drawBrushColors = listOf (Color .Black , Color .hsv(currentHue, currentSaturation, 1f )),
216214 modifier = Modifier .fillMaxWidth(),
217- enableHapticEffect = enableHapticEffect
215+ hapticEffect = hapticEffect
218216 )
219217}
220218
@@ -226,7 +224,7 @@ fun ValueSlider(
226224 * @param currentValue The current value value.
227225 * @param currentAlpha The current alpha value.
228226 * @param onAlphaChanged The callback to be called when the alpha changes.
229- * @param enableHapticEffect Whether to enable haptic feedback .
227+ * @param hapticEffect The haptic effect of the [AlphaSlider] .
230228 */
231229@Composable
232230fun AlphaSlider (
@@ -235,7 +233,7 @@ fun AlphaSlider(
235233 currentValue : Float ,
236234 currentAlpha : Float ,
237235 onAlphaChanged : (Float ) -> Unit ,
238- enableHapticEffect : Boolean = true
236+ hapticEffect : SliderDefaults . SliderHapticEffect = SliderDefaults . DefaultHapticEffect
239237) {
240238 val baseColor = Color .hsv(currentHue, currentSaturation, currentValue)
241239 val startColor = remember(baseColor) { baseColor.copy(alpha = 0f ) }
@@ -277,7 +275,7 @@ fun AlphaSlider(
277275 onValueChanged = onAlphaChanged,
278276 drawBrushColors = listOf (startColor, endColor),
279277 modifier = Modifier .fillMaxWidth(),
280- enableHapticEffect = enableHapticEffect ,
278+ hapticEffect = hapticEffect ,
281279 drawBackground = checkerBrush::draw
282280 )
283281}
@@ -291,7 +289,7 @@ private fun ColorSlider(
291289 onValueChanged : (Float ) -> Unit ,
292290 drawBrushColors : List <Color >,
293291 modifier : Modifier = Modifier ,
294- enableHapticEffect : Boolean = true ,
292+ hapticEffect : SliderDefaults . SliderHapticEffect = SliderDefaults . DefaultHapticEffect ,
295293 drawBackground : (DrawScope .(width: Float , height: Float ) -> Unit )? = null
296294) {
297295 val density = LocalDensity .current
@@ -303,21 +301,14 @@ private fun ColorSlider(
303301 val borderStroke = remember { 0.5 .dp }
304302 val borderColor = remember { Color .Gray .copy(0.1f ) }
305303 val hapticFeedback = LocalHapticFeedback .current
306- var lastHapticStep by remember { mutableStateOf( 0f ) }
304+ val hapticState = remember { SliderHapticState ( ) }
307305
308306 val dragHandler = remember(onValueChanged, sliderSizePx) {
309307 { posX: Float , width: Float ->
310308 handleSliderInteraction(posX, width, sliderSizePx).coerceIn(0f , 1f )
311309 }
312310 }
313311
314- fun performHapticFeedbackIfNeeded (valueChanged : Float ) {
315- if (enableHapticEffect && valueChanged != lastHapticStep) {
316- hapticFeedback.performHapticFeedback(HapticFeedbackType .TextHandleMove )
317- lastHapticStep = valueChanged
318- }
319- }
320-
321312 Box (
322313 modifier = modifier
323314 .height(26 .dp)
@@ -331,12 +322,19 @@ private fun ColorSlider(
331322 sliderWidth = with (density) { coordinates.size.width.toDp() }
332323 }
333324 .pointerInput(dragHandler) {
334- detectHorizontalDragGestures { change, _ ->
335- change.consume()
336- val currentValue = dragHandler(change.position.x, size.width.toFloat())
337- onValueChanged(currentValue)
338- performHapticFeedbackIfNeeded(currentValue)
339- }
325+ detectHorizontalDragGestures(
326+ onDragStart = { offset ->
327+ val currentValue = dragHandler(offset.x, size.width.toFloat())
328+ onValueChanged(currentValue)
329+ hapticState.reset(currentValue)
330+ },
331+ onHorizontalDrag = { change, _ ->
332+ change.consume()
333+ val currentValue = dragHandler(change.position.x, size.width.toFloat())
334+ onValueChanged(currentValue)
335+ hapticState.handleHapticFeedback(currentValue, hapticEffect, hapticFeedback)
336+ }
337+ )
340338 }
341339 ) {
342340 drawBackground?.invoke(this , size.width, size.height)
0 commit comments