diff --git a/srcs/juloo.keyboard2/Gesture.java b/srcs/juloo.keyboard2/Gesture.java index 073a6b5..5ee666b 100644 --- a/srcs/juloo.keyboard2/Gesture.java +++ b/srcs/juloo.keyboard2/Gesture.java @@ -26,33 +26,41 @@ public final class Gesture Ended_anticlockwise } + enum Name + { + None, + Swipe, + Roundtrip, + Circle, + Anticircle + } + /** 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 quadrants are very small. In the same unit as [current_dir] */ static final int ROTATION_THRESHOLD = 2; - /** Modify the key depending on the current gesture. Return [null] if the - gesture is invalid or if [KeyModifier] returned [null]. */ - public KeyValue modify_key(KeyValue selected_val, KeyboardData.Key key) + /** Return the currently recognized gesture. Return [null] if no gesture is + recognized. Might change everytime [changed_direction] return [true]. */ + public Name get_gesture() { switch (state) { case Cancelled: - return null; + return Name.None; case Swiped: case Ended_swipe: - return selected_val; + return Name.Swipe; case Ended_center: - return KeyModifier.modify_gesture(selected_val); + return Name.Roundtrip; case Rotating_clockwise: case Ended_clockwise: - return KeyModifier.modify_gesture(key.keys[0]); + return Name.Circle; case Rotating_anticlockwise: case Ended_anticlockwise: - // Unimplemented for now. - return key.keys[0]; + return Name.Anticircle; } - return null; // Unreachable + return Name.None; // Unreachable } public boolean is_in_progress() @@ -67,7 +75,10 @@ public final class Gesture 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) { int d = dir_diff(current_dir, direction); @@ -94,16 +105,19 @@ public final class Gesture return false; } - public void moved_to_center() + /** Return [true] if [get_gesture] will return a different value. */ + public boolean moved_to_center() { switch (state) { - case Swiped: state = State.Ended_center; break; - case Rotating_clockwise: state = State.Ended_clockwise; break; - case Rotating_anticlockwise: state = State.Ended_anticlockwise; break; + case Swiped: state = State.Ended_center; return true; + case Rotating_clockwise: state = State.Ended_clockwise; return false; + case Rotating_anticlockwise: state = State.Ended_anticlockwise; return false; } + return false; } + /** Will not change the gesture state. */ public void pointer_up() { switch (state) diff --git a/srcs/juloo.keyboard2/KeyModifier.java b/srcs/juloo.keyboard2/KeyModifier.java index e869e9f..a320ec5 100644 --- a/srcs/juloo.keyboard2/KeyModifier.java +++ b/srcs/juloo.keyboard2/KeyModifier.java @@ -33,7 +33,6 @@ public final class KeyModifier if (r == null) { r = k; - /* Order: Fn, Shift, accents */ for (int i = 0; i < n_mods; i++) r = modify(r, mods.get(i)); ks.put(mods, r); @@ -70,6 +69,7 @@ public final class KeyModifier case ALT: case META: return turn_into_keyevent(k); case FN: return apply_fn(k); + case GESTURE: return apply_gesture(k); case SHIFT: return apply_shift(k); case GRAVE: return apply_map_char(k, map_char_grave); case AIGU: return apply_map_char(k, map_char_aigu); @@ -117,15 +117,6 @@ public final class KeyModifier 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) { if (numpad_script == null) @@ -490,6 +481,15 @@ public final class KeyModifier 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. */ private static HashMap cacheEntry(KeyValue k) { diff --git a/srcs/juloo.keyboard2/KeyValue.java b/srcs/juloo.keyboard2/KeyValue.java index 8435cae..e9e66cc 100644 --- a/srcs/juloo.keyboard2/KeyValue.java +++ b/srcs/juloo.keyboard2/KeyValue.java @@ -27,6 +27,7 @@ public final class KeyValue implements Comparable public static enum Modifier { SHIFT, + GESTURE, CTRL, ALT, META, @@ -54,8 +55,8 @@ public final class KeyValue implements Comparable ARROW_RIGHT, BREVE, BAR, - FN, // Must be placed last to be applied first - } + FN, + } // Last is be applied first public static enum Editing { @@ -404,6 +405,12 @@ public final class KeyValue implements Comparable 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) { switch (name) diff --git a/srcs/juloo.keyboard2/Pointers.java b/srcs/juloo.keyboard2/Pointers.java index 61b92f3..8de4832 100644 --- a/srcs/juloo.keyboard2/Pointers.java +++ b/srcs/juloo.keyboard2/Pointers.java @@ -148,7 +148,6 @@ public final class Pointers implements Handler.Callback { // A gesture was in progress ptr.gesture.pointer_up(); - ptr_value = ptr.gesture.modify_key(ptr.value, ptr.key); } Pointer latched = getLatched(ptr); if (latched != null) // Already latched @@ -272,8 +271,8 @@ public final class Pointers implements Handler.Callback return; // Gesture ended ptr.gesture.moved_to_center(); - ptr.value = ptr.gesture.modify_key(ptr.value, ptr.key); - ptr.flags = pointer_flags_of_kv(ptr.value); + ptr.value = apply_gesture(ptr, ptr.gesture.get_gesture()); + ptr.flags = 0; } else @@ -314,7 +313,7 @@ public final class Pointers implements Handler.Callback } else { - ptr.value = ptr.gesture.modify_key(ptr.value, ptr.key); + ptr.value = apply_gesture(ptr, ptr.gesture.get_gesture()); restartKeyRepeat(ptr); ptr.flags = 0; // Special behaviors are ignored during a gesture. } @@ -479,6 +478,41 @@ public final class Pointers implements Handler.Callback 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 private static final class Pointer @@ -636,6 +670,14 @@ public final class Pointers implements Handler.Callback 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]. */ public Iterator diff(Modifiers m2) {