mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-05-17 07:22:45 +00:00
Allow changing toolbar icon and codes (#1110)
This commit is contained in:
parent
7d1cf0dd63
commit
05523ecd30
14 changed files with 433 additions and 89 deletions
|
@ -46,7 +46,7 @@ Does not use internet permission, and thus is 100% offline.
|
||||||
<li>Backup and restore your settings and learned word / history data</li>
|
<li>Backup and restore your settings and learned word / history data</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
For more information about the app and features, please visit the [wiki](https://github.com/Helium314/HeliBoard/wiki)
|
For FAQ and more information about the app and features, please visit the [wiki](https://github.com/Helium314/HeliBoard/wiki)
|
||||||
|
|
||||||
# Contributing ❤
|
# Contributing ❤
|
||||||
|
|
||||||
|
|
|
@ -938,11 +938,12 @@ public class Key implements Comparable<Key> {
|
||||||
final String iconName = getIconName();
|
final String iconName = getIconName();
|
||||||
if (iconName == null) return false;
|
if (iconName == null) return false;
|
||||||
// todo: other way of identifying the color?
|
// todo: other way of identifying the color?
|
||||||
// if yes, NAME_CLIPBOARD_ACTION_KEY and NAME_CLIPBOARD_NORMAL_KEY could be merged
|
// this should be done differently, as users can set any icon now
|
||||||
|
// how is the background drawable selected? can we use the same way?
|
||||||
return iconName.equals(KeyboardIconsSet.NAME_NEXT_KEY)
|
return iconName.equals(KeyboardIconsSet.NAME_NEXT_KEY)
|
||||||
|| iconName.equals(KeyboardIconsSet.NAME_PREVIOUS_KEY)
|
|| iconName.equals(KeyboardIconsSet.NAME_PREVIOUS_KEY)
|
||||||
|| iconName.equals(KeyboardIconsSet.NAME_CLIPBOARD_ACTION_KEY)
|
|| iconName.equals("clipboard_action_key")
|
||||||
|| iconName.equals(KeyboardIconsSet.NAME_EMOJI_ACTION_KEY);
|
|| iconName.equals("emoji_action_key");
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasFunctionalBackground() {
|
public boolean hasFunctionalBackground() {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import android.graphics.drawable.Drawable
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import helium314.keyboard.keyboard.KeyboardTheme
|
import helium314.keyboard.keyboard.KeyboardTheme
|
||||||
import helium314.keyboard.latin.R
|
import helium314.keyboard.latin.R
|
||||||
|
import helium314.keyboard.latin.customIconIds
|
||||||
import helium314.keyboard.latin.settings.Settings
|
import helium314.keyboard.latin.settings.Settings
|
||||||
import helium314.keyboard.latin.utils.DeviceProtectedUtils
|
import helium314.keyboard.latin.utils.DeviceProtectedUtils
|
||||||
import helium314.keyboard.latin.utils.Log
|
import helium314.keyboard.latin.utils.Log
|
||||||
|
@ -13,17 +14,20 @@ import helium314.keyboard.latin.utils.ToolbarKey
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
class KeyboardIconsSet private constructor() {
|
class KeyboardIconsSet private constructor() {
|
||||||
private var iconIds = emptyMap<String, Int>()
|
var iconIds = emptyMap<String, Int>()
|
||||||
|
private set
|
||||||
private val iconsByName = HashMap<String, Drawable>(80)
|
private val iconsByName = HashMap<String, Drawable>(80)
|
||||||
|
|
||||||
fun loadIcons(context: Context) {
|
fun loadIcons(context: Context) {
|
||||||
val prefs = DeviceProtectedUtils.getSharedPreferences(context)
|
val prefs = DeviceProtectedUtils.getSharedPreferences(context)
|
||||||
val iconStyle = prefs.getString(Settings.PREF_ICON_STYLE, KeyboardTheme.STYLE_MATERIAL)
|
val iconStyle = prefs.getString(Settings.PREF_ICON_STYLE, KeyboardTheme.STYLE_MATERIAL)
|
||||||
val ids = when (iconStyle) {
|
val defaultIds = when (iconStyle) {
|
||||||
KeyboardTheme.STYLE_HOLO -> keyboardIconsHolo
|
KeyboardTheme.STYLE_HOLO -> keyboardIconsHolo
|
||||||
KeyboardTheme.STYLE_ROUNDED -> keyboardIconsRounded
|
KeyboardTheme.STYLE_ROUNDED -> keyboardIconsRounded
|
||||||
else -> keyboardIconsMaterial
|
else -> keyboardIconsMaterial
|
||||||
}
|
}
|
||||||
|
val overrideIds = customIconIds(context, prefs)
|
||||||
|
val ids = if (overrideIds.isEmpty()) defaultIds else defaultIds + overrideIds
|
||||||
if (ids == iconIds) return
|
if (ids == iconIds) return
|
||||||
iconIds = ids
|
iconIds = ids
|
||||||
iconsByName.clear()
|
iconsByName.clear()
|
||||||
|
@ -38,13 +42,15 @@ class KeyboardIconsSet private constructor() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getIconDrawable(name: String?): Drawable? = iconsByName[name?.lowercase(Locale.US)]
|
fun getIconDrawable(name: String?): Drawable? = name?.lowercase(Locale.US)?.let {
|
||||||
/** gets drawable from resources, with mutate (might be necessary to avoid coloring issues...) */
|
iconsByName[it] ?: iconsByName[alternativeNames[it]]
|
||||||
fun getNewDrawable(name: String?, context: Context): Drawable? =
|
}
|
||||||
iconIds[name?.lowercase(Locale.US)]?.let { ContextCompat.getDrawable(context, it)?.mutate() }
|
|
||||||
|
/** gets drawable from resources, with mutate (might be necessary to avoid coloring issues...) */
|
||||||
|
fun getNewDrawable(name: String?, context: Context): Drawable? = name?.lowercase(Locale.US)?.let { name ->
|
||||||
|
(iconIds[name] ?: iconIds[alternativeNames[name]])?.let { ContextCompat.getDrawable(context, it)?.mutate() }
|
||||||
|
}
|
||||||
|
|
||||||
// sometimes there are 2 names for the same icon for historic reasons,
|
|
||||||
// and removing needs to be handled with care to not break custom themes
|
|
||||||
companion object {
|
companion object {
|
||||||
private val TAG = KeyboardIconsSet::class.simpleName
|
private val TAG = KeyboardIconsSet::class.simpleName
|
||||||
const val PREFIX_ICON = "!icon/"
|
const val PREFIX_ICON = "!icon/"
|
||||||
|
@ -53,7 +59,6 @@ class KeyboardIconsSet private constructor() {
|
||||||
const val NAME_SHIFT_KEY_SHIFTED = "shift_key_shifted"
|
const val NAME_SHIFT_KEY_SHIFTED = "shift_key_shifted"
|
||||||
const val NAME_SHIFT_KEY_LOCKED = "shift_key_locked"
|
const val NAME_SHIFT_KEY_LOCKED = "shift_key_locked"
|
||||||
const val NAME_DELETE_KEY = "delete_key"
|
const val NAME_DELETE_KEY = "delete_key"
|
||||||
const val NAME_SETTINGS_KEY = "settings_key"
|
|
||||||
const val NAME_SPACE_KEY = "space_key"
|
const val NAME_SPACE_KEY = "space_key"
|
||||||
const val NAME_SPACE_KEY_FOR_NUMBER_LAYOUT = "space_key_for_number_layout"
|
const val NAME_SPACE_KEY_FOR_NUMBER_LAYOUT = "space_key_for_number_layout"
|
||||||
const val NAME_ENTER_KEY = "enter_key"
|
const val NAME_ENTER_KEY = "enter_key"
|
||||||
|
@ -64,64 +69,37 @@ class KeyboardIconsSet private constructor() {
|
||||||
const val NAME_DONE_KEY = "done_key"
|
const val NAME_DONE_KEY = "done_key"
|
||||||
const val NAME_PREVIOUS_KEY = "previous_key"
|
const val NAME_PREVIOUS_KEY = "previous_key"
|
||||||
const val NAME_TAB_KEY = "tab_key"
|
const val NAME_TAB_KEY = "tab_key"
|
||||||
const val NAME_SHORTCUT_KEY = "shortcut_key"
|
|
||||||
const val NAME_INCOGNITO_KEY = "incognito_key"
|
|
||||||
const val NAME_SHORTCUT_KEY_DISABLED = "shortcut_key_disabled"
|
const val NAME_SHORTCUT_KEY_DISABLED = "shortcut_key_disabled"
|
||||||
const val NAME_LANGUAGE_SWITCH_KEY = "language_switch_key"
|
const val NAME_LANGUAGE_SWITCH_KEY = "language_switch_key"
|
||||||
const val NAME_ZWNJ_KEY = "zwnj_key"
|
const val NAME_ZWNJ_KEY = "zwnj_key"
|
||||||
const val NAME_ZWJ_KEY = "zwj_key"
|
const val NAME_ZWJ_KEY = "zwj_key"
|
||||||
const val NAME_EMOJI_ACTION_KEY = "emoji_action_key"
|
|
||||||
const val NAME_EMOJI_NORMAL_KEY = "emoji_normal_key"
|
|
||||||
const val NAME_CLIPBOARD_ACTION_KEY = "clipboard_action_key"
|
|
||||||
const val NAME_CLIPBOARD_NORMAL_KEY = "clipboard_normal_key"
|
|
||||||
const val NAME_CLEAR_CLIPBOARD_KEY = "clear_clipboard_key"
|
|
||||||
const val NAME_CUT_KEY = "cut_key"
|
|
||||||
const val NAME_START_ONEHANDED_KEY = "start_onehanded_mode_key"
|
|
||||||
const val NAME_STOP_ONEHANDED_KEY = "stop_onehanded_mode_key"
|
const val NAME_STOP_ONEHANDED_KEY = "stop_onehanded_mode_key"
|
||||||
const val NAME_SWITCH_ONEHANDED_KEY = "switch_onehanded_key"
|
const val NAME_SWITCH_ONEHANDED_KEY = "switch_onehanded_key"
|
||||||
const val NAME_RESIZE_ONEHANDED_KEY = "resize_onehanded_key"
|
const val NAME_RESIZE_ONEHANDED_KEY = "resize_onehanded_key"
|
||||||
const val NAME_TOOLBAR_KEY = "toolbar_key"
|
const val NAME_TOOLBAR_KEY = "toolbar_key"
|
||||||
const val NAME_BIN = "bin"
|
const val NAME_BIN = "bin"
|
||||||
/*
|
|
||||||
private val styleableIdByName = hashMapOf(
|
// names used in the past, and we can't just delete them because they might still be in use in some layouts
|
||||||
NAME_SHIFT_KEY to R.styleable.Keyboard_iconShiftKey,
|
// (also some of them are in use for internal layouts, but there we could just remove them...)
|
||||||
NAME_DELETE_KEY to R.styleable.Keyboard_iconDeleteKey,
|
private val alternativeNames = hashMapOf(
|
||||||
NAME_SETTINGS_KEY to R.styleable.Keyboard_iconSettingsKey,
|
"clear_clipboard_key" to ToolbarKey.CLEAR_CLIPBOARD.name.lowercase(Locale.US),
|
||||||
NAME_SPACE_KEY to R.styleable.Keyboard_iconSpaceKey,
|
"shortcut_key" to ToolbarKey.VOICE.name.lowercase(Locale.US),
|
||||||
NAME_ENTER_KEY to R.styleable.Keyboard_iconEnterKey,
|
"emoji_action_key" to ToolbarKey.EMOJI.name.lowercase(Locale.US),
|
||||||
NAME_GO_KEY to R.styleable.Keyboard_iconGoKey,
|
"emoji_normal_key" to ToolbarKey.EMOJI.name.lowercase(Locale.US),
|
||||||
NAME_SEARCH_KEY to R.styleable.Keyboard_iconSearchKey,
|
"clipboard_action_key" to ToolbarKey.CLIPBOARD.name.lowercase(Locale.US),
|
||||||
NAME_SEND_KEY to R.styleable.Keyboard_iconSendKey,
|
"clipboard_normal_key" to ToolbarKey.CLIPBOARD.name.lowercase(Locale.US),
|
||||||
NAME_NEXT_KEY to R.styleable.Keyboard_iconNextKey,
|
"cut_key" to ToolbarKey.CUT.name.lowercase(Locale.US),
|
||||||
NAME_DONE_KEY to R.styleable.Keyboard_iconDoneKey,
|
"incognito_key" to ToolbarKey.INCOGNITO.name.lowercase(Locale.US),
|
||||||
NAME_PREVIOUS_KEY to R.styleable.Keyboard_iconPreviousKey,
|
"settings_key" to ToolbarKey.SETTINGS.name.lowercase(Locale.US),
|
||||||
NAME_TAB_KEY to R.styleable.Keyboard_iconTabKey,
|
"start_onehanded_mode_key" to ToolbarKey.ONE_HANDED.name.lowercase(Locale.US),
|
||||||
NAME_SHORTCUT_KEY to R.styleable.Keyboard_iconShortcutKey,
|
)
|
||||||
NAME_INCOGNITO_KEY to R.styleable.Keyboard_iconIncognitoKey,
|
|
||||||
NAME_SPACE_KEY_FOR_NUMBER_LAYOUT to R.styleable.Keyboard_iconSpaceKeyForNumberLayout,
|
// todo: incognito and force incognito should not be the same? or not the same as toolbar key?
|
||||||
NAME_SHIFT_KEY_SHIFTED to R.styleable.Keyboard_iconShiftKeyShifted,
|
|
||||||
NAME_SHIFT_KEY_LOCKED to R.styleable.Keyboard_iconShiftKeyLocked,
|
|
||||||
NAME_SHORTCUT_KEY_DISABLED to R.styleable.Keyboard_iconShortcutKeyDisabled,
|
|
||||||
NAME_LANGUAGE_SWITCH_KEY to R.styleable.Keyboard_iconLanguageSwitchKey,
|
|
||||||
NAME_ZWNJ_KEY to R.styleable.Keyboard_iconZwnjKey,
|
|
||||||
NAME_ZWJ_KEY to R.styleable.Keyboard_iconZwjKey,
|
|
||||||
NAME_EMOJI_ACTION_KEY to R.styleable.Keyboard_iconEmojiActionKey,
|
|
||||||
NAME_EMOJI_NORMAL_KEY to R.styleable.Keyboard_iconEmojiNormalKey,
|
|
||||||
NAME_CLIPBOARD_ACTION_KEY to R.styleable.Keyboard_iconClipboardActionKey,
|
|
||||||
NAME_CLIPBOARD_NORMAL_KEY to R.styleable.Keyboard_iconClipboardNormalKey,
|
|
||||||
NAME_CLEAR_CLIPBOARD_KEY to R.styleable.Keyboard_iconClearClipboardKey,
|
|
||||||
NAME_CUT_KEY to R.styleable.Keyboard_iconCutKey,
|
|
||||||
NAME_START_ONEHANDED_KEY to R.styleable.Keyboard_iconStartOneHandedMode,
|
|
||||||
NAME_STOP_ONEHANDED_KEY to R.styleable.Keyboard_iconStopOneHandedMode,
|
|
||||||
NAME_SWITCH_ONEHANDED_KEY to R.styleable.Keyboard_iconSwitchOneHandedMode,
|
|
||||||
).apply { ToolbarKey.entries.forEach { put(it.name.lowercase(Locale.US), getStyleableIconId(it)) } }
|
|
||||||
*/
|
|
||||||
private val keyboardIconsHolo by lazy { hashMapOf(
|
private val keyboardIconsHolo by lazy { hashMapOf(
|
||||||
NAME_SHIFT_KEY to R.drawable.sym_keyboard_shift_holo,
|
NAME_SHIFT_KEY to R.drawable.sym_keyboard_shift_holo,
|
||||||
NAME_SHIFT_KEY_SHIFTED to R.drawable.sym_keyboard_shifted_holo,
|
NAME_SHIFT_KEY_SHIFTED to R.drawable.sym_keyboard_shifted_holo,
|
||||||
NAME_SHIFT_KEY_LOCKED to R.drawable.sym_keyboard_shift_lock_holo,
|
NAME_SHIFT_KEY_LOCKED to R.drawable.sym_keyboard_shift_lock_holo,
|
||||||
NAME_DELETE_KEY to R.drawable.sym_keyboard_delete_holo,
|
NAME_DELETE_KEY to R.drawable.sym_keyboard_delete_holo,
|
||||||
NAME_SETTINGS_KEY to R.drawable.sym_keyboard_settings_holo,
|
|
||||||
// NAME_SPACE_KEY to null,
|
// NAME_SPACE_KEY to null,
|
||||||
NAME_ENTER_KEY to R.drawable.sym_keyboard_return_holo,
|
NAME_ENTER_KEY to R.drawable.sym_keyboard_return_holo,
|
||||||
// NAME_GO_KEY to null,
|
// NAME_GO_KEY to null,
|
||||||
|
@ -131,20 +109,11 @@ class KeyboardIconsSet private constructor() {
|
||||||
// NAME_NEXT_KEY to null,
|
// NAME_NEXT_KEY to null,
|
||||||
// NAME_PREVIOUS_KEY to null,
|
// NAME_PREVIOUS_KEY to null,
|
||||||
NAME_TAB_KEY to R.drawable.sym_keyboard_tab_holo,
|
NAME_TAB_KEY to R.drawable.sym_keyboard_tab_holo,
|
||||||
NAME_INCOGNITO_KEY to R.drawable.sym_keyboard_incognito_holo,
|
|
||||||
NAME_SPACE_KEY_FOR_NUMBER_LAYOUT to R.drawable.sym_keyboard_space_holo,
|
NAME_SPACE_KEY_FOR_NUMBER_LAYOUT to R.drawable.sym_keyboard_space_holo,
|
||||||
NAME_SHORTCUT_KEY to R.drawable.sym_keyboard_voice_holo,
|
|
||||||
NAME_SHORTCUT_KEY_DISABLED to R.drawable.sym_keyboard_voice_off_holo,
|
NAME_SHORTCUT_KEY_DISABLED to R.drawable.sym_keyboard_voice_off_holo,
|
||||||
NAME_LANGUAGE_SWITCH_KEY to R.drawable.sym_keyboard_language_switch,
|
NAME_LANGUAGE_SWITCH_KEY to R.drawable.sym_keyboard_language_switch,
|
||||||
NAME_ZWNJ_KEY to R.drawable.sym_keyboard_zwnj_holo,
|
NAME_ZWNJ_KEY to R.drawable.sym_keyboard_zwnj_holo,
|
||||||
NAME_ZWJ_KEY to R.drawable.sym_keyboard_zwj_holo,
|
NAME_ZWJ_KEY to R.drawable.sym_keyboard_zwj_holo,
|
||||||
NAME_EMOJI_ACTION_KEY to R.drawable.sym_keyboard_smiley_holo,
|
|
||||||
NAME_EMOJI_NORMAL_KEY to R.drawable.sym_keyboard_smiley_holo,
|
|
||||||
NAME_CLIPBOARD_ACTION_KEY to R.drawable.sym_keyboard_clipboard_holo,
|
|
||||||
NAME_CLIPBOARD_NORMAL_KEY to R.drawable.sym_keyboard_clipboard_holo,
|
|
||||||
NAME_CLEAR_CLIPBOARD_KEY to R.drawable.sym_keyboard_clear_clipboard_holo,
|
|
||||||
NAME_CUT_KEY to R.drawable.sym_keyboard_cut,
|
|
||||||
NAME_START_ONEHANDED_KEY to R.drawable.sym_keyboard_start_onehanded_holo,
|
|
||||||
NAME_STOP_ONEHANDED_KEY to R.drawable.sym_keyboard_stop_onehanded_holo,
|
NAME_STOP_ONEHANDED_KEY to R.drawable.sym_keyboard_stop_onehanded_holo,
|
||||||
NAME_SWITCH_ONEHANDED_KEY to R.drawable.ic_arrow_left,
|
NAME_SWITCH_ONEHANDED_KEY to R.drawable.ic_arrow_left,
|
||||||
NAME_RESIZE_ONEHANDED_KEY to R.drawable.ic_arrow_horizontal,
|
NAME_RESIZE_ONEHANDED_KEY to R.drawable.ic_arrow_horizontal,
|
||||||
|
@ -191,7 +160,6 @@ class KeyboardIconsSet private constructor() {
|
||||||
NAME_SHIFT_KEY_SHIFTED to R.drawable.sym_keyboard_shift_lxx,
|
NAME_SHIFT_KEY_SHIFTED to R.drawable.sym_keyboard_shift_lxx,
|
||||||
NAME_SHIFT_KEY_LOCKED to R.drawable.sym_keyboard_shift_lock_lxx,
|
NAME_SHIFT_KEY_LOCKED to R.drawable.sym_keyboard_shift_lock_lxx,
|
||||||
NAME_DELETE_KEY to R.drawable.sym_keyboard_delete_lxx,
|
NAME_DELETE_KEY to R.drawable.sym_keyboard_delete_lxx,
|
||||||
NAME_SETTINGS_KEY to R.drawable.sym_keyboard_settings_lxx,
|
|
||||||
// NAME_SPACE_KEY to null,
|
// NAME_SPACE_KEY to null,
|
||||||
NAME_ENTER_KEY to R.drawable.sym_keyboard_return_lxx,
|
NAME_ENTER_KEY to R.drawable.sym_keyboard_return_lxx,
|
||||||
NAME_GO_KEY to R.drawable.sym_keyboard_go_lxx,
|
NAME_GO_KEY to R.drawable.sym_keyboard_go_lxx,
|
||||||
|
@ -201,20 +169,11 @@ class KeyboardIconsSet private constructor() {
|
||||||
NAME_NEXT_KEY to R.drawable.ic_arrow_right,
|
NAME_NEXT_KEY to R.drawable.ic_arrow_right,
|
||||||
NAME_PREVIOUS_KEY to R.drawable.ic_arrow_left,
|
NAME_PREVIOUS_KEY to R.drawable.ic_arrow_left,
|
||||||
NAME_TAB_KEY to R.drawable.sym_keyboard_tab_lxx,
|
NAME_TAB_KEY to R.drawable.sym_keyboard_tab_lxx,
|
||||||
NAME_INCOGNITO_KEY to R.drawable.sym_keyboard_incognito_lxx,
|
|
||||||
NAME_SPACE_KEY_FOR_NUMBER_LAYOUT to R.drawable.sym_keyboard_space_lxx,
|
NAME_SPACE_KEY_FOR_NUMBER_LAYOUT to R.drawable.sym_keyboard_space_lxx,
|
||||||
NAME_SHORTCUT_KEY to R.drawable.sym_keyboard_voice_lxx,
|
|
||||||
NAME_SHORTCUT_KEY_DISABLED to R.drawable.sym_keyboard_voice_off_lxx,
|
NAME_SHORTCUT_KEY_DISABLED to R.drawable.sym_keyboard_voice_off_lxx,
|
||||||
NAME_LANGUAGE_SWITCH_KEY to R.drawable.sym_keyboard_language_switch_lxx,
|
NAME_LANGUAGE_SWITCH_KEY to R.drawable.sym_keyboard_language_switch_lxx,
|
||||||
NAME_ZWNJ_KEY to R.drawable.sym_keyboard_zwnj_lxx,
|
NAME_ZWNJ_KEY to R.drawable.sym_keyboard_zwnj_lxx,
|
||||||
NAME_ZWJ_KEY to R.drawable.sym_keyboard_zwj_lxx,
|
NAME_ZWJ_KEY to R.drawable.sym_keyboard_zwj_lxx,
|
||||||
NAME_EMOJI_ACTION_KEY to R.drawable.sym_keyboard_smiley_lxx,
|
|
||||||
NAME_EMOJI_NORMAL_KEY to R.drawable.sym_keyboard_smiley_lxx,
|
|
||||||
NAME_CLIPBOARD_ACTION_KEY to R.drawable.sym_keyboard_clipboard_lxx,
|
|
||||||
NAME_CLIPBOARD_NORMAL_KEY to R.drawable.sym_keyboard_clipboard_lxx,
|
|
||||||
NAME_CLEAR_CLIPBOARD_KEY to R.drawable.sym_keyboard_clear_clipboard_lxx,
|
|
||||||
NAME_CUT_KEY to R.drawable.sym_keyboard_cut,
|
|
||||||
NAME_START_ONEHANDED_KEY to R.drawable.sym_keyboard_start_onehanded_lxx,
|
|
||||||
NAME_STOP_ONEHANDED_KEY to R.drawable.sym_keyboard_stop_onehanded_lxx,
|
NAME_STOP_ONEHANDED_KEY to R.drawable.sym_keyboard_stop_onehanded_lxx,
|
||||||
NAME_SWITCH_ONEHANDED_KEY to R.drawable.ic_arrow_left,
|
NAME_SWITCH_ONEHANDED_KEY to R.drawable.ic_arrow_left,
|
||||||
NAME_RESIZE_ONEHANDED_KEY to R.drawable.ic_arrow_horizontal,
|
NAME_RESIZE_ONEHANDED_KEY to R.drawable.ic_arrow_horizontal,
|
||||||
|
@ -261,7 +220,6 @@ class KeyboardIconsSet private constructor() {
|
||||||
NAME_SHIFT_KEY_SHIFTED to R.drawable.sym_keyboard_shift_rounded,
|
NAME_SHIFT_KEY_SHIFTED to R.drawable.sym_keyboard_shift_rounded,
|
||||||
NAME_SHIFT_KEY_LOCKED to R.drawable.sym_keyboard_shift_lock_rounded,
|
NAME_SHIFT_KEY_LOCKED to R.drawable.sym_keyboard_shift_lock_rounded,
|
||||||
NAME_DELETE_KEY to R.drawable.sym_keyboard_delete_rounded,
|
NAME_DELETE_KEY to R.drawable.sym_keyboard_delete_rounded,
|
||||||
NAME_SETTINGS_KEY to R.drawable.sym_keyboard_settings_rounded,
|
|
||||||
// NAME_SPACE_KEY to null,
|
// NAME_SPACE_KEY to null,
|
||||||
NAME_ENTER_KEY to R.drawable.sym_keyboard_return_rounded,
|
NAME_ENTER_KEY to R.drawable.sym_keyboard_return_rounded,
|
||||||
NAME_GO_KEY to R.drawable.sym_keyboard_go_rounded,
|
NAME_GO_KEY to R.drawable.sym_keyboard_go_rounded,
|
||||||
|
@ -271,20 +229,11 @@ class KeyboardIconsSet private constructor() {
|
||||||
NAME_NEXT_KEY to R.drawable.ic_arrow_right_rounded,
|
NAME_NEXT_KEY to R.drawable.ic_arrow_right_rounded,
|
||||||
NAME_PREVIOUS_KEY to R.drawable.ic_arrow_left_rounded,
|
NAME_PREVIOUS_KEY to R.drawable.ic_arrow_left_rounded,
|
||||||
NAME_TAB_KEY to R.drawable.sym_keyboard_tab_rounded,
|
NAME_TAB_KEY to R.drawable.sym_keyboard_tab_rounded,
|
||||||
NAME_INCOGNITO_KEY to R.drawable.sym_keyboard_incognito_lxx,
|
|
||||||
NAME_SPACE_KEY_FOR_NUMBER_LAYOUT to R.drawable.sym_keyboard_space_rounded,
|
NAME_SPACE_KEY_FOR_NUMBER_LAYOUT to R.drawable.sym_keyboard_space_rounded,
|
||||||
NAME_SHORTCUT_KEY to R.drawable.sym_keyboard_voice_rounded,
|
|
||||||
NAME_SHORTCUT_KEY_DISABLED to R.drawable.sym_keyboard_voice_off_rounded,
|
NAME_SHORTCUT_KEY_DISABLED to R.drawable.sym_keyboard_voice_off_rounded,
|
||||||
NAME_LANGUAGE_SWITCH_KEY to R.drawable.sym_keyboard_language_switch_lxx,
|
NAME_LANGUAGE_SWITCH_KEY to R.drawable.sym_keyboard_language_switch_lxx,
|
||||||
NAME_ZWNJ_KEY to R.drawable.sym_keyboard_zwnj_lxx,
|
NAME_ZWNJ_KEY to R.drawable.sym_keyboard_zwnj_lxx,
|
||||||
NAME_ZWJ_KEY to R.drawable.sym_keyboard_zwj_lxx,
|
NAME_ZWJ_KEY to R.drawable.sym_keyboard_zwj_lxx,
|
||||||
NAME_EMOJI_ACTION_KEY to R.drawable.sym_keyboard_smiley_rounded,
|
|
||||||
NAME_EMOJI_NORMAL_KEY to R.drawable.sym_keyboard_smiley_rounded,
|
|
||||||
NAME_CLIPBOARD_ACTION_KEY to R.drawable.sym_keyboard_clipboard_rounded,
|
|
||||||
NAME_CLIPBOARD_NORMAL_KEY to R.drawable.sym_keyboard_clipboard_rounded,
|
|
||||||
NAME_CLEAR_CLIPBOARD_KEY to R.drawable.sym_keyboard_clear_clipboard_rounded,
|
|
||||||
NAME_CUT_KEY to R.drawable.sym_keyboard_cut_rounded,
|
|
||||||
NAME_START_ONEHANDED_KEY to R.drawable.sym_keyboard_start_onehanded_rounded,
|
|
||||||
NAME_STOP_ONEHANDED_KEY to R.drawable.sym_keyboard_stop_onehanded_rounded,
|
NAME_STOP_ONEHANDED_KEY to R.drawable.sym_keyboard_stop_onehanded_rounded,
|
||||||
NAME_SWITCH_ONEHANDED_KEY to R.drawable.ic_arrow_left_rounded,
|
NAME_SWITCH_ONEHANDED_KEY to R.drawable.ic_arrow_left_rounded,
|
||||||
NAME_RESIZE_ONEHANDED_KEY to R.drawable.ic_arrow_horizontal_rounded,
|
NAME_RESIZE_ONEHANDED_KEY to R.drawable.ic_arrow_horizontal_rounded,
|
||||||
|
@ -326,6 +275,19 @@ class KeyboardIconsSet private constructor() {
|
||||||
}
|
}
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
fun getAllIcons(context: Context): Map<String, List<Int>> {
|
||||||
|
// currently active style first
|
||||||
|
val prefs = DeviceProtectedUtils.getSharedPreferences(context)
|
||||||
|
val iconStyle = prefs.getString(Settings.PREF_ICON_STYLE, KeyboardTheme.STYLE_MATERIAL)
|
||||||
|
return keyboardIconsMaterial.entries.associate { (name, id) ->
|
||||||
|
name to when (iconStyle) {
|
||||||
|
KeyboardTheme.STYLE_HOLO -> listOfNotNull(keyboardIconsHolo[name], keyboardIconsRounded[name], id)
|
||||||
|
KeyboardTheme.STYLE_ROUNDED -> listOfNotNull(keyboardIconsRounded[name], id, keyboardIconsHolo[name])
|
||||||
|
else -> listOfNotNull(id, keyboardIconsRounded[name], keyboardIconsHolo[name])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val instance = KeyboardIconsSet()
|
val instance = KeyboardIconsSet()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
app/src/main/java/helium314/keyboard/latin/Settings.kt
Normal file
16
app/src/main/java/helium314/keyboard/latin/Settings.kt
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package helium314.keyboard.latin
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import helium314.keyboard.latin.settings.Settings
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
|
fun customIconNames(prefs: SharedPreferences) = runCatching {
|
||||||
|
Json.decodeFromString<Map<String, String>>(prefs.getString(Settings.PREF_CUSTOM_ICON_NAMES, "")!!)
|
||||||
|
}.getOrElse { emptyMap() }
|
||||||
|
|
||||||
|
fun customIconIds(context: Context, prefs: SharedPreferences) = customIconNames(prefs)
|
||||||
|
.mapNotNull { entry ->
|
||||||
|
val id = runCatching { context.resources.getIdentifier(entry.value, "drawable", context.packageName) }.getOrNull()
|
||||||
|
id?.let { entry.key to it }
|
||||||
|
}
|
|
@ -10,18 +10,37 @@ import android.graphics.BitmapFactory
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.ScrollView
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.graphics.BlendModeColorFilterCompat
|
||||||
|
import androidx.core.graphics.BlendModeCompat
|
||||||
import androidx.core.util.TypedValueCompat
|
import androidx.core.util.TypedValueCompat
|
||||||
|
import androidx.core.view.forEach
|
||||||
|
import androidx.core.view.isGone
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import androidx.preference.TwoStatePreference
|
import androidx.preference.TwoStatePreference
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import helium314.keyboard.keyboard.KeyboardSwitcher
|
import helium314.keyboard.keyboard.KeyboardSwitcher
|
||||||
import helium314.keyboard.keyboard.KeyboardTheme
|
import helium314.keyboard.keyboard.KeyboardTheme
|
||||||
|
import helium314.keyboard.keyboard.internal.KeyboardIconsSet
|
||||||
import helium314.keyboard.latin.R
|
import helium314.keyboard.latin.R
|
||||||
import helium314.keyboard.latin.common.FileUtils
|
import helium314.keyboard.latin.common.FileUtils
|
||||||
|
import helium314.keyboard.latin.customIconNames
|
||||||
|
import helium314.keyboard.latin.databinding.ReorderDialogItemBinding
|
||||||
|
import helium314.keyboard.latin.utils.ResourceUtils
|
||||||
import helium314.keyboard.latin.utils.getStringResourceOrName
|
import helium314.keyboard.latin.utils.getStringResourceOrName
|
||||||
import helium314.keyboard.latin.utils.infoDialog
|
import helium314.keyboard.latin.utils.infoDialog
|
||||||
|
import kotlinx.serialization.encodeToString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
import java.lang.Float.max
|
import java.lang.Float.max
|
||||||
import java.lang.Float.min
|
import java.lang.Float.min
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
@ -73,6 +92,7 @@ class AppearanceSettingsFragment : SubScreenFragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
findPreference<Preference>("custom_background_image")?.setOnPreferenceClickListener { onClickLoadImage() }
|
findPreference<Preference>("custom_background_image")?.setOnPreferenceClickListener { onClickLoadImage() }
|
||||||
|
findPreference<Preference>(Settings.PREF_CUSTOM_ICON_NAMES)?.setOnPreferenceClickListener { onClickCustomizeIcons() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
|
@ -179,6 +199,111 @@ class AppearanceSettingsFragment : SubScreenFragment() {
|
||||||
userColorsPrefNight?.isVisible = dayNightPref?.isChecked == true && colorsNightPref?.value == KeyboardTheme.THEME_USER_NIGHT
|
userColorsPrefNight?.isVisible = dayNightPref?.isChecked == true && colorsNightPref?.value == KeyboardTheme.THEME_USER_NIGHT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// performance is not good, but not bad enough to justify work
|
||||||
|
private fun onClickCustomizeIcons(): Boolean {
|
||||||
|
val ctx = requireContext()
|
||||||
|
val padding = ResourceUtils.toPx(8, ctx.resources)
|
||||||
|
val ll = LinearLayout(context).apply {
|
||||||
|
orientation = LinearLayout.VERTICAL
|
||||||
|
setPadding(padding, 3 * padding, padding, padding)
|
||||||
|
}
|
||||||
|
val d = AlertDialog.Builder(ctx)
|
||||||
|
.setTitle(R.string.customize_icons)
|
||||||
|
.setView(ScrollView(context).apply { addView(ll) })
|
||||||
|
.setPositiveButton(R.string.dialog_close, null)
|
||||||
|
.create()
|
||||||
|
val cf = BlendModeColorFilterCompat.createBlendModeColorFilterCompat(ContextCompat.getColor(ctx, R.color.foreground), BlendModeCompat.SRC_IN)
|
||||||
|
val icons = KeyboardIconsSet.getAllIcons(ctx)
|
||||||
|
icons.keys.forEach { iconName ->
|
||||||
|
val b = ReorderDialogItemBinding.inflate(LayoutInflater.from(ctx), ll, true)
|
||||||
|
b.reorderItemIcon.setImageDrawable(KeyboardIconsSet.instance.getNewDrawable(iconName, ctx))
|
||||||
|
b.reorderItemIcon.colorFilter = cf
|
||||||
|
b.reorderItemIcon.isVisible = true
|
||||||
|
b.reorderItemName.text = iconName.getStringResourceOrName("", ctx)
|
||||||
|
if (b.reorderItemName.text == iconName)
|
||||||
|
b.reorderItemName.text = iconName.getStringResourceOrName("label_", ctx)
|
||||||
|
b.root.setOnClickListener {
|
||||||
|
customizeIcon(iconName)
|
||||||
|
d.dismiss()
|
||||||
|
}
|
||||||
|
b.reorderItemSwitch.isGone = true
|
||||||
|
b.reorderItemDragIndicator.isGone = true
|
||||||
|
}
|
||||||
|
d.show()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: icon size is an important difference between holo and others, but really awful to work with
|
||||||
|
// scaling the intrinsic icon width may look awful depending on display density
|
||||||
|
private fun customizeIcon(iconName: String) {
|
||||||
|
val ctx = requireContext()
|
||||||
|
val rv = RecyclerView(ctx)
|
||||||
|
rv.layoutManager = GridLayoutManager(ctx, 6)
|
||||||
|
val padding = ResourceUtils.toPx(6, resources)
|
||||||
|
rv.setPadding(padding, 3 * padding, padding, padding)
|
||||||
|
val icons = KeyboardIconsSet.getAllIcons(ctx)
|
||||||
|
val iconsList = icons[iconName].orEmpty().toSet().toMutableList()
|
||||||
|
val iconsSet = icons.values.flatten().toMutableSet()
|
||||||
|
iconsSet.removeAll(iconsList)
|
||||||
|
iconsList.addAll(iconsSet)
|
||||||
|
val foregroundColor = ContextCompat.getColor(ctx, R.color.foreground)
|
||||||
|
val iconColorFilter = BlendModeColorFilterCompat.createBlendModeColorFilterCompat(foregroundColor, BlendModeCompat.SRC_IN)
|
||||||
|
|
||||||
|
var currentIconId = KeyboardIconsSet.instance.iconIds[iconName]
|
||||||
|
|
||||||
|
val adapter = object : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
|
val v = ImageView(ctx)
|
||||||
|
v.colorFilter = iconColorFilter
|
||||||
|
v.setPadding(padding, padding, padding, padding)
|
||||||
|
return object : RecyclerView.ViewHolder(v) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int = iconsList.size
|
||||||
|
|
||||||
|
override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, position: Int) {
|
||||||
|
val icon = ContextCompat.getDrawable(ctx, iconsList[position])?.mutate()
|
||||||
|
val imageView = viewHolder.itemView as? ImageView
|
||||||
|
imageView?.setImageDrawable(icon)
|
||||||
|
if (iconsList[position] == currentIconId) imageView?.setColorFilter(R.color.accent)
|
||||||
|
else imageView?.colorFilter = iconColorFilter
|
||||||
|
viewHolder.itemView.setOnClickListener { v ->
|
||||||
|
rv.forEach { (it as? ImageView)?.colorFilter = iconColorFilter }
|
||||||
|
(v as? ImageView)?.setColorFilter(R.color.accent)
|
||||||
|
currentIconId = iconsList[position]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rv.adapter = adapter
|
||||||
|
val title = iconName.getStringResourceOrName("", ctx).takeUnless { it == iconName }
|
||||||
|
?: iconName.getStringResourceOrName("label_", ctx)
|
||||||
|
val builder = AlertDialog.Builder(ctx)
|
||||||
|
.setTitle(title)
|
||||||
|
.setView(rv)
|
||||||
|
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||||
|
runCatching {
|
||||||
|
val icons2 = customIconNames(sharedPreferences).toMutableMap()
|
||||||
|
icons2[iconName] = currentIconId?.let { resources.getResourceEntryName(it) } ?: return@runCatching
|
||||||
|
sharedPreferences.edit().putString(Settings.PREF_CUSTOM_ICON_NAMES, Json.encodeToString(icons2)).apply()
|
||||||
|
KeyboardIconsSet.instance.loadIcons(ctx)
|
||||||
|
}
|
||||||
|
onClickCustomizeIcons()
|
||||||
|
}
|
||||||
|
.setNegativeButton(android.R.string.cancel) { _, _ -> onClickCustomizeIcons() }
|
||||||
|
if (customIconNames(sharedPreferences).contains(iconName))
|
||||||
|
builder.setNeutralButton(R.string.button_default) { _, _ ->
|
||||||
|
runCatching {
|
||||||
|
val icons2 = customIconNames(sharedPreferences).toMutableMap()
|
||||||
|
icons2.remove(iconName)
|
||||||
|
sharedPreferences.edit().putString(Settings.PREF_CUSTOM_ICON_NAMES, Json.encodeToString(icons2)).apply()
|
||||||
|
KeyboardIconsSet.instance.loadIcons(ctx)
|
||||||
|
}
|
||||||
|
onClickCustomizeIcons()
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.show()
|
||||||
|
}
|
||||||
|
|
||||||
private fun onClickLoadImage(): Boolean {
|
private fun onClickLoadImage(): Boolean {
|
||||||
if (Settings.readDayNightPref(sharedPreferences, resources)) {
|
if (Settings.readDayNightPref(sharedPreferences, resources)) {
|
||||||
AlertDialog.Builder(requireContext())
|
AlertDialog.Builder(requireContext())
|
||||||
|
|
|
@ -44,12 +44,15 @@ import helium314.keyboard.latin.utils.ResourceUtils;
|
||||||
import helium314.keyboard.latin.utils.RunInLocaleKt;
|
import helium314.keyboard.latin.utils.RunInLocaleKt;
|
||||||
import helium314.keyboard.latin.utils.StatsUtils;
|
import helium314.keyboard.latin.utils.StatsUtils;
|
||||||
import helium314.keyboard.latin.utils.SubtypeSettingsKt;
|
import helium314.keyboard.latin.utils.SubtypeSettingsKt;
|
||||||
|
import helium314.keyboard.latin.utils.ToolbarKey;
|
||||||
|
import helium314.keyboard.latin.utils.ToolbarUtilsKt;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
public final class Settings implements SharedPreferences.OnSharedPreferenceChangeListener {
|
public final class Settings implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
@ -79,6 +82,9 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
||||||
public static final String PREF_COLOR_BACKGROUND_SUFFIX = "background";
|
public static final String PREF_COLOR_BACKGROUND_SUFFIX = "background";
|
||||||
public static final String PREF_AUTO_USER_COLOR_SUFFIX = "_auto";
|
public static final String PREF_AUTO_USER_COLOR_SUFFIX = "_auto";
|
||||||
public static final String PREF_ALL_COLORS_SUFFIX = "all_colors";
|
public static final String PREF_ALL_COLORS_SUFFIX = "all_colors";
|
||||||
|
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_AUTO_CAP = "auto_cap";
|
||||||
public static final String PREF_VIBRATE_ON = "vibrate_on";
|
public static final String PREF_VIBRATE_ON = "vibrate_on";
|
||||||
|
@ -187,6 +193,8 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
||||||
// static cache for background images to avoid potentially slow reload on every settings reload
|
// static cache for background images to avoid potentially slow reload on every settings reload
|
||||||
private static Drawable sCachedBackgroundDay;
|
private static Drawable sCachedBackgroundDay;
|
||||||
private static Drawable sCachedBackgroundNight;
|
private static Drawable sCachedBackgroundNight;
|
||||||
|
private Map<String, Integer> mCustomToolbarKeyCodes = null;
|
||||||
|
private Map<String, Integer> mCustomToolbarLongpressCodes = null;
|
||||||
|
|
||||||
private static final Settings sInstance = new Settings();
|
private static final Settings sInstance = new Settings();
|
||||||
|
|
||||||
|
@ -234,6 +242,8 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
||||||
Log.w(TAG, "onSharedPreferenceChanged called before loadSettings.");
|
Log.w(TAG, "onSharedPreferenceChanged called before loadSettings.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
mCustomToolbarLongpressCodes = null;
|
||||||
|
mCustomToolbarKeyCodes = null;
|
||||||
loadSettings(mContext, mSettingsValues.mLocale, mSettingsValues.mInputAttributes);
|
loadSettings(mContext, mSettingsValues.mLocale, mSettingsValues.mInputAttributes);
|
||||||
StatsUtils.onLoadSettings(mSettingsValues);
|
StatsUtils.onLoadSettings(mSettingsValues);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -706,4 +716,16 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
||||||
public String readCustomCurrencyKey() {
|
public String readCustomCurrencyKey() {
|
||||||
return mPrefs.getString(PREF_CUSTOM_CURRENCY_KEY, "");
|
return mPrefs.getString(PREF_CUSTOM_CURRENCY_KEY, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getCustomToolbarKeyCode(ToolbarKey key) {
|
||||||
|
if (mCustomToolbarKeyCodes == null)
|
||||||
|
mCustomToolbarKeyCodes = ToolbarUtilsKt.readCustomKeyCodes(mPrefs);
|
||||||
|
return mCustomToolbarKeyCodes.get(key.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCustomToolbarLongpressCode(ToolbarKey key) {
|
||||||
|
if (mCustomToolbarLongpressCodes == null)
|
||||||
|
mCustomToolbarLongpressCodes = ToolbarUtilsKt.readCustomLongpressCodes(mPrefs);
|
||||||
|
return mCustomToolbarLongpressCodes.get(key.name());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import helium314.keyboard.latin.utils.defaultClipboardToolbarPref
|
||||||
import helium314.keyboard.latin.utils.defaultPinnedToolbarPref
|
import helium314.keyboard.latin.utils.defaultPinnedToolbarPref
|
||||||
import helium314.keyboard.latin.utils.defaultToolbarPref
|
import helium314.keyboard.latin.utils.defaultToolbarPref
|
||||||
import helium314.keyboard.latin.utils.reorderDialog
|
import helium314.keyboard.latin.utils.reorderDialog
|
||||||
|
import helium314.keyboard.latin.utils.toolbarKeysCustomizer
|
||||||
|
|
||||||
class ToolbarSettingsFragment : SubScreenFragment() {
|
class ToolbarSettingsFragment : SubScreenFragment() {
|
||||||
private var reloadKeyboard = false
|
private var reloadKeyboard = false
|
||||||
|
@ -44,6 +45,11 @@ class ToolbarSettingsFragment : SubScreenFragment() {
|
||||||
) { iconsSet.getNewDrawable(it, requireContext()) }
|
) { iconsSet.getNewDrawable(it, requireContext()) }
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
findPreference<Preference>("customize_key_codes")?.onPreferenceClickListener =
|
||||||
|
Preference.OnPreferenceClickListener {
|
||||||
|
toolbarKeysCustomizer(requireContext())
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
|
|
|
@ -182,7 +182,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
|
||||||
mMoreSuggestionsSlidingDetector = new GestureDetector(context, mMoreSuggestionsSlidingListener);
|
mMoreSuggestionsSlidingDetector = new GestureDetector(context, mMoreSuggestionsSlidingListener);
|
||||||
|
|
||||||
final KeyboardIconsSet iconsSet = KeyboardIconsSet.Companion.getInstance();
|
final KeyboardIconsSet iconsSet = KeyboardIconsSet.Companion.getInstance();
|
||||||
mIncognitoIcon = iconsSet.getNewDrawable(KeyboardIconsSet.NAME_INCOGNITO_KEY, context);
|
mIncognitoIcon = iconsSet.getNewDrawable(ToolbarKey.INCOGNITO.name(), context);
|
||||||
mToolbarArrowIcon = iconsSet.getNewDrawable(KeyboardIconsSet.NAME_TOOLBAR_KEY, context);
|
mToolbarArrowIcon = iconsSet.getNewDrawable(KeyboardIconsSet.NAME_TOOLBAR_KEY, context);
|
||||||
mBinIcon = iconsSet.getNewDrawable(KeyboardIconsSet.NAME_BIN, context);
|
mBinIcon = iconsSet.getNewDrawable(KeyboardIconsSet.NAME_BIN, context);
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,33 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
package helium314.keyboard.latin.utils
|
package helium314.keyboard.latin.utils
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.DialogInterface
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.widget.EditText
|
||||||
import android.widget.ImageButton
|
import android.widget.ImageButton
|
||||||
import android.widget.ImageView
|
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.content.edit
|
||||||
|
import androidx.core.graphics.BlendModeColorFilterCompat
|
||||||
|
import androidx.core.graphics.BlendModeCompat
|
||||||
|
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.KeyboardIconsSet
|
||||||
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
|
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.R
|
||||||
|
import helium314.keyboard.latin.databinding.ReorderDialogItemBinding
|
||||||
import helium314.keyboard.latin.settings.Settings
|
import helium314.keyboard.latin.settings.Settings
|
||||||
import helium314.keyboard.latin.utils.ToolbarKey.*
|
import helium314.keyboard.latin.utils.ToolbarKey.*
|
||||||
|
import kotlinx.serialization.encodeToString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
import java.util.EnumMap
|
import java.util.EnumMap
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
|
@ -31,7 +48,7 @@ fun createToolbarKey(context: Context, iconsSet: KeyboardIconsSet, key: ToolbarK
|
||||||
return button
|
return button
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCodeForToolbarKey(key: ToolbarKey) = when (key) {
|
fun getCodeForToolbarKey(key: ToolbarKey) = Settings.getInstance().getCustomToolbarKeyCode(key) ?: when (key) {
|
||||||
VOICE -> KeyCode.VOICE_INPUT
|
VOICE -> KeyCode.VOICE_INPUT
|
||||||
CLIPBOARD -> KeyCode.CLIPBOARD
|
CLIPBOARD -> KeyCode.CLIPBOARD
|
||||||
NUMPAD -> KeyCode.NUMPAD
|
NUMPAD -> KeyCode.NUMPAD
|
||||||
|
@ -63,7 +80,7 @@ fun getCodeForToolbarKey(key: ToolbarKey) = when (key) {
|
||||||
PAGE_END -> KeyCode.MOVE_END_OF_PAGE
|
PAGE_END -> KeyCode.MOVE_END_OF_PAGE
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCodeForToolbarKeyLongClick(key: ToolbarKey) = when (key) {
|
fun getCodeForToolbarKeyLongClick(key: ToolbarKey) = Settings.getInstance().getCustomToolbarLongpressCode(key) ?: when (key) {
|
||||||
CLIPBOARD -> KeyCode.CLIPBOARD_PASTE
|
CLIPBOARD -> KeyCode.CLIPBOARD_PASTE
|
||||||
UNDO -> KeyCode.REDO
|
UNDO -> KeyCode.REDO
|
||||||
REDO -> KeyCode.UNDO
|
REDO -> KeyCode.UNDO
|
||||||
|
@ -175,3 +192,109 @@ private fun getEnabledToolbarKeys(prefs: SharedPreferences, pref: String, defaul
|
||||||
} else null
|
} else null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 dialog = AlertDialog.Builder(context)
|
||||||
|
.setTitle(R.string.customize_toolbar_key_codes)
|
||||||
|
.setView(ScrollView(context).apply { addView(ll) })
|
||||||
|
.setPositiveButton(R.string.dialog_close, null)
|
||||||
|
.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 = DeviceProtectedUtils.getSharedPreferences(context)
|
||||||
|
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()
|
||||||
|
checkOk()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
layout.findViewById<EditText>(R.id.toolbar_key_longpress_code)?.apply {
|
||||||
|
setText(getCodeForToolbarKeyLongClick(key).toString())
|
||||||
|
doAfterTextChanged {
|
||||||
|
longpressCode = it?.toString()
|
||||||
|
checkOk()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun readCustomKeyCodes(prefs: SharedPreferences) = prefs.getString(Settings.PREF_TOOLBAR_CUSTOM_KEY_CODES, "")!!
|
||||||
|
.split(";").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, "")!!
|
||||||
|
.split(";").associate {
|
||||||
|
val code = runCatching { it.substringAfter(",").toIntOrNull()?.checkAndConvertCode() }.getOrNull()
|
||||||
|
it.substringBefore(",") to code
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun writeCustomKeyCodes(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_KEY_CODES, string).apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
private 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()
|
||||||
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
<ImageView
|
<ImageView
|
||||||
|
android:id="@+id/reorder_item_drag_indicator"
|
||||||
android:paddingEnd="10dp"
|
android:paddingEnd="10dp"
|
||||||
android:src="@drawable/ic_drag_indicator"
|
android:src="@drawable/ic_drag_indicator"
|
||||||
app:tint="@color/foreground_weak"
|
app:tint="@color/foreground_weak"
|
||||||
|
|
42
app/src/main/res/layout/toolbar_key_customizer.xml
Normal file
42
app/src/main/res/layout/toolbar_key_customizer.xml
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingHorizontal="10dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
style="@style/PreferenceTitleText"
|
||||||
|
android:text="@string/key_code" />
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/toolbar_key_code"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="number"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
style="@style/PreferenceTitleText"
|
||||||
|
android:text="@string/long_press_code" />
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/toolbar_key_longpress_code"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="number"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -881,6 +881,36 @@ New dictionary:
|
||||||
<string name="label_pause_key" tools:keep="@string/label_pause_key">Pause</string>
|
<string name="label_pause_key" tools:keep="@string/label_pause_key">Pause</string>
|
||||||
<!-- Label for "Wait" key of phone number keyboard. Must be short to fit on key. 5 chars or less is preferable. [CHAR LIMIT=7]-->
|
<!-- Label for "Wait" key of phone number keyboard. Must be short to fit on key. 5 chars or less is preferable. [CHAR LIMIT=7]-->
|
||||||
<string name="label_wait_key" tools:keep="@string/label_wait_key">Wait</string>
|
<string name="label_wait_key" tools:keep="@string/label_wait_key">Wait</string>
|
||||||
|
<!-- Label for enter key, currently used only for showing the icon name -->
|
||||||
|
<string name="label_enter_key" tools:keep="@string/label_enter_key">Enter</string>
|
||||||
|
<!-- Label for tabulator key, currently used only for showing the icon name -->
|
||||||
|
<string name="label_tab_key" tools:keep="@string/label_tab_key">Tab</string>
|
||||||
|
<!-- Label for delete key, currently used only for showing the icon name -->
|
||||||
|
<string name="label_delete_key" tools:keep="@string/label_delete_key">Delete</string>
|
||||||
|
<!-- Label for shift key, currently used only for showing the icon name -->
|
||||||
|
<string name="label_shift_key" tools:keep="@string/label_shift_key">Shift</string>
|
||||||
|
<!-- Label for shift key when active, currently used only for showing the icon name -->
|
||||||
|
<string name="label_shift_key_shifted" tools:keep="@string/label_shift_key_shifted">Shift (shifted)</string>
|
||||||
|
<!-- Label for shift key when locked (caps lock mode), currently used only for showing the icon name -->
|
||||||
|
<string name="label_shift_key_locked" tools:keep="@string/label_shift_key_locked">Caps lock</string>
|
||||||
|
<!-- Label for the short space key (in number layouts), currently used only for showing the icon name -->
|
||||||
|
<string name="label_space_key_for_number_layout" tools:keep="@string/label_space_key_for_number_layout">Space (number layout)</string>
|
||||||
|
<!-- Label for key to stop onehanded mode, currently used only for showing the icon name -->
|
||||||
|
<string name="label_stop_onehanded_mode_key" tools:keep="@string/label_stop_onehanded_mode_key">End one-handed mode</string>
|
||||||
|
<!-- Label for key to resize onehanded mode, currently used only for showing the icon name -->
|
||||||
|
<string name="label_resize_onehanded_key" tools:keep="@string/label_resize_onehanded_key">Resize one-handed mode</string>
|
||||||
|
<!-- Label for key to switch side of onehanded mode, currently used only for showing the icon name -->
|
||||||
|
<string name="label_switch_onehanded_key" tools:keep="@string/label_switch_onehanded_key">Switch one-handed mode side</string>
|
||||||
|
<!-- Label for voice key when disabled, currently used only for showing the icon name -->
|
||||||
|
<string name="label_shortcut_key_disabled" tools:keep="@string/label_shortcut_key_disabled">Voice input disabled</string>
|
||||||
|
<!-- Label for toolbar key, currently used only for showing the icon name -->
|
||||||
|
<string name="label_toolbar_key" tools:keep="@string/label_toolbar_key">Show / hide toolbar</string>
|
||||||
|
<!-- Label for language switch key, currently used only for showing the icon name -->
|
||||||
|
<string name="label_language_switch_key" tools:keep="@string/label_language_switch_key">@string/show_language_switch_key</string>
|
||||||
|
<!-- Label for zero-width joiner key, currently used only for showing the icon name -->
|
||||||
|
<string name="label_zwj_key" tools:keep="@string/label_zwj_key">Zero-width joiner</string>
|
||||||
|
<!-- Label for zero-width non-joiner key, currently used only for showing the icon name -->
|
||||||
|
<string name="label_zwnj_key" tools:keep="@string/label_zwnj_key">Zero-width non-joiner</string>
|
||||||
<!-- Title of the setting for horizontal spacebar swipe gesture -->
|
<!-- Title of the setting for horizontal spacebar swipe gesture -->
|
||||||
<string name="show_horizontal_space_swipe">Horizontal spacebar swipe gesture</string>
|
<string name="show_horizontal_space_swipe">Horizontal spacebar swipe gesture</string>
|
||||||
<!-- Title of the setting for vertical spacebar swipe gesture -->
|
<!-- Title of the setting for vertical spacebar swipe gesture -->
|
||||||
|
@ -895,6 +925,12 @@ New dictionary:
|
||||||
<string name="var_toolbar_direction">Variable toolbar direction</string>
|
<string name="var_toolbar_direction">Variable toolbar direction</string>
|
||||||
<!-- Description of the variable toolbar direction setting -->
|
<!-- Description of the variable toolbar direction setting -->
|
||||||
<string name="var_toolbar_direction_summary">Reverse direction when a right-to-left keyboard subtype is selected</string>
|
<string name="var_toolbar_direction_summary">Reverse direction when a right-to-left keyboard subtype is selected</string>
|
||||||
|
<!-- Title of the setting to customize toolbar key codes -->
|
||||||
|
<string name="customize_toolbar_key_codes">Customize toolbar key codes</string>
|
||||||
|
<!-- Text for showing / setting key code -->
|
||||||
|
<string name="key_code">Key code</string>
|
||||||
|
<!-- Text for showing / setting long press code -->
|
||||||
|
<string name="long_press_code">Long press code</string>
|
||||||
<!-- Title of the setting for showing the toolbar automatically -->
|
<!-- Title of the setting for showing the toolbar automatically -->
|
||||||
<string name="auto_show_toolbar">Auto show toolbar</string>
|
<string name="auto_show_toolbar">Auto show toolbar</string>
|
||||||
<!-- Description of the setting for showing the toolbar automatically -->
|
<!-- Description of the setting for showing the toolbar automatically -->
|
||||||
|
@ -905,4 +941,6 @@ New dictionary:
|
||||||
<string name="auto_hide_toolbar_summary">Hide the toolbar when suggestions become available</string>
|
<string name="auto_hide_toolbar_summary">Hide the toolbar when suggestions become available</string>
|
||||||
<!-- Toast message shown when content is copied to the clipboard -->
|
<!-- Toast message shown when content is copied to the clipboard -->
|
||||||
<string name="toast_msg_clipboard_copy">Content copied</string>
|
<string name="toast_msg_clipboard_copy">Content copied</string>
|
||||||
|
<!-- Title of the setting to customize icons for keyboard and toolbar keys -->
|
||||||
|
<string name="customize_icons">Customize icons</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -25,6 +25,10 @@
|
||||||
android:defaultValue="Material"
|
android:defaultValue="Material"
|
||||||
latin:singleLineTitle="false" />
|
latin:singleLineTitle="false" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="custom_icon_names"
|
||||||
|
android:title="@string/customize_icons" />
|
||||||
|
|
||||||
<ListPreference
|
<ListPreference
|
||||||
android:key="theme_colors"
|
android:key="theme_colors"
|
||||||
android:title="@string/theme_colors"
|
android:title="@string/theme_colors"
|
||||||
|
|
|
@ -21,6 +21,10 @@
|
||||||
android:key="clipboard_toolbar_keys"
|
android:key="clipboard_toolbar_keys"
|
||||||
android:title="@string/clipboard_toolbar_keys" />
|
android:title="@string/clipboard_toolbar_keys" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="customize_key_codes"
|
||||||
|
android:title="@string/customize_toolbar_key_codes" />
|
||||||
|
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:key="quick_pin_toolbar_keys"
|
android:key="quick_pin_toolbar_keys"
|
||||||
android:title="@string/quick_pin_toolbar_keys"
|
android:title="@string/quick_pin_toolbar_keys"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue