mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-05-19 00:10:20 +00:00
use new parser for number layouts (tablet/landscape still missing some keys)
This commit is contained in:
parent
100da1beae
commit
4406f1b224
10 changed files with 347 additions and 46 deletions
49
app/src/main/assets/layouts/number.json
Normal file
49
app/src/main/assets/layouts/number.json
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
[
|
||||||
|
[
|
||||||
|
{ "label": "1", "type": "numeric" },
|
||||||
|
{ "label": "2", "type": "numeric" },
|
||||||
|
{ "label": "3", "type": "numeric" },
|
||||||
|
{ "label": "-", "popup": { "main": { "label": "+" } }, "labelFlags": 1073742336 }
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ "label": "4", "type": "numeric" },
|
||||||
|
{ "label": "5", "type": "numeric" },
|
||||||
|
{ "label": "6", "type": "numeric" },
|
||||||
|
{ "label": "space" }
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ "label": "7", "type": "numeric" },
|
||||||
|
{ "label": "8", "type": "numeric" },
|
||||||
|
{ "label": "9", "type": "numeric" },
|
||||||
|
{ "label": "delete" }
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ "$": "variation_selector",
|
||||||
|
"default": { "label": "," },
|
||||||
|
"date": { "label": "." },
|
||||||
|
"time": { "time": ".", "popup": { "relevant": [
|
||||||
|
{ "label": "!fixedColumnOrder!2" },
|
||||||
|
{ "label": "!hasLabels!" },
|
||||||
|
{ "label": "AM" },
|
||||||
|
{ "label": "PM" }
|
||||||
|
] } },
|
||||||
|
"datetime": { "time": ".", "popup": { "relevant": [
|
||||||
|
{ "label": "!fixedColumnOrder!2" },
|
||||||
|
{ "label": "!hasLabels!" },
|
||||||
|
{ "label": "AM" },
|
||||||
|
{ "label": "PM" }
|
||||||
|
] } }
|
||||||
|
},
|
||||||
|
{ "label": "0", "type": "numeric" },
|
||||||
|
{ "$": "variation_selector",
|
||||||
|
"default": { "label": "." },
|
||||||
|
"date": { "label": "/" },
|
||||||
|
"time": { "time": ":" },
|
||||||
|
"datetime": { "time": "/ :|/", "popup": { "relevant": [
|
||||||
|
{ "label": "!noPanelAutoMoreKey!" },
|
||||||
|
{ "label": "," }
|
||||||
|
] } }
|
||||||
|
},
|
||||||
|
{ "label": "enter"}
|
||||||
|
]
|
||||||
|
]
|
50
app/src/main/assets/layouts/numpad.json
Normal file
50
app/src/main/assets/layouts/numpad.json
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
[
|
||||||
|
[
|
||||||
|
{ "label": "+", "popup": {
|
||||||
|
"relevant": [
|
||||||
|
{ "label": "(" },
|
||||||
|
{ "label": "<" },
|
||||||
|
{ "label": "±" }
|
||||||
|
]
|
||||||
|
}, "labelFlags": 512 },
|
||||||
|
{ "label": "1", "type": "numeric" },
|
||||||
|
{ "label": "2", "type": "numeric" },
|
||||||
|
{ "label": "3", "type": "numeric" },
|
||||||
|
{ "label": "%", "popup": { "main": { "label": "$$$"} }, "labelFlags": 512 }
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ "label": "-", "popup": {
|
||||||
|
"relevant": [
|
||||||
|
{ "label": ")" },
|
||||||
|
{ "label": ">" },
|
||||||
|
{ "label": "~" }
|
||||||
|
]
|
||||||
|
}, "labelFlags": 512 },
|
||||||
|
{ "label": "4", "type": "numeric" },
|
||||||
|
{ "label": "5", "type": "numeric" },
|
||||||
|
{ "label": "6", "type": "numeric" },
|
||||||
|
{ "label": "space" }
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ "label": "*", "popup": {
|
||||||
|
"relevant": [
|
||||||
|
{ "label": "/" },
|
||||||
|
{ "label": "×" },
|
||||||
|
{ "label": "÷" }
|
||||||
|
]
|
||||||
|
}, "labelFlags": 512 },
|
||||||
|
{ "label": "7", "type": "numeric" },
|
||||||
|
{ "label": "8", "type": "numeric" },
|
||||||
|
{ "label": "9", "type": "numeric" },
|
||||||
|
{ "label": "delete" }
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ "label": "alpha" },
|
||||||
|
{ "label": "comma" },
|
||||||
|
{ "label": "symbol" },
|
||||||
|
{ "label": "0", "type": "numeric" },
|
||||||
|
{ "label": "=", "popup": { "relevant": [ { "label": "≠"}, { "label": "≈"} ] } },
|
||||||
|
{ "label": "period" },
|
||||||
|
{ "label": "enter" }
|
||||||
|
]
|
||||||
|
]
|
26
app/src/main/assets/layouts/phone.json
Normal file
26
app/src/main/assets/layouts/phone.json
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
[
|
||||||
|
[
|
||||||
|
{ "label": "1", "type": "numeric" },
|
||||||
|
{ "label": "2", "type": "numeric", "popup": { "main": { "label": "ABC" } } },
|
||||||
|
{ "label": "3", "type": "numeric", "popup": { "main": { "label": "DEF" } } },
|
||||||
|
{ "label": "-", "popup": { "main": { "label": "+" } }, "labelFlags": 1073742336 }
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ "label": "4", "type": "numeric", "popup": { "main": { "label": "GHI" } } },
|
||||||
|
{ "label": "5", "type": "numeric", "popup": { "main": { "label": "JKL" } } },
|
||||||
|
{ "label": "6", "type": "numeric", "popup": { "main": { "label": "MNO" } } },
|
||||||
|
{ "label": "space" }
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ "label": "7", "type": "numeric", "popup": { "main": { "label": "PQRS" } } },
|
||||||
|
{ "label": "8", "type": "numeric", "popup": { "main": { "label": "TUV" } } },
|
||||||
|
{ "label": "9", "type": "numeric", "popup": { "main": { "label": "WXYZ" } } },
|
||||||
|
{ "label": "delete" }
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ "label": "*#|!code/key_switch_alpha_symbol", "labelFlags": 524432 },
|
||||||
|
{ "label": "0 +|0", "type": "numeric", "popup": { "relevant": [ { "label": "!noPanelAutoMoreKey!" }, { "label": "+" } ] } },
|
||||||
|
{ "label": "." },
|
||||||
|
{ "label": "action" }
|
||||||
|
]
|
||||||
|
]
|
26
app/src/main/assets/layouts/phone_symbols.json
Normal file
26
app/src/main/assets/layouts/phone_symbols.json
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
[
|
||||||
|
[
|
||||||
|
{ "label": "(", "type": "numeric" },
|
||||||
|
{ "label": "/", "type": "numeric" },
|
||||||
|
{ "label": ")", "type": "numeric" },
|
||||||
|
{ "label": "-", "popup": { "main": { "label": "+" } } }
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ "label": "N", "type": "numeric" },
|
||||||
|
{ "label": "!string/label_pause_key|,", "type": "numeric" },
|
||||||
|
{ "label": ",", "type": "numeric" },
|
||||||
|
{ "label": "space" }
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ "label": "*|*", "type": "numeric" },
|
||||||
|
{ "label": "!string/label_wait_key|;", "type": "numeric" },
|
||||||
|
{ "label": "\\#", "type": "numeric" },
|
||||||
|
{ "label": "delete" }
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ "label": "123|!code/key_switch_alpha_symbol", "labelFlags": 524432 },
|
||||||
|
{ "label": "+", "type": "numeric" },
|
||||||
|
{ "label": "." },
|
||||||
|
{ "label": "action" }
|
||||||
|
]
|
||||||
|
]
|
|
@ -958,13 +958,13 @@ public class Key implements Comparable<Key> {
|
||||||
|
|
||||||
// params that remains constant
|
// params that remains constant
|
||||||
public final int mCode;
|
public final int mCode;
|
||||||
@Nullable public final String mLabel;
|
@Nullable public String mLabel;
|
||||||
@Nullable public final String mHintLabel;
|
@Nullable public final String mHintLabel;
|
||||||
public final int mLabelFlags;
|
public final int mLabelFlags;
|
||||||
public final int mIconId;
|
public final int mIconId;
|
||||||
@Nullable public final MoreKeySpec[] mMoreKeys;
|
@Nullable public MoreKeySpec[] mMoreKeys;
|
||||||
public final int mMoreKeysColumnAndFlags;
|
public final int mMoreKeysColumnAndFlags;
|
||||||
public final int mBackgroundType;
|
public int mBackgroundType;
|
||||||
public final int mActionFlags;
|
public final int mActionFlags;
|
||||||
@Nullable public final KeyVisualAttributes mKeyVisualAttributes;
|
@Nullable public final KeyVisualAttributes mKeyVisualAttributes;
|
||||||
@Nullable public OptionalAttributes mOptionalAttributes;
|
@Nullable public OptionalAttributes mOptionalAttributes;
|
||||||
|
@ -1206,6 +1206,8 @@ public class Key implements Comparable<Key> {
|
||||||
final boolean needsToUpcase = needsToUpcase(mLabelFlags, params.mId.mElementId);
|
final boolean needsToUpcase = needsToUpcase(mLabelFlags, params.mId.mElementId);
|
||||||
final Locale localeForUpcasing = params.mId.getLocale();
|
final Locale localeForUpcasing = params.mId.getLocale();
|
||||||
int actionFlags = 0;
|
int actionFlags = 0;
|
||||||
|
if (params.mId.isNumberLayout())
|
||||||
|
actionFlags = ACTION_FLAGS_NO_KEY_PREVIEW;
|
||||||
|
|
||||||
final String[] languageMoreKeys = params.mLocaleKeyTexts.getMoreKeys(keySpec);
|
final String[] languageMoreKeys = params.mLocaleKeyTexts.getMoreKeys(keySpec);
|
||||||
if (languageMoreKeys != null && layoutMoreKeys != null && languageMoreKeys[0].startsWith("!fixedColumnOrder!"))
|
if (languageMoreKeys != null && layoutMoreKeys != null && languageMoreKeys[0].startsWith("!fixedColumnOrder!"))
|
||||||
|
|
|
@ -178,6 +178,11 @@ public final class KeyboardId {
|
||||||
|| mElementId == ELEMENT_ALPHABET_AUTOMATIC_SHIFTED || mElementId == ELEMENT_ALPHABET_MANUAL_SHIFTED;
|
|| mElementId == ELEMENT_ALPHABET_AUTOMATIC_SHIFTED || mElementId == ELEMENT_ALPHABET_MANUAL_SHIFTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isNumberLayout() {
|
||||||
|
return mElementId == ELEMENT_NUMBER || mElementId == ELEMENT_NUMPAD
|
||||||
|
|| mElementId == ELEMENT_PHONE || mElementId == ELEMENT_PHONE_SYMBOLS;
|
||||||
|
}
|
||||||
|
|
||||||
public int imeAction() {
|
public int imeAction() {
|
||||||
return InputTypeUtils.getImeOptionsActionIdFromEditorInfo(mEditorInfo);
|
return InputTypeUtils.getImeOptionsActionIdFromEditorInfo(mEditorInfo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,8 +68,6 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
return this
|
return this
|
||||||
|
|
||||||
// todo: further plan
|
// todo: further plan
|
||||||
// migrate keypad layouts to this style
|
|
||||||
// will need more configurable layout definition -> another parser, or do it with compatible jsons
|
|
||||||
// make the remove duplicate moreKey thing an option?
|
// make the remove duplicate moreKey thing an option?
|
||||||
// why is it on for serbian (latin), but not for german (german)?
|
// why is it on for serbian (latin), but not for german (german)?
|
||||||
// only nordic and serbian_qwertz layouts have it disabled, default is enabled
|
// only nordic and serbian_qwertz layouts have it disabled, default is enabled
|
||||||
|
@ -81,6 +79,10 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
// write another parser, it should already consider split
|
// write another parser, it should already consider split
|
||||||
// add a setting to display all emojis (and use emojiv2 or emojicompat or whatever is necessary)
|
// add a setting to display all emojis (and use emojiv2 or emojicompat or whatever is necessary)
|
||||||
// mention in subtitle that they may not be displayed properly, depending on the app you're writing in
|
// mention in subtitle that they may not be displayed properly, depending on the app you're writing in
|
||||||
|
// uncomment the toast below
|
||||||
|
// number layouts missing details
|
||||||
|
// landscape: numpad layout has some extra keys
|
||||||
|
// tablet: number and phone layout have some extra keys (unify with numpad, so that extra keys show both in land and sw600? or only land?)
|
||||||
// now all layouts should be using the new parser -> throw an error instead of falling back to old parser
|
// now all layouts should be using the new parser -> throw an error instead of falling back to old parser
|
||||||
// more settings for localized number row, so it can be different in shift or symbols
|
// more settings for localized number row, so it can be different in shift or symbols
|
||||||
// migrate moreKeys and moreSuggestions to this style?
|
// migrate moreKeys and moreSuggestions to this style?
|
||||||
|
@ -194,19 +196,19 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
Log.w(TAG, "moreKeys not null for ${keyParams.mLabel} / ${keyParams.mCode}, but xml null")
|
Log.w(TAG, "moreKeys not null for ${keyParams.mLabel} / ${keyParams.mCode}, but xml null")
|
||||||
else if (xmlParams.mMoreKeys == null || keyParams.mMoreKeys == null || keyParams.mMoreKeys.contentEquals(xmlParams.mMoreKeys))
|
else if (xmlParams.mMoreKeys == null || keyParams.mMoreKeys == null || keyParams.mMoreKeys.contentEquals(xmlParams.mMoreKeys))
|
||||||
Unit
|
Unit
|
||||||
else if (keyParams.mMoreKeys.size < xmlParams.mMoreKeys.size) {
|
else if (keyParams.mMoreKeys!!.size < xmlParams.mMoreKeys!!.size) {
|
||||||
if (keyParams.mMoreKeys.size - xmlParams.mMoreKeys.size == -1 && keyParams.mCode.toChar().lowercase() == "s")
|
if (keyParams.mMoreKeys!!.size - xmlParams.mMoreKeys!!.size == -1 && keyParams.mCode.toChar().lowercase() == "s")
|
||||||
Log.i(TAG, "missing moreKeys for ${keyParams.mLabel} / ${keyParams.mCode}")
|
Log.i(TAG, "missing moreKeys for ${keyParams.mLabel} / ${keyParams.mCode}")
|
||||||
else
|
else
|
||||||
Log.w(TAG, "missing moreKeys for ${keyParams.mLabel} / ${keyParams.mCode}")
|
Log.w(TAG, "missing moreKeys for ${keyParams.mLabel} / ${keyParams.mCode}")
|
||||||
} else if (keyParams.mMoreKeys.size > xmlParams.mMoreKeys.size) {
|
} else if (keyParams.mMoreKeys!!.size > xmlParams.mMoreKeys!!.size) {
|
||||||
if (keyParams.mMoreKeys.toList().containsAll(xmlParams.mMoreKeys.toList()))
|
if (keyParams.mMoreKeys!!.toList().containsAll(xmlParams.mMoreKeys!!.toList()))
|
||||||
Log.i(TAG, "more moreKeys for ${keyParams.mLabel} / ${keyParams.mCode}, first same: ${keyParams.mMoreKeys.firstOrNull() == xmlParams.mMoreKeys.firstOrNull() }" +
|
Log.i(TAG, "more moreKeys for ${keyParams.mLabel} / ${keyParams.mCode}, first same: ${keyParams.mMoreKeys?.firstOrNull() == xmlParams.mMoreKeys?.firstOrNull() }" +
|
||||||
", contains all original: true") // not really an issue i would say
|
", contains all original: true") // not really an issue i would say
|
||||||
else
|
else
|
||||||
Log.w(TAG, "more moreKeys for ${keyParams.mLabel} / ${keyParams.mCode}, first same: ${keyParams.mMoreKeys.firstOrNull() == xmlParams.mMoreKeys.firstOrNull() }" +
|
Log.w(TAG, "more moreKeys for ${keyParams.mLabel} / ${keyParams.mCode}, first same: ${keyParams.mMoreKeys?.firstOrNull() == xmlParams.mMoreKeys?.firstOrNull() }" +
|
||||||
", contains all original: false")
|
", contains all original: false")
|
||||||
} else if (!keyParams.mMoreKeys.toList().containsAll(xmlParams.mMoreKeys.toList()))
|
} else if (!keyParams.mMoreKeys!!.toList().containsAll(xmlParams.mMoreKeys!!.toList()))
|
||||||
Log.w(TAG, "same size but missing moreKeys for ${keyParams.mLabel} / ${keyParams.mCode}")
|
Log.w(TAG, "same size but missing moreKeys for ${keyParams.mLabel} / ${keyParams.mCode}")
|
||||||
if (keyParams.mCode != xmlParams.mCode)
|
if (keyParams.mCode != xmlParams.mCode)
|
||||||
Log.w(TAG, "code different: ${keyParams.mCode} vs ${xmlParams.mCode}")
|
Log.w(TAG, "code different: ${keyParams.mCode} vs ${xmlParams.mCode}")
|
||||||
|
@ -237,6 +239,12 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
if (DebugFlags.DEBUG_ENABLED) {
|
||||||
|
// looks like only emoji keyboards are still using the old parser, which is expected
|
||||||
|
Log.w(TAG, "falling back to old parser for $id")
|
||||||
|
if (mParams.mId.mElementId < KeyboardId.ELEMENT_EMOJI_RECENTS || mParams.mId.mElementId > KeyboardId.ELEMENT_EMOJI_CATEGORY16)
|
||||||
|
Toast.makeText(mContext, "using old parser for $id", Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mParams.mId = id
|
mParams.mId = id
|
||||||
// loading a keyboard should set default params like mParams.readAttributes(mContext, attrs);
|
// loading a keyboard should set default params like mParams.readAttributes(mContext, attrs);
|
||||||
|
@ -298,7 +306,7 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
for (row in keysInRows) {
|
for (row in keysInRows) {
|
||||||
if (row.isEmpty()) continue
|
if (row.isEmpty()) continue
|
||||||
fillGapsWithSpacers(row)
|
fillGapsWithSpacers(row)
|
||||||
var currentX = 0f
|
var currentX = mParams.mLeftPadding.toFloat()
|
||||||
row.forEach {
|
row.forEach {
|
||||||
it.setDimensionsFromRelativeSize(currentX, currentY)
|
it.setDimensionsFromRelativeSize(currentX, currentY)
|
||||||
if (DebugFlags.DEBUG_ENABLED)
|
if (DebugFlags.DEBUG_ENABLED)
|
||||||
|
|
|
@ -9,6 +9,7 @@ package org.dslul.openboard.inputmethod.keyboard.internal;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import org.dslul.openboard.inputmethod.annotations.UsedForTesting;
|
import org.dslul.openboard.inputmethod.annotations.UsedForTesting;
|
||||||
import org.dslul.openboard.inputmethod.latin.RichInputMethodManager;
|
import org.dslul.openboard.inputmethod.latin.RichInputMethodManager;
|
||||||
|
@ -18,7 +19,6 @@ import org.dslul.openboard.inputmethod.latin.utils.RunInLocale;
|
||||||
import org.dslul.openboard.inputmethod.latin.utils.SubtypeLocaleUtils;
|
import org.dslul.openboard.inputmethod.latin.utils.SubtypeLocaleUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
@ -69,6 +69,7 @@ public final class KeyboardTextsSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getText(final String name) {
|
public String getText(final String name) {
|
||||||
|
Log.w(getClass().getSimpleName(), "still used for resolving "+name);
|
||||||
return getTextInternal(name, 0); // only used for emoji and clipboard keyboards
|
return getTextInternal(name, 0); // only used for emoji and clipboard keyboards
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser
|
package org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.res.Configuration
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.inputmethod.EditorInfo
|
import android.view.inputmethod.EditorInfo
|
||||||
|
@ -13,6 +14,7 @@ import org.dslul.openboard.inputmethod.keyboard.KeyboardTheme
|
||||||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardIconsSet
|
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardIconsSet
|
||||||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams
|
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.KeyData
|
||||||
|
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.floris.KeyType
|
||||||
import org.dslul.openboard.inputmethod.latin.R
|
import org.dslul.openboard.inputmethod.latin.R
|
||||||
import org.dslul.openboard.inputmethod.latin.common.Constants
|
import org.dslul.openboard.inputmethod.latin.common.Constants
|
||||||
import org.dslul.openboard.inputmethod.latin.common.splitOnWhitespace
|
import org.dslul.openboard.inputmethod.latin.common.splitOnWhitespace
|
||||||
|
@ -32,12 +34,10 @@ import java.util.Locale
|
||||||
* keys in symbol layouts.
|
* keys in symbol layouts.
|
||||||
* By default, all normal keys have the same width and flags, which may cause issues with the
|
* By default, all normal keys have the same width and flags, which may cause issues with the
|
||||||
* requirements of certain non-latin languages. todo: add labelFlags to Json parser, or determine automatically?
|
* requirements of certain non-latin languages. todo: add labelFlags to Json parser, or determine automatically?
|
||||||
*
|
|
||||||
* Currently the number, phone and numpad layouts are not compatible with this parser.
|
|
||||||
*/
|
*/
|
||||||
abstract class KeyboardParser(private val params: KeyboardParams, private val context: Context) {
|
abstract class KeyboardParser(private val params: KeyboardParams, private val context: Context) {
|
||||||
private val infos = layoutInfos(params)
|
private val infos = layoutInfos(params)
|
||||||
private val defaultLabelFlags = infos.defaultLabelFlags or if (!params.mId.isAlphabetKeyboard)
|
private val defaultLabelFlags = infos.defaultLabelFlags or if (params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS || params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED)
|
||||||
Key.LABEL_FLAGS_DISABLE_HINT_LABEL // reproduce the no-hints in symbol layouts, todo: add setting
|
Key.LABEL_FLAGS_DISABLE_HINT_LABEL // reproduce the no-hints in symbol layouts, todo: add setting
|
||||||
else 0
|
else 0
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
fun parseLayoutFromAssets(layoutName: String): ArrayList<ArrayList<KeyParams>> =
|
fun parseLayoutFromAssets(layoutName: String): ArrayList<ArrayList<KeyParams>> =
|
||||||
parseLayoutString(getLayoutFromAssets(layoutName))
|
parseLayoutString(getLayoutFromAssets(layoutName))
|
||||||
|
|
||||||
|
// this thing does too much... make it more understandable after everything is implemented
|
||||||
fun parseLayoutString(layoutContent: String): ArrayList<ArrayList<KeyParams>> {
|
fun parseLayoutString(layoutContent: String): ArrayList<ArrayList<KeyParams>> {
|
||||||
params.readAttributes(context, null)
|
params.readAttributes(context, null)
|
||||||
if (infos.touchPositionCorrectionData == null) // need to set correctly, as it's not properly done in readAttributes with attr = null
|
if (infos.touchPositionCorrectionData == null) // need to set correctly, as it's not properly done in readAttributes with attr = null
|
||||||
|
@ -55,8 +56,34 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
else
|
else
|
||||||
params.mTouchPositionCorrection.load(context.resources.getStringArray(infos.touchPositionCorrectionData))
|
params.mTouchPositionCorrection.load(context.resources.getStringArray(infos.touchPositionCorrectionData))
|
||||||
|
|
||||||
val keysInRows = ArrayList<ArrayList<KeyParams>>()
|
|
||||||
val baseKeys: MutableList<List<KeyData>> = parseCoreLayout(layoutContent)
|
val baseKeys: MutableList<List<KeyData>> = parseCoreLayout(layoutContent)
|
||||||
|
|
||||||
|
val keysInRows: ArrayList<ArrayList<KeyParams>>
|
||||||
|
if (params.mId.mElementId <= KeyboardId.ELEMENT_SYMBOLS_SHIFTED) {
|
||||||
|
keysInRows = createAlphaSymbolRows(baseKeys)
|
||||||
|
} else if (params.mId.isNumberLayout) {
|
||||||
|
keysInRows = createNumericRows(baseKeys)
|
||||||
|
} else {
|
||||||
|
throw(UnsupportedOperationException("creating KeyboardId ${params.mId.mElementId} not supported"))
|
||||||
|
}
|
||||||
|
// rescale height if we have more than 4 rows (todo: there is some default row count in params that could be used)
|
||||||
|
val heightRescale = if (keysInRows.size > 4) 4f / keysInRows.size else 1f
|
||||||
|
if (params.mId.mNumberRowEnabled && params.mId.mElementId <= KeyboardId.ELEMENT_SYMBOLS_SHIFTED)
|
||||||
|
keysInRows.add(0, getNumberRow()) // todo: maybe this should be in createAlphaSymbolRows, but first need to decide height stuff below
|
||||||
|
if (heightRescale != 1f) {
|
||||||
|
// rescale all keys, so number row doesn't look weird (this is done like in current parsing)
|
||||||
|
// todo: in symbols view, number row is not rescaled
|
||||||
|
// so the symbols keyboard is higher than the normal one
|
||||||
|
// not a new issue, but should be solved in this migration
|
||||||
|
// how? possibly scale all keyboards to height of main alphabet? (consider suggestion strip)
|
||||||
|
keysInRows.forEach { row -> row.forEach { it.mRelativeHeight *= heightRescale } }
|
||||||
|
}
|
||||||
|
|
||||||
|
return keysInRows
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createAlphaSymbolRows(baseKeys: MutableList<List<KeyData>>): ArrayList<ArrayList<KeyParams>> {
|
||||||
|
// number row related modifications of baseKeys
|
||||||
if (!params.mId.mNumberRowEnabled && params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS) {
|
if (!params.mId.mNumberRowEnabled && params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS) {
|
||||||
// replace first symbols row with number row
|
// replace first symbols row with number row
|
||||||
baseKeys[0] = params.mLocaleKeyTexts.getNumberRow()
|
baseKeys[0] = params.mLocaleKeyTexts.getNumberRow()
|
||||||
|
@ -76,13 +103,14 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
Toast.makeText(context, message, Toast.LENGTH_LONG).show()
|
Toast.makeText(context, message, Toast.LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val keysInRows = ArrayList<ArrayList<KeyParams>>()
|
||||||
val functionalKeysReversed = parseFunctionalKeys(R.string.key_def_functional).reversed()
|
val functionalKeysReversed = parseFunctionalKeys(R.string.key_def_functional).reversed()
|
||||||
val functionalKeysTop = parseFunctionalKeys(R.string.key_def_functional_top_row)
|
val functionalKeysTop = parseFunctionalKeys(R.string.key_def_functional_top_row)
|
||||||
|
|
||||||
// keyboard parsed bottom-up because the number of rows is not fixed, but the functional keys
|
// keyboard parsed bottom-up because the number of rows is not fixed, but the functional keys
|
||||||
// are always added to the rows near the bottom
|
// are always added to the rows near the bottom
|
||||||
keysInRows.add(getBottomRowAndAdjustBaseKeys(baseKeys))
|
keysInRows.add(getBottomRowAndAdjustBaseKeys(baseKeys))
|
||||||
|
|
||||||
baseKeys.reversed().forEachIndexed { i, it ->
|
baseKeys.reversed().forEachIndexed { i, it ->
|
||||||
val row: List<KeyData> = if (i == 0 && isTablet()) {
|
val row: List<KeyData> = if (i == 0 && isTablet()) {
|
||||||
// add bottom row extra keys
|
// add bottom row extra keys
|
||||||
|
@ -163,19 +191,6 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
keysInRows.add(0, paramsRow) // we're doing it backwards, so add on top
|
keysInRows.add(0, paramsRow) // we're doing it backwards, so add on top
|
||||||
}
|
}
|
||||||
resizeLastNormalRowIfNecessaryForAlignment(keysInRows)
|
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)
|
|
||||||
keysInRows.add(0, getNumberRow())
|
|
||||||
if (heightRescale != 1f) {
|
|
||||||
// rescale all keys, so number row doesn't look weird (this is done like in current parsing)
|
|
||||||
// todo: in symbols view, number row is not rescaled
|
|
||||||
// so the symbols keyboard is higher than the normal one
|
|
||||||
// not a new issue, but should be solved in this migration
|
|
||||||
// how? possibly scale all keyboards to height of main alphabet? (consider suggestion strip)
|
|
||||||
keysInRows.forEach { row -> row.forEach { it.mRelativeHeight *= heightRescale } }
|
|
||||||
}
|
|
||||||
|
|
||||||
return keysInRows
|
return keysInRows
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,6 +220,91 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
lastNormalRow.add(lastNormalRow.indexOfLast { it.mBackgroundType == Key.BACKGROUND_TYPE_NORMAL } + 1, KeyParams.newSpacer(params, spacerWidth))
|
lastNormalRow.add(lastNormalRow.indexOfLast { it.mBackgroundType == Key.BACKGROUND_TYPE_NORMAL } + 1, KeyParams.newSpacer(params, spacerWidth))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createNumericRows(baseKeys: MutableList<List<KeyData>>): ArrayList<ArrayList<KeyParams>> {
|
||||||
|
val keysInRows = ArrayList<ArrayList<KeyParams>>()
|
||||||
|
if (context.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||||
|
// add padding here instead of using xml (actually this is not good... todo (later))
|
||||||
|
params.mLeftPadding = (params.mOccupiedWidth * 0.1f).toInt()
|
||||||
|
params.mRightPadding = (params.mOccupiedWidth * 0.1f).toInt()
|
||||||
|
params.mBaseWidth = params.mOccupiedWidth - params.mLeftPadding - params.mRightPadding
|
||||||
|
}
|
||||||
|
baseKeys.forEachIndexed { i, row ->
|
||||||
|
val paramsRow = ArrayList<KeyParams>()
|
||||||
|
row.forEach { key ->
|
||||||
|
var keyParams: KeyParams? = null
|
||||||
|
// try parsing a functional key, converting names from florisBoard to what is used here (should be unified)
|
||||||
|
// note that this is ignoring code on those keys, if any
|
||||||
|
val functionalKeyName = when (key.label) {
|
||||||
|
"view_characters" -> "alpha"
|
||||||
|
"view_symbols" -> "symbol"
|
||||||
|
"enter" -> "action"
|
||||||
|
// todo (later): maybe add special moreKeys for phone and number layouts?
|
||||||
|
"." -> if (params.mId.mElementId == KeyboardId.ELEMENT_NUMPAD) "period" else "."
|
||||||
|
"," -> if (params.mId.mElementId == KeyboardId.ELEMENT_NUMPAD) "comma" else ","
|
||||||
|
else -> key.label
|
||||||
|
}
|
||||||
|
if (functionalKeyName.length > 1 && key.type != KeyType.NUMERIC) {
|
||||||
|
try {
|
||||||
|
keyParams = getFunctionalKeyParams(functionalKeyName)
|
||||||
|
} catch (_: Throwable) {} // just use normal label
|
||||||
|
}
|
||||||
|
if (keyParams == null) {
|
||||||
|
keyParams = if (key.type == KeyType.NUMERIC) {
|
||||||
|
val labelFlags = when (params.mId.mElementId) {
|
||||||
|
KeyboardId.ELEMENT_PHONE -> Key.LABEL_FLAGS_ALIGN_LABEL_OFF_CENTER or Key.LABEL_FLAGS_HAS_HINT_LABEL or Key.LABEL_FLAGS_FOLLOW_KEY_LARGE_LETTER_RATIO
|
||||||
|
KeyboardId.ELEMENT_PHONE_SYMBOLS -> 0
|
||||||
|
else -> Key.LABEL_FLAGS_FOLLOW_KEY_LARGE_LETTER_RATIO
|
||||||
|
}
|
||||||
|
key.compute(params).toKeyParams(params, 0.17f, labelFlags or defaultLabelFlags)
|
||||||
|
} else if (key.label.length == 1 && (params.mId.mElementId == KeyboardId.ELEMENT_PHONE || params.mId.mElementId == KeyboardId.ELEMENT_NUMBER))
|
||||||
|
key.compute(params).toKeyParams(params, additionalLabelFlags = Key.LABEL_FLAGS_FOLLOW_KEY_LARGE_LETTER_RATIO or defaultLabelFlags)
|
||||||
|
else
|
||||||
|
key.compute(params).toKeyParams(params, additionalLabelFlags = defaultLabelFlags)
|
||||||
|
}
|
||||||
|
if (key.type != KeyType.NUMERIC && keyParams.mBackgroundType != Key.BACKGROUND_TYPE_ACTION)
|
||||||
|
keyParams.mBackgroundType = Key.BACKGROUND_TYPE_FUNCTIONAL
|
||||||
|
|
||||||
|
if (params.mId.mElementId == KeyboardId.ELEMENT_PHONE && key.popup.main?.getLabel(params)?.length?.let { it > 1 } == true) {
|
||||||
|
keyParams.mMoreKeys = null // the ABC and stuff labels should not create moreKeys
|
||||||
|
}
|
||||||
|
if (keyParams.mLabel?.length?.let { it > 1 } == true && keyParams.mLabel?.startsWith("!string/") == true) {
|
||||||
|
// resolve string label
|
||||||
|
val id = context.resources.getIdentifier(keyParams.mLabel?.substringAfter("!string/"), "string", context.packageName)
|
||||||
|
if (id != 0)
|
||||||
|
keyParams.mLabel = getInLocale(id)
|
||||||
|
}
|
||||||
|
paramsRow.add(keyParams)
|
||||||
|
if (DebugFlags.DEBUG_ENABLED)
|
||||||
|
Log.d(TAG, "adding key ${keyParams.mLabel}, ${keyParams.mCode}")
|
||||||
|
}
|
||||||
|
if (i == baseKeys.lastIndex) { // bottom row needs some adjustments
|
||||||
|
val n = row.indexOfFirst { it.type == KeyType.NUMERIC }
|
||||||
|
if (n != -1) {
|
||||||
|
// make sure the keys next to 0 have normal background
|
||||||
|
paramsRow.getOrNull(n - 1)?.mBackgroundType = Key.BACKGROUND_TYPE_NORMAL
|
||||||
|
paramsRow.getOrNull(n + 1)?.mBackgroundType = Key.BACKGROUND_TYPE_NORMAL
|
||||||
|
|
||||||
|
// make those keys same width as numeric keys except in numpad layout
|
||||||
|
// but determine from row size instead of from elementId, in case user wants to adjust numpad layout
|
||||||
|
if (row.size == baseKeys[0].size) {
|
||||||
|
paramsRow.getOrNull(n - 1)?.mRelativeWidth = paramsRow[n].mRelativeWidth
|
||||||
|
paramsRow.getOrNull(n + 1)?.mRelativeWidth = paramsRow[n].mRelativeWidth
|
||||||
|
} else if (row.size == baseKeys[0].size + 2) {
|
||||||
|
// numpad last row -> make sure the keys next to 0 fit nicely
|
||||||
|
paramsRow.getOrNull(n - 1)?.mRelativeWidth = paramsRow[n].mRelativeWidth * 0.55f
|
||||||
|
paramsRow.getOrNull(n - 2)?.mRelativeWidth = paramsRow[n].mRelativeWidth * 0.45f
|
||||||
|
paramsRow.getOrNull(n + 1)?.mRelativeWidth = paramsRow[n].mRelativeWidth * 0.55f
|
||||||
|
paramsRow.getOrNull(n + 2)?.mRelativeWidth = paramsRow[n].mRelativeWidth * 0.45f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val widthSum = paramsRow.sumOf { it.mRelativeWidth }
|
||||||
|
paramsRow.forEach { it.mRelativeWidth /= widthSum }
|
||||||
|
keysInRows.add(paramsRow)
|
||||||
|
}
|
||||||
|
return keysInRows
|
||||||
|
}
|
||||||
|
|
||||||
private fun parseFunctionalKeys(@StringRes id: Int): List<Pair<List<String>, List<String>>> =
|
private fun parseFunctionalKeys(@StringRes id: Int): List<Pair<List<String>, List<String>>> =
|
||||||
context.getString(id).split("\n").mapNotNull { line ->
|
context.getString(id).split("\n").mapNotNull { line ->
|
||||||
if (line.isBlank()) return@mapNotNull null
|
if (line.isBlank()) return@mapNotNull null
|
||||||
|
@ -332,7 +432,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
FunctionalKey.PERIOD -> KeyParams(
|
FunctionalKey.PERIOD -> KeyParams(
|
||||||
// special period moreKey only in alphabet layout, except for ar and fa
|
// special period moreKey only in alphabet layout, except for ar and fa
|
||||||
// todo: here is not the place to decide this, put it somewhere else (labelPeriod and labelPeriodSymbols?)
|
// todo: here is not the place to decide this, put it somewhere else (labelPeriod and labelPeriodSymbols?)
|
||||||
label ?: if (params.mId.isAlphabetKeyboard || params.mId.locale.language in listOf("ar", "fa")) params.mLocaleKeyTexts.labelPeriod else ".",
|
label ?: getPeriodLabel(),
|
||||||
params,
|
params,
|
||||||
width,
|
width,
|
||||||
Key.LABEL_FLAGS_HAS_POPUP_HINT
|
Key.LABEL_FLAGS_HAS_POPUP_HINT
|
||||||
|
@ -344,10 +444,10 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
moreKeys?.let { getPunctuationMoreKeys() + it } ?: getPunctuationMoreKeys()
|
moreKeys?.let { getPunctuationMoreKeys() + it } ?: getPunctuationMoreKeys()
|
||||||
)
|
)
|
||||||
FunctionalKey.SPACE -> KeyParams(
|
FunctionalKey.SPACE -> KeyParams(
|
||||||
"!icon/space_key|!code/key_space", // !icon/space_key_for_number_layout in number layout, but not on tablet
|
getSpaceLabel(),
|
||||||
params,
|
params,
|
||||||
width, // will not be used for normal space (only in number layouts)
|
width, // will not be used for normal space (only in number layouts)
|
||||||
0, // todo (later): alignIconToBottom for non-tablet number layout -> check what it does / whether it's necessary
|
if (params.mId.isNumberLayout) Key.LABEL_FLAGS_ALIGN_ICON_TO_BOTTOM else 0,
|
||||||
Key.BACKGROUND_TYPE_SPACEBAR,
|
Key.BACKGROUND_TYPE_SPACEBAR,
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
|
@ -474,7 +574,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
// could change definition of numbers to query a range, or have a pre-defined list, but not that crucial
|
// could change definition of numbers to query a range, or have a pre-defined list, but not that crucial
|
||||||
params.mId.mMode in listOf(KeyboardId.MODE_URL, KeyboardId.MODE_EMAIL, KeyboardId.ELEMENT_PHONE, KeyboardId.ELEMENT_NUMBER, KeyboardId.MODE_DATE, KeyboardId.MODE_TIME, KeyboardId.MODE_DATETIME) -> when {
|
params.mId.isNumberLayout || params.mId.mMode in listOf(KeyboardId.MODE_URL, 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 -> createMoreKeysArray(MORE_KEYS_NAVIGATE_PREVIOUS)
|
||||||
action == EditorInfo.IME_ACTION_NEXT -> null
|
action == EditorInfo.IME_ACTION_NEXT -> null
|
||||||
action == EditorInfo.IME_ACTION_PREVIOUS && navigateNext -> createMoreKeysArray(MORE_KEYS_NAVIGATE_NEXT)
|
action == EditorInfo.IME_ACTION_PREVIOUS && navigateNext -> createMoreKeysArray(MORE_KEYS_NAVIGATE_NEXT)
|
||||||
|
@ -536,6 +636,10 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
Toast.makeText(context, message, Toast.LENGTH_LONG).show()
|
Toast.makeText(context, message, Toast.LENGTH_LONG).show()
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
return getInLocale(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getInLocale(@StringRes id: Int): String {
|
||||||
val ril = object : RunInLocale<String>() { // todo (later): simpler way of doing this in a single line?
|
val ril = object : RunInLocale<String>() { // todo (later): simpler way of doing this in a single line?
|
||||||
override fun job(res: Resources) = res.getString(id)
|
override fun job(res: Resources) = res.getString(id)
|
||||||
}
|
}
|
||||||
|
@ -570,11 +674,20 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
return "!icon/shift_key"
|
return "!icon/shift_key"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getPeriodLabel(): String {
|
||||||
|
if (params.mId.isNumberLayout) return "."
|
||||||
|
if (params.mId.isAlphabetKeyboard || params.mId.locale.language in listOf("ar", "fa"))
|
||||||
|
return params.mLocaleKeyTexts.labelPeriod
|
||||||
|
return "."
|
||||||
|
}
|
||||||
|
|
||||||
private fun getCommaLabel(): String {
|
private fun getCommaLabel(): String {
|
||||||
if (params.mId.mMode == KeyboardId.MODE_URL && params.mId.isAlphabetKeyboard)
|
if (params.mId.mMode == KeyboardId.MODE_URL && params.mId.isAlphabetKeyboard)
|
||||||
return "/"
|
return "/"
|
||||||
if (params.mId.mMode == KeyboardId.MODE_EMAIL && params.mId.isAlphabetKeyboard)
|
if (params.mId.mMode == KeyboardId.MODE_EMAIL && params.mId.isAlphabetKeyboard)
|
||||||
return "\\@"
|
return "\\@"
|
||||||
|
if (params.mId.isNumberLayout)
|
||||||
|
return ","
|
||||||
return params.mLocaleKeyTexts.labelComma
|
return params.mLocaleKeyTexts.labelComma
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -582,7 +695,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
val keys = mutableListOf<String>()
|
val keys = mutableListOf<String>()
|
||||||
if (!params.mId.mDeviceLocked)
|
if (!params.mId.mDeviceLocked)
|
||||||
keys.add("!icon/clipboard_normal_key|!code/key_clipboard")
|
keys.add("!icon/clipboard_normal_key|!code/key_clipboard")
|
||||||
if (!params.mId.mEmojiKeyEnabled)
|
if (!params.mId.mEmojiKeyEnabled && !params.mId.isNumberLayout)
|
||||||
keys.add("!icon/emoji_normal_key|!code/key_emoji")
|
keys.add("!icon/emoji_normal_key|!code/key_emoji")
|
||||||
if (!params.mId.mLanguageSwitchKeyEnabled)
|
if (!params.mId.mLanguageSwitchKeyEnabled)
|
||||||
keys.add("!icon/language_switch_key|!code/key_language_switch")
|
keys.add("!icon/language_switch_key|!code/key_language_switch")
|
||||||
|
@ -596,6 +709,8 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
private fun getPunctuationMoreKeys(): Array<String> {
|
private fun getPunctuationMoreKeys(): Array<String> {
|
||||||
if (params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS || params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED)
|
if (params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS || params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED)
|
||||||
return arrayOf("…")
|
return arrayOf("…")
|
||||||
|
if (params.mId.isNumberLayout)
|
||||||
|
return arrayOf(":", "…", ";", "∞", "π", "√", "°", "^")
|
||||||
val moreKeys = params.mLocaleKeyTexts.getMoreKeys("punctuation")!!
|
val moreKeys = params.mLocaleKeyTexts.getMoreKeys("punctuation")!!
|
||||||
if (params.mId.mSubtype.isRtlSubtype) {
|
if (params.mId.mSubtype.isRtlSubtype) {
|
||||||
for (i in moreKeys.indices)
|
for (i in moreKeys.indices)
|
||||||
|
@ -613,6 +728,11 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
return moreKeys
|
return moreKeys
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getSpaceLabel(): String =
|
||||||
|
if (params.mId.mElementId <= KeyboardId.ELEMENT_SYMBOLS_SHIFTED || isTablet())
|
||||||
|
"!icon/space_key|!code/key_space"
|
||||||
|
else "!icon/space_key_for_number_layout|!code/key_space"
|
||||||
|
|
||||||
private fun isTablet() = context.resources.getInteger(R.integer.config_screen_metrics) >= 3
|
private fun isTablet() = context.resources.getInteger(R.integer.config_screen_metrics) >= 3
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -628,6 +748,10 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
id.mElementId == KeyboardId.ELEMENT_SYMBOLS -> SimpleKeyboardParser(params, context).parseLayoutFromAssets("symbols")
|
id.mElementId == KeyboardId.ELEMENT_SYMBOLS -> SimpleKeyboardParser(params, context).parseLayoutFromAssets("symbols")
|
||||||
id.mElementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED
|
id.mElementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED
|
||||||
-> SimpleKeyboardParser(params, context).parseLayoutFromAssets("symbols_shifted")
|
-> SimpleKeyboardParser(params, context).parseLayoutFromAssets("symbols_shifted")
|
||||||
|
id.mElementId == KeyboardId.ELEMENT_NUMPAD -> JsonKeyboardParser(params, context).parseLayoutFromAssets("numpad")
|
||||||
|
id.mElementId == KeyboardId.ELEMENT_NUMBER -> JsonKeyboardParser(params, context).parseLayoutFromAssets("number")
|
||||||
|
id.mElementId == KeyboardId.ELEMENT_PHONE -> JsonKeyboardParser(params, context).parseLayoutFromAssets("phone")
|
||||||
|
id.mElementId == KeyboardId.ELEMENT_PHONE_SYMBOLS -> JsonKeyboardParser(params, context).parseLayoutFromAssets("phone_symbols")
|
||||||
!id.isAlphabetKeyboard -> null
|
!id.isAlphabetKeyboard -> null
|
||||||
layoutFileNames.contains("$layoutName.json") -> JsonKeyboardParser(params, context).parseLayoutFromAssets(layoutName)
|
layoutFileNames.contains("$layoutName.json") -> JsonKeyboardParser(params, context).parseLayoutFromAssets(layoutName)
|
||||||
layoutFileNames.contains("${getSimpleLayoutName(layoutName, params)}.txt")
|
layoutFileNames.contains("${getSimpleLayoutName(layoutName, params)}.txt")
|
||||||
|
@ -701,7 +825,7 @@ data class LayoutInfos(
|
||||||
)
|
)
|
||||||
|
|
||||||
fun String.rtlLabel(params: KeyboardParams): String {
|
fun String.rtlLabel(params: KeyboardParams): String {
|
||||||
if (!params.mId.mSubtype.isRtlSubtype) return this
|
if (!params.mId.mSubtype.isRtlSubtype || params.mId.isNumberLayout) return this
|
||||||
return when (this) {
|
return when (this) {
|
||||||
"{" -> "{|}"
|
"{" -> "{|}"
|
||||||
"}" -> "}|{"
|
"}" -> "}|{"
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.dslul.openboard.inputmethod.latin.common.StringUtils
|
||||||
// char_width_selector and kana_selector throw an error (not yet supported)
|
// char_width_selector and kana_selector throw an error (not yet supported)
|
||||||
// added labelFlags to keyDate
|
// added labelFlags to keyDate
|
||||||
// added manualOrLocked for shift_state_selector
|
// added manualOrLocked for shift_state_selector
|
||||||
|
// added date, time and datetime to VariationSelector
|
||||||
/**
|
/**
|
||||||
* Basic interface for a key data object. Base for all key data objects across the IME, such as text, emojis and
|
* Basic interface for a key data object. Base for all key data objects across the IME, such as text, emojis and
|
||||||
* selectors. The implementation is as abstract as possible, as different features require different implementations.
|
* selectors. The implementation is as abstract as possible, as different features require different implementations.
|
||||||
|
@ -111,9 +112,12 @@ interface KeyData : AbstractKeyData {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toKeyParams(params: KeyboardParams, width: Float = params.mDefaultRelativeKeyWidth, additionalLabelFlags: Int = 0): KeyParams {
|
fun toKeyParams(params: KeyboardParams, width: Float = params.mDefaultRelativeKeyWidth, additionalLabelFlags: Int = 0): KeyParams {
|
||||||
require(type == KeyType.CHARACTER) { "currently only KeyType.CHARACTER is supported" }
|
// numeric keys are assigned a higher width in number layouts
|
||||||
require(groupId == GROUP_DEFAULT) { "currently only KeyData.GROUP_DEFAULT is supported" }
|
require(type == KeyType.CHARACTER || type == KeyType.NUMERIC) { "only KeyType CHARACTER or NUMERIC is supported" }
|
||||||
require(code >= 0) { "functional codes ($code) not (yet) supported" }
|
// allow GROUP_ENTER negative codes so original florisboard number layouts can be used, bu actually it's ignored
|
||||||
|
require(groupId == GROUP_DEFAULT || groupId == GROUP_ENTER) { "currently only GROUP_DEFAULT or GROUP_ENTER is supported" }
|
||||||
|
// allow some negative codes so original florisboard number layouts can be used, those codes are actually ignored
|
||||||
|
require(code >= 0 || code == -7 || code == -201 || code == -202) { "functional code $code not (yet) supported" }
|
||||||
require(code != KeyCode.UNSPECIFIED || label.isNotEmpty()) { "key has no code and no label" }
|
require(code != KeyCode.UNSPECIFIED || label.isNotEmpty()) { "key has no code and no label" }
|
||||||
|
|
||||||
return if (code == KeyCode.UNSPECIFIED || code == KeyCode.MULTIPLE_CODE_POINTS) {
|
return if (code == KeyCode.UNSPECIFIED || code == KeyCode.MULTIPLE_CODE_POINTS) {
|
||||||
|
@ -258,6 +262,9 @@ data class VariationSelector(
|
||||||
val uri: AbstractKeyData? = null,
|
val uri: AbstractKeyData? = null,
|
||||||
val normal: AbstractKeyData? = null,
|
val normal: AbstractKeyData? = null,
|
||||||
val password: AbstractKeyData? = null,
|
val password: AbstractKeyData? = null,
|
||||||
|
val date: AbstractKeyData? = null,
|
||||||
|
val time: AbstractKeyData? = null,
|
||||||
|
val datetime: AbstractKeyData? = null,
|
||||||
) : AbstractKeyData {
|
) : AbstractKeyData {
|
||||||
override fun compute(params: KeyboardParams): KeyData? {
|
override fun compute(params: KeyboardParams): KeyData? {
|
||||||
return when {
|
return when {
|
||||||
|
@ -267,6 +274,9 @@ data class VariationSelector(
|
||||||
params.mId.passwordInput() -> password ?: default
|
params.mId.passwordInput() -> password ?: default
|
||||||
params.mId.mMode == KeyboardId.MODE_EMAIL -> email ?: default
|
params.mId.mMode == KeyboardId.MODE_EMAIL -> email ?: default
|
||||||
params.mId.mMode == KeyboardId.MODE_URL -> uri ?: default
|
params.mId.mMode == KeyboardId.MODE_URL -> uri ?: default
|
||||||
|
params.mId.mMode == KeyboardId.MODE_DATE -> date ?: default
|
||||||
|
params.mId.mMode == KeyboardId.MODE_TIME -> time ?: default
|
||||||
|
params.mId.mMode == KeyboardId.MODE_DATETIME -> datetime ?: default
|
||||||
else -> default
|
else -> default
|
||||||
}?.compute(params)
|
}?.compute(params)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue