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