Allow modifiers to hide keys

Modifiers can temporarily remove a key from the layout by returning
'null'.
Make sure pointer handling code handle these modified keys gracefully
and doesn't trigger a key event and a vibration for the removed key.
This commit is contained in:
Jules Aguillon 2022-03-19 15:39:20 +01:00
parent 57c6208b50
commit e872c58788
4 changed files with 66 additions and 36 deletions

View File

@ -13,7 +13,6 @@ class KeyEventHandler implements Config.IKeyEventHandler
public void handleKeyUp(KeyValue key, int flags) public void handleKeyUp(KeyValue key, int flags)
{ {
key = KeyModifier.handleFlags(key, flags);
if (key == null || (key.flags & KeyValue.FLAG_NOCHAR) != 0) if (key == null || (key.flags & KeyValue.FLAG_NOCHAR) != 0)
return; return;
switch (key.eventCode) switch (key.eventCode)

View File

@ -67,26 +67,27 @@ public class Keyboard2View extends View
invalidate(); invalidate();
} }
public void onPointerDown(KeyValue k) public KeyValue onPointerDown(KeyValue k)
{ {
updateFlags(); k = KeyModifier.handleFlags(k, _flags);
invalidate(); invalidate();
if (k != null) if (k != null)
vibrate(); vibrate();
return k;
} }
public void onPointerSwipe(KeyValue k) public KeyValue onPointerSwipe(KeyValue k)
{ {
updateFlags(); k = KeyModifier.handleFlags(k, _flags);
invalidate(); invalidate();
if (k != null) if (k != null)
vibrate(); vibrate();
return k;
} }
public void onPointerUp(KeyValue k) public void onPointerUp(KeyValue k)
{ {
_config.handler.handleKeyUp(k, _flags); _config.handler.handleKeyUp(k, _flags);
updateFlags();
invalidate(); invalidate();
} }
@ -97,7 +98,6 @@ public class Keyboard2View extends View
public void onPointerFlagsChanged() public void onPointerFlagsChanged()
{ {
updateFlags();
invalidate(); invalidate();
} }
@ -202,6 +202,7 @@ public class Keyboard2View extends View
@Override @Override
protected void onDraw(Canvas canvas) protected void onDraw(Canvas canvas)
{ {
updateFlags();
float y = _config.marginTop + _config.keyVerticalInterval / 2; float y = _config.marginTop + _config.keyVerticalInterval / 2;
for (KeyboardData.Row row : _keyboard.rows) for (KeyboardData.Row row : _keyboard.rows)
{ {

View File

@ -194,6 +194,18 @@ class KeyboardData
{ {
return new Key(key0, key1, key2, key3, key4, width * s, shift, edgekeys); return new Key(key0, key1, key2, key3, key4, width * s, shift, edgekeys);
} }
public KeyValue getValue(int index)
{
switch (index)
{
case 1: return key1;
case 2: return key2;
case 3: return key3;
case 4: return key4;
default: case 0: return key0;
}
}
} }
public static abstract interface MapKeys extends Function<KeyValue, KeyValue> { } public static abstract interface MapKeys extends Function<KeyValue, KeyValue> { }

View File

@ -52,8 +52,10 @@ public final class Pointers implements Handler.Callback
*/ */
public int getKeyFlags(KeyValue kv) public int getKeyFlags(KeyValue kv)
{ {
// Use physical equality because the key might have been modified.
String name = kv.name;
for (Pointer p : _ptrs) for (Pointer p : _ptrs)
if (p.value != null && p.value.name == kv.name) // Physical equality if (p.value != null && p.value.name == name)
return p.flags; return p.flags;
return -1; return -1;
} }
@ -66,7 +68,7 @@ public final class Pointers implements Handler.Callback
if (ptr == null) if (ptr == null)
return; return;
stopKeyRepeat(ptr); stopKeyRepeat(ptr);
Pointer latched = getLatched(ptr.value); Pointer latched = getLatched(ptr);
if (latched != null) // Already latched if (latched != null) // Already latched
{ {
removePtr(ptr); // Remove dupplicate removePtr(ptr); // Remove dupplicate
@ -112,12 +114,11 @@ public final class Pointers implements Handler.Callback
// keys. // keys.
if (isModulatedKeyPressed()) if (isModulatedKeyPressed())
return; return;
KeyValue value = key.key0; KeyValue value = _handler.onPointerDown(key.key0);
Pointer ptr = new Pointer(pointerId, key, value, x, y); Pointer ptr = new Pointer(pointerId, key, 0, value, x, y);
_ptrs.add(ptr); _ptrs.add(ptr);
if (value != null && (value.flags & KeyValue.FLAG_NOREPEAT) == 0) if (value != null && (value.flags & KeyValue.FLAG_NOREPEAT) == 0)
startKeyRepeat(ptr); startKeyRepeat(ptr);
_handler.onPointerDown(value);
} }
public void onTouchMove(float x, float y, int pointerId) public void onTouchMove(float x, float y, int pointerId)
@ -129,40 +130,41 @@ public final class Pointers implements Handler.Callback
float dy = y - ptr.downY; float dy = y - ptr.downY;
float dist = Math.abs(dx) + Math.abs(dy); float dist = Math.abs(dx) + Math.abs(dy);
ptr.ptrDist = dist; ptr.ptrDist = dist;
KeyValue newValue; int newIndex;
if (dist < _config.swipe_dist_px) if (dist < _config.swipe_dist_px)
{ {
newValue = ptr.key.key0; newIndex = 0;
} }
else if (ptr.key.edgekeys) else if (ptr.key.edgekeys)
{ {
if (Math.abs(dy) > Math.abs(dx)) // vertical swipe if (Math.abs(dy) > Math.abs(dx)) // vertical swipe
newValue = (dy < 0) ? ptr.key.key1 : ptr.key.key4; newIndex = (dy < 0) ? 1 : 4;
else // horizontal swipe else // horizontal swipe
newValue = (dx < 0) ? ptr.key.key3 : ptr.key.key2; newIndex = (dx < 0) ? 3 : 2;
} }
else else
{ {
if (dx < 0) // left side if (dx < 0) // left side
newValue = (dy < 0) ? ptr.key.key1 : ptr.key.key3; newIndex = (dy < 0) ? 1 : 3;
else // right side else // right side
newValue = (dy < 0) ? ptr.key.key2 : ptr.key.key4; newIndex = (dy < 0) ? 2 : 4;
} }
if (newValue != null && newValue != ptr.value) if (newIndex != ptr.value_index)
{ {
int old_flags = (ptr.value != null) ? ptr.value.flags : 0; ptr.value_index = newIndex;
ptr.value = newValue; KeyValue newValue = _handler.onPointerSwipe(ptr.key.getValue(newIndex));
ptr.flags = newValue.flags; if (newValue != null)
if ((old_flags & newValue.flags & KeyValue.FLAG_PRECISE_REPEAT) != 0)
{ {
int old_flags = ptr.flags;
ptr.value = newValue;
ptr.flags = newValue.flags;
// Keep the keyrepeat going between modulated keys. // Keep the keyrepeat going between modulated keys.
} if ((old_flags & newValue.flags & KeyValue.FLAG_PRECISE_REPEAT) == 0)
else {
{ stopKeyRepeat(ptr);
stopKeyRepeat(ptr); if ((newValue.flags & KeyValue.FLAG_NOREPEAT) == 0)
if ((newValue.flags & KeyValue.FLAG_NOREPEAT) == 0) startKeyRepeat(ptr);
startKeyRepeat(ptr); }
_handler.onPointerSwipe(newValue);
} }
} }
} }
@ -182,10 +184,12 @@ public final class Pointers implements Handler.Callback
_ptrs.remove(ptr); _ptrs.remove(ptr);
} }
private Pointer getLatched(KeyValue kv) private Pointer getLatched(Pointer target)
{ {
KeyboardData.Key k = target.key;
int vi = target.value_index;
for (Pointer p : _ptrs) for (Pointer p : _ptrs)
if (p.value == kv && p.pointerId == -1) if (p.key == k && p.value_index == vi && p.pointerId == -1)
return p; return p;
return null; return null;
} }
@ -278,7 +282,9 @@ public final class Pointers implements Handler.Callback
{ {
/** -1 when latched. */ /** -1 when latched. */
public int pointerId; public int pointerId;
public KeyboardData.Key key; public final KeyboardData.Key key;
public int value_index;
/** Modified value. Not equal to [key.getValue(value_index)]. */
public KeyValue value; public KeyValue value;
public float downX; public float downX;
public float downY; public float downY;
@ -290,10 +296,11 @@ public final class Pointers implements Handler.Callback
/** ptrDist at the first repeat, -1 otherwise. */ /** ptrDist at the first repeat, -1 otherwise. */
public float repeatingPtrDist; public float repeatingPtrDist;
public Pointer(int p, KeyboardData.Key k, KeyValue v, float x, float y) public Pointer(int p, KeyboardData.Key k, int vi, KeyValue v, float x, float y)
{ {
pointerId = p; pointerId = p;
key = k; key = k;
value_index = vi;
value = v; value = v;
downX = x; downX = x;
downY = y; downY = y;
@ -306,10 +313,21 @@ public final class Pointers implements Handler.Callback
public interface IPointerEventHandler public interface IPointerEventHandler
{ {
public void onPointerDown(KeyValue k); /** A key is pressed. Key can be modified or removed by returning [null].
public void onPointerSwipe(KeyValue k); [getFlags()] is not uptodate. */
public KeyValue onPointerDown(KeyValue k);
/** Pointer swipes into a corner. Key can be modified or removed. */
public KeyValue onPointerSwipe(KeyValue k);
/** Key is released. [k] is the key that was returned by [onPointerDown] or
[onPointerSwipe]. */
public void onPointerUp(KeyValue k); public void onPointerUp(KeyValue k);
/** Flags changed because latched or locked keys or cancelled pointers. */
public void onPointerFlagsChanged(); public void onPointerFlagsChanged();
/** Key is repeating. */
public void onPointerHold(KeyValue k); public void onPointerHold(KeyValue k);
} }
} }