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>
|
||||
</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 ❤
|
||||
|
||||
|
|
|
@ -938,11 +938,12 @@ public class Key implements Comparable<Key> {
|
|||
final String iconName = getIconName();
|
||||
if (iconName == null) return false;
|
||||
// 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)
|
||||
|| iconName.equals(KeyboardIconsSet.NAME_PREVIOUS_KEY)
|
||||
|| iconName.equals(KeyboardIconsSet.NAME_CLIPBOARD_ACTION_KEY)
|
||||
|| iconName.equals(KeyboardIconsSet.NAME_EMOJI_ACTION_KEY);
|
||||
|| iconName.equals("clipboard_action_key")
|
||||
|| iconName.equals("emoji_action_key");
|
||||
}
|
||||
|
||||
public boolean hasFunctionalBackground() {
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.graphics.drawable.Drawable
|
|||
import androidx.core.content.ContextCompat
|
||||
import helium314.keyboard.keyboard.KeyboardTheme
|
||||
import helium314.keyboard.latin.R
|
||||
import helium314.keyboard.latin.customIconIds
|
||||
import helium314.keyboard.latin.settings.Settings
|
||||
import helium314.keyboard.latin.utils.DeviceProtectedUtils
|
||||
import helium314.keyboard.latin.utils.Log
|
||||
|
@ -13,17 +14,20 @@ import helium314.keyboard.latin.utils.ToolbarKey
|
|||
import java.util.Locale
|
||||
|
||||
class KeyboardIconsSet private constructor() {
|
||||
private var iconIds = emptyMap<String, Int>()
|
||||
var iconIds = emptyMap<String, Int>()
|
||||
private set
|
||||
private val iconsByName = HashMap<String, Drawable>(80)
|
||||
|
||||
fun loadIcons(context: Context) {
|
||||
val prefs = DeviceProtectedUtils.getSharedPreferences(context)
|
||||
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_ROUNDED -> keyboardIconsRounded
|
||||
else -> keyboardIconsMaterial
|
||||
}
|
||||
val overrideIds = customIconIds(context, prefs)
|
||||
val ids = if (overrideIds.isEmpty()) defaultIds else defaultIds + overrideIds
|
||||
if (ids == iconIds) return
|
||||
iconIds = ids
|
||||
iconsByName.clear()
|
||||
|
@ -38,13 +42,15 @@ class KeyboardIconsSet private constructor() {
|
|||
}
|
||||
}
|
||||
|
||||
fun getIconDrawable(name: String?): Drawable? = iconsByName[name?.lowercase(Locale.US)]
|
||||
/** gets drawable from resources, with mutate (might be necessary to avoid coloring issues...) */
|
||||
fun getNewDrawable(name: String?, context: Context): Drawable? =
|
||||
iconIds[name?.lowercase(Locale.US)]?.let { ContextCompat.getDrawable(context, it)?.mutate() }
|
||||
fun getIconDrawable(name: String?): Drawable? = name?.lowercase(Locale.US)?.let {
|
||||
iconsByName[it] ?: iconsByName[alternativeNames[it]]
|
||||
}
|
||||
|
||||
/** 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 {
|
||||
private val TAG = KeyboardIconsSet::class.simpleName
|
||||
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_LOCKED = "shift_key_locked"
|
||||
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_FOR_NUMBER_LAYOUT = "space_key_for_number_layout"
|
||||
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_PREVIOUS_KEY = "previous_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_LANGUAGE_SWITCH_KEY = "language_switch_key"
|
||||
const val NAME_ZWNJ_KEY = "zwnj_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_SWITCH_ONEHANDED_KEY = "switch_onehanded_key"
|
||||
const val NAME_RESIZE_ONEHANDED_KEY = "resize_onehanded_key"
|
||||
const val NAME_TOOLBAR_KEY = "toolbar_key"
|
||||
const val NAME_BIN = "bin"
|
||||
/*
|
||||
private val styleableIdByName = hashMapOf(
|
||||
NAME_SHIFT_KEY to R.styleable.Keyboard_iconShiftKey,
|
||||
NAME_DELETE_KEY to R.styleable.Keyboard_iconDeleteKey,
|
||||
NAME_SETTINGS_KEY to R.styleable.Keyboard_iconSettingsKey,
|
||||
NAME_SPACE_KEY to R.styleable.Keyboard_iconSpaceKey,
|
||||
NAME_ENTER_KEY to R.styleable.Keyboard_iconEnterKey,
|
||||
NAME_GO_KEY to R.styleable.Keyboard_iconGoKey,
|
||||
NAME_SEARCH_KEY to R.styleable.Keyboard_iconSearchKey,
|
||||
NAME_SEND_KEY to R.styleable.Keyboard_iconSendKey,
|
||||
NAME_NEXT_KEY to R.styleable.Keyboard_iconNextKey,
|
||||
NAME_DONE_KEY to R.styleable.Keyboard_iconDoneKey,
|
||||
NAME_PREVIOUS_KEY to R.styleable.Keyboard_iconPreviousKey,
|
||||
NAME_TAB_KEY to R.styleable.Keyboard_iconTabKey,
|
||||
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,
|
||||
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)) } }
|
||||
*/
|
||||
|
||||
// names used in the past, and we can't just delete them because they might still be in use in some layouts
|
||||
// (also some of them are in use for internal layouts, but there we could just remove them...)
|
||||
private val alternativeNames = hashMapOf(
|
||||
"clear_clipboard_key" to ToolbarKey.CLEAR_CLIPBOARD.name.lowercase(Locale.US),
|
||||
"shortcut_key" to ToolbarKey.VOICE.name.lowercase(Locale.US),
|
||||
"emoji_action_key" to ToolbarKey.EMOJI.name.lowercase(Locale.US),
|
||||
"emoji_normal_key" to ToolbarKey.EMOJI.name.lowercase(Locale.US),
|
||||
"clipboard_action_key" to ToolbarKey.CLIPBOARD.name.lowercase(Locale.US),
|
||||
"clipboard_normal_key" to ToolbarKey.CLIPBOARD.name.lowercase(Locale.US),
|
||||
"cut_key" to ToolbarKey.CUT.name.lowercase(Locale.US),
|
||||
"incognito_key" to ToolbarKey.INCOGNITO.name.lowercase(Locale.US),
|
||||
"settings_key" to ToolbarKey.SETTINGS.name.lowercase(Locale.US),
|
||||
"start_onehanded_mode_key" to ToolbarKey.ONE_HANDED.name.lowercase(Locale.US),
|
||||
)
|
||||
|
||||
// todo: incognito and force incognito should not be the same? or not the same as toolbar key?
|
||||
private val keyboardIconsHolo by lazy { hashMapOf(
|
||||
NAME_SHIFT_KEY to R.drawable.sym_keyboard_shift_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_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_ENTER_KEY to R.drawable.sym_keyboard_return_holo,
|
||||
// NAME_GO_KEY to null,
|
||||
|
@ -131,20 +109,11 @@ class KeyboardIconsSet private constructor() {
|
|||
// NAME_NEXT_KEY to null,
|
||||
// NAME_PREVIOUS_KEY to null,
|
||||
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_SHORTCUT_KEY to R.drawable.sym_keyboard_voice_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_ZWNJ_KEY to R.drawable.sym_keyboard_zwnj_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_SWITCH_ONEHANDED_KEY to R.drawable.ic_arrow_left,
|
||||
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_LOCKED to R.drawable.sym_keyboard_shift_lock_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_ENTER_KEY to R.drawable.sym_keyboard_return_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_PREVIOUS_KEY to R.drawable.ic_arrow_left,
|
||||
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_SHORTCUT_KEY to R.drawable.sym_keyboard_voice_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_ZWNJ_KEY to R.drawable.sym_keyboard_zwnj_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_SWITCH_ONEHANDED_KEY to R.drawable.ic_arrow_left,
|
||||
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_LOCKED to R.drawable.sym_keyboard_shift_lock_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_ENTER_KEY to R.drawable.sym_keyboard_return_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_PREVIOUS_KEY to R.drawable.ic_arrow_left_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_SHORTCUT_KEY to R.drawable.sym_keyboard_voice_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_ZWNJ_KEY to R.drawable.sym_keyboard_zwnj_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_SWITCH_ONEHANDED_KEY to R.drawable.ic_arrow_left_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()
|
||||
}
|
||||
}
|
||||
|
|
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.os.Build
|
||||
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.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.view.forEach
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.TwoStatePreference
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import helium314.keyboard.keyboard.KeyboardSwitcher
|
||||
import helium314.keyboard.keyboard.KeyboardTheme
|
||||
import helium314.keyboard.keyboard.internal.KeyboardIconsSet
|
||||
import helium314.keyboard.latin.R
|
||||
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.infoDialog
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
import java.lang.Float.max
|
||||
import java.lang.Float.min
|
||||
import java.util.*
|
||||
|
@ -73,6 +92,7 @@ class AppearanceSettingsFragment : SubScreenFragment() {
|
|||
}
|
||||
}
|
||||
findPreference<Preference>("custom_background_image")?.setOnPreferenceClickListener { onClickLoadImage() }
|
||||
findPreference<Preference>(Settings.PREF_CUSTOM_ICON_NAMES)?.setOnPreferenceClickListener { onClickCustomizeIcons() }
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
|
@ -179,6 +199,111 @@ class AppearanceSettingsFragment : SubScreenFragment() {
|
|||
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 {
|
||||
if (Settings.readDayNightPref(sharedPreferences, resources)) {
|
||||
AlertDialog.Builder(requireContext())
|
||||
|
|
|
@ -44,12 +44,15 @@ import helium314.keyboard.latin.utils.ResourceUtils;
|
|||
import helium314.keyboard.latin.utils.RunInLocaleKt;
|
||||
import helium314.keyboard.latin.utils.StatsUtils;
|
||||
import helium314.keyboard.latin.utils.SubtypeSettingsKt;
|
||||
import helium314.keyboard.latin.utils.ToolbarKey;
|
||||
import helium314.keyboard.latin.utils.ToolbarUtilsKt;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
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 {
|
||||
|
@ -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_AUTO_USER_COLOR_SUFFIX = "_auto";
|
||||
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_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
|
||||
private static Drawable sCachedBackgroundDay;
|
||||
private static Drawable sCachedBackgroundNight;
|
||||
private Map<String, Integer> mCustomToolbarKeyCodes = null;
|
||||
private Map<String, Integer> mCustomToolbarLongpressCodes = null;
|
||||
|
||||
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.");
|
||||
return;
|
||||
}
|
||||
mCustomToolbarLongpressCodes = null;
|
||||
mCustomToolbarKeyCodes = null;
|
||||
loadSettings(mContext, mSettingsValues.mLocale, mSettingsValues.mInputAttributes);
|
||||
StatsUtils.onLoadSettings(mSettingsValues);
|
||||
} finally {
|
||||
|
@ -706,4 +716,16 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
public String readCustomCurrencyKey() {
|
||||
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.defaultToolbarPref
|
||||
import helium314.keyboard.latin.utils.reorderDialog
|
||||
import helium314.keyboard.latin.utils.toolbarKeysCustomizer
|
||||
|
||||
class ToolbarSettingsFragment : SubScreenFragment() {
|
||||
private var reloadKeyboard = false
|
||||
|
@ -44,6 +45,11 @@ class ToolbarSettingsFragment : SubScreenFragment() {
|
|||
) { iconsSet.getNewDrawable(it, requireContext()) }
|
||||
true
|
||||
}
|
||||
findPreference<Preference>("customize_key_codes")?.onPreferenceClickListener =
|
||||
Preference.OnPreferenceClickListener {
|
||||
toolbarKeysCustomizer(requireContext())
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
|
|
|
@ -182,7 +182,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
|
|||
mMoreSuggestionsSlidingDetector = new GestureDetector(context, mMoreSuggestionsSlidingListener);
|
||||
|
||||
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);
|
||||
mBinIcon = iconsSet.getNewDrawable(KeyboardIconsSet.NAME_BIN, context);
|
||||
|
||||
|
|
|
@ -1,16 +1,33 @@
|
|||
// 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.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.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.Settings
|
||||
import helium314.keyboard.latin.utils.ToolbarKey.*
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
import java.util.EnumMap
|
||||
import java.util.Locale
|
||||
|
||||
|
@ -31,7 +48,7 @@ fun createToolbarKey(context: Context, iconsSet: KeyboardIconsSet, key: ToolbarK
|
|||
return button
|
||||
}
|
||||
|
||||
fun getCodeForToolbarKey(key: ToolbarKey) = when (key) {
|
||||
fun getCodeForToolbarKey(key: ToolbarKey) = Settings.getInstance().getCustomToolbarKeyCode(key) ?: when (key) {
|
||||
VOICE -> KeyCode.VOICE_INPUT
|
||||
CLIPBOARD -> KeyCode.CLIPBOARD
|
||||
NUMPAD -> KeyCode.NUMPAD
|
||||
|
@ -63,7 +80,7 @@ fun getCodeForToolbarKey(key: ToolbarKey) = when (key) {
|
|||
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
|
||||
UNDO -> KeyCode.REDO
|
||||
REDO -> KeyCode.UNDO
|
||||
|
@ -175,3 +192,109 @@ private fun getEnabledToolbarKeys(prefs: SharedPreferences, pref: String, defaul
|
|||
} 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_height="wrap_content" />
|
||||
<ImageView
|
||||
android:id="@+id/reorder_item_drag_indicator"
|
||||
android:paddingEnd="10dp"
|
||||
android:src="@drawable/ic_drag_indicator"
|
||||
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>
|
||||
<!-- 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>
|
||||
<!-- 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 -->
|
||||
<string name="show_horizontal_space_swipe">Horizontal spacebar swipe gesture</string>
|
||||
<!-- Title of the setting for vertical spacebar swipe gesture -->
|
||||
|
@ -895,6 +925,12 @@ New dictionary:
|
|||
<string name="var_toolbar_direction">Variable toolbar direction</string>
|
||||
<!-- 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>
|
||||
<!-- 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 -->
|
||||
<string name="auto_show_toolbar">Auto show toolbar</string>
|
||||
<!-- 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>
|
||||
<!-- Toast message shown when content is copied to the clipboard -->
|
||||
<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>
|
||||
|
|
|
@ -25,6 +25,10 @@
|
|||
android:defaultValue="Material"
|
||||
latin:singleLineTitle="false" />
|
||||
|
||||
<Preference
|
||||
android:key="custom_icon_names"
|
||||
android:title="@string/customize_icons" />
|
||||
|
||||
<ListPreference
|
||||
android:key="theme_colors"
|
||||
android:title="@string/theme_colors"
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
android:key="clipboard_toolbar_keys"
|
||||
android:title="@string/clipboard_toolbar_keys" />
|
||||
|
||||
<Preference
|
||||
android:key="customize_key_codes"
|
||||
android:title="@string/customize_toolbar_key_codes" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="quick_pin_toolbar_keys"
|
||||
android:title="@string/quick_pin_toolbar_keys"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue