Fix other modifiers not applied

This adds a "GESTURE" modifier in KeyValue that materialize the gesture
into [Modifiers] and allow it to be applied at the same time as the
other modifiers, in the right order.

This moves the key modifying code back into Pointer to allow more
modifier manipulations.
This commit is contained in:
Jules Aguillon 2024-05-25 02:19:55 +02:00
parent d03afb6e8f
commit 506912be60
4 changed files with 94 additions and 31 deletions

View File

@ -26,33 +26,41 @@ public final class Gesture
Ended_anticlockwise Ended_anticlockwise
} }
enum Name
{
None,
Swipe,
Roundtrip,
Circle,
Anticircle
}
/** Angle to travel before a rotation gesture starts. A threshold too low /** Angle to travel before a rotation gesture starts. A threshold too low
would be too easy to reach while doing back and forth gestures, as the would be too easy to reach while doing back and forth gestures, as the
quadrants are very small. In the same unit as [current_dir] */ quadrants are very small. In the same unit as [current_dir] */
static final int ROTATION_THRESHOLD = 2; static final int ROTATION_THRESHOLD = 2;
/** Modify the key depending on the current gesture. Return [null] if the /** Return the currently recognized gesture. Return [null] if no gesture is
gesture is invalid or if [KeyModifier] returned [null]. */ recognized. Might change everytime [changed_direction] return [true]. */
public KeyValue modify_key(KeyValue selected_val, KeyboardData.Key key) public Name get_gesture()
{ {
switch (state) switch (state)
{ {
case Cancelled: case Cancelled:
return null; return Name.None;
case Swiped: case Swiped:
case Ended_swipe: case Ended_swipe:
return selected_val; return Name.Swipe;
case Ended_center: case Ended_center:
return KeyModifier.modify_gesture(selected_val); return Name.Roundtrip;
case Rotating_clockwise: case Rotating_clockwise:
case Ended_clockwise: case Ended_clockwise:
return KeyModifier.modify_gesture(key.keys[0]); return Name.Circle;
case Rotating_anticlockwise: case Rotating_anticlockwise:
case Ended_anticlockwise: case Ended_anticlockwise:
// Unimplemented for now. return Name.Anticircle;
return key.keys[0];
} }
return null; // Unreachable return Name.None; // Unreachable
} }
public boolean is_in_progress() public boolean is_in_progress()
@ -67,7 +75,10 @@ public final class Gesture
return false; return false;
} }
/** The pointer changed direction. Return [true] if the gesture changed state. */ public int current_direction() { return current_dir; }
/** The pointer changed direction. Return [true] if the gesture changed
state and [get_gesture] return a different value. */
public boolean changed_direction(int direction) public boolean changed_direction(int direction)
{ {
int d = dir_diff(current_dir, direction); int d = dir_diff(current_dir, direction);
@ -94,16 +105,19 @@ public final class Gesture
return false; return false;
} }
public void moved_to_center() /** Return [true] if [get_gesture] will return a different value. */
public boolean moved_to_center()
{ {
switch (state) switch (state)
{ {
case Swiped: state = State.Ended_center; break; case Swiped: state = State.Ended_center; return true;
case Rotating_clockwise: state = State.Ended_clockwise; break; case Rotating_clockwise: state = State.Ended_clockwise; return false;
case Rotating_anticlockwise: state = State.Ended_anticlockwise; break; case Rotating_anticlockwise: state = State.Ended_anticlockwise; return false;
} }
return false;
} }
/** Will not change the gesture state. */
public void pointer_up() public void pointer_up()
{ {
switch (state) switch (state)

View File

@ -33,7 +33,6 @@ public final class KeyModifier
if (r == null) if (r == null)
{ {
r = k; r = k;
/* Order: Fn, Shift, accents */
for (int i = 0; i < n_mods; i++) for (int i = 0; i < n_mods; i++)
r = modify(r, mods.get(i)); r = modify(r, mods.get(i));
ks.put(mods, r); ks.put(mods, r);
@ -70,6 +69,7 @@ public final class KeyModifier
case ALT: case ALT:
case META: return turn_into_keyevent(k); case META: return turn_into_keyevent(k);
case FN: return apply_fn(k); case FN: return apply_fn(k);
case GESTURE: return apply_gesture(k);
case SHIFT: return apply_shift(k); case SHIFT: return apply_shift(k);
case GRAVE: return apply_map_char(k, map_char_grave); case GRAVE: return apply_map_char(k, map_char_grave);
case AIGU: return apply_map_char(k, map_char_aigu); case AIGU: return apply_map_char(k, map_char_aigu);
@ -117,15 +117,6 @@ public final class KeyModifier
return k; return k;
} }
/** Modify a key affected by a round-trip or a clockwise circle gesture. */
public static KeyValue modify_gesture(KeyValue k)
{
KeyValue shifted = apply_shift(k);
if (shifted == null || shifted.equals(k))
return apply_fn(k);
return shifted;
}
public static Map_char modify_numpad_script(String numpad_script) public static Map_char modify_numpad_script(String numpad_script)
{ {
if (numpad_script == null) if (numpad_script == null)
@ -490,6 +481,15 @@ public final class KeyModifier
return k.withKeyevent(e); return k.withKeyevent(e);
} }
/** Modify a key affected by a round-trip or a clockwise circle gesture. */
private static KeyValue apply_gesture(KeyValue k)
{
KeyValue shifted = apply_shift(k);
if (shifted == null || shifted.equals(k))
return apply_fn(k);
return shifted;
}
/* Lookup the cache entry for a key. Create it needed. */ /* Lookup the cache entry for a key. Create it needed. */
private static HashMap<Pointers.Modifiers, KeyValue> cacheEntry(KeyValue k) private static HashMap<Pointers.Modifiers, KeyValue> cacheEntry(KeyValue k)
{ {

View File

@ -27,6 +27,7 @@ public final class KeyValue implements Comparable<KeyValue>
public static enum Modifier public static enum Modifier
{ {
SHIFT, SHIFT,
GESTURE,
CTRL, CTRL,
ALT, ALT,
META, META,
@ -54,8 +55,8 @@ public final class KeyValue implements Comparable<KeyValue>
ARROW_RIGHT, ARROW_RIGHT,
BREVE, BREVE,
BAR, BAR,
FN, // Must be placed last to be applied first FN,
} } // Last is be applied first
public static enum Editing public static enum Editing
{ {
@ -404,6 +405,12 @@ public final class KeyValue implements Comparable<KeyValue>
return new KeyValue(str, Kind.String, 0, flags | FLAG_SMALLER_FONT); return new KeyValue(str, Kind.String, 0, flags | FLAG_SMALLER_FONT);
} }
/** Make a modifier key for passing to [KeyModifier]. */
public static KeyValue makeInternalModifier(Modifier mod)
{
return new KeyValue("", Kind.Modifier, mod.ordinal(), 0);
}
public static KeyValue getKeyByName(String name) public static KeyValue getKeyByName(String name)
{ {
switch (name) switch (name)

View File

@ -148,7 +148,6 @@ public final class Pointers implements Handler.Callback
{ {
// A gesture was in progress // A gesture was in progress
ptr.gesture.pointer_up(); ptr.gesture.pointer_up();
ptr_value = ptr.gesture.modify_key(ptr.value, ptr.key);
} }
Pointer latched = getLatched(ptr); Pointer latched = getLatched(ptr);
if (latched != null) // Already latched if (latched != null) // Already latched
@ -272,8 +271,8 @@ public final class Pointers implements Handler.Callback
return; return;
// Gesture ended // Gesture ended
ptr.gesture.moved_to_center(); ptr.gesture.moved_to_center();
ptr.value = ptr.gesture.modify_key(ptr.value, ptr.key); ptr.value = apply_gesture(ptr, ptr.gesture.get_gesture());
ptr.flags = pointer_flags_of_kv(ptr.value); ptr.flags = 0;
} }
else else
@ -314,7 +313,7 @@ public final class Pointers implements Handler.Callback
} }
else else
{ {
ptr.value = ptr.gesture.modify_key(ptr.value, ptr.key); ptr.value = apply_gesture(ptr, ptr.gesture.get_gesture());
restartKeyRepeat(ptr); restartKeyRepeat(ptr);
ptr.flags = 0; // Special behaviors are ignored during a gesture. ptr.flags = 0; // Special behaviors are ignored during a gesture.
} }
@ -479,6 +478,41 @@ public final class Pointers implements Handler.Callback
return flags; return flags;
} }
// Gestures
/** Apply a gesture to the current key. */
KeyValue apply_gesture(Pointer ptr, Gesture.Name gesture)
{
switch (gesture)
{
case None:
return ptr.value;
case Swipe:
return ptr.value;
case Roundtrip:
return
modify_key_with_extra_modifier(
ptr,
getNearestKeyAtDirection(ptr, ptr.gesture.current_direction()),
KeyValue.Modifier.GESTURE);
case Circle:
return
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 ptr.value; // Unreachable
}
KeyValue modify_key_with_extra_modifier(Pointer ptr, KeyValue kv,
KeyValue.Modifier extra_mod)
{
return
_handler.modifyKey(kv,
ptr.modifiers.with_extra_mod(KeyValue.makeInternalModifier(extra_mod)));
}
// Pointers // Pointers
private static final class Pointer private static final class Pointer
@ -636,6 +670,14 @@ public final class Pointers implements Handler.Callback
return false; return false;
} }
/** Return a copy of this object with an extra modifier added. */
public Modifiers with_extra_mod(KeyValue m)
{
KeyValue[] newmods = Arrays.copyOf(_mods, _size + 1);
newmods[_size] = m;
return ofArray(newmods, newmods.length);
}
/** Returns the activated modifiers that are not in [m2]. */ /** Returns the activated modifiers that are not in [m2]. */
public Iterator<KeyValue> diff(Modifiers m2) public Iterator<KeyValue> diff(Modifiers m2)
{ {