mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-05-14 14:02:44 +00:00
finish toolbar screen
This commit is contained in:
parent
26a45d82f3
commit
a90a894827
4 changed files with 168 additions and 6 deletions
|
@ -299,12 +299,12 @@ fun readCustomLongpressCodes(prefs: SharedPreferences) = prefs.getString(Setting
|
||||||
it.substringBefore(",") to code
|
it.substringBefore(",") to code
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun writeCustomKeyCodes(prefs: SharedPreferences, codes: Map<String, Int?>) {
|
fun writeCustomKeyCodes(prefs: SharedPreferences, codes: Map<String, Int?>) {
|
||||||
val string = codes.mapNotNull { entry -> entry.value?.let { "${entry.key},$it" } }.joinToString(";")
|
val string = codes.mapNotNull { entry -> entry.value?.let { "${entry.key},$it" } }.joinToString(";")
|
||||||
prefs.edit().putString(Settings.PREF_TOOLBAR_CUSTOM_KEY_CODES, string).apply()
|
prefs.edit().putString(Settings.PREF_TOOLBAR_CUSTOM_KEY_CODES, string).apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun writeCustomLongpressCodes(prefs: SharedPreferences, codes: Map<String, Int?>) {
|
fun writeCustomLongpressCodes(prefs: SharedPreferences, codes: Map<String, Int?>) {
|
||||||
val string = codes.mapNotNull { entry -> entry.value?.let { "${entry.key},$it" } }.joinToString(";")
|
val string = codes.mapNotNull { entry -> entry.value?.let { "${entry.key},$it" } }.joinToString(";")
|
||||||
prefs.edit().putString(Settings.PREF_TOOLBAR_CUSTOM_LONGPRESS_CODES, string).apply()
|
prefs.edit().putString(Settings.PREF_TOOLBAR_CUSTOM_LONGPRESS_CODES, string).apply()
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
// screens could have a lazy column of preferences and category separators, and the list has an if-setting-then-null for hiding
|
// screens could have a lazy column of preferences and category separators, and the list has an if-setting-then-null for hiding
|
||||||
// lazyColumn also has the key, this should be used! and must be unique
|
// lazyColumn also has the key, this should be used! and must be unique
|
||||||
// consider that stuff in composables can get called quite often on any changes -> use remember for things that are slow (maybe add test logging)
|
// consider that stuff in composables can get called quite often on any changes -> use remember for things that are slow (maybe add test logging)
|
||||||
|
// dialogs should be rememberSaveable to survive display orientation change and stuff?
|
||||||
|
// default buttons for toolbar key(s) customizer and toolbar reorder dialog
|
||||||
|
|
||||||
// later
|
// later
|
||||||
// one single place for default values (in composables and settings)
|
// one single place for default values (in composables and settings)
|
||||||
|
@ -41,12 +43,16 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
// -> now toolbar key always has the wrong state
|
// -> now toolbar key always has the wrong state
|
||||||
// color settings needs a color search
|
// color settings needs a color search
|
||||||
// more convenient access to prefs
|
// more convenient access to prefs
|
||||||
|
// merge PREF_TOOLBAR_CUSTOM_KEY_CODES and PREF_TOOLBAR_CUSTOM_LONGPRESS_CODES
|
||||||
|
// should be single pref containing both
|
||||||
|
// needs settings upgrade of course...
|
||||||
// consider disabled settings & search
|
// consider disabled settings & search
|
||||||
// don't show -> users confused
|
// don't show -> users confused
|
||||||
// show as disabled -> users confused
|
// show as disabled -> users confused
|
||||||
// show (but change will not do anything because another setting needs to be enabled first)
|
// show (but change will not do anything because another setting needs to be enabled first)
|
||||||
// -> users confused, but probably better than the 2 above
|
// -> users confused, but probably better than the 2 above
|
||||||
// adjust layout a little, there is too much empty space and titles are too large (dialogs!)
|
// adjust layout a little, there is too much empty space and titles are too large (dialogs!)
|
||||||
|
// check dialogs have the same colors
|
||||||
|
|
||||||
// maybe later
|
// maybe later
|
||||||
// weird problem with app sometimes closing on back, but that's related to "old" settings (don't care if all are removed)
|
// weird problem with app sometimes closing on back, but that's related to "old" settings (don't care if all are removed)
|
||||||
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
package helium314.keyboard.settings.dialogs
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
|
import androidx.compose.material3.AlertDialog
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
|
import androidx.compose.material3.TextField
|
||||||
|
import androidx.compose.material3.contentColorFor
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
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.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
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.window.DialogProperties
|
||||||
|
import helium314.keyboard.keyboard.internal.KeyboardIconsSet
|
||||||
|
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode.checkAndConvertCode
|
||||||
|
import helium314.keyboard.latin.R
|
||||||
|
import helium314.keyboard.latin.settings.Settings
|
||||||
|
import helium314.keyboard.latin.utils.ToolbarKey
|
||||||
|
import helium314.keyboard.latin.utils.getCodeForToolbarKey
|
||||||
|
import helium314.keyboard.latin.utils.getCodeForToolbarKeyLongClick
|
||||||
|
import helium314.keyboard.latin.utils.getStringResourceOrName
|
||||||
|
import helium314.keyboard.latin.utils.readCustomKeyCodes
|
||||||
|
import helium314.keyboard.latin.utils.readCustomLongpressCodes
|
||||||
|
import helium314.keyboard.latin.utils.writeCustomKeyCodes
|
||||||
|
import helium314.keyboard.latin.utils.writeCustomLongpressCodes
|
||||||
|
import helium314.keyboard.settings.prefs
|
||||||
|
import helium314.keyboard.settings.screens.GetIcon
|
||||||
|
|
||||||
|
// todo:
|
||||||
|
// reading and writing prefs should be done in the preference, or at least with the provided (single!) key
|
||||||
|
@Composable
|
||||||
|
fun ToolbarKeysCustomizer(
|
||||||
|
onDismissRequest: () -> Unit
|
||||||
|
) {
|
||||||
|
val ctx = LocalContext.current
|
||||||
|
var showKeyCustomizer: ToolbarKey? by remember { mutableStateOf(null) }
|
||||||
|
AlertDialog(
|
||||||
|
onDismissRequest = onDismissRequest,
|
||||||
|
confirmButton = {
|
||||||
|
TextButton(onClick = onDismissRequest) { Text(stringResource(R.string.dialog_close)) }
|
||||||
|
},
|
||||||
|
dismissButton = { },
|
||||||
|
title = { Text(stringResource(R.string.customize_toolbar_key_codes)) },
|
||||||
|
text = {
|
||||||
|
LazyColumn {
|
||||||
|
items(ToolbarKey.entries) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier.clickable { showKeyCustomizer = it }.fillParentMaxWidth()
|
||||||
|
) {
|
||||||
|
KeyboardIconsSet.instance.GetIcon(it.name)
|
||||||
|
Text(it.name.lowercase().getStringResourceOrName("", ctx).toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
shape = MaterialTheme.shapes.medium,
|
||||||
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
|
textContentColor = contentColorFor(MaterialTheme.colorScheme.surface),
|
||||||
|
properties = DialogProperties(),
|
||||||
|
)
|
||||||
|
if (showKeyCustomizer != null) {
|
||||||
|
val shownKey = showKeyCustomizer
|
||||||
|
if (shownKey != null)
|
||||||
|
ToolbarKeyCustomizer(shownKey) { showKeyCustomizer = null }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ToolbarKeyCustomizer(
|
||||||
|
key: ToolbarKey,
|
||||||
|
onDismissRequest: () -> Unit
|
||||||
|
) {
|
||||||
|
val ctx = LocalContext.current
|
||||||
|
val prefs = ctx.prefs()
|
||||||
|
var code by remember { mutableStateOf(TextFieldValue(getCodeForToolbarKey(key).toString())) }
|
||||||
|
var longPressCode by remember { mutableStateOf(TextFieldValue(getCodeForToolbarKeyLongClick(key).toString())) }
|
||||||
|
AlertDialog(
|
||||||
|
onDismissRequest = onDismissRequest,
|
||||||
|
confirmButton = {
|
||||||
|
TextButton(
|
||||||
|
onClick = {
|
||||||
|
writeCustomKeyCodes(prefs, readCustomKeyCodes(prefs) + (key.name to checkCode(code)))
|
||||||
|
writeCustomLongpressCodes(prefs, readCustomLongpressCodes(prefs) + (key.name to checkCode(longPressCode)))
|
||||||
|
onDismissRequest()
|
||||||
|
},
|
||||||
|
enabled = checkCode(code) != null && checkCode(longPressCode) != null
|
||||||
|
) { Text(stringResource(android.R.string.ok)) }
|
||||||
|
},
|
||||||
|
dismissButton = { TextButton(onClick = onDismissRequest) { Text(stringResource(android.R.string.cancel)) } },
|
||||||
|
title = { Text(key.name.lowercase().getStringResourceOrName("", ctx).toString()) },
|
||||||
|
text = {
|
||||||
|
Column {
|
||||||
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
Text(stringResource(R.string.key_code), Modifier.weight(0.5f))
|
||||||
|
TextField(
|
||||||
|
value = code,
|
||||||
|
onValueChange = { code = it },
|
||||||
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
||||||
|
modifier = Modifier.weight(0.5f)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
Text(stringResource(R.string.long_press_code), Modifier.weight(0.5f))
|
||||||
|
TextField(
|
||||||
|
value = longPressCode,
|
||||||
|
onValueChange = { longPressCode = it },
|
||||||
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
||||||
|
modifier = Modifier.weight(0.5f)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
shape = MaterialTheme.shapes.medium,
|
||||||
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
|
textContentColor = contentColorFor(MaterialTheme.colorScheme.surface),
|
||||||
|
properties = DialogProperties(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun PreviewToolbarKeyCustomizer() {
|
||||||
|
Settings.init(LocalContext.current)
|
||||||
|
ToolbarKeyCustomizer(ToolbarKey.CUT) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun PreviewToolbarKeysCustomizer() {
|
||||||
|
Settings.init(LocalContext.current)
|
||||||
|
KeyboardIconsSet.instance.loadIcons(LocalContext.current)
|
||||||
|
ToolbarKeysCustomizer { }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkCode(code: TextFieldValue) = runCatching {
|
||||||
|
code.text.toIntOrNull()?.takeIf { it.checkAndConvertCode() <= Char.MAX_VALUE.code }
|
||||||
|
}.getOrNull()
|
|
@ -41,6 +41,7 @@ import helium314.keyboard.settings.SettingsActivity2
|
||||||
import helium314.keyboard.settings.SwitchPreference
|
import helium314.keyboard.settings.SwitchPreference
|
||||||
import helium314.keyboard.settings.Theme
|
import helium314.keyboard.settings.Theme
|
||||||
import helium314.keyboard.settings.dialogs.ReorderDialog
|
import helium314.keyboard.settings.dialogs.ReorderDialog
|
||||||
|
import helium314.keyboard.settings.dialogs.ToolbarKeysCustomizer
|
||||||
import helium314.keyboard.settings.prefs
|
import helium314.keyboard.settings.prefs
|
||||||
import helium314.keyboard.settings.themeChanged
|
import helium314.keyboard.settings.themeChanged
|
||||||
|
|
||||||
|
@ -112,8 +113,11 @@ fun createToolbarPrefs(context: Context) = listOf(
|
||||||
name = def.title,
|
name = def.title,
|
||||||
onClick = { showDialog = true },
|
onClick = { showDialog = true },
|
||||||
)
|
)
|
||||||
// todo: needs the dialog!
|
if (showDialog)
|
||||||
// which actually changes a different pref key... see if we can avoid it without too much work
|
// todo: CUSTOM_KEY_CODES vs the 2 actual prefs that are changed...
|
||||||
|
ToolbarKeysCustomizer(
|
||||||
|
onDismissRequest = { showDialog = false }
|
||||||
|
)
|
||||||
},
|
},
|
||||||
PrefDef(context, Settings.PREF_QUICK_PIN_TOOLBAR_KEYS, R.string.quick_pin_toolbar_keys, R.string.quick_pin_toolbar_keys_summary) { def ->
|
PrefDef(context, Settings.PREF_QUICK_PIN_TOOLBAR_KEYS, R.string.quick_pin_toolbar_keys, R.string.quick_pin_toolbar_keys_summary) { def ->
|
||||||
SwitchPreference(
|
SwitchPreference(
|
||||||
|
@ -168,7 +172,7 @@ fun ToolbarKeyReorderDialog(
|
||||||
displayItem = { item ->
|
displayItem = { item ->
|
||||||
var checked by remember { mutableStateOf(item.state) }
|
var checked by remember { mutableStateOf(item.state) }
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
KeyboardIconsSet.instance.GetIcon(item.name.lowercase())
|
KeyboardIconsSet.instance.GetIcon(item.name)
|
||||||
val text = item.name.lowercase().getStringResourceOrName("", ctx).toString()
|
val text = item.name.lowercase().getStringResourceOrName("", ctx).toString()
|
||||||
Text(text, Modifier.weight(1f))
|
Text(text, Modifier.weight(1f))
|
||||||
Switch(
|
Switch(
|
||||||
|
@ -199,7 +203,7 @@ fun KeyboardIconsSet.GetIcon(name: String?) {
|
||||||
val drawable = getNewDrawable(name, ctx)
|
val drawable = getNewDrawable(name, ctx)
|
||||||
Box(Modifier.size(40.dp), contentAlignment = Alignment.Center) {
|
Box(Modifier.size(40.dp), contentAlignment = Alignment.Center) {
|
||||||
if (drawable is VectorDrawable)
|
if (drawable is VectorDrawable)
|
||||||
Icon(painterResource(iconIds[name]!!), null, Modifier.fillMaxSize(0.8f))
|
Icon(painterResource(iconIds[name?.lowercase()]!!), null, Modifier.fillMaxSize(0.8f))
|
||||||
else if (drawable != null) {
|
else if (drawable != null) {
|
||||||
val px = TypedValueCompat.dpToPx(40f, ctx.resources.displayMetrics).toInt()
|
val px = TypedValueCompat.dpToPx(40f, ctx.resources.displayMetrics).toInt()
|
||||||
Icon(drawable.toBitmap(px, px).asImageBitmap(), null, Modifier.fillMaxSize(0.8f))
|
Icon(drawable.toBitmap(px, px).asImageBitmap(), null, Modifier.fillMaxSize(0.8f))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue