@@ -47,13 +47,15 @@ import com.dessalines.thumbkey.utils.KeyAction
4747import com.dessalines.thumbkey.utils.KeyC
4848import com.dessalines.thumbkey.utils.KeyDisplay
4949import com.dessalines.thumbkey.utils.KeyItemC
50+ import com.dessalines.thumbkey.utils.Selection
5051import com.dessalines.thumbkey.utils.SlideType
5152import com.dessalines.thumbkey.utils.SwipeDirection
5253import com.dessalines.thumbkey.utils.buildTapActions
5354import com.dessalines.thumbkey.utils.colorVariantToColor
5455import com.dessalines.thumbkey.utils.doneKeyAction
5556import com.dessalines.thumbkey.utils.fontSizeVariantToFontSize
5657import com.dessalines.thumbkey.utils.performKeyAction
58+ import com.dessalines.thumbkey.utils.startSelection
5759import com.dessalines.thumbkey.utils.swipeDirection
5860import kotlin.math.abs
5961
@@ -106,6 +108,8 @@ fun KeyboardKey(
106108 var offsetX by remember { mutableFloatStateOf(0f ) }
107109 var offsetY by remember { mutableFloatStateOf(0f ) }
108110
111+ var selection by remember { mutableStateOf(Selection ()) }
112+
109113 val backgroundColor = if (! (isDragged.value || isPressed)) {
110114 colorVariantToColor(colorVariant = key.backgroundColor)
111115 } else {
@@ -183,18 +187,46 @@ fun KeyboardKey(
183187 offsetX + = x
184188 offsetY + = y
185189 if (key.slideType == SlideType .MOVE_CURSOR && slideEnabled) {
186- if (abs(offsetX) > slideSensitivity) {
190+ if (abs(offsetY) > slideSensitivity * 5 ) {
191+ // If user slides upwards, enable selection
192+ if (! selection.active) {
193+ // Activate selection
194+ selection = startSelection(ime)
195+ }
196+ if (abs(offsetX) > slideSensitivity) {
197+ if (offsetX < 0.00 ) {
198+ selection.left()
199+ } else {
200+ selection.right()
201+ }
202+ ime.currentInputConnection.setSelection(
203+ selection.start,
204+ selection.end,
205+ )
206+ offsetX = 0f
207+ }
208+ } else if (abs(offsetX) > slideSensitivity) {
209+ // If user slides horizontally only, move cursor
210+ if (selection.active) selection = Selection (0 , 0 , false )
187211 val direction: Int
188212 var shouldMove = false
189213 if (offsetX < 0.00 ) {
190214 // move left
191- if (ime.currentInputConnection.getTextBeforeCursor(1 , 0 )?.length != 0 ) {
215+ if (ime.currentInputConnection.getTextBeforeCursor(
216+ 1 ,
217+ 0 ,
218+ )?.length != 0
219+ ) {
192220 shouldMove = true
193221 }
194222 direction = KeyEvent .KEYCODE_DPAD_LEFT
195223 } else {
196224 // move right
197- if (ime.currentInputConnection.getTextAfterCursor(1 , 0 )?.length != 0 ) {
225+ if (ime.currentInputConnection.getTextAfterCursor(
226+ 1 ,
227+ 0 ,
228+ )?.length != 0
229+ ) {
198230 shouldMove = true
199231 }
200232 direction = KeyEvent .KEYCODE_DPAD_RIGHT
@@ -219,15 +251,37 @@ fun KeyboardKey(
219251 onSwitchPosition = onSwitchPosition,
220252 )
221253 }
254+ // reset offsetX, do not reset offsetY when sliding, it will break selecting
222255 offsetX = 0f
223- offsetY = 0f
256+ }
257+ } else if (key.slideType == SlideType .DELETE && slideEnabled) {
258+ if (! selection.active) {
259+ // Activate selection, first detection is longer to preserve swipe actions
260+ if (abs(offsetX) > slideSensitivity * 10 ) {
261+ selection = startSelection(ime)
262+ }
263+ } else {
264+ if (abs(offsetX) > slideSensitivity) {
265+ if (offsetX < 0.00 ) {
266+ selection.left()
267+ } else {
268+ selection.right()
269+ }
270+ ime.currentInputConnection.setSelection(
271+ selection.start,
272+ selection.end,
273+ )
274+ offsetX = 0f
275+ }
224276 }
225277 }
226278 },
227279 onDragEnd = {
228- if (key.slideType == SlideType .NONE || ! slideEnabled) {
229- val swipeDirection = swipeDirection(offsetX, offsetY, minSwipeLength, key.swipeType)
230- val action = key.swipes?.get(swipeDirection)?.action ? : key.center.action
280+ lateinit var action: KeyAction
281+ if (key.slideType == SlideType .NONE || ! slideEnabled || (key.slideType == SlideType .DELETE && ! selection.active)) {
282+ val swipeDirection =
283+ swipeDirection(offsetX, offsetY, minSwipeLength, key.swipeType)
284+ action = key.swipes?.get(swipeDirection)?.action ? : key.center.action
231285
232286 performKeyAction(
233287 action = action,
@@ -241,28 +295,72 @@ fun KeyboardKey(
241295 onSwitchLanguage = onSwitchLanguage,
242296 onSwitchPosition = onSwitchPosition,
243297 )
244- tapCount = 0
245- lastAction.value = action
246-
247- // Reset the drags
248- offsetX = 0f
249- offsetY = 0f
250-
251- doneKeyAction(scope, action, isDragged, releasedKey, animationHelperSpeed)
252- } else {
253298 doneKeyAction(
254299 scope,
255- KeyAction .SendEvent (
256- KeyEvent (
257- KeyEvent .ACTION_UP ,
258- KeyEvent .KEYCODE_DPAD_RIGHT ,
259- ),
300+ action,
301+ isDragged,
302+ releasedKey,
303+ animationHelperSpeed,
304+ )
305+ } else if (key.slideType == SlideType .DELETE ) {
306+ action = KeyAction .SendEvent (
307+ KeyEvent (
308+ KeyEvent .ACTION_DOWN ,
309+ KeyEvent
310+ .KEYCODE_DEL ,
260311 ),
312+ )
313+ // only delete if valid selection
314+ val sel = ime.currentInputConnection.getSelectedText(0 )
315+ sel?.let {
316+ if (it.isNotEmpty()) {
317+ performKeyAction(
318+ action = action,
319+ ime = ime,
320+ autoCapitalize = autoCapitalize,
321+ onToggleShiftMode = onToggleShiftMode,
322+ onToggleNumericMode = onToggleNumericMode,
323+ onToggleCapsLock = onToggleCapsLock,
324+ onAutoCapitalize = onAutoCapitalize,
325+ onSwitchLanguage = onSwitchLanguage,
326+ onSwitchPosition = onSwitchPosition,
327+ onToggleEmojiMode = onToggleEmojiMode,
328+ )
329+ }
330+ }
331+ doneKeyAction(
332+ scope,
333+ action,
334+ isDragged,
335+ releasedKey,
336+ animationHelperSpeed,
337+ )
338+ } else {
339+ action = KeyAction .SendEvent (
340+ KeyEvent (
341+ KeyEvent .ACTION_UP ,
342+ KeyEvent .KEYCODE_DPAD_RIGHT ,
343+ ),
344+ )
345+ doneKeyAction(
346+ scope,
347+ action,
261348 isDragged,
262349 releasedKey,
263350 animationHelperSpeed,
264351 )
265352 }
353+
354+ // Set tapCount and lastAction to avoid issues with multitap after slide
355+ tapCount = 0
356+ lastAction.value = action
357+
358+ // Reset the drags
359+ offsetX = 0f
360+ offsetY = 0f
361+
362+ // Reset selection
363+ selection = Selection ()
266364 },
267365 )
268366 }
@@ -373,7 +471,8 @@ fun KeyboardKey(
373471 ) {
374472 Box (
375473 contentAlignment = Alignment .Center ,
376- modifier = Modifier .fillMaxSize()
474+ modifier = Modifier
475+ .fillMaxSize()
377476 .background(color = MaterialTheme .colorScheme.tertiaryContainer),
378477 ) {}
379478 }
0 commit comments