Skip to content

Commit

Permalink
Space swipe to toggle numpad layout, with side bonuses (#950)
Browse files Browse the repository at this point in the history
* make the numpad key toggle-based, allowing for use in its own layout. it also remembers the symbols-shift state.
* add space swipe gesture to toggle the numpad
* fix sliding key input for the numpad key bugs
  • Loading branch information
devycarol authored Jul 9, 2024
1 parent 309d7f2 commit 105d044
Show file tree
Hide file tree
Showing 15 changed files with 129 additions and 38 deletions.
4 changes: 2 additions & 2 deletions app/src/main/assets/layouts/numpad.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@
[
{ "label": "alpha" },
{ "label": "comma", "width": 0.1 },
{ "label": "symbol", "type": "character", "width": 0.12 },
{ "label": "symbol", "width": 0.12 },
{ "label": "0", "type": "numeric" },
{ "label": "=", "width": 0.12, "popup": { "relevant": [ { "label": ""}, { "label": ""} ] } },
{ "label": "=", "type": "function", "width": 0.12, "popup": { "relevant": [ { "label": ""}, { "label": ""} ] } },
{ "label": "period", "width": 0.1 },
{ "label": "action" }
]
Expand Down
7 changes: 5 additions & 2 deletions app/src/main/java/helium314/keyboard/keyboard/Key.java
Original file line number Diff line number Diff line change
Expand Up @@ -515,8 +515,11 @@ public final boolean isShift() {
}

public final boolean isModifier() {
return mCode == KeyCode.SHIFT || mCode == KeyCode.SYMBOL_ALPHA || mCode == KeyCode.ALPHA || mCode == KeyCode.SYMBOL
|| mCode == KeyCode.CTRL || mCode == KeyCode.ALT || mCode == KeyCode.FN || mCode == KeyCode.META;
return switch (mCode) {
case KeyCode.SHIFT, KeyCode.SYMBOL_ALPHA, KeyCode.ALPHA, KeyCode.SYMBOL, KeyCode.NUMPAD, KeyCode.CTRL,
KeyCode.ALT, KeyCode.FN, KeyCode.META -> true;
default -> false;
};
}

public final boolean isRepeatable() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public interface KeyboardActionListener {
*/
boolean onHorizontalSpaceSwipe(int steps);
boolean onVerticalSpaceSwipe(int steps);
boolean toggleNumpad(boolean withSliding, boolean forceReturnToAlpha);

void onMoveDeletePointer(int steps);
void onUpWithDeletePointerActive();
Expand All @@ -107,6 +108,7 @@ public interface KeyboardActionListener {
int SWIPE_NO_ACTION = 0;
int SWIPE_MOVE_CURSOR = 1;
int SWIPE_SWITCH_LANGUAGE = 2;
int SWIPE_TOGGLE_NUMPAD = 3;

class Adapter implements KeyboardActionListener {
@Override
Expand Down Expand Up @@ -142,6 +144,10 @@ public boolean onVerticalSpaceSwipe(int steps) {
return false;
}
@Override
public boolean toggleNumpad(boolean withSliding, boolean forceReturnToAlpha) {
return false;
}
@Override
public void onMoveDeletePointer(int steps) {}
@Override
public void onUpWithDeletePointerActive() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,22 @@ class KeyboardActionListenerImpl(private val latinIME: LatinIME, private val inp
override fun onHorizontalSpaceSwipe(steps: Int): Boolean = when (Settings.getInstance().current.mSpaceSwipeHorizontal) {
KeyboardActionListener.SWIPE_MOVE_CURSOR -> onMoveCursorHorizontally(steps)
KeyboardActionListener.SWIPE_SWITCH_LANGUAGE -> onLanguageSlide(steps)
KeyboardActionListener.SWIPE_TOGGLE_NUMPAD -> toggleNumpad(false, false)
else -> false
}

override fun onVerticalSpaceSwipe(steps: Int): Boolean = when (Settings.getInstance().current.mSpaceSwipeVertical) {
KeyboardActionListener.SWIPE_MOVE_CURSOR -> onMoveCursorVertically(steps)
KeyboardActionListener.SWIPE_SWITCH_LANGUAGE -> onLanguageSlide(steps)
KeyboardActionListener.SWIPE_TOGGLE_NUMPAD -> toggleNumpad(false, false)
else -> false
}

override fun toggleNumpad(withSliding: Boolean, forceReturnToAlpha: Boolean): Boolean {
KeyboardSwitcher.getInstance().toggleNumpad(withSliding, latinIME.currentAutoCapsState, latinIME.currentRecapitalizeState, forceReturnToAlpha)
return true
}

override fun onMoveDeletePointer(steps: Int) {
inputLogic.finishInput()
val end = inputLogic.mConnection.expectedSelectionEnd
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,15 @@ public void setNumpadKeyboard() {
setKeyboard(KeyboardId.ELEMENT_NUMPAD, KeyboardSwitchState.OTHER);
}

@Override
public void toggleNumpad(final boolean withSliding, final int autoCapsFlags, final int recapitalizeMode,
final boolean forceReturnToAlpha) {
if (DEBUG_ACTION) {
Log.d(TAG, "toggleNumpad");
}
mState.toggleNumpad(withSliding, autoCapsFlags, recapitalizeMode, forceReturnToAlpha, true);
}

public enum KeyboardSwitchState {
HIDDEN(-1),
SYMBOLS_SHIFTED(KeyboardId.ELEMENT_SYMBOLS_SHIFTED),
Expand Down
17 changes: 13 additions & 4 deletions app/src/main/java/helium314/keyboard/keyboard/PointerTracker.java
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,8 @@ private boolean callListenerOnPressAndCheckKeyboardLayoutChange(final Key key,
// primaryCode is different from {@link Key#mKeyCode}.
private void callListenerOnCodeInput(final Key key, final int primaryCode, final int x,
final int y, final long eventTime, final boolean isKeyRepeat) {
final boolean ignoreModifierKey = mIsInDraggingFinger && key.isModifier();
final boolean ignoreModifierKey = mIsInDraggingFinger && key.isModifier()
&& key.getCode() != KeyCode.NUMPAD; // we allow for the numpad to be toggled from sliding input
final boolean altersCode = key.altCodeWhileTyping() && sTimerProxy.isTypingState() && !isClearlyInsideKey(key, x, y);
final int code = altersCode ? key.getAltCode() : primaryCode;
if (DEBUG_LISTENER) {
Expand Down Expand Up @@ -879,6 +880,13 @@ private void dragFingerOutFromOldKey(final Key oldKey, final int x, final int y)
}
}

private boolean oneShotSwipe(final int swipeSetting) {
return switch (swipeSetting) {
case KeyboardActionListener.SWIPE_NO_ACTION, KeyboardActionListener.SWIPE_TOGGLE_NUMPAD -> true;
default -> false;
};
}

private void onKeySwipe(final int code, final int x, final int y, final long eventTime) {
final SettingsValues sv = Settings.getInstance().getCurrent();
final int fastTypingTimeout = 2 * sv.mKeyLongpressTimeout / 3;
Expand All @@ -896,7 +904,7 @@ private void onKeySwipe(final int code, final int x, final int y, final long eve
if (!mInVerticalSwipe) {
sTimerProxy.cancelKeyTimersOf(this);
mInVerticalSwipe = true;
}
} else if (oneShotSwipe(sv.mSpaceSwipeVertical)) return;
if (sListener.onVerticalSpaceSwipe(stepsY)) {
mStartY += stepsY * sPointerStep;
}
Expand All @@ -909,7 +917,7 @@ private void onKeySwipe(final int code, final int x, final int y, final long eve
if (!mInHorizontalSwipe) {
sTimerProxy.cancelKeyTimersOf(this);
mInHorizontalSwipe = true;
}
} else if (oneShotSwipe(sv.mSpaceSwipeHorizontal)) return;
if (sListener.onHorizontalSpaceSwipe(stepsX)) {
mStartX += stepsX * sPointerStep;
}
Expand Down Expand Up @@ -1105,7 +1113,8 @@ public void onLongPressed() {
}
}
if (code == KeyCode.SYMBOL_ALPHA && Settings.getInstance().getCurrent().mLongPressSymbolsForNumpad) {
sListener.onCodeInput(KeyCode.NUMPAD, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false);
// toggle numpad with sliding input enabled, forcing return to the alpha layout when done
sListener.toggleNumpad(true, true);
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ public static int getCode(final String name) {
"key_emoji",
"key_unspecified",
"key_clipboard",
"key_numpad",
"key_start_onehanded",
"key_stop_onehanded",
"key_switch_onehanded"
Expand All @@ -78,7 +77,6 @@ public static int getCode(final String name) {
KeyCode.EMOJI,
KeyCode.NOT_SPECIFIED,
KeyCode.CLIPBOARD,
KeyCode.NUMPAD,
KeyCode.START_ONE_HANDED_MODE,
KeyCode.STOP_ONE_HANDED_MODE,
KeyCode.SWITCH_ONE_HANDED_MODE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ class KeyboardIconsSet {
const val NAME_CLIPBOARD_NORMAL_KEY = "clipboard_normal_key"
const val NAME_CLEAR_CLIPBOARD_KEY = "clear_clipboard_key"
const val NAME_CUT_KEY = "cut_key"
const val NAME_NUMPAD_KEY = "numpad_key"
const val NAME_START_ONEHANDED_KEY = "start_onehanded_mode_key"
const val NAME_STOP_ONEHANDED_KEY = "stop_onehanded_mode_key"
const val NAME_SWITCH_ONEHANDED_KEY = "switch_onehanded_key"
Expand Down Expand Up @@ -90,7 +89,6 @@ class KeyboardIconsSet {
NAME_CLIPBOARD_NORMAL_KEY to R.styleable.Keyboard_iconClipboardNormalKey,
NAME_CLEAR_CLIPBOARD_KEY to R.styleable.Keyboard_iconClearClipboardKey,
NAME_CUT_KEY to R.styleable.Keyboard_iconCutKey,
NAME_NUMPAD_KEY to R.styleable.Keyboard_iconNumpadKey,
NAME_START_ONEHANDED_KEY to R.styleable.Keyboard_iconStartOneHandedMode,
NAME_STOP_ONEHANDED_KEY to R.styleable.Keyboard_iconStopOneHandedMode,
NAME_SWITCH_ONEHANDED_KEY to R.styleable.Keyboard_iconSwitchOneHandedMode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public interface SwitchActions {
void setEmojiKeyboard();
void setClipboardKeyboard();
void setNumpadKeyboard();
void toggleNumpad(final boolean withSliding, final int autoCapsFlags, final int recapitalizeMode,
final boolean forceReturnToAlpha);
void setSymbolsKeyboard();
void setSymbolsShiftedKeyboard();

Expand Down Expand Up @@ -81,7 +83,8 @@ public interface SwitchActions {
private static final int SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL = 4;
private static final int SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE = 5;
private static final int SWITCH_STATE_MOMENTARY_ALPHA_SHIFT = 6;
private static final int SWITCH_STATE_MOMENTARY_FROM_NUMPAD = 7;
private static final int SWITCH_STATE_MOMENTARY_TO_NUMPAD = 7;
private static final int SWITCH_STATE_MOMENTARY_FROM_NUMPAD = 8;
private int mSwitchState = SWITCH_STATE_ALPHA;

private static final int MODE_ALPHABET = 0;
Expand All @@ -90,6 +93,7 @@ public interface SwitchActions {
private static final int MODE_CLIPBOARD = 3;
private static final int MODE_NUMPAD = 4;
private int mMode = MODE_ALPHABET;
private int mModeBeforeNumpad = MODE_ALPHABET;
private boolean mIsSymbolShifted;
private boolean mPrevMainKeyboardWasShiftLocked;
private boolean mPrevSymbolsKeyboardWasShifted;
Expand Down Expand Up @@ -203,7 +207,8 @@ private void onRestoreKeyboardState(final int autoCapsFlags, final int recapital
return;
}
if (state.mMode == MODE_NUMPAD) {
setNumpadKeyboard();
// don't overwrite toggle state if reloading from orientation change, etc.
setNumpadKeyboard(false, false, false);
return;
}
// Symbol mode
Expand Down Expand Up @@ -379,17 +384,57 @@ private void setClipboardKeyboard() {
mSwitchActions.setClipboardKeyboard();
}

private void setNumpadKeyboard() {
private void setNumpadKeyboard(final boolean withSliding, final boolean forceReturnToAlpha,
final boolean rememberState) {
if (DEBUG_INTERNAL_ACTION) {
Log.d(TAG, "setNumpadKeyboard");
}
if (rememberState) {
if (mMode == MODE_ALPHABET) {
// Remember caps lock mode and reset alphabet shift state.
mPrevMainKeyboardWasShiftLocked = mAlphabetShiftState.isShiftLocked();
mAlphabetShiftState.setShiftLocked(false);
} else if (mMode == MODE_SYMBOLS) {
// Remember symbols shifted state
mPrevSymbolsKeyboardWasShifted = mIsSymbolShifted;
} // When d-pad is added, "selection mode" may need to be remembered if not a global state
mModeBeforeNumpad = forceReturnToAlpha ? MODE_ALPHABET : mMode;
}
mMode = MODE_NUMPAD;
mRecapitalizeMode = RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE;
// Remember caps lock mode and reset alphabet shift state.
mPrevMainKeyboardWasShiftLocked = mAlphabetShiftState.isShiftLocked();
mAlphabetShiftState.setShiftLocked(false);
mSwitchActions.setNumpadKeyboard();
mSwitchState = SWITCH_STATE_NUMPAD;
mSwitchState = withSliding ? SWITCH_STATE_MOMENTARY_TO_NUMPAD : SWITCH_STATE_NUMPAD;
}

public void toggleNumpad(final boolean withSliding, final int autoCapsFlags, final int recapitalizeMode,
final boolean forceReturnToAlpha, final boolean rememberState) {
if (DEBUG_INTERNAL_ACTION) {
Log.d(TAG, "toggleNumpad");
}
if (mMode != MODE_NUMPAD) setNumpadKeyboard(withSliding, forceReturnToAlpha, rememberState);
else {
if (mModeBeforeNumpad == MODE_ALPHABET || forceReturnToAlpha) {
setAlphabetKeyboard(autoCapsFlags, recapitalizeMode);
if (mPrevMainKeyboardWasShiftLocked) {
setShiftLocked(true);
}
mPrevMainKeyboardWasShiftLocked = false;
} else switch (mModeBeforeNumpad) {
case MODE_SYMBOLS -> {
if (mPrevSymbolsKeyboardWasShifted) {
setSymbolsShiftedKeyboard();
} else {
setSymbolsKeyboard();
}
mPrevSymbolsKeyboardWasShifted = false;
}
// toggling numpad and emoji layout isn't actually possible yet due to lack of toolbar
// keys or key-swipes in that layout, but included for safety.
case MODE_EMOJI -> setEmojiKeyboard();
case MODE_CLIPBOARD -> setClipboardKeyboard();
}
if (withSliding) mSwitchState = SWITCH_STATE_MOMENTARY_FROM_NUMPAD;
}
}

private void setOneHandedModeEnabled(boolean enabled) {
Expand Down Expand Up @@ -430,6 +475,9 @@ public void onPressKey(final int code, final boolean isSinglePointer, final int
} else if (code == KeyCode.ALPHA) {
// don't start sliding, causes issues with fully customizable layouts
// (also does not allow chording, but can be fixed later)
} else if (code == KeyCode.NUMPAD) {
// don't start sliding, causes issues with fully customizable layouts
// (also does not allow chording, but can be fixed later)
} else {
mShiftKeyState.onOtherKeyPressed();
mSymbolKeyState.onOtherKeyPressed();
Expand Down Expand Up @@ -459,17 +507,17 @@ public void onReleaseKey(final int code, final boolean withSliding, final int au
+ " sliding=" + withSliding
+ " " + stateToString(autoCapsFlags, recapitalizeMode));
}
if (code == KeyCode.SHIFT) {
onReleaseShift(withSliding, autoCapsFlags, recapitalizeMode);
} else if (code == KeyCode.CAPS_LOCK) {
setShiftLocked(!mAlphabetShiftState.isShiftLocked());
} else if (code == KeyCode.SYMBOL_ALPHA) {
onReleaseAlphaSymbol(withSliding, autoCapsFlags, recapitalizeMode);
} else if (code == KeyCode.SYMBOL) {
onReleaseSymbol(withSliding, autoCapsFlags, recapitalizeMode);
} else if (code == KeyCode.ALPHA) {
onReleaseAlpha(withSliding, autoCapsFlags, recapitalizeMode);
}
switch (code) {
case KeyCode.SHIFT -> onReleaseShift(withSliding, autoCapsFlags, recapitalizeMode);
case KeyCode.CAPS_LOCK -> setShiftLocked(!mAlphabetShiftState.isShiftLocked());
case KeyCode.SYMBOL_ALPHA -> onReleaseAlphaSymbol(withSliding, autoCapsFlags, recapitalizeMode);
case KeyCode.SYMBOL -> onReleaseSymbol(withSliding, autoCapsFlags, recapitalizeMode);
case KeyCode.ALPHA -> onReleaseAlpha(withSliding, autoCapsFlags, recapitalizeMode);
case KeyCode.NUMPAD -> {
// if no sliding, toggling is instead handled by {@link #onEvent} to accommodate toolbar key.
// also prevent sliding to clipboard layout, which isn't supported yet.
if (withSliding) setNumpadKeyboard(true, mModeBeforeNumpad == MODE_CLIPBOARD, true);
}}
}

private void onPressAlphaSymbol(final int autoCapsFlags, final int recapitalizeMode) {
Expand Down Expand Up @@ -678,12 +726,14 @@ public void onFinishSlidingInput(final int autoCapsFlags, final int recapitalize
if (DEBUG_EVENT) {
Log.d(TAG, "onFinishSlidingInput: " + stateToString(autoCapsFlags, recapitalizeMode));
}
// Switch back to the previous keyboard mode if the user cancels sliding input.
switch (mSwitchState) {
// Switch back to the previous keyboard mode if the user didn't enter the numpad.
if (mMode != MODE_NUMPAD) switch (mSwitchState) {
case SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL -> toggleAlphabetAndSymbols(autoCapsFlags, recapitalizeMode);
case SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE -> toggleShiftInSymbols();
case SWITCH_STATE_MOMENTARY_ALPHA_SHIFT -> setAlphabetKeyboard(autoCapsFlags, recapitalizeMode);
case SWITCH_STATE_MOMENTARY_FROM_NUMPAD -> setNumpadKeyboard();
case SWITCH_STATE_MOMENTARY_FROM_NUMPAD -> setNumpadKeyboard(false, false, false);
} else if (mSwitchState == SWITCH_STATE_MOMENTARY_TO_NUMPAD) {
toggleNumpad(false, autoCapsFlags, recapitalizeMode, false, false);
}
}

Expand Down Expand Up @@ -763,7 +813,7 @@ public void onEvent(final Event event, final int autoCapsFlags, final int recapi
setClipboardKeyboard();
}
} else if (code == KeyCode.NUMPAD) {
setNumpadKeyboard();
toggleNumpad(false, autoCapsFlags, recapitalizeMode, false, true);
} else if (code == KeyCode.SYMBOL) {
setSymbolsKeyboard();
} else if (code == KeyCode.START_ONE_HANDED_MODE) {
Expand Down Expand Up @@ -793,6 +843,7 @@ private static String switchStateToString(final int switchState) {
case SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE -> "MOMENTARY-SYMBOL-MORE";
case SWITCH_STATE_MOMENTARY_ALPHA_SHIFT -> "MOMENTARY-ALPHA_SHIFT";
case SWITCH_STATE_NUMPAD -> "NUMPAD";
case SWITCH_STATE_MOMENTARY_TO_NUMPAD -> "MOMENTARY-TO-NUMPAD";
case SWITCH_STATE_MOMENTARY_FROM_NUMPAD -> "MOMENTARY-FROM-NUMPAD";
default -> null;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,6 @@ sealed interface KeyData : AbstractKeyData {
// todo (later): label and popupKeys for .com should be in localeKeyTexts, handled similar to currency key
KeyLabel.COM -> ".com"
KeyLabel.LANGUAGE_SWITCH -> "!icon/language_switch_key|!code/key_language_switch"
KeyLabel.NUMPAD -> "!icon/numpad_key|!code/key_numpad"
KeyLabel.ZWNJ -> "!icon/zwnj_key|\u200C"
KeyLabel.CURRENCY -> params.mLocaleKeyboardInfos.currencyKey.first
KeyLabel.CURRENCY1 -> params.mLocaleKeyboardInfos.currencyKey.second[0]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ public static int readHorizontalSpaceSwipe(final SharedPreferences prefs) {
return switch (prefs.getString(PREF_SPACE_HORIZONTAL_SWIPE, "none")) {
case "move_cursor" -> KeyboardActionListener.SWIPE_MOVE_CURSOR;
case "switch_language" -> KeyboardActionListener.SWIPE_SWITCH_LANGUAGE;
case "toggle_numpad" -> KeyboardActionListener.SWIPE_TOGGLE_NUMPAD;
default -> KeyboardActionListener.SWIPE_NO_ACTION;
};
}
Expand All @@ -389,6 +390,7 @@ public static int readVerticalSpaceSwipe(final SharedPreferences prefs) {
return switch (prefs.getString(PREF_SPACE_VERTICAL_SWIPE, "none")) {
case "move_cursor" -> KeyboardActionListener.SWIPE_MOVE_CURSOR;
case "switch_language" -> KeyboardActionListener.SWIPE_SWITCH_LANGUAGE;
case "toggle_numpad" -> KeyboardActionListener.SWIPE_TOGGLE_NUMPAD;
default -> KeyboardActionListener.SWIPE_NO_ACTION;
};
}
Expand Down
Loading

0 comments on commit 105d044

Please sign in to comment.