mirror of
https://github.com/dessalines/thumb-key.git
synced 2024-09-11 17:05:34 +03:00
Added ghost key functionality. (#961)
* Added ghost key functionality. This lets you swipe symbol keys which are not visible, but exist in the corresponding location in the numerical view. * Added comments and descriptions, simplified key composition logic, ran linter
This commit is contained in:
parent
09dec63ce8
commit
eb252a5d78
@ -104,6 +104,10 @@ Enabling `Backspace: Allow normal swipes to work with slide gestures`, in keyboa
|
||||
- You can type the opposite-case letter by dragging away from, then back to the original key.
|
||||
- Clockwise and counter-clockwise drags can be configured to type the opposite-case letter, or the equivalent center key on the numeric layout.
|
||||
|
||||
### Ghost keys
|
||||
|
||||
Enabling `Ghost keys` in keyboard settings will enable swiping hidden symbol keys without switching to the numeric layout.
|
||||
|
||||
### Coming from MessagEase Keyboard Tips
|
||||
|
||||
- For those use to tapping on the hand key to hide the MessagEase Keyboard and make more screen real estate available, this can be done by using the Android back key or on Android 10 and higher using the guesture navigation for back.
|
||||
|
@ -56,6 +56,7 @@ const val DEFAULT_DRAG_RETURN_ENABLED = 1
|
||||
const val DEFAULT_CIRCULAR_DRAG_ENABLED = 1
|
||||
const val DEFAULT_CLOCKWISE_DRAG_ACTION = 0
|
||||
const val DEFAULT_COUNTERCLOCKWISE_DRAG_ACTION = 1
|
||||
const val DEFAULT_GHOST_KEYS_ENABLED = 0
|
||||
|
||||
@Entity
|
||||
data class AppSettings(
|
||||
@ -226,6 +227,11 @@ data class AppSettings(
|
||||
defaultValue = DEFAULT_COUNTERCLOCKWISE_DRAG_ACTION.toString(),
|
||||
)
|
||||
val counterclockwiseDragAction: Int,
|
||||
@ColumnInfo(
|
||||
name = "ghost_keys_enabled",
|
||||
defaultValue = DEFAULT_GHOST_KEYS_ENABLED.toString(),
|
||||
)
|
||||
val ghostKeysEnabled: Int,
|
||||
)
|
||||
|
||||
data class LayoutsUpdate(
|
||||
@ -334,6 +340,8 @@ data class BehaviorUpdate(
|
||||
val clockwiseDragAction: Int,
|
||||
@ColumnInfo(name = "counterclockwise_drag_action")
|
||||
val counterclockwiseDragAction: Int,
|
||||
@ColumnInfo(name = "ghost_keys_enabled")
|
||||
val ghostKeysEnabled: Int,
|
||||
)
|
||||
|
||||
@Dao
|
||||
@ -565,8 +573,17 @@ val MIGRATION_14_15 =
|
||||
}
|
||||
}
|
||||
|
||||
val MIGRATION_15_16 =
|
||||
object : Migration(15, 16) {
|
||||
override fun migrate(db: SupportSQLiteDatabase) {
|
||||
db.execSQL(
|
||||
"alter table AppSettings add column ghost_keys_enabled INTEGER NOT NULL default $DEFAULT_GHOST_KEYS_ENABLED",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Database(
|
||||
version = 15,
|
||||
version = 16,
|
||||
entities = [AppSettings::class],
|
||||
exportSchema = true,
|
||||
)
|
||||
@ -603,6 +620,7 @@ abstract class AppDB : RoomDatabase() {
|
||||
MIGRATION_12_13,
|
||||
MIGRATION_13_14,
|
||||
MIGRATION_14_15,
|
||||
MIGRATION_15_16,
|
||||
)
|
||||
// Necessary because it can't insert data on creation
|
||||
.addCallback(
|
||||
|
@ -60,6 +60,7 @@ import com.dessalines.thumbkey.utils.KeyboardDefinitionSettings
|
||||
import com.dessalines.thumbkey.utils.Selection
|
||||
import com.dessalines.thumbkey.utils.SlideType
|
||||
import com.dessalines.thumbkey.utils.SwipeDirection
|
||||
import com.dessalines.thumbkey.utils.SwipeNWay
|
||||
import com.dessalines.thumbkey.utils.buildTapActions
|
||||
import com.dessalines.thumbkey.utils.circularDirection
|
||||
import com.dessalines.thumbkey.utils.colorVariantToColor
|
||||
@ -80,6 +81,10 @@ import kotlin.math.min
|
||||
@Composable
|
||||
fun KeyboardKey(
|
||||
key: KeyItemC,
|
||||
// Hidden background key to detect swipes for. When a swipe isn't captured by the key, the ghost
|
||||
// key will attempt to capture it instead. This is derived automatically from the keyboard
|
||||
// layout, and should not be set directly in the keyboard definition.
|
||||
ghostKey: KeyItemC? = null,
|
||||
lastAction: MutableState<KeyAction?>,
|
||||
animationHelperSpeed: Int,
|
||||
animationSpeed: Int,
|
||||
@ -120,7 +125,7 @@ fun KeyboardKey(
|
||||
) {
|
||||
// Necessary for swipe settings to get updated correctly
|
||||
val id =
|
||||
key.toString() + animationHelperSpeed + animationSpeed + autoCapitalize +
|
||||
key.toString() + ghostKey.toString() + animationHelperSpeed + animationSpeed + autoCapitalize +
|
||||
vibrateOnTap + soundOnTap + legendHeight + legendWidth + minSwipeLength + slideSensitivity +
|
||||
slideEnabled + slideCursorMovementMode + slideSpacebarDeadzoneEnabled +
|
||||
slideBackspaceDeadzoneEnabled + dragReturnEnabled + circularDragEnabled +
|
||||
@ -469,8 +474,15 @@ fun KeyboardKey(
|
||||
)
|
||||
} else {
|
||||
val swipeDirection =
|
||||
swipeDirection(offsetX, offsetY, minSwipeLength, key.swipeType)
|
||||
key.swipes?.get(swipeDirection)?.action
|
||||
swipeDirection(
|
||||
offsetX,
|
||||
offsetY,
|
||||
minSwipeLength,
|
||||
if (ghostKey == null) key.swipeType else SwipeNWay.EIGHT_WAY,
|
||||
)
|
||||
key.swipes?.get(swipeDirection)?.action ?: (
|
||||
ghostKey?.swipes?.get(swipeDirection)?.action
|
||||
)
|
||||
}
|
||||
) ?: key.center.action
|
||||
|
||||
|
@ -39,6 +39,7 @@ import com.dessalines.thumbkey.db.DEFAULT_CIRCULAR_DRAG_ENABLED
|
||||
import com.dessalines.thumbkey.db.DEFAULT_CLOCKWISE_DRAG_ACTION
|
||||
import com.dessalines.thumbkey.db.DEFAULT_COUNTERCLOCKWISE_DRAG_ACTION
|
||||
import com.dessalines.thumbkey.db.DEFAULT_DRAG_RETURN_ENABLED
|
||||
import com.dessalines.thumbkey.db.DEFAULT_GHOST_KEYS_ENABLED
|
||||
import com.dessalines.thumbkey.db.DEFAULT_HIDE_LETTERS
|
||||
import com.dessalines.thumbkey.db.DEFAULT_HIDE_SYMBOLS
|
||||
import com.dessalines.thumbkey.db.DEFAULT_KEYBOARD_LAYOUT
|
||||
@ -143,6 +144,7 @@ fun KeyboardScreen(
|
||||
val clockwiseDragAction = CircularDragAction.entries[settings?.clockwiseDragAction ?: DEFAULT_CLOCKWISE_DRAG_ACTION]
|
||||
val counterclockwiseDragAction =
|
||||
CircularDragAction.entries[settings?.counterclockwiseDragAction ?: DEFAULT_COUNTERCLOCKWISE_DRAG_ACTION]
|
||||
val ghostKeysEnabled = (settings?.ghostKeysEnabled ?: DEFAULT_GHOST_KEYS_ENABLED).toBool()
|
||||
|
||||
val keyBorderWidthFloat = keyBorderWidth / 10.0f
|
||||
val keyBorderColour = MaterialTheme.colorScheme.outline
|
||||
@ -362,8 +364,19 @@ fun KeyboardScreen(
|
||||
Row {
|
||||
row.forEachIndexed { j, key ->
|
||||
Column {
|
||||
val ghostKey =
|
||||
if (ghostKeysEnabled) {
|
||||
when (mode) {
|
||||
KeyboardMode.MAIN -> keyboardDefinition.modes.numeric
|
||||
KeyboardMode.SHIFTED -> keyboardDefinition.modes.numeric
|
||||
else -> null
|
||||
}?.arr?.getOrNull(i)?.getOrNull(j)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
KeyboardKey(
|
||||
key = key,
|
||||
ghostKey = ghostKey,
|
||||
lastAction = lastAction,
|
||||
legendHeight = legendHeight,
|
||||
legendWidth = legendWidth,
|
||||
|
@ -46,6 +46,7 @@ import com.dessalines.thumbkey.db.DEFAULT_CIRCULAR_DRAG_ENABLED
|
||||
import com.dessalines.thumbkey.db.DEFAULT_CLOCKWISE_DRAG_ACTION
|
||||
import com.dessalines.thumbkey.db.DEFAULT_COUNTERCLOCKWISE_DRAG_ACTION
|
||||
import com.dessalines.thumbkey.db.DEFAULT_DRAG_RETURN_ENABLED
|
||||
import com.dessalines.thumbkey.db.DEFAULT_GHOST_KEYS_ENABLED
|
||||
import com.dessalines.thumbkey.db.DEFAULT_HIDE_LETTERS
|
||||
import com.dessalines.thumbkey.db.DEFAULT_HIDE_SYMBOLS
|
||||
import com.dessalines.thumbkey.db.DEFAULT_KEYBOARD_LAYOUT
|
||||
@ -306,6 +307,7 @@ private fun resetAppSettingsToDefault(appSettingsViewModel: AppSettingsViewModel
|
||||
circularDragEnabled = DEFAULT_CIRCULAR_DRAG_ENABLED,
|
||||
clockwiseDragAction = DEFAULT_CLOCKWISE_DRAG_ACTION,
|
||||
counterclockwiseDragAction = DEFAULT_COUNTERCLOCKWISE_DRAG_ACTION,
|
||||
ghostKeysEnabled = DEFAULT_GHOST_KEYS_ENABLED,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import androidx.compose.material.icons.automirrored.outlined.Backspace
|
||||
import androidx.compose.material.icons.automirrored.outlined.RotateLeft
|
||||
import androidx.compose.material.icons.automirrored.outlined.RotateRight
|
||||
import androidx.compose.material.icons.outlined.Abc
|
||||
import androidx.compose.material.icons.outlined.BorderInner
|
||||
import androidx.compose.material.icons.outlined.Circle
|
||||
import androidx.compose.material.icons.outlined.SpaceBar
|
||||
import androidx.compose.material.icons.outlined.SwapHoriz
|
||||
@ -43,6 +44,7 @@ import com.dessalines.thumbkey.db.DEFAULT_CIRCULAR_DRAG_ENABLED
|
||||
import com.dessalines.thumbkey.db.DEFAULT_CLOCKWISE_DRAG_ACTION
|
||||
import com.dessalines.thumbkey.db.DEFAULT_COUNTERCLOCKWISE_DRAG_ACTION
|
||||
import com.dessalines.thumbkey.db.DEFAULT_DRAG_RETURN_ENABLED
|
||||
import com.dessalines.thumbkey.db.DEFAULT_GHOST_KEYS_ENABLED
|
||||
import com.dessalines.thumbkey.db.DEFAULT_MIN_SWIPE_LENGTH
|
||||
import com.dessalines.thumbkey.db.DEFAULT_SLIDE_BACKSPACE_DEADZONE_ENABLED
|
||||
import com.dessalines.thumbkey.db.DEFAULT_SLIDE_CURSOR_MOVEMENT_MODE
|
||||
@ -94,6 +96,7 @@ fun BehaviorActivity(
|
||||
var clockwiseDragActionState = CircularDragAction.entries[settings?.clockwiseDragAction ?: DEFAULT_CLOCKWISE_DRAG_ACTION]
|
||||
var counterclockwiseDragActionState =
|
||||
CircularDragAction.entries[settings?.counterclockwiseDragAction ?: DEFAULT_COUNTERCLOCKWISE_DRAG_ACTION]
|
||||
var ghostKeysEnabledState = (settings?.ghostKeysEnabled ?: DEFAULT_GHOST_KEYS_ENABLED).toBool()
|
||||
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
|
||||
@ -117,6 +120,7 @@ fun BehaviorActivity(
|
||||
circularDragEnabled = circularDragEnabledState.toInt(),
|
||||
clockwiseDragAction = clockwiseDragActionState.ordinal,
|
||||
counterclockwiseDragAction = counterclockwiseDragActionState.ordinal,
|
||||
ghostKeysEnabled = ghostKeysEnabledState.toInt(),
|
||||
),
|
||||
)
|
||||
}
|
||||
@ -381,6 +385,25 @@ fun BehaviorActivity(
|
||||
)
|
||||
},
|
||||
)
|
||||
SwitchPreference(
|
||||
value = ghostKeysEnabledState,
|
||||
onValueChange = {
|
||||
ghostKeysEnabledState = it
|
||||
updateBehavior()
|
||||
},
|
||||
title = {
|
||||
Text(stringResource(R.string.ghost_keys_enable))
|
||||
},
|
||||
summary = {
|
||||
Text(stringResource(R.string.ghost_keys_description))
|
||||
},
|
||||
icon = {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.BorderInner,
|
||||
contentDescription = stringResource(R.string.ghost_keys_enable),
|
||||
)
|
||||
},
|
||||
)
|
||||
SettingsDivider()
|
||||
TestOutTextField()
|
||||
}
|
||||
|
@ -85,4 +85,6 @@
|
||||
<string name="send_oppsite_case">Opposite case letter</string>
|
||||
<string name="send_numeric">Number key</string>
|
||||
<string name="circular_drag_enable">Circular drag</string>
|
||||
<string name="ghost_keys_enable">Ghost keys</string>
|
||||
<string name="ghost_keys_description">Access hidden symbol keys without switching to numeric view</string>
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user