Skip to content

Commit 74e639b

Browse files
add ColorPickerRingDiamondHEX with HEX selection
1 parent 2e44270 commit 74e639b

File tree

9 files changed

+320
-11
lines changed

9 files changed

+320
-11
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ by [mchome's flutter_colorpicker for Flutter](https://github.com/mchome/flutter
2222
There are various selection of default color pickers and with selectors sliders, and hex displays
2323
it's possible to create new ones either.
2424

25-
| Hue Ring-Diamond HSL | Hue- Ring-Rect HSL | Hue Ring-Rect HSV| Hue-Hex HSV|
25+
| Hue Ring-Diamond HSL | Hue Ring-Diamond HEX | Hue- Ring-Rect HSL | Hue Ring-Rect HSV|
2626
| ----------|-----------| -----------| -----------|
27-
| <img src="./screenshots/colorpicker/cp_ring_diamond_hsl.png"/> | <img src="./screenshots/colorpicker/cp_ring_rect_hsl.png"/> | <img src="./screenshots/colorpicker/cp_ring_rect_hsv.png"/> | <img src="./screenshots/colorpicker/cp_ring_rect_hex_hsv.png"/> |
27+
| <img src="./screenshots/colorpicker/cp_ring_diamond_hsl.png"/> | <img src="./screenshots/colorpicker/cp_ring_diamond_hex.png"/> | <img src="./screenshots/colorpicker/cp_ring_rect_hsl.png"/> | <img src="./screenshots/colorpicker/cp_ring_rect_hsv.png"/> |
2828

29-
| Saturation-Value HSV | Saturation-Lightness HSL | Hue-Circle HSV
29+
| Saturation-Value HSV | Saturation-Lightness HSL | Hue-Circle HSV | Hue Ring-Rect Hex|
3030
| ----------|-----------| -----------|
31-
| <img src="./screenshots/colorpicker/cp_rect_saturation_value_hsv.png"/> | <img src="./screenshots/colorpicker/cp_rect_saturation_lightness_hsl.png"/> | <img src="./screenshots/colorpicker/cp_circle_hue_saturation_hsv.png"/>
31+
| <img src="./screenshots/colorpicker/cp_rect_saturation_value_hsv.png"/> | <img src="./screenshots/colorpicker/cp_rect_saturation_lightness_hsl.png"/> | <img src="./screenshots/colorpicker/cp_circle_hue_saturation_hsv.png"/> <img src="./screenshots/colorpicker/cp_ring_rect_hex_hsv.png"/> |
3232

3333
| Hue-Saturation HSV | Hue-Value HSV | Hue-Saturation HSL | Hue-Lightness HSL |
3434
| ----------|-----------| -----------| -----------|

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

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,19 @@ fun ColorPickerDemo() {
7979
}
8080
)
8181

82+
// Ring Hue, Diamond Saturation-Lightness selector HSL and HEX Picker
83+
DialogRingDiamondHEX(
84+
modifier = buttonModifier,
85+
color = color,
86+
onPreviousColorChange = {
87+
previousColor = it
88+
},
89+
onCurrentColorChange = { colorChange, hexChange ->
90+
color = colorChange
91+
hexString = hexChange
92+
}
93+
)
94+
8295
// Ring Hue, Rect Saturation-Lightness selector HSL Picker
8396
DialogRingRectHSL(
8497
modifier = buttonModifier,
@@ -237,6 +250,37 @@ private fun DialogRingDiamondHSL(
237250
}
238251
}
239252

