abouttreesummaryrefslogcommitdiff
path: root/srcs/juloo.keyboard2/KeyboardData.java
diff options
context:
space:
mode:
authorJules Aguillon2023-09-15 18:00:27 +0200
committerJules Aguillon2023-09-15 18:00:27 +0200
commit66b1bdc9c90e1f29ecec096286136b527ec6b8ed (patch)
tree581d6f693ba487a91775725e7d6e3ffe7437c2b1 /srcs/juloo.keyboard2/KeyboardData.java
parentd771e9d2c7de7d62f5514995f4a224e1e293a376 (diff)
downloadunexpected-keyboard-66b1bdc9c90e1f29ecec096286136b527ec6b8ed.tar.gz
unexpected-keyboard-66b1bdc9c90e1f29ecec096286136b527ec6b8ed.zip
Refactor: Preferred positions for extra keys
The new PreferredPos class represents where an extra key should be placed Currently used to place keys at the same positions they were placed before.
Diffstat (limited to 'srcs/juloo.keyboard2/KeyboardData.java')
-rw-r--r--srcs/juloo.keyboard2/KeyboardData.java117
1 files changed, 90 insertions, 27 deletions
diff --git a/srcs/juloo.keyboard2/KeyboardData.java b/srcs/juloo.keyboard2/KeyboardData.java
index 0083b38..94c1384 100644
--- a/srcs/juloo.keyboard2/KeyboardData.java
+++ b/srcs/juloo.keyboard2/KeyboardData.java
@@ -36,26 +36,68 @@ class KeyboardData
return new KeyboardData(rows_, keysWidth, modmap, script);
}
- /** Add keys from the given iterator into the keyboard. Extra keys are added
- * on the empty key4 corner of the second row, from right to left. If there's
- * not enough room, key3 of the second row is tried then key2 and key1 of the
- * third row. */
- public KeyboardData addExtraKeys(Iterator<KeyValue> k)
+ /** Add keys from the given iterator into the keyboard. Preferred position is
+ specified via [PreferredPos]. */
+ public KeyboardData addExtraKeys(Iterator<Map.Entry<KeyValue, PreferredPos>> extra_keys)
{
+ /* Keys that couldn't be placed at their preferred position. */
+ ArrayList<KeyValue> unplaced_keys = new ArrayList<KeyValue>();
ArrayList<Row> rows = new ArrayList<Row>(this.rows);
- addExtraKeys_to_row(rows, k, 1, 4);
- addExtraKeys_to_row(rows, k, 1, 3);
- addExtraKeys_to_row(rows, k, 2, 2);
- addExtraKeys_to_row(rows, k, 2, 1);
- if (k.hasNext())
+ while (extra_keys.hasNext())
{
- for (int r = 0; r < rows.size(); r++)
- for (int c = 1; c <= 4; c++)
- addExtraKeys_to_row(rows, k, r, c);
+ Map.Entry<KeyValue, PreferredPos> kp = extra_keys.next();
+ if (!add_key_to_preferred_pos(rows, kp.getKey(), kp.getValue()))
+ unplaced_keys.add(kp.getKey());
}
+ for (KeyValue kv : unplaced_keys)
+ add_key_to_preferred_pos(rows, kv, PreferredPos.ANYWHERE);
return new KeyboardData(rows, keysWidth, modmap, script);
}
+ /** Place a key on the keyboard according to its preferred position. Mutates
+ [rows]. Returns [false] if it couldn't be placed. */
+ boolean add_key_to_preferred_pos(List<Row> rows, KeyValue kv, PreferredPos pos)
+ {
+ for (KeyPos p : pos.positions)
+ if (add_key_to_pos(rows, kv, p))
+ return true;
+ return false;
+ }
+
+ /** Place a key on the keyboard. A value of [-1] in one of the coordinate
+ means that the key can be placed anywhere in that coordinate, see
+ [PreferredPos]. Mutates [rows]. Returns [false] if it couldn't be placed.
+ */
+ boolean add_key_to_pos(List<Row> rows, KeyValue kv, KeyPos p)
+ {
+ int i_row = p.row;
+ int i_row_end = p.row;
+ if (p.row == -1) { i_row = 0; i_row_end = rows.size() - 1; }
+ for (; i_row <= i_row_end; i_row++)
+ {
+ Row row = rows.get(i_row);
+ int i_col = p.col;
+ int i_col_end = p.col;
+ if (p.col == -1) { i_col = 0; i_col_end = row.keys.size() - 1; }
+ for (; i_col <= i_col_end; i_col++)
+ {
+ Key col = row.keys.get(i_col);
+ int i_dir = p.dir;
+ int i_dir_end = p.dir;
+ if (p.dir == -1) { i_dir = 1; i_dir_end = 4; }
+ for (; i_dir <= i_dir_end; i_dir++)
+ {
+ if (col.getKeyValue(i_dir) == null)
+ {
+ row.keys.set(i_col, col.withKeyValue(i_dir, kv));
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
public KeyboardData addNumPad(KeyboardData num_pad)
{
ArrayList<Row> extendedRows = new ArrayList<Row>();
@@ -107,20 +149,6 @@ class KeyboardData
return _key_pos;
}
- private static void addExtraKeys_to_row(ArrayList<Row> rows, final Iterator<KeyValue> extra_keys, int row_i, final int d)
- {
- if (!extra_keys.hasNext() || row_i >= rows.size())
- return;
- rows.set(row_i, rows.get(row_i).mapKeys(new MapKey(){
- public Key apply(Key k) {
- if (k.getKeyValue(d) == null && extra_keys.hasNext())
- return k.withKeyValue(d, extra_keys.next());
- else
- return k;
- }
- }));
- }
-
public static Row bottom_row;
public static Row number_row;
public static KeyboardData num_pad;
@@ -263,6 +291,11 @@ class KeyboardData
return new Row(keys, h, shift);
}
+ public Row copy()
+ {
+ return new Row(new ArrayList<Key>(keys), height, shift);
+ }
+
public void getKeys(Map<KeyValue, KeyPos> dst, int row)
{
for (int c = 0; c < keys.size(); c++)
@@ -490,6 +523,36 @@ class KeyboardData
}
}
+ /** See [addExtraKeys()]. */
+ public final static class PreferredPos
+ {
+ public static final PreferredPos DEFAULT;
+ public static final PreferredPos ANYWHERE;
+
+ /** 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
+ searched in this order: [dir], [col], [row]. */
+ public KeyPos[] positions = ANYWHERE_POSITIONS;
+
+ public PreferredPos() {}
+
+ static final KeyPos[] ANYWHERE_POSITIONS =
+ new KeyPos[]{ new KeyPos(-1, -1, -1) };
+
+ static
+ {
+ DEFAULT = new PreferredPos();
+ DEFAULT.positions = new KeyPos[]{
+ new KeyPos(1, -1, 4),
+ new KeyPos(1, -1, 3),
+ new KeyPos(2, -1, 2),
+ new KeyPos(2, -1, 1)
+ };
+ ANYWHERE = new PreferredPos();
+ }
+ }
+
/** Parsing utils */
/** Returns [false] on [END_DOCUMENT] or [END_TAG], [true] otherwise. */