0
0
mirror of https://github.com/florisboard/florisboard.git synced 2024-09-20 03:52:18 +02:00

Merge pull request #218 from florisboard/fix-key-precise-swipe

Fix precise character deletion behaviour
This commit is contained in:
Patrick Goldinger 2021-01-21 18:33:16 +01:00 committed by GitHub
commit ef075151fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 93 additions and 74 deletions

View File

@ -26,6 +26,36 @@ import kotlin.math.*
* Wrapper class which holds all enums, interfaces and classes for detecting a swipe gesture.
*/
abstract class SwipeGesture {
companion object {
/**
* Returns a numeric value for a given [DistanceThreshold], based on the values defined in
* the resources dimens.xml file.
*/
fun numericValue(context: Context, of: DistanceThreshold): Double {
return when (of) {
DistanceThreshold.VERY_SHORT -> context.resources.getDimension(R.dimen.gesture_distance_threshold_very_short)
DistanceThreshold.SHORT -> context.resources.getDimension(R.dimen.gesture_distance_threshold_short)
DistanceThreshold.NORMAL -> context.resources.getDimension(R.dimen.gesture_distance_threshold_normal)
DistanceThreshold.LONG -> context.resources.getDimension(R.dimen.gesture_distance_threshold_long)
DistanceThreshold.VERY_LONG -> context.resources.getDimension(R.dimen.gesture_distance_threshold_very_long)
}.toDouble()
}
/**
* Returns a numeric value for a given [VelocityThreshold], based on the values defined in
* the resources dimens.xml file.
*/
fun numericValue(context: Context, of: VelocityThreshold): Double {
return when (of) {
VelocityThreshold.VERY_SLOW -> context.resources.getInteger(R.integer.gesture_velocity_threshold_very_slow)
VelocityThreshold.SLOW -> context.resources.getInteger(R.integer.gesture_velocity_threshold_slow)
VelocityThreshold.NORMAL -> context.resources.getInteger(R.integer.gesture_velocity_threshold_normal)
VelocityThreshold.FAST -> context.resources.getInteger(R.integer.gesture_velocity_threshold_fast)
VelocityThreshold.VERY_FAST -> context.resources.getInteger(R.integer.gesture_velocity_threshold_very_fast)
}.toDouble()
}
}
/**
* Class which detects swipes based on given [MotionEvent]s. Only supports single-finger swipes
* and ignores additional pointers provided, if any.
@ -50,14 +80,20 @@ abstract class SwipeGesture {
}
MotionEvent.ACTION_MOVE -> {
eventList.add(MotionEvent.obtainNoHistory(event))
val firstEvent = eventList[indexFirst]
val lastEvent = eventList[indexLastMoveRecognized]
val diffX = event.x - lastEvent.x
val diffY = event.y - lastEvent.y
val distanceThresholdNV = numericValue(distanceThreshold) / 4.0f
val distanceThresholdNV = numericValue(context, distanceThreshold) / 4.0f
return if (abs(diffX) > distanceThresholdNV || abs(diffY) > distanceThresholdNV) {
indexLastMoveRecognized = eventList.size - 1
val direction = detectDirection(diffX.toDouble(), diffY.toDouble())
listener.onSwipe(direction, Type.TOUCH_MOVE)
listener.onSwipe(Event(
direction = direction,
type = Type.TOUCH_MOVE,
diffX = event.x - firstEvent.x,
diffY = event.y - firstEvent.y
))
} else {
false
}
@ -67,7 +103,7 @@ abstract class SwipeGesture {
val firstEvent = eventList[indexFirst]
val diffX = event.x - firstEvent.x
val diffY = event.y - firstEvent.y
val distanceThresholdNV = numericValue(distanceThreshold)
val distanceThresholdNV = numericValue(context, distanceThreshold)
/*val velocityThresholdNV = numericValue(velocityThreshold)
val velocity =
((convertPixelsToDp(
@ -78,7 +114,12 @@ abstract class SwipeGesture {
// return if ((abs(diffX) > distanceThresholdNV || abs(diffY) > distanceThresholdNV) && velocity >= velocityThresholdNV) {
return if ((abs(diffX) > distanceThresholdNV || abs(diffY) > distanceThresholdNV)) {
val direction = detectDirection(diffX.toDouble(), diffY.toDouble())
listener.onSwipe(direction, Type.TOUCH_UP)
listener.onSwipe(Event(
direction = direction,
type = Type.TOUCH_UP,
diffX = diffX,
diffY = diffY
))
} else {
false
}
@ -144,38 +185,10 @@ abstract class SwipeGesture {
indexFirst = 0
indexLastMoveRecognized = 0
}
/**
* Returns a numeric value for a given [DistanceThreshold], based on the values defined in
* the resources dimens.xml file.
*/
private fun numericValue(of: DistanceThreshold): Double {
return when (of) {
DistanceThreshold.VERY_SHORT -> context.resources.getDimension(R.dimen.gesture_distance_threshold_very_short)
DistanceThreshold.SHORT -> context.resources.getDimension(R.dimen.gesture_distance_threshold_short)
DistanceThreshold.NORMAL -> context.resources.getDimension(R.dimen.gesture_distance_threshold_normal)
DistanceThreshold.LONG -> context.resources.getDimension(R.dimen.gesture_distance_threshold_long)
DistanceThreshold.VERY_LONG -> context.resources.getDimension(R.dimen.gesture_distance_threshold_very_long)
}.toDouble()
}
/**
* Returns a numeric value for a given [VelocityThreshold], based on the values defined in
* the resources dimens.xml file.
*/
private fun numericValue(of: VelocityThreshold): Double {
return when (of) {
VelocityThreshold.VERY_SLOW -> context.resources.getInteger(R.integer.gesture_velocity_threshold_very_slow)
VelocityThreshold.SLOW -> context.resources.getInteger(R.integer.gesture_velocity_threshold_slow)
VelocityThreshold.NORMAL -> context.resources.getInteger(R.integer.gesture_velocity_threshold_normal)
VelocityThreshold.FAST -> context.resources.getInteger(R.integer.gesture_velocity_threshold_fast)
VelocityThreshold.VERY_FAST -> context.resources.getInteger(R.integer.gesture_velocity_threshold_very_fast)
}.toDouble()
}
}
interface Listener {
fun onSwipe(direction: Direction, type: Type): Boolean
fun onSwipe(event: Event): Boolean
}
enum class Direction {
@ -189,6 +202,13 @@ abstract class SwipeGesture {
LEFT,
}
data class Event(
val direction: Direction,
val type: Type,
val diffX: Float,
val diffY: Float
)
enum class Type {
TOUCH_UP,
TOUCH_MOVE;

View File

@ -101,7 +101,7 @@ class KeyView(
private var themeValueCache: ThemeValueCache = ThemeValueCache()
var florisboard: FlorisBoard? = null
private val swipeGestureDetector = SwipeGesture.Detector(context, this)
val swipeGestureDetector = SwipeGesture.Detector(context, this)
var touchHitBox: Rect = Rect(-1, -1, -1, -1)
init {
@ -308,46 +308,32 @@ class KeyView(
* Swipe event handler. Listens to touch_move left/right swipes and triggers the swipe action
* defined in the prefs.
*/
override fun onSwipe(direction: SwipeGesture.Direction, type: SwipeGesture.Type): Boolean {
override fun onSwipe(event: SwipeGesture.Event): Boolean {
return when (data.code) {
KeyCode.DELETE -> when (type) {
SwipeGesture.Type.TOUCH_MOVE -> when (direction) {
SwipeGesture.Direction.LEFT -> when (prefs.gestures.deleteKeySwipeLeft) {
SwipeAction.DELETE_CHARACTERS_PRECISELY -> {
florisboard?.activeEditorInstance?.apply {
setSelection(
if (selection.start > 0) { selection.start - 1 } else { selection.start },
selection.end
)
}
hasTriggeredGestureMove = true
shouldBlockNextKeyCode = true
true
KeyCode.DELETE -> when (event.type) {
SwipeGesture.Type.TOUCH_MOVE -> when (prefs.gestures.deleteKeySwipeLeft) {
SwipeAction.DELETE_CHARACTERS_PRECISELY -> {
val charWidth = SwipeGesture.numericValue(context, swipeGestureDetector.distanceThreshold) / 4.0f
florisboard?.activeEditorInstance?.apply {
setSelection(
(selection.end - (event.diffX.times(-1) / charWidth).toInt()).coerceIn(0, selection.end),
selection.end
)
}
SwipeAction.DELETE_WORDS_PRECISELY -> {
hasTriggeredGestureMove = true
shouldBlockNextKeyCode = true
true
}
SwipeAction.DELETE_WORDS_PRECISELY -> when (event.direction) {
SwipeGesture.Direction.LEFT -> {
florisboard?.activeEditorInstance?.apply {
leftAppendWordToSelection()
}
hasTriggeredGestureMove = true
shouldBlockNextKeyCode = true
true
}
else -> false
}
SwipeGesture.Direction.RIGHT -> when (prefs.gestures.deleteKeySwipeLeft) {
SwipeAction.DELETE_CHARACTERS_PRECISELY -> {
florisboard?.activeEditorInstance?.apply {
setSelection(
if (selection.start < selection.end) { selection.start + 1 } else { selection.start },
selection.end
)
}
shouldBlockNextKeyCode = true
true
}
SwipeAction.DELETE_WORDS_PRECISELY -> {
SwipeGesture.Direction.RIGHT -> {
florisboard?.activeEditorInstance?.apply {
leftPopWordFromSelection()
}
@ -360,8 +346,8 @@ class KeyView(
}
else -> false
}
KeyCode.SPACE -> when (type) {
SwipeGesture.Type.TOUCH_MOVE -> when (direction) {
KeyCode.SPACE -> when (event.type) {
SwipeGesture.Type.TOUCH_MOVE -> when (event.direction) {
SwipeGesture.Direction.UP -> {
florisboard?.executeSwipeAction(prefs.gestures.spaceBarSwipeUp)
shouldBlockNextKeyCode = true

View File

@ -103,6 +103,7 @@ class KeyboardView : LinearLayout, FlorisBoard.EventListener, SwipeGesture.Liste
}
if (!isPreviewMode) {
themeManager.requestThemeUpdate(this)
onWindowShown()
} else {
updateVisibility()
}
@ -138,6 +139,18 @@ class KeyboardView : LinearLayout, FlorisBoard.EventListener, SwipeGesture.Liste
distanceThreshold = prefs.gestures.swipeDistanceThreshold
velocityThreshold = prefs.gestures.swipeVelocityThreshold
}
for (row in children) {
if (row is ViewGroup) {
for (keyView in row.children) {
if (keyView is KeyView) {
keyView.swipeGestureDetector.apply {
distanceThreshold = prefs.gestures.swipeDistanceThreshold
velocityThreshold = prefs.gestures.swipeVelocityThreshold
}
}
}
}
}
}
/**
@ -244,10 +257,10 @@ class KeyboardView : LinearLayout, FlorisBoard.EventListener, SwipeGesture.Liste
* Swipe event handler. Listens to touch_up swipes and executes the swipe action defined for it
* in the prefs.
*/
override fun onSwipe(direction: SwipeGesture.Direction, type: SwipeGesture.Type): Boolean {
override fun onSwipe(event: SwipeGesture.Event): Boolean {
return when {
initialKeyCode == KeyCode.DELETE -> {
if (type == SwipeGesture.Type.TOUCH_UP && direction == SwipeGesture.Direction.LEFT &&
if (event.type == SwipeGesture.Type.TOUCH_UP && event.direction == SwipeGesture.Direction.LEFT &&
prefs.gestures.deleteKeySwipeLeft == SwipeAction.DELETE_WORD) {
florisboard?.executeSwipeAction(prefs.gestures.deleteKeySwipeLeft)
true
@ -256,9 +269,9 @@ class KeyboardView : LinearLayout, FlorisBoard.EventListener, SwipeGesture.Liste
}
}
initialKeyCode > KeyCode.SPACE && !popupManager.isShowingExtendedPopup -> when {
!prefs.glide.enabled -> when (type) {
!prefs.glide.enabled -> when (event.type) {
SwipeGesture.Type.TOUCH_UP -> {
val swipeAction = when (direction) {
val swipeAction = when (event.direction) {
SwipeGesture.Direction.UP -> prefs.gestures.swipeUp
SwipeGesture.Direction.DOWN -> prefs.gestures.swipeDown
SwipeGesture.Direction.LEFT -> prefs.gestures.swipeLeft

View File

@ -26,7 +26,7 @@
<PreferenceCategory
app:iconSpaceReserved="false"
app:key="gestures"
app:key="general_gestures"
app:title="@string/pref__gestures__general_title">
<ListPreference
@ -73,7 +73,7 @@
<PreferenceCategory
app:iconSpaceReserved="false"
app:key="gestures"
app:key="space_bar_gestures"
app:title="@string/pref__gestures__space_bar_title">
<ListPreference
@ -116,7 +116,7 @@
<PreferenceCategory
app:iconSpaceReserved="false"
app:key="gestures"
app:key="other_gestures"
app:title="@string/pref__gestures__other_title">
<ListPreference