Skip to content

Commit 17a0524

Browse files
add ColorPickerRingRectHSV
1 parent c8a4399 commit 17a0524

File tree

5 files changed

+241
-57
lines changed

5 files changed

+241
-57
lines changed

app/src/main/java/com/smarttoolfactory/composecolorpicker/demo/ColorPickerDemo.kt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import androidx.compose.ui.Modifier
1313
import androidx.compose.ui.graphics.Color
1414
import androidx.compose.ui.unit.dp
1515
import com.smarttoolfactory.colorpicker.dialog.ColorPickerRingDiamondHSLDialog
16+
import com.smarttoolfactory.colorpicker.dialog.ColorPickerRingRectHSVDialog
1617
import com.smarttoolfactory.colorpicker.widget.ColorDisplayRoundedRect
1718
import com.smarttoolfactory.composecolorpicker.ui.theme.backgroundColor
1819

@@ -67,6 +68,29 @@ fun ColorPickerDemo() {
6768
color = it
6869
}
6970
}
71+
72+
73+
var showColorDialogRingRectHSV by remember { mutableStateOf(false) }
74+
75+
OutlinedButton(
76+
modifier = buttonModifier,
77+
onClick = { showColorDialogRingRectHSV = !showColorDialogRingRectHSV },
78+
colors = ButtonDefaults.outlinedButtonColors(
79+
backgroundColor = Color.Transparent
80+
)
81+
82+
) {
83+
Text(text = "Hue Ring-Rect HSV Dialog")
84+
}
85+
86+
if (showColorDialogRingRectHSV) {
87+
previousColor = color.copy()
88+
89+
ColorPickerRingRectHSVDialog(color) {
90+
showColorDialogRingRectHSV = !showColorDialogRingRectHSV
91+
color = it
92+
}
93+
}
7094
}
7195
}
7296

colorpicker/src/main/java/com/smarttoolfactory/colorpicker/dialog/ColorPickerDialog.kt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import androidx.compose.ui.graphics.Color
1616
import androidx.compose.ui.unit.dp
1717
import androidx.compose.ui.window.Dialog
1818
import com.smarttoolfactory.colorpicker.picker.ColorPickerRingDiamondHSL
19+
import com.smarttoolfactory.colorpicker.picker.ColorPickerRingRectHSV
1920
import com.smarttoolfactory.colorpicker.ui.Blue400
2021

2122
@Composable
@@ -53,4 +54,40 @@ fun ColorPickerRingDiamondHSLDialog(initialColor: Color, onDismiss: (Color) -> U
5354
}
5455
}
5556

57+
@Composable
58+
fun ColorPickerRingRectHSVDialog(initialColor: Color, onDismiss: (Color) -> Unit) {
59+
60+
var color by remember { mutableStateOf(initialColor.copy()) }
61+
Dialog(
62+
onDismissRequest = {
63+
onDismiss(color)
64+
}
65+
) {
66+
Column(horizontalAlignment = Alignment.CenterHorizontally) {
67+
ColorPickerRingRectHSV(
68+
modifier = Modifier
69+
.fillMaxWidth()
70+
.weight(1f)
71+
.background(Color(0xcc212121), shape = RoundedCornerShape(5.dp))
72+
.padding(horizontal = 10.dp, vertical = 2.dp),
73+
initialColor = initialColor
74+
) {
75+
color = it
76+
}
77+
78+
FloatingActionButton(
79+
onClick = { onDismiss(color) },
80+
backgroundColor = Color.Black
81+
) {
82+
Icon(
83+
imageVector = Icons.Filled.Close,
84+
contentDescription = null,
85+
tint = Blue400
86+
)
87+
}
88+
}
89+
}
90+
}
91+
92+
5693

colorpicker/src/main/java/com/smarttoolfactory/colorpicker/picker/ColorPickerRingDimondHSL.kt

Lines changed: 37 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,48 @@
11
package com.smarttoolfactory.colorpicker.picker
22

33
import androidx.compose.foundation.layout.*
4-
import androidx.compose.material.Text
5-
import androidx.compose.material.TextButton
64
import androidx.compose.runtime.*
75
import androidx.compose.ui.Alignment
86
import androidx.compose.ui.Modifier
97
import androidx.compose.ui.graphics.Color
10-
import androidx.compose.ui.text.font.FontWeight
8+
import androidx.compose.ui.unit.Dp
119
import androidx.compose.ui.unit.dp
12-
import androidx.compose.ui.unit.sp
1310
import com.smarttoolfactory.colorpicker.model.ColorHSL
1411
import com.smarttoolfactory.colorpicker.model.ColorModel
1512
import com.smarttoolfactory.colorpicker.selector.HueSelectorRing
1613
import com.smarttoolfactory.colorpicker.selector.SaturationLightnessSelectorDiamondHSL
1714
import com.smarttoolfactory.colorpicker.slider.CompositeSliderPanel
18-
import com.smarttoolfactory.colorpicker.util.argbToHex
1915
import com.smarttoolfactory.colorpicker.util.colorToHSL
2016
import com.smarttoolfactory.colorpicker.widget.ColorDisplayRoundedRect
21-
import com.smarttoolfactory.colorpicker.widget.HexDisplay
22-
17+
import com.smarttoolfactory.colorpicker.widget.ColorModelChangeTabRow
18+
19+
/**
20+
* ColorPicker with [HueSelectorRing] hue selector and [SaturationLightnessSelectorDiamondHSL]
21+
* saturation lightness Selector uses [HSL](https://en.wikipedia.org/wiki/HSL_and_HSV)
22+
* color model as base.
23+
*
24+
* This color picker has tabs section that can be changed between
25+
* HSL, HSV and RGB color models and color can be set using [CompositeSliderPanel] which contains
26+
* sliders for each color models.
27+
*
28+
* @param initialColor color that is passed to this picker initially.
29+
* @param ringOuterRadiusFraction outer radius of [HueSelectorRing].
30+
* @param ringInnerRadiusFraction inner radius of [HueSelectorRing].
31+
* @param ringBackgroundColor background from center to inner radius of [HueSelectorRing].
32+
* @param ringBorderStrokeColor stroke color for drawing borders around inner or outer radius.
33+
* @param ringBorderStrokeWidth stroke width of borders.
34+
* @param onColorChange callback that is triggered when [Color] is changed using [HueSelectorRing],
35+
* [SaturationLightnessSelectorDiamondHSL] or [CompositeSliderPanel]
36+
*/
2337
@Composable
2438
fun ColorPickerRingDiamondHSL(
2539
modifier: Modifier = Modifier,
2640
initialColor: Color,
27-
outerRadiusFraction: Float = .9f,
28-
innerRadiusFraction: Float = .6f,
41+
ringOuterRadiusFraction: Float = .9f,
42+
ringInnerRadiusFraction: Float = .6f,
43+
ringBackgroundColor: Color = Color.Black,
44+
ringBorderStrokeColor: Color = Color.Black,
45+
ringBorderStrokeWidth: Dp = 4.dp,
2946
onColorChange: (Color) -> Unit
3047
) {
3148

@@ -43,17 +60,6 @@ fun ColorPickerRingDiamondHSL(
4360

4461
onColorChange(currentColor)
4562

46-
var hexString by remember(currentColor) {
47-
mutableStateOf(
48-
argbToHex(
49-
currentColor.alpha,
50-
currentColor.red,
51-
currentColor.green,
52-
currentColor.blue
53-
)
54-
)
55-
}
56-
5763
Column(
5864
modifier = modifier,
5965
horizontalAlignment = Alignment.CenterHorizontally,
@@ -71,23 +77,25 @@ fun ColorPickerRingDiamondHSL(
7177
currentColor = currentColor
7278
)
7379

74-
7580
Box(contentAlignment = Alignment.Center) {
7681

7782
// Ring Shaped Hue Selector
7883
HueSelectorRing(
7984
modifier = Modifier.fillMaxWidth(1f),
8085
hue = hue,
81-
outerRadiusFraction = outerRadiusFraction,
82-
innerRadiusFraction = innerRadiusFraction,
86+
outerRadiusFraction = ringOuterRadiusFraction,
87+
innerRadiusFraction = ringInnerRadiusFraction,
88+
backgroundColor = ringBackgroundColor,
89+
borderStrokeColor = ringBorderStrokeColor,
90+
borderStrokeWidth = ringBorderStrokeWidth,
8391
selectionRadius = 8.dp
8492
) { hueChange ->
8593
hue = hueChange
8694
}
8795

8896
// Diamond Shaped Saturation and Lightness Selector
8997
SaturationLightnessSelectorDiamondHSL(
90-
modifier = Modifier.fillMaxWidth(innerRadiusFraction * .9f),
98+
modifier = Modifier.fillMaxWidth(ringInnerRadiusFraction * .9f),
9199
hue = hue,
92100
saturation = saturation,
93101
lightness = lightness,
@@ -99,31 +107,13 @@ fun ColorPickerRingDiamondHSL(
99107
}
100108

101109
// HSL-HSV-RGB Color Model Change Tabs
102-
Row(
110+
ColorModelChangeTabRow(
103111
modifier = Modifier.width(350.dp),
104-
horizontalArrangement = Arrangement.SpaceEvenly
105-
) {
106-
TextButton(
107-
onClick = { inputColorModel = ColorModel.HSL },
108-
modifier = Modifier.weight(1f)
109-
) {
110-
Text(text = "HSL", fontWeight = FontWeight.Bold)
111-
}
112-
TextButton(
113-
onClick = { inputColorModel = ColorModel.HSV },
114-
modifier = Modifier.weight(1f)
115-
) {
116-
Text(text = "HSV", fontWeight = FontWeight.Bold)
112+
colorModel = inputColorModel,
113+
onColorModelChange = {
114+
inputColorModel = it
117115
}
118-
119-
TextButton(
120-
onClick = { inputColorModel = ColorModel.RGB },
121-
modifier = Modifier.weight(1f)
122-
) {
123-
Text(text = "RGB", fontWeight = FontWeight.Bold)
124-
}
125-
}
126-
116+
)
127117
// HSL-HSV-RGB Sliders
128118
CompositeSliderPanel(
129119
compositeColor = ColorHSL(
@@ -138,9 +128,7 @@ fun ColorPickerRingDiamondHSL(
138128
saturation = color.saturation
139129
lightness = color.lightness
140130
alpha = color.alpha
141-
hexString = color.argbHexString
142131
}
143-
144132
},
145133
showAlphaSlider = true,
146134
inputColorModel = inputColorModel,
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package com.smarttoolfactory.colorpicker.picker
2+
3+
import androidx.compose.foundation.layout.*
4+
import androidx.compose.runtime.*
5+
import androidx.compose.ui.Alignment
6+
import androidx.compose.ui.Modifier
7+
import androidx.compose.ui.graphics.Color
8+
import androidx.compose.ui.unit.Dp
9+
import androidx.compose.ui.unit.dp
10+
import com.smarttoolfactory.colorpicker.model.ColorHSV
11+
import com.smarttoolfactory.colorpicker.model.ColorModel
12+
import com.smarttoolfactory.colorpicker.selector.HueSelectorRing
13+
import com.smarttoolfactory.colorpicker.selector.SaturationLightnessSelectorDiamondHSL
14+
import com.smarttoolfactory.colorpicker.selector.SaturationValueSelectorRectHSV
15+
import com.smarttoolfactory.colorpicker.slider.CompositeSliderPanel
16+
import com.smarttoolfactory.colorpicker.util.colorToHSV
17+
import com.smarttoolfactory.colorpicker.widget.ColorDisplayRoundedRect
18+
import com.smarttoolfactory.colorpicker.widget.ColorModelChangeTabRow
19+
20+
/**
21+
* ColorPicker with [HueSelectorRing] hue selector and [SaturationValueSelectorRectHSV]
22+
* saturation lightness Selector that uses [HSV](https://en.wikipedia.org/wiki/HSL_and_HSV)
23+
* color model as base.
24+
* This color picker has tabs section that can be changed between
25+
* HSL, HSV and RGB color models and color can be set using [CompositeSliderPanel] which contains
26+
* sliders for each color models.
27+
*
28+
* @param initialColor color that is passed to this picker initially.
29+
* @param ringOuterRadiusFraction outer radius of [HueSelectorRing].
30+
* @param ringInnerRadiusFraction inner radius of [HueSelectorRing].
31+
* @param ringBackgroundColor background from center to inner radius of [HueSelectorRing].
32+
* @param ringBorderStrokeColor stroke color for drawing borders around inner or outer radius.
33+
* @param ringBorderStrokeWidth stroke width of borders.
34+
* @param onColorChange callback that is triggered when [Color] is changed using [HueSelectorRing],
35+
* [SaturationValueSelectorRectHSV] or [CompositeSliderPanel]
36+
*/
37+
@Composable
38+
fun ColorPickerRingRectHSV(
39+
modifier: Modifier = Modifier,
40+
initialColor: Color,
41+
ringOuterRadiusFraction: Float = .9f,
42+
ringInnerRadiusFraction: Float = .6f,
43+
ringBackgroundColor:Color=Color.Transparent,
44+
ringBorderStrokeColor: Color = Color.Black,
45+
ringBorderStrokeWidth: Dp = 4.dp,
46+
onColorChange: (Color) -> Unit
47+
) {
48+
49+
var inputColorModel by remember { mutableStateOf(ColorModel.HSV) }
50+
51+
val hsvArray = colorToHSV(initialColor)
52+
53+
var hue by remember { mutableStateOf(hsvArray[0]) }
54+
var saturation by remember { mutableStateOf(hsvArray[1]) }
55+
var value by remember { mutableStateOf(hsvArray[2]) }
56+
var alpha by remember { mutableStateOf(initialColor.alpha) }
57+
58+
val currentColor =
59+
Color.hsv(hue = hue, saturation = saturation, value = value, alpha = alpha)
60+
61+
onColorChange(currentColor)
62+
63+
Column(
64+
modifier = modifier,
65+
horizontalAlignment = Alignment.CenterHorizontally,
66+
verticalArrangement = Arrangement.Center
67+
) {
68+
69+
Spacer(modifier = Modifier.height(10.dp))
70+
71+
// Initial and Current Colors
72+
ColorDisplayRoundedRect(
73+
modifier = Modifier
74+
.fillMaxWidth()
75+
.padding(horizontal = 50.dp, vertical = 10.dp),
76+
initialColor = initialColor,
77+
currentColor = currentColor
78+
)
79+
80+
Box(contentAlignment = Alignment.Center) {
81+
82+
// Ring Shaped Hue Selector
83+
HueSelectorRing(
84+
modifier = Modifier.fillMaxWidth(1f),
85+
hue = hue,
86+
outerRadiusFraction = ringOuterRadiusFraction,
87+
innerRadiusFraction = ringInnerRadiusFraction,
88+
backgroundColor = ringBackgroundColor,
89+
borderStrokeColor = ringBorderStrokeColor,
90+
borderStrokeWidth = ringBorderStrokeWidth,
91+
selectionRadius = 8.dp,
92+
) { hueChange ->
93+
hue = hueChange
94+
}
95+
96+
// Diamond Shaped Saturation and Lightness Selector
97+
SaturationValueSelectorRectHSV(
98+
modifier = Modifier
99+
.fillMaxWidth(ringInnerRadiusFraction * .65f)
100+
.aspectRatio(1f),
101+
hue = hue,
102+
saturation = saturation,
103+
value = value,
104+
selectionRadius = 8.dp
105+
) { s, v ->
106+
saturation = s
107+
value = v
108+
}
109+
}
110+
111+
// HSL-HSV-RGB Color Model Change Tabs
112+
ColorModelChangeTabRow(
113+
modifier = Modifier.width(350.dp),
114+
colorModel = inputColorModel,
115+
onColorModelChange = {
116+
inputColorModel = it
117+
}
118+
)
119+
120+
// HSL-HSV-RGB Sliders
121+
CompositeSliderPanel(
122+
compositeColor = ColorHSV(
123+
hue = hue,
124+
saturation = saturation,
125+
value = value,
126+
alpha = alpha
127+
),
128+
onColorChange = {
129+
(it as? ColorHSV)?.let { color ->
130+
hue = color.hue
131+
saturation = color.saturation
132+
value = color.value
133+
alpha = color.alpha
134+
}
135+
136+
},
137+
showAlphaSlider = true,
138+
inputColorModel = inputColorModel,
139+
outputColorModel = ColorModel.HSV
140+
)
141+
}
142+
}

colorpicker/src/main/java/com/smarttoolfactory/colorpicker/ui/Color.kt

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,7 @@ val Brown400 = Color(0xff8D6E63)
1313
val BlueGrey400 = Color(0xff78909C)
1414
val Grey400 = Color(0xffBDBDBD)
1515

16-
val ThumbColor = Color(0xffffffff)
17-
val DisabledThumbColor = Color(0xfff0f0f0)
18-
19-
val ActiveTrackColor = Color(0xff489cef)
20-
val DisabledActiveTrackColor = Color(0xff489cef)
21-
val InactiveTrackColor = Color(0xffcccccc)
22-
val DisabledInactiveTrackColor = Color(0xffcccccc)
23-
val TickColor = Color(0xffcccccc)
16+
val Grey600 = Color(0xff757575)
2417

2518
val Gray = Color(0xff808080)
2619
val WhiteTransparent = Color(0x00ffffff)

0 commit comments

Comments
 (0)