Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Space swipe to toggle numpad layout, with side bonuses #950

Merged
merged 16 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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) {
Helium314 marked this conversation as resolved.
Show resolved Hide resolved
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);
Helium314 marked this conversation as resolved.
Show resolved Hide resolved

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 @@ -352,6 +352,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) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The one-shot swipe logic seems to be more suitable for KeyboardActionListenerImpl.
Is it not in there because there is no callback when a key swipe has ended (except for delete)?

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