-
-
Notifications
You must be signed in to change notification settings - Fork 188
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This implements clockwise/anticlockwise circle and round trip gestures inspired by Messagease. The circle gestures start after a small threshold to avoid making the regular swipe too hard to aim. The gestures do: - clockwise circle: Shift variant of the center symbol - anticlockwise circle: Fn variant of the center symbol - round trip: Fn variant of the targetted side symbol The Gesture class now keep track of what the pointer is doing while it moves on a key. It replaces the 'selected_direction' integer.
- Loading branch information
Showing
3 changed files
with
210 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package juloo.keyboard2; | ||
|
||
public final class Gesture | ||
{ | ||
/** The pointer direction that caused the last state change. | ||
Integer from 0 to 15 (included). */ | ||
int current_dir; | ||
|
||
State state; | ||
|
||
public Gesture(int starting_direction) | ||
{ | ||
current_dir = starting_direction; | ||
state = State.Swiped; | ||
} | ||
|
||
enum State | ||
{ | ||
Cancelled, | ||
Swiped, | ||
Rotating_clockwise, | ||
Rotating_anticlockwise, | ||
Ended_swipe, | ||
Ended_center, | ||
Ended_clockwise, | ||
Ended_anticlockwise | ||
} | ||
|
||
/** 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) | ||
{ | ||
switch (state) | ||
{ | ||
case Cancelled: | ||
return null; | ||
case Swiped: | ||
case Ended_swipe: | ||
return selected_val; | ||
case Ended_center: | ||
return KeyModifier.modify_round_trip(selected_val); | ||
case Rotating_clockwise: | ||
case Ended_clockwise: | ||
return KeyModifier.modify_circle(key.keys[0], true); | ||
case Rotating_anticlockwise: | ||
case Ended_anticlockwise: | ||
return KeyModifier.modify_circle(key.keys[0], false); | ||
} | ||
return null; // Unreachable | ||
} | ||
|
||
public boolean is_in_progress() | ||
{ | ||
switch (state) | ||
{ | ||
case Swiped: | ||
case Rotating_clockwise: | ||
case Rotating_anticlockwise: | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
/** The pointer changed direction. Return [true] if the gesture changed state. */ | ||
public boolean changed_direction(int direction) | ||
{ | ||
int d = dir_diff(current_dir, direction); | ||
boolean clockwise = d < 0; | ||
switch (state) | ||
{ | ||
case Swiped: | ||
if (Math.abs(d) < ROTATION_THRESHOLD) | ||
return false; | ||
// Start a rotation | ||
state = (clockwise) ? | ||
State.Rotating_clockwise : State.Rotating_anticlockwise; | ||
current_dir = direction; | ||
return true; | ||
// Check that rotation is not reversing | ||
case Rotating_clockwise: | ||
case Rotating_anticlockwise: | ||
current_dir = direction; | ||
if ((state == State.Rotating_clockwise) == clockwise) | ||
return false; | ||
state = State.Cancelled; | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
public void 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; | ||
} | ||
} | ||
|
||
public void pointer_up() | ||
{ | ||
switch (state) | ||
{ | ||
case Swiped: state = State.Ended_swipe; break; | ||
case Rotating_clockwise: state = State.Ended_clockwise; break; | ||
case Rotating_anticlockwise: state = State.Ended_anticlockwise; break; | ||
} | ||
} | ||
|
||
static int dir_diff(int d1, int d2) | ||
{ | ||
final int n = 16; | ||
// Shortest-path in modulo arithmetic | ||
if (d1 == d2) | ||
return 0; | ||
int left = (d1 - d2 + n) % n; | ||
int right = (d2 - d1 + n) % n; | ||
return (left < right) ? -left : right; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters