Make settings screens fully usable on Android 15 (#1484)

enable edge to edge in settings for all Android versions to avoid minor glitches and have more consistent appearance
This commit is contained in:
Eran Leshem 2025-04-21 09:06:41 +03:00 committed by GitHub
parent d15a97ccba
commit d9f17733d9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 301 additions and 229 deletions

View file

@ -6,9 +6,14 @@ import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.union
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
@ -20,6 +25,7 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
@ -58,36 +64,41 @@ fun SearchSettingsScreen(
content = {
if (content != null) content()
else {
Column(Modifier.verticalScroll(rememberScrollState())) {
settings.forEach {
if (it is Int) {
PreferenceCategory(stringResource(it))
} else {
// this only animates appearing prefs
// a solution would be using a list(visible to key)
AnimatedVisibility(visible = it != null) {
if (it != null)
SettingsActivity.settingsContainer[it]?.Preference()
Scaffold(contentWindowInsets = WindowInsets.systemBars.union(WindowInsets.ime)) { innerPadding ->
Column(
Modifier.verticalScroll(rememberScrollState())
.then(Modifier.padding(bottom = innerPadding.calculateBottomPadding()))
) {
settings.forEach {
if (it is Int) {
PreferenceCategory(stringResource(it))
} else {
// this only animates appearing prefs
// a solution would be using a list(visible to key)
AnimatedVisibility(visible = it != null) {
if (it != null)
SettingsActivity.settingsContainer[it]?.Preference()
}
}
}
}
// lazyColumn has janky scroll for a while (not sure why compose gets smoother after a while)
// maybe related to unnecessary recompositions? but even for just displaying text it's there
// didn't manage to improve things with @Immutable list wrapper and other lazy list hints
// so for now: just use "normal" Column
// even though it takes up to ~50% longer to load it's much better UX
// and the missing appear animations could be added
// LazyColumn {
// items(prefs.filterNotNull(), key = { it }) {
// Box(Modifier.animateItem()) {
// if (it is Int)
// PreferenceCategory(stringResource(it))
// else
// SettingsActivity.settingsContainer[it]!!.Preference()
// }
// }
// }
}
// lazyColumn has janky scroll for a while (not sure why compose gets smoother after a while)
// maybe related to unnecessary recompositions? but even for just displaying text it's there
// didn't manage to improve things with @Immutable list wrapper and other lazy list hints
// so for now: just use "normal" Column
// even though it takes up to ~50% longer to load it's much better UX
// and the missing appear animations could be added
// LazyColumn {
// items(prefs.filterNotNull(), key = { it }) {
// Box(Modifier.animateItem()) {
// if (it is Int)
// PreferenceCategory(stringResource(it))
// else
// SettingsActivity.settingsContainer[it]!!.Preference()
// }
// }
// }
}
},
filteredItems = { SettingsActivity.settingsContainer.filter(it) },
@ -195,9 +206,11 @@ fun <T: Any?> SearchScreen(
}
} else {
val items = filteredItems(searchText.text)
LazyColumn {
items(items) {
itemContent(it)
Scaffold(contentWindowInsets = WindowInsets.systemBars.union(WindowInsets.ime)) { innerPadding ->
LazyColumn(contentPadding = PaddingValues.Absolute(bottom = innerPadding.calculateBottomPadding())) {
items(items) {
itemContent(it)
}
}
}
}

View file

@ -12,7 +12,14 @@ import android.view.WindowInsets.Type
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import androidx.activity.ComponentActivity
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.union
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.collectAsState
@ -20,6 +27,7 @@ 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.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.core.view.ViewCompat
import helium314.keyboard.compat.locale
@ -98,9 +106,11 @@ class SettingsActivity : ComponentActivity(), SharedPreferences.OnSharedPreferen
|| !UncachedInputMethodManagerUtils.isThisImeEnabled(this, imm)
) }
if (spellchecker)
Column { // lazy way of implementing spell checker settings
settingsContainer[Settings.PREF_USE_CONTACTS]!!.Preference()
settingsContainer[Settings.PREF_BLOCK_POTENTIALLY_OFFENSIVE]!!.Preference()
Scaffold(contentWindowInsets = WindowInsets.systemBars.union(WindowInsets.ime)) { innerPadding ->
Column(Modifier.padding(innerPadding)) { // lazy way of implementing spell checker settings
settingsContainer[Settings.PREF_USE_CONTACTS]!!.Preference()
settingsContainer[Settings.PREF_BLOCK_POTENTIALLY_OFFENSIVE]!!.Preference()
}
}
else
SettingsNavHost(onClickBack = { this.finish() })
@ -143,6 +153,8 @@ class SettingsActivity : ComponentActivity(), SharedPreferences.OnSharedPreferen
}
intent = null
}
enableEdgeToEdge()
}
override fun onStart() {

View file

@ -2,8 +2,14 @@
package helium314.keyboard.settings.screens
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.union
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@ -42,59 +48,64 @@ fun MainSettingsScreen(
settings = emptyList(),
) {
val enabledSubtypes = SubtypeSettings.getEnabledSubtypes(true)
Column(Modifier.verticalScroll(rememberScrollState())) {
Preference(
name = stringResource(R.string.language_and_layouts_title),
description = enabledSubtypes.joinToString(", ") { it.displayName(ctx) },
onClick = onClickLanguage,
icon = R.drawable.ic_settings_languages
) { NextScreenIcon() }
Preference(
name = stringResource(R.string.settings_screen_preferences),
onClick = onClickPreferences,
icon = R.drawable.ic_settings_preferences
) { NextScreenIcon() }
Preference(
name = stringResource(R.string.settings_screen_appearance),
onClick = onClickAppearance,
icon = R.drawable.ic_settings_appearance
) { NextScreenIcon() }
Preference(
name = stringResource(R.string.settings_screen_toolbar),
onClick = onClickToolbar,
icon = R.drawable.ic_settings_toolbar
) { NextScreenIcon() }
if (JniUtils.sHaveGestureLib)
Scaffold(contentWindowInsets = WindowInsets.systemBars.union(WindowInsets.ime)) { innerPadding ->
Column(
Modifier.verticalScroll(rememberScrollState())
.then(Modifier.padding(bottom = innerPadding.calculateBottomPadding()))
) {
Preference(
name = stringResource(R.string.settings_screen_gesture),
onClick = onClickGestureTyping,
icon = R.drawable.ic_settings_gesture
name = stringResource(R.string.language_and_layouts_title),
description = enabledSubtypes.joinToString(", ") { it.displayName(ctx) },
onClick = onClickLanguage,
icon = R.drawable.ic_settings_languages
) { NextScreenIcon() }
Preference(
name = stringResource(R.string.settings_screen_correction),
onClick = onClickTextCorrection,
icon = R.drawable.ic_settings_correction
) { NextScreenIcon() }
Preference(
name = stringResource(R.string.settings_screen_secondary_layouts),
onClick = onClickLayouts,
icon = R.drawable.ic_ime_switcher
) { NextScreenIcon() }
Preference(
name = stringResource(R.string.dictionary_settings_category),
onClick = onClickDictionaries,
icon = R.drawable.ic_dictionary
) { NextScreenIcon() }
Preference(
name = stringResource(R.string.settings_screen_advanced),
onClick = onClickAdvanced,
icon = R.drawable.ic_settings_advanced
) { NextScreenIcon() }
Preference(
name = stringResource(R.string.settings_screen_about),
onClick = onClickAbout,
icon = R.drawable.ic_settings_about
) { NextScreenIcon() }
Preference(
name = stringResource(R.string.settings_screen_preferences),
onClick = onClickPreferences,
icon = R.drawable.ic_settings_preferences
) { NextScreenIcon() }
Preference(
name = stringResource(R.string.settings_screen_appearance),
onClick = onClickAppearance,
icon = R.drawable.ic_settings_appearance
) { NextScreenIcon() }
Preference(
name = stringResource(R.string.settings_screen_toolbar),
onClick = onClickToolbar,
icon = R.drawable.ic_settings_toolbar
) { NextScreenIcon() }
if (JniUtils.sHaveGestureLib)
Preference(
name = stringResource(R.string.settings_screen_gesture),
onClick = onClickGestureTyping,
icon = R.drawable.ic_settings_gesture
) { NextScreenIcon() }
Preference(
name = stringResource(R.string.settings_screen_correction),
onClick = onClickTextCorrection,
icon = R.drawable.ic_settings_correction
) { NextScreenIcon() }
Preference(
name = stringResource(R.string.settings_screen_secondary_layouts),
onClick = onClickLayouts,
icon = R.drawable.ic_ime_switcher
) { NextScreenIcon() }
Preference(
name = stringResource(R.string.dictionary_settings_category),
onClick = onClickDictionaries,
icon = R.drawable.ic_dictionary
) { NextScreenIcon() }
Preference(
name = stringResource(R.string.settings_screen_advanced),
onClick = onClickAdvanced,
icon = R.drawable.ic_settings_advanced
) { NextScreenIcon() }
Preference(
name = stringResource(R.string.settings_screen_about),
onClick = onClickAbout,
icon = R.drawable.ic_settings_about
) { NextScreenIcon() }
}
}
}
}

View file

@ -10,7 +10,9 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.ExtendedFloatingActionButton
@ -177,6 +179,7 @@ fun PersonalDictionaryScreen(
text = { Text(stringResource(R.string.user_dict_add_word_button)) },
icon = { Icon(painter = painterResource(R.drawable.ic_edit), stringResource(R.string.user_dict_add_word_button)) },
modifier = Modifier.wrapContentSize(Alignment.BottomEnd).padding(all = 12.dp)
.then(Modifier.systemBarsPadding().imePadding())
)
}

View file

@ -4,8 +4,12 @@ import android.content.Context
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.union
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
@ -13,6 +17,7 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
@ -140,163 +145,191 @@ fun SubtypeScreen(
itemContent = { },
filteredItems = { emptyList<String>() }
) {
Column(
modifier = Modifier.verticalScroll(scrollState).padding(horizontal = 12.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
MainLayoutRow(currentSubtype, customMainLayouts) { setCurrentSubtype(it) }
if (availableLocalesForScript.size > 1) {
WithSmallTitle(stringResource(R.string.secondary_locale)) {
TextButton(onClick = { showSecondaryLocaleDialog = true }) {
val text = getSecondaryLocales(currentSubtype.extraValues).joinToString(", ") {
it.localizedDisplayName(ctx)
}.ifEmpty { stringResource(R.string.action_none) }
Text(text, Modifier.fillMaxWidth())
}
}
}
Row {
TextButton(onClick = { showKeyOrderDialog = true }, Modifier.weight(1f))
{ Text(stringResource(R.string.popup_order)) }
DefaultButton(currentSubtype.getExtraValueOf(ExtraValue.POPUP_ORDER) == null) {
setCurrentSubtype(currentSubtype.without(ExtraValue.POPUP_ORDER))
}
}
Row {
TextButton(onClick = { showHintOrderDialog = true }, Modifier.weight(1f))
{ Text(stringResource(R.string.hint_source)) }
DefaultButton(currentSubtype.getExtraValueOf(ExtraValue.HINT_ORDER) == null) {
setCurrentSubtype(currentSubtype.without(ExtraValue.HINT_ORDER))
}
}
if (currentSubtype.locale.script() == ScriptUtils.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)!!
Row {
TextButton(onClick = { showMorePopupsDialog = true }, Modifier.weight(1f))
{ Text(stringResource(morePopupKeysResId(value))) }
DefaultButton(explicitValue == null) {
setCurrentSubtype(currentSubtype.without(ExtraValue.MORE_POPUPS))
Scaffold(contentWindowInsets = WindowInsets.systemBars.union(WindowInsets.ime)) { innerPadding ->
Column(
modifier = Modifier.verticalScroll(scrollState).padding(horizontal = 12.dp)
.then(Modifier.padding(bottom = innerPadding.calculateBottomPadding())),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
MainLayoutRow(currentSubtype, customMainLayouts) { setCurrentSubtype(it) }
if (availableLocalesForScript.size > 1) {
WithSmallTitle(stringResource(R.string.secondary_locale)) {
TextButton(onClick = { showSecondaryLocaleDialog = true }) {
val text = getSecondaryLocales(currentSubtype.extraValues).joinToString(", ") {
it.localizedDisplayName(ctx)
}.ifEmpty { stringResource(R.string.action_none) }
Text(text, Modifier.fillMaxWidth())
}
}
}
}
if (hasLocalizedNumberRow(currentSubtype.locale, ctx)) {
Row(verticalAlignment = Alignment.CenterVertically) {
val checked = currentSubtype.getExtraValueOf(ExtraValue.LOCALIZED_NUMBER_ROW)?.toBoolean()
Text(stringResource(R.string.localized_number_row), Modifier.weight(1f))
Switch(
checked = checked ?: prefs.getBoolean(Settings.PREF_LOCALIZED_NUMBER_ROW, Defaults.PREF_LOCALIZED_NUMBER_ROW),
onCheckedChange = {
setCurrentSubtype(currentSubtype.with(ExtraValue.LOCALIZED_NUMBER_ROW, it.toString()))
}
)
DefaultButton(checked == null) {
setCurrentSubtype(currentSubtype.without(ExtraValue.LOCALIZED_NUMBER_ROW))
Row {
TextButton(onClick = { showKeyOrderDialog = true }, Modifier.weight(1f))
{ Text(stringResource(R.string.popup_order)) }
DefaultButton(currentSubtype.getExtraValueOf(ExtraValue.POPUP_ORDER) == null) {
setCurrentSubtype(currentSubtype.without(ExtraValue.POPUP_ORDER))
}
}
}
HorizontalDivider()
Text(stringResource(R.string.settings_screen_secondary_layouts), style = MaterialTheme.typography.titleMedium)
LayoutType.entries.forEach { type ->
if (type == LayoutType.MAIN) return@forEach
WithSmallTitle(stringResource(type.displayNameId)) {
val explicitLayout = currentSubtype.layoutName(type)
val layout = explicitLayout ?: Settings.readDefaultLayoutName(type, prefs)
val defaultLayouts = LayoutUtils.getAvailableLayouts(type, ctx)
val customLayouts = LayoutUtilsCustom.getLayoutFiles(type, ctx).map { it.name }
DropDownField(
items = defaultLayouts + customLayouts,
selectedItem = layout,
onSelected = {
setCurrentSubtype(currentSubtype.withLayout(type, it))
},
extraButton = { DefaultButton(explicitLayout == null) {
setCurrentSubtype(currentSubtype.withoutLayout(type))
} },
) {
val displayName = if (LayoutUtilsCustom.isCustomLayout(it)) LayoutUtilsCustom.getDisplayName(it)
else it.getStringResourceOrName("layout_", ctx)
var showLayoutEditDialog by remember { mutableStateOf(false) }
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth()
Row {
TextButton(onClick = { showHintOrderDialog = true }, Modifier.weight(1f))
{ Text(stringResource(R.string.hint_source)) }
DefaultButton(currentSubtype.getExtraValueOf(ExtraValue.HINT_ORDER) == null) {
setCurrentSubtype(currentSubtype.without(ExtraValue.HINT_ORDER))
}
}
if (currentSubtype.locale.script() == ScriptUtils.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
)!!
Row {
TextButton(onClick = { showMorePopupsDialog = true }, Modifier.weight(1f))
{ Text(stringResource(morePopupKeysResId(value))) }
DefaultButton(explicitValue == null) {
setCurrentSubtype(currentSubtype.without(ExtraValue.MORE_POPUPS))
}
}
}
}
if (hasLocalizedNumberRow(currentSubtype.locale, ctx)) {
Row(verticalAlignment = Alignment.CenterVertically) {
val checked = currentSubtype.getExtraValueOf(ExtraValue.LOCALIZED_NUMBER_ROW)?.toBoolean()
Text(stringResource(R.string.localized_number_row), Modifier.weight(1f))
Switch(
checked = checked ?: prefs.getBoolean(
Settings.PREF_LOCALIZED_NUMBER_ROW,
Defaults.PREF_LOCALIZED_NUMBER_ROW
),
onCheckedChange = {
setCurrentSubtype(currentSubtype.with(ExtraValue.LOCALIZED_NUMBER_ROW, it.toString()))
}
)
DefaultButton(checked == null) {
setCurrentSubtype(currentSubtype.without(ExtraValue.LOCALIZED_NUMBER_ROW))
}
}
}
HorizontalDivider()
Text(
stringResource(R.string.settings_screen_secondary_layouts),
style = MaterialTheme.typography.titleMedium
)
LayoutType.entries.forEach { type ->
if (type == LayoutType.MAIN) return@forEach
WithSmallTitle(stringResource(type.displayNameId)) {
val explicitLayout = currentSubtype.layoutName(type)
val layout = explicitLayout ?: Settings.readDefaultLayoutName(type, prefs)
val defaultLayouts = LayoutUtils.getAvailableLayouts(type, ctx)
val customLayouts = LayoutUtilsCustom.getLayoutFiles(type, ctx).map { it.name }
DropDownField(
items = defaultLayouts + customLayouts,
selectedItem = layout,
onSelected = {
setCurrentSubtype(currentSubtype.withLayout(type, it))
},
extraButton = {
DefaultButton(explicitLayout == null) {
setCurrentSubtype(currentSubtype.withoutLayout(type))
}
},
) {
Text(displayName)
if (LayoutUtilsCustom.isCustomLayout(it))
IconButton({ showLayoutEditDialog = true }) { Icon(painterResource(R.drawable.ic_edit), stringResource(R.string.edit_layout)) }
val displayName =
if (LayoutUtilsCustom.isCustomLayout(it)) LayoutUtilsCustom.getDisplayName(it)
else it.getStringResourceOrName("layout_", ctx)
var showLayoutEditDialog by remember { mutableStateOf(false) }
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth()
) {
Text(displayName)
if (LayoutUtilsCustom.isCustomLayout(it))
IconButton({
showLayoutEditDialog = true
}) {
Icon(
painterResource(R.drawable.ic_edit),
stringResource(R.string.edit_layout)
)
}
}
if (showLayoutEditDialog)
LayoutEditDialog(
onDismissRequest = { showLayoutEditDialog = false },
layoutType = type,
initialLayoutName = it,
isNameValid = null
)
}
if (showLayoutEditDialog)
LayoutEditDialog(
onDismissRequest = { showLayoutEditDialog = false },
layoutType = type,
initialLayoutName = it,
isNameValid = null
)
}
}
}
}
}
if (showSecondaryLocaleDialog)
MultiListPickerDialog(
onDismissRequest = { showSecondaryLocaleDialog = false },
onConfirmed = { locales ->
val newValue = locales.joinToString(Separators.KV) { it.toLanguageTag() }
setCurrentSubtype(
if (newValue.isEmpty()) currentSubtype.without(ExtraValue.SECONDARY_LOCALES)
else currentSubtype.with(ExtraValue.SECONDARY_LOCALES, newValue)
)
},
title = { Text(stringResource(R.string.locales_with_dict)) },
items = availableLocalesForScript,
initialSelection = currentSubtype.getExtraValueOf(ExtraValue.SECONDARY_LOCALES)
?.split(Separators.KV)?.map { it.constructLocale() }.orEmpty(),
getItemName = { it.localizedDisplayName(ctx) }
)
if (showKeyOrderDialog) {
val setting = currentSubtype.getExtraValueOf(ExtraValue.POPUP_ORDER)
PopupOrderDialog(
onDismissRequest = { showKeyOrderDialog = false },
initialValue = setting ?: prefs.getString(Settings.PREF_POPUP_KEYS_ORDER, Defaults.PREF_POPUP_KEYS_ORDER)!!,
title = stringResource(R.string.popup_order),
showDefault = setting != null,
onConfirmed = {
setCurrentSubtype(
if (it == null) currentSubtype.without(ExtraValue.POPUP_ORDER)
else currentSubtype.with(ExtraValue.POPUP_ORDER, it)
)
}
)
}
if (showHintOrderDialog) {
val setting = currentSubtype.getExtraValueOf(ExtraValue.HINT_ORDER)
PopupOrderDialog(
onDismissRequest = { showHintOrderDialog = false },
initialValue = setting ?: prefs.getString(Settings.PREF_POPUP_KEYS_LABELS_ORDER, Defaults.PREF_POPUP_KEYS_LABELS_ORDER)!!,
title = stringResource(R.string.hint_source),
showDefault = setting != null,
onConfirmed = {
setCurrentSubtype(
if (it == null) currentSubtype.without(ExtraValue.HINT_ORDER)
else currentSubtype.with(ExtraValue.HINT_ORDER, it)
)
}
)
}
if (showMorePopupsDialog) {
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)
ListPickerDialog(
onDismissRequest = { showMorePopupsDialog = false },
items = items,
getItemName = { stringResource(morePopupKeysResId(it)) },
selectedItem = value,
onItemSelected = { setCurrentSubtype(currentSubtype.with(ExtraValue.MORE_POPUPS, it)) }
)
if (showSecondaryLocaleDialog)
MultiListPickerDialog(
onDismissRequest = { showSecondaryLocaleDialog = false },
onConfirmed = { locales ->
val newValue = locales.joinToString(Separators.KV) { it.toLanguageTag() }
setCurrentSubtype(
if (newValue.isEmpty()) currentSubtype.without(ExtraValue.SECONDARY_LOCALES)
else currentSubtype.with(ExtraValue.SECONDARY_LOCALES, newValue)
)
},
title = { Text(stringResource(R.string.locales_with_dict)) },
items = availableLocalesForScript,
initialSelection = currentSubtype.getExtraValueOf(ExtraValue.SECONDARY_LOCALES)
?.split(Separators.KV)?.map { it.constructLocale() }.orEmpty(),
getItemName = { it.localizedDisplayName(ctx) }
)
if (showKeyOrderDialog) {
val setting = currentSubtype.getExtraValueOf(ExtraValue.POPUP_ORDER)
PopupOrderDialog(
onDismissRequest = { showKeyOrderDialog = false },
initialValue = setting ?: prefs.getString(
Settings.PREF_POPUP_KEYS_ORDER,
Defaults.PREF_POPUP_KEYS_ORDER
)!!,
title = stringResource(R.string.popup_order),
showDefault = setting != null,
onConfirmed = {
setCurrentSubtype(
if (it == null) currentSubtype.without(ExtraValue.POPUP_ORDER)
else currentSubtype.with(ExtraValue.POPUP_ORDER, it)
)
}
)
}
if (showHintOrderDialog) {
val setting = currentSubtype.getExtraValueOf(ExtraValue.HINT_ORDER)
PopupOrderDialog(
onDismissRequest = { showHintOrderDialog = false },
initialValue = setting ?: prefs.getString(
Settings.PREF_POPUP_KEYS_LABELS_ORDER,
Defaults.PREF_POPUP_KEYS_LABELS_ORDER
)!!,
title = stringResource(R.string.hint_source),
showDefault = setting != null,
onConfirmed = {
setCurrentSubtype(
if (it == null) currentSubtype.without(ExtraValue.HINT_ORDER)
else currentSubtype.with(ExtraValue.HINT_ORDER, it)
)
}
)
}
if (showMorePopupsDialog) {
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)
ListPickerDialog(
onDismissRequest = { showMorePopupsDialog = false },
items = items,
getItemName = { stringResource(morePopupKeysResId(it)) },
selectedItem = value,
onItemSelected = { setCurrentSubtype(currentSubtype.with(ExtraValue.MORE_POPUPS, it)) }
)
}
}
}