Skip to content

Commit

Permalink
Color picker for compose
Browse files Browse the repository at this point in the history
  • Loading branch information
massivemadness committed Feb 5, 2025
1 parent 0117098 commit 4d3dfc6
Show file tree
Hide file tree
Showing 53 changed files with 257 additions and 248 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/*
* Copyright 2023 Squircle CE contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.blacksquircle.ui.ds.dialog

import android.graphics.Typeface
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.DialogProperties
import androidx.core.graphics.toColorInt
import com.blacksquircle.ui.ds.SquircleTheme
import com.blacksquircle.ui.ds.extensions.toHexString
import com.blacksquircle.ui.ds.textfield.TextField
import com.github.skydoves.colorpicker.compose.AlphaSlider
import com.github.skydoves.colorpicker.compose.BrightnessSlider
import com.github.skydoves.colorpicker.compose.HsvColorPicker
import com.github.skydoves.colorpicker.compose.rememberColorPickerController

@Composable
fun ColorPickerDialog(
title: String,
onDismiss: () -> Unit,
modifier: Modifier = Modifier,
confirmButton: String? = null,
dismissButton: String? = null,
alphaSlider: Boolean = true,
brightnessSlider: Boolean = true,
initialColor: Color = Color.White,
onColorSelected: (Color) -> Unit = {},
onDismissClicked: () -> Unit = {},
properties: DialogProperties = DialogProperties(),
) {
val controller = rememberColorPickerController()
var textColor by rememberSaveable {
mutableStateOf(initialColor.toHexString())
}

AlertDialog(
title = title,
content = {
Column {
HsvColorPicker(
initialColor = initialColor,
onColorChanged = { colorEnvelope ->
if (colorEnvelope.fromUser) {
textColor = "#" + colorEnvelope.hexCode
}
},
controller = controller,
modifier = Modifier
.aspectRatio(1f / 1f)
.padding(24.dp),
)

if (alphaSlider) {
AlphaSlider(
initialColor = initialColor,
controller = controller,
modifier = Modifier
.fillMaxWidth()
.height(28.dp),
)
Spacer(Modifier.height(16.dp))
}

if (brightnessSlider) {
BrightnessSlider(
initialColor = initialColor,
controller = controller,
modifier = Modifier
.fillMaxWidth()
.height(28.dp),
)
Spacer(Modifier.height(16.dp))
}

TextField(
inputText = textColor,
onInputChanged = { input ->
textColor = input
try {
val color = Color(input.toColorInt())
controller.selectByColor(color, fromUser = false)
} catch (e: Exception) {
// ignored
}
},
textStyle = TextStyle(
fontFamily = FontFamily(Typeface.MONOSPACE),
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
),
modifier = Modifier
.align(Alignment.CenterHorizontally)
.width(150.dp)
)
}
},
onDismiss = onDismiss,
modifier = modifier,
verticalScroll = true,
horizontalPadding = true,
confirmButton = confirmButton,
dismissButton = dismissButton,
onConfirmClicked = { onColorSelected(controller.selectedColor.value) },
onDismissClicked = onDismissClicked,
properties = properties,
)
}

@Preview
@Composable
private fun ColorPickerDialogPreview() {
SquircleTheme {
ColorPickerDialog(
title = "Color Picker",
onDismiss = {},
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,20 @@ package com.blacksquircle.ui.ds.extensions

import android.content.res.Resources
import android.graphics.Color
import androidx.compose.ui.graphics.Color as ComposeColor

fun Int.dpToPx(): Int = (this * Resources.getSystem().displayMetrics.density).toInt()
fun Int.pxToDp(): Int = (this / Resources.getSystem().displayMetrics.density).toInt()

fun Int.toHexString(fallbackColor: String = "#000000"): String {
fun ComposeColor.toHexString(): String {
val red = this.red * 255
val green = this.green * 255
val blue = this.blue * 255
val alpha = this.alpha * 255
return String.format("#%02x%02x%02x%02x", alpha.toInt(), red.toInt(), green.toInt(), blue.toInt())
}

fun Int.toHexString(fallbackColor: String = "#FFFFFF"): String {
return try {
"#" + Integer.toHexString(this)
} catch (e: Exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,38 +22,18 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.mapSaver
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.blacksquircle.ui.ds.R
import com.blacksquircle.ui.ds.SquircleTheme
import com.blacksquircle.ui.ds.dialog.AlertDialog

private const val RedKey = "red"
private const val GreenKey = "green"
private const val BlueKey = "blue"

private val ColorSaver = mapSaver(
save = {
mapOf(
RedKey to it.red,
GreenKey to it.green,
BlueKey to it.blue,
)
},
restore = {
Color(
red = it[RedKey] as Float,
green = it[GreenKey] as Float,
blue = it[BlueKey] as Float
)
}
)
import com.blacksquircle.ui.ds.dialog.ColorPickerDialog

@Composable
fun ColorPreference(
Expand All @@ -63,10 +43,8 @@ fun ColorPreference(
initialColor: Color = Color.Black,
onColorSelected: (Color) -> Unit = {},
enabled: Boolean = true,
dialogTitle: String? = null,
dialogTitle: String = stringResource(R.string.dialog_title_color_picker),
dialogShown: Boolean = false,
confirmButton: String? = null,
dismissButton: String? = null,
) {
var showDialog by rememberSaveable {
mutableStateOf(dialogShown)
Expand All @@ -89,23 +67,17 @@ fun ColorPreference(
modifier = modifier,
)
if (showDialog) {
val color = rememberSaveable(stateSaver = ColorSaver) {
mutableStateOf(initialColor)
}
AlertDialog(
title = dialogTitle ?: title,
content = {
// TODO ColorLayout
},
confirmButton = confirmButton,
onConfirmClicked = {
showDialog = false
onColorSelected(color.value)
},
dismissButton = dismissButton,
onDismissClicked = {
ColorPickerDialog(
title = dialogTitle,
confirmButton = stringResource(R.string.common_select),
dismissButton = stringResource(android.R.string.cancel),
alphaSlider = false,
initialColor = initialColor,
onColorSelected = { color ->
showDialog = false
onColorSelected(color)
},
onDismissClicked = { showDialog = false },
onDismiss = { showDialog = false },
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
Expand Down Expand Up @@ -57,7 +57,7 @@ fun Preference(
) {
if (leadingContent != null) {
leadingContent()
Spacer(modifier = Modifier.size(16.dp))
Spacer(modifier = Modifier.width(16.dp))
}
Column(modifier = Modifier.weight(1f)) {
Text(
Expand Down Expand Up @@ -86,7 +86,7 @@ fun Preference(
}
}
if (trailingContent != null) {
Spacer(modifier = Modifier.size(16.dp))
Spacer(modifier = Modifier.width(16.dp))
trailingContent()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ fun PreferenceHeader(
modifier = modifier
.fillMaxWidth()
.clickable(onClick = onClick)
.padding(horizontal = 18.dp, vertical = 8.dp)
.padding(
horizontal = 24.dp,
vertical = 8.dp
)
) {
Text(
text = title,
Expand Down
Loading

0 comments on commit 4d3dfc6

Please sign in to comment.