add layout infos for new parser, to be (re)moved after removing old parser

This commit is contained in:
Helium314 2023-11-30 11:01:03 +01:00
parent fd247eeb50
commit 99cf72684d
3 changed files with 83 additions and 21 deletions

View file

@ -64,20 +64,20 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
// todo: further plan // todo: further plan
// migrate other languages/layouts to this style // migrate other languages/layouts to this style
// may be tricky in some cases, like additional row, or no shift key // integrated number rows should be removed / ignored when migrating
// also the integrated number row is weird together with the number row setting, and should be removed / ignored
// at least some of these layouts will need more complicated definition and have separate shift layouts
// test the zwnj key // test the zwnj key
// label flags: some should be set by keyboard, not by row/letter // test whether the layouts really are the same (screenshots for everything added, compare old and new parser)
// e.g. arabic looks weird with number row in holo being bold, but all other letters normal // check all the keyboard_layout_set and kbd_files for things like touchPositionCorrectionData
// careful with korean, iirc the layouts are copied somewhere in the code -> try reading them instead of having them duplicate hardcoded // some keyboard_layout_set have supportedScript that is enum synced with script id in ScriptUtils
// check the kbd_files for thing like touchPositionCorrectionData // that's one more reason for using language tags...
// issues: // issues:
// armenian has label flag fontNormal on all keys -> how to do? define on every letter, or have some other way of doing this?
// add such a label flag to languageKeyTexts (apply only to alphabet layouts)
// fontNormal: armenian, urdu, thai, ...
// armenian bottom row: functional keys should be narrower // armenian bottom row: functional keys should be narrower
// urdu: no labels because the moreKeys are languageMoreKeys -> need the moreKeys setting soon (at least setting to show first language moreKey if no symbol) // rtl parentheses hint label (urdu and more)
// urdu and others: no labels because the moreKeys are languageMoreKeys -> need the moreKeys setting soon (at least setting to show first language moreKey if no symbol)
// setting: symbol morekeys(s): layout default, take from symbols, layout default but fill from symbols if empty
// setting: hint label: from symbol morekey only, symbol but language if none, first choice on long press
// (later): setting which moreKeys to prefer (default: symbol or important language, always symbol, always language)
// and have some setting to enable configuring this per locale (in language settings -> potentially should not be a dialog any more but a fragment?)
// migrate pcqwerty to this style // migrate pcqwerty to this style
// this will be more complicated... // this will be more complicated...
// linked shift keys might be easy // linked shift keys might be easy
@ -95,6 +95,8 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
// parsing could be done into a single row, which is then split as needed // parsing could be done into a single row, which is then split as needed
// this might help with split layout (no change in key size, but in number of rows) // this might help with split layout (no change in key size, but in number of rows)
// 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)
// mention in subtitle that they may not be displayed properly, depending on the app you're writing in
// migrate moreKeys and moreSuggestions to this style? // 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?)
// remove the old parser // remove the old parser
@ -162,7 +164,7 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
fun loadFromXml(xmlId: Int, id: KeyboardId): KeyboardBuilder<KP> { fun loadFromXml(xmlId: Int, id: KeyboardId): KeyboardBuilder<KP> {
if (Settings.getInstance().current.mUseNewKeyboardParsing if (Settings.getInstance().current.mUseNewKeyboardParsing
&& id.mElementId != KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED && id.mElementId != KeyboardId.ELEMENT_SYMBOLS_SHIFTED // && id.mElementId != KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED && id.mElementId != KeyboardId.ELEMENT_SYMBOLS_SHIFTED
&& this::class == KeyboardBuilder::class // otherwise this will apply to moreKeys and moreSuggestions, and then some parameters are off && this::class == KeyboardBuilder::class // otherwise this will apply to moreKeys and moreSuggestions, and then some parameters are off
) { ) {
if (loadFromAssets(id) != null) if (loadFromAssets(id) != null)

View file

@ -7,6 +7,8 @@ import android.view.inputmethod.EditorInfo
import android.widget.Toast import android.widget.Toast
import org.dslul.openboard.inputmethod.keyboard.Key import org.dslul.openboard.inputmethod.keyboard.Key
import org.dslul.openboard.inputmethod.keyboard.Key.KeyParams import org.dslul.openboard.inputmethod.keyboard.Key.KeyParams
import org.dslul.openboard.inputmethod.keyboard.Key.LABEL_FLAGS_AUTO_X_SCALE
import org.dslul.openboard.inputmethod.keyboard.Key.LABEL_FLAGS_FONT_NORMAL
import org.dslul.openboard.inputmethod.keyboard.KeyboardId import org.dslul.openboard.inputmethod.keyboard.KeyboardId
import org.dslul.openboard.inputmethod.keyboard.KeyboardTheme import org.dslul.openboard.inputmethod.keyboard.KeyboardTheme
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardIconsSet import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardIconsSet
@ -34,7 +36,8 @@ import org.dslul.openboard.inputmethod.latin.utils.sumOf
* Currently the number, phone and numpad layouts are not compatible with this parser. * 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 defaultLabelFlags = if (!params.mId.isAlphabetKeyboard) private val infos = layoutInfos(params)
private val defaultLabelFlags = infos.defaultLabelFlags or if (!params.mId.isAlphabetKeyboard)
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
@ -47,15 +50,20 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
fun parseLayoutString(layoutContent: String): ArrayList<ArrayList<KeyParams>> { fun parseLayoutString(layoutContent: String): ArrayList<ArrayList<KeyParams>> {
params.readAttributes(context, null) params.readAttributes(context, null)
val keysInRows = ArrayList<ArrayList<KeyParams>>() if (infos.touchPositionCorrectionData == null) // need to set correctly, as it's not properly done in readAttributes with attr = null
params.mTouchPositionCorrection.load(emptyArray())
else
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)
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()
} else if (!params.mId.mNumberRowEnabled && params.mId.isAlphabetKeyboard) { } else if (!params.mId.mNumberRowEnabled && params.mId.isAlphabetKeyboard && params.mId.locale.language != "ko") {
// add number to the first 10 keys in first row // add number to the first 10 keys in first row
// setting the correct moreKeys is handled in PopupSet // setting the correct moreKeys is handled in PopupSet
// not for korean layouts, todo: should be decided in the layout, not in the parser
baseKeys.first().take(10).forEachIndexed { index, keyData -> keyData.popup.numberIndex = index } baseKeys.first().take(10).forEachIndexed { index, keyData -> keyData.popup.numberIndex = index }
} }
val functionalKeysReversed = parseFunctionalKeys().reversed() val functionalKeysReversed = parseFunctionalKeys().reversed()
@ -166,8 +174,12 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
context.getString(R.string.key_def_functional).split("\n").mapNotNull { line -> context.getString(R.string.key_def_functional).split("\n").mapNotNull { line ->
if (line.isBlank()) return@mapNotNull null if (line.isBlank()) return@mapNotNull null
val p = line.split(";") val p = line.split(";")
p.first().let { if (it.isBlank()) emptyList() else it.split(",") } to splitFunctionalKeyDefs(p.first()) to splitFunctionalKeyDefs(p.last())
p.last().let { if (it.isBlank()) emptyList() else it.split(",") } }
private fun splitFunctionalKeyDefs(def: String): List<String> {
if (def.isBlank()) return emptyList()
return def.split(",").filter { infos.hasShiftKey || !it.startsWith("shift") }
} }
private fun getBottomRowAndAdjustBaseKeys(baseKeys: MutableList<List<KeyData>>): ArrayList<KeyParams> { private fun getBottomRowAndAdjustBaseKeys(baseKeys: MutableList<List<KeyData>>): ArrayList<KeyParams> {
@ -225,7 +237,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
if (params.mId.mEmojiKeyEnabled) if (params.mId.mEmojiKeyEnabled)
bottomRow.add(getFunctionalKeyParams(FunctionalKey.EMOJI)) bottomRow.add(getFunctionalKeyParams(FunctionalKey.EMOJI))
bottomRow.add(keyParams) bottomRow.add(keyParams)
if (params.mId.locale.language in languagesThatNeedZwnjKey) if (infos.hasZwnjKey)
bottomRow.add(getFunctionalKeyParams(FunctionalKey.ZWNJ)) bottomRow.add(getFunctionalKeyParams(FunctionalKey.ZWNJ))
} }
} else { } else {
@ -571,6 +583,40 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
"south_slavic", "east_slavic" -> params.mId.locale.language // layouts split per language now, much less convoluted "south_slavic", "east_slavic" -> params.mId.locale.language // layouts split per language now, much less convoluted
else -> layoutName else -> layoutName
} }
// todo: layoutInfos should be stored in method.xml (imeSubtypeExtraValue)
// or somewhere else... some replacement for keyboard_layout_set xml maybe
// move it after old parser is removed
// currently only labelFlags are used
// touchPositionCorrectionData needs to be loaded, currently always holo is applied in readAttributes
private fun layoutInfos(params: KeyboardParams): LayoutInfos {
val name = params.mId.mSubtype.keyboardLayoutSetName
val labelFlags = if (!params.mId.isAlphabetKeyboard) 0 else when (name) {
"armenian_phonetic", "arabic", "arabic_pc", "bengali", "bengali_akkhor", "bengali_unijoy",
"farsi", "hindi", "hindi_compact", "lao", "marathi", "nepali_romanized", "nepali_traditional",
"thai", "urdu" -> LABEL_FLAGS_FONT_NORMAL
"kannada", "khmer", "malayalam", "sinhala", "tamil", "telugu" -> LABEL_FLAGS_FONT_NORMAL or LABEL_FLAGS_AUTO_X_SCALE
else -> 0
}
// only for alphabet, but some exceptions for shift layouts
val enableProximityCharsCorrection = params.mId.isAlphabetKeyboard && when (name) {
// todo: test effect on correction (just add qwerty to the list for testing)
"akkhor", "georgian", "hindi", "lao", "nepali_romanized", "nepali_traditional", "sinhala", "thai" ->
params.mId.mElementId == KeyboardId.ELEMENT_ALPHABET
else -> true
}
// this is weird...
val allowRedundantMoreKeys = name != "nordic" && name != "serbian_qwertz"
// essentially this is default for 4 row and non-alphabet layouts, maybe this could be determined automatically instead of using a list
// todo: check the difference between default (i.e. none) and holo (test behavior on keyboard)
// todo: null for MoreKeysKeyboard only
val touchPositionCorrectionData = if (params.mId.isAlphabetKeyboard && name in listOf("armenian_phonetic", "khmer", "lao", "malayalam", "pcqwerty", "thai"))
R.array.touch_position_correction_data_default
else R.array.touch_position_correction_data_holo
val hasZwnjKey = params.mId.locale.language in listOf("fa", "ne", "kn", "te") // determine from language, user might have custom layout
val hasShiftKey = name !in listOf("hindi_compact", "arabic", "arabic_pc", "hebrew", "kannada", "malayalam", "marathi", "farsi", "tamil", "telugu")
return LayoutInfos(labelFlags, enableProximityCharsCorrection, allowRedundantMoreKeys, touchPositionCorrectionData, hasZwnjKey, hasShiftKey)
}
} }
protected enum class FunctionalKey { protected enum class FunctionalKey {
@ -579,6 +625,20 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
} }
data class LayoutInfos(
val defaultLabelFlags: Int = 0,
// disabled by default, but enabled for all alphabet layouts
// currently set in keyboardLayoutSet
val enableProximityCharsCorrection: Boolean = false,
val allowRedundantMoreKeys: Boolean = true, // only false for nordic and serbian_qwertz, could add a setting when doing the moreKeys customizing
// there is holo, default and null
// null only for moreKeys keyboard
// currently read as part of readAttributes, and thus wrong with the new parser
val touchPositionCorrectionData: Int? = null,
val hasZwnjKey: Boolean = false,
val hasShiftKey: Boolean = true,
)
fun String.rtlLabel(params: KeyboardParams): String { fun String.rtlLabel(params: KeyboardParams): String {
if (!params.mId.mSubtype.isRtlSubtype) return this if (!params.mId.mSubtype.isRtlSubtype) return this
return when (this) { return when (this) {
@ -610,6 +670,3 @@ private const val MORE_KEYS_NAVIGATE_EMOJI_PREVIOUS = "!fixedColumnOrder!3,!need
private const val MORE_KEYS_NAVIGATE_EMOJI = "!icon/clipboard_action_key|!code/key_clipboard,!icon/emoji_action_key|!code/key_emoji" private const val MORE_KEYS_NAVIGATE_EMOJI = "!icon/clipboard_action_key|!code/key_clipboard,!icon/emoji_action_key|!code/key_emoji"
private const val MORE_KEYS_NAVIGATE_EMOJI_NEXT = "!fixedColumnOrder!3,!needsDividers!,!icon/clipboard_action_key|!code/key_clipboard,!icon/emoji_action_key|!code/key_emoji,!icon/next_key|!code/key_action_next" private const val MORE_KEYS_NAVIGATE_EMOJI_NEXT = "!fixedColumnOrder!3,!needsDividers!,!icon/clipboard_action_key|!code/key_clipboard,!icon/emoji_action_key|!code/key_emoji,!icon/next_key|!code/key_action_next"
private const val MORE_KEYS_NAVIGATE_EMOJI_PREVIOUS_NEXT = "!fixedColumnOrder!4,!needsDividers!,!icon/previous_key|!code/key_action_previous,!icon/clipboard_action_key|!code/key_clipboard,!icon/emoji_action_key|!code/key_emoji,!icon/next_key|!code/key_action_next" private const val MORE_KEYS_NAVIGATE_EMOJI_PREVIOUS_NEXT = "!fixedColumnOrder!4,!needsDividers!,!icon/previous_key|!code/key_action_previous,!icon/clipboard_action_key|!code/key_clipboard,!icon/emoji_action_key|!code/key_emoji,!icon/next_key|!code/key_action_next"
// farsi|kannada|nepali_romanized|nepali_traditional|telugu"
private val languagesThatNeedZwnjKey = listOf("fa", "ne", "kn", "te")

View file

@ -7,3 +7,6 @@ One key per line, two consecutive newlines mark a row end.
Key format: [label] [moreKeys], all separated by space, e.g. `a 0 + *` will create a key with text a, and the keys `0`, `+`, and `*` on long press. Some characters currently require escape using `\` (todo: add the list, or better add them in code instead of requiring it in the layouts). Key format: [label] [moreKeys], all separated by space, e.g. `a 0 + *` will create a key with text a, and the keys `0`, `+`, and `*` on long press. Some characters currently require escape using `\` (todo: add the list, or better add them in code instead of requiring it in the layouts).
Special symbols: `%` (only for language-dependent moreKeys, not user defined, also better use sth like `%%%`) acts as placeholder for normal moreKeys. `$$$` will be replaced by currency (or default to `$`). Special symbols: `%` (only for language-dependent moreKeys, not user defined, also better use sth like `%%%`) acts as placeholder for normal moreKeys. `$$$` will be replaced by currency (or default to `$`).
Language-dependent moreKeys should never contain "special" moreKeys, i.e. those starting with `!` (exception for `punctuation`) Language-dependent moreKeys should never contain "special" moreKeys, i.e. those starting with `!` (exception for `punctuation`)
## json
Character layouts from FlorisBoard, but missing code or label will be determined automatically. And not everything supported...