mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-06-05 06:10:14 +00:00
solve some todos in SubtypeDialog
This commit is contained in:
parent
47070c1086
commit
40de17c148
4 changed files with 91 additions and 48 deletions
|
@ -18,7 +18,7 @@ object LayoutUtils {
|
|||
.apply { addAll(context.resources.getStringArray(R.array.predefined_layouts)) }
|
||||
if (locale.script() == ScriptUtils.SCRIPT_LATIN)
|
||||
return context.resources.getStringArray(R.array.predefined_layouts).toList()
|
||||
return SubtypeSettings.getSubtypesForLocale(locale).mapNotNullTo(HashSet()) { it.mainLayoutName() }
|
||||
return SubtypeSettings.getResourceSubtypesForLocale(locale).mapNotNullTo(HashSet()) { it.mainLayoutName() }
|
||||
}
|
||||
|
||||
fun getLMainLayoutsForLocales(locales: List<Locale>, context: Context): Collection<String> =
|
||||
|
|
|
@ -224,8 +224,21 @@ public final class SubtypeLocaleUtils {
|
|||
}
|
||||
|
||||
@NonNull
|
||||
public static String getSubtypeDisplayNameInSystemLocale(
|
||||
@NonNull final InputMethodSubtype subtype) {
|
||||
public static String getDisplayNameInSystemLocale(@NonNull final String mainLayoutName, @NonNull final Locale locale) {
|
||||
final String displayName = getMainLayoutDisplayName(mainLayoutName);
|
||||
if (displayName != null) // works for custom and latin layouts
|
||||
return displayName;
|
||||
// we have some locale-specific layout
|
||||
for (InputMethodSubtype subtype : SubtypeSettings.INSTANCE.getResourceSubtypesForLocale(locale)) {
|
||||
final String main = LayoutType.Companion.getMainLayoutFromExtraValue(subtype.getExtraValue());
|
||||
if (mainLayoutName.equals(main))
|
||||
return getSubtypeDisplayNameInSystemLocale(subtype);
|
||||
}
|
||||
return mainLayoutName; // should never happen...
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getSubtypeDisplayNameInSystemLocale(@NonNull final InputMethodSubtype subtype) {
|
||||
final Locale displayLocale = ConfigurationCompatKt.locale(sResources.getConfiguration());
|
||||
return getSubtypeDisplayNameInternal(subtype, displayLocale);
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@ object SubtypeSettings {
|
|||
return !resourceSubtypesByLocale[locale].isNullOrEmpty()
|
||||
}
|
||||
|
||||
fun getSubtypesForLocale(locale: Locale): List<InputMethodSubtype> = resourceSubtypesByLocale[locale].orEmpty()
|
||||
fun getResourceSubtypesForLocale(locale: Locale): List<InputMethodSubtype> = resourceSubtypesByLocale[locale].orEmpty()
|
||||
|
||||
fun getAvailableSubtypeLocales(): Collection<Locale> {
|
||||
require(initialized)
|
||||
|
|
|
@ -3,6 +3,7 @@ package helium314.keyboard.settings.dialogs
|
|||
import android.content.Context
|
||||
import android.view.inputmethod.InputMethodSubtype
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
|
@ -12,6 +13,7 @@ import androidx.compose.foundation.rememberScrollState
|
|||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
|
@ -58,20 +60,16 @@ import helium314.keyboard.latin.utils.SubtypeSettings
|
|||
import helium314.keyboard.latin.utils.SubtypeUtilsAdditional
|
||||
import helium314.keyboard.latin.utils.getDictionaryLocales
|
||||
import helium314.keyboard.latin.utils.getStringResourceOrName
|
||||
import helium314.keyboard.latin.utils.locale
|
||||
import helium314.keyboard.latin.utils.prefs
|
||||
import helium314.keyboard.settings.screens.GetIcon
|
||||
import java.util.Locale
|
||||
|
||||
// todo:
|
||||
// save when "editing" a resource subtypes is not working
|
||||
// default buttons missing
|
||||
// string resources
|
||||
// dialog doesn't look good...
|
||||
// settings upgrade to move the override settings to extra values, and actually use them (via getSelectedSubtype, not RichIMM)
|
||||
@Composable
|
||||
fun SubtypeDialog(
|
||||
// could also use InputMethodSubtype if there is any advantage
|
||||
// but as soon as anything is changed we will need an additional subtype anyway...
|
||||
onDismissRequest: () -> Unit,
|
||||
subtype: InputMethodSubtype,
|
||||
onConfirmed: (SettingsSubtype) -> Unit,
|
||||
|
@ -99,8 +97,9 @@ fun SubtypeDialog(
|
|||
text = {
|
||||
Column(
|
||||
modifier = Modifier.verticalScroll(scrollState),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
WithSmallTitle("main layout") {
|
||||
WithSmallTitle(stringResource(R.string.keyboard_layout_set)) {
|
||||
val appLayouts = LayoutUtils.getAvailableLayouts(LayoutType.MAIN, ctx, currentSubtype.locale)
|
||||
val customLayouts = LayoutUtilsCustom.getLayoutFiles(LayoutType.MAIN, ctx, currentSubtype.locale).map { it.name }
|
||||
DropDownField(
|
||||
|
@ -110,10 +109,9 @@ fun SubtypeDialog(
|
|||
currentSubtype = currentSubtype.withLayout(LayoutType.MAIN, it)
|
||||
}
|
||||
) {
|
||||
// todo: displayName can be complicated and may require an inputmethodsubtype...
|
||||
// maybe search for stuff in resource subtypes?
|
||||
Text(it)
|
||||
Text(SubtypeLocaleUtils.getDisplayNameInSystemLocale(it, currentSubtype.locale))
|
||||
// todo: edit button? or only for selected layout? and delete button?
|
||||
// yes, even just to make clear what is custom
|
||||
}
|
||||
}
|
||||
WithSmallTitle(stringResource(R.string.secondary_locale)) {
|
||||
|
@ -121,7 +119,7 @@ fun SubtypeDialog(
|
|||
val text = currentSubtype.getExtraValueOf(ExtraValue.SECONDARY_LOCALES)
|
||||
?.split(Separators.KV)?.joinToString(", ") {
|
||||
LocaleUtils.getLocaleDisplayNameInSystemLocale(it.constructLocale(), ctx)
|
||||
} ?: "none"
|
||||
} ?: stringResource(R.string.action_none)
|
||||
Text(text, Modifier.fillMaxWidth(), style = MaterialTheme.typography.bodyLarge)
|
||||
}
|
||||
}
|
||||
|
@ -131,32 +129,56 @@ fun SubtypeDialog(
|
|||
Text("not yet implemented")
|
||||
}
|
||||
// todo: this looks strange without the title
|
||||
TextButton(onClick = { showKeyOrderDialog = true })
|
||||
{ Text(stringResource(R.string.popup_order), Modifier.fillMaxWidth(), style = MaterialTheme.typography.bodyLarge) }
|
||||
TextButton(onClick = { showHintOrderDialog = true })
|
||||
{ Text(stringResource(R.string.hint_source), Modifier.fillMaxWidth(), style = MaterialTheme.typography.bodyLarge) }
|
||||
if (currentSubtype.locale.script() == SCRIPT_LATIN)
|
||||
Row {
|
||||
TextButton(onClick = { showKeyOrderDialog = true }, Modifier.weight(1f))
|
||||
{ Text(stringResource(R.string.popup_order), style = MaterialTheme.typography.bodyLarge) }
|
||||
DefaultButton(
|
||||
{ currentSubtype = currentSubtype.without(ExtraValue.POPUP_ORDER) },
|
||||
currentSubtype.getExtraValueOf(ExtraValue.POPUP_ORDER) == null
|
||||
)
|
||||
}
|
||||
Row {
|
||||
TextButton(onClick = { showHintOrderDialog = true }, Modifier.weight(1f))
|
||||
{ Text(stringResource(R.string.hint_source), style = MaterialTheme.typography.bodyLarge) }
|
||||
DefaultButton(
|
||||
{ currentSubtype = currentSubtype.without(ExtraValue.HINT_ORDER) },
|
||||
currentSubtype.getExtraValueOf(ExtraValue.HINT_ORDER) == null
|
||||
)
|
||||
}
|
||||
if (currentSubtype.locale.script() == SCRIPT_LATIN) {
|
||||
WithSmallTitle(stringResource(R.string.show_popup_keys_title)) {
|
||||
val explicitValue = currentSubtype.getExtraValueOf(ExtraValue.MORE_POPUPS)
|
||||
val value = explicitValue ?: prefs.getString(Settings.PREF_MORE_POPUP_KEYS, Defaults.PREF_MORE_POPUP_KEYS)!!
|
||||
TextButton(onClick = { showMorePopupsDialog = true }, Modifier.fillMaxWidth())
|
||||
Row {
|
||||
TextButton(onClick = { showMorePopupsDialog = true }, Modifier.weight(1f))
|
||||
{ Text(stringResource(morePopupKeysResId(value))) }
|
||||
DefaultButton(
|
||||
{ currentSubtype = currentSubtype.without(ExtraValue.MORE_POPUPS) },
|
||||
explicitValue == null
|
||||
)
|
||||
}
|
||||
}
|
||||
if (hasLocalizedNumberRow(currentSubtype.locale, ctx))
|
||||
}
|
||||
if (hasLocalizedNumberRow(currentSubtype.locale, ctx)) {
|
||||
Row {
|
||||
val checked = currentSubtype.getExtraValueOf(ExtraValue.LOCALIZED_NUMBER_ROW)?.toBoolean()
|
||||
Text(stringResource(R.string.localized_number_row), Modifier.weight(1f))
|
||||
Switch(
|
||||
checked = currentSubtype.getExtraValueOf(ExtraValue.LOCALIZED_NUMBER_ROW)?.toBoolean()
|
||||
?: prefs.getBoolean(Settings.PREF_LOCALIZED_NUMBER_ROW, Defaults.PREF_LOCALIZED_NUMBER_ROW),
|
||||
checked = checked ?: prefs.getBoolean(Settings.PREF_LOCALIZED_NUMBER_ROW, Defaults.PREF_LOCALIZED_NUMBER_ROW),
|
||||
onCheckedChange = {
|
||||
currentSubtype = currentSubtype.with(ExtraValue.LOCALIZED_NUMBER_ROW, it.toString())
|
||||
}
|
||||
)
|
||||
// todo: default button?
|
||||
DefaultButton(
|
||||
{ currentSubtype = currentSubtype.without(ExtraValue.LOCALIZED_NUMBER_ROW) },
|
||||
checked == null
|
||||
)
|
||||
}
|
||||
}
|
||||
HorizontalDivider()
|
||||
Text(stringResource(R.string.settings_screen_secondary_layouts), style = MaterialTheme.typography.titleMedium)
|
||||
LayoutType.entries.forEach { type ->
|
||||
if (type == LayoutType.MAIN) return@forEach
|
||||
// todo: also some default button, to be shown when necessary, uses currentSubtype.withoutLayout(type)
|
||||
WithSmallTitle(stringResource(type.displayNameId)) {
|
||||
val explicitLayout = currentSubtype.layoutName(type)
|
||||
val layout = explicitLayout ?: Settings.readDefaultLayoutName(type, prefs)
|
||||
|
@ -167,10 +189,12 @@ fun SubtypeDialog(
|
|||
selectedItem = layout,
|
||||
onSelected = {
|
||||
currentSubtype = currentSubtype.withLayout(type, it)
|
||||
}
|
||||
},
|
||||
onDefault = { currentSubtype = currentSubtype.withoutLayout(type) },
|
||||
isDefault = explicitLayout == null
|
||||
) {
|
||||
val displayName = if (LayoutUtilsCustom.isCustomLayout(it)) LayoutUtilsCustom.getDisplayName(it)
|
||||
else it.getStringResourceOrName("layout_", ctx)
|
||||
else it.getStringResourceOrName("layout_", ctx)
|
||||
Text(displayName)
|
||||
// content is name, and if it's user layout there is an edit button
|
||||
// also maybe there should be an "add" button similar to the old settings
|
||||
|
@ -183,8 +207,8 @@ fun SubtypeDialog(
|
|||
if (showSecondaryLocaleDialog)
|
||||
MultiListPickerDialog(
|
||||
onDismissRequest = { showSecondaryLocaleDialog = false },
|
||||
onConfirmed = {
|
||||
val newValue = it.joinToString(Separators.KV) { it.toLanguageTag() }
|
||||
onConfirmed = { locales ->
|
||||
val newValue = locales.joinToString(Separators.KV) { it.toLanguageTag() }
|
||||
currentSubtype = if (newValue.isEmpty()) currentSubtype.without(ExtraValue.SECONDARY_LOCALES)
|
||||
else currentSubtype.with(ExtraValue.SECONDARY_LOCALES, newValue)
|
||||
},
|
||||
|
@ -201,8 +225,8 @@ fun SubtypeDialog(
|
|||
title = stringResource(R.string.popup_order),
|
||||
showDefault = setting != null,
|
||||
onConfirmed = {
|
||||
if (it == null) currentSubtype = currentSubtype.without(ExtraValue.POPUP_ORDER)
|
||||
else currentSubtype = currentSubtype.with(ExtraValue.POPUP_ORDER, it)
|
||||
currentSubtype = if (it == null) currentSubtype.without(ExtraValue.POPUP_ORDER)
|
||||
else currentSubtype.with(ExtraValue.POPUP_ORDER, it)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -214,13 +238,12 @@ fun SubtypeDialog(
|
|||
title = stringResource(R.string.hint_source),
|
||||
showDefault = setting != null,
|
||||
onConfirmed = {
|
||||
if (it == null) currentSubtype = currentSubtype.without(ExtraValue.HINT_ORDER)
|
||||
else currentSubtype = currentSubtype.with(ExtraValue.HINT_ORDER, it)
|
||||
currentSubtype = if (it == null) currentSubtype.without(ExtraValue.HINT_ORDER)
|
||||
else currentSubtype.with(ExtraValue.HINT_ORDER, it)
|
||||
}
|
||||
)
|
||||
}
|
||||
if (showMorePopupsDialog) {
|
||||
// todo: default button in here? or next to the pref?
|
||||
val items = listOf(POPUP_KEYS_NORMAL, POPUP_KEYS_MAIN, POPUP_KEYS_MORE, POPUP_KEYS_ALL)
|
||||
val explicitValue = currentSubtype.getExtraValueOf(ExtraValue.MORE_POPUPS)
|
||||
val value = explicitValue ?: prefs.getString(Settings.PREF_MORE_POPUP_KEYS, Defaults.PREF_MORE_POPUP_KEYS)
|
||||
|
@ -262,7 +285,7 @@ private fun PopupOrderDialog(
|
|||
var checked by rememberSaveable { mutableStateOf(item.state) }
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
KeyboardIconsSet.instance.GetIcon(item.name)
|
||||
val text = item.name.lowercase().getStringResourceOrName("", ctx)
|
||||
val text = item.name.lowercase().getStringResourceOrName("popup_keys_", ctx)
|
||||
Text(text, Modifier.weight(1f))
|
||||
Switch(
|
||||
checked = checked,
|
||||
|
@ -290,6 +313,8 @@ private fun <T>DropDownField(
|
|||
items: List<T>,
|
||||
selectedItem: T,
|
||||
onSelected: (T) -> Unit,
|
||||
isDefault: Boolean? = null,
|
||||
onDefault: () -> Unit = {},
|
||||
itemContent: @Composable (T) -> Unit,
|
||||
) {
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
|
@ -299,7 +324,7 @@ private fun <T>DropDownField(
|
|||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.padding(start = 8.dp, end = 8.dp, bottom = 4.dp)
|
||||
modifier = Modifier.padding(start = 8.dp, bottom = 4.dp)
|
||||
) {
|
||||
Box(Modifier.weight(1f)) {
|
||||
itemContent(selectedItem)
|
||||
|
@ -310,10 +335,12 @@ private fun <T>DropDownField(
|
|||
) {
|
||||
Icon(
|
||||
painterResource(R.drawable.ic_arrow_left),
|
||||
null,
|
||||
"show dropdown",
|
||||
Modifier.rotate(-90f)
|
||||
)
|
||||
}
|
||||
if (isDefault != null)
|
||||
DefaultButton(onDefault, isDefault)
|
||||
}
|
||||
}
|
||||
DropdownMenu(
|
||||
|
@ -329,16 +356,19 @@ private fun <T>DropDownField(
|
|||
}
|
||||
}
|
||||
|
||||
// get locales with same script as main locale, but different language
|
||||
// todo: do we need any sort of force-ascii like in old variant?
|
||||
// now we use hi-Latn and sr-Latn for the relevant subtypes, so it should be fine
|
||||
// only potential issue is the Latn-default if we don't have the script for a locale,
|
||||
// but in that case we should rather add the script to ScriptUtils
|
||||
private fun getAvailableSecondaryLocales(context: Context, mainLocale: Locale): List<Locale> {
|
||||
val locales = getDictionaryLocales(context)
|
||||
locales.removeAll {
|
||||
// it.language == mainLocale.language || it.script() != mainLocale.script()
|
||||
it == mainLocale || it.script() != mainLocale.script() // todo: check whether this is fine, otherwise go back to the variant above
|
||||
@Composable
|
||||
private fun DefaultButton(
|
||||
onDefault: () -> Unit,
|
||||
isDefault: Boolean
|
||||
) {
|
||||
IconButton(
|
||||
onClick = onDefault,
|
||||
enabled = !isDefault
|
||||
) {
|
||||
Icon(painterResource(R.drawable.sym_keyboard_settings_holo), "default") // todo: more understandable icon!
|
||||
}
|
||||
return locales.toList()
|
||||
|
||||
}
|
||||
|
||||
private fun getAvailableSecondaryLocales(context: Context, mainLocale: Locale): List<Locale> =
|
||||
getDictionaryLocales(context).filter { it != mainLocale && it.script() == mainLocale.script() }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue