Skip to content

Commit f5600b6

Browse files
add color name parsing
1 parent 6695b9e commit f5600b6

File tree

16 files changed

+3957
-4861
lines changed

16 files changed

+3957
-4861
lines changed

README.md

Lines changed: 360 additions & 11 deletions
Large diffs are not rendered by default.
Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
package com.smarttoolfactory.composecolorsextended
2+
3+
import android.widget.Toast
4+
import androidx.compose.foundation.background
5+
import androidx.compose.foundation.clickable
6+
import androidx.compose.foundation.layout.*
7+
import androidx.compose.foundation.lazy.grid.GridCells
8+
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
9+
import androidx.compose.foundation.lazy.grid.itemsIndexed
10+
import androidx.compose.foundation.shape.RoundedCornerShape
11+
import androidx.compose.material.Icon
12+
import androidx.compose.material.IconButton
13+
import androidx.compose.material.Text
14+
import androidx.compose.material.icons.Icons
15+
import androidx.compose.material.icons.filled.Check
16+
import androidx.compose.runtime.*
17+
import androidx.compose.ui.Alignment
18+
import androidx.compose.ui.Modifier
19+
import androidx.compose.ui.draw.clip
20+
import androidx.compose.ui.graphics.Color
21+
import androidx.compose.ui.platform.LocalClipboardManager
22+
import androidx.compose.ui.platform.LocalContext
23+
import androidx.compose.ui.res.painterResource
24+
import androidx.compose.ui.text.AnnotatedString
25+
import androidx.compose.ui.text.font.FontWeight
26+
import androidx.compose.ui.text.style.TextAlign
27+
import androidx.compose.ui.unit.dp
28+
import androidx.compose.ui.unit.sp
29+
import com.smarttoolfactory.extendedcolors.ColorSwatch
30+
import com.smarttoolfactory.extendedcolors.MaterialColor
31+
import com.smarttoolfactory.extendedcolors.parser.rememberColorParser
32+
import com.smarttoolfactory.extendedcolors.util.colorToHSL
33+
import com.smarttoolfactory.extendedcolors.util.colorToHex
34+
import com.smarttoolfactory.extendedcolors.util.getColorTonesList
35+
import com.smarttoolfactory.extendedcolors.util.material3ToneRange
36+
import kotlinx.coroutines.Dispatchers
37+
import kotlinx.coroutines.flow.distinctUntilChanged
38+
import kotlinx.coroutines.flow.flowOn
39+
import kotlinx.coroutines.flow.mapLatest
40+
41+
@Composable
42+
fun M3ColorPicker(onColorChange: (Color) -> Unit) {
43+
44+
val clipboardManager = LocalClipboardManager.current
45+
val context = LocalContext.current
46+
47+
Column(
48+
modifier = Modifier
49+
.fillMaxSize()
50+
.background(Color.Black.copy(alpha = .8f)),
51+
horizontalAlignment = Alignment.CenterHorizontally
52+
) {
53+
54+
val colorNameParser = rememberColorParser()
55+
56+
var colorSwatchIndex by remember { mutableStateOf(0) }
57+
var color by remember { mutableStateOf(MaterialColor.Red500) }
58+
var md3Tones by remember { mutableStateOf(getColorTonesList(color)) }
59+
60+
val colorSelectionIndex =
61+
remember { ColorSelectionIndex(mainSelection = 0, subSelection = 0) }
62+
63+
val colorSwatch: LinkedHashMap<Int, Color> =
64+
remember(colorSwatchIndex) { ColorSwatch.primaryColorSwatches[colorSwatchIndex] }
65+
66+
val keys: MutableList<Int> = colorSwatch.keys.toMutableList()
67+
val colors: MutableList<Color> = colorSwatch.values.toMutableList()
68+
69+
var colorName by remember { mutableStateOf("") }
70+
71+
LaunchedEffect(key1 = colorNameParser) {
72+
73+
snapshotFlow { color }
74+
.distinctUntilChanged()
75+
.mapLatest { color: Color ->
76+
colorNameParser.parseColorName(color)
77+
}
78+
.flowOn(Dispatchers.Default)
79+
.collect { name: String ->
80+
colorName = name
81+
}
82+
}
83+
84+
LazyVerticalGrid(
85+
columns = GridCells.Fixed(6),
86+
contentPadding = PaddingValues(8.dp),
87+
verticalArrangement = Arrangement.spacedBy(4.dp),
88+
horizontalArrangement = Arrangement.spacedBy(4.dp),
89+
) {
90+
itemsIndexed(ColorSwatch.primaryHeaderColors) { index: Int, item: Color ->
91+
92+
ColorDisplayWithIcon(
93+
modifier = Modifier
94+
.clip(RoundedCornerShape(8.dp))
95+
.aspectRatio(1f)
96+
.clickable {
97+
color = item
98+
onColorChange(item)
99+
colorSwatchIndex = index
100+
colorSelectionIndex.mainSelection = 0
101+
colorSelectionIndex.subSelection = index
102+
md3Tones = getColorTonesList(item)
103+
},
104+
selected = (colorSelectionIndex.mainSelection == 0 &&
105+
colorSelectionIndex.subSelection == index) || (
106+
colorSelectionIndex.mainSelection == 1 &&
107+
colorSelectionIndex.subSelection == 5 &&
108+
index == colorSwatchIndex
109+
),
110+
backgroundColor = item
111+
)
112+
}
113+
}
114+
115+
Text(
116+
text = "Material Design2 Shade",
117+
modifier = Modifier
118+
.fillMaxWidth()
119+
.padding(2.dp),
120+
textAlign = TextAlign.Center,
121+
fontSize = 16.sp,
122+
fontWeight = FontWeight.Bold,
123+
color = Color.White
124+
)
125+
126+
LazyVerticalGrid(
127+
columns = GridCells.Fixed(8),
128+
contentPadding = PaddingValues(8.dp),
129+
verticalArrangement = Arrangement.spacedBy(4.dp),
130+
horizontalArrangement = Arrangement.spacedBy(4.dp),
131+
) {
132+
itemsIndexed(colors) { index: Int, item: Color ->
133+
ColorDisplayWithTitle(
134+
modifier = Modifier
135+
.clip(RoundedCornerShape(8.dp))
136+
.aspectRatio(1f)
137+
.clickable {
138+
color = item
139+
colorSelectionIndex.mainSelection = 1
140+
colorSelectionIndex.subSelection = index
141+
onColorChange(item)
142+
md3Tones = getColorTonesList(item)
143+
},
144+
selected = (colorSelectionIndex.mainSelection == 0 && index == 5)
145+
|| (colorSelectionIndex.mainSelection == 1
146+
&& colorSelectionIndex.subSelection == index),
147+
backgroundColor = item,
148+
contentColor = if (index < 5) Color.Black else Color.White,
149+
title = keys[index].toString(),
150+
)
151+
}
152+
}
153+
154+
Text(
155+
text = "Material Design3 Tonal Palette",
156+
modifier = Modifier
157+
.fillMaxWidth()
158+
.padding(2.dp),
159+
textAlign = TextAlign.Center,
160+
fontSize = 16.sp,
161+
fontWeight = FontWeight.Bold,
162+
color = Color.White
163+
)
164+
165+
LazyVerticalGrid(
166+
columns = GridCells.Fixed(8),
167+
contentPadding = PaddingValues(8.dp),
168+
verticalArrangement = Arrangement.spacedBy(4.dp),
169+
horizontalArrangement = Arrangement.spacedBy(4.dp),
170+
) {
171+
itemsIndexed(md3Tones) { index: Int, item: Color ->
172+
ColorDisplayWithTitle(
173+
modifier = Modifier
174+
.aspectRatio(1f)
175+
.clip(RoundedCornerShape(8.dp))
176+
.aspectRatio(1f)
177+
.clickable {
178+
colorSelectionIndex.mainSelection = 2
179+
colorSelectionIndex.subSelection = index
180+
color = item
181+
onColorChange(item)
182+
},
183+
backgroundColor = item,
184+
selected = (colorSelectionIndex.mainSelection == 2
185+
&& colorSelectionIndex.subSelection == index),
186+
contentColor = if (index < 6) Color.White else Color.Black,
187+
title = material3ToneRange[index].toString()
188+
)
189+
}
190+
}
191+
192+
Spacer(modifier = Modifier.height(30.dp))
193+
val lightness = colorToHSL(color)[2]
194+
val textColor = if (lightness < .6f) Color.White else Color.Black
195+
196+
197+
Text(
198+
text = colorName,
199+
modifier = Modifier
200+
.fillMaxWidth()
201+
.padding(2.dp),
202+
textAlign = TextAlign.Center,
203+
fontSize = 20.sp,
204+
fontWeight = FontWeight.Bold,
205+
color = Color.White
206+
)
207+
208+
209+
Row(
210+
modifier = Modifier
211+
.padding(8.dp)
212+
.background(color = color, RoundedCornerShape(50))
213+
.padding(horizontal = 20.dp, vertical = 10.dp),
214+
verticalAlignment = Alignment.CenterVertically
215+
) {
216+
217+
val hexText = colorToHex(color = color)
218+
Text(
219+
text = hexText,
220+
fontSize = 24.sp,
221+
color = textColor
222+
)
223+
Spacer(modifier = Modifier.width(20.dp))
224+
IconButton(onClick = {
225+
Toast.makeText(context, "Copied $hexText", Toast.LENGTH_SHORT).show()
226+
clipboardManager.setText(AnnotatedString(hexText))
227+
}) {
228+
Icon(
229+
tint = textColor,
230+
painter = painterResource(id = R.drawable.ic_baseline_content_copy_24),
231+
contentDescription = "clipboard"
232+
)
233+
}
234+
}
235+
236+
}
237+
}
238+
239+
@Composable
240+
fun ColorDisplayWithTitle(
241+
modifier: Modifier,
242+
title: String = "",
243+
selected: Boolean,
244+
contentColor: Color = Color.Unspecified,
245+
backgroundColor: Color
246+
) {
247+
Box(
248+
contentAlignment = Alignment.Center
249+
) {
250+
Box(
251+
modifier = modifier
252+
.background(backgroundColor)
253+
)
254+
255+
Text(text = title, color = contentColor, fontSize = 16.sp)
256+
257+
if (selected) {
258+
Icon(
259+
modifier = modifier
260+
.background(contentColor.copy(alpha = .5f))
261+
.padding(4.dp),
262+
imageVector = Icons.Default.Check,
263+
contentDescription = "check",
264+
tint = Color.Green
265+
)
266+
}
267+
}
268+
}
269+
270+
@Composable
271+
fun ColorDisplayWithIcon(
272+
modifier: Modifier,
273+
selected: Boolean,
274+
contentColor: Color = Color.Unspecified,
275+
backgroundColor: Color
276+
) {
277+
Box(
278+
contentAlignment = Alignment.Center
279+
) {
280+
Box(
281+
modifier = modifier
282+
.background(backgroundColor)
283+
)
284+
285+
if (selected) {
286+
Icon(
287+
modifier = modifier
288+
.background(contentColor.copy(alpha = .5f))
289+
.padding(4.dp),
290+
imageVector = Icons.Default.Check,
291+
contentDescription = "check",
292+
tint = Color.Green
293+
)
294+
}
295+
}
296+
}
297+
298+
data class ColorSelectionIndex(var mainSelection: Int = 0, var subSelection: Int = 0)

app/src/main/java/com/smarttoolfactory/composecolorsextended/MainActivity.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import androidx.compose.material.*
1111
import androidx.compose.runtime.*
1212
import androidx.compose.ui.Modifier
1313
import androidx.compose.ui.graphics.Color
14+
import androidx.compose.ui.platform.ClipboardManager
15+
import androidx.compose.ui.platform.LocalClipboardManager
16+
import androidx.compose.ui.text.AnnotatedString
1417
import androidx.compose.ui.unit.dp
1518
import com.google.accompanist.pager.ExperimentalPagerApi
1619
import com.google.accompanist.pager.HorizontalPager
@@ -21,7 +24,6 @@ import com.smarttoolfactory.composecolorsextended.demo.GradientAngleDemo
2124
import com.smarttoolfactory.composecolorsextended.demo.MD2ColorSelectionDemo
2225
import com.smarttoolfactory.composecolorsextended.demo.MD3ColorShadeSelectionDemo
2326
import com.smarttoolfactory.composecolorsextended.ui.theme.ComposeColorsExtendedTheme
24-
import com.smarttoolfactory.extendedcolors.ColorSwatch
2527
import com.smarttoolfactory.extendedcolors.util.colorToHSL
2628
import kotlinx.coroutines.launch
2729

app/src/main/java/com/smarttoolfactory/composecolorsextended/MaterialColorPicker.kt

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -118,35 +118,6 @@ fun ColorDisplay(modifier: Modifier, color: Color) {
118118
)
119119
}
120120

121-
@Composable
122-
fun ColorDisplayWithTitle(
123-
modifier: Modifier,
124-
title: String,
125-
selected: Boolean,
126-
textColor: Color,
127-
color: Color
128-
) {
129-
Box(
130-
contentAlignment = Alignment.Center
131-
) {
132-
Box(
133-
modifier = modifier
134-
.background(color)
135-
)
136-
137-
Text(text = title, color = textColor, fontSize = 16.sp)
138-
139-
if (selected) {
140-
Icon(
141-
imageVector = Icons.Default.Check,
142-
contentDescription = "check",
143-
modifier = modifier.background(textColor.copy(alpha = .5f)),
144-
tint = Color.Green
145-
)
146-
}
147-
}
148-
}
149-
150121
@Composable
151122
fun ColorRowWithInfo(
152123
modifier: Modifier,

app/src/main/java/com/smarttoolfactory/composecolorsextended/demo/ColorData.kt

Lines changed: 3 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)