Skip to content

Commit e607277

Browse files
committed
#1725 feat: action to move cursor to previous/next character, word, line, paragraph, or page.
1 parent a9da29d commit e607277

13 files changed

Lines changed: 233 additions & 57 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
- #1466 show onboarding when creating a key map for the first time
88
- #1729 target Android 16.
9+
- #1725 action to move cursor to previous/next character, word, line, paragraph, or page.
910

1011
## Changed
1112

base/src/main/java/io/github/sds100/keymapper/base/actions/ActionData.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -764,8 +764,16 @@ sealed class ActionData : Comparable<ActionData> {
764764
}
765765

766766
@Serializable
767-
data object MoveCursorToEnd : ActionData() {
768-
override val id = ActionId.MOVE_CURSOR_TO_END
767+
data class MoveCursor(val moveType: Type, val direction: Direction) : ActionData() {
768+
override val id = ActionId.MOVE_CURSOR
769+
770+
enum class Type {
771+
CHAR, WORD, LINE, PARAGRAPH, PAGE
772+
}
773+
774+
enum class Direction {
775+
START, END
776+
}
769777
}
770778

771779
@Serializable

base/src/main/java/io/github/sds100/keymapper/base/actions/ActionDataEntityMapper.kt

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ object ActionDataEntityMapper {
258258

259259
ActionId.VOLUME_INCREASE_STREAM,
260260
ActionId.VOLUME_DECREASE_STREAM,
261-
-> {
261+
-> {
262262
val stream =
263263
entity.extras.getData(ActionEntity.EXTRA_STREAM_TYPE).then {
264264
VOLUME_STREAM_MAP.getKey(it)!!.success()
@@ -283,7 +283,7 @@ object ActionDataEntityMapper {
283283
ActionId.VOLUME_TOGGLE_MUTE,
284284
ActionId.VOLUME_UNMUTE,
285285
ActionId.VOLUME_MUTE,
286-
-> {
286+
-> {
287287
val showVolumeUi =
288288
entity.flags.hasFlag(ActionEntity.ACTION_FLAG_SHOW_VOLUME_UI)
289289

@@ -304,7 +304,7 @@ object ActionDataEntityMapper {
304304
ActionId.TOGGLE_FLASHLIGHT,
305305
ActionId.ENABLE_FLASHLIGHT,
306306
ActionId.CHANGE_FLASHLIGHT_STRENGTH,
307-
-> {
307+
-> {
308308
val lens = entity.extras.getData(ActionEntity.EXTRA_LENS).then {
309309
LENS_MAP.getKey(it)!!.success()
310310
}.valueOrNull() ?: return null
@@ -330,7 +330,7 @@ object ActionDataEntityMapper {
330330
}
331331

332332
ActionId.DISABLE_FLASHLIGHT,
333-
-> {
333+
-> {
334334
val lens = entity.extras.getData(ActionEntity.EXTRA_LENS).then {
335335
LENS_MAP.getKey(it)!!.success()
336336
}.valueOrNull() ?: return null
@@ -339,7 +339,7 @@ object ActionDataEntityMapper {
339339

340340
ActionId.TOGGLE_DND_MODE,
341341
ActionId.ENABLE_DND_MODE,
342-
-> {
342+
-> {
343343
val dndMode = entity.extras.getData(ActionEntity.EXTRA_DND_MODE).then {
344344
DND_MODE_MAP.getKey(it)!!.success()
345345
}.valueOrNull() ?: return null
@@ -369,7 +369,7 @@ object ActionDataEntityMapper {
369369
ActionId.STOP_MEDIA_PACKAGE,
370370
ActionId.STEP_FORWARD_PACKAGE,
371371
ActionId.STEP_BACKWARD_PACKAGE,
372-
-> {
372+
-> {
373373
val packageName =
374374
entity.extras.getData(ActionEntity.EXTRA_PACKAGE_NAME).valueOrNull()
375375
?: return null
@@ -498,7 +498,6 @@ object ActionDataEntityMapper {
498498
ActionId.DISABLE_NFC -> ActionData.Nfc.Disable
499499
ActionId.TOGGLE_NFC -> ActionData.Nfc.Toggle
500500

501-
ActionId.MOVE_CURSOR_TO_END -> ActionData.MoveCursorToEnd
502501
ActionId.TOGGLE_KEYBOARD -> ActionData.ToggleKeyboard
503502
ActionId.SHOW_KEYBOARD -> ActionData.ShowKeyboard
504503
ActionId.HIDE_KEYBOARD -> ActionData.HideKeyboard
@@ -606,6 +605,39 @@ object ActionDataEntityMapper {
606605
nodeActions = actions,
607606
)
608607
}
608+
609+
ActionId.MOVE_CURSOR -> {
610+
// For compatibility with the old "Move cursor to the end" action.
611+
if (entity.extras.isEmpty()) {
612+
return ActionData.MoveCursor(
613+
moveType = ActionData.MoveCursor.Type.PAGE,
614+
ActionData.MoveCursor.Direction.END
615+
)
616+
}
617+
618+
val type =
619+
entity.extras.getData(ActionEntity.EXTRA_MOVE_CURSOR_TYPE).then { value ->
620+
when (value) {
621+
ActionEntity.CURSOR_TYPE_CHAR -> Success(ActionData.MoveCursor.Type.CHAR)
622+
ActionEntity.CURSOR_TYPE_WORD -> Success(ActionData.MoveCursor.Type.WORD)
623+
ActionEntity.CURSOR_TYPE_LINE -> Success(ActionData.MoveCursor.Type.LINE)
624+
ActionEntity.CURSOR_TYPE_PARAGRAPH -> Success(ActionData.MoveCursor.Type.PARAGRAPH)
625+
ActionEntity.CURSOR_TYPE_PAGE -> Success(ActionData.MoveCursor.Type.PAGE)
626+
else -> KMError.Exception(IllegalArgumentException("Unknown move cursor type: $value"))
627+
}
628+
}.valueOrNull() ?: return null
629+
630+
val direction =
631+
entity.extras.getData(ActionEntity.EXTRA_MOVE_CURSOR_DIRECTION).then { value ->
632+
when (value) {
633+
ActionEntity.CURSOR_DIRECTION_START -> Success(ActionData.MoveCursor.Direction.START)
634+
ActionEntity.CURSOR_DIRECTION_END -> Success(ActionData.MoveCursor.Direction.END)
635+
else -> KMError.Exception(IllegalArgumentException("Unknown move cursor direction: $value"))
636+
}
637+
}.valueOrNull() ?: return null
638+
639+
ActionData.MoveCursor(moveType = type, direction = direction)
640+
}
609641
}
610642
}
611643

@@ -918,6 +950,24 @@ object ActionDataEntityMapper {
918950
}
919951
}
920952

953+
is ActionData.MoveCursor -> buildList {
954+
val typeString = when (data.moveType) {
955+
ActionData.MoveCursor.Type.CHAR -> ActionEntity.CURSOR_TYPE_CHAR
956+
ActionData.MoveCursor.Type.WORD -> ActionEntity.CURSOR_TYPE_WORD
957+
ActionData.MoveCursor.Type.LINE -> ActionEntity.CURSOR_TYPE_LINE
958+
ActionData.MoveCursor.Type.PARAGRAPH -> ActionEntity.CURSOR_TYPE_PARAGRAPH
959+
ActionData.MoveCursor.Type.PAGE -> ActionEntity.CURSOR_TYPE_PAGE
960+
}
961+
add(EntityExtra(ActionEntity.EXTRA_MOVE_CURSOR_TYPE, typeString))
962+
963+
val directionString = when (data.direction) {
964+
ActionData.MoveCursor.Direction.START -> ActionEntity.CURSOR_DIRECTION_START
965+
ActionData.MoveCursor.Direction.END -> ActionEntity.CURSOR_DIRECTION_END
966+
}
967+
add(EntityExtra(ActionEntity.EXTRA_MOVE_CURSOR_DIRECTION, directionString))
968+
}
969+
970+
921971
else -> emptyList()
922972
}
923973

@@ -1051,7 +1101,9 @@ object ActionDataEntityMapper {
10511101
ActionId.DISABLE_NFC to "nfc_disable",
10521102
ActionId.TOGGLE_NFC to "nfc_toggle",
10531103

1054-
ActionId.MOVE_CURSOR_TO_END to "move_cursor_to_end",
1104+
// This action used to just move the cursor to the end. Do not change the
1105+
// id for compatibility reasons.
1106+
ActionId.MOVE_CURSOR to "move_cursor_to_end",
10551107
ActionId.TOGGLE_KEYBOARD to "toggle_keyboard",
10561108
ActionId.SHOW_KEYBOARD to "show_keyboard",
10571109
ActionId.HIDE_KEYBOARD to "hide_keyboard",

base/src/main/java/io/github/sds100/keymapper/base/actions/ActionId.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ enum class ActionId {
103103
TEXT_CUT,
104104
TEXT_COPY,
105105
TEXT_PASTE,
106-
MOVE_CURSOR_TO_END,
106+
MOVE_CURSOR,
107107
SELECT_WORD_AT_CURSOR,
108108
TOGGLE_KEYBOARD,
109109
SHOW_KEYBOARD,

base/src/main/java/io/github/sds100/keymapper/base/actions/ActionUiHelper.kt

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ class ActionUiHelper(
262262
R.string.action_toggle_front_flashlight_with_strength,
263263
action.strengthPercent.toPercentString(),
264264

265-
)
265+
)
266266
} else {
267267
getString(
268268
R.string.action_toggle_flashlight_with_strength,
@@ -492,7 +492,29 @@ class ActionUiHelper(
492492
ActionData.MobileData.Enable -> getString(R.string.action_enable_mobile_data)
493493
ActionData.MobileData.Toggle -> getString(R.string.action_toggle_mobile_data)
494494

495-
ActionData.MoveCursorToEnd -> getString(R.string.action_move_to_end_of_text)
495+
is ActionData.MoveCursor -> {
496+
when (action.direction) {
497+
ActionData.MoveCursor.Direction.START -> {
498+
when (action.moveType) {
499+
ActionData.MoveCursor.Type.CHAR -> getString(R.string.action_move_cursor_prev_character)
500+
ActionData.MoveCursor.Type.WORD -> getString(R.string.action_move_cursor_start_word)
501+
ActionData.MoveCursor.Type.LINE -> getString(R.string.action_move_cursor_start_line)
502+
ActionData.MoveCursor.Type.PARAGRAPH -> getString(R.string.action_move_cursor_start_paragraph)
503+
ActionData.MoveCursor.Type.PAGE -> getString(R.string.action_move_cursor_start_page)
504+
}
505+
}
506+
507+
ActionData.MoveCursor.Direction.END -> {
508+
when (action.moveType) {
509+
ActionData.MoveCursor.Type.CHAR -> getString(R.string.action_move_cursor_next_character)
510+
ActionData.MoveCursor.Type.WORD -> getString(R.string.action_move_cursor_end_word)
511+
ActionData.MoveCursor.Type.LINE -> getString(R.string.action_move_cursor_end_line)
512+
ActionData.MoveCursor.Type.PARAGRAPH -> getString(R.string.action_move_cursor_end_paragraph)
513+
ActionData.MoveCursor.Type.PAGE -> getString(R.string.action_move_cursor_end_page)
514+
}
515+
}
516+
}
517+
}
496518

497519
ActionData.Nfc.Disable -> getString(R.string.action_nfc_disable)
498520
ActionData.Nfc.Enable -> getString(R.string.action_nfc_enable)

0 commit comments

Comments
 (0)