@@ -23,20 +23,17 @@ import androidx.compose.ui.Alignment
2323import  androidx.compose.ui.Modifier 
2424import  androidx.compose.ui.draw.clip 
2525import  androidx.compose.ui.draw.drawBehind 
26+ import  androidx.compose.ui.draw.drawWithCache 
27+ import  androidx.compose.ui.geometry.Rect 
2628import  androidx.compose.ui.graphics.Brush 
2729import  androidx.compose.ui.graphics.Color 
28- import  androidx.compose.ui.graphics.ImageBitmap 
29- import  androidx.compose.ui.graphics.ImageShader 
30- import  androidx.compose.ui.graphics.Paint 
31- import  androidx.compose.ui.graphics.ShaderBrush 
30+ import  androidx.compose.ui.graphics.Path 
3231import  androidx.compose.ui.graphics.TileMode 
33- import  androidx.compose.ui.graphics.drawscope.DrawScope 
3432import  androidx.compose.ui.graphics.drawscope.Stroke 
3533import  androidx.compose.ui.input.pointer.pointerInput 
3634import  androidx.compose.ui.layout.onGloballyPositioned 
3735import  androidx.compose.ui.platform.LocalDensity 
3836import  androidx.compose.ui.platform.LocalHapticFeedback 
39- import  androidx.compose.ui.unit.Density 
4037import  androidx.compose.ui.unit.Dp 
4138import  androidx.compose.ui.unit.dp 
4239import  top.yukonga.miuix.kmp.utils.CapsuleShape 
@@ -45,6 +42,8 @@ import top.yukonga.miuix.kmp.utils.Hsv
4542import  top.yukonga.miuix.kmp.utils.OkLab 
4643import  top.yukonga.miuix.kmp.utils.toHsv 
4744import  top.yukonga.miuix.kmp.utils.toOkLab 
45+ import  kotlin.math.ceil 
46+ import  kotlin.math.min 
4847
4948/* *
5049 * A [ColorPicker] component with Miuix style that supports multiple color spaces. 
@@ -299,26 +298,20 @@ fun HsvAlphaSlider(
299298    onAlphaChanged :  (Float ) ->  Unit ,
300299    hapticEffect :  SliderDefaults .SliderHapticEffect  = SliderDefaults .DefaultHapticEffect 
301300) {
302-     val  density =  LocalDensity .current
303- 
304301    val  alphaColors =  remember(currentHue, currentSaturation, currentValue) {
305302        val  baseColor =  Hsv (currentHue.toDouble(), (currentValue *  100.0 ), (currentSaturation *  100.0 )).toColor()
306303        listOf (baseColor.copy(alpha =  0f ), baseColor.copy(alpha =  1f ))
307304    }
308305
309-     val  checkerBrush =  remember(density) {
310-         createCheckerboardBrush(density)
311-     }
312306
313307    ColorSlider (
314308        value =  currentAlpha,
315309        onValueChanged =  onAlphaChanged,
316310        drawBrushColors =  alphaColors,
317-         modifier =  Modifier .fillMaxWidth(),
318-         hapticEffect =  hapticEffect,
319-         drawBackground =  { _, _ -> 
320-             drawRect(brush =  checkerBrush)
321-         }
311+         modifier =  Modifier 
312+             .fillMaxWidth()
313+             .drawCheckerboard(),
314+         hapticEffect =  hapticEffect
322315    )
323316}
324317
@@ -527,26 +520,19 @@ fun OkHsvAlphaSlider(
527520    onAlphaChanged :  (Float ) ->  Unit ,
528521    hapticEffect :  SliderDefaults .SliderHapticEffect  = SliderDefaults .DefaultHapticEffect 
529522) {
530-     val  density =  LocalDensity .current
531- 
532523    val  alphaColors =  remember(currentH, currentS, currentV) {
533524        val  baseColor =  ColorUtils .okhsvToColor(currentH, currentS, currentV)
534525        listOf (baseColor.copy(alpha =  0f ), baseColor.copy(alpha =  1f ))
535526    }
536527
537-     val  checkerBrush =  remember(density) {
538-         createCheckerboardBrush(density)
539-     }
540- 
541528    ColorSlider (
542529        value =  currentAlpha,
543530        onValueChanged =  onAlphaChanged,
544531        drawBrushColors =  alphaColors,
545-         modifier =  Modifier .fillMaxWidth(),
546-         hapticEffect =  hapticEffect,
547-         drawBackground =  { _, _ -> 
548-             drawRect(brush =  checkerBrush)
549-         }
532+         modifier =  Modifier 
533+             .fillMaxWidth()
534+             .drawCheckerboard(),
535+         hapticEffect =  hapticEffect
550536    )
551537}
552538
@@ -766,8 +752,6 @@ fun OkLabAlphaSlider(
766752    onAlphaChanged :  (Float ) ->  Unit ,
767753    hapticEffect :  SliderDefaults .SliderHapticEffect  = SliderDefaults .DefaultHapticEffect 
768754) {
769-     val  density =  LocalDensity .current
770- 
771755    val  alphaColors =  remember(currentL, currentA, currentB) {
772756        val  baseColor =  OkLab (
773757            l =  currentL *  100.0 ,
@@ -777,43 +761,50 @@ fun OkLabAlphaSlider(
777761        listOf (baseColor.copy(alpha =  0f ), baseColor.copy(alpha =  1f ))
778762    }
779763
780-     val  checkerBrush =  remember(density) {
781-         createCheckerboardBrush(density)
782-     }
783- 
784764    ColorSlider (
785765        value =  currentAlpha,
786766        onValueChanged =  onAlphaChanged,
787767        drawBrushColors =  alphaColors,
788-         modifier =  Modifier .fillMaxWidth(),
768+         modifier =  Modifier .fillMaxWidth()
769+             .drawCheckerboard(),
789770        hapticEffect =  hapticEffect,
790-         drawBackground =  { _, _ -> 
791-             drawRect(brush =  checkerBrush)
792-         }
793771    )
794772}
795773
796- private  fun  createCheckerboardBrush (density :  Density ): ShaderBrush  {
797-     val  lightColor =  Color (0xFFCCCCCC )
798-     val  darkColor =  Color (0xFFAAAAAA )
799-     val  checkerSizeDp =  3 .dp
800- 
801-     val  pixelSize =  with (density) { checkerSizeDp.toPx() }
802-     val  tileBitmapSideLengthPx =  (2  *  pixelSize).toInt().coerceAtLeast(1 )
803- 
804-     val  imageBitmap =  ImageBitmap (tileBitmapSideLengthPx, tileBitmapSideLengthPx)
805-     val  canvasForBitmap =  androidx.compose.ui.graphics.Canvas (imageBitmap)
806- 
807-     val  lightPaint =  Paint ().apply  { color =  lightColor }
808-     val  darkPaint =  Paint ().apply  { color =  darkColor }
809- 
810-     canvasForBitmap.drawRect(0f , 0f , tileBitmapSideLengthPx.toFloat(), tileBitmapSideLengthPx.toFloat(), lightPaint)
811-     canvasForBitmap.drawRect(pixelSize, 0f , 2  *  pixelSize, pixelSize, darkPaint)
812-     canvasForBitmap.drawRect(0f , pixelSize, pixelSize, 2  *  pixelSize, darkPaint)
774+ fun  Modifier.drawCheckerboard (
775+     cellSizeDp :  Dp  = 3.dp,
776+     lightColor :  Color  = Color (0xFFCCCCCC),
777+     darkColor :  Color  = Color (0xFFAAAAAA)
778+ ): Modifier  =  this .then(
779+     Modifier .drawWithCache {
780+         val  cell =  cellSizeDp.toPx().coerceAtLeast(1f )
781+         val  rows =  ceil(size.height /  cell).toInt().coerceAtLeast(1 )
782+ 
783+         val  darkPath =  Path ().apply  {
784+             var  y =  0f 
785+             for  (row in  0  until rows) {
786+                 var  x =  if  ((row and  1 ) ==  0 ) cell else  0f 
787+                 while  (x <  size.width) {
788+                     addRect(
789+                         Rect (
790+                             x,
791+                             y,
792+                             min(x +  cell, size.width),
793+                             min(y +  cell, size.height)
794+                         )
795+                     )
796+                     x + =  cell *  2f 
797+                 }
798+                 y + =  cell
799+             }
800+         }
813801
814-     val  shader =  ImageShader (imageBitmap, TileMode .Repeated , TileMode .Repeated )
815-     return  ShaderBrush (shader)
816- }
802+         onDrawBehind {
803+             drawRect(color =  lightColor)
804+             drawPath(path =  darkPath, color =  darkColor)
805+         }
806+     }
807+ )
817808
818809/* *
819810 * Generic slider component for color selection. 
@@ -825,7 +816,6 @@ private fun ColorSlider(
825816    drawBrushColors :  List <Color >,
826817    modifier :  Modifier  = Modifier ,
827818    hapticEffect :  SliderDefaults .SliderHapticEffect  = SliderDefaults .DefaultHapticEffect ,
828-     drawBackground :  (DrawScope .(width: Float , height: Float ) ->  Unit )?  = null
829819) {
830820    val  density =  LocalDensity .current
831821    var  sliderWidth by remember { mutableStateOf(0 .dp) }
@@ -847,17 +837,15 @@ private fun ColorSlider(
847837    }
848838
849839    Box (
850-         modifier =  modifier
851-             .height(sliderHeightDp)
840+         modifier =  Modifier 
852841            .clip(CapsuleShape ())
842+             .then(modifier)
843+             .height(sliderHeightDp)
853844            .onGloballyPositioned { coordinates -> 
854845                sliderWidth =  with (density) { coordinates.size.width.toDp() }
855846            }
856847            .drawBehind {
857-                 drawBackground?.invoke(this , size.width, size.height)
858-                 drawRect(
859-                     brush =  gradientBrush,
860-                 )
848+                 drawRect(brush =  gradientBrush)
861849                drawRect(
862850                    color =  Color .Gray .copy(0.1f ),
863851                    style =  Stroke (width =  with (density) { 0.5 .dp.toPx() }),
@@ -867,7 +855,10 @@ private fun ColorSlider(
867855                detectHorizontalDragGestures(
868856                    onDragStart =  { offset -> 
869857                        val  newValue = 
870-                             handleSliderInteraction(offset.x, size.width.toFloat(), with (density) { sliderHeightDp.toPx() }).coerceIn(
858+                             handleSliderInteraction(
859+                                 offset.x,
860+                                 size.width.toFloat(),
861+                                 with (density) { sliderHeightDp.toPx() }).coerceIn(
871862                                0f ,
872863                                1f 
873864                            )
@@ -916,7 +907,6 @@ private fun SliderIndicator(
916907        modifier =  modifier
917908            .offset(x =  indicatorOffsetXDp)
918909            .size(indicatorSize)
919-             .clip(CapsuleShape ())
920910            .border(6 .dp, Color .White , CapsuleShape ())
921911            .background(Color .Transparent , CapsuleShape ())
922912    )
0 commit comments