refactor: Allow modifier of other key kinds

Allow keys of a kind other than Modifier to be a modifier.

This requires writing a compareTo function for KeyValue. Fields are
compared in this order: Kind, value, flags, symbol.
This commit is contained in:
Jules Aguillon 2024-03-18 00:14:19 +01:00
parent ec8e78d5cc
commit dc3a303af1
4 changed files with 69 additions and 32 deletions

View File

@ -113,7 +113,7 @@ public final class KeyEventHandler implements Config.IKeyEventHandler
void update_meta_state(Pointers.Modifiers mods) void update_meta_state(Pointers.Modifiers mods)
{ {
// Released modifiers // Released modifiers
Iterator<KeyValue.Modifier> it = _mods.diff(mods); Iterator<KeyValue> it = _mods.diff(mods);
while (it.hasNext()) while (it.hasNext())
sendMetaKeyForModifier(it.next(), false); sendMetaKeyForModifier(it.next(), false);
// Activated modifiers // Activated modifiers
@ -147,23 +147,28 @@ public final class KeyEventHandler implements Config.IKeyEventHandler
} }
} }
void sendMetaKeyForModifier(KeyValue.Modifier mod, boolean down) void sendMetaKeyForModifier(KeyValue kv, boolean down)
{ {
switch (mod) switch (kv.getKind())
{ {
case CTRL: case Modifier:
sendMetaKey(KeyEvent.KEYCODE_CTRL_LEFT, KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_CTRL_ON, down); switch (kv.getModifier())
break; {
case ALT: case CTRL:
sendMetaKey(KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_ON, down); sendMetaKey(KeyEvent.KEYCODE_CTRL_LEFT, KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_CTRL_ON, down);
break; break;
case SHIFT: case ALT:
sendMetaKey(KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_ON, down); sendMetaKey(KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_ON, down);
break; break;
case META: case SHIFT:
sendMetaKey(KeyEvent.KEYCODE_META_LEFT, KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_ON, down); sendMetaKey(KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_ON, down);
break; break;
default: case META:
sendMetaKey(KeyEvent.KEYCODE_META_LEFT, KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_ON, down);
break;
default:
break;
}
break; break;
} }
} }

View File

