allow moving the cursor by long pressing Space and swiping to sides

This commit is contained in:
tibbi 2022-01-19 22:31:41 +01:00
parent 13ccdc5108
commit d5a53a1089
2 changed files with 74 additions and 9 deletions

View File

@ -187,6 +187,20 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
} }
} }
override fun moveCursorRight() {
currentInputConnection?.apply {
sendKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT))
sendKeyEvent(KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_RIGHT))
}
}
override fun moveCursorLeft() {
currentInputConnection?.apply {
sendKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT))
sendKeyEvent(KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_LEFT))
}
}
override fun onText(text: CharSequence?) {} override fun onText(text: CharSequence?) {}
override fun swipeLeft() {} override fun swipeLeft() {}

View File

@ -103,6 +103,16 @@ class MyKeyboardView @JvmOverloads constructor(context: Context, attrs: Attribut
* Called when the finger has been lifted after pressing a key * Called when the finger has been lifted after pressing a key
*/ */
fun onActionUp() fun onActionUp()
/**
* Called when the user long presses Space and moves to the left
*/
fun moveCursorLeft()
/**
* Called when the user long presses Space and moves to the right
*/
fun moveCursorRight()
} }
private var mKeyboard: MyKeyboard? = null private var mKeyboard: MyKeyboard? = null
@ -197,6 +207,8 @@ class MyKeyboardView @JvmOverloads constructor(context: Context, attrs: Attribut
private val mSwipeTracker: SwipeTracker = SwipeTracker() private val mSwipeTracker: SwipeTracker = SwipeTracker()
private val mSwipeThreshold: Int private val mSwipeThreshold: Int
private val mDisambiguateSwipe: Boolean private val mDisambiguateSwipe: Boolean
private var mIsLongPressingSpace = false
private var mLastSpaceMoveX = 0
private var mPopupMaxMoveDistance = 0f private var mPopupMaxMoveDistance = 0f
private var topSmallNumberSize = 0f private var topSmallNumberSize = 0f
private var topSmallNumberMarginWidth = 0f private var topSmallNumberMarginWidth = 0f
@ -256,6 +268,7 @@ class MyKeyboardView @JvmOverloads constructor(context: Context, attrs: Attribut
private val LONGPRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout() private val LONGPRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout()
private const val MAX_NEARBY_KEYS = 12 private const val MAX_NEARBY_KEYS = 12
private const val MULTITAP_INTERVAL = 800 // milliseconds private const val MULTITAP_INTERVAL = 800 // milliseconds
private const val SPACE_MOVE_THRESHOLD = 20
} }
init { init {
@ -334,7 +347,7 @@ class MyKeyboardView @JvmOverloads constructor(context: Context, attrs: Attribut
when (msg.what) { when (msg.what) {
MSG_SHOW_PREVIEW -> showKey(msg.arg1) MSG_SHOW_PREVIEW -> showKey(msg.arg1)
MSG_REMOVE_PREVIEW -> mPreviewText!!.visibility = INVISIBLE MSG_REMOVE_PREVIEW -> mPreviewText!!.visibility = INVISIBLE
MSG_REPEAT -> if (repeatKey()) { MSG_REPEAT -> if (repeatKey(false)) {
val repeat = Message.obtain(this, MSG_REPEAT) val repeat = Message.obtain(this, MSG_REPEAT)
sendMessageDelayed(repeat, REPEAT_INTERVAL.toLong()) sendMessageDelayed(repeat, REPEAT_INTERVAL.toLong())
} }
@ -1069,6 +1082,14 @@ class MyKeyboardView @JvmOverloads constructor(context: Context, attrs: Attribut
override fun onActionUp() { override fun onActionUp() {
onKeyboardActionListener!!.onActionUp() onKeyboardActionListener!!.onActionUp()
} }
override fun moveCursorLeft() {
onKeyboardActionListener!!.moveCursorLeft()
}
override fun moveCursorRight() {
onKeyboardActionListener!!.moveCursorRight()
}
} }
//mInputView.setSuggest(mSuggest); //mInputView.setSuggest(mSuggest);
@ -1303,9 +1324,15 @@ class MyKeyboardView @JvmOverloads constructor(context: Context, attrs: Attribut
var wasHandled = false var wasHandled = false
if (mCurrentKey >= 0 && mKeys[mCurrentKey].repeatable) { if (mCurrentKey >= 0 && mKeys[mCurrentKey].repeatable) {
mRepeatKeyIndex = mCurrentKey mRepeatKeyIndex = mCurrentKey
// if the user long presses Space, move the cursor after swipine left/right
if (mKeys[mCurrentKey].codes.firstOrNull() == MyKeyboard.KEYCODE_SPACE) {
val msg = mHandler!!.obtainMessage(MSG_REPEAT) val msg = mHandler!!.obtainMessage(MSG_REPEAT)
mHandler!!.sendMessageDelayed(msg, REPEAT_START_DELAY.toLong()) mHandler!!.sendMessageDelayed(msg, REPEAT_START_DELAY.toLong())
repeatKey() mLastSpaceMoveX = touchX
} else {
repeatKey(true)
}
// Delivering the key could have caused an abort // Delivering the key could have caused an abort
if (mAbortKey) { if (mAbortKey) {
mRepeatKeyIndex = NOT_A_KEY mRepeatKeyIndex = NOT_A_KEY
@ -1341,7 +1368,17 @@ class MyKeyboardView @JvmOverloads constructor(context: Context, attrs: Attribut
} }
} }
if (!continueLongPress) { if (mIsLongPressingSpace) {
val diff = mLastX - mLastSpaceMoveX
if (diff > SPACE_MOVE_THRESHOLD) {
onKeyboardActionListener?.moveCursorRight()
mLastSpaceMoveX = mLastX
} else if (diff < -SPACE_MOVE_THRESHOLD) {
onKeyboardActionListener?.moveCursorLeft()
mLastSpaceMoveX = mLastX
}
} else if (!continueLongPress) {
// Cancel old longpress // Cancel old longpress
mHandler!!.removeMessages(MSG_LONGPRESS) mHandler!!.removeMessages(MSG_LONGPRESS)
// Start new longpress if key has changed // Start new longpress if key has changed
@ -1349,11 +1386,13 @@ class MyKeyboardView @JvmOverloads constructor(context: Context, attrs: Attribut
val msg = mHandler!!.obtainMessage(MSG_LONGPRESS, me) val msg = mHandler!!.obtainMessage(MSG_LONGPRESS, me)
mHandler!!.sendMessageDelayed(msg, LONGPRESS_TIMEOUT.toLong()) mHandler!!.sendMessageDelayed(msg, LONGPRESS_TIMEOUT.toLong())
} }
}
showPreview(mCurrentKey) showPreview(mCurrentKey)
mLastMoveTime = eventTime mLastMoveTime = eventTime
} }
}
MotionEvent.ACTION_UP -> { MotionEvent.ACTION_UP -> {
mLastSpaceMoveX = 0
removeMessages() removeMessages()
if (keyIndex == mCurrentKey) { if (keyIndex == mCurrentKey) {
mCurrentKeyTime += eventTime - mLastMoveTime mCurrentKeyTime += eventTime - mLastMoveTime
@ -1376,11 +1415,19 @@ class MyKeyboardView @JvmOverloads constructor(context: Context, attrs: Attribut
if (mRepeatKeyIndex == NOT_A_KEY && !mMiniKeyboardOnScreen && !mAbortKey) { if (mRepeatKeyIndex == NOT_A_KEY && !mMiniKeyboardOnScreen && !mAbortKey) {
detectAndSendKey(mCurrentKey, touchX, touchY, eventTime) detectAndSendKey(mCurrentKey, touchX, touchY, eventTime)
} }
if (mKeys[mCurrentKey].codes.firstOrNull() == MyKeyboard.KEYCODE_SPACE && !mIsLongPressingSpace) {
detectAndSendKey(mCurrentKey, touchX, touchY, eventTime)
}
invalidateKey(keyIndex) invalidateKey(keyIndex)
mRepeatKeyIndex = NOT_A_KEY mRepeatKeyIndex = NOT_A_KEY
onKeyboardActionListener!!.onActionUp() onKeyboardActionListener!!.onActionUp()
mIsLongPressingSpace = false
} }
MotionEvent.ACTION_CANCEL -> { MotionEvent.ACTION_CANCEL -> {
mIsLongPressingSpace = false
mLastSpaceMoveX = 0
removeMessages() removeMessages()
dismissPopupKeyboard() dismissPopupKeyboard()
mAbortKey = true mAbortKey = true
@ -1394,9 +1441,13 @@ class MyKeyboardView @JvmOverloads constructor(context: Context, attrs: Attribut
return true return true
} }
private fun repeatKey(): Boolean { private fun repeatKey(initialCall: Boolean): Boolean {
val key = mKeys[mRepeatKeyIndex] val key = mKeys[mRepeatKeyIndex]
if (!initialCall && key.codes.firstOrNull() == MyKeyboard.KEYCODE_SPACE) {
mIsLongPressingSpace = true
} else {
detectAndSendKey(mCurrentKey, key.x, key.y, mLastTapTime) detectAndSendKey(mCurrentKey, key.x, key.y, mLastTapTime)
}
return true return true
} }