Skip to content

Commit

Permalink
Add support for moving cursor on spacebar slide. Fixes #91 (#401)
Browse files Browse the repository at this point in the history
* Add initial support for moving cursor with long swipes

* Run formatKotlin

* Cleanup stuff that got lost when rebasing main

* Fix issue where sliding to far moves focus out of text field

* Rename spacebar_slide to slide_enabled and fix migrations

* Release spacebar after slide
  • Loading branch information
storvik committed Sep 14, 2023
1 parent f1f3185 commit 27263f3
Show file tree
Hide file tree
Showing 7 changed files with 255 additions and 22 deletions.
26 changes: 25 additions & 1 deletion app/src/main/java/com/dessalines/thumbkey/db/AppDb.kt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ const val DEFAULT_HIDE_LETTERS = 0
const val DEFAULT_HIDE_SYMBOLS = 0
const val DEFAULT_KEY_BORDERS = 1
const val DEFAULT_SPACEBAR_MULTITAPS = 1
const val DEFAULT_SLIDE_SENSITIVITY = 9
const val DEFAULT_SLIDE_ENABLED = 0

@Entity
data class AppSettings(
Expand Down Expand Up @@ -90,6 +92,11 @@ data class AppSettings(
name = "sound_on_tap",
defaultValue = DEFAULT_SOUND_ON_TAP.toString(),
)
val slideEnabled: Int,
@ColumnInfo(
name = "slide_enabled",
defaultValue = DEFAULT_SLIDE_ENABLED.toString(),
)
val soundOnTap: Int,
@ColumnInfo(
name = "theme",
Expand All @@ -112,6 +119,11 @@ data class AppSettings(
defaultValue = DEFAULT_MIN_SWIPE_LENGTH.toString(),
)
val minSwipeLength: Int,
@ColumnInfo(
name = "slide_sensitivity",
defaultValue = DEFAULT_SLIDE_SENSITIVITY.toString(),
)
val slideSensitivity: Int,
@ColumnInfo(
name = "pushup_size",
defaultValue = DEFAULT_PUSHUP_SIZE.toString(),
Expand Down Expand Up @@ -275,8 +287,19 @@ val MIGRATION_8_9 = object : Migration(8, 9) {
}
}

val MIGRATION_9_10 = object : Migration(9, 10) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(
"alter table AppSettings add column slide_enabled INTEGER NOT NULL default $DEFAULT_SLIDE_ENABLED",
)
database.execSQL(
"alter table AppSettings add column slide_sensitivity INTEGER NOT NULL default $DEFAULT_SLIDE_SENSITIVITY",
)
}
}

