forked from extern/Unexpected-Keyboard
Configure anticircle gesture per-key (#644)
This adds the new 'anticircle' attribute to layouts '<key>' 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.
This commit is contained in:
parent
304375268d
commit
1a290f96f2
@ -61,6 +61,8 @@ For example, to make the `I` key behave as in Turkish:
|
|||||||
|
|
||||||
There can be as many of these tags inside `<modmap>` as needed.
|
There can be as many of these tags inside `<modmap>` as needed.
|
||||||
|
|
||||||
|
Shift and Fn modmaps also affect the clockwise circle and the roundtrip gestures.
|
||||||
|
|
||||||
### Row
|
### Row
|
||||||
|
|
||||||
The `<row>` tag encloses one row on the keyboard. It requires no properties, and supports the following:
|
The `<row>` 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.
|
* `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. `<key key0="2" indication="ABC" />`). Caution: if you have `key8` defined, it overlaps!
|
* `indication`: An extra label to show under the main label, intended to be used as a legend for 2A typing (e.g. `<key key0="2" indication="ABC" />`). 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.
|
* `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
|
## Possible key values
|
||||||
|
|
||||||
|
@ -322,10 +322,7 @@ public class Keyboard2View extends View
|
|||||||
if (k.keys[i] != null)
|
if (k.keys[i] != null)
|
||||||
drawSubLabel(canvas, k.keys[i], x, y, keyW, keyH, i, isKeyDown);
|
drawSubLabel(canvas, k.keys[i], x, y, keyW, keyH, i, isKeyDown);
|
||||||
}
|
}
|
||||||
if (k.indication != null)
|
drawIndication(canvas, k, x, y, keyW, keyH);
|
||||||
{
|
|
||||||
drawIndication(canvas, k.indication, keyW / 2f + x, y, keyH);
|
|
||||||
}
|
|
||||||
x += _keyWidth * k.width;
|
x += _keyWidth * k.width;
|
||||||
}
|
}
|
||||||
y += row.height * _config.keyHeight;
|
y += row.height * _config.keyHeight;
|
||||||
@ -443,15 +440,33 @@ public class Keyboard2View extends View
|
|||||||
canvas.drawText(label, 0, label_len, x, y, p);
|
canvas.drawText(label, 0, label_len, x, y, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawIndication(Canvas canvas, String indication, float x,
|
private void drawIndication(Canvas canvas, KeyboardData.Key k, float x,
|
||||||
float y, float keyH)
|
float y, float keyW, float keyH)
|
||||||
{
|
{
|
||||||
float textSize = keyH * _config.sublabelTextSize * _config.characterSize;
|
boolean special_font = false;
|
||||||
Paint p = _theme.indicationPaint();
|
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.setColor(_theme.subLabelColor);
|
||||||
p.setTextSize(textSize);
|
p.setTextSize(text_size);
|
||||||
canvas.drawText(indication, x,
|
// Limit indication length to 3 characters
|
||||||
(keyH - p.ascent() - p.descent()) * 4/5 + y, p);
|
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)
|
private float scaleTextSize(KeyValue k, float rel_size, float keyH)
|
||||||
|
@ -374,6 +374,8 @@ public final class KeyboardData
|
|||||||
* 3 8 4
|
* 3 8 4
|
||||||
*/
|
*/
|
||||||
public final KeyValue[] keys;
|
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]. */
|
/** Pack flags for every key values. Flags are: [F_LOC]. */
|
||||||
private final int keysflags;
|
private final int keysflags;
|
||||||
/** Key width in relative unit. */
|
/** Key width in relative unit. */
|
||||||
@ -390,9 +392,10 @@ public final class KeyboardData
|
|||||||
public static final int F_LOC = 1;
|
public static final int F_LOC = 1;
|
||||||
public static final int ALL_FLAGS = F_LOC;
|
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;
|
keys = ks;
|
||||||
|
anticircle = antic;
|
||||||
keysflags = f;
|
keysflags = f;
|
||||||
width = w;
|
width = w;
|
||||||
shift = s;
|
shift = s;
|
||||||
@ -434,6 +437,14 @@ public final class KeyboardData
|
|||||||
return (flags << index);
|
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)
|
static String stripPrefix(String s, String prefix)
|
||||||
{
|
{
|
||||||
return s.startsWith(prefix) ? s.substring(prefix.length()) : null;
|
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, "key7", "n"), ks, 7);
|
||||||
keysflags |= parse_key_attr(parser, get_key_attr(parser, "key8", "s"), ks, 8);
|
keysflags |= parse_key_attr(parser, get_key_attr(parser, "key8", "s"), ks, 8);
|
||||||
/* Other key attributes */
|
/* Other key attributes */
|
||||||
|
KeyValue anticircle = parse_nonloc_key_attr(parser, "anticircle");
|
||||||
float width = attribute_float(parser, "width", 1f);
|
float width = attribute_float(parser, "width", 1f);
|
||||||
float shift = attribute_float(parser, "shift", 0.f);
|
float shift = attribute_float(parser, "shift", 0.f);
|
||||||
boolean slider = attribute_bool(parser, "slider", false);
|
boolean slider = attribute_bool(parser, "slider", false);
|
||||||
String indication = parser.getAttributeValue(null, "indication");
|
String indication = parser.getAttributeValue(null, "indication");
|
||||||
while (parser.next() != XmlPullParser.END_TAG)
|
while (parser.next() != XmlPullParser.END_TAG)
|
||||||
continue;
|
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]. */
|
/** Whether key at [index] as [flag]. */
|
||||||
@ -472,7 +484,8 @@ public final class KeyboardData
|
|||||||
/** New key with the width multiplied by 's'. */
|
/** New key with the width multiplied by 's'. */
|
||||||
public Key scaleWidth(float 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<KeyValue, KeyPos> dst, int row, int col)
|
public void getKeys(Map<KeyValue, KeyPos> 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];
|
for (int j = 0; j < keys.length; j++) ks[j] = keys[j];
|
||||||
ks[i] = kv;
|
ks[i] = kv;
|
||||||
int flags = (keysflags & ~(ALL_FLAGS << i));
|
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)
|
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)
|
public boolean hasValue(KeyValue kv)
|
||||||
@ -524,7 +537,7 @@ public final class KeyboardData
|
|||||||
for (int i = 0; i < ks.length; i++)
|
for (int i = 0; i < ks.length; i++)
|
||||||
if (k.keys[i] != null)
|
if (k.keys[i] != null)
|
||||||
ks[i] = apply(k.keys[i], k.keyHasFlag(i, Key.F_LOC));
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,7 +500,7 @@ public final class Pointers implements Handler.Callback
|
|||||||
modify_key_with_extra_modifier(ptr, ptr.key.keys[0],
|
modify_key_with_extra_modifier(ptr, ptr.key.keys[0],
|
||||||
KeyValue.Modifier.GESTURE);
|
KeyValue.Modifier.GESTURE);
|
||||||
case Anticircle:
|
case Anticircle:
|
||||||
return _handler.modifyKey(ptr.key.keys[0], ptr.modifiers);
|
return _handler.modifyKey(ptr.key.anticircle, ptr.modifiers);
|
||||||
}
|
}
|
||||||
return ptr.value; // Unreachable
|
return ptr.value; // Unreachable
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ public class Theme
|
|||||||
private final Paint _keySubLabelPaint;
|
private final Paint _keySubLabelPaint;
|
||||||
private final Paint _specialKeySubLabelPaint;
|
private final Paint _specialKeySubLabelPaint;
|
||||||
private final Paint _indicationPaint;
|
private final Paint _indicationPaint;
|
||||||
|
private final Paint _specialIndicationPaint;
|
||||||
|
|
||||||
public Theme(Context context, AttributeSet attrs)
|
public Theme(Context context, AttributeSet attrs)
|
||||||
{
|
{
|
||||||
@ -68,6 +69,7 @@ public class Theme
|
|||||||
_specialKeyLabelPaint = initLabelPaint(Paint.Align.CENTER, specialKeyFont);
|
_specialKeyLabelPaint = initLabelPaint(Paint.Align.CENTER, specialKeyFont);
|
||||||
_specialKeySubLabelPaint = initLabelPaint(Paint.Align.LEFT, specialKeyFont);
|
_specialKeySubLabelPaint = initLabelPaint(Paint.Align.LEFT, specialKeyFont);
|
||||||
_indicationPaint = initLabelPaint(Paint.Align.CENTER, null);
|
_indicationPaint = initLabelPaint(Paint.Align.CENTER, null);
|
||||||
|
_specialIndicationPaint = initLabelPaint(Paint.Align.CENTER, specialKeyFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Paint labelPaint(boolean special_font)
|
public Paint labelPaint(boolean special_font)
|
||||||
@ -83,9 +85,9 @@ public class Theme
|
|||||||
return p;
|
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'. */
|
/** Interpolate the 'value' component toward its opposite by 'alpha'. */
|
||||||
|
Loading…
Reference in New Issue
Block a user