@ -38,6 +38,16 @@ public final class KeyModifier
return r; return r;
} }
public static KeyValue modify(KeyValue k, KeyValue mod)
{
switch (mod.getKind())
{
case Modifier:
return modify(k, mod.getModifier());
}
return k;
}
public static KeyValue modify(KeyValue k, KeyValue.Modifier mod) public static KeyValue modify(KeyValue k, KeyValue.Modifier mod)
{ {
switch (mod) switch (mod)

View File

@ -3,7 +3,7 @@ package juloo.keyboard2;
import android.view.KeyEvent; import android.view.KeyEvent;
import java.util.HashMap; import java.util.HashMap;
public final class KeyValue public final class KeyValue implements Comparable<KeyValue>
{ {
public static enum Event public static enum Event
{ {
@ -224,6 +224,18 @@ public final class KeyValue
return sameKey((KeyValue)obj); return sameKey((KeyValue)obj);
} }
public int compareTo(KeyValue snd)
{
// Compare the kind and value first, then the flags.
int d = (_code & ~FLAGS_BITS) - (snd._code & ~FLAGS_BITS);
if (d != 0)
return d;
d = _code - snd._code;
if (d != 0)
return d;
return _symbol.compareTo(snd._symbol);
}
/** Type-safe alternative to [equals]. */ /** Type-safe alternative to [equals]. */
public boolean sameKey(KeyValue snd) public boolean sameKey(KeyValue snd)
{ {

View File

@ -42,15 +42,15 @@ public final class Pointers implements Handler.Callback
private Modifiers getModifiers(boolean skip_latched) private Modifiers getModifiers(boolean skip_latched)
{ {
int n_ptrs = _ptrs.size(); int n_ptrs = _ptrs.size();
KeyValue.Modifier[] mods = new KeyValue.Modifier[n_ptrs]; KeyValue[] mods = new KeyValue[n_ptrs];
int n_mods = 0; int n_mods = 0;
for (int i = 0; i < n_ptrs; i++) for (int i = 0; i < n_ptrs; i++)
{ {
Pointer p = _ptrs.get(i); Pointer p = _ptrs.get(i);
if (p.value != null && p.value.getKind() == KeyValue.Kind.Modifier if (p.value != null
&& !(skip_latched && p.hasFlagsAny(FLAG_P_LATCHED) && !(skip_latched && p.hasFlagsAny(FLAG_P_LATCHED)
&& (p.flags & FLAG_P_LOCKED) == 0)) && (p.flags & FLAG_P_LOCKED) == 0))
mods[n_mods++] = p.value.getModifier(); mods[n_mods++] = p.value;
} }
return Modifiers.ofArray(mods, n_mods); return Modifiers.ofArray(mods, n_mods);
} }
@ -503,23 +503,33 @@ public final class Pointers implements Handler.Callback
Sorted in the order they should be evaluated. */ Sorted in the order they should be evaluated. */
public static final class Modifiers public static final class Modifiers
{ {
private final KeyValue.Modifier[] _mods; private final KeyValue[] _mods;
private final int _size; private final int _size;
private Modifiers(KeyValue.Modifier[] m, int s) private Modifiers(KeyValue[] m, int s)
{ {
_mods = m; _size = s; _mods = m; _size = s;
} }
public KeyValue.Modifier get(int i) { return _mods[_size - 1 - i]; } public KeyValue get(int i) { return _mods[_size - 1 - i]; }
public int size() { return _size; } public int size() { return _size; }
public boolean has(KeyValue.Modifier m) public boolean has(KeyValue.Modifier m)
{ {
return (Arrays.binarySearch(_mods, 0, _size, m) >= 0); for (int i = 0; i < _size; i++)
{
KeyValue kv = _mods[i];
switch (kv.getKind())
{
case Modifier:
if (kv.getModifier().equals(m))
return true;
}
}
return false;
} }
/** Returns the activated modifiers that are not in [m2]. */ /** Returns the activated modifiers that are not in [m2]. */
public Iterator<KeyValue.Modifier> diff(Modifiers m2) public Iterator<KeyValue> diff(Modifiers m2)
{ {
return new ModifiersDiffIterator(this, m2); return new ModifiersDiffIterator(this, m2);
} }
@ -533,9 +543,9 @@ public final class Pointers implements Handler.Callback
} }
public static final Modifiers EMPTY = public static final Modifiers EMPTY =
new Modifiers(new KeyValue.Modifier[0], 0); new Modifiers(new KeyValue[0], 0);
protected static Modifiers ofArray(KeyValue.Modifier[] mods, int size) protected static Modifiers ofArray(KeyValue[] mods, int size)
{ {
// Sort and remove duplicates and nulls. // Sort and remove duplicates and nulls.
if (size > 1) if (size > 1)
@ -544,7 +554,7 @@ public final class Pointers implements Handler.Callback
int j = 0; int j = 0;
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
{ {
KeyValue.Modifier m = mods[i]; KeyValue m = mods[i];
if (m != null && (i + 1 >= size || m != mods[i + 1])) if (m != null && (i + 1 >= size || m != mods[i + 1]))
{ {
mods[j] = m; mods[j] = m;
@ -558,7 +568,7 @@ public final class Pointers implements Handler.Callback
/** Returns modifiers that are in [m1_] but not in [m2_]. */ /** Returns modifiers that are in [m1_] but not in [m2_]. */
static final class ModifiersDiffIterator static final class ModifiersDiffIterator
implements Iterator<KeyValue.Modifier> implements Iterator<KeyValue>
{ {
Modifiers m1; Modifiers m1;
int i1 = 0; int i1 = 0;
@ -577,11 +587,11 @@ public final class Pointers implements Handler.Callback
return i1 < m1._size; return i1 < m1._size;
} }
public KeyValue.Modifier next() public KeyValue next()
{ {
if (i1 >= m1._size) if (i1 >= m1._size)
throw new NoSuchElementException(); throw new NoSuchElementException();
KeyValue.Modifier m = m1._mods[i1]; KeyValue m = m1._mods[i1];
i1++; i1++;
advance(); advance();
return m; return m;
@ -593,7 +603,7 @@ public final class Pointers implements Handler.Callback
{ {
while (i1 < m1.size()) while (i1 < m1.size())
{ {
KeyValue.Modifier m = m1._mods[i1]; KeyValue m = m1._mods[i1];
while (true) while (true)
{ {
if (i2 >= m2._size) if (i2 >= m2._size)