mirror of
https://gitlab.futo.org/keyboard/latinime.git
synced 2024-09-28 14:54:30 +01:00
Remove some unnecessary fields and add KDoc comments to some of the layout data structures
This commit is contained in:
parent
942fe63d96
commit
0ae761faf9
@ -1,7 +1,6 @@
|
||||
name: Arabic (AOSP)
|
||||
description: The default Arabic keyboard from AOSP Keyboard.
|
||||
languages: ar
|
||||
script: Arabic
|
||||
rows:
|
||||
- letters:
|
||||
# U+0636: "ض" ARABIC LETTER DAD
|
||||
|
@ -2,7 +2,6 @@
|
||||
name: "العربية/لؤلؤة"
|
||||
description: Arabic/lulua keyboard from AnySoftKeyboard
|
||||
languages: ar
|
||||
script: Arabic
|
||||
attributes:
|
||||
width: Grow
|
||||
overrideWidths:
|
||||
|
@ -92,7 +92,7 @@ rows:
|
||||
- "d"
|
||||
- type: base
|
||||
spec: "e"
|
||||
moreKeys: "ę,ė"
|
||||
moreKeys: ["ę", "ė"]
|
||||
|
||||
# You can use list syntax anywhere that expects a Key, such as `case`
|
||||
- letters:
|
||||
@ -251,145 +251,6 @@ rows:
|
||||
|
||||
---
|
||||
|
||||
## Type reference
|
||||
# API Reference
|
||||
|
||||
### Keyboard
|
||||
#### name: `String`
|
||||
Describes the name of the keyboard layout. If this is a layout for a specific language, this should be written localized to that language. For example, "Lietuvių QWERTY klaviatūra" instead of "Lithuanian QWERTY Keyboard".
|
||||
|
||||
#### rows: `List<Row>`
|
||||
List of rows to be included in the layout.
|
||||
|
||||
#### symbolsLayout: `String` (optional)
|
||||
Which symbols layout to use. Normally this should be left to the default "symbols" layout.
|
||||
|
||||
#### symbolsShiftLayout: `string` (optional)
|
||||
Which shifted symbols layout to use. Normally this should be left to the default "symbols_shift" layout.
|
||||
|
||||
#### numberRowMode: `NumberRowMode` (optional)
|
||||
This can be set to one of the following:
|
||||
|
||||
* `UserConfigurable` - settings number row toggle will toggle this layout's number row
|
||||
* `AlwaysEnabled` - this layout's number row is always enabled
|
||||
* `AlwaysDisabled` - this layout's number row is always disabled
|
||||
|
||||
#### script: `Script` (optional) = Latin
|
||||
This can be set to one of the following:
|
||||
|
||||
* `Arabic`
|
||||
* `Armenian`
|
||||
* `Bengali`
|
||||
* `Cyrillic`
|
||||
* `Devanagari`
|
||||
* `Georgian`
|
||||
* `Greek`
|
||||
* `Hebrew`
|
||||
* `Kannada`
|
||||
* `Khmer`
|
||||
* `Lao`
|
||||
* `Latin`
|
||||
* `Malayalam`
|
||||
* `Myanmar`
|
||||
* `Sinhala`
|
||||
* `Tamil`
|
||||
* `Telugu`
|
||||
* `Thai`
|
||||
|
||||
---
|
||||
|
||||
### Row
|
||||
#### (numbers|letters|bottom): `List<Key>`
|
||||
When defining a row, at most one of `numbers`, `letters`, or `bottom` can be set. This is mainly done as a yaml shorthand for defining the row type. The row type also has some effects on the keys. Number rows hide key backgrounds by default, and have a shorter height. They are also unsplittable, like action rows.
|
||||
|
||||
For most cases, you only need to define `letters` rows. The default numbers and bottom rows are added automatically.
|
||||
|
||||
An example of defining a QWERTY layout:
|
||||
```yaml
|
||||
name: "QWERTY"
|
||||
rows:
|
||||
- letters: q w e r t y u i o p
|
||||
- letters: a s d f g h j k l
|
||||
- letters: z x c v b n m
|
||||
```
|
||||
|
||||
If your layout is more complex, you can override all rows:
|
||||
```yaml
|
||||
name: "DVORAK"
|
||||
rows:
|
||||
- letters: "$delete $delete ' p y f g c r l"
|
||||
- letters: "a o e u i d h t n s"
|
||||
- letters: "$shift q j k x b m w v z"
|
||||
- bottom: "$symbols , $space . $enter $enter"
|
||||
```
|
||||
|
||||
#### rowHeight: `Double` (optional) = `1.0`
|
||||
|
||||
#### splittable: `Boolean` (optional) = `true`
|
||||
|
||||
#### fillerRowForNumberRow: `Boolean` (optional) = `false`
|
||||
When set, the row will only appear if the number row is active in the primary layout. Mainly used for symbol layouts.
|
||||
|
||||
---
|
||||
|
||||
### KeyAttributes
|
||||
#### width: `KeyWidth` (optional)
|
||||
Can be set to one of the following:
|
||||
|
||||
* `Regular` - default regular key width
|
||||
* `FunctionalKey` - width used for enter, backspace, etc
|
||||
* `Grow` - fills all empty space in the row, used for spacebar and number row
|
||||
* `Custom1` - if used, override width for `Custom1` must be defined in the keyboard
|
||||
* `Custom2` - if used, override width for `Custom2` must be defined in the keyboard
|
||||
* `Custom3` - if used, override width for `Custom3` must be defined in the keyboard
|
||||
|
||||
#### style: `KeyVisualStyle` (optional)
|
||||
Defines mainly the background for the key. Valid values:
|
||||
|
||||
* `Normal` - default visual style
|
||||
* `NoBackground` - no background, used for number row
|
||||
* `Functional` - darker key, used for shift and backspace
|
||||
* `Action` - rounded bright key, used for enter
|
||||
* `Spacebar` - used for spacebar
|
||||
* `StickyOff`
|
||||
* `StickyOn`
|
||||
|
||||
#### showPopup: `Boolean` (optional)
|
||||
Whether or not to show a popup to indicate the key was tapped
|
||||
|
||||
#### moreKeyMode: `MoreKeyMode` (optional)
|
||||
Declares how more keys should be inserted automatically. Valid values:
|
||||
|
||||
* `All` - add all automatic morekeys
|
||||
* `OnlyFromKeyspec` - add only for matching keyspec shortcut
|
||||
* ``
|
||||
|
||||
### Key (`type: base`)
|
||||
#### spec: `String`
|
||||
This is the key spec. Usually it should just be a letter.
|
||||
|
||||
Text references are permitted, such as `!text/keyspec_q`
|
||||
|
||||
You can set a custom icon and code here as well: `!icon/action_paste|!code/action_paste`
|
||||
|
||||
#### code: `Int` (optional)
|
||||
Override the code for this key
|
||||
|
||||
#### icon: `String` (optional)
|
||||
Custom icon for the key. For example, can be `action_settings`.
|
||||
|
||||
#### shiftedCode: `Int`
|
||||
#### anchored: `Boolean`
|
||||
#### showPopup: `Boolean`
|
||||
#### moreKeys: `String`
|
||||
#### longPressEnabled: `Boolean`
|
||||
#### repeatableEnabled: `Boolean`
|
||||
|
||||
### Key (`type: case`)
|
||||
#### normal: `Key`
|
||||
#### shifted: `Key` = normal
|
||||
#### automaticShifted: `Key` = shifted
|
||||
#### manualShifted: `Key` = shifted
|
||||
#### shiftLocked: `Key` = shifted
|
||||
#### shiftLockShifted: `Key` = shiftLocked
|
||||
#### symbols: `Key` = normal
|
||||
#### symbolsShifted: `Key` = normal
|
||||
TODO
|
@ -1,5 +1,4 @@
|
||||
name: "Symbols"
|
||||
element: Symbols
|
||||
attributes:
|
||||
shiftable: false
|
||||
rows:
|
||||
|
@ -1,5 +1,4 @@
|
||||
name: "Symbols (Shifted)"
|
||||
element: SymbolsShifted
|
||||
numberRowMode: UserConfigurable
|
||||
attributes:
|
||||
shiftable: false
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -12,14 +12,68 @@ import org.futo.inputmethod.latin.common.StringUtils
|
||||
|
||||
typealias KeyJ = org.futo.inputmethod.keyboard.Key
|
||||
|
||||
/**
|
||||
* Width tokens for keys. Rather than explicitly specifying a width in percentage as is common in
|
||||
* other layout systems, we instead use width tokens, which eliminates the need to explicitly
|
||||
* calculate and specify width percentages for most cases.
|
||||
*/
|
||||
@Serializable
|
||||
enum class KeyWidth {
|
||||
/**
|
||||
* Regular key width. Used for normal letters (QWERTY etc)
|
||||
*
|
||||
* ##### Width calculation
|
||||
* Simply put, the width of this is calculated by dividing the total keyboard width by the
|
||||
* maximum number of keys in a row. It is consistent across the entire keyboard.
|
||||
*
|
||||
* For example, if a keyboard has 3 rows, with 10, 9, and 7 keys respectively,
|
||||
* the regular key width will be 100% / 10 = 10% for the entire keyboard.
|
||||
* The rows with 9 and 7 keys will receive padding by default to keep them centered due
|
||||
* to the extra space.
|
||||
*/
|
||||
Regular,
|
||||
|
||||
/**
|
||||
* Functional key width. Used for functional keys (Shift, Backspace, Enter, Symbols, etc)
|
||||
*
|
||||
* ##### Width calculation
|
||||
* The width of this is at least the value specified in [Keyboard.minimumFunctionalKeyWidth]
|
||||
* or, for the bottom row, [Keyboard.minimumBottomRowFunctionalKeyWidth].
|
||||
*
|
||||
* The width may be larger than the minimum if the available space is there.
|
||||
* For example on the QWERTY layout, the ZXCV row has only 7 keys at a width of 10%, using up
|
||||
* only 70% of space. The remaining 30% of space is divided among the shift and backspace,
|
||||
* meaning the functional width is 15%.
|
||||
*/
|
||||
FunctionalKey,
|
||||
|
||||
/**
|
||||
* Grow width. Takes up all remaining space divided evenly among all grow keys in the row.
|
||||
* Mainly used for spacebar.
|
||||
*
|
||||
* Grow keys are not supported in split layouts, and their presence can complicate width
|
||||
* calculation for functional keys and others. Avoid use when possible.
|
||||
*/
|
||||
Grow,
|
||||
|
||||
/**
|
||||
* The Custom1 width as defined in [Keyboard.overrideWidths] (values are between 0.0 and 1.0)
|
||||
*/
|
||||
Custom1,
|
||||
|
||||
/**
|
||||
* The Custom2 width as defined in [Keyboard.overrideWidths] (values are between 0.0 and 1.0)
|
||||
*/
|
||||
Custom2,
|
||||
|
||||
/**
|
||||
* The Custom3 width as defined in [Keyboard.overrideWidths] (values are between 0.0 and 1.0)
|
||||
*/
|
||||
Custom3,
|
||||
|
||||
/**
|
||||
* The Custom4 width as defined in [Keyboard.overrideWidths] (values are between 0.0 and 1.0)
|
||||
*/
|
||||
Custom4,
|
||||
}
|
||||
|
||||
@ -91,14 +145,29 @@ internal fun filterMoreKeysFlags(moreKeys: List<String>): List<String> =
|
||||
!it.startsWith(KeyJ.MORE_KEYS_NO_PANEL_AUTO_MORE_KEY)
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies which morekeys can be automatically added to the key.
|
||||
*/
|
||||
@Serializable
|
||||
enum class MoreKeyMode(
|
||||
val autoFromKeyspec: Boolean,
|
||||
val autoNumFromCoord: Boolean,
|
||||
val autoSymFromCoord: Boolean
|
||||
) {
|
||||
/**
|
||||
* Automatically insert morekeys from keyspec shortcuts, as well as numbers, symbols and actions
|
||||
* (if not disabled by user). These count towards KeyCoordinate.
|
||||
*/
|
||||
All(true, true, true),
|
||||
|
||||
/**
|
||||
* Only automatically insert morekeys from keyspec shortcut.
|
||||
*/
|
||||
OnlyFromKeyspec(true, false, false),
|
||||
|
||||
/**
|
||||
* Do not automatically insert any morekeys.
|
||||
*/
|
||||
OnlyExplicit(false, false, false)
|
||||
}
|
||||
|
||||
@ -106,7 +175,9 @@ private fun Int.and(other: Boolean): Int {
|
||||
return if(other) { this } else { 0 }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Flags for the key label
|
||||
*/
|
||||
@Serializable
|
||||
data class LabelFlags(
|
||||
val alignHintLabelToBottom: Boolean = false,
|
||||
@ -129,17 +200,73 @@ data class LabelFlags(
|
||||
KeyJ.LABEL_FLAGS_AUTO_X_SCALE.and(autoXScale)
|
||||
}
|
||||
|
||||
/**
|
||||
* Attributes for keys.
|
||||
*
|
||||
* Values are inherited in the following order:
|
||||
* `Key.attributes > Row.attributes > Keyboard.attributes > DefaultKeyAttributes`
|
||||
*/
|
||||
@Serializable
|
||||
data class KeyAttributes(
|
||||
/**
|
||||
* Key width token
|
||||
*/
|
||||
val width: KeyWidth? = null,
|
||||
|
||||
/**
|
||||
* Visual style (background) for the key
|
||||
*/
|
||||
val style: KeyVisualStyle? = null,
|
||||
|
||||
/**
|
||||
* Whether or not to anchor the key to the edges.
|
||||
*
|
||||
* When a row is not wide enough to fill 100%, padding is added to the edges of the row.
|
||||
* If there are anchored keys in the row, the padding will be added after the anchored
|
||||
* keys, keeping the anchored keys at the edge.
|
||||
*/
|
||||
val anchored: Boolean? = null,
|
||||
|
||||
/**
|
||||
* Whether or not to show the popup indicator when the key is pressed.
|
||||
* This is usually desirable for letters on normal layouts (QWERTY letters), but undesirable
|
||||
* for functional keys (Shift, Backspace), or certain layouts (phone layout)
|
||||
*/
|
||||
val showPopup: Boolean? = null,
|
||||
|
||||
/**
|
||||
* Which moreKeys to add automatically
|
||||
*/
|
||||
val moreKeyMode: MoreKeyMode? = null,
|
||||
|
||||
/**
|
||||
* Whether or not to use keyspec shortcuts.
|
||||
* For example, `$` gets automatically converted to `!text/keyspec_currency`.
|
||||
*
|
||||
* The full list of keyspec shortcuts is defined in `KeySpecShortcuts`.
|
||||
*/
|
||||
val useKeySpecShortcut: Boolean? = null,
|
||||
|
||||
/**
|
||||
* Whether or not longpress is enabled for the key
|
||||
*/
|
||||
val longPressEnabled: Boolean? = null,
|
||||
|
||||
/**
|
||||
* Label flags for how the key's label (and its hint) should be presented
|
||||
*/
|
||||
val labelFlags: LabelFlags? = null,
|
||||
|
||||
/**
|
||||
* Whether or not the key is repeatable, intended for backspace
|
||||
*/
|
||||
val repeatableEnabled: Boolean? = null,
|
||||
|
||||
/**
|
||||
* Whether or not the key is automatically shiftable. If true, it automatically becomes
|
||||
* uppercased when the layout is shifted. If this is not desired, this can be set to false.
|
||||
* Shift behavior can be customized by using a [CaseSelector].
|
||||
*/
|
||||
val shiftable: Boolean? = null,
|
||||
) {
|
||||
fun getEffectiveAttributes(row: Row, keyboard: Keyboard): KeyAttributes {
|
||||
@ -190,24 +317,56 @@ object MoreKeysListSerializer: SpacedListSerializer<String>(String.serializer(),
|
||||
MoreKeySpec.splitKeySpecs(it)?.toList() ?: listOf()
|
||||
})
|
||||
|
||||
/**
|
||||
* The base key
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("base")
|
||||
data class BaseKey(
|
||||
// AOSP Keyboard key spec
|
||||
/**
|
||||
* AOSP key spec. It can contain a custom label, code, icon, output text.
|
||||
*
|
||||
* Each key specification is one of the following:
|
||||
* - Label optionally followed by keyOutputText (keyLabel|keyOutputText).
|
||||
* - Label optionally followed by code point (keyLabel|!code/code_name).
|
||||
* - Icon followed by keyOutputText (!icon/icon_name|keyOutputText).
|
||||
* - Icon followed by code point (!icon/icon_name|!code/code_name).
|
||||
*
|
||||
* Label and keyOutputText are one of the following:
|
||||
* - Literal string.
|
||||
* - Label reference represented by (!text/label_name), see {@link KeyboardTextsSet}.
|
||||
* - String resource reference represented by (!text/resource_name), see {@link KeyboardTextsSet}.
|
||||
*
|
||||
* Icon is represented by (!icon/icon_name), see {@link KeyboardIconsSet}.
|
||||
*
|
||||
* Code is one of the following:
|
||||
* - Code point presented by hexadecimal string prefixed with "0x"
|
||||
* - Code reference represented by (!code/code_name), see {@link KeyboardCodesSet}.
|
||||
*
|
||||
* Special character, comma ',' backslash '\', and bar '|' can be escaped by '\' character.
|
||||
* Note that the '\' is also parsed by XML parser and {@link MoreKeySpec#splitKeySpecs(String)}
|
||||
* as well.
|
||||
*/
|
||||
val spec: String,
|
||||
|
||||
// Attributes
|
||||
/**
|
||||
* Attributes for this key. Values defined here supersede any other values. Values which are
|
||||
* not defined are inherited from the row, keyboard, or default attributes.
|
||||
*/
|
||||
val attributes: KeyAttributes = KeyAttributes(),
|
||||
|
||||
/**
|
||||
* More keys for this key. In YAML, it can be defined as a list or a comma-separated string.
|
||||
*
|
||||
* The values here are key specs.
|
||||
*/
|
||||
val moreKeys: @Serializable(with = MoreKeysListSerializer::class) List<String> = listOf(),
|
||||
|
||||
// If these values are set, they override spec values
|
||||
val outputText: String? = null,
|
||||
val label: String? = null,
|
||||
val code: Int? = null,
|
||||
val icon: String? = null,
|
||||
|
||||
// If set, will override default hint from moreKeys
|
||||
/**
|
||||
* If set, overrides a default hint from the value of moreKeys.
|
||||
*
|
||||
* TODO: Currently does not override
|
||||
*/
|
||||
val hint: String? = null,
|
||||
) : AbstractKey {
|
||||
override fun computeData(params: KeyboardParams, row: Row, keyboard: Keyboard, coordinate: KeyCoordinate): ComputedKeyData {
|
||||
@ -232,10 +391,10 @@ data class BaseKey(
|
||||
?: spec
|
||||
)
|
||||
|
||||
val label = label ?: expandedSpec?.let { KeySpecParser.getLabel(it) } ?: ""
|
||||
val icon = icon ?: expandedSpec?.let { KeySpecParser.getIconId(it) } ?: ""
|
||||
val code = code ?: KeySpecParser.getCode(expandedSpec)
|
||||
val outputText = outputText ?: KeySpecParser.getOutputText(expandedSpec)
|
||||
val label = expandedSpec?.let { KeySpecParser.getLabel(it) } ?: ""
|
||||
val icon = expandedSpec?.let { KeySpecParser.getIconId(it) } ?: ""
|
||||
val code = KeySpecParser.getCode(expandedSpec)
|
||||
val outputText = KeySpecParser.getOutputText(expandedSpec)
|
||||
|
||||
val moreKeyMode = attributes.moreKeyMode!!
|
||||
|
||||
@ -295,16 +454,38 @@ data class BaseKey(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Case selector key. Allows specifying a different type of key depending on when the layout is
|
||||
* shifted or not.
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("case")
|
||||
data class CaseSelector(
|
||||
/**
|
||||
* Key to use normally
|
||||
*/
|
||||
val normal: Key,
|
||||
|
||||
/**
|
||||
* Key to use when shifted
|
||||
*/
|
||||
val shifted: Key = normal,
|
||||
val automaticShifted: Key = shifted,
|
||||
val manualShifted: Key = shifted,
|
||||
|
||||
/**
|
||||
* Key to use when shift locked (caps lock), defaults to [shifted]
|
||||
*/
|
||||
val shiftLocked: Key = shifted,
|
||||
val shiftLockShifted: Key = shiftLocked,
|
||||
|
||||
/**
|
||||
* Key to use when in symbols layout, defaults to [normal]. Mainly used internally for
|
||||
* [TemplateShiftKey]
|
||||
*/
|
||||
val symbols: Key = normal,
|
||||
|
||||
/**
|
||||
* Key to use when in symbols layout, defaults to [normal]. Mainly used internally for
|
||||
* [TemplateShiftKey]
|
||||
*/
|
||||
val symbolsShifted: Key = normal
|
||||
) : AbstractKey {
|
||||
override fun computeData(
|
||||
@ -315,10 +496,15 @@ data class CaseSelector(
|
||||
): ComputedKeyData? =
|
||||
when(params.mId.mElementId) {
|
||||
KeyboardId.ELEMENT_ALPHABET -> normal
|
||||
KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED -> automaticShifted
|
||||
KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED -> manualShifted
|
||||
KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED -> shiftLocked
|
||||
KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED -> shiftLockShifted
|
||||
|
||||
// KeyboardState.kt currently doesn't distinguish between these
|
||||
KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED,
|
||||
KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED -> shifted
|
||||
|
||||
// KeyboardState.kt currently doesn't distinguish between these
|
||||
KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED,
|
||||
KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED -> shiftLocked
|
||||
|
||||
KeyboardId.ELEMENT_SYMBOLS -> symbols
|
||||
KeyboardId.ELEMENT_SYMBOLS_SHIFTED -> symbolsShifted
|
||||
else -> normal
|
||||
@ -356,15 +542,47 @@ object KeyContextualSerializer : ClassOrScalarsSerializer<AbstractKey>(
|
||||
)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Affects the background for the key. Depending on the user theme settings, backgrounds may be
|
||||
* different.
|
||||
*/
|
||||
@Serializable
|
||||
enum class KeyVisualStyle {
|
||||
/**
|
||||
* Uses a normal key background, intended for all letters.
|
||||
*/
|
||||
Normal,
|
||||
|
||||
/**
|
||||
* Uses no key background, intended for number row numbers.
|
||||
*/
|
||||
NoBackground,
|
||||
|
||||
/**
|
||||
* Uses a slightly darker colored background, intended for functional keys (backspace, etc)
|
||||
*/
|
||||
Functional,
|
||||
|
||||
/**
|
||||
* Intended for Shift when it's not shiftlocked
|
||||
*/
|
||||
StickyOff,
|
||||
|
||||
/**
|
||||
* Intended for Shift to indicate it's shiftlocked. Uses a more bright background
|
||||
*/
|
||||
StickyOn,
|
||||
|
||||
/**
|
||||
* Uses a bright fully rounded background, normally used for the enter key
|
||||
*/
|
||||
Action,
|
||||
|
||||
/**
|
||||
* Depending on the key borders setting, this is either
|
||||
* the same as [Normal] (key borders enabled) or a
|
||||
* fully rounded rectangle (key borders disabled)
|
||||
*/
|
||||
Spacebar
|
||||
}
|
||||
|
||||
@ -379,6 +597,9 @@ fun KeyVisualStyle.toBackgroundTypeInt(): Int = when(this) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* An empty gap in place of a key
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("gap")
|
||||
class GapKey(val attributes: KeyAttributes = KeyAttributes()) : AbstractKey {
|
||||
|
@ -1,13 +1,14 @@
|
||||
package org.futo.inputmethod.v2keyboard
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import org.futo.inputmethod.keyboard.internal.KeyboardLayoutElement
|
||||
import org.futo.inputmethod.keyboard.internal.KeyboardParams
|
||||
import org.futo.inputmethod.keyboard.internal.MoreKeySpec
|
||||
|
||||
data class KeyCoordinate(
|
||||
val regularRow: Int,
|
||||
val regularColumn: Int,
|
||||
val element: KeyboardElement
|
||||
val element: KeyboardLayoutElement
|
||||
)
|
||||
|
||||
@Serializable
|
||||
|
@ -16,16 +16,58 @@ enum class RowNumberRowMode(val displayByDefault: Boolean, val displayWhenExplic
|
||||
Hideable(false, false, true),
|
||||
}
|
||||
|
||||
typealias KeyList = @Serializable(with = RowKeyListSerializer::class) List<Key>
|
||||
|
||||
/**
|
||||
* A keyboard row. Only one of [numbers], [letters], or [bottom] must be defined. The row type is
|
||||
* determined by which one of those is defined.
|
||||
*/
|
||||
@Serializable
|
||||
data class Row(
|
||||
// Only one of these must be defined
|
||||
val numbers: @Serializable(with = RowKeyListSerializer::class) List<Key>? = null,
|
||||
val letters: @Serializable(with = RowKeyListSerializer::class) List<Key>? = null,
|
||||
val bottom: @Serializable(with = RowKeyListSerializer::class) List<Key>? = null,
|
||||
/**
|
||||
* If defined, this is a number row. Number rows by default have grow keys, no background,
|
||||
* and smaller height. They may also be hidden depending on the user settings and the value
|
||||
* of [Keyboard.numberRowMode].
|
||||
*
|
||||
* See [DefaultNumberRow]
|
||||
*/
|
||||
val numbers: KeyList? = null,
|
||||
|
||||
/**
|
||||
* If defined, this is a letters row. Letter rows by default are splittable.
|
||||
*/
|
||||
val letters: KeyList? = null,
|
||||
|
||||
/**
|
||||
* If defined, this is a bottom row. Bottom row should typically contain:
|
||||
* $symbols $action $space $contextual $enter
|
||||
*
|
||||
* See [DefaultBottomRow]
|
||||
*/
|
||||
val bottom: KeyList? = null,
|
||||
|
||||
/**
|
||||
* (optional) The height multiplier for this row
|
||||
*/
|
||||
val rowHeight: Double = if(numbers == null) { 1.0 } else { NumberRowHeight },
|
||||
|
||||
/**
|
||||
* (optional) Whether or not this row is splittable. Enabled for letter rows by default.
|
||||
*/
|
||||
val splittable: Boolean = letters != null,
|
||||
|
||||
/**
|
||||
* (optional) How this row should behave with respect to the number row. Valid values:
|
||||
* * `Default` - always display this row
|
||||
* * `Filler` - only display when the number row is explicitly active
|
||||
* * `Hideable` - only display when the number row is explicitly inactive
|
||||
*/
|
||||
val numRowMode: RowNumberRowMode = RowNumberRowMode.Default,
|
||||
|
||||
/**
|
||||
* (optional) Default key attributes for keys in this row. Values set here supersede values
|
||||
* set in `Keyboard.attributes`.
|
||||
*/
|
||||
val attributes: KeyAttributes = KeyAttributes(
|
||||
style = when {
|
||||
numbers != null -> KeyVisualStyle.NoBackground
|
||||
@ -80,15 +122,6 @@ val DefaultBottomRow = Row(
|
||||
)
|
||||
)
|
||||
|
||||
public enum class KeyboardElement {
|
||||
Alphabet,
|
||||
Symbols,
|
||||
SymbolsShifted,
|
||||
Phone,
|
||||
PhoneSymbols,
|
||||
Number
|
||||
}
|
||||
|
||||
enum class NumberRowMode {
|
||||
UserConfigurable,
|
||||
AlwaysEnabled,
|
||||
@ -105,16 +138,6 @@ enum class BottomRowWidthMode(val separateFunctional: Boolean) {
|
||||
Identical(false)
|
||||
}
|
||||
|
||||
enum class RowWidthMode {
|
||||
PadSides,
|
||||
FillSpace
|
||||
}
|
||||
|
||||
enum class LongPressKeysMode {
|
||||
UserConfigurable,
|
||||
LayoutOnly
|
||||
}
|
||||
|
||||
enum class RowHeightMode(val clampHeight: Boolean) {
|
||||
ClampHeight(true),
|
||||
FillHeight(false)
|
||||
@ -123,33 +146,113 @@ enum class RowHeightMode(val clampHeight: Boolean) {
|
||||
object SpacedLanguageListSerializer : SpacedListSerializer<String>(String.serializer(), { it.split(" ") })
|
||||
typealias SpacedStringList = @Serializable(with = SpacedLanguageListSerializer::class) List<String>
|
||||
|
||||
|
||||
/**
|
||||
* Override the symbols and other layouts for a specific layout.
|
||||
*/
|
||||
@Serializable
|
||||
data class LayoutSetOverrides(
|
||||
val symbols: String = "symbols",
|
||||
val symbolsShifted: String = "symbols_shift",
|
||||
val number: String = "number",
|
||||
val numberShifted: String = "number_shift",
|
||||
val phone: String = "phone",
|
||||
val phoneShifted: String = "phone_shift"
|
||||
)
|
||||
|
||||
/**
|
||||
* A keyboard layout definition, the entry point for the layout yaml files.
|
||||
*/
|
||||
@Serializable
|
||||
data class Keyboard(
|
||||
/**
|
||||
* The human-readable name of the layout. If the layout is for a specific language, this should
|
||||
* be written in the relevant language.
|
||||
*/
|
||||
val name: String,
|
||||
|
||||
@SerialName("rows")
|
||||
private val definedRows: List<Row>,
|
||||
/**
|
||||
* The rows defined for the layout. Defining the number row, bottom row, or the functional
|
||||
* keys (shift/backspace) is optional here. If they are missing, defaults will automatically be
|
||||
* added to `effectiveRows`.
|
||||
*/
|
||||
private val rows: List<Row>,
|
||||
|
||||
val description: String = "",
|
||||
/**
|
||||
* List of languages this layout is intended for. It will be displayed as an option for the
|
||||
* specified languages.
|
||||
*/
|
||||
val languages: SpacedStringList = listOf(),
|
||||
val symbolsLayout: String = "symbols",
|
||||
val symbolsShiftLayout: String = "symbols_shift",
|
||||
val element: KeyboardElement = KeyboardElement.Alphabet,
|
||||
|
||||
/**
|
||||
* (optional) A human-readable description of the layout. Authorship/origin information may
|
||||
* be added here. This is intended to be displayed to the user when they are selecting layouts.
|
||||
*/
|
||||
val description: String = "",
|
||||
|
||||
/**
|
||||
* (optional) Override the symbols layout or other layouts for this layout set.
|
||||
*/
|
||||
val layoutSetOverrides: LayoutSetOverrides = LayoutSetOverrides(),
|
||||
|
||||
/**
|
||||
* (optional) Whether the number row should be user-configurable, always displayed, or never.
|
||||
*/
|
||||
val numberRowMode: NumberRowMode = NumberRowMode.UserConfigurable,
|
||||
|
||||
/**
|
||||
* (optional) Whether the bottom row should always maintain a consistent height, or whether
|
||||
* it should grow and shrink.
|
||||
*/
|
||||
val bottomRowHeightMode: BottomRowHeightMode = BottomRowHeightMode.Fixed,
|
||||
|
||||
/**
|
||||
* (optional) Whether the bottom row should follow key widths of other rows, or should maintain
|
||||
* separate widths for consistency.
|
||||
*/
|
||||
val bottomRowWidthMode: BottomRowWidthMode = BottomRowWidthMode.SeparateFunctional,
|
||||
val rowWidthMode: RowWidthMode = RowWidthMode.PadSides,
|
||||
val script: Script = Script.Latin,
|
||||
val longPressKeysMode: LongPressKeysMode = LongPressKeysMode.UserConfigurable,
|
||||
|
||||
/**
|
||||
* (optional) Default attributes to use for all rows
|
||||
*/
|
||||
val attributes: KeyAttributes = KeyAttributes(),
|
||||
|
||||
/**
|
||||
* (optional) Definitions of custom key widths. Values are between 0.0 and 1.0, with 1.0
|
||||
* representing 100% of the keyboard width.
|
||||
*/
|
||||
val overrideWidths: Map<KeyWidth, Float> = mapOf(),
|
||||
|
||||
/**
|
||||
* (optional) Whether or not rows should fill the vertical space, or have vertical gaps added.
|
||||
*/
|
||||
val rowHeightMode: RowHeightMode = RowHeightMode.ClampHeight,
|
||||
|
||||
/**
|
||||
* (optional) Whether or not the ZWNJ key should be shown in place of the contextual key.
|
||||
*/
|
||||
val useZWNJKey: Boolean = false,
|
||||
|
||||
/**
|
||||
* (optional) Minimum width for functional keys.
|
||||
*/
|
||||
val minimumFunctionalKeyWidth: Float = 0.125f,
|
||||
|
||||
/**
|
||||
* (optional) Minimum width for functional keys in the bottom row.
|
||||
*/
|
||||
val minimumBottomRowFunctionalKeyWidth: Float = 0.15f,
|
||||
|
||||
/**
|
||||
* (optional) Alternative pages for this layout, use in conjunction with $alt0, $alt1, $alt2
|
||||
*/
|
||||
val altPages: List<List<Row>> = listOf()
|
||||
|
||||
// TODO: Custom long-press key settings configuration
|
||||
//val element: KeyboardElement = KeyboardElement.Alphabet,
|
||||
//val rowWidthMode: RowWidthMode = RowWidthMode.PadSides,
|
||||
//val script: Script = Script.Latin,
|
||||
//val longPressKeysMode: LongPressKeysMode = LongPressKeysMode.UserConfigurable,
|
||||
) {
|
||||
var id: String = ""
|
||||
|
||||
@ -161,7 +264,7 @@ data class Keyboard(
|
||||
assert(rows.count { it.isLetterRow } in 1..8) { "Keyboard must contain between 1 and 8 letter rows" }
|
||||
}
|
||||
|
||||
val effectiveRows = definedRows.toMutableList().apply {
|
||||
val effectiveRows = rows.toMutableList().apply {
|
||||
if(find { it.isNumberRow } == null) {
|
||||
add(0, DefaultNumberRow)
|
||||
}
|
||||
|
@ -105,12 +105,12 @@ class KeyboardLayoutSetV2 internal constructor(
|
||||
|
||||
val layoutName = forcedLayout ?: params.keyboardLayoutSet
|
||||
val mainLayout = LayoutManager.getLayout(context, layoutName)
|
||||
val symbolsLayout = LayoutManager.getLayout(context, mainLayout.symbolsLayout)
|
||||
val symbolsShiftedLayout = LayoutManager.getLayout(context, mainLayout.symbolsShiftLayout)
|
||||
val numberLayout = LayoutManager.getLayout(context, "number")
|
||||
val numberShiftLayout = LayoutManager.getLayout(context, "number_shift")
|
||||
val phoneLayout = LayoutManager.getLayout(context, "phone")
|
||||
val phoneSymbolsLayout = LayoutManager.getLayout(context, "phone_shift")
|
||||
val symbolsLayout = LayoutManager.getLayout(context, mainLayout.layoutSetOverrides.symbols)
|
||||
val symbolsShiftedLayout = LayoutManager.getLayout(context, mainLayout.layoutSetOverrides.symbolsShifted)
|
||||
val numberLayout = LayoutManager.getLayout(context, mainLayout.layoutSetOverrides.number)
|
||||
val numberShiftLayout = LayoutManager.getLayout(context, mainLayout.layoutSetOverrides.numberShifted)
|
||||
val phoneLayout = LayoutManager.getLayout(context, mainLayout.layoutSetOverrides.phone)
|
||||
val phoneSymbolsLayout = LayoutManager.getLayout(context, mainLayout.layoutSetOverrides.phoneShifted)
|
||||
val errorLayout = LayoutManager.getLayout(context, "error")
|
||||
|
||||
val elements = mapOf(
|
||||
@ -170,7 +170,7 @@ class KeyboardLayoutSetV2 internal constructor(
|
||||
val baseLayout = elements[baseElement]
|
||||
baseLayout?.altPages?.get(altIdx)
|
||||
}?.let {
|
||||
mainLayout.copy(definedRows = it)
|
||||
mainLayout.copy(rows = it)
|
||||
}
|
||||
} ?: run {
|
||||
// If all else fails, show the error layout
|
||||
@ -240,7 +240,8 @@ class KeyboardLayoutSetV2 internal constructor(
|
||||
val layoutParams = LayoutParams(
|
||||
gap = params.gap.dp,
|
||||
useSplitLayout = params.useSplitLayout,
|
||||
standardRowHeight = singularRowHeight
|
||||
standardRowHeight = singularRowHeight,
|
||||
element = element
|
||||
)
|
||||
|
||||
try {
|
||||
@ -269,34 +270,6 @@ Stack trace: ${e.stackTrace.map { it.toString() }}
|
||||
}
|
||||
}
|
||||
|
||||
private fun elementIdToElement(id: Int): KeyboardElement =
|
||||
when(id) {
|
||||
KeyboardId.ELEMENT_ALPHABET,
|
||||
KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED,
|
||||
KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED,
|
||||
KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED,
|
||||
KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED ->
|
||||
KeyboardElement.Alphabet
|
||||
|
||||
KeyboardId.ELEMENT_SYMBOLS ->
|
||||
KeyboardElement.Symbols
|
||||
|
||||
KeyboardId.ELEMENT_SYMBOLS_SHIFTED ->
|
||||
KeyboardElement.SymbolsShifted
|
||||
|
||||
KeyboardId.ELEMENT_PHONE ->
|
||||
KeyboardElement.Phone
|
||||
|
||||
KeyboardId.ELEMENT_PHONE_SYMBOLS ->
|
||||
KeyboardElement.PhoneSymbols
|
||||
|
||||
KeyboardId.ELEMENT_NUMBER ->
|
||||
KeyboardElement.Number
|
||||
|
||||
else -> KeyboardElement.Alphabet
|
||||
}
|
||||
|
||||
|
||||
public fun getKeyboardMode(editorInfo: EditorInfo): Int {
|
||||
val inputType = editorInfo.inputType
|
||||
val variation = inputType and InputType.TYPE_MASK_VARIATION
|
||||
|
@ -6,6 +6,7 @@ import androidx.compose.ui.unit.Dp
|
||||
import org.futo.inputmethod.keyboard.Key.ACTION_FLAGS_ENABLE_LONG_PRESS
|
||||
import org.futo.inputmethod.keyboard.Key.ACTION_FLAGS_IS_REPEATABLE
|
||||
import org.futo.inputmethod.keyboard.Key.ACTION_FLAGS_NO_KEY_PREVIEW
|
||||
import org.futo.inputmethod.keyboard.internal.KeyboardLayoutElement
|
||||
import org.futo.inputmethod.keyboard.internal.KeyboardParams
|
||||
import org.futo.inputmethod.latin.R
|
||||
import org.futo.inputmethod.latin.common.Constants
|
||||
@ -85,7 +86,8 @@ data class LayoutRow(
|
||||
data class LayoutParams(
|
||||
val gap: Dp,
|
||||
val useSplitLayout: Boolean,
|
||||
val standardRowHeight: Double
|
||||
val standardRowHeight: Double,
|
||||
val element: KeyboardLayoutElement,
|
||||
)
|
||||
|
||||
data class LayoutEngine(
|
||||
@ -365,7 +367,7 @@ data class LayoutEngine(
|
||||
val computedRowWithoutWidths = rows.map { row ->
|
||||
var regularColumn = 0
|
||||
row.keys.mapNotNull { key ->
|
||||
key.computeData(params, row, keyboard, KeyCoordinate(regularRow, regularColumn, keyboard.element))?.let { data ->
|
||||
key.computeData(params, row, keyboard, KeyCoordinate(regularRow, regularColumn, layoutParams.element))?.let { data ->
|
||||
if(data.countsToKeyCoordinate) {
|
||||
regularColumn += 1
|
||||
}
|
||||
|
@ -67,8 +67,8 @@ object LayoutManager {
|
||||
|
||||
fun queryLayoutsForLocale(locale: Locale): List<Keyboard> {
|
||||
val language = locale.language
|
||||
val script = locale.getKeyboardScript()
|
||||
return layoutsById!!.values.filter { it.languages.contains(language) || it.script == script }
|
||||
//val script = locale.getKeyboardScript()
|
||||
return layoutsById!!.values.filter { it.languages.contains(language) }
|
||||
}
|
||||
|
||||
fun getAllLayoutNames(context: Context): List<String> {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.futo.inputmethod.v2keyboard
|
||||
|
||||
import org.futo.inputmethod.keyboard.internal.KeyboardLayoutKind
|
||||
import org.futo.inputmethod.latin.common.Constants
|
||||
|
||||
fun getDefaultMoreKeysForKey(code: Int, relevantSpecShortcut: List<String>?): String {
|
||||
@ -21,7 +22,7 @@ val QwertySymbols = listOf(
|
||||
)
|
||||
|
||||
fun getSymsForCoordinate(keyCoordinate: KeyCoordinate): String {
|
||||
if(keyCoordinate.element != KeyboardElement.Alphabet) return ""
|
||||
if(keyCoordinate.element.kind != KeyboardLayoutKind.Alphabet) return ""
|
||||
|
||||
val row = QwertySymbols.getOrNull(keyCoordinate.regularRow)
|
||||
val letter = row?.getOrNull(keyCoordinate.regularColumn)
|
||||
@ -33,7 +34,7 @@ fun getSymsForCoordinate(keyCoordinate: KeyCoordinate): String {
|
||||
}
|
||||
|
||||
fun getNumForCoordinate(keyCoordinate: KeyCoordinate): String {
|
||||
if(keyCoordinate.element != KeyboardElement.Alphabet) return ""
|
||||
if(keyCoordinate.element.kind != KeyboardLayoutKind.Alphabet) return ""
|
||||
|
||||
if(keyCoordinate.regularRow == 0 && keyCoordinate.regularColumn <= 9) {
|
||||
if(keyCoordinate.regularColumn == 9) {
|
||||
|
Loading…
Reference in New Issue
Block a user