@Database(
version = 9,
version = 10,
entities = [AppSettings::class],
exportSchema = true,
)
Expand Down Expand Up @@ -308,6 +331,7 @@ abstract class AppDB : RoomDatabase() {
MIGRATION_6_7,
MIGRATION_7_8,
MIGRATION_8_9,
MIGRATION_9_10,
)
// Necessary because it can't insert data on creation
.addCallback(object : Callback() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import com.dessalines.thumbkey.utils.KeyAction
import com.dessalines.thumbkey.utils.KeyC
import com.dessalines.thumbkey.utils.KeyDisplay
import com.dessalines.thumbkey.utils.KeyItemC
import com.dessalines.thumbkey.utils.SlideType
import com.dessalines.thumbkey.utils.SwipeDirection
import com.dessalines.thumbkey.utils.SwipeNWay

Expand Down Expand Up @@ -117,6 +118,7 @@ val SPACEBAR_KEY_ITEM =
action = KeyAction.CommitText(" "),
),
swipeType = SwipeNWay.TWO_WAY_HORIZONTAL,
slideType = SlideType.MOVE_CURSOR,
swipes = mapOf(
SwipeDirection.LEFT to KeyC(
action = KeyAction.SendEvent(
Expand Down Expand Up @@ -157,6 +159,7 @@ val SPACEBAR_PROGRAMMER_KEY_ITEM =
action = KeyAction.CommitText(" "),
),
swipeType = SwipeNWay.FOUR_WAY_CROSS,
slideType = SlideType.MOVE_CURSOR,
swipes = mapOf(
SwipeDirection.LEFT to KeyC(
action = KeyAction.SendEvent(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.dessalines.thumbkey.ui.components.keyboard
import android.content.Context
import android.media.AudioManager
import android.view.KeyEvent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.core.tween
Expand Down Expand Up @@ -44,13 +45,15 @@ import com.dessalines.thumbkey.utils.KeyAction
import com.dessalines.thumbkey.utils.KeyC
import com.dessalines.thumbkey.utils.KeyDisplay
import com.dessalines.thumbkey.utils.KeyItemC
import com.dessalines.thumbkey.utils.SlideType
import com.dessalines.thumbkey.utils.SwipeDirection
import com.dessalines.thumbkey.utils.buildTapActions
import com.dessalines.thumbkey.utils.colorVariantToColor
import com.dessalines.thumbkey.utils.doneKeyAction
import com.dessalines.thumbkey.utils.fontSizeVariantToFontSize
import com.dessalines.thumbkey.utils.performKeyAction
import com.dessalines.thumbkey.utils.swipeDirection
import kotlin.math.abs

@Composable
fun KeyboardKey(
Expand All @@ -68,6 +71,8 @@ fun KeyboardKey(
capsLock: Boolean,
keySize: Int,
minSwipeLength: Int,
slideSensitivity: Int,
slideEnabled: Boolean,
onToggleShiftMode: (enable: Boolean) -> Unit,
onToggleNumericMode: (enable: Boolean) -> Unit,
onToggleCapsLock: () -> Unit,
Expand All @@ -76,7 +81,7 @@ fun KeyboardKey(
onSwitchPosition: () -> Unit,
) {
// Necessary for swipe settings to get updated correctly
val id = key.toString() + animationHelperSpeed + animationSpeed + autoCapitalize + vibrateOnTap + soundOnTap + keySize + minSwipeLength
val id = key.toString() + animationHelperSpeed + animationSpeed + autoCapitalize + vibrateOnTap + soundOnTap + keySize + minSwipeLength + slideSensitivity + slideEnabled

val ctx = LocalContext.current
val ime = ctx as IMEService
Expand Down Expand Up @@ -173,30 +178,85 @@ fun KeyboardKey(
val (x, y) = dragAmount
offsetX += x
offsetY += y
if (key.slideType == SlideType.MOVE_CURSOR && slideEnabled) {
if (abs(offsetX) > slideSensitivity) {
var direction = 0
var shouldMove = false
if (offsetX < 0.00) {
// move left
if (ime.currentInputConnection.getTextBeforeCursor(1, 0)?.length != 0) {
shouldMove = true
}
direction = KeyEvent.KEYCODE_DPAD_LEFT
} else {
// move right
if (ime.currentInputConnection.getTextAfterCursor(1, 0)?.length != 0) {
shouldMove = true
}
direction = KeyEvent.KEYCODE_DPAD_RIGHT
}
if (shouldMove) {
val action = KeyAction.SendEvent(
KeyEvent(
KeyEvent.ACTION_DOWN,
direction,
),
)
performKeyAction(
action = action,
ime = ime,
autoCapitalize = autoCapitalize,
onToggleShiftMode = onToggleShiftMode,
onToggleNumericMode = onToggleNumericMode,
onToggleCapsLock = onToggleCapsLock,
onAutoCapitalize = onAutoCapitalize,
onSwitchLanguage = onSwitchLanguage,
onSwitchPosition = onSwitchPosition,
)
}
offsetX = 0f
offsetY = 0f
}
}
},
onDragEnd = {
val swipeDirection = swipeDirection(offsetX, offsetY, minSwipeLength, key.swipeType)
val action = key.swipes?.get(swipeDirection)?.action ?: key.center.action
if (key.slideType == SlideType.NONE || !slideEnabled) {
val swipeDirection = swipeDirection(offsetX, offsetY, minSwipeLength, key.swipeType)
val action = key.swipes?.get(swipeDirection)?.action ?: key.center.action

performKeyAction(
action = action,
ime = ime,
autoCapitalize = autoCapitalize,
onToggleShiftMode = onToggleShiftMode,
onToggleNumericMode = onToggleNumericMode,
onToggleCapsLock = onToggleCapsLock,
onAutoCapitalize = onAutoCapitalize,
onSwitchLanguage = onSwitchLanguage,
onSwitchPosition = onSwitchPosition,
)
tapCount = 0
lastAction.value = action
performKeyAction(
action = action,
ime = ime,
autoCapitalize = autoCapitalize,
onToggleShiftMode = onToggleShiftMode,
onToggleNumericMode = onToggleNumericMode,
onToggleCapsLock = onToggleCapsLock,
onAutoCapitalize = onAutoCapitalize,
onSwitchLanguage = onSwitchLanguage,
onSwitchPosition = onSwitchPosition,
)
tapCount = 0
lastAction.value = action

// Reset the drags
offsetX = 0f
offsetY = 0f
// Reset the drags
offsetX = 0f
offsetY = 0f

doneKeyAction(scope, action, isDragged, releasedKey, animationHelperSpeed)
doneKeyAction(scope, action, isDragged, releasedKey, animationHelperSpeed)
} else {
doneKeyAction(
scope,
KeyAction.SendEvent(
KeyEvent(
KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_DPAD_RIGHT,
),
),
isDragged,
releasedKey,
animationHelperSpeed,
)
}
},
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import com.dessalines.thumbkey.db.DEFAULT_KEY_SIZE
import com.dessalines.thumbkey.db.DEFAULT_MIN_SWIPE_LENGTH
import com.dessalines.thumbkey.db.DEFAULT_POSITION
import com.dessalines.thumbkey.db.DEFAULT_PUSHUP_SIZE
import com.dessalines.thumbkey.db.DEFAULT_SLIDE_ENABLED
import com.dessalines.thumbkey.db.DEFAULT_SLIDE_SENSITIVITY
import com.dessalines.thumbkey.db.DEFAULT_SOUND_ON_TAP
import com.dessalines.thumbkey.db.DEFAULT_SPACEBAR_MULTITAPS
import com.dessalines.thumbkey.db.DEFAULT_VIBRATE_ON_TAP
Expand Down Expand Up @@ -83,6 +85,7 @@ fun KeyboardScreen(

val autoCapitalize = (settings?.autoCapitalize ?: DEFAULT_AUTO_CAPITALIZE).toBool()
val spacebarMultiTaps = (settings?.spacebarMultiTaps ?: DEFAULT_SPACEBAR_MULTITAPS).toBool()
val slideEnabled = (settings?.slideEnabled ?: DEFAULT_SLIDE_ENABLED).toBool()
val keyBorders = (settings?.keyBorders ?: DEFAULT_KEY_BORDERS).toBool()
val vibrateOnTap = (settings?.vibrateOnTap ?: DEFAULT_VIBRATE_ON_TAP).toBool()
val soundOnTap = (settings?.soundOnTap ?: DEFAULT_SOUND_ON_TAP).toBool()
Expand Down Expand Up @@ -119,6 +122,8 @@ fun KeyboardScreen(
animationHelperSpeed = settings?.animationHelperSpeed
?: DEFAULT_ANIMATION_HELPER_SPEED,
minSwipeLength = settings?.minSwipeLength ?: DEFAULT_MIN_SWIPE_LENGTH,
slideSensitivity = settings?.slideSensitivity ?: DEFAULT_SLIDE_SENSITIVITY,
slideEnabled = slideEnabled,
onToggleShiftMode = { enable ->
mode = if (enable) {
KeyboardMode.SHIFTED
Expand Down
Loading

0 comments on commit 27263f3

Please sign in to comment.