abouttreesummaryrefslogcommitdiff
path: root/srcs/juloo.keyboard2/KeyboardData.java
diff options
context:
space:
mode:
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. */