@@ -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