mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-05-14 05:52:47 +00:00
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:
parent
d15a97ccba
commit
d9f17733d9
5 changed files with 301 additions and 229 deletions
|
@ -6,9 +6,14 @@ import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.ColumnScope
|
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.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.ime
|
||||||
import androidx.compose.foundation.layout.padding
|
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.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
@ -20,6 +25,7 @@ import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.LocalTextStyle
|
import androidx.compose.material3.LocalTextStyle
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextField
|
import androidx.compose.material3.TextField
|
||||||
|
@ -58,36 +64,41 @@ fun SearchSettingsScreen(
|
||||||
content = {
|
content = {
|
||||||
if (content != null) content()
|
if (content != null) content()
|
||||||
else {
|
else {
|
||||||
Column(Modifier.verticalScroll(rememberScrollState())) {
|
Scaffold(contentWindowInsets = WindowInsets.systemBars.union(WindowInsets.ime)) { innerPadding ->
|
||||||
settings.forEach {
|
Column(
|
||||||
if (it is Int) {
|
Modifier.verticalScroll(rememberScrollState())
|
||||||
PreferenceCategory(stringResource(it))
|
.then(Modifier.padding(bottom = innerPadding.calculateBottomPadding()))
|
||||||
} else {
|
) {
|
||||||
// this only animates appearing prefs
|
settings.forEach {
|
||||||
// a solution would be using a list(visible to key)
|
if (it is Int) {
|
||||||
AnimatedVisibility(visible = it != null) {
|
PreferenceCategory(stringResource(it))
|
||||||
if (it != null)
|
} else {
|
||||||
SettingsActivity.settingsContainer[it]?.Preference()
|
// 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) },
|
filteredItems = { SettingsActivity.settingsContainer.filter(it) },
|
||||||
|
@ -195,9 +206,11 @@ fun <T: Any?> SearchScreen(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val items = filteredItems(searchText.text)
|
val items = filteredItems(searchText.text)
|
||||||
LazyColumn {
|
Scaffold(contentWindowInsets = WindowInsets.systemBars.union(WindowInsets.ime)) { innerPadding ->
|
||||||
items(items) {
|
LazyColumn(contentPadding = PaddingValues.Absolute(bottom = innerPadding.calculateBottomPadding())) {
|
||||||
itemContent(it)
|
items(items) {
|
||||||
|
itemContent(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,14 @@ import android.view.WindowInsets.Type
|
||||||
import android.view.inputmethod.EditorInfo
|
import android.view.inputmethod.EditorInfo
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.compose.foundation.layout.Column
|
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.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
|
@ -20,6 +27,7 @@ import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
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.Modifier
|
||||||
import androidx.compose.ui.platform.ComposeView
|
import androidx.compose.ui.platform.ComposeView
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import helium314.keyboard.compat.locale
|
import helium314.keyboard.compat.locale
|
||||||
|
@ -98,9 +106,11 @@ class SettingsActivity : ComponentActivity(), SharedPreferences.OnSharedPreferen
|
||||||
|| !UncachedInputMethodManagerUtils.isThisImeEnabled(this, imm)
|
|| !UncachedInputMethodManagerUtils.isThisImeEnabled(this, imm)
|
||||||
) }
|
) }
|
||||||
if (spellchecker)
|
if (spellchecker)
|
||||||
Column { // lazy way of implementing spell checker settings
|
Scaffold(contentWindowInsets = WindowInsets.systemBars.union(WindowInsets.ime)) { innerPadding ->
|
||||||
settingsContainer[Settings.PREF_USE_CONTACTS]!!.Preference()
|
Column(Modifier.padding(innerPadding)) { // lazy way of implementing spell checker settings
|
||||||
settingsContainer[Settings.PREF_BLOCK_POTENTIALLY_OFFENSIVE]!!.Preference()
|
settingsContainer[Settings.PREF_USE_CONTACTS]!!.Preference()
|
||||||
|
settingsContainer[Settings.PREF_BLOCK_POTENTIALLY_OFFENSIVE]!!.Preference()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SettingsNavHost(onClickBack = { this.finish() })
|
SettingsNavHost(onClickBack = { this.finish() })
|
||||||
|
@ -143,6 +153,8 @@ class SettingsActivity : ComponentActivity(), SharedPreferences.OnSharedPreferen
|
||||||
}
|
}
|
||||||
intent = null
|
intent = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enableEdgeToEdge()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
|
|
|
@ -2,8 +2,14 @@
|
||||||
package helium314.keyboard.settings.screens
|
package helium314.keyboard.settings.screens
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
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.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
@ -42,59 +48,64 @@ fun MainSettingsScreen(
|
||||||
settings = emptyList(),
|
settings = emptyList(),
|
||||||
) {
|
) {
|
||||||
val enabledSubtypes = SubtypeSettings.getEnabledSubtypes(true)
|
val enabledSubtypes = SubtypeSettings.getEnabledSubtypes(true)
|
||||||
Column(Modifier.verticalScroll(rememberScrollState())) {
|
Scaffold(contentWindowInsets = WindowInsets.systemBars.union(WindowInsets.ime)) { innerPadding ->
|
||||||
Preference(
|
Column(
|
||||||
name = stringResource(R.string.language_and_layouts_title),
|
Modifier.verticalScroll(rememberScrollState())
|
||||||
description = enabledSubtypes.joinToString(", ") { it.displayName(ctx) },
|
.then(Modifier.padding(bottom = innerPadding.calculateBottomPadding()))
|
||||||
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)
|
|
||||||
Preference(
|
Preference(
|
||||||
name = stringResource(R.string.settings_screen_gesture),
|
name = stringResource(R.string.language_and_layouts_title),
|
||||||
onClick = onClickGestureTyping,
|
description = enabledSubtypes.joinToString(", ") { it.displayName(ctx) },
|
||||||
icon = R.drawable.ic_settings_gesture
|
onClick = onClickLanguage,
|
||||||
|
icon = R.drawable.ic_settings_languages
|
||||||
) { NextScreenIcon() }
|
) { NextScreenIcon() }
|
||||||
Preference(
|
Preference(
|
||||||
name = stringResource(R.string.settings_screen_correction),
|
name = stringResource(R.string.settings_screen_preferences),
|
||||||
onClick = onClickTextCorrection,
|
onClick = onClickPreferences,
|
||||||
icon = R.drawable.ic_settings_correction
|
icon = R.drawable.ic_settings_preferences
|
||||||
) { NextScreenIcon() }
|
) { NextScreenIcon() }
|
||||||
Preference(
|
Preference(
|
||||||
name = stringResource(R.string.settings_screen_secondary_layouts),
|
name = stringResource(R.string.settings_screen_appearance),
|
||||||
onClick = onClickLayouts,
|
onClick = onClickAppearance,
|
||||||
icon = R.drawable.ic_ime_switcher
|
icon = R.drawable.ic_settings_appearance
|
||||||
) { NextScreenIcon() }
|
) { NextScreenIcon() }
|
||||||
Preference(
|
Preference(
|
||||||
name = stringResource(R.string.dictionary_settings_category),
|
name = stringResource(R.string.settings_screen_toolbar),
|
||||||
onClick = onClickDictionaries,
|
onClick = onClickToolbar,
|
||||||
icon = R.drawable.ic_dictionary
|
icon = R.drawable.ic_settings_toolbar
|
||||||
) { NextScreenIcon() }
|
) { NextScreenIcon() }
|
||||||
Preference(
|
if (JniUtils.sHaveGestureLib)
|
||||||
name = stringResource(R.string.settings_screen_advanced),
|
Preference(
|
||||||
onClick = onClickAdvanced,
|
name = stringResource(R.string.settings_screen_gesture),
|
||||||
icon = R.drawable.ic_settings_advanced
|
onClick = onClickGestureTyping,
|
||||||
) { NextScreenIcon() }
|
icon = R.drawable.ic_settings_gesture
|
||||||
Preference(
|
) { NextScreenIcon() }
|
||||||
name = stringResource(R.string.settings_screen_about),
|
Preference(
|
||||||
onClick = onClickAbout,
|
name = stringResource(R.string.settings_screen_correction),
|
||||||
icon = R.drawable.ic_settings_about
|
onClick = onClickTextCorrection,
|
||||||
) { NextScreenIcon() }
|
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() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,9 @@ import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.systemBarsPadding
|
||||||
import androidx.compose.foundation.layout.wrapContentSize
|
import androidx.compose.foundation.layout.wrapContentSize
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.material3.ExtendedFloatingActionButton
|
import androidx.compose.material3.ExtendedFloatingActionButton
|
||||||
|
@ -177,6 +179,7 @@ fun PersonalDictionaryScreen(
|
||||||
text = { Text(stringResource(R.string.user_dict_add_word_button)) },
|
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)) },
|
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)
|
modifier = Modifier.wrapContentSize(Alignment.BottomEnd).padding(all = 12.dp)
|
||||||
|
.then(Modifier.systemBarsPadding().imePadding())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,12 @@ import android.content.Context
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.ime
|
||||||
import androidx.compose.foundation.layout.padding
|
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.layout.widthIn
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
@ -13,6 +17,7 @@ import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Switch
|
import androidx.compose.material3.Switch
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
@ -140,163 +145,191 @@ fun SubtypeScreen(
|
||||||
itemContent = { },
|
itemContent = { },
|
||||||
filteredItems = { emptyList<String>() }
|
filteredItems = { emptyList<String>() }
|
||||||
) {
|
) {
|
||||||
Column(
|
Scaffold(contentWindowInsets = WindowInsets.systemBars.union(WindowInsets.ime)) { innerPadding ->
|
||||||
modifier = Modifier.verticalScroll(scrollState).padding(horizontal = 12.dp),
|
Column(
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
modifier = Modifier.verticalScroll(scrollState).padding(horizontal = 12.dp)
|
||||||
) {
|
.then(Modifier.padding(bottom = innerPadding.calculateBottomPadding())),
|
||||||
MainLayoutRow(currentSubtype, customMainLayouts) { setCurrentSubtype(it) }
|
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
if (availableLocalesForScript.size > 1) {
|
) {
|
||||||
WithSmallTitle(stringResource(R.string.secondary_locale)) {
|
MainLayoutRow(currentSubtype, customMainLayouts) { setCurrentSubtype(it) }
|
||||||
TextButton(onClick = { showSecondaryLocaleDialog = true }) {
|
if (availableLocalesForScript.size > 1) {
|
||||||
val text = getSecondaryLocales(currentSubtype.extraValues).joinToString(", ") {
|
WithSmallTitle(stringResource(R.string.secondary_locale)) {
|
||||||
it.localizedDisplayName(ctx)
|
TextButton(onClick = { showSecondaryLocaleDialog = true }) {
|
||||||
}.ifEmpty { stringResource(R.string.action_none) }
|
val text = getSecondaryLocales(currentSubtype.extraValues).joinToString(", ") {
|
||||||
Text(text, Modifier.fillMaxWidth())
|
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))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
Row {
|
||||||
if (hasLocalizedNumberRow(currentSubtype.locale, ctx)) {
|
TextButton(onClick = { showKeyOrderDialog = true }, Modifier.weight(1f))
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
{ Text(stringResource(R.string.popup_order)) }
|
||||||
val checked = currentSubtype.getExtraValueOf(ExtraValue.LOCALIZED_NUMBER_ROW)?.toBoolean()
|
DefaultButton(currentSubtype.getExtraValueOf(ExtraValue.POPUP_ORDER) == null) {
|
||||||
Text(stringResource(R.string.localized_number_row), Modifier.weight(1f))
|
setCurrentSubtype(currentSubtype.without(ExtraValue.POPUP_ORDER))
|
||||||
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 {
|
||||||
HorizontalDivider()
|
TextButton(onClick = { showHintOrderDialog = true }, Modifier.weight(1f))
|
||||||
Text(stringResource(R.string.settings_screen_secondary_layouts), style = MaterialTheme.typography.titleMedium)
|
{ Text(stringResource(R.string.hint_source)) }
|
||||||
LayoutType.entries.forEach { type ->
|
DefaultButton(currentSubtype.getExtraValueOf(ExtraValue.HINT_ORDER) == null) {
|
||||||
if (type == LayoutType.MAIN) return@forEach
|
setCurrentSubtype(currentSubtype.without(ExtraValue.HINT_ORDER))
|
||||||
WithSmallTitle(stringResource(type.displayNameId)) {
|
}
|
||||||
val explicitLayout = currentSubtype.layoutName(type)
|
}
|
||||||
val layout = explicitLayout ?: Settings.readDefaultLayoutName(type, prefs)
|
if (currentSubtype.locale.script() == ScriptUtils.SCRIPT_LATIN) {
|
||||||
val defaultLayouts = LayoutUtils.getAvailableLayouts(type, ctx)
|
WithSmallTitle(stringResource(R.string.show_popup_keys_title)) {
|
||||||
val customLayouts = LayoutUtilsCustom.getLayoutFiles(type, ctx).map { it.name }
|
val explicitValue = currentSubtype.getExtraValueOf(ExtraValue.MORE_POPUPS)
|
||||||
DropDownField(
|
val value = explicitValue ?: prefs.getString(
|
||||||
items = defaultLayouts + customLayouts,
|
Settings.PREF_MORE_POPUP_KEYS,
|
||||||
selectedItem = layout,
|
Defaults.PREF_MORE_POPUP_KEYS
|
||||||
onSelected = {
|
)!!
|
||||||
setCurrentSubtype(currentSubtype.withLayout(type, it))
|
Row {
|
||||||
},
|
TextButton(onClick = { showMorePopupsDialog = true }, Modifier.weight(1f))
|
||||||
extraButton = { DefaultButton(explicitLayout == null) {
|
{ Text(stringResource(morePopupKeysResId(value))) }
|
||||||
setCurrentSubtype(currentSubtype.withoutLayout(type))
|
DefaultButton(explicitValue == null) {
|
||||||
} },
|
setCurrentSubtype(currentSubtype.without(ExtraValue.MORE_POPUPS))
|
||||||
) {
|
}
|
||||||
val displayName = if (LayoutUtilsCustom.isCustomLayout(it)) LayoutUtilsCustom.getDisplayName(it)
|
}
|
||||||
else it.getStringResourceOrName("layout_", ctx)
|
}
|
||||||
var showLayoutEditDialog by remember { mutableStateOf(false) }
|
}
|
||||||
Row(
|
if (hasLocalizedNumberRow(currentSubtype.locale, ctx)) {
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
val checked = currentSubtype.getExtraValueOf(ExtraValue.LOCALIZED_NUMBER_ROW)?.toBoolean()
|
||||||
modifier = Modifier.fillMaxWidth()
|
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)
|
val displayName =
|
||||||
if (LayoutUtilsCustom.isCustomLayout(it))
|
if (LayoutUtilsCustom.isCustomLayout(it)) LayoutUtilsCustom.getDisplayName(it)
|
||||||
IconButton({ showLayoutEditDialog = true }) { Icon(painterResource(R.drawable.ic_edit), stringResource(R.string.edit_layout)) }
|
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)
|
||||||
if (showSecondaryLocaleDialog)
|
MultiListPickerDialog(
|
||||||
MultiListPickerDialog(
|
onDismissRequest = { showSecondaryLocaleDialog = false },
|
||||||
onDismissRequest = { showSecondaryLocaleDialog = false },
|
onConfirmed = { locales ->
|
||||||
onConfirmed = { locales ->
|
val newValue = locales.joinToString(Separators.KV) { it.toLanguageTag() }
|
||||||
val newValue = locales.joinToString(Separators.KV) { it.toLanguageTag() }
|
setCurrentSubtype(
|
||||||
setCurrentSubtype(
|
if (newValue.isEmpty()) currentSubtype.without(ExtraValue.SECONDARY_LOCALES)
|
||||||
if (newValue.isEmpty()) currentSubtype.without(ExtraValue.SECONDARY_LOCALES)
|
else currentSubtype.with(ExtraValue.SECONDARY_LOCALES, newValue)
|
||||||
else currentSubtype.with(ExtraValue.SECONDARY_LOCALES, newValue)
|
)
|
||||||
)
|
},
|
||||||
},
|
title = { Text(stringResource(R.string.locales_with_dict)) },
|
||||||
title = { Text(stringResource(R.string.locales_with_dict)) },
|
items = availableLocalesForScript,
|
||||||
items = availableLocalesForScript,
|
initialSelection = currentSubtype.getExtraValueOf(ExtraValue.SECONDARY_LOCALES)
|
||||||
initialSelection = currentSubtype.getExtraValueOf(ExtraValue.SECONDARY_LOCALES)
|
?.split(Separators.KV)?.map { it.constructLocale() }.orEmpty(),
|
||||||
?.split(Separators.KV)?.map { it.constructLocale() }.orEmpty(),
|
getItemName = { it.localizedDisplayName(ctx) }
|
||||||
getItemName = { it.localizedDisplayName(ctx) }
|
)
|
||||||
)
|
if (showKeyOrderDialog) {
|
||||||
if (showKeyOrderDialog) {
|
val setting = currentSubtype.getExtraValueOf(ExtraValue.POPUP_ORDER)
|
||||||
val setting = currentSubtype.getExtraValueOf(ExtraValue.POPUP_ORDER)
|
PopupOrderDialog(
|
||||||
PopupOrderDialog(
|
onDismissRequest = { showKeyOrderDialog = false },
|
||||||
onDismissRequest = { showKeyOrderDialog = false },
|
initialValue = setting ?: prefs.getString(
|
||||||
initialValue = setting ?: prefs.getString(Settings.PREF_POPUP_KEYS_ORDER, Defaults.PREF_POPUP_KEYS_ORDER)!!,
|
Settings.PREF_POPUP_KEYS_ORDER,
|
||||||
title = stringResource(R.string.popup_order),
|
Defaults.PREF_POPUP_KEYS_ORDER
|
||||||
showDefault = setting != null,
|
)!!,
|
||||||
onConfirmed = {
|
title = stringResource(R.string.popup_order),
|
||||||
setCurrentSubtype(
|
showDefault = setting != null,
|
||||||
if (it == null) currentSubtype.without(ExtraValue.POPUP_ORDER)
|
onConfirmed = {
|
||||||
else currentSubtype.with(ExtraValue.POPUP_ORDER, it)
|
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(
|
if (showHintOrderDialog) {
|
||||||
onDismissRequest = { showHintOrderDialog = false },
|
val setting = currentSubtype.getExtraValueOf(ExtraValue.HINT_ORDER)
|
||||||
initialValue = setting ?: prefs.getString(Settings.PREF_POPUP_KEYS_LABELS_ORDER, Defaults.PREF_POPUP_KEYS_LABELS_ORDER)!!,
|
PopupOrderDialog(
|
||||||
title = stringResource(R.string.hint_source),
|
onDismissRequest = { showHintOrderDialog = false },
|
||||||
showDefault = setting != null,
|
initialValue = setting ?: prefs.getString(
|
||||||
onConfirmed = {
|
Settings.PREF_POPUP_KEYS_LABELS_ORDER,
|
||||||
setCurrentSubtype(
|
Defaults.PREF_POPUP_KEYS_LABELS_ORDER
|
||||||
if (it == null) currentSubtype.without(ExtraValue.HINT_ORDER)
|
)!!,
|
||||||
else currentSubtype.with(ExtraValue.HINT_ORDER, it)
|
title = stringResource(R.string.hint_source),
|
||||||
)
|
showDefault = setting != null,
|
||||||
}
|
onConfirmed = {
|
||||||
)
|
setCurrentSubtype(
|
||||||
}
|
if (it == null) currentSubtype.without(ExtraValue.HINT_ORDER)
|
||||||
if (showMorePopupsDialog) {
|
else currentSubtype.with(ExtraValue.HINT_ORDER, it)
|
||||||
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 },
|
if (showMorePopupsDialog) {
|
||||||
items = items,
|
val items = listOf(POPUP_KEYS_NORMAL, POPUP_KEYS_MAIN, POPUP_KEYS_MORE, POPUP_KEYS_ALL)
|
||||||
getItemName = { stringResource(morePopupKeysResId(it)) },
|
val explicitValue = currentSubtype.getExtraValueOf(ExtraValue.MORE_POPUPS)
|
||||||
selectedItem = value,
|
val value = explicitValue ?: prefs.getString(Settings.PREF_MORE_POPUP_KEYS, Defaults.PREF_MORE_POPUP_KEYS)
|
||||||
onItemSelected = { setCurrentSubtype(currentSubtype.with(ExtraValue.MORE_POPUPS, it)) }
|
ListPickerDialog(
|
||||||
)
|
onDismissRequest = { showMorePopupsDialog = false },
|
||||||
|
items = items,
|
||||||
|
getItemName = { stringResource(morePopupKeysResId(it)) },
|
||||||
|
selectedItem = value,
|
||||||
|
onItemSelected = { setCurrentSubtype(currentSubtype.with(ExtraValue.MORE_POPUPS, it)) }
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue