mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-04-24 08:36:26 +00:00
move keyboardActionListener implementation into separate class
(it will be extended later)
This commit is contained in:
parent
8ec6138771
commit
cd44d2dc9f
3 changed files with 156 additions and 155 deletions
|
@ -0,0 +1,142 @@
|
|||
package helium314.keyboard.keyboard
|
||||
|
||||
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
|
||||
import helium314.keyboard.latin.LatinIME
|
||||
import helium314.keyboard.latin.RichInputMethodManager
|
||||
import helium314.keyboard.latin.common.Constants
|
||||
import helium314.keyboard.latin.common.InputPointers
|
||||
import helium314.keyboard.latin.inputlogic.InputLogic
|
||||
import helium314.keyboard.latin.settings.Settings
|
||||
import kotlin.math.abs
|
||||
|
||||
class KeyboardActionListenerImpl(private val latinIME: LatinIME, private val inputLogic: InputLogic) : KeyboardActionListener {
|
||||
|
||||
private val keyboardSwitcher = KeyboardSwitcher.getInstance()
|
||||
private val settings = Settings.getInstance()
|
||||
|
||||
override fun onPressKey(primaryCode: Int, repeatCount: Int, isSinglePointer: Boolean) {
|
||||
keyboardSwitcher.onPressKey(primaryCode, isSinglePointer, latinIME.currentAutoCapsState, latinIME.currentRecapitalizeState)
|
||||
}
|
||||
|
||||
override fun onReleaseKey(primaryCode: Int, withSliding: Boolean) {
|
||||
keyboardSwitcher.onReleaseKey(primaryCode, withSliding, latinIME.currentAutoCapsState, latinIME.currentRecapitalizeState)
|
||||
}
|
||||
|
||||
override fun onCodeInput(primaryCode: Int, x: Int, y: Int, isKeyRepeat: Boolean) =
|
||||
latinIME.onCodeInput(primaryCode, x, y, isKeyRepeat)
|
||||
|
||||
override fun onTextInput(text: String?) = latinIME.onTextInput(text)
|
||||
|
||||
override fun onStartBatchInput() = latinIME.onStartBatchInput()
|
||||
|
||||
override fun onUpdateBatchInput(batchPointers: InputPointers?) = latinIME.onUpdateBatchInput(batchPointers)
|
||||
|
||||
override fun onEndBatchInput(batchPointers: InputPointers?) = latinIME.onEndBatchInput(batchPointers)
|
||||
|
||||
override fun onCancelBatchInput() = latinIME.onCancelBatchInput()
|
||||
|
||||
// User released a finger outside any key
|
||||
override fun onCancelInput() { }
|
||||
|
||||
override fun onFinishSlidingInput() =
|
||||
keyboardSwitcher.onFinishSlidingInput(latinIME.currentAutoCapsState, latinIME.currentRecapitalizeState)
|
||||
|
||||
override fun onCustomRequest(requestCode: Int): Boolean {
|
||||
if (requestCode == Constants.CUSTOM_CODE_SHOW_INPUT_METHOD_PICKER)
|
||||
return latinIME.showInputPickerDialog()
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onHorizontalSpaceSwipe(steps: Int): Boolean = when (Settings.getInstance().current.mSpaceSwipeHorizontal) {
|
||||
KeyboardActionListener.SWIPE_MOVE_CURSOR -> onMoveCursorHorizontally(steps)
|
||||
KeyboardActionListener.SWIPE_SWITCH_LANGUAGE -> onLanguageSlide(steps)
|
||||
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)
|
||||
else -> false
|
||||
}
|
||||
|
||||
override fun onMoveDeletePointer(steps: Int) {
|
||||
inputLogic.finishInput()
|
||||
val end = inputLogic.mConnection.expectedSelectionEnd
|
||||
val start = inputLogic.mConnection.expectedSelectionStart + steps
|
||||
if (start > end) return
|
||||
inputLogic.mConnection.setSelection(start, end)
|
||||
}
|
||||
|
||||
override fun onUpWithDeletePointerActive() {
|
||||
if (!inputLogic.mConnection.hasSelection()) return
|
||||
inputLogic.finishInput()
|
||||
onCodeInput(KeyCode.DELETE, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false)
|
||||
}
|
||||
|
||||
private fun onLanguageSlide(steps: Int): Boolean {
|
||||
if (abs(steps) < 4) return false
|
||||
val subtypes = RichInputMethodManager.getInstance().getMyEnabledInputMethodSubtypeList(false)
|
||||
if (subtypes.size <= 1) { // only allow if we have more than one subtype
|
||||
return false
|
||||
}
|
||||
// decide next or previous dependent on up or down
|
||||
val current = RichInputMethodManager.getInstance().currentSubtype.rawSubtype
|
||||
var wantedIndex = subtypes.indexOf(current) + if (steps > 0) 1 else -1
|
||||
wantedIndex %= subtypes.size
|
||||
if (wantedIndex < 0)
|
||||
wantedIndex += subtypes.size
|
||||
KeyboardSwitcher.getInstance().switchToSubtype(subtypes[wantedIndex])
|
||||
return true
|
||||
}
|
||||
|
||||
private fun onMoveCursorVertically(steps: Int): Boolean {
|
||||
if (steps == 0) return false
|
||||
val code = if (steps < 0) KeyCode.ARROW_UP else KeyCode.ARROW_DOWN
|
||||
onCodeInput(code, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun onMoveCursorHorizontally(_steps: Int): Boolean {
|
||||
if (_steps == 0) return false
|
||||
var steps = _steps
|
||||
// for RTL languages we want to invert pointer movement
|
||||
if (RichInputMethodManager.getInstance().currentSubtype.isRtlSubtype) steps = -steps
|
||||
val moveSteps: Int
|
||||
if (steps < 0) {
|
||||
val availableCharacters: Int = inputLogic.mConnection.getTextBeforeCursor(64, 0).length
|
||||
moveSteps = if (availableCharacters < -steps) -availableCharacters else steps
|
||||
if (moveSteps == 0) {
|
||||
// some apps don't return any text via input connection, and the cursor can't be moved
|
||||
// we fall back to virtually pressing the left/right key one or more times instead
|
||||
while (steps != 0) {
|
||||
onCodeInput(KeyCode.ARROW_LEFT, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false)
|
||||
++steps
|
||||
}
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
val availableCharacters: Int = inputLogic.mConnection.getTextAfterCursor(64, 0).length
|
||||
moveSteps = availableCharacters.coerceAtMost(steps)
|
||||
if (moveSteps == 0) {
|
||||
while (steps != 0) {
|
||||
onCodeInput(KeyCode.ARROW_RIGHT, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false)
|
||||
--steps
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
if (inputLogic.moveCursorByAndReturnIfInsideComposingWord(moveSteps)) {
|
||||
// no need to finish input and restart suggestions if we're still in the word
|
||||
// this is a noticeable performance improvement
|
||||
val newPosition: Int = inputLogic.mConnection.mExpectedSelStart + moveSteps
|
||||
inputLogic.mConnection.setSelection(newPosition, newPosition)
|
||||
return true
|
||||
}
|
||||
inputLogic.finishInput()
|
||||
val newPosition: Int = inputLogic.mConnection.mExpectedSelStart + moveSteps
|
||||
inputLogic.mConnection.setSelection(newPosition, newPosition)
|
||||
inputLogic.restartSuggestionsOnWordTouchedByCursor(settings.current, keyboardSwitcher.currentKeyboardScript)
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
|
@ -561,14 +561,14 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
|||
mClipboardHistoryView = mCurrentInputView.findViewById(R.id.clipboard_history_view);
|
||||
|
||||
mKeyboardViewWrapper = mCurrentInputView.findViewById(R.id.keyboard_view_wrapper);
|
||||
mKeyboardViewWrapper.setKeyboardActionListener(mLatinIME);
|
||||
mKeyboardViewWrapper.setKeyboardActionListener(mLatinIME.mKeyboardActionListener);
|
||||
mKeyboardView = mCurrentInputView.findViewById(R.id.keyboard_view);
|
||||
mKeyboardView.setHardwareAcceleratedDrawingEnabled(isHardwareAcceleratedDrawingEnabled);
|
||||
mKeyboardView.setKeyboardActionListener(mLatinIME);
|
||||
mKeyboardView.setKeyboardActionListener(mLatinIME.mKeyboardActionListener);
|
||||
mEmojiPalettesView.setHardwareAcceleratedDrawingEnabled(isHardwareAcceleratedDrawingEnabled);
|
||||
mEmojiPalettesView.setKeyboardActionListener(mLatinIME);
|
||||
mEmojiPalettesView.setKeyboardActionListener(mLatinIME.mKeyboardActionListener);
|
||||
mClipboardHistoryView.setHardwareAcceleratedDrawingEnabled(isHardwareAcceleratedDrawingEnabled);
|
||||
mClipboardHistoryView.setKeyboardActionListener(mLatinIME);
|
||||
mClipboardHistoryView.setKeyboardActionListener(mLatinIME.mKeyboardActionListener);
|
||||
mEmojiTabStripView = mCurrentInputView.findViewById(R.id.emoji_tab_strip);
|
||||
mClipboardStripView = mCurrentInputView.findViewById(R.id.clipboard_strip);
|
||||
mSuggestionStripView = mCurrentInputView.findViewById(R.id.suggestion_strip_view);
|
||||
|
|
|
@ -42,6 +42,8 @@ import android.view.inputmethod.InputMethodSubtype;
|
|||
import helium314.keyboard.accessibility.AccessibilityUtils;
|
||||
import helium314.keyboard.compat.ConfigurationCompatKt;
|
||||
import helium314.keyboard.compat.EditorInfoCompatUtils;
|
||||
import helium314.keyboard.keyboard.KeyboardActionListener;
|
||||
import helium314.keyboard.keyboard.KeyboardActionListenerImpl;
|
||||
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
|
||||
import helium314.keyboard.latin.common.InsetsOutlineProvider;
|
||||
import helium314.keyboard.dictionarypack.DictionaryPackConstants;
|
||||
|
@ -51,7 +53,6 @@ import helium314.keyboard.event.HardwareEventDecoder;
|
|||
import helium314.keyboard.event.HardwareKeyboardEventDecoder;
|
||||
import helium314.keyboard.event.InputTransaction;
|
||||
import helium314.keyboard.keyboard.Keyboard;
|
||||
import helium314.keyboard.keyboard.KeyboardActionListener;
|
||||
import helium314.keyboard.keyboard.KeyboardId;
|
||||
import helium314.keyboard.keyboard.KeyboardLayoutSet;
|
||||
import helium314.keyboard.keyboard.KeyboardSwitcher;
|
||||
|
@ -102,7 +103,7 @@ import androidx.core.content.ContextCompat;
|
|||
/**
|
||||
* Input method implementation for Qwerty'ish keyboard.
|
||||
*/
|
||||
public class LatinIME extends InputMethodService implements KeyboardActionListener,
|
||||
public class LatinIME extends InputMethodService implements
|
||||
SuggestionStripView.Listener, SuggestionStripViewAccessor,
|
||||
DictionaryFacilitator.DictionaryInitializationListener,
|
||||
PermissionsManager.PermissionsResultCallback {
|
||||
|
@ -122,6 +123,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
private static final String SCHEME_PACKAGE = "package";
|
||||
|
||||
final Settings mSettings;
|
||||
public final KeyboardActionListener mKeyboardActionListener;
|
||||
private int mOriginalNavBarColor = 0;
|
||||
private int mOriginalNavBarFlags = 0;
|
||||
private final DictionaryFacilitator mDictionaryFacilitator =
|
||||
|
@ -562,6 +564,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
mSettings = Settings.getInstance();
|
||||
mKeyboardSwitcher = KeyboardSwitcher.getInstance();
|
||||
mStatsUtilsManager = StatsUtilsManager.getInstance();
|
||||
mKeyboardActionListener = new KeyboardActionListenerImpl(this, mInputLogic);
|
||||
mIsHardwareAcceleratedDrawingEnabled = this.enableHardwareAcceleration();
|
||||
Log.i(TAG, "Hardware accelerated drawing: " + mIsHardwareAcceleratedDrawingEnabled);
|
||||
}
|
||||
|
@ -1374,121 +1377,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
launchSettings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCustomRequest(final int requestCode) {
|
||||
public boolean showInputPickerDialog() {
|
||||
if (isShowingOptionDialog()) return false;
|
||||
if (requestCode == Constants.CUSTOM_CODE_SHOW_INPUT_METHOD_PICKER) {
|
||||
if (mRichImm.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) {
|
||||
mOptionsDialog = InputMethodPickerKt.createInputMethodPickerDialog(this, mRichImm, mKeyboardSwitcher.getMainKeyboardView().getWindowToken());
|
||||
mOptionsDialog.show();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onHorizontalSpaceSwipe(final int steps) {
|
||||
return switch (mSettings.getCurrent().mSpaceSwipeHorizontal) {
|
||||
case KeyboardActionListener.SWIPE_MOVE_CURSOR -> onMoveCursorHorizontally(steps);
|
||||
case KeyboardActionListener.SWIPE_SWITCH_LANGUAGE -> onLanguageSlide(steps);
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
private boolean onMoveCursorHorizontally(int steps) {
|
||||
if (steps == 0) return false;
|
||||
// for RTL languages we want to invert pointer movement
|
||||
if (mRichImm.getCurrentSubtype().isRtlSubtype())
|
||||
steps = -steps;
|
||||
|
||||
final int moveSteps;
|
||||
if (steps < 0) {
|
||||
int availableCharacters = mInputLogic.mConnection.getTextBeforeCursor(64, 0).length();
|
||||
moveSteps = availableCharacters < -steps ? -availableCharacters : steps;
|
||||
if (moveSteps == 0) {
|
||||
// some apps don't return any text via input connection, and the cursor can't be moved
|
||||
// we fall back to virtually pressing the left/right key one or more times instead
|
||||
while (steps != 0) {
|
||||
onCodeInput(KeyCode.ARROW_LEFT, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false);
|
||||
++steps;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
int availableCharacters = mInputLogic.mConnection.getTextAfterCursor(64, 0).length();
|
||||
moveSteps = Math.min(availableCharacters, steps);
|
||||
if (moveSteps == 0) {
|
||||
while (steps != 0) {
|
||||
onCodeInput(KeyCode.ARROW_RIGHT, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false);
|
||||
--steps;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mInputLogic.moveCursorByAndReturnIfInsideComposingWord(moveSteps)) {
|
||||
// no need to finish input and restart suggestions if we're still in the word
|
||||
// this is a noticeable performance improvement
|
||||
int newPosition = mInputLogic.mConnection.mExpectedSelStart + moveSteps;
|
||||
mInputLogic.mConnection.setSelection(newPosition, newPosition);
|
||||
if (mRichImm.hasMultipleEnabledIMEsOrSubtypes(true)) {
|
||||
mOptionsDialog = InputMethodPickerKt.createInputMethodPickerDialog(this, mRichImm, mKeyboardSwitcher.getMainKeyboardView().getWindowToken());
|
||||
mOptionsDialog.show();
|
||||
return true;
|
||||
}
|
||||
mInputLogic.finishInput();
|
||||
int newPosition = mInputLogic.mConnection.mExpectedSelStart + moveSteps;
|
||||
mInputLogic.mConnection.setSelection(newPosition, newPosition);
|
||||
mInputLogic.restartSuggestionsOnWordTouchedByCursor(mSettings.getCurrent(), mKeyboardSwitcher.getCurrentKeyboardScript());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onVerticalSpaceSwipe(final int steps) {
|
||||
return switch (mSettings.getCurrent().mSpaceSwipeVertical) {
|
||||
case KeyboardActionListener.SWIPE_MOVE_CURSOR -> onMoveCursorVertically(steps);
|
||||
case KeyboardActionListener.SWIPE_SWITCH_LANGUAGE -> onLanguageSlide(steps);
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
private boolean onLanguageSlide(final int steps) {
|
||||
if (Math.abs(steps) < 4)
|
||||
return false;
|
||||
List<InputMethodSubtype> subtypes = RichInputMethodManager.getInstance().getMyEnabledInputMethodSubtypeList(false);
|
||||
if (subtypes.size() <= 1) { // only allow if we have more than one subtype
|
||||
return false;
|
||||
}
|
||||
// decide next or previous dependent on up or down
|
||||
InputMethodSubtype current = RichInputMethodManager.getInstance().getCurrentSubtype().getRawSubtype();
|
||||
int wantedIndex = (subtypes.indexOf(current) + ((steps > 0) ? 1 : -1)) % subtypes.size();
|
||||
if (wantedIndex < 0) wantedIndex += subtypes.size();
|
||||
KeyboardSwitcher.getInstance().switchToSubtype(subtypes.get(wantedIndex));
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean onMoveCursorVertically(int steps) {
|
||||
if (steps == 0) return false;
|
||||
int code = (steps < 0) ? KeyCode.ARROW_UP : KeyCode.ARROW_DOWN;
|
||||
onCodeInput(code, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMoveDeletePointer(int steps) {
|
||||
mInputLogic.finishInput();
|
||||
int end = mInputLogic.mConnection.getExpectedSelectionEnd();
|
||||
int start = mInputLogic.mConnection.getExpectedSelectionStart() + steps;
|
||||
if (start > end)
|
||||
return;
|
||||
mInputLogic.mConnection.setSelection(start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpWithDeletePointerActive() {
|
||||
if (mInputLogic.mConnection.hasSelection()) {
|
||||
mInputLogic.finishInput();
|
||||
onCodeInput(KeyCode.DELETE, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isShowingOptionDialog() {
|
||||
|
@ -1628,24 +1524,20 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
mKeyboardSwitcher.onEvent(event, getCurrentAutoCapsState(), getCurrentRecapitalizeState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartBatchInput() {
|
||||
mInputLogic.onStartBatchInput(mSettings.getCurrent(), mKeyboardSwitcher, mHandler);
|
||||
mGestureConsumer.onGestureStarted(mRichImm.getCurrentSubtypeLocale(), mKeyboardSwitcher.getKeyboard());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateBatchInput(final InputPointers batchPointers) {
|
||||
mInputLogic.onUpdateBatchInput(batchPointers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEndBatchInput(final InputPointers batchPointers) {
|
||||
mInputLogic.onEndBatchInput(batchPointers);
|
||||
mGestureConsumer.onGestureCompleted(batchPointers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelBatchInput() {
|
||||
mInputLogic.onCancelBatchInput(mHandler);
|
||||
mGestureConsumer.onGestureCanceled();
|
||||
|
@ -1673,21 +1565,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
dismissGestureFloatingPreviewText /* dismissDelayed */);
|
||||
}
|
||||
|
||||
// Called from PointerTracker through the KeyboardActionListener interface
|
||||
@Override
|
||||
public void onFinishSlidingInput() {
|
||||
// User finished sliding input.
|
||||
mKeyboardSwitcher.onFinishSlidingInput(getCurrentAutoCapsState(),
|
||||
getCurrentRecapitalizeState());
|
||||
}
|
||||
|
||||
// Called from PointerTracker through the KeyboardActionListener interface
|
||||
@Override
|
||||
public void onCancelInput() {
|
||||
// User released a finger outside any key
|
||||
// Nothing to do so far.
|
||||
}
|
||||
|
||||
public boolean hasSuggestionStripView() {
|
||||
return null != mSuggestionStripView;
|
||||
}
|
||||
|
@ -1846,24 +1723,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
feedbackManager.performAudioFeedback(code);
|
||||
}
|
||||
|
||||
// Callback of the {@link KeyboardActionListener}. This is called when a key is depressed;
|
||||
// release matching call is {@link #onReleaseKey(int,boolean)} below.
|
||||
@Override
|
||||
public void onPressKey(final int primaryCode, final int repeatCount,
|
||||
final boolean isSinglePointer) {
|
||||
mKeyboardSwitcher.onPressKey(primaryCode, isSinglePointer, getCurrentAutoCapsState(),
|
||||
getCurrentRecapitalizeState());
|
||||
hapticAndAudioFeedback(primaryCode, repeatCount);
|
||||
}
|
||||
|
||||
// Callback of the {@link KeyboardActionListener}. This is called when a key is released;
|
||||
// press matching call is {@link #onPressKey(int,int,boolean)} above.
|
||||
@Override
|
||||
public void onReleaseKey(final int primaryCode, final boolean withSliding) {
|
||||
mKeyboardSwitcher.onReleaseKey(primaryCode, withSliding, getCurrentAutoCapsState(),
|
||||
getCurrentRecapitalizeState());
|
||||
}
|
||||
|
||||
private HardwareEventDecoder getHardwareKeyEventDecoder(final int deviceId) {
|
||||
final HardwareEventDecoder decoder = mHardwareEventDecoders.get(deviceId);
|
||||
if (null != decoder) return decoder;
|
||||
|
|
Loading…
Add table
Reference in a new issue