diff options
Diffstat (limited to 'srcs/juloo.keyboard2')
| -rw-r--r-- | srcs/juloo.keyboard2/Config.java | 20 | ||||
| -rw-r--r-- | srcs/juloo.keyboard2/CustomExtraKeysPreference.java | 10 | ||||
| -rw-r--r-- | srcs/juloo.keyboard2/ExtraKeys.java | 11 | ||||
| -rw-r--r-- | srcs/juloo.keyboard2/ExtraKeysPreference.java | 10 | ||||
| -rw-r--r-- | srcs/juloo.keyboard2/KeyboardData.java | 117 |
5 files changed, 120 insertions, 48 deletions
diff --git a/srcs/juloo.keyboard2/Config.java b/srcs/juloo.keyboard2/Config.java index da78f7f..bde4aea 100644 --- a/srcs/juloo.keyboard2/Config.java +++ b/srcs/juloo.keyboard2/Config.java @@ -9,8 +9,10 @@ import android.util.TypedValue; import android.view.KeyEvent; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; final class Config @@ -59,8 +61,8 @@ final class Config public int actionId; // Meaningful only when 'actionLabel' isn't 'null' public boolean swapEnterActionKey; // Swap the "enter" and "action" keys public ExtraKeys extra_keys_subtype; - public Set<KeyValue> extra_keys_param; - public List<KeyValue> extra_keys_custom; + public Map<KeyValue, KeyboardData.PreferredPos> extra_keys_param; + public Map<KeyValue, KeyboardData.PreferredPos> extra_keys_custom; public final IKeyEventHandler handler; public boolean orientation_landscape = false; @@ -174,16 +176,16 @@ final class Config final KeyValue action_key = action_key(); // Extra keys are removed from the set as they are encountered during the // first iteration then automatically added. - final Set<KeyValue> extra_keys = new HashSet<KeyValue>(); + final Map<KeyValue, KeyboardData.PreferredPos> extra_keys = new HashMap<KeyValue, KeyboardData.PreferredPos>(); final Set<KeyValue> remove_keys = new HashSet<KeyValue>(); - extra_keys.addAll(extra_keys_param); - extra_keys.addAll(extra_keys_custom); + extra_keys.putAll(extra_keys_param); + extra_keys.putAll(extra_keys_custom); if (extra_keys_subtype != null) { Set<KeyValue> present = new HashSet<KeyValue>(); present.addAll(kw.getKeys().keySet()); - present.addAll(extra_keys_param); - present.addAll(extra_keys_custom); + present.addAll(extra_keys_param.keySet()); + present.addAll(extra_keys_custom.keySet()); extra_keys_subtype.compute(extra_keys, new ExtraKeys.Query(kw.script, present)); } @@ -193,7 +195,7 @@ final class Config kw = kw.mapKeys(new KeyboardData.MapKeyValues() { public KeyValue apply(KeyValue key, boolean localized) { - boolean is_extra_key = extra_keys.contains(key); + boolean is_extra_key = extra_keys.containsKey(key); if (is_extra_key) extra_keys.remove(key); if (localized && !is_extra_key) @@ -246,7 +248,7 @@ final class Config if (number_row) kw = kw.addNumberRow(); if (extra_keys.size() > 0) - kw = kw.addExtraKeys(extra_keys.iterator()); + kw = kw.addExtraKeys(extra_keys.entrySet().iterator()); return kw; } diff --git a/srcs/juloo.keyboard2/CustomExtraKeysPreference.java b/srcs/juloo.keyboard2/CustomExtraKeysPreference.java index b17ff8d..d007bf7 100644 --- a/srcs/juloo.keyboard2/CustomExtraKeysPreference.java +++ b/srcs/juloo.keyboard2/CustomExtraKeysPreference.java @@ -10,8 +10,9 @@ import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; -import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.json.JSONArray; import org.json.JSONException; @@ -30,14 +31,15 @@ public class CustomExtraKeysPreference extends ListGroupPreference<String> setKey(KEY); } - public static List<KeyValue> get(SharedPreferences prefs) + public static Map<KeyValue, KeyboardData.PreferredPos> get(SharedPreferences prefs) { - List<KeyValue> kvs = new ArrayList<KeyValue>(); + Map<KeyValue, KeyboardData.PreferredPos> kvs = + new HashMap<KeyValue, KeyboardData.PreferredPos>(); List<String> key_names = load_from_preferences(KEY, prefs, null, SERIALIZER); if (key_names != null) { for (String key_name : key_names) - kvs.add(KeyValue.makeStringKey(key_name)); + kvs.put(KeyValue.makeStringKey(key_name), KeyboardData.PreferredPos.DEFAULT); } return kvs; } diff --git a/srcs/juloo.keyboard2/ExtraKeys.java b/srcs/juloo.keyboard2/ExtraKeys.java index cfac362..aa2e38f 100644 --- a/srcs/juloo.keyboard2/ExtraKeys.java +++ b/srcs/juloo.keyboard2/ExtraKeys.java @@ -22,7 +22,7 @@ class ExtraKeys /** Add the keys that should be added to the keyboard into [dst]. Keys already added to [dst] might have an impact, see [ExtraKey.compute]. */ - public void compute(Set<KeyValue> dst, Query q) + public void compute(Map<KeyValue, KeyboardData.PreferredPos> dst, Query q) { for (ExtraKey k : _ks) k.compute(dst, q); @@ -72,7 +72,7 @@ class ExtraKeys } /** Whether the key should be added to the keyboard. */ - public void compute(Set<KeyValue> dst, Query q) + public void compute(Map<KeyValue, KeyboardData.PreferredPos> dst, Query q) { // Add the alternative if it's the only one. The list of alternatives is // enforced to be complete by the merging step. The same [kv] will not @@ -80,11 +80,14 @@ class ExtraKeys // alternatives. // Selecting the dead key in the "Add key to the keyboard" option would // disable this behavior for a key. - boolean use_alternative = (alternatives.size() == 1 && !dst.contains(kv)); + boolean use_alternative = (alternatives.size() == 1 && !dst.containsKey(kv)); if ((q.script == null || script == null || q.script.equals(script)) && (alternatives.size() == 0 || !q.present.containsAll(alternatives))) - dst.add(use_alternative ? alternatives.get(0) : kv); + { + KeyValue kv_ = use_alternative ? alternatives.get(0) : kv; + dst.put(kv_, KeyboardData.PreferredPos.DEFAULT); + } } /** Return a new key from two. [kv] are expected to be equal. [script] is diff --git a/srcs/juloo.keyboard2/ExtraKeysPreference.java b/srcs/juloo.keyboard2/ExtraKeysPreference.java index 8dacdea..0bbf0ce 100644 --- a/srcs/juloo.keyboard2/ExtraKeysPreference.java +++ b/srcs/juloo.keyboard2/ExtraKeysPreference.java @@ -8,7 +8,8 @@ import android.preference.PreferenceCategory; import android.util.AttributeSet; import android.view.View; import android.widget.TextView; -import java.util.HashSet; +import java.util.HashMap; +import java.util.Map; import java.util.Set; /** This class implements the "extra keys" preference but also defines the @@ -100,14 +101,15 @@ public class ExtraKeysPreference extends PreferenceCategory } /** Get the set of enabled extra keys. */ - public static Set<KeyValue> get_extra_keys(SharedPreferences prefs) + public static Map<KeyValue, KeyboardData.PreferredPos> get_extra_keys(SharedPreferences prefs) { - HashSet<KeyValue> ks = new HashSet<KeyValue>(); + Map<KeyValue, KeyboardData.PreferredPos> ks = + new HashMap<KeyValue, KeyboardData.PreferredPos>(); for (String key_name : extra_keys) { if (prefs.getBoolean(pref_key_of_key_name(key_name), default_checked(key_name))) - ks.add(KeyValue.getKeyByName(key_name)); + ks.put(KeyValue.getKeyByName(key_name), KeyboardData.PreferredPos.DEFAULT); } return ks; } 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. */ |
