Skip to content

Commit bd0da6a

Browse files
committed
feat: hold toolbar arrow keys to auto-repeat
1 parent ba7ad8f commit bd0da6a

3 files changed

Lines changed: 90 additions & 4 deletions

File tree

app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ import helium314.keyboard.latin.settings.Settings
3434
import helium314.keyboard.latin.utils.ResourceUtils
3535
import helium314.keyboard.latin.utils.ToolbarKey
3636
import helium314.keyboard.latin.utils.createToolbarKey
37+
import helium314.keyboard.latin.utils.isRepeatableToolbarKey
38+
import helium314.keyboard.latin.utils.RepeatableKeyTouchListener
3739
import helium314.keyboard.latin.utils.getCodeForToolbarKey
3840
import helium314.keyboard.latin.utils.getCodeForToolbarKeyLongClick
3941
import helium314.keyboard.latin.utils.getEnabledClipboardToolbarKeys
@@ -196,8 +198,21 @@ class ClipboardHistoryView @JvmOverloads constructor(
196198
val clipboardStrip = KeyboardSwitcher.getInstance().clipboardStrip
197199
toolbarKeys.forEach {
198200
clipboardStrip.addView(it)
199-
it.setOnClickListener(this@ClipboardHistoryView)
200-
it.setOnLongClickListener(this@ClipboardHistoryView)
201+
val tag = it.tag
202+
if (tag is ToolbarKey && isRepeatableToolbarKey(tag)) {
203+
it.setOnTouchListener(RepeatableKeyTouchListener { repeatCount ->
204+
if (repeatCount == 0 || repeatCount % 4 == 0) {
205+
AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback(KeyCode.NOT_SPECIFIED, it, HapticEvent.KEY_PRESS)
206+
}
207+
val code = getCodeForToolbarKey(tag)
208+
if (code != KeyCode.UNSPECIFIED) {
209+
keyboardActionListener.onCodeInput(code, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, repeatCount > 0)
210+
}
211+
})
212+
} else {
213+
it.setOnClickListener(this@ClipboardHistoryView)
214+
it.setOnLongClickListener(this@ClipboardHistoryView)
215+
}
201216
colors.setColor(it, ColorType.TOOL_BAR_KEY)
202217
it.setBackgroundResource(R.drawable.toolbar_key_background)
203218
colors.setColor(it.background, ColorType.TOOL_BAR_EXPAND_KEY_BACKGROUND)

app/src/main/java/helium314/keyboard/latin/suggestions/SuggestionStripView.kt

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ import helium314.keyboard.latin.utils.ToolbarKey
5151
import helium314.keyboard.latin.utils.ToolbarMode
5252
import helium314.keyboard.latin.utils.addPinnedKey
5353
import helium314.keyboard.latin.utils.createToolbarKey
54+
import helium314.keyboard.latin.utils.isRepeatableToolbarKey
55+
import helium314.keyboard.latin.utils.RepeatableKeyTouchListener
5456
import helium314.keyboard.latin.utils.dpToPx
5557
import helium314.keyboard.latin.utils.getCodeForToolbarKey
5658
import helium314.keyboard.latin.utils.getCodeForToolbarKeyLongClick
@@ -866,8 +868,21 @@ class SuggestionStripView(context: Context, attrs: AttributeSet?, defStyle: Int)
866868
}
867869

868870
private fun setupKey(view: ImageButton, colors: Colors) {
869-
view.setOnClickListener(this)
870-
view.setOnLongClickListener(this)
871+
val tag = view.tag
872+
if (tag is ToolbarKey && isRepeatableToolbarKey(tag)) {
873+
view.setOnTouchListener(RepeatableKeyTouchListener { repeatCount ->
874+
if (repeatCount == 0 || repeatCount % 4 == 0) {
875+
AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback(KeyCode.NOT_SPECIFIED, view, HapticEvent.KEY_PRESS)
876+
}
877+
val code = getCodeForToolbarKey(tag)
878+
if (code != KeyCode.UNSPECIFIED) {
879+
listener.onCodeInput(code, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, repeatCount > 0)
880+
}
881+
})
882+
} else {
883+
view.setOnClickListener(this)
884+
view.setOnLongClickListener(this)
885+
}
871886
colors.setColor(view, ColorType.TOOL_BAR_KEY)
872887
// Set circular background for toolbar keys
873888
view.setBackgroundResource(R.drawable.toolbar_key_background)

app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ import android.view.ViewGroup
77
import android.widget.ImageButton
88
import android.widget.ImageView
99
import androidx.core.content.edit
10+
import android.view.View
11+
import android.view.MotionEvent
12+
import android.os.Handler
13+
import android.os.Looper
14+
import android.annotation.SuppressLint
1015
import androidx.core.view.forEach
1116
import helium314.keyboard.keyboard.internal.KeyboardIconsSet
1217
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
@@ -409,3 +414,54 @@ fun clearCustomToolbarKeyCodes() {
409414
}
410415

411416
private var customToolbarKeyCodes: EnumMap<ToolbarKey, Pair<Int?, Int?>>? = null
417+
418+
fun isRepeatableToolbarKey(key: ToolbarKey): Boolean {
419+
return when (key) {
420+
LEFT, RIGHT, UP, DOWN,
421+
WORD_LEFT, WORD_RIGHT,
422+
PAGE_UP, PAGE_DOWN -> true
423+
else -> false
424+
}
425+
}
426+
427+
class RepeatableKeyTouchListener(
428+
private val onClick: (repeatCount: Int) -> Unit
429+
) : View.OnTouchListener {
430+
private val handler = Handler(Looper.getMainLooper())
431+
private var repeatCount = 0
432+
private val runnable = object : Runnable {
433+
override fun run() {
434+
repeatCount++
435+
onClick(repeatCount)
436+
handler.postDelayed(this, 50L)
437+
}
438+
}
439+
440+
@SuppressLint("ClickableViewAccessibility")
441+
override fun onTouch(v: View, event: MotionEvent): Boolean {
442+
when (event.action) {
443+
MotionEvent.ACTION_DOWN -> {
444+
repeatCount = 0
445+
onClick(0)
446+
handler.postDelayed(runnable, 400L)
447+
v.isPressed = true
448+
return true
449+
}
450+
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
451+
handler.removeCallbacks(runnable)
452+
v.isPressed = false
453+
return true
454+
}
455+
MotionEvent.ACTION_MOVE -> {
456+
val x = event.x
457+
val y = event.y
458+
if (x < 0 || x > v.width || y < 0 || y > v.height) {
459+
handler.removeCallbacks(runnable)
460+
v.isPressed = false
461+
}
462+
return true
463+
}
464+
}
465+
return false
466+
}
467+
}

0 commit comments

Comments
 (0)