Preferred position for locale extra_keys

`method.xml` is now able to specify a preferred position for each extra
keys in term of an other key to which it should be placed nearby.

It's implemented for French as an example.
This commit is contained in:
Jules Aguillon 2023-09-24 16:35:24 +02:00
parent 66b1bdc9c9
commit d5cbcb37e3
3 changed files with 55 additions and 14 deletions

View File

@ -12,7 +12,7 @@
<subtype android:label="%s" android:languageTag="es" android:imeSubtypeLocale="es_ES" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_es,extra_keys=accent_aigu:á:é:í:ó:ú|accent_tilde:ñ|accent_grave|accent_trema|€"/>
<subtype android:label="%s" android:languageTag="fa" android:imeSubtypeLocale="fa_IR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=arab_pc_ir"/>
<subtype android:label="%s" android:languageTag="fr-CH" android:imeSubtypeLocale="fr_CH" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwertz_fr_ch,extra_keys=accent_grave:à:è:ù|accent_aigu:é|accent_circonflexe:â:ê:ô|accent_cedille:ç|accent_trema:ë:ï:ü:ÿ|€"/>
<subtype android:label="%s" android:languageTag="fr-FR" android:imeSubtypeLocale="fr_FR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_azerty_fr,extra_keys=accent_grave:à:è:ù|accent_aigu:é|accent_circonflexe:â:ê:ô|accent_cedille:ç|accent_trema:ë:ï:ü:ÿ|€"/>
<subtype android:label="%s" android:languageTag="fr-FR" android:imeSubtypeLocale="fr_FR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_azerty_fr,extra_keys=accent_grave:à:è:ù@a|accent_aigu:é@e|accent_circonflexe:â:ê:ô@e|accent_cedille:ç@c|accent_trema:ë:ï:ü:ÿ@l|€"/>
<subtype android:label="%s" android:languageTag="he" android:imeSubtypeLocale="he_IL" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=hebrew,default_layout=hebr_1_il,extra_keys=₪|€"/>
<subtype android:label="%s" android:languageTag="hi" android:imeSubtypeLocale="hi_IN" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=devanagari,default_layout=deva_inscript,extra_keys=₹"/>
<subtype android:label="%s" android:languageTag="hu" android:imeSubtypeLocale="hu_HU" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwertz_hu,extra_keys=accent_aigu:á:é:í:ó:ú|accent_trema:ö:ü|accent_ogonek|accent_double_aigu:ő:ű|€"/>

View File

@ -63,12 +63,15 @@ class ExtraKeys
/** The key will not be added to layout that already contain all the
alternatives. */
final List<KeyValue> alternatives;
/** The key next to which to add. Might be [null]. */
final KeyValue next_to;
ExtraKey(KeyValue kv_, String script_, List<KeyValue> alts_)
ExtraKey(KeyValue kv_, String script_, List<KeyValue> alts_, KeyValue next_to_)
{
kv = kv_;
script = script_;
alternatives = alts_;
next_to = next_to_;
}
/** Whether the key should be added to the keyboard. */
@ -86,7 +89,13 @@ class ExtraKeys
&& (alternatives.size() == 0 || !q.present.containsAll(alternatives)))
{
KeyValue kv_ = use_alternative ? alternatives.get(0) : kv;
dst.put(kv_, KeyboardData.PreferredPos.DEFAULT);
KeyboardData.PreferredPos pos = KeyboardData.PreferredPos.DEFAULT;
if (next_to != null)
{
pos = new KeyboardData.PreferredPos(pos);
pos.next_to = next_to;
}
dst.put(kv_, pos);
}
}
@ -95,23 +104,33 @@ class ExtraKeys
*/
public ExtraKey merge_with(ExtraKey k2)
{
String script_ =
(script != null && k2.script != null && script.equals(k2.script))
? script : null;
String script_ = one_or_none(script, k2.script);
List<KeyValue> alts = new ArrayList<KeyValue>(alternatives);
KeyValue next_to_ = one_or_none(next_to, k2.next_to);
alts.addAll(k2.alternatives);
return new ExtraKey(kv, script_, alts);
return new ExtraKey(kv, script_, alts, next_to_);
}
/** Extra keys are of the form "key name" or "key name:alt 1:alt 2". */
/** If one of [a] or [b] is null, return the other. If [a] and [b] are
equal, return [a]. Otherwise, return null. */
<E> E one_or_none(E a, E b)
{
return (a == null) ? b : (b == null || a.equals(b)) ? a : null;
}
/** Extra keys are of the form "key name" or "key name:alt1:alt2@next_to". */
public static ExtraKey parse(String str, String script)
{
String[] strs = str.split(":");
KeyValue kv = KeyValue.getKeyByName(strs[0]);
KeyValue[] alts = new KeyValue[strs.length-1];
for (int i = 1; i < strs.length; i++)
alts[i-1] = KeyValue.getKeyByName(strs[i]);
return new ExtraKey(kv, script, Arrays.asList(alts));
String[] split_on_at = str.split("@", 2);
String[] key_names = split_on_at[0].split(":");
KeyValue kv = KeyValue.getKeyByName(key_names[0]);
KeyValue[] alts = new KeyValue[key_names.length-1];
for (int i = 1; i < key_names.length; i++)
alts[i-1] = KeyValue.getKeyByName(key_names[i]);
KeyValue next_to = null;
if (split_on_at.length > 1)
next_to = KeyValue.getKeyByName(split_on_at[1]);
return new ExtraKey(kv, script, Arrays.asList(alts), next_to);
}
}

View File

@ -58,6 +58,13 @@ class KeyboardData
[rows]. Returns [false] if it couldn't be placed. */
boolean add_key_to_preferred_pos(List<Row> rows, KeyValue kv, PreferredPos pos)
{
if (pos.next_to != null)
{
KeyPos next_to_pos = getKeys().get(pos.next_to);
if (next_to_pos != null
&& add_key_to_pos(rows, kv, next_to_pos.with_dir(-1)))
return true;
}
for (KeyPos p : pos.positions)
if (add_key_to_pos(rows, kv, p))
return true;
@ -521,6 +528,11 @@ class KeyboardData
col = c;
dir = d;
}
public KeyPos with_dir(int d)
{
return new KeyPos(row, col, d);
}
}
/** See [addExtraKeys()]. */
@ -529,6 +541,10 @@ class KeyboardData
public static final PreferredPos DEFAULT;
public static final PreferredPos ANYWHERE;
/** Prefer the free position on the same keyboard key as the specified key.
Considered before [positions]. Might be [null]. */
public KeyValue next_to = null;
/** Array of positions to try in order. The special value [-1] as [row],
[col] or [dir] means that the field is unspecified. Every possible
values are tried for unspecified fields. Unspecified fields are
@ -537,6 +553,12 @@ class KeyboardData
public PreferredPos() {}
public PreferredPos(PreferredPos src)
{
next_to = src.next_to;
positions = src.positions;
}
static final KeyPos[] ANYWHERE_POSITIONS =
new KeyPos[]{ new KeyPos(-1, -1, -1) };