2023-12-28 22:47:31 +01:00
|
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
2024-01-31 18:32:43 +01:00
|
|
|
package helium314.keyboard.latin.utils
|
2023-12-21 21:57:53 +01:00
|
|
|
|
|
|
|
import android.content.Context
|
2023-12-28 22:47:31 +01:00
|
|
|
import android.content.SharedPreferences
|
2023-12-21 21:57:53 +01:00
|
|
|
import android.content.res.TypedArray
|
2024-04-06 12:22:14 +02:00
|
|
|
import android.graphics.drawable.Drawable
|
2023-12-21 21:57:53 +01:00
|
|
|
import android.widget.ImageButton
|
|
|
|
import android.widget.ImageView
|
2024-04-06 12:22:14 +02:00
|
|
|
import androidx.appcompat.view.ContextThemeWrapper
|
2023-12-28 22:47:31 +01:00
|
|
|
import androidx.core.content.edit
|
2024-04-06 12:22:14 +02:00
|
|
|
import helium314.keyboard.keyboard.KeyboardTheme
|
2024-03-02 21:02:48 +01:00
|
|
|
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
|
2024-01-31 18:32:43 +01:00
|
|
|
import helium314.keyboard.latin.R
|
|
|
|
import helium314.keyboard.latin.settings.Settings
|
|
|
|
import helium314.keyboard.latin.utils.ToolbarKey.*
|
2023-12-21 21:57:53 +01:00
|
|
|
|
2023-12-28 20:32:29 +01:00
|
|
|
fun createToolbarKey(context: Context, keyboardAttr: TypedArray, key: ToolbarKey): ImageButton {
|
2023-12-21 21:57:53 +01:00
|
|
|
val button = ImageButton(context, null, R.attr.suggestionWordStyle)
|
|
|
|
button.scaleType = ImageView.ScaleType.CENTER
|
2023-12-28 20:32:29 +01:00
|
|
|
button.tag = key
|
2023-12-28 22:47:31 +01:00
|
|
|
val contentDescriptionId = context.resources.getIdentifier(key.name.lowercase(), "string", context.packageName)
|
|
|
|
if (contentDescriptionId != 0)
|
|
|
|
button.contentDescription = context.getString(contentDescriptionId)
|
2023-12-28 20:32:29 +01:00
|
|
|
if (key == LEFT || key == RIGHT || key == UP || key == DOWN) {
|
2023-12-21 21:57:53 +01:00
|
|
|
// arrows look a little awkward when not scaled
|
|
|
|
button.scaleX = 1.2f
|
|
|
|
button.scaleY = 1.2f
|
|
|
|
}
|
2024-01-07 14:44:23 +01:00
|
|
|
button.isActivated = !when (key) {
|
2024-01-01 13:16:49 +01:00
|
|
|
INCOGNITO -> Settings.readAlwaysIncognitoMode(DeviceProtectedUtils.getSharedPreferences(context))
|
|
|
|
ONE_HANDED -> Settings.getInstance().current.mOneHandedModeEnabled
|
|
|
|
AUTOCORRECT -> Settings.getInstance().current.mAutoCorrectionEnabledPerUserSettings
|
|
|
|
else -> true
|
|
|
|
}
|
2024-01-07 14:44:23 +01:00
|
|
|
button.setImageDrawable(keyboardAttr.getDrawable(getStyleableIconId(key))?.mutate())
|
2023-12-21 21:57:53 +01:00
|
|
|
return button
|
|
|
|
}
|
|
|
|
|
2023-12-28 20:32:29 +01:00
|
|
|
fun getCodeForToolbarKey(key: ToolbarKey) = when (key) {
|
2024-03-02 21:02:48 +01:00
|
|
|
VOICE -> KeyCode.VOICE_INPUT
|
|
|
|
SETTINGS -> KeyCode.SETTINGS
|
|
|
|
CLIPBOARD -> KeyCode.CLIPBOARD
|
|
|
|
SELECT_ALL -> KeyCode.CLIPBOARD_SELECT_ALL
|
|
|
|
COPY -> KeyCode.CLIPBOARD_COPY
|
2024-04-12 18:05:53 +03:00
|
|
|
CUT -> KeyCode.CLIPBOARD_CUT
|
2024-03-02 21:02:48 +01:00
|
|
|
ONE_HANDED -> if (Settings.getInstance().current.mOneHandedModeEnabled) KeyCode.STOP_ONE_HANDED_MODE else KeyCode.START_ONE_HANDED_MODE
|
|
|
|
LEFT -> KeyCode.ARROW_LEFT
|
|
|
|
RIGHT -> KeyCode.ARROW_RIGHT
|
|
|
|
UP -> KeyCode.ARROW_UP
|
|
|
|
DOWN -> KeyCode.ARROW_DOWN
|
|
|
|
UNDO -> KeyCode.UNDO
|
|
|
|
REDO -> KeyCode.REDO
|
|
|
|
INCOGNITO -> KeyCode.TOGGLE_INCOGNITO_MODE
|
|
|
|
AUTOCORRECT -> KeyCode.TOGGLE_AUTOCORRECT
|
|
|
|
FULL_LEFT -> KeyCode.MOVE_START_OF_LINE
|
|
|
|
FULL_RIGHT -> KeyCode.MOVE_END_OF_LINE
|
|
|
|
SELECT_WORD -> KeyCode.CLIPBOARD_SELECT_WORD
|
2024-05-01 22:59:16 +02:00
|
|
|
CLEAR_CLIPBOARD -> KeyCode.UNSPECIFIED // not managed via code input
|
2024-04-06 19:11:28 +03:00
|
|
|
CLOSE_HISTORY -> KeyCode.ALPHA
|
2023-12-21 21:57:53 +01:00
|
|
|
}
|
|
|
|
|
2024-05-01 23:44:51 +03:00
|
|
|
fun getCodeForToolbarKeyLongClick(key: ToolbarKey) = when (key) {
|
|
|
|
RIGHT -> KeyCode.MOVE_END_OF_LINE
|
|
|
|
LEFT -> KeyCode.MOVE_START_OF_LINE
|
|
|
|
UP -> KeyCode.PAGE_UP
|
|
|
|
DOWN -> KeyCode.PAGE_DOWN
|
|
|
|
UNDO -> KeyCode.REDO
|
|
|
|
REDO -> KeyCode.UNDO
|
|
|
|
COPY -> KeyCode.CLIPBOARD_COPY_ALL
|
|
|
|
SELECT_WORD -> KeyCode.CLIPBOARD_SELECT_ALL
|
|
|
|
CLIPBOARD -> KeyCode.CLIPBOARD_PASTE
|
|
|
|
else -> KeyCode.UNSPECIFIED
|
|
|
|
}
|
|
|
|
|
2024-05-12 18:08:15 +02:00
|
|
|
fun getStyleableIconId(key: ToolbarKey) = when (key) {
|
2023-12-28 20:32:29 +01:00
|
|
|
VOICE -> R.styleable.Keyboard_iconShortcutKey
|
|
|
|
SETTINGS -> R.styleable.Keyboard_iconSettingsKey
|
|
|
|
CLIPBOARD -> R.styleable.Keyboard_iconClipboardNormalKey
|
|
|
|
SELECT_ALL -> R.styleable.Keyboard_iconSelectAll
|
|
|
|
COPY -> R.styleable.Keyboard_iconCopyKey
|
2024-04-12 18:05:53 +03:00
|
|
|
CUT -> R.styleable.Keyboard_iconCutKey
|
2023-12-28 20:32:29 +01:00
|
|
|
ONE_HANDED -> R.styleable.Keyboard_iconStartOneHandedMode
|
|
|
|
LEFT -> R.styleable.Keyboard_iconArrowLeft
|
|
|
|
RIGHT -> R.styleable.Keyboard_iconArrowRight
|
|
|
|
UP -> R.styleable.Keyboard_iconArrowUp
|
|
|
|
DOWN -> R.styleable.Keyboard_iconArrowDown
|
|
|
|
UNDO -> R.styleable.Keyboard_iconUndo
|
|
|
|
REDO -> R.styleable.Keyboard_iconRedo
|
2024-01-01 13:16:49 +01:00
|
|
|
INCOGNITO -> R.styleable.Keyboard_iconIncognitoKey
|
2024-04-06 13:47:37 +03:00
|
|
|
AUTOCORRECT -> R.styleable.Keyboard_iconAutoCorrect
|
2023-12-28 20:32:29 +01:00
|
|
|
CLEAR_CLIPBOARD -> R.styleable.Keyboard_iconClearClipboardKey
|
2024-01-18 10:18:22 +01:00
|
|
|
FULL_LEFT -> R.styleable.Keyboard_iconFullLeft
|
|
|
|
FULL_RIGHT -> R.styleable.Keyboard_iconFullRight
|
|
|
|
SELECT_WORD -> R.styleable.Keyboard_iconSelectWord
|
2024-04-06 19:33:11 +02:00
|
|
|
CLOSE_HISTORY -> R.styleable.Keyboard_iconClose
|
2023-12-21 21:57:53 +01:00
|
|
|
}
|
|
|
|
|
2024-04-06 12:22:14 +02:00
|
|
|
fun getToolbarIconByName(name: String, context: Context): Drawable? {
|
|
|
|
val key = entries.firstOrNull { it.name == name } ?: return null
|
|
|
|
val themeContext = ContextThemeWrapper(context, KeyboardTheme.getKeyboardTheme(context).mStyleId)
|
|
|
|
val attrs = themeContext.obtainStyledAttributes(null, R.styleable.Keyboard)
|
|
|
|
val icon = attrs.getDrawable(getStyleableIconId(key))?.mutate()
|
|
|
|
attrs.recycle()
|
|
|
|
return icon
|
|
|
|
}
|
|
|
|
|
2023-12-28 22:47:31 +01:00
|
|
|
// names need to be aligned with resources strings (using lowercase of key.name)
|
2023-12-28 20:32:29 +01:00
|
|
|
enum class ToolbarKey {
|
2024-04-12 18:05:53 +03:00
|
|
|
VOICE, CLIPBOARD, UNDO, REDO, SETTINGS, SELECT_ALL, SELECT_WORD, COPY, CUT, ONE_HANDED, LEFT, RIGHT, UP, DOWN,
|
2024-04-06 19:11:28 +03:00
|
|
|
FULL_LEFT, FULL_RIGHT, INCOGNITO, AUTOCORRECT, CLEAR_CLIPBOARD, CLOSE_HISTORY
|
2023-12-28 20:32:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
fun toToolbarKeyString(keys: Collection<ToolbarKey>) = keys.joinToString(";") { it.name }
|
2023-12-28 22:47:31 +01:00
|
|
|
|
2024-04-06 19:11:28 +03:00
|
|
|
val defaultToolbarPref = entries.filterNot { it == CLEAR_CLIPBOARD || it == CLOSE_HISTORY }.joinToString(";") {
|
2024-01-01 13:16:49 +01:00
|
|
|
when (it) {
|
2024-04-12 18:05:53 +03:00
|
|
|
INCOGNITO, AUTOCORRECT, UP, DOWN, ONE_HANDED, FULL_LEFT, FULL_RIGHT, CUT -> "${it.name},false"
|
2024-01-01 13:16:49 +01:00
|
|
|
else -> "${it.name},true"
|
|
|
|
}
|
|
|
|
}
|
2023-12-28 22:47:31 +01:00
|
|
|
|
2024-05-01 23:41:11 +02:00
|
|
|
val defaultClipboardToolbarPref by lazy {
|
|
|
|
val default = listOf(ONE_HANDED, UNDO, UP, DOWN, LEFT, RIGHT, CLEAR_CLIPBOARD, COPY, CUT, SELECT_WORD, CLOSE_HISTORY)
|
|
|
|
val others = entries.filterNot { it in default }
|
|
|
|
default.joinToString(";") { "${it.name},true" } + ";" + others.joinToString(";") { "${it.name},false" }
|
|
|
|
}
|
|
|
|
|
2023-12-28 22:47:31 +01:00
|
|
|
/** add missing keys, typically because a new key has been added */
|
2024-05-01 23:41:11 +02:00
|
|
|
fun upgradeToolbarPrefs(prefs: SharedPreferences) {
|
2024-05-17 18:36:41 +02:00
|
|
|
upgradeToolbarPref(prefs, Settings.PREF_TOOLBAR_KEYS, defaultToolbarPref)
|
|
|
|
upgradeToolbarPref(prefs, Settings.PREF_CLIPBOARD_TOOLBAR_KEYS, defaultClipboardToolbarPref)
|
2024-05-01 23:41:11 +02:00
|
|
|
}
|
|
|
|
|
2024-05-17 18:36:41 +02:00
|
|
|
private fun upgradeToolbarPref(prefs: SharedPreferences, pref: String, default: String) {
|
|
|
|
if (!prefs.contains(pref)) return
|
2024-05-01 23:41:11 +02:00
|
|
|
val list = prefs.getString(pref, default)!!.split(";").toMutableList()
|
2024-01-01 13:16:49 +01:00
|
|
|
val splitDefault = defaultToolbarPref.split(";")
|
|
|
|
if (list.size == splitDefault.size) return
|
|
|
|
splitDefault.forEach { entry ->
|
|
|
|
val keyWithComma = entry.substringBefore(",") + ","
|
|
|
|
if (list.none { it.startsWith(keyWithComma) })
|
2024-05-17 18:36:41 +02:00
|
|
|
list.add("${keyWithComma}false")
|
2023-12-28 22:47:31 +01:00
|
|
|
}
|
|
|
|
// likely not needed, but better prepare for possibility of key removal
|
|
|
|
list.removeAll {
|
|
|
|
try {
|
|
|
|
ToolbarKey.valueOf(it.substringBefore(","))
|
|
|
|
false
|
|
|
|
} catch (_: IllegalArgumentException) {
|
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
prefs.edit { putString(Settings.PREF_TOOLBAR_KEYS, list.joinToString(";")) }
|
|
|
|
}
|
|
|
|
|
2024-05-01 23:41:11 +02:00
|
|
|
fun getEnabledToolbarKeys(prefs: SharedPreferences) = getEnabledToolbarKeys(prefs, Settings.PREF_TOOLBAR_KEYS, defaultToolbarPref)
|
|
|
|
|
|
|
|
fun getEnabledClipboardToolbarKeys(prefs: SharedPreferences) = getEnabledToolbarKeys(prefs, Settings.PREF_CLIPBOARD_TOOLBAR_KEYS, defaultClipboardToolbarPref)
|
|
|
|
|
|
|
|
private fun getEnabledToolbarKeys(prefs: SharedPreferences, pref: String, default: String): List<ToolbarKey> {
|
|
|
|
val string = prefs.getString(pref, default)!!
|
2023-12-28 22:47:31 +01:00
|
|
|
return string.split(";").mapNotNull {
|
|
|
|
val split = it.split(",")
|
|
|
|
if (split.last() == "true") {
|
|
|
|
try {
|
|
|
|
ToolbarKey.valueOf(split.first())
|
|
|
|
} catch (_: IllegalArgumentException) {
|
|
|
|
null
|
|
|
|
}
|
|
|
|
} else null
|
|
|
|
}
|
|
|
|
}
|