Newer
Older
package org.futo.inputmethod.v2keyboard
import org.futo.inputmethod.keyboard.KeyConsts
import org.futo.inputmethod.keyboard.internal.KeyboardLayoutKind
import org.futo.inputmethod.keyboard.internal.KeyboardParams
import org.futo.inputmethod.keyboard.internal.MoreKeySpec
import org.futo.inputmethod.latin.settings.LongPressKey
typealias MoreKeys = List<String>
val QwertySymbols = listOf(
"qwertyuiop".toList(),
"asdfghjkl".toList() + listOf("r2_e1"),
"zxcvbnm".toList()
)
private fun getNumForCoordinate(keyCoordinate: KeyCoordinate): String {
if(keyCoordinate.element.kind != KeyboardLayoutKind.Alphabet) return ""
if(keyCoordinate.regularRow == 0) {
val colOffset = (keyCoordinate.measurement.numColumnsByRow[keyCoordinate.regularRow] - 10) / 2
val centeredCol = keyCoordinate.regularColumn - colOffset
if(centeredCol == 9) {
return "!text/keyspec_symbols_0,!text/additional_morekeys_symbols_0"
} else if(centeredCol in 0 until 9) {
return "!text/keyspec_symbols_${centeredCol + 1},!text/additional_morekeys_symbols_${centeredCol + 1}"
} else {
return ""
}
}
return ""
}
private fun symsForCoord(keyCoordinate: KeyCoordinate): String {
if(keyCoordinate.element.kind != KeyboardLayoutKind.Alphabet) return ""
val row = QwertySymbols.getOrNull(keyCoordinate.regularRow) ?: return ""
val colOffset = (keyCoordinate.measurement.numColumnsByRow[keyCoordinate.regularRow] - row.size) / 2
val centeredCol = keyCoordinate.regularColumn - colOffset.coerceAtLeast(0)
if(centeredCol < 0) return ""
val letter = row.getOrNull(centeredCol)
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
return if(letter != null) {
"!text/qwertysyms_$letter"
} else {
""
}
}
private fun actionForCoord(keyCoordinate: KeyCoordinate): String {
if(keyCoordinate.element.kind != KeyboardLayoutKind.Alphabet) return ""
val row = QwertySymbols.getOrNull(keyCoordinate.regularRow)
val letter = row?.getOrNull(keyCoordinate.regularColumn)
return if(letter != null) {
"!text/actions_$letter"
} else {
""
}
}
data class BuiltMoreKeys(
val specs: List<MoreKeySpec>,
val flags: Int
)
data class MoreKeysBuilder(
val code: Int,
val mode: MoreKeyMode,
val coordinate: KeyCoordinate,
val row: Row,
val keyboard: Keyboard,
val params: KeyboardParams,
val moreKeys: MoreKeys = listOf()
) {
private fun insertMoreKeys(resolvedMoreKeys: MoreKeys): MoreKeysBuilder {
if(resolvedMoreKeys.isEmpty()) return this
val idxOfMarker = moreKeys.indexOf("%")
val newMoreKeys = if(idxOfMarker == -1) {
moreKeys + resolvedMoreKeys
} else {
moreKeys.subList(0, idxOfMarker) + resolvedMoreKeys + moreKeys.subList(idxOfMarker, moreKeys.size)
}
return this.copy(moreKeys = newMoreKeys)
}
fun insertMoreKeys(moreKeysToInsert: String): MoreKeysBuilder {
val resolved = MoreKeySpec.splitKeySpecs(params.mTextsSet.resolveTextReference(moreKeysToInsert))?.toList()
return resolved?.let { insertMoreKeys(it) } ?: this
}
private val isNumberRowActive = keyboard.numberRowMode.isActive(params.mId.mNumberRow)
private fun canAddMoreKey(key: LongPressKey): Boolean =
row.isLetterRow && when(key) {
LongPressKey.QuickActions -> mode.autoSymFromCoord
// Numbers added to top row requires the number row being inactive
LongPressKey.Numbers -> (mode.autoNumFromCoord && !isNumberRowActive)
// Symbols for top row requires number row being active (it replaces the number long-press keys)
LongPressKey.Symbols -> (mode.autoSymFromCoord && (coordinate.regularRow > 0 || isNumberRowActive))
// Language keys require a-z code
LongPressKey.LanguageKeys, LongPressKey.MiscLetters -> (mode.autoFromLanguageKey && row.isLetterRow && code >= 'a'.code && code <= 'z'.code)
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
}
private fun moreKey(key: LongPressKey): String =
when(key) {
LongPressKey.Numbers -> getNumForCoordinate(coordinate)
LongPressKey.Symbols -> symsForCoord(coordinate)
LongPressKey.QuickActions -> actionForCoord(coordinate)
LongPressKey.LanguageKeys -> "!text/morekeys_${code.toChar()}"
LongPressKey.MiscLetters -> "!text/morekeys_misc_${code.toChar()}"
}
fun insertMoreKeys(key: LongPressKey): MoreKeysBuilder {
if(!canAddMoreKey(key)) return this
return insertMoreKeys(moreKey(key))
}
fun build(shifted: Boolean): BuiltMoreKeys {
return BuiltMoreKeys(
specs = filterMoreKeysFlags(moreKeys).filter { it != "%" }.map {
MoreKeySpec(it, shifted, params.mId.locale)
},
flags = computeMoreKeysFlags(moreKeys.toTypedArray(), params)
)
}
}
private fun computeMoreKeysFlags(moreKeys: Array<String>, params: KeyboardParams): Int {
// Get maximum column order number and set a relevant mode value.
var moreKeysColumnAndFlags =
(KeyConsts.MORE_KEYS_MODE_MAX_COLUMN_WITH_AUTO_ORDER
or params.mMaxMoreKeysKeyboardColumn)
var value: Int
if ((MoreKeySpec.getIntValue(
moreKeys,
KeyConsts.MORE_KEYS_AUTO_COLUMN_ORDER,
-1
).also {
value = it
}) > 0
) {
// Override with fixed column order number and set a relevant mode value.
moreKeysColumnAndFlags =
(KeyConsts.MORE_KEYS_MODE_FIXED_COLUMN_WITH_AUTO_ORDER
or (value and KeyConsts.MORE_KEYS_COLUMN_NUMBER_MASK))
}
if ((MoreKeySpec.getIntValue(
moreKeys,
KeyConsts.MORE_KEYS_FIXED_COLUMN_ORDER,
-1
).also {
value = it
}) > 0
) {
// Override with fixed column order number and set a relevant mode value.
moreKeysColumnAndFlags =
(KeyConsts.MORE_KEYS_MODE_FIXED_COLUMN_WITH_FIXED_ORDER
or (value and KeyConsts.MORE_KEYS_COLUMN_NUMBER_MASK))
}
if (MoreKeySpec.getBooleanValue(
moreKeys,
KeyConsts.MORE_KEYS_HAS_LABELS
)
) {
moreKeysColumnAndFlags =
moreKeysColumnAndFlags or KeyConsts.MORE_KEYS_FLAGS_HAS_LABELS
}
if (MoreKeySpec.getBooleanValue(
moreKeys,
KeyConsts.MORE_KEYS_NEEDS_DIVIDERS
)
) {
moreKeysColumnAndFlags =
moreKeysColumnAndFlags or KeyConsts.MORE_KEYS_FLAGS_NEEDS_DIVIDERS
}
if (MoreKeySpec.getBooleanValue(
moreKeys,
KeyConsts.MORE_KEYS_NO_PANEL_AUTO_MORE_KEY
)
) {
moreKeysColumnAndFlags =
moreKeysColumnAndFlags or KeyConsts.MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY
}
return moreKeysColumnAndFlags
}
private fun filterMoreKeysFlags(moreKeys: List<String>): List<String> =
moreKeys.filter {
!it.startsWith(KeyConsts.MORE_KEYS_AUTO_COLUMN_ORDER) &&
!it.startsWith(KeyConsts.MORE_KEYS_FIXED_COLUMN_ORDER) &&
!it.startsWith(KeyConsts.MORE_KEYS_HAS_LABELS) &&
!it.startsWith(KeyConsts.MORE_KEYS_NEEDS_DIVIDERS) &&
!it.startsWith(KeyConsts.MORE_KEYS_NO_PANEL_AUTO_MORE_KEY)
}