improvements for tablet layouts with new parser

This commit is contained in:
Helium314 2023-12-04 12:11:53 +01:00
parent 8edf006a32
commit 2232bc3848
11 changed files with 78 additions and 59 deletions

View file

@ -73,7 +73,7 @@ Features that may go unnoticed
* Reduce space between keys, with option to use old values, https://github.com/Helium314/openboard/pull/8 * Reduce space between keys, with option to use old values, https://github.com/Helium314/openboard/pull/8
* Fix number row not split in split keyboard view, https://github.com/Helium314/openboard/pull/27 * Fix number row not split in split keyboard view, https://github.com/Helium314/openboard/pull/27
* Fix issue with spell checker incorrectly flagging words before a period as wrong on newer Android versions, https://github.com/openboard-team/openboard/pull/679 * Fix issue with spell checker incorrectly flagging words before a period as wrong on newer Android versions, https://github.com/openboard-team/openboard/pull/679
* maybe not properly fixed, this causes some other issues * maybe not properly fixed, this causes some other issues, https://github.com/Helium314/openboard/issues/55
* Fix always-dark settings on some Android versions, https://github.com/Helium314/openboard/pull/69 * Fix always-dark settings on some Android versions, https://github.com/Helium314/openboard/pull/69
* Fix bug with space before word being deleted in some apps / input fields, https://github.com/Helium314/openboard/commit/ce0bf06545c4547d3fc5791cc769508db0a89e87 * Fix bug with space before word being deleted in some apps / input fields, https://github.com/Helium314/openboard/commit/ce0bf06545c4547d3fc5791cc769508db0a89e87
* Allow using auto theme on some devices with Android 9 * Allow using auto theme on some devices with Android 9
@ -82,11 +82,14 @@ Features that may go unnoticed
* Updated translations * Updated translations
* Open dictionary files with the app * Open dictionary files with the app
* Add more options to the language switch key * Add more options to the language switch key
* New keyboard parser (no need to use `tools:make-keyboard-text:makeText` any more)
* Can use simple text files or JSON files as used by [FlorisBoard](https://github.com/florisboard/florisboard/tree/master/app/src/main/assets/ime/keyboard/org.florisboard.layouts/layouts)
## The rough plan/todo before "full" release ## The rough plan/todo before "full" release
* Finish keyboard parsing upgrades * Finish keyboard parsing upgrades
* In the end, layouts should be defined in either simple text files, or json files, ideally in same format as used by [FlorisBoard](https://github.com/florisboard/florisboard/tree/master/app/src/main/assets/ime/keyboard/org.florisboard.layouts/layouts)
* Users should be allowed to add their own layouts * Users should be allowed to add their own layouts
* Determine symbol popup keys from symbols layout instead of hardcoding them to the layout (still allow layout to override or add popup keys)
* Allow users more control over popup keys (which hint label to show, which popup keys (language, layout, symbols) to show first or at all)
* Overhaul the view system * Overhaul the view system
* Have a fixed height common to all views (keyboard, emoji, clipboard) * Have a fixed height common to all views (keyboard, emoji, clipboard)
* Should allow for more flexible one-handed mode (though the actual one-handed mode changes may be implemented later) * Should allow for more flexible one-handed mode (though the actual one-handed mode changes may be implemented later)

View file

@ -18,6 +18,7 @@ punctuation !fixedColumnOrder!7 ٕ|ٕ ٔ|ٔ ْ|ْ ٍ|ٍ ٌ|ٌ ً|ً ّ|ّ
alphabet: أ‌ب‌ج alphabet: أ‌ب‌ج
symbol: ٣٢١؟ symbol: ٣٢١؟
comma: ، comma: ،
question: ؟
[number_row] [number_row]
١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩ ٠ ١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩ ٠

View file

@ -11,6 +11,7 @@ punctuation !fixedColumnOrder!7 ٕ|ٕ ْ|ْ ّ|ّ ٌ|ٌ ٍ|ٍ ً|ً ٔ|ٔ
alphabet: ا‌ب‌پ alphabet: ا‌ب‌پ
symbol: ۳۲۱؟ symbol: ۳۲۱؟
comma: ، comma: ،
question: ؟
[number_row] [number_row]
۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹ ۰ ۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹ ۰

View file

@ -25,6 +25,7 @@ alphabet: اب‌پ
comma: ، comma: ،
symbol: ۳۲۱؟ symbol: ۳۲۱؟
period: ۔ period: ۔
question: ؟
[number_row] [number_row]
۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹ ۰ ۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹ ۰

View file

@ -25,4 +25,4 @@ $$$
: :
؛ ; ؛ ;
! !
؟ ? ¿ ؟

View file

@ -978,6 +978,7 @@ public class Key implements Comparable<Key> {
public static KeyParams newSpacer(final KeyboardParams params, final float relativeWidth) { public static KeyParams newSpacer(final KeyboardParams params, final float relativeWidth) {
final KeyParams spacer = new KeyParams(params); final KeyParams spacer = new KeyParams(params);
spacer.mRelativeWidth = relativeWidth; spacer.mRelativeWidth = relativeWidth;
spacer.mRelativeHeight = params.mDefaultRelativeRowHeight;
return spacer; return spacer;
} }

View file

@ -63,30 +63,14 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
return this return this
// todo: further plan // todo: further plan
// migrate other languages/layouts to this style
// test whether the layouts really are the same
// comparing params with both parsers looks good, see list of detected differences below
// still need to check moreKeys, there will be many more differences that might just be minor
// write down a list of differences, ask users to open issues if they don't like them
// some keyboard_layout_set have supportedScript that is enum synced with script id in ScriptUtils
// that's one more reason for using language tags...
// but currently it's still read from xml outside the keyboard parser, so that's fine for now
// issues:
// armenian bottom row (and some more): functional keys could be narrower
// 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 morekey(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)
// (later): setting whether to show duplicate moreKeys (describe properly what it actually does)
// and have some setting to enable configuring this per locale (in language settings -> potentially should not be a dialog any more but a fragment?)
// label flags are horrible to "decompile" when viewing a layout
// 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
// distance below number row with high row, but reduced key height? // distance below number row with high row, but reduced key height?
// consider settings key needs to disappear if device is locked // consider settings key needs to disappear if device is locked
// ignore number row setting? // ignore number row setting to avoid duplicate number row?
// and test tablet layout!
// do the moreKeys thing (only now, because pc layout may change stuff)
// migrate keypad layouts to this style // migrate keypad layouts to this style
// will need more configurable layout definition -> another parser, or do it with compatible jsons // 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?
@ -100,9 +84,16 @@ 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
// 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?
// 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?)
// setting which moreKeys to prefer (default: symbol or important language, always symbol, always language)
// setting whether to show duplicate moreKeys (describe properly what it actually does)
// some keyboard_layout_set have supportedScript that is enum synced with script id in ScriptUtils
// that's one more reason for using language tags...
// currently it's still read from xml outside the keyboard parser, but should still go to some other place
// maybe use scriptUtils to determine, just make sure it's correct (also for hindi and serbian!)
// remove the old parser // remove the old parser
// then finally the spanish/german/swiss/nordic layouts can be removed and replaced by some hasExtraKeys parameter // then finally the spanish/german/swiss/nordic layouts can be removed and replaced by some hasExtraKeys parameter
// also the eo check could then be removed // also the eo check could then be removed
@ -155,7 +146,7 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
// autoXScale: com key, action keys, some on phone layout, some non-latin languages // autoXScale: com key, action keys, some on phone layout, some non-latin languages
// autoScale: only one single letter in khmer layout (includes autoXScale) // autoScale: only one single letter in khmer layout (includes autoXScale)
// preserveCase: action key + more keys, com key, shift keys // preserveCase: action key + more keys, com key, shift keys
// shiftedLetterActivated: period and some keys on pcqwerty, tablet only // shiftedLetterActivated: period and some keys on pcqwerty, tablet only (wtf, when enabled can't open moreKeys -> remove? or what would be the use?)
// fromCustomActionLabel: action key with customLabelActionKeyStyle -> check parser where to get this info // fromCustomActionLabel: action key with customLabelActionKeyStyle -> check parser where to get this info
// followFunctionalTextColor: number mode keys, action key // followFunctionalTextColor: number mode keys, action key
// keepBackgroundAspectRatio: lxx and rounded action more keys, lxx no-border action and emoji, moreKeys keyboard view // keepBackgroundAspectRatio: lxx and rounded action more keys, lxx no-border action and emoji, moreKeys keyboard view
@ -189,18 +180,6 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
return@forEachIndexed return@forEachIndexed
} }
xmlRow2.forEachIndexed { index1, xmlParams -> xmlRow2.forEachIndexed { index1, xmlParams ->
// todo: compare tablet layouts (how to best force it for both parsers?)
// just rename the sw600 folders to sw 360
// ->
// to shift symbols label should be ~ [ <
// last symbols row should be \ = * " ' : ; ! ? (but is * " ' : ; ! ? ! ?)
// last shift symbols row should have inverted ! and ?
// some different label flags
// ar: last symbols row should be \ = * " ' : ; ! ؟ (but is * « » : ; ! ؟ ! ?)
// ar: layout should not have ! and ? added (just empty space here...)
// ru, sr (both), others don't have a right shift key (come on...)
// but bulgarian (default) has -> not even per language
// armenian (and probably other 4 row layouts) messed up (delete key should be in first for, not x from bottom)
val keyParams = row[index1] val keyParams = row[index1]
if (keyParams.mLabel != xmlParams.mLabel) if (keyParams.mLabel != xmlParams.mLabel)
// currency keys (shift symbol) arranged differently // currency keys (shift symbol) arranged differently

View file

@ -5,6 +5,7 @@ import android.content.res.Resources
import android.util.Log import android.util.Log
import android.view.inputmethod.EditorInfo import android.view.inputmethod.EditorInfo
import android.widget.Toast import android.widget.Toast
import androidx.annotation.StringRes
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.KeyboardId import org.dslul.openboard.inputmethod.keyboard.KeyboardId
@ -12,7 +13,6 @@ 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.toTextKey
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
@ -75,28 +75,29 @@ 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 functionalKeysReversed = parseFunctionalKeys().reversed() val functionalKeysReversed = parseFunctionalKeys(R.string.key_def_functional).reversed()
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) { val row: List<KeyData> = if (i == 0 && isTablet()) {
// add bottom row extra keys // add bottom row extra keys
// todo: question mark might be different -> get it from localeKeyTexts val tabletExtraKeys = params.mLocaleKeyTexts.getTabletExtraKeys(params.mId.mElementId)
// also, maybe check device dimension int instead of getting this from resources, then using language labels is easier tabletExtraKeys.first + it + tabletExtraKeys.second
// and in shift symbols it should be inverted question/exclamation marks
it + context.getString(R.string.key_def_extra_bottom_right)
.split(",").mapNotNull { if (it.isBlank()) null else it.trim().toTextKey(labelFlags = Key.LABEL_FLAGS_FONT_DEFAULT) }
} else { } else {
it it
} }
// parse functional keys for this row (if any) // parse functional keys for this row (if any)
val outerFunctionalKeyDefs = if (i == baseKeys.lastIndex && functionalKeysTop.isNotEmpty()) functionalKeysTop.first()
else emptyList<String>() to emptyList()
val functionalKeysDefs = if (i < functionalKeysReversed.size) functionalKeysReversed[i] val functionalKeysDefs = if (i < functionalKeysReversed.size) functionalKeysReversed[i]
else emptyList<String>() to emptyList() else emptyList<String>() to emptyList()
val functionalKeysLeft = functionalKeysDefs.first.map { getFunctionalKeyParams(it) } // if we have a top row and top row entries from normal functional key defs, use top row as outer keys
val functionalKeysRight = functionalKeysDefs.second.map { getFunctionalKeyParams(it) } val functionalKeysLeft = outerFunctionalKeyDefs.first.map { getFunctionalKeyParams(it) } + functionalKeysDefs.first.map { getFunctionalKeyParams(it) }
val functionalKeysRight = functionalKeysDefs.second.map { getFunctionalKeyParams(it) } + outerFunctionalKeyDefs.second.map { getFunctionalKeyParams(it) }
val paramsRow = ArrayList<KeyParams>(functionalKeysLeft) val paramsRow = ArrayList<KeyParams>(functionalKeysLeft)
// determine key width, maybe scale factor for keys, and spacers to add // determine key width, maybe scale factor for keys, and spacers to add
@ -152,7 +153,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
// so the symbols keyboard is higher than the normal one // so the symbols keyboard is higher than the normal one
// not a new issue, but should be solved in this migration // not a new issue, but should be solved in this migration
// how? possibly scale all keyboards to height of main alphabet? (consider suggestion strip) // how? possibly scale all keyboards to height of main alphabet? (consider suggestion strip)
keysInRows.forEach { key -> key.forEach { it.mRelativeHeight *= heightRescale } } keysInRows.forEach { row -> row.forEach { it.mRelativeHeight *= heightRescale } }
} }
return keysInRows return keysInRows
@ -184,8 +185,8 @@ 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 parseFunctionalKeys(): List<Pair<List<String>, List<String>>> = private fun parseFunctionalKeys(@StringRes id: Int): List<Pair<List<String>, List<String>>> =
context.getString(R.string.key_def_functional).split("\n").mapNotNull { line -> context.getString(id).split("\n").mapNotNull { line ->
if (line.isBlank()) return@mapNotNull null if (line.isBlank()) return@mapNotNull null
val p = line.split(";") val p = line.split(";")
splitFunctionalKeyDefs(p.first()) to splitFunctionalKeyDefs(p.last()) splitFunctionalKeyDefs(p.first()) to splitFunctionalKeyDefs(p.last())
@ -491,6 +492,17 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
moreKeys.add("$replacementText|${iconPrefixRemoved.substringAfter("|")}") moreKeys.add("$replacementText|${iconPrefixRemoved.substringAfter("|")}")
} }
} }
// remove emoji shortcut on enter in tablet mode (like original, because bottom row always has an emoji key)
// (probably not necessary, but whatever)
if (isTablet() && moreKeys.remove("!icon/emoji_action_key|!code/key_emoji")) {
val i = moreKeys.indexOfFirst { it.startsWith("!fixedColumnOrder") }
if (i > -1) {
val n = moreKeys[i].substringAfter("!fixedColumnOrder!").toIntOrNull()
if (n != null)
moreKeys[i] = moreKeys[i].replace(n.toString(), (n - 1).toString())
}
// remove emoji on enter, because tablet layout has a separate emoji key
}
return moreKeys.toTypedArray() return moreKeys.toTypedArray()
} }
@ -531,7 +543,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
if (elementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED) if (elementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED)
return params.mLocaleKeyTexts.labelSymbol return params.mLocaleKeyTexts.labelSymbol
if (elementId == KeyboardId.ELEMENT_SYMBOLS) if (elementId == KeyboardId.ELEMENT_SYMBOLS)
return params.mLocaleKeyTexts.labelShiftSymbol return params.mLocaleKeyTexts.getShiftSymbolLabel(isTablet())
if (elementId == KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED || elementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED if (elementId == KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED || elementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED
|| elementId == KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED || elementId == KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED) || elementId == KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED || elementId == KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED)
return "!icon/shift_key_shifted" return "!icon/shift_key_shifted"
@ -569,8 +581,8 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
for (i in moreKeys.indices) for (i in moreKeys.indices)
moreKeys[i] = moreKeys[i].rtlLabel(params) // for parentheses moreKeys[i] = moreKeys[i].rtlLabel(params) // for parentheses
} }
if (context.resources.getInteger(R.integer.config_screen_metrics) >= 3 && moreKeys.contains("!") && moreKeys.contains("?")) { if (isTablet() && moreKeys.contains("!") && moreKeys.contains("?")) {
// we have a tablet, remove ! and ? keys and reduce number in autoColumnOrder // remove ! and ? keys and reduce number in autoColumnOrder
// this makes use of removal of empty moreKeys in MoreKeySpec.insertAdditionalMoreKeys // this makes use of removal of empty moreKeys in MoreKeySpec.insertAdditionalMoreKeys
moreKeys[moreKeys.indexOf("!")] = "" moreKeys[moreKeys.indexOf("!")] = ""
moreKeys[moreKeys.indexOf("?")] = "" moreKeys[moreKeys.indexOf("?")] = ""
@ -581,6 +593,8 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
return moreKeys return moreKeys
} }
private fun isTablet() = context.resources.getInteger(R.integer.config_screen_metrics) >= 3
companion object { companion object {
private val TAG = KeyboardParser::class.simpleName private val TAG = KeyboardParser::class.simpleName

View file

@ -3,6 +3,7 @@ package org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser
import android.content.Context import android.content.Context
import org.dslul.openboard.inputmethod.keyboard.Key import org.dslul.openboard.inputmethod.keyboard.Key
import org.dslul.openboard.inputmethod.keyboard.KeyboardId
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.toTextKey import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.floris.toTextKey
@ -20,12 +21,13 @@ class LocaleKeyTexts(dataStream: InputStream?, locale: Locale) {
private set private set
var labelAlphabet = "ABC" var labelAlphabet = "ABC"
private set private set
var labelShiftSymbol = "= \\\\ <" private var labelShiftSymbol = "= \\\\ <"
private set private var labelShiftSymbolTablet = "~ [ <"
var labelComma = "," var labelComma = ","
private set private set
var labelPeriod = "." var labelPeriod = "."
private set private set
private var labelQuestion = "?"
val currencyKey = getCurrencyKey(locale) val currencyKey = getCurrencyKey(locale)
private var numberKeys = ((1..9) + 0).map { it.toString() } private var numberKeys = ((1..9) + 0).map { it.toString() }
private val numbersMoreKeys = arrayOf( private val numbersMoreKeys = arrayOf(
@ -51,8 +53,8 @@ class LocaleKeyTexts(dataStream: InputStream?, locale: Locale) {
moreKeys["\""] = arrayOf("!fixedColumnOrder!5", "", "", "", "«", "»") moreKeys["\""] = arrayOf("!fixedColumnOrder!5", "", "", "", "«", "»")
if ("!" !in moreKeys) if ("!" !in moreKeys)
moreKeys["!"] = arrayOf("¡") moreKeys["!"] = arrayOf("¡")
if ("?" !in moreKeys) if (labelQuestion !in moreKeys)
moreKeys["?"] = arrayOf("¿") moreKeys[labelQuestion] = if (labelQuestion == "?") arrayOf("¿") else arrayOf("?", "¿")
if ("punctuation" !in moreKeys) if ("punctuation" !in moreKeys)
moreKeys["punctuation"] = arrayOf("${Key.MORE_KEYS_AUTO_COLUMN_ORDER}8", "\\,", "?", "!", "#", ")", "(", "/", ";", "'", "@", ":", "-", "\"", "+", "\\%", "&") moreKeys["punctuation"] = arrayOf("${Key.MORE_KEYS_AUTO_COLUMN_ORDER}8", "\\,", "?", "!", "#", ")", "(", "/", ";", "'", "@", ":", "-", "\"", "+", "\\%", "&")
} }
@ -80,6 +82,19 @@ class LocaleKeyTexts(dataStream: InputStream?, locale: Locale) {
} }
} }
/** Pair(extraKeysLeft, extraKeysRight) */
// todo: they should be optional, or will unexpectedly appear on custom layouts
fun getTabletExtraKeys(elementId: Int): Pair<List<KeyData>, List<KeyData>> {
val flags = Key.LABEL_FLAGS_FONT_DEFAULT
return when (elementId) {
KeyboardId.ELEMENT_SYMBOLS -> listOf("\\".toTextKey(labelFlags = flags), "=".toTextKey(labelFlags = flags)) to emptyList()
KeyboardId.ELEMENT_SYMBOLS_SHIFTED -> emptyList<KeyData>() to listOf("¡".toTextKey(labelFlags = flags), "¿".toTextKey(labelFlags = flags))
else -> emptyList<KeyData>() to listOf("!".toTextKey(labelFlags = flags), labelQuestion.toTextKey(labelFlags = flags)) // assume alphabet
}
}
fun getShiftSymbolLabel(isTablet: Boolean) = if (isTablet) labelShiftSymbolTablet else labelShiftSymbol
// need tp provide a copy because some functions like MoreKeySpec.insertAdditionalMoreKeys may modify the array // need tp provide a copy because some functions like MoreKeySpec.insertAdditionalMoreKeys may modify the array
fun getMoreKeys(label: String): Array<String>? = moreKeys[label]?.copyOf() fun getMoreKeys(label: String): Array<String>? = moreKeys[label]?.copyOf()
@ -125,8 +140,10 @@ class LocaleKeyTexts(dataStream: InputStream?, locale: Locale) {
"symbol" -> labelSymbol = split.last() "symbol" -> labelSymbol = split.last()
"alphabet" -> labelAlphabet = split.last() "alphabet" -> labelAlphabet = split.last()
"shift_symbol" -> labelShiftSymbol = split.last() // never used, but could be... "shift_symbol" -> labelShiftSymbol = split.last() // never used, but could be...
"shift_symbol_tablet" -> labelShiftSymbolTablet = split.last() // never used, but could be...
"comma" -> labelComma = split.last() "comma" -> labelComma = split.last()
"period" -> labelPeriod = split.last() "period" -> labelPeriod = split.last()
"question" -> labelQuestion = split.last()
} }
} }

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="key_def_functional">";delete 10% <string name="key_def_functional">"
;action 10% ;action 10%
shift 10%; shift"</string> shift 10%; shift"</string>
<string name="key_def_extra_bottom_right">"!, ?"</string> <string name="key_def_functional_top_row" translatable="false">";delete 10%"</string>
<string name="key_def_bottom_row">"symbol, comma, space, period, emoji_com"</string> <string name="key_def_bottom_row">"symbol, comma, space, period, emoji_com"</string>
</resources> </resources>

View file

@ -5,12 +5,14 @@
the left side, keys after are on the right side. Use comma to separate keys on the same side. the left side, keys after are on the right side. Use comma to separate keys on the same side.
Valid key names are at the bottom of SimpleLayoutParser (todo: location may change) Valid key names are at the bottom of SimpleLayoutParser (todo: location may change)
Width (in percent of keyboard width) can be appended to the key name, defaults to default key width Width (in percent of keyboard width) can be appended to the key name, defaults to default key width
Applied from bottom
--> -->
<string name="key_def_functional" translatable="false">"shift 15%; delete 15%"</string> <string name="key_def_functional" translatable="false">"shift 15%; delete 15%"</string>
<!-- <!--
Extra keys to be inserted at the right side into row above space (only labels, comma-separated) Functional key definitions for a single row, on top of the keyboard.
This is to consider that some keyboards have more than 3 rows (relevant for tablet layout)
--> -->
<string name="key_def_extra_bottom_right" translatable="false">""</string> <string name="key_def_functional_top_row" translatable="false">""</string>
<!-- <!--
Bottom row definition is similar to functional key definition, but only one row, and not Bottom row definition is similar to functional key definition, but only one row, and not
split into two groups. Space bar will be adjusted in code for language and emoji keys, split into two groups. Space bar will be adjusted in code for language and emoji keys,