mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-05-16 23:12:47 +00:00
Switch most latin layouts to use the simple parser (#276)
And do some tweaks so it works better
This commit is contained in:
parent
da6dcece7f
commit
cbfa934721
69 changed files with 1448 additions and 177 deletions
|
@ -131,7 +131,7 @@ public class Key implements Comparable<Key> {
|
|||
private static final int MORE_KEYS_FLAGS_NEEDS_DIVIDERS = 0x20000000;
|
||||
private static final int MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY = 0x10000000;
|
||||
// TODO: Rename these specifiers to !autoOrder! and !fixedOrder! respectively.
|
||||
private static final String MORE_KEYS_AUTO_COLUMN_ORDER = "!autoColumnOrder!";
|
||||
public static final String MORE_KEYS_AUTO_COLUMN_ORDER = "!autoColumnOrder!";
|
||||
private static final String MORE_KEYS_FIXED_COLUMN_ORDER = "!fixedColumnOrder!";
|
||||
private static final String MORE_KEYS_HAS_LABELS = "!hasLabels!";
|
||||
private static final String MORE_KEYS_NEEDS_DIVIDERS = "!needsDividers!";
|
||||
|
@ -943,7 +943,7 @@ public class Key implements Comparable<Key> {
|
|||
// for creating keys that might get modified later
|
||||
public static class KeyParams {
|
||||
// params for building
|
||||
private boolean isSpacer;
|
||||
public boolean isSpacer;
|
||||
private final KeyboardParams mKeyboardParams; // for reading gaps and keyboard width / height
|
||||
public float mRelativeWidth;
|
||||
public float mRelativeHeight; // also should allow negative values, indicating absolute height is defined
|
||||
|
@ -975,8 +975,10 @@ public class Key implements Comparable<Key> {
|
|||
return keyParams;
|
||||
}
|
||||
|
||||
public static KeyParams newSpacer(final KeyboardParams params) {
|
||||
return new KeyParams(params);
|
||||
public static KeyParams newSpacer(final KeyboardParams params, final float relativeWidth) {
|
||||
final KeyParams spacer = new KeyParams(params);
|
||||
spacer.mRelativeWidth = relativeWidth;
|
||||
return spacer;
|
||||
}
|
||||
|
||||
public Key createKey() {
|
||||
|
@ -987,7 +989,7 @@ public class Key implements Comparable<Key> {
|
|||
public void setDimensionsFromRelativeSize(final float newX, final float newY) {
|
||||
if (mRelativeHeight == 0)
|
||||
mRelativeHeight = mKeyboardParams.mDefaultRelativeRowHeight;
|
||||
if (mRelativeWidth == 0)
|
||||
if (!isSpacer && mRelativeWidth == 0)
|
||||
mRelativeWidth = mKeyboardParams.mDefaultRelativeKeyWidth;
|
||||
if (mRelativeHeight < 0)
|
||||
// todo (later): deal with it properly when it needs to be adjusted, i.e. when changing moreKeys or moreSuggestions
|
||||
|
@ -998,7 +1000,7 @@ public class Key implements Comparable<Key> {
|
|||
mFullHeight = mRelativeHeight * mKeyboardParams.mBaseHeight;
|
||||
}
|
||||
|
||||
private static int getMoreKeysColumnAndFlags(final KeyboardParams params, final String[] moreKeys) {
|
||||
private static int getMoreKeysColumnAndFlagsAndSetNullInArray(final KeyboardParams params, final String[] moreKeys) {
|
||||
// Get maximum column order number and set a relevant mode value.
|
||||
int moreKeysColumnAndFlags = MORE_KEYS_MODE_MAX_COLUMN_WITH_AUTO_ORDER | params.mMaxMoreKeysKeyboardColumn;
|
||||
int value;
|
||||
|
@ -1066,7 +1068,7 @@ public class Key implements Comparable<Key> {
|
|||
final Locale localeForUpcasing = params.mId.getLocale();
|
||||
int actionFlags = style.getFlags(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
|
||||
String[] moreKeys = style.getStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys);
|
||||
mMoreKeysColumnAndFlags = getMoreKeysColumnAndFlags(params, moreKeys);
|
||||
mMoreKeysColumnAndFlags = getMoreKeysColumnAndFlagsAndSetNullInArray(params, moreKeys);
|
||||
|
||||
final String[] additionalMoreKeys;
|
||||
if ((mLabelFlags & LABEL_FLAGS_DISABLE_ADDITIONAL_MORE_KEYS) != 0) {
|
||||
|
@ -1172,7 +1174,7 @@ public class Key implements Comparable<Key> {
|
|||
mLabelFlags = labelFlags;
|
||||
mRelativeWidth = relativeWidth;
|
||||
mRelativeHeight = params.mDefaultRelativeRowHeight;
|
||||
mMoreKeysColumnAndFlags = getMoreKeysColumnAndFlags(params, layoutMoreKeys);
|
||||
mMoreKeysColumnAndFlags = getMoreKeysColumnAndFlagsAndSetNullInArray(params, layoutMoreKeys);
|
||||
mIconId = KeySpecParser.getIconId(keySpec);
|
||||
|
||||
final boolean needsToUpcase = needsToUpcase(mLabelFlags, params.mId.mElementId);
|
||||
|
@ -1184,10 +1186,10 @@ public class Key implements Comparable<Key> {
|
|||
languageMoreKeys = null;
|
||||
} else {
|
||||
// same style as additionalMoreKeys (i.e. moreKeys with the % placeholder(s))
|
||||
// todo: read from assets or xml, and cache the results for quick reading again
|
||||
languageMoreKeys = null; // todo: getLanguageMoreKeys(keySpec, mKeyboardParams.mId.getLocale());
|
||||
languageMoreKeys = params.mLocaleKeyTexts.getMoreKeys(keySpec);
|
||||
}
|
||||
final String[] finalMoreKeys = MoreKeySpec.insertAdditionalMoreKeys(languageMoreKeys, layoutMoreKeys);
|
||||
|
||||
if (finalMoreKeys != null) {
|
||||
actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS;
|
||||
mMoreKeys = new MoreKeySpec[finalMoreKeys.length];
|
||||
|
@ -1314,7 +1316,7 @@ public class Key implements Comparable<Key> {
|
|||
|
||||
if (moreKeySpecs != null) {
|
||||
String[] moreKeys = MoreKeySpec.splitKeySpecs(moreKeySpecs);
|
||||
mMoreKeysColumnAndFlags = getMoreKeysColumnAndFlags(params, moreKeys);
|
||||
mMoreKeysColumnAndFlags = getMoreKeysColumnAndFlagsAndSetNullInArray(params, moreKeys);
|
||||
|
||||
moreKeys = MoreKeySpec.insertAdditionalMoreKeys(moreKeys, null);
|
||||
int actionFlags = 0;
|
||||
|
|
|
@ -20,6 +20,7 @@ import android.view.inputmethod.InputMethodSubtype;
|
|||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardBuilder;
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams;
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.UniqueKeysCache;
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.LocaleKeyTextsKt;
|
||||
import org.dslul.openboard.inputmethod.latin.InputAttributes;
|
||||
import org.dslul.openboard.inputmethod.latin.R;
|
||||
import org.dslul.openboard.inputmethod.latin.RichInputMethodSubtype;
|
||||
|
@ -127,6 +128,7 @@ public final class KeyboardLayoutSet {
|
|||
|
||||
public static void onSystemLocaleChanged() {
|
||||
clearKeyboardCache();
|
||||
LocaleKeyTextsKt.clearCache();
|
||||
}
|
||||
|
||||
public static void onKeyboardThemeChanged() {
|
||||
|
|
|
@ -13,8 +13,11 @@ import org.dslul.openboard.inputmethod.keyboard.Key
|
|||
import org.dslul.openboard.inputmethod.keyboard.Key.KeyParams
|
||||
import org.dslul.openboard.inputmethod.keyboard.Keyboard
|
||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardId
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.MORE_KEYS_ALL
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.MORE_KEYS_MORE
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.SimpleKeyboardParser
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.XmlKeyboardParser
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.addLocaleKeyTextsToParams
|
||||
import org.dslul.openboard.inputmethod.latin.R
|
||||
import org.dslul.openboard.inputmethod.latin.common.Constants
|
||||
import org.dslul.openboard.inputmethod.latin.settings.Settings
|
||||
|
@ -46,47 +49,25 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
|||
|
||||
fun loadSimpleKeyboard(id: KeyboardId): KeyboardBuilder<KP> {
|
||||
mParams.mId = id
|
||||
keysInRows = SimpleKeyboardParser(mParams, mContext).parseFromAssets("qwerty")
|
||||
useRelative()
|
||||
addLocaleKeyTextsToParams(mContext, mParams)
|
||||
when (Settings.getInstance().current.mShowMoreKeys) {
|
||||
MORE_KEYS_ALL -> mParams.mLocaleKeyTexts.addFile(mContext.assets.open("language_key_texts/all_more_keys.txt"))
|
||||
MORE_KEYS_MORE -> mParams.mLocaleKeyTexts.addFile(mContext.assets.open("language_key_texts/more_more_keys.txt"))
|
||||
}
|
||||
keysInRows = SimpleKeyboardParser(mParams, mContext).parseFromAssets(id.mSubtype.keyboardLayoutSetName)
|
||||
determineAbsoluteValues()
|
||||
return this
|
||||
|
||||
// todo: further plan to make is actually useful
|
||||
// create languageMoreKeys list from stuff in keyboard-text tools
|
||||
// probably use files in assets, and cache them in a weak hash map with localestring as key
|
||||
// or better 2 letter code, and join codes when combining languageMoreKeys for multiple locales
|
||||
// or maybe locale tag, but that's super annoying for api < 24(?)
|
||||
// or no caching if loading and combining is fast anyway (need to test)
|
||||
// the locale morekeys then should be a map label -> moreKeys
|
||||
// the whole moreKeys map for the current keyboard could be in mParams to simplify access when creating keys
|
||||
// file format? it's easy to switch, but still... text like above? json?
|
||||
// or use resources? could look like donottranslate-more-keys files
|
||||
// should be possible with configuration and contextThemeWrapper, but probably more complicated than simple files
|
||||
// also would be a bit annoying as it would require to have empty base strings for all possible keys
|
||||
// test first whether something like morekeys_ဂ, or morekeys_ø or better morekeys_ø actually works
|
||||
// if not, definitely don't use resources
|
||||
// consider the % placeholder, this should still be used and documented
|
||||
// though maybe has issues when merging languages?
|
||||
// how to deal with unnecessary moreKeys?
|
||||
// e.g. german should have ö as moreKey on o, but swiss german layout has ö as separate key
|
||||
// still have ö on o (like now), or remove it? or make it optional?
|
||||
// is this handled by KeyboardParams.removeRedundantMoreKeys?
|
||||
// not only moreKeys, also currency key and some labels keys should be translated, though not necessarily in that map
|
||||
// need some placeholder for currency key, like $$$
|
||||
// have an explicit all-more-keys definition, which is created from a script merging all available moreKeys
|
||||
// only letter forms and nothing else, right?
|
||||
// maybe some most-but-not-all? e.g. only all that occur for more than one language
|
||||
// migrate latin layouts to this style (need to make exception for pcqwerty!)
|
||||
// finalize simple layout format
|
||||
// keep like now: nice, because simple and allows defining any number of moreKeys
|
||||
// rows of letters, separated with space: very straightforward, but moreKeys are annoying and only one possible
|
||||
// consider the current layout maybe doesn't have the correct moreKeys
|
||||
// where to actually get the current keyboard layout name, so it can be used to select the correct file?
|
||||
// maybe KeyboardLayoutSet will need to be replaced
|
||||
// need to solve the scaling issue with number row and 5 row keyboards
|
||||
// allow users to switch to old style (keep it until all layouts are switched)
|
||||
// really helps to find differences
|
||||
// add a text that issues / unwanted differences should be reported, as the setting will be removed at some point
|
||||
// label flags to do (top part is for latin!)
|
||||
// todo: further plan
|
||||
// add a parser for more complex layouts, and slowly extend it with whatever is needed
|
||||
// initially it's just alternative key for shifted layout
|
||||
// so dvorak and azerty and colemak and others can be migrated
|
||||
// try to make the format compatible with florisboard
|
||||
// migrate symbol layouts to this style
|
||||
// better before user-defined layouts
|
||||
// should be straightforward to do
|
||||
// allow users to define their own layouts
|
||||
// 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
|
||||
// readme, maybe also some "help" button in a dialog
|
||||
// some sort of proper UI, or simply text input?
|
||||
|
@ -98,9 +79,22 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
|||
// need to somehow test for this
|
||||
// is that autoColumnOrder thing a workaround for that?
|
||||
// still would crash for a single huge label
|
||||
// potential keyspec parsing issues:
|
||||
// MoreKeySpec constructor does things like KeySpecParser.getLabel and others
|
||||
// these work with special characters like | and \ doing things depending on their position
|
||||
// if used wrongly, things can crash
|
||||
// -> maybe disable this style of parsing when creating MoreKeySpec of a user-provided layout
|
||||
// or also for the simple layouts, because there is no need to have it in layouts
|
||||
// does the same issue apply to normal key labels?
|
||||
// popup and (single key) long press preview rescale the label on x only, which may deform emojis
|
||||
// migrate symbol layouts to this style
|
||||
// does glide typing work with multiple letters on one key? if not, users should be notified
|
||||
// maybe allow users to define their own symbol and shift-symbol layouts
|
||||
// allow users to import layouts, which essentially just fills the text from a file
|
||||
// can be json too, but need to have a (close to) final definition first
|
||||
// make the remove duplicate moreKey thing an option?
|
||||
// why is it on for serbian (latin), but not for german (german)?
|
||||
// only nordic and serbian_qwertz layouts have it disabled, default is enabled
|
||||
// -> add the option, but disable it by default for all layouts
|
||||
// migrate emoji layouts to this style
|
||||
// emojis are defined in that string array, should be simple to handle
|
||||
// parsing could be done into a single row, which is then split as needed
|
||||
|
@ -113,27 +107,23 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
|||
// migrate keypad layouts to this style
|
||||
// will need more configurable layout definition -> another parser
|
||||
// migrate moreKeys and moreSuggestions to this style?
|
||||
// at least they should not make use of the KeyTextsSet/Table and of the XmlKeyboardParser
|
||||
// at least they should not make use of the KeyTextsSet/Table (and of the XmlKeyboardParser?)
|
||||
// migrate other languages to this style
|
||||
// may be difficult in some cases, like additional row, or no shift key, or pc qwerty layout
|
||||
// also the (integrated) number row might cause issues
|
||||
// at least some of these layouts will need more complicated definition, not just a simple text file
|
||||
// remove all the keyboard layout related xmls if possible
|
||||
// rows_, rowkeys_, row_, kbd_ maybe keyboard_layout_set, keys_, keystyle_, key_
|
||||
// and the texts_table and its source tools
|
||||
// some languages also change symbol view, e.g. fa changes symbols row 3
|
||||
// add more layouts before doing this? or just keep the layout conversion script
|
||||
|
||||
// todo: label flags
|
||||
// alignHintLabelToBottom -> what does it do?
|
||||
// fontNormal -> check / compare turkish layout
|
||||
// fontDefault -> check exclamation and question keys
|
||||
// hasShiftedLetterHint, shiftedLetterActivated -> what is the effect on period key?
|
||||
// labelFlags should be set correctly
|
||||
// alignHintLabelToBottom: on lxx and rounded themes
|
||||
// alignHintLabelToBottom: on lxx and rounded themes, but did not find what it actually does...
|
||||
// alignIconToBottom: space_key_for_number_layout
|
||||
// alignLabelOffCenter: number keys in phone layout
|
||||
// fontNormal: turkish (rows 1 and 2 only), .com, emojis, numModeKeyStyle, a bunch of non-latin languages
|
||||
// fontMonoSpace: unused (not really: fontDefault is monospace + normal)
|
||||
// -> switches to normal typeface, only relevant for holo which has bold
|
||||
// fontMonoSpace: unused
|
||||
// fontDefault: keyExclamationQuestion, a bunch of "normal" keys in fontNormal layouts like thai
|
||||
// -> switches to default defined typeface, useful e.g. if row has fontNormal
|
||||
// followKeyLargeLetterRatio: number keys in number/phone/numpad layouts
|
||||
// followKeyLetterRatio: mode keys in number layouts, some keys in some non-latin layouts
|
||||
// followKeyLabelRatio: enter key, some keys in phone layout (same as followKeyLetterRatio + followKeyLargeLetterRatio)
|
||||
|
@ -154,12 +144,18 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
|||
// maybe remove some of the flags? or keep supporting them?
|
||||
// for pcqwerty: hasShiftedLetterHint -> hasShiftedLetterHint|shiftedLetterActivated when shift is enabled, need to consider if the flag is used
|
||||
// actually period key also has shifted letter hint
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
fun loadFromXml(xmlId: Int, id: KeyboardId): KeyboardBuilder<KP> {
|
||||
mParams.mId = id
|
||||
if (Settings.getInstance().current.mUseNewKeyboardParsing
|
||||
&& id.isAlphabetKeyboard
|
||||
&& this::class == KeyboardBuilder::class // otherwise this will apply to moreKeys and moreSuggestions
|
||||
&& SimpleKeyboardParser.hasLayoutFile(mParams.mId.mSubtype.keyboardLayoutSetName)
|
||||
) {
|
||||
loadSimpleKeyboard(id)
|
||||
return this
|
||||
}
|
||||
// loading a keyboard should set default params like mParams.readAttributes(mContext, attrs);
|
||||
// attrs may be null, then default values are used (looks good for "normal" keyboards)
|
||||
try {
|
||||
|
@ -167,10 +163,10 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
|||
keysInRows = keyboardParser.parseKeyboard()
|
||||
}
|
||||
} catch (e: XmlPullParserException) {
|
||||
Log.w(BUILDER_TAG, "keyboard XML parse error", e)
|
||||
Log.w(TAG, "keyboard XML parse error", e)
|
||||
throw IllegalArgumentException(e.message, e)
|
||||
} catch (e: IOException) {
|
||||
Log.w(BUILDER_TAG, "keyboard XML parse error", e)
|
||||
Log.w(TAG, "keyboard XML parse error", e)
|
||||
throw RuntimeException(e.message, e)
|
||||
}
|
||||
return this
|
||||
|
@ -194,12 +190,11 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
|||
return Keyboard(mParams)
|
||||
}
|
||||
|
||||
// resize keyboard using relative params
|
||||
// determine key size and positions using relative width and height
|
||||
// ideally this should not change anything
|
||||
// but it does a little, depending on how float -> int is done (cast or round, and when to sum up gaps and width)
|
||||
// still should not be more than a pixel difference
|
||||
// keep it around for a while, for testing
|
||||
private fun useRelative() {
|
||||
private fun determineAbsoluteValues() {
|
||||
var currentY = mParams.mTopPadding.toFloat()
|
||||
for (row in keysInRows) {
|
||||
if (row.isEmpty()) continue
|
||||
|
@ -229,10 +224,8 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
|||
val currentKeyXPos = row[i].xPos
|
||||
if (currentKeyXPos > currentX) {
|
||||
// insert spacer
|
||||
val spacer = KeyParams.newSpacer(mParams)
|
||||
spacer.mRelativeWidth = (currentKeyXPos - currentX) / mParams.mBaseWidth
|
||||
val spacer = KeyParams.newSpacer(mParams, (currentKeyXPos - currentX) / mParams.mBaseWidth)
|
||||
spacer.yPos = row[i].yPos
|
||||
spacer.mRelativeHeight = row[i].mRelativeHeight
|
||||
row.add(i, spacer)
|
||||
i++
|
||||
currentX += currentKeyXPos - currentX
|
||||
|
@ -242,9 +235,7 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
|||
}
|
||||
if (currentX < mParams.mOccupiedWidth) {
|
||||
// insert spacer
|
||||
val spacer = KeyParams.newSpacer(mParams)
|
||||
spacer.mRelativeWidth = (mParams.mOccupiedWidth - currentX) / mParams.mBaseWidth
|
||||
spacer.mRelativeHeight = row.last().mRelativeHeight
|
||||
val spacer = KeyParams.newSpacer(mParams, (mParams.mOccupiedWidth - currentX) / mParams.mBaseWidth)
|
||||
spacer.yPos = row.last().yPos
|
||||
row.add(spacer)
|
||||
}
|
||||
|
@ -253,7 +244,6 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
|||
private fun addSplit() {
|
||||
val spacerRelativeWidth = Settings.getInstance().current.mSpacerRelativeWidth
|
||||
// adjust gaps for the whole keyboard, so it's the same for all rows
|
||||
// todo: maybe remove? not sure if narrower gaps are desirable
|
||||
mParams.mRelativeHorizontalGap *= 1f / (1f + spacerRelativeWidth)
|
||||
mParams.mHorizontalGap = (mParams.mRelativeHorizontalGap * mParams.mId.mWidth).toInt()
|
||||
var maxWidthBeforeSpacer = 0f
|
||||
|
@ -262,11 +252,9 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
|||
fillGapsWithSpacers(row)
|
||||
val y = row.first().yPos // all have the same y, so this is fine
|
||||
val relativeWidthSum = row.sumOf { it.mRelativeWidth } // sum up relative widths
|
||||
val spacer = KeyParams.newSpacer(mParams)
|
||||
spacer.mRelativeWidth = spacerRelativeWidth
|
||||
spacer.mRelativeHeight = row.first().mRelativeHeight
|
||||
val spacer = KeyParams.newSpacer(mParams, spacerRelativeWidth)
|
||||
// insert spacer before first key that starts right of the center (also consider gap)
|
||||
var insertIndex = row.indexOfFirst { it.xPos > mParams.mOccupiedWidth / 2 }
|
||||
var insertIndex = row.indexOfFirst { it.xPos + it.mFullWidth / 3 > mParams.mOccupiedWidth / 2 }
|
||||
.takeIf { it > -1 } ?: (row.size / 2) // fallback should never be needed, but better than having an error
|
||||
if (row.any { it.mCode == Constants.CODE_SPACE }) {
|
||||
val spaceLeft = row.single { it.mCode == Constants.CODE_SPACE }
|
||||
|
@ -378,9 +366,6 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
|||
startRow()
|
||||
for (keyParams in row) {
|
||||
endKey(keyParams.createKey())
|
||||
// todo (later): markAsBottomKey if in bottom row?
|
||||
// this is not done in original parsing style, but why not?
|
||||
// just test it (with different bottom paddings)
|
||||
}
|
||||
endRow()
|
||||
}
|
||||
|
@ -388,6 +373,6 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
|||
}
|
||||
|
||||
companion object {
|
||||
private const val BUILDER_TAG = "Keyboard.Builder"
|
||||
private const val TAG = "Keyboard.Builder"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import androidx.annotation.Nullable;
|
|||
|
||||
import org.dslul.openboard.inputmethod.keyboard.Key;
|
||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardId;
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.LocaleKeyTexts;
|
||||
import org.dslul.openboard.inputmethod.latin.R;
|
||||
import org.dslul.openboard.inputmethod.latin.common.Constants;
|
||||
import org.dslul.openboard.inputmethod.latin.settings.Settings;
|
||||
|
@ -84,6 +85,8 @@ public class KeyboardParams {
|
|||
@NonNull
|
||||
private final UniqueKeysCache mUniqueKeysCache;
|
||||
public boolean mAllowRedundantMoreKeys;
|
||||
@NonNull
|
||||
public LocaleKeyTexts mLocaleKeyTexts;
|
||||
|
||||
public int mMostCommonKeyHeight = 0;
|
||||
public int mMostCommonKeyWidth = 0;
|
||||
|
@ -219,8 +222,10 @@ public class KeyboardParams {
|
|||
R.styleable.Keyboard_keyboardRightPadding, width, width, 0);
|
||||
|
||||
mBaseWidth = mOccupiedWidth - mLeftPadding - mRightPadding;
|
||||
final float defaultKeyWidthFactor = context.getResources().getInteger(R.integer.config_screen_metrics) > 2
|
||||
? 0.9f : 1f;
|
||||
mDefaultRelativeKeyWidth = keyAttr.getFraction(R.styleable.Keyboard_Key_keyWidth,
|
||||
1, 1, 1f / DEFAULT_KEYBOARD_COLUMNS);
|
||||
1, 1, defaultKeyWidthFactor / DEFAULT_KEYBOARD_COLUMNS);
|
||||
mDefaultKeyWidth = (int) (mDefaultRelativeKeyWidth * mBaseWidth);
|
||||
|
||||
// todo: maybe settings should not be accessed from here?
|
||||
|
|
|
@ -52,7 +52,7 @@ public final class KeyboardTextsSet {
|
|||
mResourceLocale = SubtypeLocaleUtils.NO_LANGUAGE.equals(locale.toString()) ? null : locale;
|
||||
mResourcePackageName = resourcePackageName;
|
||||
mTextsTables.clear();
|
||||
if (Settings.getInstance().getCurrent().mShowAllMoreKeys) {
|
||||
if (Settings.getInstance().getCurrent().mShowMoreKeys > 0) {
|
||||
mTextsTables.add(KeyboardTextsTable.getTextsTable(new Locale(SubtypeLocaleUtils.NO_LANGUAGE)));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,228 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
package org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser
|
||||
|
||||
import android.content.Context
|
||||
import org.dslul.openboard.inputmethod.keyboard.Key
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams
|
||||
import org.dslul.openboard.inputmethod.latin.common.splitOnWhitespace
|
||||
import org.dslul.openboard.inputmethod.latin.settings.Settings
|
||||
import java.io.InputStream
|
||||
import java.util.Locale
|
||||
import kotlin.math.round
|
||||
|
||||
class LocaleKeyTexts(dataStream: InputStream?) {
|
||||
private val moreKeys = hashMapOf<String, Array<String>>()
|
||||
private val extraKeys = Array<MutableList<Pair<String, Array<String>?>>?>(5) { null }
|
||||
var labelSymbols = "\\?123"
|
||||
var labelAlphabet = "ABC"
|
||||
var labelShiftSymbols = "=\\<"
|
||||
init {
|
||||
readStream(dataStream, false)
|
||||
// set default quote moreKeys if necessary
|
||||
// should this also be done with punctuation moreKeys??
|
||||
if ("\'" !in moreKeys)
|
||||
moreKeys["\'"] = arrayOf("‚", "‘", "’", "‹", "›")
|
||||
if ("\"" !in moreKeys)
|
||||
moreKeys["\""] = arrayOf("„", "“", "”", "«", "»")
|
||||
if ("!" !in moreKeys)
|
||||
moreKeys["!"] = arrayOf("¡")
|
||||
if ("?" !in moreKeys)
|
||||
moreKeys["?"] = arrayOf("¿")
|
||||
}
|
||||
|
||||
private fun readStream(stream: InputStream?, onlyMoreKeys: Boolean) {
|
||||
if (stream == null) return
|
||||
stream.reader().use { reader ->
|
||||
var mode = READER_MODE_NONE
|
||||
val colonSpaceRegex = ":\\s+".toRegex()
|
||||
reader.forEachLine { l ->
|
||||
val line = l.trim()
|
||||
when (line) {
|
||||
"[morekeys]" -> { mode = READER_MODE_MORE_KEYS; return@forEachLine }
|
||||
"[extra_keys]" -> { mode = READER_MODE_EXTRA_KEYS; return@forEachLine }
|
||||
"[labels]" -> { mode = READER_MODE_LABELS; return@forEachLine }
|
||||
}
|
||||
when (mode) {
|
||||
READER_MODE_MORE_KEYS -> addMoreKeys(line.splitOnWhitespace())
|
||||
READER_MODE_EXTRA_KEYS -> if (!onlyMoreKeys) addExtraKey(line.split(colonSpaceRegex, 1))
|
||||
READER_MODE_LABELS -> if (!onlyMoreKeys) addLabel(line.split(colonSpaceRegex, 1))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 getExtraKeys(row: Int): List<Pair<String, Array<String>?>>? =
|
||||
if (row > extraKeys.size) null
|
||||
else extraKeys[row]
|
||||
|
||||
fun addFile(dataStream: InputStream?) {
|
||||
readStream(dataStream, true)
|
||||
}
|
||||
|
||||
private fun addMoreKeys(split: List<String>) {
|
||||
if (split.size == 1) return
|
||||
val existingMoreKeys = moreKeys[split.first()]
|
||||
if (existingMoreKeys == null)
|
||||
moreKeys[split.first()] = Array(split.size - 1) { split[it + 1] }
|
||||
else
|
||||
moreKeys[split.first()] = mergeMoreKeys(existingMoreKeys, split.drop(1))
|
||||
}
|
||||
|
||||
private fun addExtraKey(split: List<String>) {
|
||||
if (split.size < 2) return
|
||||
val row = split.first().toIntOrNull() ?: return
|
||||
val keys = split.last().splitOnWhitespace()
|
||||
val morekeys = if (keys.size == 1) null else Array(keys.size - 1) { keys[it + 1] }
|
||||
if (extraKeys[row] == null)
|
||||
extraKeys[row] = mutableListOf()
|
||||
extraKeys[row]?.add(keys.first() to morekeys)
|
||||
}
|
||||
|
||||
private fun addLabel(split: List<String>) {
|
||||
if (split.size < 2) return
|
||||
when (split.first()) {
|
||||
"symbols" -> labelSymbols = split.last()
|
||||
"alphabet" -> labelAlphabet = split.last()
|
||||
"shift_symbols" -> labelShiftSymbols = split.last()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) }) {
|
||||
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) }
|
||||
if (originalColumnCount != null && moreKeys.size <= 20 // not for too wide layout
|
||||
&& originalColumnCount == round((original.size - 1 + 0.1f) / 2f).toInt()) { // +0.1 f against rounding issues
|
||||
// we had 2 rows, and want it again
|
||||
return (l + "${Key.MORE_KEYS_AUTO_COLUMN_ORDER}${round(l.size / 2f).toInt()}").toTypedArray()
|
||||
}
|
||||
// just drop autoColumnOrder otherwise (maybe not? depends on arising issues)
|
||||
return l.toTypedArray()
|
||||
}
|
||||
return moreKeys.toTypedArray()
|
||||
}
|
||||
|
||||
fun addLocaleKeyTextsToParams(context: Context, params: KeyboardParams) {
|
||||
val locales = Settings.getInstance().current.mSecondaryLocales + params.mId.locale
|
||||
params.mLocaleKeyTexts = moreKeysAndLabels.getOrPut(locales.joinToString { it.toString() }) {
|
||||
val lkt = LocaleKeyTexts(getStreamForLocale(params.mId.locale, context))
|
||||
locales.forEach { locale ->
|
||||
if (locale == params.mId.locale) return@forEach
|
||||
lkt.addFile(getStreamForLocale(locale, context))
|
||||
}
|
||||
lkt
|
||||
}
|
||||
}
|
||||
|
||||
private fun getStreamForLocale(locale: Locale, context: Context) =
|
||||
try {
|
||||
if (locale.toString() == "zz") context.assets.open("language_key_texts/more_more_keys.txt")
|
||||
else context.assets.open("language_key_texts/${locale.toString().lowercase()}.txt")
|
||||
} catch (_: Exception) {
|
||||
try {
|
||||
context.assets.open("language_key_texts/${locale.language.lowercase()}.txt")
|
||||
} catch (_: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun clearCache() = moreKeysAndLabels.clear()
|
||||
|
||||
// cache the texts, so they don't need to be read over and over
|
||||
private val moreKeysAndLabels = hashMapOf<String, LocaleKeyTexts>()
|
||||
|
||||
private const val READER_MODE_NONE = 0
|
||||
private const val READER_MODE_MORE_KEYS = 1
|
||||
private const val READER_MODE_EXTRA_KEYS = 2
|
||||
private const val READER_MODE_LABELS = 3
|
||||
|
||||
// probably could be improved and extended, currently this is what's done in key_styles_currency.xml
|
||||
fun getCurrencyKey(locale: Locale): Pair<String, Array<String>> {
|
||||
if (locale.country.matches(euroCountries))
|
||||
return euro
|
||||
if (locale.toString().matches(euroLocales))
|
||||
return euro
|
||||
if (locale.language.matches("ca|eu|lb|mt".toRegex()))
|
||||
return euro
|
||||
if (locale.language.matches("fa|iw|ko|lo|mn|ne|th|uk|vi".toRegex()))
|
||||
return genericCurrencyKey(getCurrency(locale))
|
||||
if (locale.language == "hy")
|
||||
return dram
|
||||
if (locale.language == "tr")
|
||||
return lira
|
||||
if (locale.language == "ru")
|
||||
return ruble
|
||||
if (locale.country == "LK" || locale.country == "BD")
|
||||
return genericCurrencyKey(getCurrency(locale))
|
||||
if (locale.country == "IN" || locale.language.matches("hi|kn|ml|mr|ta|te".toRegex()))
|
||||
return rupee
|
||||
if (locale.country == "GB")
|
||||
return pound
|
||||
return genericCurrencyKey("$")
|
||||
}
|
||||
|
||||
private fun genericCurrencyKey(currency: String) = currency to genericCurrencyMoreKeys
|
||||
private val genericCurrencyMoreKeys = arrayOf("$", "¢", "£", "€", "¥", "₱")
|
||||
|
||||
private fun getCurrency(locale: Locale): String {
|
||||
if (locale.country == "BD") return "৳"
|
||||
if (locale.country == "LK") return "රු"
|
||||
return when (locale.language) {
|
||||
"fa" -> "﷼"
|
||||
"iw" -> "₪"
|
||||
"ko" -> "₩"
|
||||
"lo" -> "₭"
|
||||
"mn" -> "₮"
|
||||
"ne" -> "रु."
|
||||
"si" -> "රු"
|
||||
"th" -> "฿"
|
||||
"uk" -> "₴"
|
||||
"vi" -> "₫"
|
||||
else -> "$"
|
||||
}
|
||||
}
|
||||
|
||||
// needs at least 4 moreKeys for working shift-symbol keyboard
|
||||
private val euro = "€" to arrayOf("¢", "£", "$", "¥", "₱")
|
||||
private val dram = "֏" to arrayOf("€", "$", "₽", "¥", "£")
|
||||
private val rupee = "₹" to arrayOf("¢", "£", "€", "¥", "₱")
|
||||
private val pound = "£" to arrayOf("¢", "$", "€", "¥", "₱")
|
||||
private val ruble = "₽" to arrayOf("€", "$", "£", "¥")
|
||||
private val lira = "₺" to arrayOf("€", "$", "£", "¥")
|
||||
private val euroCountries = "AD|AT|BE|BG|HR|CY|CZ|DA|EE|FI|FR|DE|GR|HU|IE|IT|XK|LV|LT|LU|MT|MO|ME|NL|PL|PT|RO|SM|SK|SI|ES|VA".toRegex()
|
||||
private val euroLocales = "bg|ca|cs|da|de|el|en|es|et|eu|fi|fr|ga|gl|hr|hu|it|lb|lt|lv|mt|nl|pl|pt|ro|sk|sl|sq|sr|sv".toRegex()
|
||||
|
||||
const val MORE_KEYS_ALL = 2;
|
||||
const val MORE_KEYS_MORE = 1;
|
||||
const val MORE_KEYS_NORMAL = 0;
|
|
@ -2,6 +2,7 @@
|
|||
package org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Resources
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import org.dslul.openboard.inputmethod.keyboard.Key
|
||||
import org.dslul.openboard.inputmethod.keyboard.Key.KeyParams
|
||||
|
@ -10,7 +11,9 @@ import org.dslul.openboard.inputmethod.keyboard.KeyboardTheme
|
|||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardIconsSet
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams
|
||||
import org.dslul.openboard.inputmethod.latin.R
|
||||
import org.dslul.openboard.inputmethod.latin.common.splitOnWhitespace
|
||||
import org.dslul.openboard.inputmethod.latin.utils.InputTypeUtils
|
||||
import org.dslul.openboard.inputmethod.latin.utils.RunInLocale
|
||||
import org.dslul.openboard.inputmethod.latin.utils.sumOf
|
||||
|
||||
/**
|
||||
|
@ -27,14 +30,25 @@ import org.dslul.openboard.inputmethod.latin.utils.sumOf
|
|||
*/
|
||||
class SimpleKeyboardParser(private val params: KeyboardParams, private val context: Context) {
|
||||
|
||||
fun parseFromAssets(layoutName: String) =
|
||||
parse(context.assets.open("layouts/$layoutName.txt").reader().readText())
|
||||
private var addExtraKeys = false
|
||||
fun parseFromAssets(layoutName: String): ArrayList<ArrayList<KeyParams>> {
|
||||
val layoutFile = when (layoutName) {
|
||||
"nordic" -> { addExtraKeys = true; "qwerty" }
|
||||
"spanish" -> {
|
||||
if (params.mId.locale.language == "eo") "eo" // this behaves a bit different than before, but probably still fine
|
||||
else { addExtraKeys = true; "qwerty" }
|
||||
}
|
||||
"german", "swiss", "serbian_qwertz" -> { addExtraKeys = true; "qwertz" }
|
||||
else -> layoutName
|
||||
}
|
||||
return parse(context.assets.open("layouts/$layoutFile.txt").reader().readText())
|
||||
}
|
||||
|
||||
fun parse(layoutContent: String): ArrayList<ArrayList<KeyParams>> {
|
||||
params.readAttributes(context, null)
|
||||
val keysInRows = ArrayList<ArrayList<KeyParams>>()
|
||||
|
||||
val baseKeys: MutableList<List<BaseKey>> = parseAdjustablePartOfLayout(layoutContent)
|
||||
val baseKeys: MutableList<List<BaseKey>> = parseCoreLayout(layoutContent)
|
||||
if (!params.mId.mNumberRowEnabled) {
|
||||
// todo (later): not all layouts have numbers on first row, so maybe have some layout flag to switch it off (or an option)
|
||||
// but for latin it's fine, so don't care now
|
||||
|
@ -51,7 +65,14 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
|||
// are always added to the rows near the bottom
|
||||
keysInRows.add(getBottomRowAndAdjustBaseKeys(baseKeys))
|
||||
|
||||
baseKeys.reversed().forEachIndexed { i, row ->
|
||||
baseKeys.reversed().forEachIndexed { i, it ->
|
||||
val row: List<BaseKey> = if (i == 0) {
|
||||
// add bottom row extra keys
|
||||
it + context.getString(R.string.key_def_extra_bottom_right)
|
||||
.split(",").mapNotNull { if (it.isBlank()) null else BaseKey(it.trim()) }
|
||||
} else {
|
||||
it
|
||||
}
|
||||
// parse functional keys for this row (if any)
|
||||
val functionalKeysDefs = if (i < functionalKeysReversed.size) functionalKeysReversed[i]
|
||||
else emptyList<String>() to emptyList()
|
||||
|
@ -61,38 +82,50 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
|||
|
||||
// determine key width, maybe scale factor for keys, and spacers to add
|
||||
val usedKeyWidth = params.mDefaultRelativeKeyWidth * row.size
|
||||
val availableWidth = 1f - (functionalKeysLeft.sumOf { it.mRelativeWidth }) - (functionalKeysRight.sumOf { it.mRelativeWidth })
|
||||
val width: Float
|
||||
val functionalKeyWidth = (functionalKeysLeft.sumOf { it.mRelativeWidth }) + (functionalKeysRight.sumOf { it.mRelativeWidth })
|
||||
val availableWidth = 1f - functionalKeyWidth
|
||||
var keyWidth: Float
|
||||
val spacerWidth: Float
|
||||
if (availableWidth - usedKeyWidth > 0.0001f) { // don't add spacers if only a tiny bit is empty
|
||||
// width available, add spacer
|
||||
width = params.mDefaultRelativeKeyWidth
|
||||
keyWidth = params.mDefaultRelativeKeyWidth
|
||||
spacerWidth = (availableWidth - usedKeyWidth) / 2
|
||||
} else {
|
||||
// need more width, re-scale
|
||||
spacerWidth = 0f
|
||||
width = availableWidth / row.size
|
||||
keyWidth = availableWidth / row.size
|
||||
}
|
||||
if (spacerWidth != 0f) {
|
||||
paramsRow.add(KeyParams.newSpacer(params).apply { mRelativeWidth = spacerWidth })
|
||||
paramsRow.add(KeyParams.newSpacer(params, spacerWidth))
|
||||
}
|
||||
if (keyWidth < params.mDefaultRelativeKeyWidth * 0.82 && spacerWidth == 0f) {
|
||||
// keys are very narrow, also rescale the functional keys to make keys a little wider
|
||||
// 0.82 is just some guess for "too narrow"
|
||||
// todo (maybe): works reasonably well, but actually functional keys could give some more of their width,
|
||||
// as long as they end up above mDefaultRelativeKeyWidth
|
||||
val allKeyScale = 1f / (functionalKeyWidth + row.size * params.mDefaultRelativeKeyWidth)
|
||||
keyWidth = params.mDefaultRelativeKeyWidth * allKeyScale
|
||||
functionalKeysLeft.forEach { it.mRelativeWidth *= allKeyScale }
|
||||
functionalKeysRight.forEach { it.mRelativeWidth *= allKeyScale }
|
||||
}
|
||||
|
||||
for (key in row) {
|
||||
paramsRow.add(KeyParams(
|
||||
key.label,
|
||||
params,
|
||||
width, // any reasonable way to scale width if there is a long text? might be allowed in user-defined layout
|
||||
keyWidth, // any reasonable way to scale width if there is a long text? might be allowed in user-defined layout
|
||||
0, // todo: maybe autoScale / autoXScale if label has more than 2 characters (exception for emojis?)
|
||||
Key.BACKGROUND_TYPE_NORMAL,
|
||||
key.moreKeys
|
||||
))
|
||||
}
|
||||
if (spacerWidth != 0f) {
|
||||
paramsRow.add(KeyParams.newSpacer(params).apply { mRelativeWidth = spacerWidth })
|
||||
paramsRow.add(KeyParams.newSpacer(params, spacerWidth))
|
||||
}
|
||||
functionalKeysRight.forEach { paramsRow.add(it) }
|
||||
keysInRows.add(0, paramsRow) // we're doing it backwards, so add on top
|
||||
}
|
||||
resizeLastNormalRowIfNecessaryForAlignment(keysInRows)
|
||||
// rescale height if we have more than 4 rows
|
||||
val heightRescale = if (keysInRows.size > 4) 4f / keysInRows.size else 1f
|
||||
if (params.mId.mNumberRowEnabled)
|
||||
|
@ -108,13 +141,53 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
|||
return keysInRows
|
||||
}
|
||||
|
||||
private fun parseAdjustablePartOfLayout(layoutContent: String) =
|
||||
layoutContent.split("\n\n").mapTo(mutableListOf()) { row -> row.split("\n").mapNotNull {
|
||||
if (it.isBlank()) return@mapNotNull null
|
||||
val split = it.split(" ")
|
||||
val moreKeys = if (split.size == 1) null else Array(split.size - 1) { split[it + 1] }
|
||||
BaseKey(split.first(), moreKeys)
|
||||
} }
|
||||
// resize keys in last row if they are wider than keys in the row above
|
||||
// this is done so the keys align with the keys above
|
||||
// done e.g. for nordic and swiss layouts
|
||||
private fun resizeLastNormalRowIfNecessaryForAlignment(keysInRows: ArrayList<ArrayList<KeyParams>>) {
|
||||
if (keysInRows.size < 3)
|
||||
return
|
||||
val lastNormalRow = keysInRows[keysInRows.lastIndex - 1]
|
||||
val rowAboveLastNormalRow = keysInRows[keysInRows.lastIndex - 2]
|
||||
if (lastNormalRow.any { it.isSpacer } || rowAboveLastNormalRow.any { it.isSpacer })
|
||||
return // annoying to deal with, and probably no resize needed anyway
|
||||
val lastNormalRowKeyWidth = lastNormalRow.first { it.mBackgroundType == Key.BACKGROUND_TYPE_NORMAL }.mRelativeWidth
|
||||
val rowAboveLastNormalRowKeyWidth = rowAboveLastNormalRow.first { it.mBackgroundType == Key.BACKGROUND_TYPE_NORMAL }.mRelativeWidth
|
||||
if (lastNormalRowKeyWidth <= rowAboveLastNormalRowKeyWidth + 0.0001f)
|
||||
return // no need
|
||||
if (lastNormalRow.any { it.mBackgroundType == Key.BACKGROUND_TYPE_NORMAL && it.mRelativeWidth != lastNormalRowKeyWidth })
|
||||
return // normal keys have different width, don't deal with this
|
||||
val numberOfNormalKeys = lastNormalRow.count { it.mBackgroundType == Key.BACKGROUND_TYPE_NORMAL }
|
||||
val widthBefore = numberOfNormalKeys * lastNormalRowKeyWidth
|
||||
val widthAfter = numberOfNormalKeys * rowAboveLastNormalRowKeyWidth
|
||||
val spacerWidth = (widthBefore - widthAfter) / 2
|
||||
// resize keys and add spacers
|
||||
lastNormalRow.forEach { if (it.mBackgroundType == Key.BACKGROUND_TYPE_NORMAL) it.mRelativeWidth = rowAboveLastNormalRowKeyWidth }
|
||||
lastNormalRow.add(lastNormalRow.indexOfFirst { it.mBackgroundType == Key.BACKGROUND_TYPE_NORMAL }, KeyParams.newSpacer(params, spacerWidth))
|
||||
lastNormalRow.add(lastNormalRow.indexOfLast { it.mBackgroundType == Key.BACKGROUND_TYPE_NORMAL } + 1, KeyParams.newSpacer(params, spacerWidth))
|
||||
}
|
||||
|
||||
private fun parseCoreLayout(layoutContent: String) =
|
||||
layoutContent.replace("\r\n", "\n").split("\n\n").mapIndexedTo(mutableListOf()) { i, row ->
|
||||
row.split("\n").mapNotNull {
|
||||
if (it.isBlank()) return@mapNotNull null
|
||||
val split = it.splitOnWhitespace()
|
||||
val moreKeys = if (split.size == 1) {
|
||||
null
|
||||
} else if (split.size == 2 && split.last() == "$$$") { // todo: no good reason to ignore it if size > 2
|
||||
// todo (later): could improve handling and show more currency moreKeys, depending on the moreMoreKeys setting
|
||||
if (params.mId.passwordInput())
|
||||
arrayOf("$")
|
||||
else
|
||||
arrayOf(getCurrencyKey(params.mId.locale).first)
|
||||
} else {
|
||||
Array(split.size - 1) { split[it + 1] }
|
||||
}
|
||||
BaseKey(split.first(), moreKeys)
|
||||
} + if (addExtraKeys)
|
||||
(params.mLocaleKeyTexts.getExtraKeys(i + 1)?.let { it.map { BaseKey(it.first, it.second) } } ?: emptyList())
|
||||
else emptyList()
|
||||
}
|
||||
|
||||
private fun parseFunctionalKeys(): List<Pair<List<String>, List<String>>> =
|
||||
context.getString(R.string.key_def_functional).split("\n").mapNotNull { line ->
|
||||
|
@ -136,7 +209,7 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
|||
baseKeys.removeLast()
|
||||
val bottomRow = ArrayList<KeyParams>()
|
||||
context.getString(R.string.key_def_bottom_row).split(",").forEach {
|
||||
val key = it.trim().split(" ").first()
|
||||
val key = it.trim().splitOnWhitespace().first()
|
||||
val adjustKey = when (key) {
|
||||
KEY_COMMA -> adjustedKeys?.first()
|
||||
KEY_PERIOD -> adjustedKeys?.last()
|
||||
|
@ -203,7 +276,7 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
|||
n,
|
||||
params,
|
||||
params.mDefaultRelativeKeyWidth,
|
||||
Key.LABEL_FLAGS_DISABLE_HINT_LABEL, // todo (later): maybe optional or enable (but then all numbers should have hints)
|
||||
Key.LABEL_FLAGS_DISABLE_HINT_LABEL, // todo (later): maybe optional or enable (but then all numbers should have moreKeys)
|
||||
Key.BACKGROUND_TYPE_NORMAL,
|
||||
numbersMoreKeys[i] // todo (later, non-latin): language may add some (either alt numbers, or latin numbers if they are replaced above, see number todo)
|
||||
))
|
||||
|
@ -213,7 +286,7 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
|||
|
||||
// for comma and period: label will override default, moreKeys will be appended
|
||||
private fun getFunctionalKeyParams(def: String, label: String? = null, moreKeys: Array<String>? = null): KeyParams {
|
||||
val split = def.trim().split(" ")
|
||||
val split = def.trim().splitOnWhitespace()
|
||||
val key = split[0]
|
||||
val width = if (split.size == 2) split[1].substringBefore("%").toFloat() / 100f
|
||||
else params.mDefaultRelativeKeyWidth
|
||||
|
@ -248,7 +321,7 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
|||
width,
|
||||
Key.LABEL_FLAGS_HAS_POPUP_HINT or Key.LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT, // todo (later): check what LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT does, maybe remove the flag here
|
||||
if (label?.first()?.isLetter() == true) Key.BACKGROUND_TYPE_NORMAL else Key.BACKGROUND_TYPE_FUNCTIONAL,
|
||||
moreKeys?.let { getPeriodMoreKeys() + it } ?: getPeriodMoreKeys()
|
||||
moreKeys?.let { getPunctuationMoreKeys() + it } ?: getPunctuationMoreKeys()
|
||||
)
|
||||
KEY_ACTION -> KeyParams(
|
||||
"${getActionKeyLabel()}|${getActionKeyCode()}",
|
||||
|
@ -293,13 +366,13 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
|||
KEY_EMOJI_COM -> if (params.mId.mMode == KeyboardId.MODE_URL || params.mId.mMode == KeyboardId.MODE_EMAIL)
|
||||
getFunctionalKeyParams(KEY_COM)
|
||||
else getFunctionalKeyParams(KEY_EMOJI)
|
||||
KEY_COM -> KeyParams(
|
||||
".com", // todo: should depend on language
|
||||
KEY_COM -> KeyParams( // todo: label and moreKeys could be in localeKeyTexts
|
||||
".com",
|
||||
params,
|
||||
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("!hasLabels!", ".net", ".org", ".gov", ".edu") // todo: maybe should be in languageMoreKeys
|
||||
arrayOf("!hasLabels!", ".net", ".org", ".gov", ".edu")
|
||||
)
|
||||
KEY_LANGUAGE_SWITCH -> KeyParams(
|
||||
"!icon/language_switch_key|!code/key_language_switch",
|
||||
|
@ -325,22 +398,6 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
|||
Key.BACKGROUND_TYPE_FUNCTIONAL,
|
||||
null
|
||||
)
|
||||
KEY_EXCLAMATION -> KeyParams(
|
||||
"!",
|
||||
params,
|
||||
width,
|
||||
Key.LABEL_FLAGS_FONT_DEFAULT,
|
||||
Key.BACKGROUND_TYPE_NORMAL,
|
||||
arrayOf("¡") // todo (later) may depend on language
|
||||
)
|
||||
KEY_QUESTION -> KeyParams(
|
||||
"\\?",
|
||||
params,
|
||||
width,
|
||||
Key.LABEL_FLAGS_FONT_DEFAULT,
|
||||
Key.BACKGROUND_TYPE_NORMAL,
|
||||
arrayOf("¿") // todo (later) may depend on language
|
||||
)
|
||||
else -> throw IllegalArgumentException("unknown key definition \"$key\"")
|
||||
}
|
||||
}
|
||||
|
@ -370,7 +427,6 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
|||
"!code/key_shift_enter"
|
||||
else "!code/key_enter"
|
||||
|
||||
|
||||
private fun getActionKeyMoreKeys(): Array<String>? {
|
||||
val action = params.mId.imeAction()
|
||||
val navigatePrev = params.mId.navigatePrevious()
|
||||
|
@ -431,23 +487,20 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
|||
private fun String.replaceIconWithLabelIfNoDrawable(): String {
|
||||
if (params.mIconsSet.getIconDrawable(KeyboardIconsSet.getIconId(this)) != null) return this
|
||||
val id = context.resources.getIdentifier("label_$this", "string", context.packageName)
|
||||
return context.getString(id)
|
||||
val ril = object : RunInLocale<String>() { // todo (later): simpler way of doing this in a single line?
|
||||
override fun job(res: Resources) = res.getString(id)
|
||||
}
|
||||
return ril.runInLocale(context.resources, params.mId.locale)
|
||||
}
|
||||
|
||||
// todo: may depend on language
|
||||
private fun getAlphabetLabel(): String {
|
||||
return "ABC"
|
||||
}
|
||||
private fun getAlphabetLabel() = params.mLocaleKeyTexts.labelAlphabet
|
||||
|
||||
// todo: may depend on language
|
||||
private fun getSymbolLabel(): String {
|
||||
return "\\?123"
|
||||
}
|
||||
private fun getSymbolLabel() = params.mLocaleKeyTexts.labelSymbols
|
||||
|
||||
private fun getShiftLabel(): String {
|
||||
val elementId = params.mId.mElementId
|
||||
if (elementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED)
|
||||
return "=\\<" // todo: may depend on language
|
||||
return params.mLocaleKeyTexts.labelShiftSymbols
|
||||
if (elementId == KeyboardId.ELEMENT_SYMBOLS)
|
||||
return getSymbolLabel()
|
||||
if (elementId == KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED || elementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED
|
||||
|
@ -476,16 +529,29 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
|||
return keys.toTypedArray()
|
||||
}
|
||||
|
||||
private fun getPeriodMoreKeys(): Array<String> {
|
||||
private fun getPunctuationMoreKeys(): Array<String> {
|
||||
if (params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS || params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED)
|
||||
return arrayOf("…")
|
||||
// todo: language-dependent, also influences the number after autoColumnOrder
|
||||
// there is a weird messup with morekeys_punctuation and morekeys_period
|
||||
// by default, morekeys_period is taken from morekeys_punctuation, but some languages override this
|
||||
// morekeys_period is also changed by some languages
|
||||
// period key always uses morekeys_period, except for dvorak layout which is the only user of morekeys_punctuation
|
||||
// -> clean it up when implementing the language-dependent moreKeys
|
||||
return arrayOf("!autoColumnOrder!8", "\\,", "?", "!", "#", ")", "(", "/", ";", "'", "@", ":", "-", "\"", "+", "\\%", "&")
|
||||
val moreKeys = params.mLocaleKeyTexts.getMoreKeys("punctuation") ?:
|
||||
// todo: some (non-latin) languages have different parenthesis keys
|
||||
arrayOf("${Key.MORE_KEYS_AUTO_COLUMN_ORDER}8", "\\,", "?", "!", "#", ")", "(", "/", ";", "'", "@", ":", "-", "\"", "+", "\\%", "&")
|
||||
if (context.resources.getInteger(R.integer.config_screen_metrics) >= 3 && moreKeys.contains("!") && moreKeys.contains("?")) {
|
||||
// we have a tablet, remove ! and ? keys and reduce number in autoColumnOrder
|
||||
// this makes use of removal of empty moreKeys in MoreKeySpec.insertAdditionalMoreKeys
|
||||
// todo: maybe do this as part of removing unnecessary moreKeys instead of here?
|
||||
moreKeys[moreKeys.indexOf("!")] = ""
|
||||
moreKeys[moreKeys.indexOf("?")] = ""
|
||||
val columns = moreKeys[0].substringAfter(Key.MORE_KEYS_AUTO_COLUMN_ORDER).toIntOrNull()
|
||||
if (columns != null)
|
||||
moreKeys[0] = "${Key.MORE_KEYS_AUTO_COLUMN_ORDER}${columns - 1}"
|
||||
}
|
||||
return moreKeys
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun hasLayoutFile(layoutName: String) = layoutName in supportedLayouts
|
||||
// todo: adjust when changing layout names, and of course when anything changes...
|
||||
private val supportedLayouts = hashSetOf("qwerty", "qwertz", "halmak", "workman", "bepo", "swiss", "german", "nordic", "spanish", "serbian_qwertz")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -536,5 +602,3 @@ private const val KEY_SHIFT = "shift"
|
|||
private const val KEY_NUMPAD = "numpad"
|
||||
private const val KEY_SYMBOL = "symbol"
|
||||
private const val KEY_ALPHA = "alphabet"
|
||||
private const val KEY_QUESTION = "question"
|
||||
private const val KEY_EXCLAMATION = "exclamation"
|
||||
|
|
|
@ -609,6 +609,8 @@ public final class StringUtils {
|
|||
if (label == null || !ScriptUtils.scriptSupportsUppercase(locale)) {
|
||||
return label;
|
||||
}
|
||||
if (label.equals("ß"))
|
||||
return "ẞ"; // upcasing of standalone ß, SS is not useful as s is on the keyboard anyway
|
||||
|
||||
return label.toUpperCase(getLocaleUsedForToTitleCase(locale));
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -15,8 +15,11 @@ import android.util.Log
|
|||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.preference.Preference
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.dslul.openboard.inputmethod.dictionarypack.DictionaryPackConstants
|
||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardLayoutSet
|
||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardSwitcher
|
||||
import org.dslul.openboard.inputmethod.latin.AudioAndHapticFeedbackManager
|
||||
import org.dslul.openboard.inputmethod.latin.BuildConfig
|
||||
import org.dslul.openboard.inputmethod.latin.R
|
||||
|
@ -24,9 +27,6 @@ import org.dslul.openboard.inputmethod.latin.SystemBroadcastReceiver
|
|||
import org.dslul.openboard.inputmethod.latin.common.FileUtils
|
||||
import org.dslul.openboard.inputmethod.latin.define.JniLibName
|
||||
import org.dslul.openboard.inputmethod.latin.settings.SeekBarDialogPreference.ValueProxy
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardSwitcher
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.IOException
|
||||
|
@ -56,8 +56,6 @@ class AdvancedSettingsFragment : SubScreenFragment() {
|
|||
"userunigram.*/userunigram.*\\.(body|header)".toRegex(),
|
||||
"UserHistoryDictionary.*/UserHistoryDictionary.*\\.(body|header)".toRegex(),
|
||||
"spellcheck_userunigram.*/spellcheck_userunigram.*\\.(body|header)".toRegex(),
|
||||
// todo: found "b.<locale>.dict" folder, where does it come from?
|
||||
// possibly some obfuscation thing that occurred after upgrading to gradle 8?
|
||||
) }
|
||||
|
||||
private val libraryFilePicker = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
|
@ -290,10 +288,9 @@ class AdvancedSettingsFragment : SubScreenFragment() {
|
|||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(prefs: SharedPreferences, key: String?) {
|
||||
if (Settings.PREF_SHOW_SETUP_WIZARD_ICON == key) {
|
||||
SystemBroadcastReceiver.toggleAppIcon(requireContext())
|
||||
} else if (Settings.PREF_SHOW_ALL_MORE_KEYS == key) {
|
||||
KeyboardLayoutSet.onKeyboardThemeChanged()
|
||||
when (key) {
|
||||
Settings.PREF_SHOW_SETUP_WIZARD_ICON -> SystemBroadcastReceiver.toggleAppIcon(requireContext())
|
||||
Settings.PREF_MORE_MORE_KEYS, Settings.PREF_USE_NEW_KEYBOARD_PARSING -> KeyboardLayoutSet.onSystemLocaleChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
package org.dslul.openboard.inputmethod.latin.settings
|
||||
|
||||
import android.content.Context
|
||||
|
@ -18,6 +17,7 @@ import androidx.core.view.isGone
|
|||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.size
|
||||
import org.dslul.openboard.inputmethod.dictionarypack.DictionaryPackConstants
|
||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardLayoutSet
|
||||
import org.dslul.openboard.inputmethod.latin.BinaryDictionaryGetter
|
||||
import org.dslul.openboard.inputmethod.latin.R
|
||||
import org.dslul.openboard.inputmethod.latin.common.LocaleUtils
|
||||
|
@ -182,9 +182,11 @@ class LanguageSettingsDialog(
|
|||
Settings.setSecondaryLocales(prefs, mainLocaleString, localeStrings - locale.toString())
|
||||
binding.secondaryLocales.removeView(rowBinding.root)
|
||||
reloadSetting()
|
||||
KeyboardLayoutSet.onSystemLocaleChanged()
|
||||
}
|
||||
}
|
||||
binding.secondaryLocales.addView(rowBinding.root)
|
||||
KeyboardLayoutSet.onSystemLocaleChanged()
|
||||
}
|
||||
|
||||
private fun fillDictionariesView() {
|
||||
|
|
|
@ -24,6 +24,7 @@ import androidx.annotation.NonNull;
|
|||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardTheme;
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.LocaleKeyTextsKt;
|
||||
import org.dslul.openboard.inputmethod.latin.AudioAndHapticFeedbackManager;
|
||||
import org.dslul.openboard.inputmethod.latin.InputAttributes;
|
||||
import org.dslul.openboard.inputmethod.latin.R;
|
||||
|
@ -102,6 +103,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
public static final String PREF_GESTURE_FLOATING_PREVIEW_TEXT = "pref_gesture_floating_preview_text";
|
||||
public static final String PREF_GESTURE_SPACE_AWARE = "pref_gesture_space_aware";
|
||||
public static final String PREF_SHOW_SETUP_WIZARD_ICON = "pref_show_setup_wizard_icon";
|
||||
public static final String PREF_USE_NEW_KEYBOARD_PARSING = "pref_use_new_keyboard_parsing"; // todo: remove later
|
||||
|
||||
public static final String PREF_ONE_HANDED_MODE = "pref_one_handed_mode_enabled";
|
||||
public static final String PREF_ONE_HANDED_GRAVITY = "pref_one_handed_mode_gravity";
|
||||
|
@ -124,7 +126,7 @@ 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_SHOW_ALL_MORE_KEYS = "pref_show_all_more_keys";
|
||||
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";
|
||||
|
@ -469,6 +471,14 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
prefs.edit().putString(Settings.PREF_PINNED_KEYS, String.join(";", keys)).apply();
|
||||
}
|
||||
|
||||
public static int readMoreMoreKeysPref(final SharedPreferences prefs) {
|
||||
return switch (prefs.getString(Settings.PREF_MORE_MORE_KEYS, "normal")) {
|
||||
case "all" -> LocaleKeyTextsKt.MORE_KEYS_ALL;
|
||||
case "more" -> LocaleKeyTextsKt.MORE_KEYS_MORE;
|
||||
default -> LocaleKeyTextsKt.MORE_KEYS_NORMAL;
|
||||
};
|
||||
}
|
||||
|
||||
public static List<Locale> getSecondaryLocales(final SharedPreferences prefs, final String mainLocaleString) {
|
||||
final String localesString = prefs.getString(PREF_SECONDARY_LOCALES_PREFIX + mainLocaleString.toLowerCase(Locale.ROOT), "");
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.dslul.openboard.inputmethod.compat.AppWorkaroundsUtils;
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.LocaleKeyTextsKt;
|
||||
import org.dslul.openboard.inputmethod.latin.InputAttributes;
|
||||
import org.dslul.openboard.inputmethod.latin.R;
|
||||
import org.dslul.openboard.inputmethod.latin.RichInputMethodManager;
|
||||
|
@ -79,7 +80,7 @@ public class SettingsValues {
|
|||
public final boolean mOneHandedModeEnabled;
|
||||
public final int mOneHandedModeGravity;
|
||||
public final boolean mNarrowKeyGaps;
|
||||
public final boolean mShowAllMoreKeys;
|
||||
public final int mShowMoreKeys;
|
||||
public final List<Locale> mSecondaryLocales;
|
||||
// Use bigrams to predict the next word when there is no input for it yet
|
||||
public final boolean mBigramPredictionEnabled;
|
||||
|
@ -104,6 +105,7 @@ public class SettingsValues {
|
|||
public final boolean mUrlDetectionEnabled;
|
||||
public final List<String> mPinnedKeys;
|
||||
public final float mBottomPaddingScale;
|
||||
public final boolean mUseNewKeyboardParsing;
|
||||
|
||||
// From the input box
|
||||
@NonNull
|
||||
|
@ -215,7 +217,9 @@ public class SettingsValues {
|
|||
mOneHandedModeGravity = Settings.readOneHandedModeGravity(prefs);
|
||||
final InputMethodSubtype selectedSubtype = SubtypeSettingsKt.getSelectedSubtype(prefs);
|
||||
mSecondaryLocales = Settings.getSecondaryLocales(prefs, selectedSubtype.getLocale());
|
||||
mShowAllMoreKeys = selectedSubtype.isAsciiCapable() && prefs.getBoolean(Settings.PREF_SHOW_ALL_MORE_KEYS, false);
|
||||
mShowMoreKeys = selectedSubtype.isAsciiCapable()
|
||||
? Settings.readMoreMoreKeysPref(prefs)
|
||||
: LocaleKeyTextsKt.MORE_KEYS_NORMAL;
|
||||
mColors = Settings.getColorsForCurrentTheme(context, prefs);
|
||||
|
||||
mAddToPersonalDictionary = prefs.getBoolean(Settings.PREF_ADD_TO_PERSONAL_DICTIONARY, false);
|
||||
|
@ -230,6 +234,7 @@ public class SettingsValues {
|
|||
mPinnedKeys = Settings.readPinnedKeys(prefs);
|
||||
mSpacingAndPunctuations = new SpacingAndPunctuations(res, mUrlDetectionEnabled);
|
||||
mBottomPaddingScale = prefs.getFloat(Settings.PREF_BOTTOM_PADDING_SCALE, DEFAULT_SIZE_SCALE);
|
||||
mUseNewKeyboardParsing = prefs.getBoolean(Settings.PREF_USE_NEW_KEYBOARD_PARSING, true);
|
||||
}
|
||||
|
||||
public boolean isApplicationSpecifiedCompletionsOn() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue