diff --git a/srcs/juloo.keyboard2/Keyboard2View.java b/srcs/juloo.keyboard2/Keyboard2View.java index 0a75529..cb93b3a 100644 --- a/srcs/juloo.keyboard2/Keyboard2View.java +++ b/srcs/juloo.keyboard2/Keyboard2View.java @@ -370,9 +370,9 @@ public class Keyboard2View extends View return sublabel ? _theme.subLabelColor : _theme.labelColor; } - private void drawLabel(Canvas canvas, KeyboardData.Corner k, float x, float y, float keyH, boolean isKeyDown) + private void drawLabel(Canvas canvas, KeyValue kv, float x, float y, float keyH, boolean isKeyDown) { - KeyValue kv = KeyModifier.modify(k.kv, _mods); + kv = KeyModifier.modify(kv, _mods); if (kv == null) return; float textSize = scaleTextSize(kv, _config.labelTextSize, keyH); @@ -383,12 +383,12 @@ public class Keyboard2View extends View canvas.drawText(kv.getString(), x, (keyH - p.ascent() - p.descent()) / 2f + y, p); } - private void drawSubLabel(Canvas canvas, KeyboardData.Corner k, float x, - float y, float keyW, float keyH, int sub_index, boolean isKeyDown) + private void drawSubLabel(Canvas canvas, KeyValue kv, float x, float y, + float keyW, float keyH, int sub_index, boolean isKeyDown) { Paint.Align a = LABEL_POSITION_H[sub_index]; Vertical v = LABEL_POSITION_V[sub_index]; - KeyValue kv = KeyModifier.modify(k.kv, _mods); + kv = KeyModifier.modify(kv, _mods); if (kv == null) return; float textSize = scaleTextSize(kv, _config.sublabelTextSize, keyH); diff --git a/srcs/juloo.keyboard2/KeyboardData.java b/srcs/juloo.keyboard2/KeyboardData.java index 945e6ee..5578a99 100644 --- a/srcs/juloo.keyboard2/KeyboardData.java +++ b/srcs/juloo.keyboard2/KeyboardData.java @@ -284,8 +284,9 @@ class KeyboardData * 5 0 6 * 3 8 4 */ - public final Corner[] keys; - + public final KeyValue[] keys; + /** Pack flags for every key values. Flags are: [F_LOC]. */ + private final int keysflags; /** Key width in relative unit. */ public final float width; /** Extra empty space on the left of the key. */ @@ -296,125 +297,112 @@ class KeyboardData /** String printed on the keys. It has no other effect. */ public final String indication; - protected Key(Corner[] ks, float w, float s, boolean sl, String i) + /** Whether a key was declared with the 'loc' prefix. */ + public static final int F_LOC = 1; + public static final int ALL_FLAGS = F_LOC; + + protected Key(KeyValue[] ks, int f, float w, float s, boolean sl, String i) { keys = ks; + keysflags = f; width = w; shift = s; slider = sl; indication = i; } + /** Write the parsed key into [ks] at [index]. Doesn't write if the + attribute is not present. Return flags that can be aggregated into the + value for [keysflags]. */ + static int parse_key_attr(XmlPullParser parser, String attr, KeyValue[] ks, + int index) + throws Exception + { + String name = parser.getAttributeValue(null, attr); + int flags = 0; + if (name == null) + return 0; + String name_loc = stripPrefix(name, "loc "); + if (name_loc != null) + { + flags |= F_LOC; + name = name_loc; + } + ks[index] = KeyValue.getKeyByName(name); + return (flags << index); + } + + static String stripPrefix(String s, String prefix) + { + return s.startsWith(prefix) ? s.substring(prefix.length()) : null; + } + public static Key parse(XmlPullParser parser) throws Exception { - Corner[] ks = new Corner[9]; - ks[0] = Corner.parse_of_attr(parser, "key0"); - ks[1] = Corner.parse_of_attr(parser, "key1"); - ks[2] = Corner.parse_of_attr(parser, "key2"); - ks[3] = Corner.parse_of_attr(parser, "key3"); - ks[4] = Corner.parse_of_attr(parser, "key4"); - ks[5] = Corner.parse_of_attr(parser, "key5"); - ks[6] = Corner.parse_of_attr(parser, "key6"); - ks[7] = Corner.parse_of_attr(parser, "key7"); - ks[8] = Corner.parse_of_attr(parser, "key8"); + KeyValue[] ks = new KeyValue[9]; + int keysflags = 0; + keysflags |= parse_key_attr(parser, "key0", ks, 0); + keysflags |= parse_key_attr(parser, "key1", ks, 1); + keysflags |= parse_key_attr(parser, "key2", ks, 2); + keysflags |= parse_key_attr(parser, "key3", ks, 3); + keysflags |= parse_key_attr(parser, "key4", ks, 4); + keysflags |= parse_key_attr(parser, "key5", ks, 5); + keysflags |= parse_key_attr(parser, "key6", ks, 6); + keysflags |= parse_key_attr(parser, "key7", ks, 7); + keysflags |= parse_key_attr(parser, "key8", ks, 8); float width = attribute_float(parser, "width", 1f); float shift = attribute_float(parser, "shift", 0.f); boolean slider = attribute_bool(parser, "slider", false); String indication = parser.getAttributeValue(null, "indication"); while (parser.next() != XmlPullParser.END_TAG) - continue ; - return new Key(ks, width, shift, slider, indication); + continue; + return new Key(ks, keysflags, width, shift, slider, indication); + } + + /** Whether key at [index] as [flag]. */ + public boolean keyHasFlag(int index, int flag) + { + return (keysflags & (flag << index)) != 0; } /** New key with the width multiplied by 's'. */ public Key scaleWidth(float s) { - return new Key(keys, width * s, shift, slider, indication); + return new Key(keys, keysflags, width * s, shift, slider, indication); } public void getKeys(Set dst) { for (int i = 0; i < keys.length; i++) if (keys[i] != null) - dst.add(keys[i].kv); + dst.add(keys[i]); } public KeyValue getKeyValue(int i) { - if (keys[i] == null) - return null; - return keys[i].kv; + return keys[i]; } public Key withKeyValue(int i, KeyValue kv) { - Corner[] ks = Arrays.copyOf(keys, keys.length); - ks[i] = Corner.of_kv(kv); - return new Key(ks, width, shift, slider, indication); + KeyValue[] ks = Arrays.copyOf(keys, keys.length); + ks[i] = kv; + int flags = (keysflags & ~(ALL_FLAGS << i)); + return new Key(ks, flags, width, shift, slider, indication); } public Key withShift(float s) { - return new Key(keys, width, s, slider, indication); + return new Key(keys, keysflags, width, s, slider, indication); } public boolean hasValue(KeyValue kv) { for (int i = 0; i < keys.length; i++) - if (keys[i] != null && keys[i].kv.equals(kv)) + if (keys[i] != null && keys[i].equals(kv)) return true; return false; } - - public boolean hasValue(KeyValue kv, int i) - { - if (keys[i] == null) - return false; - return kv.equals(keys[i].kv); - } - } - - public static final class Corner - { - public final KeyValue kv; - /** Whether the kv is marked with the "loc " prefix. To be removed if not - specified in the [extra_keys]. */ - public final boolean localized; - - protected Corner(KeyValue k, boolean l) - { - kv = k; - localized = l; - } - - public static Corner parse_of_attr(XmlPullParser parser, String attr) throws Exception - { - String name = parser.getAttributeValue(null, attr); - boolean localized = false; - - if (name == null) - return null; - String name_loc = stripPrefix(name, "loc "); - if (name_loc != null) - { - localized = true; - name = name_loc; - } - return new Corner(KeyValue.getKeyByName(name), localized); - } - - public static Corner of_kv(KeyValue kv) - { - return new Corner(kv, false); - } - - private static String stripPrefix(String s, String prefix) - { - if (s.startsWith(prefix)) - return s.substring(prefix.length()); - else - return null; - } } // Not using Function to keep compatibility with Android 6. @@ -427,17 +415,11 @@ class KeyboardData public Key apply(Key k) { - Corner[] ks = new Corner[k.keys.length]; + KeyValue[] ks = new KeyValue[k.keys.length]; for (int i = 0; i < ks.length; i++) if (k.keys[i] != null) - ks[i] = apply(k.keys[i]); - return new Key(ks, k.width, k.shift, k.slider, k.indication); - } - - protected Corner apply(Corner c) - { - KeyValue kv = apply(c.kv, c.localized); - return (kv == null) ? null : new Corner(kv, c.localized); + ks[i] = apply(k.keys[i], k.keyHasFlag(i, Key.F_LOC)); + return new Key(ks, k.keysflags, k.width, k.shift, k.slider, k.indication); } } diff --git a/srcs/juloo.keyboard2/Pointers.java b/srcs/juloo.keyboard2/Pointers.java index b9e4d07..6979d7b 100644 --- a/srcs/juloo.keyboard2/Pointers.java +++ b/srcs/juloo.keyboard2/Pointers.java @@ -167,7 +167,7 @@ public final class Pointers implements Handler.Callback // Don't take latched modifiers into account if an other key is pressed. // The other key already "own" the latched modifiers and will clear them. Modifiers mods = getModifiers(isOtherPointerDown()); - KeyValue value = handleKV(key.keys[0], mods); + KeyValue value = _handler.modifyKey(key.keys[0], mods); Pointer ptr = new Pointer(pointerId, key, value, x, y, mods); _ptrs.add(ptr); startKeyRepeat(ptr); @@ -184,10 +184,7 @@ public final class Pointers implements Handler.Callback */ KeyValue getKeyAtDirection(KeyboardData.Key k, int direction) { - int i = DIRECTION_TO_INDEX[direction]; - if (k.keys[i] == null) - return null; - return k.keys[i].kv; + return k.keys[DIRECTION_TO_INDEX[direction]]; } /* @@ -201,7 +198,7 @@ public final class Pointers implements Handler.Callback private KeyValue getNearestKeyAtDirection(Pointer ptr, Integer direction) { if (direction == null) - return handleKV(ptr.key.keys[0], ptr.modifiers); + return _handler.modifyKey(ptr.key.keys[0], ptr.modifiers); KeyValue k; // [i] is [0, -1, 1, -2, 2, ...] for (int i = 0; i > -4; i = (~i>>31) - i) @@ -216,13 +213,6 @@ public final class Pointers implements Handler.Callback return null; } - private KeyValue handleKV(KeyboardData.Corner c, Modifiers modifiers) - { - if (c == null) - return null; - return _handler.modifyKey(c.kv, modifiers); - } - public void onTouchMove(float x, float y, int pointerId) { Pointer ptr = getPtr(pointerId); @@ -265,7 +255,8 @@ public final class Pointers implements Handler.Callback ptr.flags = newValue.getFlags(); // Sliding mode is entered when key5 or key6 is down on a slider key. if (ptr.key.slider && - (ptr.key.hasValue(newValue, 5) || ptr.key.hasValue(newValue, 6))) + (newValue.equals(ptr.key.getKeyValue(5)) + || newValue.equals(ptr.key.getKeyValue(6)))) { startSliding(ptr, dy); } @@ -424,7 +415,7 @@ public final class Pointers implements Handler.Callback if (count == ptr.sliding_count) return; int key_index = (count < ptr.sliding_count) ? 5 : 6; - KeyValue newValue = handleKV(ptr.key.keys[key_index], ptr.modifiers); + KeyValue newValue = _handler.modifyKey(ptr.key.keys[key_index], ptr.modifiers); ptr.sliding_count = count; ptr.value = newValue; if (newValue != null)