merge pref for toolbar normal and longpress codes

and remove old toolbar customizer dialog
This commit is contained in:
Helium314 2025-02-12 16:47:31 +01:00
parent b31b8f8fe2
commit f2f7426ee5
8 changed files with 71 additions and 167 deletions

View file

@ -13,8 +13,8 @@ android {
applicationId = "helium314.keyboard"
minSdk = 21
targetSdk = 34
versionCode = 2302
versionName = "2.3+dev1"
versionCode = 2303
versionName = "2.3+dev2"
ndk {
abiFilters.clear()
abiFilters.addAll(listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64"))

View file

@ -3,9 +3,11 @@ package helium314.keyboard.latin
import android.app.Application
import android.content.Context
import android.content.SharedPreferences
import androidx.core.content.edit
import helium314.keyboard.keyboard.ColorSetting
import helium314.keyboard.keyboard.KeyboardTheme
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode.checkAndConvertCode
import helium314.keyboard.latin.common.ColorType
import helium314.keyboard.latin.common.LocaleUtils.constructLocale
import helium314.keyboard.latin.settings.Defaults
@ -22,6 +24,7 @@ import helium314.keyboard.latin.utils.onCustomLayoutFileListChanged
import helium314.keyboard.latin.utils.prefs
import helium314.keyboard.latin.utils.protectedPrefs
import helium314.keyboard.latin.utils.upgradeToolbarPrefs
import helium314.keyboard.latin.utils.writeCustomKeyCodes
import java.io.File
import java.util.EnumMap
@ -212,6 +215,27 @@ fun checkVersionUpgrade(context: Context) {
if (prefs.getString(Settings.PREF_THEME_COLORS_NIGHT, Defaults.PREF_THEME_COLORS_NIGHT) == "user_night")
prefs.edit().putString(Settings.PREF_THEME_COLORS_NIGHT, themeNameNight).apply()
}
if (oldVersion <= 2302) {
fun readCustomKeyCodes(setting: String) =
prefs.getString(setting, "")!!
.split(";").filter { it.isNotEmpty()}.associate {
val code = runCatching { it.substringAfter(",").toIntOrNull()?.checkAndConvertCode() }.getOrNull()
it.substringBefore(",") to code
}
val customCodes = readCustomKeyCodes("toolbar_custom_key_codes")
val customLongpressCodes = readCustomKeyCodes("toolbar_custom_longpress_codes")
prefs.edit().remove("toolbar_custom_longpress_codes").remove("toolbar_custom_key_codes").apply()
val combined = EnumMap<ToolbarKey, Pair<Int?, Int?>>(ToolbarKey::class.java)
customCodes.forEach { runCatching {
val key = ToolbarKey.valueOf(it.key)
combined[key] = (combined[key] ?: (null to null)).copy(first = it.value)
} }
customLongpressCodes.forEach { runCatching {
val key = ToolbarKey.valueOf(it.key)
combined[key] = (combined[key] ?: (null to null)).copy(second = it.value)
} }
writeCustomKeyCodes(prefs, combined)
}
upgradeToolbarPrefs(prefs)
onCustomLayoutFileListChanged() // just to be sure
prefs.edit { putInt(Settings.PREF_VERSION_CODE, BuildConfig.VERSION_CODE) }

View file

@ -36,7 +36,6 @@ object Defaults {
val PREF_THEME_DAY_NIGHT = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
const val PREF_CUSTOM_ICON_NAMES = ""
const val PREF_TOOLBAR_CUSTOM_KEY_CODES = ""
const val PREF_TOOLBAR_CUSTOM_LONGPRESS_CODES = ""
const val PREF_AUTO_CAP = true
const val PREF_VIBRATE_ON = false
const val PREF_VIBRATE_IN_DND_MODE = false

View file

@ -47,7 +47,6 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
public final class Settings implements SharedPreferences.OnSharedPreferenceChangeListener {
@ -69,7 +68,6 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
public static final String PREF_CUSTOM_ICON_NAMES = "custom_icon_names";
public static final String PREF_TOOLBAR_CUSTOM_KEY_CODES = "toolbar_custom_key_codes";
public static final String PREF_TOOLBAR_CUSTOM_LONGPRESS_CODES = "toolbar_custom_longpress_codes";
public static final String PREF_AUTO_CAP = "auto_cap";
public static final String PREF_VIBRATE_ON = "vibrate_on";
@ -187,8 +185,6 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
private final static Drawable[] sCachedBackgroundImages = new Drawable[4];
private static Typeface sCachedTypeface;
private static boolean sCustomTypefaceLoaded; // to avoid repeatedly checking custom typeface file when there is no custom typeface
private Map<String, Integer> mCustomToolbarKeyCodes = null;
private Map<String, Integer> mCustomToolbarLongpressCodes = null;
private static final Settings sInstance = new Settings();
@ -236,8 +232,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
Log.w(TAG, "onSharedPreferenceChanged called before loadSettings.");
return;
}
mCustomToolbarLongpressCodes = null;
mCustomToolbarKeyCodes = null;
ToolbarUtilsKt.clearCustomToolbarKeyCodes();
loadSettings(mContext, mSettingsValues.mLocale, mSettingsValues.mInputAttributes);
StatsUtils.onLoadSettings(mSettingsValues);
} finally {
@ -543,15 +538,11 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
}
public Integer getCustomToolbarKeyCode(ToolbarKey key) {
if (mCustomToolbarKeyCodes == null)
mCustomToolbarKeyCodes = ToolbarUtilsKt.readCustomKeyCodes(mPrefs);
return mCustomToolbarKeyCodes.get(key.name());
return ToolbarUtilsKt.getCustomKeyCode(key, mPrefs);
}
public Integer getCustomToolbarLongpressCode(ToolbarKey key) {
if (mCustomToolbarLongpressCodes == null)
mCustomToolbarLongpressCodes = ToolbarUtilsKt.readCustomLongpressCodes(mPrefs);
return mCustomToolbarLongpressCodes.get(key.name());
return ToolbarUtilsKt.getCustomLongpressKeyCode(key, mPrefs);
}
public static File getCustomFontFile(final Context context) {

View file

@ -10,7 +10,6 @@ import helium314.keyboard.latin.utils.defaultClipboardToolbarPref
import helium314.keyboard.latin.utils.defaultPinnedToolbarPref
import helium314.keyboard.latin.utils.defaultToolbarPref
import helium314.keyboard.latin.utils.reorderDialog
import helium314.keyboard.latin.utils.toolbarKeysCustomizer
class ToolbarSettingsFragment : SubScreenFragment() {
private var reloadKeyboard = false
@ -47,7 +46,7 @@ class ToolbarSettingsFragment : SubScreenFragment() {
}
findPreference<Preference>("customize_key_codes")?.onPreferenceClickListener =
Preference.OnPreferenceClickListener {
toolbarKeysCustomizer(requireContext())
//toolbarKeysCustomizer(requireContext())
true
}
}

View file

@ -1,38 +1,22 @@
// SPDX-License-Identifier: GPL-3.0-only
package helium314.keyboard.latin.utils
import android.annotation.SuppressLint
import android.content.Context
import android.content.DialogInterface
import android.content.SharedPreferences
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.EditText
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.ScrollView
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
import androidx.core.content.edit
import androidx.core.graphics.BlendModeColorFilterCompat
import androidx.core.graphics.BlendModeCompat
import androidx.core.view.forEach
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.core.widget.doAfterTextChanged
import helium314.keyboard.keyboard.internal.KeyboardIconsSet
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode.checkAndConvertCode
import helium314.keyboard.latin.R
import helium314.keyboard.latin.databinding.ReorderDialogItemBinding
import helium314.keyboard.latin.settings.Defaults
import helium314.keyboard.latin.settings.Settings
import helium314.keyboard.latin.utils.ToolbarKey.*
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.serialization.json.Json
import java.util.EnumMap
import java.util.Locale
@ -217,120 +201,37 @@ private fun getEnabledToolbarKeys(prefs: SharedPreferences, pref: String, defaul
}
}
fun toolbarKeysCustomizer(context: Context) {
val padding = ResourceUtils.toPx(8, context.resources)
val ll = LinearLayout(context).apply {
orientation = LinearLayout.VERTICAL
setPadding(3 * padding, padding, padding, padding)
}
val builder = AlertDialog.Builder(context)
.setTitle(R.string.customize_toolbar_key_codes)
.setView(ScrollView(context).apply { addView(ll) })
.setPositiveButton(R.string.dialog_close, null)
val prefs = context.prefs()
if (readCustomKeyCodes(prefs).isNotEmpty() || readCustomLongpressCodes(prefs).isNotEmpty())
builder.setNeutralButton(R.string.button_default) { _, _ ->
confirmDialog(context, context.getString(R.string.customize_toolbar_key_code_reset_message), context.getString(android.R.string.ok)) {
prefs.edit {
remove(Settings.PREF_TOOLBAR_CUSTOM_KEY_CODES)
remove(Settings.PREF_TOOLBAR_CUSTOM_LONGPRESS_CODES)
}
}
}
val dialog = builder.create()
val cf = BlendModeColorFilterCompat.createBlendModeColorFilterCompat(ContextCompat.getColor(context, R.color.foreground), BlendModeCompat.SRC_IN)
ToolbarKey.entries.forEach { key ->
val binding = ReorderDialogItemBinding.inflate(LayoutInflater.from(context), ll, true)
binding.reorderItemIcon.setImageDrawable(KeyboardIconsSet.instance.getNewDrawable(key.name, context))
binding.reorderItemIcon.colorFilter = cf
binding.reorderItemIcon.isVisible = true
binding.reorderItemName.text = key.name.lowercase().getStringResourceOrName("", context)
binding.root.setOnClickListener {
toolbarKeyCustomizer(context, key)
dialog.dismiss()
}
binding.reorderItemSwitch.isGone = true
binding.reorderItemDragIndicator.isGone = true
}
dialog.show()
}
@SuppressLint("SetTextI18n")
private fun toolbarKeyCustomizer(context: Context, key: ToolbarKey) {
val layout = LayoutInflater.from(context).inflate(R.layout.toolbar_key_customizer, null)
val prefs = context.prefs()
var keyCode: String? = null
var longpressCode: String? = null
val builder = AlertDialog.Builder(context)
.setTitle(key.name.lowercase().getStringResourceOrName("", context))
.setView(ScrollView(context).apply { addView(layout) })
.setPositiveButton(android.R.string.ok) { _, _ ->
val newKeyCode = runCatching { keyCode?.toIntOrNull()?.checkAndConvertCode() }.getOrNull()?.takeIf { it < Char.MAX_VALUE.code }
val newLongpressCode = runCatching { longpressCode?.toIntOrNull()?.checkAndConvertCode() }.getOrNull()?.takeIf { it < Char.MAX_VALUE.code }
if (newKeyCode != null)
writeCustomKeyCodes(prefs, readCustomKeyCodes(prefs) + (key.name to newKeyCode))
if (newLongpressCode != null)
writeCustomLongpressCodes(prefs, readCustomLongpressCodes(prefs) + (key.name to newLongpressCode))
toolbarKeysCustomizer(context)
}
.setNegativeButton(android.R.string.cancel) { _, _ -> toolbarKeysCustomizer(context) }
if (readCustomKeyCodes(prefs).containsKey(key.name) || readCustomLongpressCodes(prefs).containsKey(key.name))
builder.setNeutralButton(R.string.button_default) { _, _ ->
val keys = readCustomKeyCodes(prefs).toMutableMap()
keys.remove(key.name)
prefs.edit().putString(Settings.PREF_TOOLBAR_CUSTOM_KEY_CODES, Json.encodeToString(keys)).apply()
val longpressKeys = readCustomLongpressCodes(prefs).toMutableMap()
longpressKeys.remove(key.name)
prefs.edit().putString(Settings.PREF_TOOLBAR_CUSTOM_LONGPRESS_CODES, Json.encodeToString(longpressKeys)).apply()
toolbarKeysCustomizer(context)
}
val dialog = builder.create()
fun checkOk() {
val keyOk = keyCode == null
|| runCatching { keyCode?.toIntOrNull()?.let { it.checkAndConvertCode() <= Char.MAX_VALUE.code } }.getOrNull() ?: false
val longPressOk = longpressCode == null
|| runCatching { longpressCode?.toIntOrNull()?.let { it.checkAndConvertCode() <= Char.MAX_VALUE.code } }.getOrNull() ?: false
dialog.getButton(DialogInterface.BUTTON_POSITIVE)?.isEnabled = keyOk && longPressOk
}
layout.findViewById<EditText>(R.id.toolbar_key_code)?.apply {
setText(getCodeForToolbarKey(key).toString())
doAfterTextChanged {
keyCode = it?.toString()?.ifEmpty { "0" }
checkOk()
}
}
layout.findViewById<EditText>(R.id.toolbar_key_longpress_code)?.apply {
setText(getCodeForToolbarKeyLongClick(key).toString())
doAfterTextChanged {
longpressCode = it?.toString()?.ifEmpty { "0" }
checkOk()
}
}
dialog.show()
}
fun readCustomKeyCodes(prefs: SharedPreferences) =
prefs.getString(Settings.PREF_TOOLBAR_CUSTOM_KEY_CODES, Defaults.PREF_TOOLBAR_CUSTOM_KEY_CODES)!!
.split(";").filter { it.isNotEmpty()}.associate {
val code = runCatching { it.substringAfter(",").toIntOrNull()?.checkAndConvertCode() }.getOrNull()
it.substringBefore(",") to code
}
fun readCustomLongpressCodes(prefs: SharedPreferences) =
prefs.getString(Settings.PREF_TOOLBAR_CUSTOM_LONGPRESS_CODES, Defaults.PREF_TOOLBAR_CUSTOM_LONGPRESS_CODES)!!
.split(";").filter { it.isNotEmpty()}.associate {
val code = runCatching { it.substringAfter(",").toIntOrNull()?.checkAndConvertCode() }.getOrNull()
it.substringBefore(",") to code
}
fun writeCustomKeyCodes(prefs: SharedPreferences, codes: Map<String, Int?>) {
val string = codes.mapNotNull { entry -> entry.value?.let { "${entry.key},$it" } }.joinToString(";")
fun writeCustomKeyCodes(prefs: SharedPreferences, codes: EnumMap<ToolbarKey, Pair<Int?, Int?>>) {
val string = codes.mapNotNull { entry -> entry.value?.let { "${entry.key.name},${it.first},${it.second}" } }.joinToString(";")
prefs.edit().putString(Settings.PREF_TOOLBAR_CUSTOM_KEY_CODES, string).apply()
}
fun writeCustomLongpressCodes(prefs: SharedPreferences, codes: Map<String, Int?>) {
val string = codes.mapNotNull { entry -> entry.value?.let { "${entry.key},$it" } }.joinToString(";")
prefs.edit().putString(Settings.PREF_TOOLBAR_CUSTOM_LONGPRESS_CODES, string).apply()
fun readCustomKeyCodes(prefs: SharedPreferences): EnumMap<ToolbarKey, Pair<Int?, Int?>> {
val map = EnumMap<ToolbarKey, Pair<Int?, Int?>>(ToolbarKey::class.java)
prefs.getString(Settings.PREF_TOOLBAR_CUSTOM_KEY_CODES, Defaults.PREF_TOOLBAR_CUSTOM_KEY_CODES)!!
.split(";").forEach {
runCatching {
val s = it.split(",")
map[ToolbarKey.valueOf(s[0])] = s[1].toIntOrNull() to s[2].toIntOrNull()
}
}
return map
}
fun getCustomKeyCode(key: ToolbarKey, prefs: SharedPreferences): Int? {
if (customToolbarKeyCodes == null)
customToolbarKeyCodes = readCustomKeyCodes(prefs)
return customToolbarKeyCodes!![key]?.first
}
fun getCustomLongpressKeyCode(key: ToolbarKey, prefs: SharedPreferences): Int? {
if (customToolbarKeyCodes == null)
customToolbarKeyCodes = readCustomKeyCodes(prefs)
return customToolbarKeyCodes!![key]?.second
}
fun clearCustomToolbarKeyCodes() {
customToolbarKeyCodes = null
}
private var customToolbarKeyCodes: EnumMap<ToolbarKey, Pair<Int?, Int?>>? = null

View file

@ -124,6 +124,8 @@ fun ColorThemePickerDialog(
val uri = it.data?.data ?: return@rememberLauncherForActivityResult
ctx.getActivity()?.contentResolver?.openInputStream(uri)?.use {
errorDialog = !loadColorString(it.reader().readText(), prefs)
if (!errorDialog)
onDismissRequest() // todo: for some reason the list doesn't update after importing a file, only from clipboard
}
}
if (showLoadDialog) {
@ -265,7 +267,6 @@ private fun loadColorString(colorString: String, prefs: SharedPreferences): Bool
return false
}
}
keyboardNeedsReload = true
return true
}

View file

@ -13,7 +13,6 @@ import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
@ -24,7 +23,6 @@ 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.unit.dp
import androidx.core.content.edit
import helium314.keyboard.keyboard.internal.KeyboardIconsSet
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode.checkAndConvertCode
import helium314.keyboard.latin.R
@ -35,13 +33,9 @@ import helium314.keyboard.latin.utils.getCodeForToolbarKeyLongClick
import helium314.keyboard.latin.utils.getStringResourceOrName
import helium314.keyboard.latin.utils.prefs
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.screens.GetIcon
import kotlinx.serialization.json.Json
// todo (later): reading and writing prefs should be done in the preference, or at least with the provided (single!) pref key
@Composable
fun ToolbarKeysCustomizer(
onDismissRequest: () -> Unit
@ -55,7 +49,7 @@ fun ToolbarKeysCustomizer(
cancelButtonText = stringResource(R.string.dialog_close),
confirmButtonText = null,
onConfirmed = { },
neutralButtonText = if (readCustomKeyCodes(prefs).isNotEmpty() || readCustomLongpressCodes(prefs).isNotEmpty()) stringResource(R.string.button_default) else null,
neutralButtonText = if (readCustomKeyCodes(prefs).isNotEmpty()) stringResource(R.string.button_default) else null,
onNeutral = { showDeletePrefConfirmDialog = true },
title = { Text(stringResource(R.string.customize_toolbar_key_codes)) },
text = {
@ -85,10 +79,7 @@ fun ToolbarKeysCustomizer(
onConfirmed = {
showDeletePrefConfirmDialog = false
onDismissRequest()
prefs.edit {
remove(Settings.PREF_TOOLBAR_CUSTOM_KEY_CODES)
remove(Settings.PREF_TOOLBAR_CUSTOM_LONGPRESS_CODES)
}
prefs.edit().remove(Settings.PREF_TOOLBAR_CUSTOM_KEY_CODES).apply()
},
text = { Text(stringResource(R.string.customize_toolbar_key_code_reset_message)) }
)
@ -106,21 +97,19 @@ private fun ToolbarKeyCustomizer(
ThreeButtonAlertDialog(
onDismissRequest = onDismissRequest,
onConfirmed = {
writeCustomKeyCodes(prefs, readCustomKeyCodes(prefs) + (key.name to checkCode(code)))
writeCustomLongpressCodes(prefs, readCustomLongpressCodes(prefs) + (key.name to checkCode(longPressCode)))
val codes = readCustomKeyCodes(prefs)
codes[key] = checkCode(code) to checkCode(longPressCode)
writeCustomKeyCodes(prefs, codes)
},
checkOk = { checkCode(code) != null && checkCode(longPressCode) != null },
neutralButtonText = if (readCustomKeyCodes(prefs).containsKey(key.name) || readCustomLongpressCodes(prefs).containsKey(key.name))
neutralButtonText = if (readCustomKeyCodes(prefs).containsKey(key))
stringResource(R.string.button_default)
else null,
onNeutral = {
onDismissRequest()
val keys = readCustomKeyCodes(prefs).toMutableMap()
keys.remove(key.name)
prefs.edit().putString(Settings.PREF_TOOLBAR_CUSTOM_KEY_CODES, Json.encodeToString(keys)).apply()
val longpressKeys = readCustomLongpressCodes(prefs).toMutableMap()
longpressKeys.remove(key.name)
prefs.edit().putString(Settings.PREF_TOOLBAR_CUSTOM_LONGPRESS_CODES, Json.encodeToString(longpressKeys)).apply()
val keys = readCustomKeyCodes(prefs)
keys.remove(key)
writeCustomKeyCodes(prefs, keys)
},
title = { Text(key.name.lowercase().getStringResourceOrName("", ctx)) },
text = {