253+
@Composable
254+
private fun DialogRingDiamondHEX(
255+
modifier: Modifier,
256+
color: Color,
257+
onPreviousColorChange: (Color) -> Unit,
258+
onCurrentColorChange: (Color, String) -> Unit
259+
260+
) {
261+
var showDialog by remember { mutableStateOf(false) }
262+
263+
OutlinedButton(
264+
modifier = modifier,
265+
onClick = { showDialog = !showDialog },
266+
colors = ButtonDefaults.outlinedButtonColors(
267+
backgroundColor = Color.Transparent
268+
)
269+
270+
) {
271+
Text(text = "Hue Ring-Diamond HEX Dialog")
272+
}
273+
274+
if (showDialog) {
275+
onPreviousColorChange(color.copy())
276+
277+
ColorPickerRingDiamondHEXDialog(color) { colorChange, hexChange ->
278+
showDialog = !showDialog
279+
onCurrentColorChange(colorChange, hexChange)
280+
}
281+
}
282+
}
283+
240284
@Composable
241285
private fun DialogRingRectHSL(
242286
modifier: Modifier,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ fun HexConversionDemo() {
4545

4646
HexTextField(
4747
hexString = hexString,
48-
48+
useAlpha = true,
4949
onTextChange = {
5050
hexString = it
5151
}, onColorChange = {

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

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,62 @@ fun ColorPickerRingDiamondHSLDialog(
7878
}
7979
}
8080

81+
@Composable
82+
fun ColorPickerRingDiamondHEXDialog(
83+
initialColor: Color,
84+
ringOuterRadiusFraction: Float = .9f,
85+
ringInnerRadiusFraction: Float = .6f,
86+
ringBackgroundColor: Color = Color.Transparent,
87+
ringBorderStrokeColor: Color = Color.Black,
88+
ringBorderStrokeWidth: Dp = 4.dp,
89+
selectionRadius: Dp = 8.dp,
90+
onDismiss: (Color, String) -> Unit
91+
) {
92+
93+
var color by remember { mutableStateOf(initialColor.copy()) }
94+
var hexString by remember { mutableStateOf(colorToHex(color)) }
95+
96+
Dialog(
97+
onDismissRequest = {
98+
onDismiss(color, hexString)
99+
}
100+
) {
101+
Column(horizontalAlignment = Alignment.CenterHorizontally) {
102+
103+
ColorPickerRingDiamondHEX(
104+
modifier = Modifier
105+
.fillMaxWidth()
106+
.weight(1f)
107+
.background(Color(0xcc212121), shape = RoundedCornerShape(5.dp))
108+
.padding(horizontal = 10.dp, vertical = 2.dp),
109+
initialColor = initialColor,
110+
ringOuterRadiusFraction = ringOuterRadiusFraction,
111+
ringInnerRadiusFraction = ringInnerRadiusFraction,
112+
ringBackgroundColor = ringBackgroundColor,
113+
ringBorderStrokeColor = ringBorderStrokeColor,
114+
ringBorderStrokeWidth = ringBorderStrokeWidth,
115+
selectionRadius = selectionRadius
116+
) { colorChange, hexChange ->
117+
color = colorChange
118+
hexString = hexChange
119+
}
120+
121+
FloatingActionButton(
122+
onClick = {
123+
onDismiss(color, hexString)
124+
},
125+
backgroundColor = Color.Black
126+
) {
127+
Icon(
128+
imageVector = Icons.Filled.Close,
129+
contentDescription = null,
130+
tint = Blue400
131+
)
132+
}
133+
}
134+
}
135+
}
136+
81137
@Composable
82138
fun ColorPickerRingRectHSLDialog(
83139
initialColor: Color,
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
package com.smarttoolfactory.colorpicker.picker
2+
3+
import androidx.compose.foundation.layout.*
4+
import androidx.compose.material.TextFieldDefaults
5+
import androidx.compose.runtime.*
6+
import androidx.compose.ui.Alignment
7+
import androidx.compose.ui.Modifier
8+
import androidx.compose.ui.graphics.Color
9+
import androidx.compose.ui.unit.Dp
10+
import androidx.compose.ui.unit.dp
11+
import com.smarttoolfactory.colorpicker.model.ColorHSL
12+
import com.smarttoolfactory.colorpicker.model.ColorModel
13+
import com.smarttoolfactory.colorpicker.selector.SelectorDiamondSaturationLightnessHSL
14+
import com.smarttoolfactory.colorpicker.selector.SelectorRingHue
15+
import com.smarttoolfactory.colorpicker.slider.CompositeSliderPanel
16+
import com.smarttoolfactory.colorpicker.ui.Grey400
17+
import com.smarttoolfactory.colorpicker.ui.Grey600
18+
import com.smarttoolfactory.colorpicker.util.colorToHSL
19+
import com.smarttoolfactory.colorpicker.util.colorToHex
20+
import com.smarttoolfactory.colorpicker.util.colorToHexAlpha
21+
import com.smarttoolfactory.colorpicker.widget.ColorDisplayRoundedRect
22+
import com.smarttoolfactory.colorpicker.widget.ColorModelChangeTabRow
23+
import com.smarttoolfactory.colorpicker.widget.HexTextField
24+
25+
/**
26+
* ColorPicker with [SelectorRingHue] hue selector and [SelectorDiamondSaturationLightnessHSL]
27+
* saturation lightness Selector uses [HSL](https://en.wikipedia.org/wiki/HSL_and_HSV)
28+
* color model as base.
29+
*
30+
* This color picker has tabs section that can be changed between
31+
* HSL, HSV and RGB color models and color can be set using [CompositeSliderPanel] which contains
32+
* sliders for each color models.
33+
*
34+
* @param initialColor color that is passed to this picker initially.
35+
* @param ringOuterRadiusFraction outer radius of [SelectorRingHue].
36+
* @param ringInnerRadiusFraction inner radius of [SelectorRingHue].
37+
* @param ringBackgroundColor background from center to inner radius of [SelectorRingHue].
38+
* @param ringBorderStrokeColor stroke color for drawing borders around inner or outer radius.
39+
* @param ringBorderStrokeWidth stroke width of borders.
40+
* @param selectionRadius radius of white and black circle selector.
41+
* @param onColorChange callback that is triggered when [Color] is changed using [SelectorRingHue],
42+
* [SelectorDiamondSaturationLightnessHSL] or [CompositeSliderPanel]
43+
*/
44+
@Composable
45+
fun ColorPickerRingDiamondHEX(
46+
modifier: Modifier = Modifier,
47+
initialColor: Color,
48+
ringOuterRadiusFraction: Float = .9f,
49+
ringInnerRadiusFraction: Float = .6f,
50+
ringBackgroundColor: Color = Color.Black,
51+
ringBorderStrokeColor: Color = Color.Black,
52+
ringBorderStrokeWidth: Dp = 4.dp,
53+
selectionRadius: Dp = 8.dp,
54+
onColorChange: (Color, String) -> Unit
55+
) {
56+
57+
var inputColorModel by remember { mutableStateOf(ColorModel.HSL) }
58+
59+
val hslArray = colorToHSL(initialColor)
60+
61+
var hue by remember { mutableStateOf(hslArray[0]) }
62+
var saturation by remember { mutableStateOf(hslArray[1]) }
63+
var lightness by remember { mutableStateOf(hslArray[2]) }
64+
var alpha by remember { mutableStateOf(initialColor.alpha) }
65+
66+
val currentColor =
67+
Color.hsl(hue = hue, saturation = saturation, lightness = lightness, alpha = alpha)
68+
69+
var hexString by remember {
70+
mutableStateOf(
71+
colorToHexAlpha(
72+
currentColor
73+
)
74+
)
75+
}
76+
77+
onColorChange(currentColor, colorToHex(currentColor))
78+
79+
Column(
80+
modifier = modifier,
81+
horizontalAlignment = Alignment.CenterHorizontally
82+
) {
83+
84+
Spacer(modifier = Modifier.height(10.dp))
85+
86+
// Initial and Current Colors
87+
ColorDisplayRoundedRect(
88+
modifier = Modifier
89+
.fillMaxWidth()
90+
.padding(horizontal = 50.dp, vertical = 10.dp),
91+
initialColor = initialColor,
92+
currentColor = currentColor
93+
)
94+
95+
Box(contentAlignment = Alignment.Center) {
96+
97+
// Ring Shaped Hue Selector
98+
SelectorRingHue(
99+
modifier = Modifier.fillMaxWidth(1f),
100+
hue = hue,
101+
outerRadiusFraction = ringOuterRadiusFraction,
102+
innerRadiusFraction = ringInnerRadiusFraction,
103+
backgroundColor = ringBackgroundColor,
104+
borderStrokeColor = ringBorderStrokeColor,
105+
borderStrokeWidth = ringBorderStrokeWidth,
106+
selectionRadius = selectionRadius
107+
) { hueChange ->
108+
hue = hueChange
109+
hexString = colorToHexAlpha(
110+
Color.hsl(
111+
hue = hue,
112+
saturation = saturation,
113+
lightness = lightness,
114+
alpha = alpha
115+
)
116+
)
117+
}
118+
119+
// Diamond Shaped Saturation and Lightness Selector
120+
SelectorDiamondSaturationLightnessHSL(
121+
modifier = Modifier.fillMaxWidth(ringInnerRadiusFraction * .9f),
122+
hue = hue,
123+
saturation = saturation,
124+
lightness = lightness,
125+
selectionRadius = selectionRadius
126+
) { s, l ->
127+
saturation = s
128+
lightness = l
129+
hexString = colorToHexAlpha(
130+
Color.hsl(
131+
hue = hue,
132+
saturation = saturation,
133+
lightness = lightness,
134+
alpha = alpha
135+
)
136+
)
137+
}
138+
}
139+
140+
// HSL-HSV-RGB Color Model Change Tabs
141+
ColorModelChangeTabRow(
142+
modifier = Modifier.width(350.dp),
143+
colorModel = inputColorModel,
144+
onColorModelChange = {
145+
inputColorModel = it
146+
}
147+
)
148+
// HSL-HSV-RGB Sliders
149+
CompositeSliderPanel(
150+
modifier = Modifier.padding(start = 10.dp, end = 7.dp),
151+
compositeColor = ColorHSL(
152+
hue = hue,
153+
saturation = saturation,
154+
lightness = lightness,
155+
alpha = alpha
156+
),
157+
onColorChange = {
158+
(it as? ColorHSL)?.let { color ->
159+
hue = color.hue
160+
saturation = color.saturation
161+
lightness = color.lightness
162+
alpha = color.alpha
163+
164+
hexString = colorToHexAlpha(
165+
Color.hsl(
166+
hue = hue,
167+
saturation = saturation,
168+
lightness = lightness,
169+
alpha = alpha
170+
)
171+
)
172+
}
173+
},
174+
showAlphaSlider = true,
175+
inputColorModel = inputColorModel,
176+
outputColorModel = ColorModel.HSL
177+
)
178+
179+
HexTextField(
180+
modifier = Modifier
181+
.padding(horizontal = 10.dp)
182+
.fillMaxWidth(),
183+
hexString = hexString,
184+
useAlpha = true,
185+
colors = TextFieldDefaults.textFieldColors(
186+
textColor = Grey400,
187+
placeholderColor = Grey600,
188+
backgroundColor = Color.Transparent,
189+
focusedIndicatorColor = Color.Transparent,
190+
unfocusedIndicatorColor = Color.Transparent
191+
),
192+
onTextChange = {
193+
hexString = it
194+
},
195+
onColorChange = {
196+
val hslArrayNew = colorToHSL(it)
197+
hue = hslArrayNew[0]
198+
saturation = hslArrayNew[1]
199+
lightness = hslArrayNew[2]
200+
alpha = it.alpha
201+
}
202+
)
203+
}
204+
}

colorpicker/src/main/java/com/smarttoolfactory/colorpicker/widget/HexTextField.kt

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,18 @@ import com.smarttoolfactory.colorpicker.util.hexToColor
2828
import com.smarttoolfactory.colorpicker.util.hexWithAlphaRegex
2929

3030
/**
31-
* [TextField] that displays color in hex representation either with #RRGGBB or ##AARRGGBB
31+
* [TextField] that displays color in hex representation either with #RRGGBB or #AARRGGBB
3232
* depending on [useAlpha] flag.
33-
*
34-
* @param hexString
35-
* @param useAlpha
36-
* @param onTextChange
37-
* @param onColorChange
33+
* @param colors that are used by default [TextField] to set background and many other default
34+
* properties.
35+
* @param textStyle style for [Text] of [TextField].
36+
* @param shape of this [TextField].
37+
* @param hexString string in hex format.
38+
* @param useAlpha when set to true returns colors in #AARRGGBB format.
39+
* @param onTextChange this callback returns when the last char typed by user is an acceptable
40+
* HEX char between 0-9,a-f, or A-F.
41+
* @param onColorChange when user type valid 6 or 8 char hex returns a [Color] associated
42+
* with the hex string.
3843
*/
3944
@Composable
4045
fun HexTextField(
338 KB
Loading

0 commit comments

Comments
 (0)