abouttreesummaryrefslogcommitdiff
path: root/srcs/juloo.keyboard2
diff options
context:
space:
mode:
Diffstat (limited to 'srcs/juloo.keyboard2')
-rw-r--r--srcs/juloo.keyboard2/Config.java20
-rw-r--r--srcs/juloo.keyboard2/CustomExtraKeysPreference.java10
-rw-r--r--srcs/juloo.keyboard2/ExtraKeys.java11
-rw-r--r--srcs/juloo.keyboard2/ExtraKeysPreference.java10
-rw-r--r--srcs/juloo.keyboard2/KeyboardData.java117
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. */