mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-04-24 08:36:26 +00:00
some todos in SubtypeDialog
This commit is contained in:
parent
e3fa210031
commit
4edaa485b6
2 changed files with 114 additions and 96 deletions
|
@ -21,6 +21,7 @@ import androidx.compose.material3.Switch
|
|||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
|
@ -51,6 +52,7 @@ import helium314.keyboard.latin.utils.LayoutType
|
|||
import helium314.keyboard.latin.utils.LayoutType.Companion.displayNameId
|
||||
import helium314.keyboard.latin.utils.LayoutUtils
|
||||
import helium314.keyboard.latin.utils.LayoutUtilsCustom
|
||||
import helium314.keyboard.latin.utils.Log
|
||||
import helium314.keyboard.latin.utils.ScriptUtils.SCRIPT_LATIN
|
||||
import helium314.keyboard.latin.utils.ScriptUtils.script
|
||||
import helium314.keyboard.latin.utils.SettingsSubtype
|
||||
|
@ -58,22 +60,21 @@ import helium314.keyboard.latin.utils.SettingsSubtype.Companion.toSettingsSubtyp
|
|||
import helium314.keyboard.latin.utils.SubtypeLocaleUtils
|
||||
import helium314.keyboard.latin.utils.SubtypeSettings
|
||||
import helium314.keyboard.latin.utils.SubtypeUtilsAdditional
|
||||
import helium314.keyboard.latin.utils.getActivity
|
||||
import helium314.keyboard.latin.utils.getDictionaryLocales
|
||||
import helium314.keyboard.latin.utils.getSecondaryLocales
|
||||
import helium314.keyboard.latin.utils.getStringResourceOrName
|
||||
import helium314.keyboard.latin.utils.mainLayoutName
|
||||
import helium314.keyboard.latin.utils.prefs
|
||||
import helium314.keyboard.settings.SettingsActivity
|
||||
import helium314.keyboard.settings.layoutFilePicker
|
||||
import helium314.keyboard.settings.layoutIntent
|
||||
import helium314.keyboard.settings.screens.GetIcon
|
||||
import java.util.Locale
|
||||
|
||||
// todo:
|
||||
// fix the display name (why is the layout always added now e.g. after adding a secondary locale, when it's not there initially?)
|
||||
// dropdown content is not refreshed on deleting a layout, maybe need to do the pref listener trick
|
||||
// layout edit dialog does not care about ime padding when called from here
|
||||
// layout edit dialog does not care about ime padding when called from here, why?
|
||||
// rotating closes the dialog
|
||||
// split this up a little, it's too long... and maybe we could re-use parts other dialogs?
|
||||
@Composable
|
||||
fun SubtypeDialog(
|
||||
onDismissRequest: () -> Unit,
|
||||
|
@ -83,6 +84,9 @@ fun SubtypeDialog(
|
|||
// todo: make sure the values are always correct (e.g. if using rememberSaveable and rotating)
|
||||
val ctx = LocalContext.current
|
||||
val prefs = ctx.prefs()
|
||||
val b = (LocalContext.current.getActivity() as? SettingsActivity)?.prefChanged?.collectAsState()
|
||||
if ((b?.value ?: 0) < 0)
|
||||
Log.v("irrelevant", "stupid way to trigger recomposition on preference change")
|
||||
var currentSubtype by remember { mutableStateOf(subtype.toSettingsSubtype()) }
|
||||
val availableLocalesForScript = getAvailableSecondaryLocales(ctx, currentSubtype.locale).sortedBy { it.toLanguageTag() }
|
||||
var showSecondaryLocaleDialog by remember { mutableStateOf(false) }
|
||||
|
@ -90,6 +94,7 @@ fun SubtypeDialog(
|
|||
var showHintOrderDialog by remember { mutableStateOf(false) }
|
||||
var showMorePopupsDialog by remember { mutableStateOf(false) }
|
||||
val scrollState = rememberScrollState()
|
||||
val customMainLayouts = LayoutUtilsCustom.getLayoutFiles(LayoutType.MAIN, ctx, currentSubtype.locale).map { it.name }
|
||||
ThreeButtonAlertDialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
onConfirmed = { onConfirmed(currentSubtype) },
|
||||
|
@ -105,91 +110,7 @@ fun SubtypeDialog(
|
|||
modifier = Modifier.verticalScroll(scrollState),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
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 }
|
||||
var showAddLayoutDialog by remember { mutableStateOf(false) }
|
||||
var showLayoutEditDialog: Pair<String, String?>? by remember { mutableStateOf(null) }
|
||||
val layoutPicker = layoutFilePicker { content, name ->
|
||||
showLayoutEditDialog = (name ?: "new layout") to content
|
||||
}
|
||||
DropDownField(
|
||||
items = appLayouts + customLayouts,
|
||||
selectedItem = currentSubtype.mainLayoutName() ?: "qwerty",
|
||||
onSelected = {
|
||||
currentSubtype = currentSubtype.withLayout(LayoutType.MAIN, it)
|
||||
}
|
||||
) {
|
||||
var showLayoutDeleteDialog by remember { mutableStateOf(false) }
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(SubtypeLocaleUtils.getDisplayNameInSystemLocale(it, currentSubtype.locale))
|
||||
Row (verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(painterResource(R.drawable.ic_edit), stringResource(R.string.edit_layout), Modifier.clickable { showLayoutEditDialog = it to null })
|
||||
if (it in customLayouts && subtype.mainLayoutName() != it) // don't allow current main layout
|
||||
Icon(painterResource(R.drawable.ic_bin), stringResource(R.string.delete), Modifier.clickable { showLayoutDeleteDialog = true })
|
||||
}
|
||||
}
|
||||
if (showLayoutDeleteDialog) {
|
||||
val others = SubtypeSettings.getAdditionalSubtypes().filter { st -> st.mainLayoutName() == it }.any { it != subtype }
|
||||
ConfirmationDialog(
|
||||
onDismissRequest = { showLayoutDeleteDialog = false },
|
||||
confirmButtonText = stringResource(R.string.delete),
|
||||
title = { Text(stringResource(R.string.delete_layout, LayoutUtilsCustom.getDisplayName(it))) },
|
||||
text = { if (others) Text(stringResource(R.string.layout_in_use)) },
|
||||
onConfirmed = {
|
||||
if (it == currentSubtype.mainLayoutName())
|
||||
currentSubtype = currentSubtype.withoutLayout(LayoutType.MAIN)
|
||||
LayoutUtilsCustom.deleteLayout(it, LayoutType.MAIN, ctx)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
// todo: should be in same row as DropDownField
|
||||
// maybe make the default button more customizable
|
||||
IconButton(
|
||||
{ showAddLayoutDialog = true }
|
||||
) { Icon(painterResource(R.drawable.ic_plus), stringResource(R.string.button_title_add_custom_layout)) }
|
||||
if (showLayoutEditDialog != null) {
|
||||
val layoutName = showLayoutEditDialog!!.first
|
||||
val startContent = showLayoutEditDialog?.second
|
||||
?: if (layoutName in appLayouts) LayoutUtils.getContent(LayoutType.MAIN, layoutName, ctx)
|
||||
else null
|
||||
LayoutEditDialog(
|
||||
onDismissRequest = { showLayoutEditDialog = null },
|
||||
layoutType = LayoutType.MAIN,
|
||||
initialLayoutName = layoutName,
|
||||
startContent = startContent,
|
||||
locale = currentSubtype.locale,
|
||||
// only can edit name for new custom layout
|
||||
isNameValid = if (layoutName in customLayouts) null else ({ it !in customLayouts }),
|
||||
onEdited = {
|
||||
if (layoutName !in customLayouts)
|
||||
currentSubtype = currentSubtype.withLayout(LayoutType.MAIN, it)
|
||||
}
|
||||
)
|
||||
}
|
||||
if (showAddLayoutDialog) {
|
||||
// todo: maybe supply link to discussion section for layouts
|
||||
// todo: no html for compose, so message is broken
|
||||
// try annotatedString
|
||||
val link = "<a href='$LAYOUT_FORMAT_URL'>" + ctx.getString(R.string.dictionary_link_text) + "</a>"
|
||||
ConfirmationDialog(
|
||||
onDismissRequest = { showAddLayoutDialog = false },
|
||||
title = { Text(stringResource(R.string.button_title_add_custom_layout)) },
|
||||
text = { Text(stringResource(R.string.message_add_custom_layout, link)) },
|
||||
onConfirmed = { showLayoutEditDialog = "new layout" to "" },
|
||||
neutralButtonText = stringResource(R.string.button_load_custom),
|
||||
onNeutral = {
|
||||
showAddLayoutDialog = false
|
||||
layoutPicker.launch(layoutIntent)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
MainLayoutRow(subtype, currentSubtype, customMainLayouts) { currentSubtype = it }
|
||||
if (availableLocalesForScript.size > 1) {
|
||||
WithSmallTitle(stringResource(R.string.secondary_locale)) {
|
||||
TextButton(onClick = { showSecondaryLocaleDialog = true }) {
|
||||
|
@ -261,8 +182,10 @@ fun SubtypeDialog(
|
|||
onSelected = {
|
||||
currentSubtype = currentSubtype.withLayout(type, it)
|
||||
},
|
||||
onDefault = { currentSubtype = currentSubtype.withoutLayout(type) },
|
||||
isDefault = explicitLayout == null
|
||||
extraButton = { DefaultButton(
|
||||
onDefault = { currentSubtype = currentSubtype.withoutLayout(type) },
|
||||
isDefault = explicitLayout == null
|
||||
) },
|
||||
) {
|
||||
val displayName = if (LayoutUtilsCustom.isCustomLayout(it)) LayoutUtilsCustom.getDisplayName(it)
|
||||
else it.getStringResourceOrName("layout_", ctx)
|
||||
|
@ -296,7 +219,7 @@ fun SubtypeDialog(
|
|||
currentSubtype = if (newValue.isEmpty()) currentSubtype.without(ExtraValue.SECONDARY_LOCALES)
|
||||
else currentSubtype.with(ExtraValue.SECONDARY_LOCALES, newValue)
|
||||
},
|
||||
title = { Text("languages with dictionaries") }, // todo: string resource
|
||||
title = { Text(stringResource(R.string.locales_with_dict)) },
|
||||
items = availableLocalesForScript,
|
||||
initialSelection = currentSubtype.getExtraValueOf(ExtraValue.SECONDARY_LOCALES)
|
||||
?.split(Separators.KV)?.map { it.constructLocale() }.orEmpty(),
|
||||
|
@ -382,6 +305,100 @@ private fun PopupOrderDialog(
|
|||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MainLayoutRow(
|
||||
subtype: InputMethodSubtype,
|
||||
currentSubtype: SettingsSubtype,
|
||||
customLayouts: List<String>,
|
||||
setCurrentSubtype: (SettingsSubtype) -> Unit,
|
||||
) {
|
||||
val ctx = LocalContext.current
|
||||
WithSmallTitle(stringResource(R.string.keyboard_layout_set)) {
|
||||
val appLayouts = LayoutUtils.getAvailableLayouts(LayoutType.MAIN, ctx, currentSubtype.locale)
|
||||
var showAddLayoutDialog by remember { mutableStateOf(false) }
|
||||
var showLayoutEditDialog: Pair<String, String?>? by remember { mutableStateOf(null) }
|
||||
val layoutPicker = layoutFilePicker { content, name ->
|
||||
showLayoutEditDialog = (name ?: "new layout") to content
|
||||
}
|
||||
DropDownField(
|
||||
items = appLayouts + customLayouts,
|
||||
selectedItem = currentSubtype.mainLayoutName() ?: SubtypeLocaleUtils.QWERTY,
|
||||
onSelected = {
|
||||
setCurrentSubtype(currentSubtype.withLayout(LayoutType.MAIN, it))
|
||||
},
|
||||
extraButton = {
|
||||
IconButton({ showAddLayoutDialog = true })
|
||||
{ Icon(painterResource(R.drawable.ic_plus), stringResource(R.string.button_title_add_custom_layout)) }
|
||||
}
|
||||
) {
|
||||
var showLayoutDeleteDialog by remember { mutableStateOf(false) }
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(SubtypeLocaleUtils.getDisplayNameInSystemLocale(it, currentSubtype.locale))
|
||||
Row (verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(painterResource(R.drawable.ic_edit), stringResource(R.string.edit_layout), Modifier.clickable { showLayoutEditDialog = it to null })
|
||||
if (it in customLayouts && subtype.mainLayoutName() != it) // don't allow current main layout
|
||||
Icon(painterResource(R.drawable.ic_bin), stringResource(R.string.delete), Modifier.clickable { showLayoutDeleteDialog = true })
|
||||
}
|
||||
}
|
||||
if (showLayoutDeleteDialog) {
|
||||
val others = SubtypeSettings.getAdditionalSubtypes().filter { st -> st.mainLayoutName() == it }.any { it != subtype }
|
||||
ConfirmationDialog(
|
||||
onDismissRequest = { showLayoutDeleteDialog = false },
|
||||
confirmButtonText = stringResource(R.string.delete),
|
||||
title = { Text(stringResource(R.string.delete_layout, LayoutUtilsCustom.getDisplayName(it))) },
|
||||
text = { if (others) Text(stringResource(R.string.layout_in_use)) },
|
||||
onConfirmed = {
|
||||
if (it == currentSubtype.mainLayoutName())
|
||||
setCurrentSubtype(currentSubtype.withoutLayout(LayoutType.MAIN))
|
||||
LayoutUtilsCustom.deleteLayout(it, LayoutType.MAIN, ctx)
|
||||
(ctx.getActivity() as? SettingsActivity)?.prefChanged?.value = 1234
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
if (showLayoutEditDialog != null) {
|
||||
val layoutName = showLayoutEditDialog!!.first
|
||||
val startContent = showLayoutEditDialog?.second
|
||||
?: if (layoutName in appLayouts) LayoutUtils.getContent(LayoutType.MAIN, layoutName, ctx)
|
||||
else null
|
||||
LayoutEditDialog(
|
||||
onDismissRequest = { showLayoutEditDialog = null },
|
||||
layoutType = LayoutType.MAIN,
|
||||
initialLayoutName = layoutName,
|
||||
startContent = startContent,
|
||||
locale = currentSubtype.locale,
|
||||
// only can edit name for new custom layout
|
||||
isNameValid = if (layoutName in customLayouts) null else ({ it !in customLayouts }),
|
||||
onEdited = {
|
||||
if (layoutName !in customLayouts)
|
||||
setCurrentSubtype(currentSubtype.withLayout(LayoutType.MAIN, it))
|
||||
}
|
||||
)
|
||||
}
|
||||
if (showAddLayoutDialog) {
|
||||
// todo: maybe supply link to discussion section for layouts
|
||||
// todo: no html for compose, so message is broken
|
||||
// try annotatedString
|
||||
val link = "<a href='$LAYOUT_FORMAT_URL'>" + ctx.getString(R.string.dictionary_link_text) + "</a>"
|
||||
ConfirmationDialog(
|
||||
onDismissRequest = { showAddLayoutDialog = false },
|
||||
title = { Text(stringResource(R.string.button_title_add_custom_layout)) },
|
||||
text = { Text(stringResource(R.string.message_add_custom_layout, link)) },
|
||||
onConfirmed = { showLayoutEditDialog = "new layout" to "" },
|
||||
neutralButtonText = stringResource(R.string.button_load_custom),
|
||||
onNeutral = {
|
||||
showAddLayoutDialog = false
|
||||
layoutPicker.launch(layoutIntent)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun WithSmallTitle(
|
||||
description: String,
|
||||
|
@ -398,8 +415,7 @@ fun <T>DropDownField(
|
|||
items: List<T>,
|
||||
selectedItem: T,
|
||||
onSelected: (T) -> Unit,
|
||||
isDefault: Boolean? = null,
|
||||
onDefault: () -> Unit = {},
|
||||
extraButton: @Composable (() -> Unit)? = null,
|
||||
itemContent: @Composable (T) -> Unit,
|
||||
) {
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
|
@ -423,8 +439,8 @@ fun <T>DropDownField(
|
|||
Modifier.rotate(-90f)
|
||||
)
|
||||
}
|
||||
if (isDefault != null)
|
||||
DefaultButton(onDefault, isDefault)
|
||||
if (extraButton != null)
|
||||
extraButton()
|
||||
}
|
||||
}
|
||||
DropdownMenu(
|
||||
|
|
|
@ -196,6 +196,8 @@
|
|||
<string name="button_restore">Restore</string>
|
||||
<!-- Preferences item for choosing secondary language -->
|
||||
<string name="secondary_locale">Multilingual typing</string>
|
||||
<!-- Clarification which locales are available for multilingual typing -->
|
||||
<string name="locales_with_dict">Languages with dictionaries</string>
|
||||
<!-- Preferences item for loading an external gesture typing library -->
|
||||
<string name="load_gesture_library">Load gesture typing library</string>
|
||||
<!-- Description for "load_gesture_library" option -->
|
||||
|
|
Loading…
Add table
Reference in a new issue