From 1a290f96f26b848a217ee5db3d6d5920c7c38a27 Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Wed, 29 May 2024 11:59:54 +0200 Subject: [PATCH] Configure anticircle gesture per-key (#644) This adds the new 'anticircle' attribute to layouts '' elements that configure the key to send when doing a anti-clockwise circle gesture on it. Labels are drawn the same way as indication. Updated docs. --- doc/Custom-layouts.md | 3 ++ srcs/juloo.keyboard2/Keyboard2View.java | 37 +++++++++++++++++-------- srcs/juloo.keyboard2/KeyboardData.java | 25 +++++++++++++---- srcs/juloo.keyboard2/Pointers.java | 2 +- srcs/juloo.keyboard2/Theme.java | 6 ++-- 5 files changed, 53 insertions(+), 20 deletions(-) diff --git a/doc/Custom-layouts.md b/doc/Custom-layouts.md index 83ec299..993a1dc 100644 --- a/doc/Custom-layouts.md +++ b/doc/Custom-layouts.md @@ -61,6 +61,8 @@ For example, to make the `I` key behave as in Turkish: There can be as many of these tags inside `` as needed. +Shift and Fn modmaps also affect the clockwise circle and the roundtrip gestures. + ### Row The `` tag encloses one row on the keyboard. It requires no properties, and supports the following: @@ -94,6 +96,7 @@ The following properties are optionally supported: * `shift`: How much empty space to add to the left of this key. Defaults to `0` and accepts a non-negative floating point value. * `indication`: An extra label to show under the main label, intended to be used as a legend for 2A typing (e.g. ``). Caution: if you have `key8` defined, it overlaps! * `slider`: If set to `true`, the keys `w` and `e` are sent repeatedly when the key is being slid on. Intended to be used on the space bar, and in fact used on the default space bar. +* `anticircle`: The key value to send when doing an anti-clockwise circle gesture on the key. The clockwise circle and round-trip gestures are not configurable that way. ## Possible key values diff --git a/srcs/juloo.keyboard2/Keyboard2View.java b/srcs/juloo.keyboard2/Keyboard2View.java index 40def60..2eea6ea 100644 --- a/srcs/juloo.keyboard2/Keyboard2View.java +++ b/srcs/juloo.keyboard2/Keyboard2View.java @@ -322,10 +322,7 @@ public class Keyboard2View extends View if (k.keys[i] != null) drawSubLabel(canvas, k.keys[i], x, y, keyW, keyH, i, isKeyDown); } - if (k.indication != null) - { - drawIndication(canvas, k.indication, keyW / 2f + x, y, keyH); - } + drawIndication(canvas, k, x, y, keyW, keyH); x += _keyWidth * k.width; } y += row.height * _config.keyHeight; @@ -443,15 +440,33 @@ public class Keyboard2View extends View canvas.drawText(label, 0, label_len, x, y, p); } - private void drawIndication(Canvas canvas, String indication, float x, - float y, float keyH) + private void drawIndication(Canvas canvas, KeyboardData.Key k, float x, + float y, float keyW, float keyH) { - float textSize = keyH * _config.sublabelTextSize * _config.characterSize; - Paint p = _theme.indicationPaint(); + boolean special_font = false; + String indic; + float text_size; + if (k.indication != null) + { + indic = k.indication; + text_size = keyH * _config.sublabelTextSize * _config.characterSize; + } + else if (k.anticircle != null) + { + indic = k.anticircle.getString(); + special_font = k.anticircle.hasFlagsAny(KeyValue.FLAG_KEY_FONT); + text_size = scaleTextSize(k.anticircle, _config.sublabelTextSize, keyH); + } + else + { + return; + } + Paint p = _theme.indicationPaint(special_font); p.setColor(_theme.subLabelColor); - p.setTextSize(textSize); - canvas.drawText(indication, x, - (keyH - p.ascent() - p.descent()) * 4/5 + y, p); + p.setTextSize(text_size); + // Limit indication length to 3 characters + canvas.drawText(indic, 0, Math.min(indic.length(), 3), + x + keyW / 2f, (keyH - p.ascent() - p.descent()) * 4/5 + y, p); } private float scaleTextSize(KeyValue k, float rel_size, float keyH) diff --git a/srcs/juloo.keyboard2/KeyboardData.java b/srcs/juloo.keyboard2/KeyboardData.java index 6206f5b..a106e03 100644 --- a/srcs/juloo.keyboard2/KeyboardData.java +++ b/srcs/juloo.keyboard2/KeyboardData.java @@ -374,6 +374,8 @@ public final class KeyboardData * 3 8 4 */ public final KeyValue[] keys; + /** Key accessed by the anti-clockwise circle gesture. */ + public final KeyValue anticircle; /** Pack flags for every key values. Flags are: [F_LOC]. */ private final int keysflags; /** Key width in relative unit. */ @@ -390,9 +392,10 @@ public final class KeyboardData 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) + protected Key(KeyValue[] ks, KeyValue antic, int f, float w, float s, boolean sl, String i) { keys = ks; + anticircle = antic; keysflags = f; width = w; shift = s; @@ -434,6 +437,14 @@ public final class KeyboardData return (flags << index); } + static KeyValue parse_nonloc_key_attr(XmlPullParser parser, String attr_name) throws Exception + { + String name = parser.getAttributeValue(null, attr_name); + if (name == null) + return null; + return KeyValue.getKeyByName(name); + } + static String stripPrefix(String s, String prefix) { return s.startsWith(prefix) ? s.substring(prefix.length()) : null; @@ -454,13 +465,14 @@ public final class KeyboardData keysflags |= parse_key_attr(parser, get_key_attr(parser, "key7", "n"), ks, 7); keysflags |= parse_key_attr(parser, get_key_attr(parser, "key8", "s"), ks, 8); /* Other key attributes */ + KeyValue anticircle = parse_nonloc_key_attr(parser, "anticircle"); 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, keysflags, width, shift, slider, indication); + return new Key(ks, anticircle, keysflags, width, shift, slider, indication); } /** Whether key at [index] as [flag]. */ @@ -472,7 +484,8 @@ public final class KeyboardData /** New key with the width multiplied by 's'. */ public Key scaleWidth(float s) { - return new Key(keys, keysflags, width * s, shift, slider, indication); + return new Key(keys, anticircle, keysflags, width * s, shift, slider, + indication); } public void getKeys(Map dst, int row, int col) @@ -493,12 +506,12 @@ public final class KeyboardData for (int j = 0; j < keys.length; j++) ks[j] = keys[j]; ks[i] = kv; int flags = (keysflags & ~(ALL_FLAGS << i)); - return new Key(ks, flags, width, shift, slider, indication); + return new Key(ks, anticircle, flags, width, shift, slider, indication); } public Key withShift(float s) { - return new Key(keys, keysflags, width, s, slider, indication); + return new Key(keys, anticircle, keysflags, width, s, slider, indication); } public boolean hasValue(KeyValue kv) @@ -524,7 +537,7 @@ public final class KeyboardData for (int i = 0; i < ks.length; i++) if (k.keys[i] != null) 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); + return new Key(ks, k.anticircle, 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 8de4832..01d95bd 100644 --- a/srcs/juloo.keyboard2/Pointers.java +++ b/srcs/juloo.keyboard2/Pointers.java @@ -500,7 +500,7 @@ public final class Pointers implements Handler.Callback modify_key_with_extra_modifier(ptr, ptr.key.keys[0], KeyValue.Modifier.GESTURE); case Anticircle: - return _handler.modifyKey(ptr.key.keys[0], ptr.modifiers); + return _handler.modifyKey(ptr.key.anticircle, ptr.modifiers); } return ptr.value; // Unreachable } diff --git a/srcs/juloo.keyboard2/Theme.java b/srcs/juloo.keyboard2/Theme.java index aedf33a..9eff44f 100644 --- a/srcs/juloo.keyboard2/Theme.java +++ b/srcs/juloo.keyboard2/Theme.java @@ -35,6 +35,7 @@ public class Theme private final Paint _keySubLabelPaint; private final Paint _specialKeySubLabelPaint; private final Paint _indicationPaint; + private final Paint _specialIndicationPaint; public Theme(Context context, AttributeSet attrs) { @@ -68,6 +69,7 @@ public class Theme _specialKeyLabelPaint = initLabelPaint(Paint.Align.CENTER, specialKeyFont); _specialKeySubLabelPaint = initLabelPaint(Paint.Align.LEFT, specialKeyFont); _indicationPaint = initLabelPaint(Paint.Align.CENTER, null); + _specialIndicationPaint = initLabelPaint(Paint.Align.CENTER, specialKeyFont); } public Paint labelPaint(boolean special_font) @@ -83,9 +85,9 @@ public class Theme return p; } - public Paint indicationPaint() + public Paint indicationPaint(boolean special_font) { - return _indicationPaint; + return special_font ? _specialIndicationPaint : _indicationPaint; } /** Interpolate the 'value' component toward its opposite by 'alpha'. */