mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-04-20 22:29:10 +00:00
allow adjusting popup order and label source
This commit is contained in:
parent
07f2c43e38
commit
7097fd8fae
19 changed files with 401 additions and 251 deletions
|
@ -17,8 +17,10 @@ import org.dslul.openboard.inputmethod.keyboard.internal.KeyVisualAttributes;
|
|||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardIconsSet;
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams;
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.MoreKeySpec;
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.floris.PopupSet;
|
||||
import org.dslul.openboard.inputmethod.latin.common.Constants;
|
||||
import org.dslul.openboard.inputmethod.latin.common.StringUtils;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.MoreKeysUtilsKt;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
@ -1047,9 +1049,9 @@ public class Key implements Comparable<Key> {
|
|||
final float relativeWidth,
|
||||
final int labelFlags,
|
||||
final int backgroundType,
|
||||
@Nullable final String[] layoutMoreKeys
|
||||
@Nullable final PopupSet<?> popupSet
|
||||
) {
|
||||
this(keySpec, KeySpecParser.getCode(keySpec), params, relativeWidth, labelFlags, backgroundType, layoutMoreKeys);
|
||||
this(keySpec, KeySpecParser.getCode(keySpec), params, relativeWidth, labelFlags, backgroundType, popupSet);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1064,7 +1066,7 @@ public class Key implements Comparable<Key> {
|
|||
final float relativeWidth,
|
||||
final int labelFlags,
|
||||
final int backgroundType,
|
||||
@Nullable final String[] layoutMoreKeys // same style as current moreKeys (relevant for the special keys)
|
||||
@Nullable final PopupSet<?> popupSet
|
||||
) {
|
||||
mKeyboardParams = params;
|
||||
mBackgroundType = backgroundType;
|
||||
|
@ -1079,15 +1081,9 @@ public class Key implements Comparable<Key> {
|
|||
if (params.mId.isNumberLayout())
|
||||
actionFlags = ACTION_FLAGS_NO_KEY_PREVIEW;
|
||||
|
||||
final String[] languageMoreKeys = params.mLocaleKeyTexts.getMoreKeys(keySpec);
|
||||
if (languageMoreKeys != null && layoutMoreKeys != null && languageMoreKeys[0].startsWith("!fixedColumnOrder!"))
|
||||
languageMoreKeys[0] = null; // we change the number of keys, so better not use fixedColumnOrder to avoid awkward layout
|
||||
// todo: after removing old parser this could be done in a less awkward way without almostFinalMoreKeys
|
||||
final String[] almostFinalMoreKeys = MoreKeySpec.insertAdditionalMoreKeys(languageMoreKeys, layoutMoreKeys);
|
||||
mMoreKeysColumnAndFlags = getMoreKeysColumnAndFlagsAndSetNullInArray(params, almostFinalMoreKeys);
|
||||
final String[] finalMoreKeys = almostFinalMoreKeys == null
|
||||
? null
|
||||
: MoreKeySpec.filterOutEmptyString(almostFinalMoreKeys);
|
||||
final String[] moreKeys = MoreKeysUtilsKt.createMoreKeysArray(popupSet, mKeyboardParams, keySpec);
|
||||
mMoreKeysColumnAndFlags = getMoreKeysColumnAndFlagsAndSetNullInArray(params, moreKeys);
|
||||
final String[] finalMoreKeys = moreKeys == null ? null : MoreKeySpec.filterOutEmptyString(moreKeys);
|
||||
|
||||
if (finalMoreKeys != null) {
|
||||
actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS;
|
||||
|
@ -1116,18 +1112,8 @@ public class Key implements Comparable<Key> {
|
|||
mHintLabel = null;
|
||||
} else {
|
||||
// maybe also always null for comma and period keys
|
||||
String hintLabel;
|
||||
if (mKeyboardParams.mHintLabelFromFirstMoreKey) {
|
||||
hintLabel = mMoreKeys == null ? null : mMoreKeys[0].mLabel;
|
||||
if (hintLabel != null && backgroundType == BACKGROUND_TYPE_FUNCTIONAL && mKeyboardParams.mId.isAlphabetKeyboard())
|
||||
// bad workaround for the ugly comma label on period key, todo: do it better when re-working moreKey stuff
|
||||
hintLabel = null;
|
||||
} else {
|
||||
hintLabel = layoutMoreKeys == null ? null : KeySpecParser.getLabel(layoutMoreKeys[0]); // note that some entries may have been changed to other string or null
|
||||
// todo: this should be adjusted when re-working moreKey stuff... also KeySpecParser.getLabel may throw, which is bad when users do uncommon things
|
||||
if (hintLabel != null && hintLabel.length() > 1 && hintLabel.startsWith("!")) // this is not great, but other than removing com key label this is definitely ok
|
||||
hintLabel = null;
|
||||
}
|
||||
// todo: maybe remove mKeyboardParams.mHintLabelFromFirstMoreKey?
|
||||
final String hintLabel = MoreKeysUtilsKt.getHintLabel(popupSet, params, keySpec);
|
||||
mHintLabel = needsToUpcase
|
||||
? StringUtils.toTitleCaseOfKeyLabel(hintLabel, localeForUpcasing)
|
||||
: hintLabel;
|
||||
|
|
|
@ -49,18 +49,10 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
|||
|
||||
// todo: further plan
|
||||
// after the old parser is removed
|
||||
// finally the spanish/german/swiss/nordic layouts can be removed and replaced by some hasExtraKeys parameter
|
||||
// still they should keep their name though... or switch to sth like "default"?
|
||||
// also the "eo" check could then be removed
|
||||
// and maybe the language -> layout thing could be moved to assets? and maybe even here the extra keys could be defined...
|
||||
// maybe the language -> layout thing could be moved to assets? and maybe even here the extra keys could be defined...
|
||||
// should be either both in method.xml, or both in assets (actually method might be more suitable)
|
||||
// go through a lot of todos in parsers, key, keyboardlayoutset, ... as a lot of things should only change after old parser is removed
|
||||
// also remove the keybpard_layout_set files?
|
||||
// they are still in use e.g. for enableProximityCharsCorrection and supportedScript
|
||||
// but ideally this should be replaced
|
||||
// enableProximityCharsCorrection should be in LayoutInfos
|
||||
// supportedScript could be determined using ScriptUtils, but first make sure that there is less latin fallback happening
|
||||
// or use locale to store script, but that's only possible starting at api 21
|
||||
// also remove the keyboard_layout_set files?
|
||||
// allow users to define their own layouts (maybe do everything else first?)
|
||||
// need to solve the scaling issue with number row and 5 row keyboards
|
||||
// write up how things work for users, also regarding language more keys
|
||||
|
@ -125,7 +117,10 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
|||
keysInRows = EmojiParser(mParams, mContext).parse()
|
||||
} else {
|
||||
try {
|
||||
addLocaleKeyTextsToParams(mContext, mParams, Settings.getInstance().current.mShowMoreKeys)
|
||||
val sv = Settings.getInstance().current
|
||||
addLocaleKeyTextsToParams(mContext, mParams, sv.mShowMoreMoreKeys)
|
||||
mParams.mMoreKeyTypes.addAll(sv.mMoreKeyTypes)
|
||||
mParams.mMoreKeyLabelSources.addAll(sv.mMoreKeyLabelSources)
|
||||
keysInRows = KeyboardParser.parseFromAssets(mParams, mContext)
|
||||
determineAbsoluteValues()
|
||||
} catch (e: Exception) {
|
||||
|
|
|
@ -81,11 +81,12 @@ public class KeyboardParams {
|
|||
public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet();
|
||||
@NonNull // todo: not good, this only works because params are currently always created for the active subtype
|
||||
public final List<Locale> mSecondaryLocales = Settings.getInstance().getCurrent().mSecondaryLocales;
|
||||
public final ArrayList<String> mMoreKeyTypes = new ArrayList<>();
|
||||
public final ArrayList<String> mMoreKeyLabelSources = new ArrayList<>();
|
||||
|
||||
@NonNull
|
||||
private final UniqueKeysCache mUniqueKeysCache;
|
||||
public boolean mAllowRedundantMoreKeys;
|
||||
public final boolean mHintLabelFromFirstMoreKey = Settings.getInstance().getCurrent().mHintLabelFromFirstMoreKey;
|
||||
@NonNull
|
||||
public LocaleKeyTexts mLocaleKeyTexts;
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardIconsSet
|
|||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.floris.KeyData
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.floris.KeyType
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.floris.SimplePopups
|
||||
import org.dslul.openboard.inputmethod.latin.R
|
||||
import org.dslul.openboard.inputmethod.latin.common.Constants
|
||||
import org.dslul.openboard.inputmethod.latin.common.splitOnWhitespace
|
||||
|
@ -335,7 +336,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
|||
"period" -> adjustedKeys?.last()
|
||||
else -> null
|
||||
}
|
||||
val keyParams = getFunctionalKeyParams(it, adjustKey?.label, adjustKey?.popup?.toMoreKeys(params))
|
||||
val keyParams = getFunctionalKeyParams(it, adjustKey?.label, adjustKey?.popup?.getPopupKeyLabels(params))
|
||||
if (key == "space") { // add the extra keys around space
|
||||
if (params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS) {
|
||||
bottomRow.add(getFunctionalKeyParams(FunctionalKey.NUMPAD))
|
||||
|
@ -346,7 +347,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
|||
params.mDefaultRelativeKeyWidth,
|
||||
defaultLabelFlags,
|
||||
Key.BACKGROUND_TYPE_FUNCTIONAL,
|
||||
adjustedKeys?.get(1)?.popup?.toMoreKeys(params)
|
||||
adjustedKeys?.get(1)?.popup
|
||||
))
|
||||
} else if (params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED) {
|
||||
bottomRow.add(KeyParams(
|
||||
|
@ -355,7 +356,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
|||
params.mDefaultRelativeKeyWidth,
|
||||
defaultLabelFlags or Key.LABEL_FLAGS_HAS_POPUP_HINT,
|
||||
Key.BACKGROUND_TYPE_FUNCTIONAL,
|
||||
adjustedKeys?.get(1)?.popup?.toMoreKeys(params) ?: arrayOf("!fixedColumnOrder!3", "‹", "≤", "«")
|
||||
adjustedKeys?.get(1)?.popup ?: SimplePopups(listOf("!fixedColumnOrder!3", "‹", "≤", "«"))
|
||||
))
|
||||
bottomRow.add(keyParams)
|
||||
bottomRow.add(KeyParams(
|
||||
|
@ -364,7 +365,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
|||
params.mDefaultRelativeKeyWidth,
|
||||
defaultLabelFlags or Key.LABEL_FLAGS_HAS_POPUP_HINT,
|
||||
Key.BACKGROUND_TYPE_FUNCTIONAL,
|
||||
adjustedKeys?.get(2)?.popup?.toMoreKeys(params) ?: arrayOf("!fixedColumnOrder!3", "›", "≥", "»")
|
||||
adjustedKeys?.get(2)?.popup ?: SimplePopups(listOf("!fixedColumnOrder!3", "›", "≥", "»"))
|
||||
))
|
||||
} else { // alphabet
|
||||
if (params.mId.mLanguageSwitchKeyEnabled)
|
||||
|
@ -390,7 +391,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
|||
it.toKeyParams(params, additionalLabelFlags = Key.LABEL_FLAGS_DISABLE_HINT_LABEL or defaultLabelFlags)
|
||||
}
|
||||
|
||||
private fun getFunctionalKeyParams(def: String, label: String? = null, moreKeys: Array<String>? = null): KeyParams {
|
||||
private fun getFunctionalKeyParams(def: String, label: String? = null, moreKeys: Collection<String>? = null): KeyParams {
|
||||
val split = def.trim().splitOnWhitespace()
|
||||
val key = FunctionalKey.valueOf(split[0].uppercase())
|
||||
val width = if (split.size == 2) split[1].substringBefore("%").toFloat() / 100f
|
||||
|
@ -398,7 +399,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
|||
return getFunctionalKeyParams(key, width, label, moreKeys)
|
||||
}
|
||||
|
||||
private fun getFunctionalKeyParams(key: FunctionalKey, relativeWidth: Float? = null, label: String? = null, moreKeys: Array<String>? = null): KeyParams {
|
||||
private fun getFunctionalKeyParams(key: FunctionalKey, relativeWidth: Float? = null, label: String? = null, moreKeys: Collection<String>? = null): KeyParams {
|
||||
// for comma and period: label will override default, moreKeys will be appended
|
||||
val width = relativeWidth ?: params.mDefaultRelativeKeyWidth
|
||||
return when (key) {
|
||||
|
@ -427,7 +428,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
|||
Key.LABEL_FLAGS_HAS_POPUP_HINT, // previously only if normal comma, but always is more correct
|
||||
if (label?.first()?.isLetter() == true) Key.BACKGROUND_TYPE_NORMAL // mimic behavior of old dvorak and halmak layouts
|
||||
else Key.BACKGROUND_TYPE_FUNCTIONAL,
|
||||
moreKeys?.let { getCommaMoreKeys() + it } ?: getCommaMoreKeys()
|
||||
SimplePopups(moreKeys?.let { getCommaMoreKeys() + it } ?: getCommaMoreKeys())
|
||||
)
|
||||
FunctionalKey.PERIOD -> KeyParams(
|
||||
// special period moreKey only in alphabet layout, except for ar and fa
|
||||
|
@ -441,7 +442,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
|||
or defaultLabelFlags,
|
||||
if (label?.first()?.isLetter() == true) Key.BACKGROUND_TYPE_NORMAL
|
||||
else Key.BACKGROUND_TYPE_FUNCTIONAL,
|
||||
moreKeys?.let { getPunctuationMoreKeys() + it } ?: getPunctuationMoreKeys()
|
||||
SimplePopups(moreKeys?.let { getPunctuationMoreKeys() + it } ?: getPunctuationMoreKeys())
|
||||
)
|
||||
FunctionalKey.SPACE -> KeyParams(
|
||||
getSpaceLabel(),
|
||||
|
@ -462,7 +463,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
|||
or Key.LABEL_FLAGS_HAS_POPUP_HINT
|
||||
or KeyboardTheme.getThemeActionAndEmojiKeyLabelFlags(params.mThemeId),
|
||||
Key.BACKGROUND_TYPE_ACTION,
|
||||
getActionKeyMoreKeys()
|
||||
getActionKeyMoreKeys()?.let { SimplePopups(it) }
|
||||
)
|
||||
FunctionalKey.DELETE -> KeyParams(
|
||||
"!icon/delete_key|!code/key_delete",
|
||||
|
@ -481,7 +482,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
|||
if (params.mId.mElementId == KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED || params.mId.mElementId == KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED)
|
||||
Key.BACKGROUND_TYPE_STICKY_ON
|
||||
else Key.BACKGROUND_TYPE_STICKY_OFF,
|
||||
if (params.mId.isAlphabetKeyboard) arrayOf("!noPanelAutoMoreKey!", " |!code/key_capslock") else null // why the alphabe morekeys actually?
|
||||
if (params.mId.isAlphabetKeyboard) SimplePopups(listOf("!noPanelAutoMoreKey!", " |!code/key_capslock")) else null // why the alphabet morekeys actually?
|
||||
)
|
||||
FunctionalKey.EMOJI -> KeyParams(
|
||||
"!icon/emoji_normal_key|!code/key_emoji",
|
||||
|
@ -503,7 +504,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
|||
width,
|
||||
Key.LABEL_FLAGS_AUTO_X_SCALE or Key.LABEL_FLAGS_FONT_NORMAL or Key.LABEL_FLAGS_HAS_POPUP_HINT or Key.LABEL_FLAGS_PRESERVE_CASE,
|
||||
Key.BACKGROUND_TYPE_FUNCTIONAL,
|
||||
arrayOf(Key.MORE_KEYS_HAS_LABELS, ".net", ".org", ".gov", ".edu")
|
||||
SimplePopups(listOf(Key.MORE_KEYS_HAS_LABELS, ".net", ".org", ".gov", ".edu"))
|
||||
)
|
||||
FunctionalKey.LANGUAGE_SWITCH -> KeyParams(
|
||||
"!icon/language_switch_key|!code/key_language_switch",
|
||||
|
@ -528,7 +529,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
|||
Key.LABEL_FLAGS_HAS_POPUP_HINT,
|
||||
// this may not be a good place to make this choice, but probably it's fine (though reading from settings here is not good)
|
||||
if (Settings.getInstance().current.mColors.hasKeyBorders) Key.BACKGROUND_TYPE_SPACEBAR else Key.BACKGROUND_TYPE_NORMAL,
|
||||
arrayOf("!icon/zwj_key|\u200D")
|
||||
SimplePopups(listOf("!icon/zwj_key|\u200D"))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -558,44 +559,44 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
|||
"!code/key_shift_enter"
|
||||
else "!code/key_enter"
|
||||
|
||||
private fun getActionKeyMoreKeys(): Array<String>? {
|
||||
private fun getActionKeyMoreKeys(): Collection<String>? {
|
||||
val action = params.mId.imeAction()
|
||||
val navigatePrev = params.mId.navigatePrevious()
|
||||
val navigateNext = params.mId.navigateNext()
|
||||
return when {
|
||||
params.mId.passwordInput() -> when {
|
||||
navigatePrev && action == EditorInfo.IME_ACTION_NEXT -> createMoreKeysArray(MORE_KEYS_NAVIGATE_PREVIOUS)
|
||||
navigatePrev && action == EditorInfo.IME_ACTION_NEXT -> createMoreKeys(MORE_KEYS_NAVIGATE_PREVIOUS)
|
||||
action == EditorInfo.IME_ACTION_NEXT -> null
|
||||
navigateNext && action == EditorInfo.IME_ACTION_PREVIOUS -> createMoreKeysArray(MORE_KEYS_NAVIGATE_NEXT)
|
||||
navigateNext && action == EditorInfo.IME_ACTION_PREVIOUS -> createMoreKeys(MORE_KEYS_NAVIGATE_NEXT)
|
||||
action == EditorInfo.IME_ACTION_PREVIOUS -> null
|
||||
navigateNext && navigatePrev -> createMoreKeysArray(MORE_KEYS_NAVIGATE_PREVIOUS_NEXT)
|
||||
navigateNext -> createMoreKeysArray(MORE_KEYS_NAVIGATE_NEXT)
|
||||
navigatePrev -> createMoreKeysArray(MORE_KEYS_NAVIGATE_PREVIOUS)
|
||||
navigateNext && navigatePrev -> createMoreKeys(MORE_KEYS_NAVIGATE_PREVIOUS_NEXT)
|
||||
navigateNext -> createMoreKeys(MORE_KEYS_NAVIGATE_NEXT)
|
||||
navigatePrev -> createMoreKeys(MORE_KEYS_NAVIGATE_PREVIOUS)
|
||||
else -> null
|
||||
}
|
||||
// could change definition of numbers to query a range, or have a pre-defined list, but not that crucial
|
||||
params.mId.isNumberLayout || params.mId.mMode in listOf(KeyboardId.MODE_EMAIL, KeyboardId.MODE_DATE, KeyboardId.MODE_TIME, KeyboardId.MODE_DATETIME) -> when {
|
||||
action == EditorInfo.IME_ACTION_NEXT && navigatePrev -> createMoreKeysArray(MORE_KEYS_NAVIGATE_PREVIOUS)
|
||||
action == EditorInfo.IME_ACTION_NEXT && navigatePrev -> createMoreKeys(MORE_KEYS_NAVIGATE_PREVIOUS)
|
||||
action == EditorInfo.IME_ACTION_NEXT -> null
|
||||
action == EditorInfo.IME_ACTION_PREVIOUS && navigateNext -> createMoreKeysArray(MORE_KEYS_NAVIGATE_NEXT)
|
||||
action == EditorInfo.IME_ACTION_PREVIOUS && navigateNext -> createMoreKeys(MORE_KEYS_NAVIGATE_NEXT)
|
||||
action == EditorInfo.IME_ACTION_PREVIOUS -> null
|
||||
navigateNext && navigatePrev -> createMoreKeysArray(MORE_KEYS_NAVIGATE_PREVIOUS_NEXT)
|
||||
navigateNext -> createMoreKeysArray(MORE_KEYS_NAVIGATE_NEXT)
|
||||
navigatePrev -> createMoreKeysArray(MORE_KEYS_NAVIGATE_PREVIOUS)
|
||||
navigateNext && navigatePrev -> createMoreKeys(MORE_KEYS_NAVIGATE_PREVIOUS_NEXT)
|
||||
navigateNext -> createMoreKeys(MORE_KEYS_NAVIGATE_NEXT)
|
||||
navigatePrev -> createMoreKeys(MORE_KEYS_NAVIGATE_PREVIOUS)
|
||||
else -> null
|
||||
}
|
||||
action == EditorInfo.IME_ACTION_NEXT && navigatePrev -> createMoreKeysArray(MORE_KEYS_NAVIGATE_EMOJI_PREVIOUS)
|
||||
action == EditorInfo.IME_ACTION_NEXT -> createMoreKeysArray(MORE_KEYS_NAVIGATE_EMOJI)
|
||||
action == EditorInfo.IME_ACTION_PREVIOUS && navigateNext -> createMoreKeysArray(MORE_KEYS_NAVIGATE_EMOJI_NEXT)
|
||||
action == EditorInfo.IME_ACTION_PREVIOUS -> createMoreKeysArray(MORE_KEYS_NAVIGATE_EMOJI)
|
||||
navigateNext && navigatePrev -> createMoreKeysArray(MORE_KEYS_NAVIGATE_EMOJI_PREVIOUS_NEXT)
|
||||
navigateNext -> createMoreKeysArray(MORE_KEYS_NAVIGATE_EMOJI_NEXT)
|
||||
navigatePrev -> createMoreKeysArray(MORE_KEYS_NAVIGATE_EMOJI_PREVIOUS)
|
||||
else -> createMoreKeysArray(MORE_KEYS_NAVIGATE_EMOJI)
|
||||
action == EditorInfo.IME_ACTION_NEXT && navigatePrev -> createMoreKeys(MORE_KEYS_NAVIGATE_EMOJI_PREVIOUS)
|
||||
action == EditorInfo.IME_ACTION_NEXT -> createMoreKeys(MORE_KEYS_NAVIGATE_EMOJI)
|
||||
action == EditorInfo.IME_ACTION_PREVIOUS && navigateNext -> createMoreKeys(MORE_KEYS_NAVIGATE_EMOJI_NEXT)
|
||||
action == EditorInfo.IME_ACTION_PREVIOUS -> createMoreKeys(MORE_KEYS_NAVIGATE_EMOJI)
|
||||
navigateNext && navigatePrev -> createMoreKeys(MORE_KEYS_NAVIGATE_EMOJI_PREVIOUS_NEXT)
|
||||
navigateNext -> createMoreKeys(MORE_KEYS_NAVIGATE_EMOJI_NEXT)
|
||||
navigatePrev -> createMoreKeys(MORE_KEYS_NAVIGATE_EMOJI_PREVIOUS)
|
||||
else -> createMoreKeys(MORE_KEYS_NAVIGATE_EMOJI)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createMoreKeysArray(moreKeysDef: String): Array<String> {
|
||||
private fun createMoreKeys(moreKeysDef: String): List<String> {
|
||||
val moreKeys = mutableListOf<String>()
|
||||
for (moreKey in moreKeysDef.split(",")) {
|
||||
val iconPrefixRemoved = moreKey.substringAfter("!icon/")
|
||||
|
@ -615,15 +616,14 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
|||
// remove emoji shortcut on enter in tablet mode (like original, because bottom row always has an emoji key)
|
||||
// (probably not necessary, but whatever)
|
||||
if (isTablet() && moreKeys.remove("!icon/emoji_action_key|!code/key_emoji")) {
|
||||
val i = moreKeys.indexOfFirst { it.startsWith("!fixedColumnOrder") }
|
||||
val i = moreKeys.indexOfFirst { it.startsWith(Key.MORE_KEYS_FIXED_COLUMN_ORDER) }
|
||||
if (i > -1) {
|
||||
val n = moreKeys[i].substringAfter("!fixedColumnOrder!").toIntOrNull()
|
||||
val n = moreKeys[i].substringAfter(Key.MORE_KEYS_FIXED_COLUMN_ORDER).toIntOrNull()
|
||||
if (n != null)
|
||||
moreKeys[i] = moreKeys[i].replace(n.toString(), (n - 1).toString())
|
||||
}
|
||||
// remove emoji on enter, because tablet layout has a separate emoji key
|
||||
}
|
||||
return moreKeys.toTypedArray()
|
||||
return moreKeys
|
||||
}
|
||||
|
||||
private fun String.replaceIconWithLabelIfNoDrawable(): String {
|
||||
|
@ -705,7 +705,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
|||
return params.mLocaleKeyTexts.labelComma
|
||||
}
|
||||
|
||||
private fun getCommaMoreKeys(): Array<String> {
|
||||
private fun getCommaMoreKeys(): List<String> {
|
||||
val keys = mutableListOf<String>()
|
||||
if (!params.mId.mDeviceLocked)
|
||||
keys.add("!icon/clipboard_normal_key|!code/key_clipboard")
|
||||
|
@ -717,14 +717,14 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
|||
keys.add("!icon/start_onehanded_mode_key|!code/key_start_onehanded")
|
||||
if (!params.mId.mDeviceLocked)
|
||||
keys.add("!icon/settings_key|!code/key_settings")
|
||||
return keys.toTypedArray()
|
||||
return keys
|
||||
}
|
||||
|
||||
private fun getPunctuationMoreKeys(): Array<String> {
|
||||
private fun getPunctuationMoreKeys(): List<String> {
|
||||
if (params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS || params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED)
|
||||
return arrayOf("…")
|
||||
return listOf("…")
|
||||
if (params.mId.isNumberLayout)
|
||||
return arrayOf(":", "…", ";", "∞", "π", "√", "°", "^")
|
||||
return listOf(":", "…", ";", "∞", "π", "√", "°", "^")
|
||||
val moreKeys = params.mLocaleKeyTexts.getMoreKeys("punctuation")!!
|
||||
if (params.mId.mSubtype.isRtlSubtype) {
|
||||
for (i in moreKeys.indices)
|
||||
|
@ -739,7 +739,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
|||
if (columns != null)
|
||||
moreKeys[0] = "${Key.MORE_KEYS_AUTO_COLUMN_ORDER}${columns - 1}"
|
||||
}
|
||||
return moreKeys
|
||||
return moreKeys.toList()
|
||||
}
|
||||
|
||||
private fun getSpaceLabel(): String =
|
||||
|
|
|
@ -15,7 +15,8 @@ import java.util.Locale
|
|||
import kotlin.math.round
|
||||
|
||||
class LocaleKeyTexts(dataStream: InputStream?, locale: Locale) {
|
||||
private val moreKeys = hashMapOf<String, Array<String>>()
|
||||
private val moreKeys = hashMapOf<String, Array<String>>() // todo: no need for arrays any more, better use a list?
|
||||
private val priorityMoreKeys = hashMapOf<String, Array<String>>()
|
||||
private val extraKeys = Array<MutableList<KeyData>?>(5) { null }
|
||||
var labelSymbol = "\\?123"
|
||||
private set
|
||||
|
@ -95,8 +96,8 @@ class LocaleKeyTexts(dataStream: InputStream?, locale: Locale) {
|
|||
|
||||
fun getShiftSymbolLabel(isTablet: Boolean) = if (isTablet) labelShiftSymbolTablet else labelShiftSymbol
|
||||
|
||||
// need tp provide a copy because some functions like MoreKeySpec.insertAdditionalMoreKeys may modify the array
|
||||
fun getMoreKeys(label: String): Array<String>? = moreKeys[label]?.copyOf()
|
||||
fun getMoreKeys(label: String): Array<String>? = moreKeys[label]
|
||||
fun getPriorityMoreKeys(label: String): Array<String>? = priorityMoreKeys[label]
|
||||
|
||||
// used by simple parser only, but could be possible for json as well (if necessary)
|
||||
fun getExtraKeys(row: Int): List<KeyData>? =
|
||||
|
@ -115,6 +116,18 @@ class LocaleKeyTexts(dataStream: InputStream?, locale: Locale) {
|
|||
else line.splitOnWhitespace()
|
||||
if (split.size == 1) return
|
||||
val key = split.first()
|
||||
val priorityMarkerIndex = split.indexOf("%")
|
||||
if (priorityMarkerIndex > 0) {
|
||||
val existingPriorityMoreKeys = priorityMoreKeys[key]
|
||||
priorityMoreKeys[key] = if (existingPriorityMoreKeys == null)
|
||||
Array(priorityMarkerIndex - 1) { split[it + 1] }
|
||||
else existingPriorityMoreKeys + split.subList(1, priorityMarkerIndex)
|
||||
val existingMoreKeys = moreKeys[key]
|
||||
moreKeys[key] = if (existingMoreKeys == null)
|
||||
Array(split.size - priorityMarkerIndex - 1) { split[it + priorityMarkerIndex + 1] }
|
||||
else existingMoreKeys + split.subList(priorityMarkerIndex, split.size)
|
||||
} else {
|
||||
// a but more special treatment, this should not occur together with priority marker (but technically could)
|
||||
val existingMoreKeys = moreKeys[key]
|
||||
val newMoreKeys = if (existingMoreKeys == null)
|
||||
Array(split.size - 1) { split[it + 1] }
|
||||
|
@ -124,6 +137,7 @@ class LocaleKeyTexts(dataStream: InputStream?, locale: Locale) {
|
|||
else -> newMoreKeys
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun addExtraKey(split: List<String>) {
|
||||
if (split.size < 2) return
|
||||
|
@ -183,33 +197,8 @@ class LocaleKeyTexts(dataStream: InputStream?, locale: Locale) {
|
|||
}
|
||||
|
||||
private fun mergeMoreKeys(original: Array<String>, added: List<String>): Array<String> {
|
||||
val markerIndexInOriginal = original.indexOf("%")
|
||||
val markerIndexInAddedIndex = added.indexOf("%")
|
||||
val moreKeys = mutableSetOf<String>()
|
||||
if (markerIndexInOriginal != -1 && markerIndexInAddedIndex != -1) {
|
||||
// add original and then added until %
|
||||
original.forEachIndexed { index, s -> if (index < markerIndexInOriginal) moreKeys.add(s) }
|
||||
added.forEachIndexed { index, s -> if (index < markerIndexInAddedIndex) moreKeys.add(s) }
|
||||
// add % and remaining moreKeys
|
||||
original.forEachIndexed { index, s -> if (index >= markerIndexInOriginal) moreKeys.add(s) }
|
||||
added.forEachIndexed { index, s -> if (index > markerIndexInAddedIndex) moreKeys.add(s) }
|
||||
} else if (markerIndexInOriginal != -1) {
|
||||
// add original until %, then added, then remaining original
|
||||
original.forEachIndexed { index, s -> if (index <= markerIndexInOriginal) moreKeys.add(s) }
|
||||
moreKeys.addAll(added)
|
||||
original.forEachIndexed { index, s -> if (index > markerIndexInOriginal) moreKeys.add(s) }
|
||||
} else if (markerIndexInAddedIndex != -1) {
|
||||
// add added until %, then original, then remaining added
|
||||
added.forEachIndexed { index, s -> if (index <= markerIndexInAddedIndex) moreKeys.add(s) }
|
||||
moreKeys.addAll(original)
|
||||
added.forEachIndexed { index, s -> if (index > markerIndexInAddedIndex) moreKeys.add(s) }
|
||||
} else {
|
||||
// use original, then added
|
||||
moreKeys.addAll(original)
|
||||
moreKeys.addAll(added)
|
||||
}
|
||||
// in fact this is only special treatment for the punctuation moreKeys
|
||||
if (moreKeys.any { it.startsWith(Key.MORE_KEYS_AUTO_COLUMN_ORDER) }) {
|
||||
if (original.any { it.startsWith(Key.MORE_KEYS_AUTO_COLUMN_ORDER) } || added.any { it.startsWith(Key.MORE_KEYS_AUTO_COLUMN_ORDER) }) {
|
||||
val moreKeys = (original + added).toSet()
|
||||
val originalColumnCount = original.firstOrNull { it.startsWith(Key.MORE_KEYS_AUTO_COLUMN_ORDER) }
|
||||
?.substringAfter(Key.MORE_KEYS_AUTO_COLUMN_ORDER)?.toIntOrNull()
|
||||
val l = moreKeys.filterNot { it.startsWith(Key.MORE_KEYS_AUTO_COLUMN_ORDER) }
|
||||
|
@ -221,15 +210,15 @@ private fun mergeMoreKeys(original: Array<String>, added: List<String>): Array<S
|
|||
// just drop autoColumnOrder otherwise
|
||||
return l.toTypedArray()
|
||||
}
|
||||
return moreKeys.toTypedArray()
|
||||
return original + added
|
||||
}
|
||||
|
||||
private fun addFixedColumnOrder(moreKeys: Array<String>): Array<String> {
|
||||
if (moreKeys.none { it.startsWith("!fixedColumnOrder") })
|
||||
return arrayOf("!fixedColumnOrder!${moreKeys.size}", *moreKeys)
|
||||
val newMoreKeys = moreKeys.filterNot { it.startsWith("!fixedColumnOrder") }
|
||||
if (moreKeys.none { it.startsWith(Key.MORE_KEYS_FIXED_COLUMN_ORDER) })
|
||||
return arrayOf("${Key.MORE_KEYS_FIXED_COLUMN_ORDER}${moreKeys.size}", *moreKeys)
|
||||
val newMoreKeys = moreKeys.filterNot { it.startsWith(Key.MORE_KEYS_FIXED_COLUMN_ORDER) }
|
||||
return Array(newMoreKeys.size + 1) {
|
||||
if (it == 0) "!fixedColumnOrder!${newMoreKeys.size}"
|
||||
if (it == 0) "${Key.MORE_KEYS_FIXED_COLUMN_ORDER}${newMoreKeys.size}"
|
||||
else newMoreKeys[it - 1]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ interface KeyData : AbstractKeyData {
|
|||
width,
|
||||
labelFlags or additionalLabelFlags,
|
||||
Key.BACKGROUND_TYPE_NORMAL, // todo (when supported): determine type
|
||||
popup.toMoreKeys(params),
|
||||
popup,
|
||||
)
|
||||
} else {
|
||||
KeyParams(
|
||||
|
@ -139,7 +139,7 @@ interface KeyData : AbstractKeyData {
|
|||
width,
|
||||
labelFlags or additionalLabelFlags,
|
||||
Key.BACKGROUND_TYPE_NORMAL,
|
||||
popup.toMoreKeys(params),
|
||||
popup,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Patrick Goldinger
|
||||
* modified
|
||||
* SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
|
||||
*/
|
||||
|
@ -6,114 +7,27 @@ package org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.floris
|
|||
|
||||
import kotlinx.serialization.Serializable
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.rtlLabel
|
||||
|
||||
// taken from FlorisBoard, small modifications
|
||||
// mutable set removed (currently the moreKeys assembly is happening in KeyParams)
|
||||
// .toMoreKeys added
|
||||
// PopupKeys not used, but might switch to this later
|
||||
// currently hint would be taken from other, and languageMoreKeys are prioritized
|
||||
/**
|
||||
* A popup set for a single key. This set describes, if the key has a [main] character and other [relevant] popups.
|
||||
*
|
||||
* Note that a hint character cannot and should not be set in a json extended popup file, rather it
|
||||
* should only be dynamically set by the LayoutManager.
|
||||
*/
|
||||
// taken from FlorisBoard, considerably modified
|
||||
// we don't care about the difference between main and relevant in this app
|
||||
@Serializable
|
||||
open class PopupSet<T : AbstractKeyData>(
|
||||
open val main: T? = null,
|
||||
open val relevant: List<T> = emptyList()
|
||||
open val relevant: List<T>? = null
|
||||
) {
|
||||
// todo (idea):
|
||||
// this is very simple, but essentially what happens in the old system
|
||||
// could make use of PopupKeys, and also provide a hint depending on user choice
|
||||
// then language key joining should be done in here too
|
||||
// also what about getting the moreKeys and key hint from chosen symbol layout?
|
||||
fun toMoreKeys(params: KeyboardParams): Array<String>? {
|
||||
// get labels of all popup keys
|
||||
open fun getPopupKeyLabels(params: KeyboardParams): Collection<String>? {
|
||||
if (main == null && relevant == null) return null
|
||||
val moreKeys = mutableListOf<String>()
|
||||
// number + main + relevant in this order (label is later taken from first element in resulting array)
|
||||
params.mLocaleKeyTexts.getNumberLabel(numberIndex)?.let { moreKeys.add(it) }
|
||||
main?.getLabel(params)?.let { moreKeys.add(transformLabel(it, params)) }
|
||||
moreKeys.addAll(relevant.map { transformLabel(it.getLabel(params), params) })
|
||||
return moreKeys.takeIf { it.isNotEmpty() }?.toTypedArray()
|
||||
main?.getLabel(params)?.let { moreKeys.add(it) }
|
||||
relevant?.let { moreKeys.addAll(it.map { it.getLabel(params) }) }
|
||||
if (moreKeys.isEmpty()) return null
|
||||
return moreKeys
|
||||
}
|
||||
|
||||
private fun transformLabel(label: String, params: KeyboardParams): String =
|
||||
if (label == "$$$") { // currency key
|
||||
if (params.mId.passwordInput()) "$"
|
||||
else params.mLocaleKeyTexts.currencyKey.first
|
||||
} else if (params.mId.mSubtype.isRtlSubtype) {
|
||||
label.rtlLabel(params)
|
||||
} else label
|
||||
|
||||
private val popupKeys: PopupKeys<T> by lazy {
|
||||
PopupKeys(null, listOfNotNull(main), relevant)
|
||||
}
|
||||
var numberIndex: Int? = null
|
||||
}
|
||||
|
||||
/**
|
||||
* A fully configured collection of popup keys. It contains a list of keys to be prioritized
|
||||
* during rendering (ordered by relevance descending) by showing those keys close to the
|
||||
* popup spawning point.
|
||||
*
|
||||
* The keys contain a separate [hint] key to ease rendering the hint label, but the hint, if
|
||||
* present, also occurs in the [prioritized] list.
|
||||
*
|
||||
* The popup keys can be accessed like an array with the addition that negative indexes defined
|
||||
* within this companion object are allowed (as long as the corresponding [prioritized] list
|
||||
* contains the corresponding amount of keys.
|
||||
*/
|
||||
class PopupKeys<T>(
|
||||
val hint: T?,
|
||||
val prioritized: List<T>,
|
||||
val other: List<T>
|
||||
) : Collection<T> {
|
||||
companion object {
|
||||
const val FIRST_PRIORITIZED = -1
|
||||
const val SECOND_PRIORITIZED = -2
|
||||
const val THIRD_PRIORITIZED = -3
|
||||
}
|
||||
|
||||
override val size: Int
|
||||
get() = prioritized.size + other.size
|
||||
|
||||
override fun contains(element: T): Boolean {
|
||||
return prioritized.contains(element) || other.contains(element)
|
||||
}
|
||||
|
||||
override fun containsAll(elements: Collection<T>): Boolean {
|
||||
return (prioritized + other).containsAll(elements)
|
||||
}
|
||||
|
||||
override fun isEmpty(): Boolean {
|
||||
return prioritized.isEmpty() && other.isEmpty()
|
||||
}
|
||||
|
||||
override fun iterator(): Iterator<T> {
|
||||
return (prioritized + other).listIterator()
|
||||
}
|
||||
|
||||
fun getOrNull(index: Int): T? {
|
||||
if (index >= other.size || index < -prioritized.size) {
|
||||
return null
|
||||
}
|
||||
return when (index) {
|
||||
FIRST_PRIORITIZED -> prioritized[0]
|
||||
SECOND_PRIORITIZED -> prioritized[1]
|
||||
THIRD_PRIORITIZED -> prioritized[2]
|
||||
else -> other.getOrNull(index)
|
||||
}
|
||||
}
|
||||
|
||||
operator fun get(index: Int): T {
|
||||
val item = getOrNull(index)
|
||||
if (item == null) {
|
||||
throw IndexOutOfBoundsException(
|
||||
"Specified index $index is not an valid entry in this PopupKeys!"
|
||||
)
|
||||
} else {
|
||||
return item
|
||||
}
|
||||
}
|
||||
class SimplePopups(val moreKeys: Collection<String>?) : PopupSet<AbstractKeyData>() {
|
||||
override fun getPopupKeyLabels(params: KeyboardParams) = moreKeys
|
||||
}
|
||||
|
|
|
@ -148,7 +148,5 @@ fun String.toTextKey(moreKeys: Collection<String>? = null, labelFlags: Int = 0):
|
|||
TextKeyData(
|
||||
label = this,
|
||||
labelFlags = labelFlags,
|
||||
popup = moreKeys
|
||||
?.let { keys -> PopupSet(null, keys.map { it.toTextKey() }) }
|
||||
?: PopupSet()
|
||||
popup = SimplePopups(moreKeys)
|
||||
)
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.dslul.openboard.inputmethod.keyboard.KeyboardSwitcher;
|
|||
import org.dslul.openboard.inputmethod.latin.AudioAndHapticFeedbackManager;
|
||||
import org.dslul.openboard.inputmethod.latin.R;
|
||||
import org.dslul.openboard.inputmethod.latin.RichInputMethodManager;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.MoreKeysUtilsKt;
|
||||
|
||||
import kotlin.collections.ArraysKt;
|
||||
|
||||
|
@ -67,7 +68,15 @@ public final class PreferencesSettingsFragment extends SubScreenFragment {
|
|||
setupHistoryRetentionTimeSettings();
|
||||
refreshEnablingsOfKeypressSoundAndVibrationAndHistRetentionSettings();
|
||||
setLocalizedNumberRowVisibility();
|
||||
findPreference(Settings.PREF_HINT_LABEL_FROM_FIRST_MORE_KEY).setVisible(getSharedPreferences().getBoolean(Settings.PREF_SHOW_HINTS, false));
|
||||
findPreference(Settings.PREF_MORE_KEYS_LABELS_ORDER).setVisible(getSharedPreferences().getBoolean(Settings.PREF_SHOW_HINTS, false));
|
||||
findPreference(Settings.PREF_MORE_KEYS_ORDER).setOnPreferenceClickListener((pref) -> {
|
||||
MoreKeysUtilsKt.reorderMoreKeysDialog(requireContext(), Settings.PREF_MORE_KEYS_ORDER, MoreKeysUtilsKt.MORE_KEYS_ORDER_DEFAULT, R.string.popup_order);
|
||||
return true;
|
||||
});
|
||||
findPreference(Settings.PREF_MORE_KEYS_LABELS_ORDER).setOnPreferenceClickListener((pref) -> {
|
||||
MoreKeysUtilsKt.reorderMoreKeysDialog(requireContext(), Settings.PREF_MORE_KEYS_LABELS_ORDER, MoreKeysUtilsKt.MORE_KEYS_LABEL_DEFAULT, R.string.hint_source);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,12 +87,13 @@ public final class PreferencesSettingsFragment extends SubScreenFragment {
|
|||
@Override
|
||||
public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
|
||||
refreshEnablingsOfKeypressSoundAndVibrationAndHistRetentionSettings();
|
||||
if (Settings.PREF_SHOW_POPUP_HINTS.equals(key) || Settings.PREF_HINT_LABEL_FROM_FIRST_MORE_KEY.equals(key) || Settings.PREF_SHOW_NUMBER_ROW.equals(key))
|
||||
mReloadKeyboard = true;
|
||||
if (key.equals(Settings.PREF_LOCALIZED_NUMBER_ROW))
|
||||
KeyboardLayoutSet.onSystemLocaleChanged();
|
||||
if (Settings.PREF_SHOW_HINTS.equals(key)) {
|
||||
findPreference(Settings.PREF_HINT_LABEL_FROM_FIRST_MORE_KEY).setVisible(prefs.getBoolean(Settings.PREF_SHOW_HINTS, false));
|
||||
if (key == null) return;
|
||||
switch (key) {
|
||||
case Settings.PREF_MORE_KEYS_ORDER, Settings.PREF_SHOW_POPUP_HINTS, Settings.PREF_SHOW_NUMBER_ROW, Settings.PREF_MORE_KEYS_LABELS_ORDER
|
||||
-> mReloadKeyboard = true;
|
||||
case Settings.PREF_LOCALIZED_NUMBER_ROW -> KeyboardLayoutSet.onSystemLocaleChanged();
|
||||
case Settings.PREF_SHOW_HINTS
|
||||
-> findPreference(Settings.PREF_MORE_KEYS_LABELS_ORDER).setVisible(prefs.getBoolean(Settings.PREF_SHOW_HINTS, false));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -112,8 +112,10 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
public static final String PREF_LOCALIZED_NUMBER_ROW = "pref_localized_number_row";
|
||||
|
||||
public static final String PREF_SHOW_HINTS = "pref_show_hints";
|
||||
public static final String PREF_HINT_LABEL_FROM_FIRST_MORE_KEY = "pref_hint_label_from_first_more_key";
|
||||
public static final String PREF_MORE_KEYS_ORDER = "pref_more_keys_order";
|
||||
public static final String PREF_MORE_KEYS_LABELS_ORDER = "pref_more_keys_labels_order";
|
||||
public static final String PREF_SHOW_POPUP_HINTS = "pref_show_popup_hints";
|
||||
public static final String PREF_MORE_MORE_KEYS = "pref_more_more_keys";
|
||||
|
||||
public static final String PREF_SPACE_TO_CHANGE_LANG = "prefs_long_press_keyboard_to_change_lang";
|
||||
public static final String PREF_SPACE_LANGUAGE_SLIDE = "pref_space_language_slide";
|
||||
|
@ -128,7 +130,6 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
public static final String PREF_ENABLED_INPUT_STYLES = "pref_enabled_input_styles";
|
||||
public static final String PREF_SELECTED_INPUT_STYLE = "pref_selected_input_style";
|
||||
public static final String PREF_USE_SYSTEM_LOCALES = "pref_use_system_locales";
|
||||
public static final String PREF_MORE_MORE_KEYS = "pref_more_more_keys";
|
||||
public static final String PREF_URL_DETECTION = "pref_url_detection";
|
||||
|
||||
public static final String PREF_DONT_SHOW_MISSING_DICTIONARY_DIALOG = "pref_dont_show_missing_dict_dialog";
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.dslul.openboard.inputmethod.latin.RichInputMethodManager;
|
|||
import org.dslul.openboard.inputmethod.latin.common.Colors;
|
||||
import org.dslul.openboard.inputmethod.latin.spellcheck.AndroidSpellCheckerService;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.AsyncResultHolder;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.MoreKeysUtilsKt;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.ScriptUtils;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.TargetPackageInfoGetterTask;
|
||||
|
||||
|
@ -66,7 +67,6 @@ public class SettingsValues {
|
|||
public final boolean mShowsNumberRow;
|
||||
public final boolean mLocalizedNumberRow;
|
||||
public final boolean mShowsHints;
|
||||
public final boolean mHintLabelFromFirstMoreKey;
|
||||
public final boolean mShowsPopupHints;
|
||||
public final boolean mSpaceForLangChange;
|
||||
public final boolean mSpaceLanguageSlide;
|
||||
|
@ -83,7 +83,9 @@ public class SettingsValues {
|
|||
public final int mOneHandedModeGravity;
|
||||
public final float mOneHandedModeScale;
|
||||
public final boolean mNarrowKeyGaps;
|
||||
public final int mShowMoreKeys;
|
||||
public final int mShowMoreMoreKeys;
|
||||
public final List<String> mMoreKeyTypes;
|
||||
public final List<String> mMoreKeyLabelSources;
|
||||
public final List<Locale> mSecondaryLocales;
|
||||
// Use bigrams to predict the next word when there is no input for it yet
|
||||
public final boolean mBigramPredictionEnabled;
|
||||
|
@ -152,7 +154,6 @@ public class SettingsValues {
|
|||
mShowsNumberRow = prefs.getBoolean(Settings.PREF_SHOW_NUMBER_ROW, false);
|
||||
mLocalizedNumberRow = prefs.getBoolean(Settings.PREF_LOCALIZED_NUMBER_ROW, true);
|
||||
mShowsHints = prefs.getBoolean(Settings.PREF_SHOW_HINTS, true);
|
||||
mHintLabelFromFirstMoreKey = mShowsHints && prefs.getBoolean(Settings.PREF_HINT_LABEL_FROM_FIRST_MORE_KEY, false);
|
||||
mShowsPopupHints = prefs.getBoolean(Settings.PREF_SHOW_POPUP_HINTS, false);
|
||||
mSpaceForLangChange = prefs.getBoolean(Settings.PREF_SPACE_TO_CHANGE_LANG, true);
|
||||
mSpaceLanguageSlide = prefs.getBoolean(Settings.PREF_SPACE_LANGUAGE_SLIDE, false);
|
||||
|
@ -228,9 +229,12 @@ public class SettingsValues {
|
|||
mOneHandedModeScale = 1f;
|
||||
final InputMethodSubtype selectedSubtype = SubtypeSettingsKt.getSelectedSubtype(prefs);
|
||||
mSecondaryLocales = Settings.getSecondaryLocales(prefs, selectedSubtype.getLocale());
|
||||
mShowMoreKeys = selectedSubtype.isAsciiCapable()
|
||||
mShowMoreMoreKeys = selectedSubtype.isAsciiCapable()
|
||||
? Settings.readMoreMoreKeysPref(prefs)
|
||||
: LocaleKeyTextsKt.MORE_KEYS_NORMAL;
|
||||
mMoreKeyTypes = MoreKeysUtilsKt.getEnabledMoreKeys(prefs, Settings.PREF_MORE_KEYS_ORDER, MoreKeysUtilsKt.MORE_KEYS_ORDER_DEFAULT);
|
||||
// todo: if the type is disabled, the label should not occur too?
|
||||
mMoreKeyLabelSources = MoreKeysUtilsKt.getEnabledMoreKeys(prefs, Settings.PREF_MORE_KEYS_LABELS_ORDER, MoreKeysUtilsKt.MORE_KEYS_LABEL_DEFAULT);
|
||||
mColors = Settings.getColorsForCurrentTheme(context, prefs);
|
||||
|
||||
mAddToPersonalDictionary = prefs.getBoolean(Settings.PREF_ADD_TO_PERSONAL_DICTIONARY, false);
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
package org.dslul.openboard.inputmethod.latin.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.widget.SwitchCompat
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.dslul.openboard.inputmethod.keyboard.Key
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.floris.PopupSet
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.rtlLabel
|
||||
import org.dslul.openboard.inputmethod.latin.R
|
||||
import java.util.Collections
|
||||
|
||||
private const val MORE_KEYS_NUMBER = "more_keys_number"
|
||||
private const val MORE_KEYS_LANGUAGE_PRIORITY = "more_keys_language_priority"
|
||||
private const val MORE_KEYS_LAYOUT = "more_keys_layout"
|
||||
private const val MORE_KEYS_SYMBOLS = "more_keys_symbols"
|
||||
private const val MORE_KEYS_LANGUAGE = "more_keys_language"
|
||||
const val MORE_KEYS_LABEL_DEFAULT = "$MORE_KEYS_NUMBER,true;$MORE_KEYS_LANGUAGE_PRIORITY,false;$MORE_KEYS_LAYOUT,true;$MORE_KEYS_SYMBOLS,true;$MORE_KEYS_LANGUAGE,false"
|
||||
const val MORE_KEYS_ORDER_DEFAULT = "$MORE_KEYS_LANGUAGE_PRIORITY,true;$MORE_KEYS_NUMBER,true;$MORE_KEYS_SYMBOLS,true;$MORE_KEYS_LAYOUT,true;$MORE_KEYS_LANGUAGE,true"
|
||||
|
||||
// todo:
|
||||
// take moreKeys from symbols layout (in a separate commit)
|
||||
// maybe also add a (simple) parser cache... or cache the layout somewhere else?
|
||||
// that might be annoying with base and full layout (functional keys and spacers)
|
||||
// because base layout not available later... put it to keyParams?
|
||||
// or create symbol moreKeys in the parser? that should work best, there we have proper access to layouts
|
||||
|
||||
fun createMoreKeysArray(popupSet: PopupSet<*>?, params: KeyboardParams, label: String): Array<String>? {
|
||||
val moreKeys = mutableSetOf<String>()
|
||||
params.mMoreKeyTypes.forEach { type ->
|
||||
when (type) {
|
||||
MORE_KEYS_NUMBER -> params.mLocaleKeyTexts.getNumberLabel(popupSet?.numberIndex)?.let { moreKeys.add(it) }
|
||||
MORE_KEYS_LAYOUT -> popupSet?.getPopupKeyLabels(params)?.let { moreKeys.addAll(it) }
|
||||
MORE_KEYS_SYMBOLS -> {} // todo
|
||||
MORE_KEYS_LANGUAGE -> params.mLocaleKeyTexts.getMoreKeys(label)?.let { moreKeys.addAll(it) }
|
||||
MORE_KEYS_LANGUAGE_PRIORITY -> params.mLocaleKeyTexts.getPriorityMoreKeys(label)?.let { moreKeys.addAll(it) }
|
||||
}
|
||||
}
|
||||
if (moreKeys.isEmpty()) return null
|
||||
val fco = moreKeys.firstOrNull { it.startsWith(Key.MORE_KEYS_FIXED_COLUMN_ORDER) }
|
||||
if (fco != null && fco.substringAfter(Key.MORE_KEYS_FIXED_COLUMN_ORDER).toIntOrNull() != moreKeys.size - 1) {
|
||||
moreKeys.remove(fco) // maybe rather adjust the number instead of remove?
|
||||
}
|
||||
// autoColumnOrder should be fine
|
||||
|
||||
val array = moreKeys.toTypedArray()
|
||||
for (i in array.indices) {
|
||||
array[i] = transformLabel(array[i], params)
|
||||
}
|
||||
return array
|
||||
}
|
||||
|
||||
fun getHintLabel(popupSet: PopupSet<*>?, params: KeyboardParams, label: String): String? {
|
||||
var hintLabel: String? = null
|
||||
for (type in params.mMoreKeyLabelSources) {
|
||||
when (type) {
|
||||
MORE_KEYS_NUMBER -> params.mLocaleKeyTexts.getNumberLabel(popupSet?.numberIndex)?.let { hintLabel = it }
|
||||
MORE_KEYS_LAYOUT -> popupSet?.getPopupKeyLabels(params)?.let { hintLabel = it.firstOrNull() }
|
||||
MORE_KEYS_SYMBOLS -> {} // todo
|
||||
MORE_KEYS_LANGUAGE -> params.mLocaleKeyTexts.getMoreKeys(label)?.let { hintLabel = it.firstOrNull() }
|
||||
MORE_KEYS_LANGUAGE_PRIORITY -> params.mLocaleKeyTexts.getPriorityMoreKeys(label)?.let { hintLabel = it.firstOrNull() }
|
||||
}
|
||||
if (hintLabel != null) break
|
||||
}
|
||||
|
||||
// avoid e.g. !autoColumnOrder! as label
|
||||
// this will avoid having labels on comma and period keys
|
||||
return hintLabel?.let { transformLabel(it, params) }
|
||||
?.takeIf { !it.startsWith("!") || it == "!" }
|
||||
}
|
||||
|
||||
private fun transformLabel(label: String, params: KeyboardParams): String =
|
||||
if (label == "$$$") { // currency key
|
||||
if (params.mId.passwordInput()) "$"
|
||||
else params.mLocaleKeyTexts.currencyKey.first
|
||||
} else if (params.mId.mSubtype.isRtlSubtype) {
|
||||
label.rtlLabel(params)
|
||||
} else label
|
||||
|
||||
/** returns a list of enabled more keys for pref [key] */
|
||||
fun getEnabledMoreKeys(prefs: SharedPreferences, key: String, defaultSetting: String): List<String> {
|
||||
return prefs.getString(key, defaultSetting)?.split(";")?.mapNotNull {
|
||||
val split = it.split(",")
|
||||
if (split.last() == "true") split.first() else null
|
||||
} ?: emptyList()
|
||||
}
|
||||
|
||||
/**
|
||||
* show a dialog that allows re-ordering and dis/enabling the more keys list for the pref [key]
|
||||
* see e.g. [MORE_KEYS_LABEL_DEFAULT] for the internally used format
|
||||
*/
|
||||
fun reorderMoreKeysDialog(context: Context, key: String, defaultSetting: String, title: Int) {
|
||||
val prefs = DeviceProtectedUtils.getSharedPreferences(context)
|
||||
val orderedItems = prefs.getString(key, defaultSetting)!!.split(";").mapTo(ArrayList()) {
|
||||
val both = it.split(",")
|
||||
both.first() to both.last().toBoolean()
|
||||
}
|
||||
val rv = RecyclerView(context)
|
||||
rv.setPadding(30, 10, 10, 10)
|
||||
rv.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
|
||||
val callback = object : DiffUtil.ItemCallback<Pair<String, Boolean>>() {
|
||||
override fun areItemsTheSame(p0: Pair<String, Boolean>, p1: Pair<String, Boolean>) = p0 == p1
|
||||
override fun areContentsTheSame(p0: Pair<String, Boolean>, p1: Pair<String, Boolean>) = p0 == p1
|
||||
}
|
||||
val adapter = object : ListAdapter<Pair<String, Boolean>, RecyclerView.ViewHolder>(callback) {
|
||||
override fun onCreateViewHolder(p0: ViewGroup, p1: Int): RecyclerView.ViewHolder {
|
||||
val b = LayoutInflater.from(context).inflate(R.layout.morekeys_list_item, rv, false)
|
||||
// wtf? this results in transparent background, but when the background is set in xml it's fine?
|
||||
// but of course when setting in xml i need to duplicate the entire thing except for background because of api things
|
||||
// why tf is it so complicated to just use the dialog's background?
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
// b.setBackgroundColor(android.R.attr.colorBackgroundFloating)
|
||||
// }
|
||||
return object : RecyclerView.ViewHolder(b) { }
|
||||
}
|
||||
override fun onBindViewHolder(p0: RecyclerView.ViewHolder, p1: Int) {
|
||||
val (text, wasChecked) = orderedItems[p1]
|
||||
val displayTextId = context.resources.getIdentifier(text, "string", context.packageName)
|
||||
val displayText = if (displayTextId == 0) text else context.getString(displayTextId)
|
||||
p0.itemView.findViewById<TextView>(R.id.morekeys_type)?.text = displayText
|
||||
val switch = p0.itemView.findViewById<SwitchCompat>(R.id.morekeys_switch)
|
||||
switch?.isChecked = wasChecked
|
||||
switch?.setOnCheckedChangeListener { _, isChecked ->
|
||||
val position = orderedItems.indexOfFirst { it.first == text }
|
||||
orderedItems[position] = text to isChecked
|
||||
}
|
||||
}
|
||||
}
|
||||
rv.adapter = adapter
|
||||
ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0) {
|
||||
override fun onMove(p0: RecyclerView, p1: RecyclerView.ViewHolder, p2: RecyclerView.ViewHolder): Boolean {
|
||||
val pos1 = p1.absoluteAdapterPosition
|
||||
val pos2 = p2.absoluteAdapterPosition
|
||||
Collections.swap(orderedItems, pos1, pos2)
|
||||
adapter.notifyItemMoved(pos1, pos2)
|
||||
return true
|
||||
}
|
||||
override fun onSwiped(p0: RecyclerView.ViewHolder, p1: Int) { }
|
||||
}).attachToRecyclerView(rv)
|
||||
adapter.submitList(orderedItems)
|
||||
AlertDialog.Builder(context)
|
||||
.setTitle(title)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
val value = orderedItems.joinToString(";") { it.first + "," + it.second }
|
||||
prefs.edit().putString(key, value).apply()
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setNeutralButton(R.string.button_default) { _, _ ->
|
||||
prefs.edit().remove(key).apply()
|
||||
}
|
||||
.setView(rv)
|
||||
.show()
|
||||
}
|
13
app/src/main/res/drawable/ic_drag_indicator.xml
Normal file
13
app/src/main/res/drawable/ic_drag_indicator.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!--
|
||||
icon available in Android Studio
|
||||
modified
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24">
|
||||
<path android:fillColor="#FFF"
|
||||
android:pathData="M11,18c0,1.1 -0.9,2 -2,2s-2,-0.9 -2,-2 0.9,-2 2,-2 2,0.9 2,2zM9,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM9,4c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM15,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM15,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM15,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
|
||||
</vector>
|
39
app/src/main/res/layout-v23/morekeys_list_item.xml
Normal file
39
app/src/main/res/layout-v23/morekeys_list_item.xml
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
SPDX-License-Identifier: GPL-3.0-only
|
||||
-->
|
||||
<!--
|
||||
why is the android resource system sometimes so horrible to work with?
|
||||
setting colorBackgroundFloating in code sets an empty background
|
||||
using a color that's colorBackground, but colorBackgroundFloating in v23 crashes
|
||||
with Failed to resolve attribute at index 13: TypedValue{t=0x2/d=0x1010031 a=3 r=0x7f06008c}
|
||||
it seems to be absolutely necessary to clone the layout... wtf?
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:paddingHorizontal="10dp"
|
||||
android:paddingVertical="4dp"
|
||||
android:orientation="horizontal"
|
||||
android:background="?android:attr/colorBackgroundFloating"
|
||||
android:minHeight="48dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
<TextView
|
||||
android:id="@+id/morekeys_type"
|
||||
style="@style/PreferenceTitleText"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content" />
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/morekeys_switch"
|
||||
android:padding="6dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
<ImageView
|
||||
android:paddingEnd="10dp"
|
||||
android:src="@drawable/ic_drag_indicator"
|
||||
app:tint="@color/foreground_weak"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
33
app/src/main/res/layout/morekeys_list_item.xml
Normal file
33
app/src/main/res/layout/morekeys_list_item.xml
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
SPDX-License-Identifier: GPL-3.0-only
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:paddingVertical="4dp"
|
||||
android:orientation="horizontal"
|
||||
android:background="?android:attr/colorBackground"
|
||||
android:minHeight="48dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
<TextView
|
||||
android:id="@+id/morekeys_type"
|
||||
style="@style/PreferenceTitleText"
|
||||
android:layout_gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/morekeys_switch"
|
||||
android:padding="6dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
<ImageView
|
||||
android:paddingEnd="10dp"
|
||||
android:src="@drawable/ic_drag_indicator"
|
||||
app:tint="@color/foreground_weak"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
|
@ -209,8 +209,6 @@ Nouveau dictionnaire:
|
|||
<string name="prefs_long_press_keyboard_to_change_lang_summary">Un appui long sur la barre d\'espace fera apparaître le menu de sélection des claviers</string>
|
||||
<string name="show_hints">Afficher les indices de touches</string>
|
||||
<string name="show_hints_summary">Affiche les caractères alternatifs lors d\'un appui long</string>
|
||||
<string name="show_hints_from_first_popup_key">Afficher les indices à partir de la première sélection du popup</string>
|
||||
<string name="show_hints_from_first_popup_key_summary">Les caractères alternatifs par défaut sont remplacés par ceux sélectionnés en premier lors d\'un appui long</string>
|
||||
<string name="show_popup_hints">Afficher les indices sur les touches fonctionnelles</string>
|
||||
<string name="show_popup_hints_summary">Affiche un signe ( <b>…</b> ) sur les touches où un appui long déclenche une fonctionnalité supplémentaire</string>
|
||||
<string name="prefs_keyboard_height_scale">Échelle de hauteur du clavier</string>
|
||||
|
|
|
@ -234,10 +234,15 @@
|
|||
<string name="show_hints">Show key hints</string>
|
||||
<!-- Description of the settings to show hints -->
|
||||
<string name="show_hints_summary">Show long-press hints</string>
|
||||
<!-- Title of the settings to show hint based on actual long-press key -->
|
||||
<string name="show_hints_from_first_popup_key">Take hint label from first popup key</string>
|
||||
<!-- Summary of the settings to show hint based on actual long-press key -->
|
||||
<string name="show_hints_from_first_popup_key_summary">The default key hints are replaced by those selected first on a long press</string>
|
||||
<!-- Title of the settings to select key hints source -->
|
||||
<string name="hint_source">Select hint source</string>
|
||||
<!-- Title of the settings to set popup key order -->
|
||||
<string name="popup_order">Select popup key order</string>
|
||||
<string name="more_keys_number">Number</string>
|
||||
<string name="more_keys_language">Language</string>
|
||||
<string name="more_keys_language_priority">Language (priority)</string>
|
||||
<string name="more_keys_layout">Layout</string>
|
||||
<string name="more_keys_symbols">Symbols</string>
|
||||
<!-- Title of the settings to show "..." as hints for more functionality on long-press -->
|
||||
<string name="show_popup_hints">Show functional hints</string>
|
||||
<!-- Description of the show_popup_hints setting -->
|
||||
|
|
|
@ -17,12 +17,13 @@
|
|||
android:defaultValue="true"
|
||||
android:persistent="true" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:key="pref_hint_label_from_first_more_key"
|
||||
android:title="@string/show_hints_from_first_popup_key"
|
||||
android:summary="@string/show_hints_from_first_popup_key_summary"
|
||||
android:defaultValue="false"
|
||||
android:persistent="true" />
|
||||
<Preference
|
||||
android:key="pref_more_keys_labels_order"
|
||||
android:title="@string/hint_source" />
|
||||
|
||||
<Preference
|
||||
android:key="pref_more_keys_order"
|
||||
android:title="@string/popup_order" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:key="pref_show_popup_hints"
|
||||
|
|
|
@ -7,7 +7,7 @@ buildscript {
|
|||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.2.0'
|
||||
classpath 'com.android.tools.build:gradle:8.1.4' // 8.2 requires newer Android Studio that is even worse than 2022.x in performance
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
|
||||
|
||||
|
@ -17,7 +17,7 @@ buildscript {
|
|||
}
|
||||
|
||||
plugins {
|
||||
id 'org.jetbrains.kotlin.plugin.serialization' version '1.9.10' apply false
|
||||
id 'org.jetbrains.kotlin.plugin.serialization' version '1.9.21' apply false
|
||||
}
|
||||
|
||||
allprojects {
|
||||
|
|
Loading…
Add table
Reference in a new issue