mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-04-24 00:26:22 +00:00
improve color picker: better landscape layout and survive orientation change
This commit is contained in:
parent
1c955a34b2
commit
b65d00e142
3 changed files with 91 additions and 70 deletions
|
@ -301,8 +301,6 @@ sealed interface KeyData : AbstractKeyData {
|
|||
// idea: directly create PopupKeySpec, but need to deal with needsToUpcase and popupKeysColumnAndFlags
|
||||
fun getPopupLabel(params: KeyboardParams): String {
|
||||
val newLabel = processLabel(params)
|
||||
if (newLabel == "!")
|
||||
Log.w("test", "code $code, newCode ${processCode()}")
|
||||
if (code == KeyCode.UNSPECIFIED) {
|
||||
if (newLabel == label) return label
|
||||
val newCode = processCode()
|
||||
|
|
|
@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Row
|
|||
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.text.KeyboardOptions
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
|
@ -15,22 +16,24 @@ import androidx.compose.runtime.getValue
|
|||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
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.graphics.Paint
|
||||
import androidx.compose.ui.graphics.PaintingStyle
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.text.TextRange
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
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
|
||||
|
||||
// todo: needs different layout in landscape (bars on the side or something like that)
|
||||
@Composable
|
||||
fun ColorPickerDialog(
|
||||
onDismissRequest: () -> Unit,
|
||||
|
@ -50,70 +53,91 @@ fun ColorPickerDialog(
|
|||
val initialString = initialColor.toUInt().toString(16)
|
||||
var textValue by remember { mutableStateOf(TextFieldValue(initialString, TextRange(initialString.length))) }
|
||||
var currentColor by remember { mutableStateOf(Color(initialColor)) }
|
||||
val width = LocalConfiguration.current.screenWidthDp
|
||||
val height = LocalConfiguration.current.screenHeightDp
|
||||
val useWideLayout = height < 500 && width > height
|
||||
@Composable fun topBar() {
|
||||
Row {
|
||||
Surface(
|
||||
color = Color(initialColor),
|
||||
modifier = Modifier.fillMaxWidth(0.5f)
|
||||
.padding(start = 10.dp)
|
||||
.height(barHeight))
|
||||
{ }
|
||||
Surface(
|
||||
color = currentColor,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.padding(end = 10.dp)
|
||||
.height(barHeight))
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@Composable fun picker() {
|
||||
HsvColorPicker(
|
||||
modifier = Modifier
|
||||
.size(300.dp)
|
||||
.padding(10.dp),
|
||||
controller = controller,
|
||||
onColorChanged = {
|
||||
if (it.fromUser)
|
||||
textValue = TextFieldValue(it.hexCode, selection = TextRange(it.hexCode.length))
|
||||
currentColor = it.color
|
||||
},
|
||||
initialColor = Color(initialColor),
|
||||
)
|
||||
}
|
||||
@Composable fun slidersAndTextField() {
|
||||
AlphaSlider(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(10.dp)
|
||||
.height(barHeight),
|
||||
controller = controller,
|
||||
initialColor = Color(initialColor),
|
||||
wheelPaint = wheelPaint
|
||||
)
|
||||
BrightnessSlider(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(10.dp)
|
||||
.height(barHeight),
|
||||
controller = controller,
|
||||
initialColor = Color(initialColor),
|
||||
wheelPaint = wheelPaint
|
||||
)
|
||||
TextField(
|
||||
value = textValue,
|
||||
// todo: KeyboardType.Password is a crappy way of avoiding suggestions... is there really no way in compose?
|
||||
keyboardOptions = KeyboardOptions(autoCorrectEnabled = false, keyboardType = KeyboardType.Password),
|
||||
onValueChange = {
|
||||
textValue = it
|
||||
val androidColor = runCatching { android.graphics.Color.parseColor("#${it.text}") }.getOrNull()
|
||||
if (androidColor != null)
|
||||
controller.selectByColor(Color(androidColor), false)
|
||||
}
|
||||
)
|
||||
}
|
||||
ThreeButtonAlertDialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
onConfirmed = { onConfirmed(controller.selectedColor.value.toArgb()) },
|
||||
title = { Text(title) },
|
||||
content = {
|
||||
Column {
|
||||
Row {
|
||||
Surface(
|
||||
color = Color(initialColor),
|
||||
modifier = Modifier.fillMaxWidth(0.5f)
|
||||
.padding(start = 10.dp)
|
||||
.height(barHeight))
|
||||
{ }
|
||||
Surface(
|
||||
color = currentColor,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.padding(end = 10.dp)
|
||||
.height(barHeight))
|
||||
{ }
|
||||
}
|
||||
HsvColorPicker(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(300.dp)
|
||||
.padding(10.dp),
|
||||
controller = controller,
|
||||
onColorChanged = {
|
||||
if (it.fromUser)
|
||||
textValue = TextFieldValue(it.hexCode, selection = TextRange(it.hexCode.length))
|
||||
currentColor = it.color
|
||||
},
|
||||
initialColor = Color(initialColor),
|
||||
)
|
||||
AlphaSlider(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(10.dp)
|
||||
.height(barHeight),
|
||||
controller = controller,
|
||||
initialColor = Color(initialColor),
|
||||
wheelPaint = wheelPaint
|
||||
)
|
||||
BrightnessSlider(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(10.dp)
|
||||
.height(barHeight),
|
||||
controller = controller,
|
||||
initialColor = Color(initialColor),
|
||||
wheelPaint = wheelPaint
|
||||
)
|
||||
TextField(
|
||||
value = textValue,
|
||||
// KeyboardType.Password is a crappy way of avoiding suggestions... is there really no way in compose?
|
||||
keyboardOptions = KeyboardOptions(autoCorrectEnabled = false, keyboardType = KeyboardType.Password),
|
||||
onValueChange = {
|
||||
textValue = it
|
||||
val androidColor = kotlin.runCatching { android.graphics.Color.parseColor("#${it.text}") }.getOrNull()
|
||||
if (androidColor != null)
|
||||
controller.selectByColor(Color(androidColor), false)
|
||||
if (useWideLayout)
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
picker()
|
||||
Column {
|
||||
topBar()
|
||||
slidersAndTextField()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
Column {
|
||||
topBar()
|
||||
picker()
|
||||
slidersAndTextField()
|
||||
}
|
||||
},
|
||||
properties = DialogProperties(usePlatformDefaultWidth = !useWideLayout)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ import androidx.compose.runtime.LaunchedEffect
|
|||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
|
@ -116,7 +115,8 @@ fun ColorsScreen(
|
|||
else color ?: KeyboardTheme.determineUserColor(userColors, ctx, name, isNight)
|
||||
|
||||
var newThemeName by rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue(themeName)) }
|
||||
var chosenColor: ColorSetting? by remember { mutableStateOf(null) }
|
||||
var chosenColorString: String by rememberSaveable { mutableStateOf("") }
|
||||
val chosenColor = runCatching { Json.decodeFromString<ColorSetting?>(chosenColorString) }.getOrNull()
|
||||
val saveLauncher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
if (it.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult
|
||||
val uri = it.data?.data ?: return@rememberLauncherForActivityResult
|
||||
|
@ -174,7 +174,7 @@ fun ColorsScreen(
|
|||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
.clickable { chosenColor = colorSetting }
|
||||
.clickable { chosenColorString = Json.encodeToString(colorSetting) }
|
||||
) {
|
||||
Spacer(
|
||||
modifier = Modifier
|
||||
|
@ -204,19 +204,18 @@ fun ColorsScreen(
|
|||
}
|
||||
)
|
||||
if (chosenColor != null) {
|
||||
val color = chosenColor!!
|
||||
ColorPickerDialog(
|
||||
onDismissRequest = { chosenColor = null },
|
||||
initialColor = color.displayColor(),
|
||||
title = color.displayName,
|
||||
onDismissRequest = { chosenColorString = "" },
|
||||
initialColor = chosenColor.displayColor(),
|
||||
title = chosenColor.displayName,
|
||||
) {
|
||||
if (moreColors == 2) {
|
||||
val oldColors = KeyboardTheme.readUserAllColors(prefs, themeName)
|
||||
oldColors[ColorType.valueOf(color.name)] = it
|
||||
oldColors[ColorType.valueOf(chosenColor.name)] = it
|
||||
KeyboardTheme.writeUserAllColors(prefs, themeName, oldColors)
|
||||
} else {
|
||||
val oldUserColors = KeyboardTheme.readUserColors(prefs, themeName)
|
||||
val newUserColors = (oldUserColors + ColorSetting(color.name, false, it))
|
||||
val newUserColors = (oldUserColors + ColorSetting(chosenColor.name, false, it))
|
||||
.reversed().distinctBy { it.displayName }
|
||||
KeyboardTheme.writeUserColors(prefs, themeName, newUserColors)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue