From d5cbcb37e315a62b9e61873937bc4b38e4d0f5a7 Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Sun, 24 Sep 2023 16:35:24 +0200 Subject: [PATCH] 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. --- res/xml/method.xml | 2 +- srcs/juloo.keyboard2/ExtraKeys.java | 45 ++++++++++++++++++-------- srcs/juloo.keyboard2/KeyboardData.java | 22 +++++++++++++ 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/res/xml/method.xml b/res/xml/method.xml index f602377..3dcd898 100644 --- a/res/xml/method.xml +++ b/res/xml/method.xml @@ -12,7 +12,7 @@ - + diff --git a/srcs/juloo.keyboard2/ExtraKeys.java b/srcs/juloo.keyboard2/ExtraKeys.java index aa2e38f..ca9e46a 100644 --- a/srcs/juloo.keyboard2/ExtraKeys.java +++ b/srcs/juloo.keyboard2/ExtraKeys.java @@ -63,12 +63,15 @@ class ExtraKeys /** The key will not be added to layout that already contain all the alternatives. */ final List alternatives; + /** The key next to which to add. Might be [null]. */ + final KeyValue next_to; - ExtraKey(KeyValue kv_, String script_, List alts_) + ExtraKey(KeyValue kv_, String script_, List 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 alts = new ArrayList(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 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); } } diff --git a/srcs/juloo.keyboard2/KeyboardData.java b/srcs/juloo.keyboard2/KeyboardData.java index 94c1384..8ecd053 100644 --- a/srcs/juloo.keyboard2/KeyboardData.java +++ b/srcs/juloo.keyboard2/KeyboardData.java @@ -58,6 +58,13 @@ class KeyboardData [rows]. Returns [false] if it couldn't be placed. */ boolean add_key_to_preferred_pos(List 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) };