Skip to content

Commit

Permalink
Merge pull request #1161 from pixel-shock/feature/pinch-gesture
Browse files Browse the repository at this point in the history
Feature: Add Pinch (in/out) support
  • Loading branch information
sds100 authored Oct 7, 2023
2 parents c5fd625 + 926ccde commit e145b75
Show file tree
Hide file tree
Showing 30 changed files with 1,213 additions and 85 deletions.
14 changes: 14 additions & 0 deletions app/src/main/java/io/github/sds100/keymapper/actions/ActionData.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.github.sds100.keymapper.actions

import io.github.sds100.keymapper.actions.pinchscreen.PinchScreenType
import io.github.sds100.keymapper.system.camera.CameraLens
import io.github.sds100.keymapper.system.display.Orientation
import io.github.sds100.keymapper.system.intents.IntentTarget
Expand Down Expand Up @@ -320,6 +321,19 @@ sealed class ActionData {
override val id = ActionId.SWIPE_SCREEN
}

@Serializable
data class PinchScreen(
val x: Int,
val y: Int,
val distance: Int,
val pinchType: PinchScreenType,
val fingerCount: Int,
val duration: Int,
val description: String?
) : ActionData() {
override val id = ActionId.PINCH_SCREEN
}

@Serializable
data class PhoneCall(
val number: String
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.github.sds100.keymapper.actions

import io.github.sds100.keymapper.actions.pinchscreen.PinchScreenType
import io.github.sds100.keymapper.data.entities.ActionEntity
import io.github.sds100.keymapper.data.entities.Extra
import io.github.sds100.keymapper.data.entities.getData
Expand Down Expand Up @@ -30,6 +31,7 @@ object ActionDataEntityMapper {
ActionEntity.Type.URL -> ActionId.URL
ActionEntity.Type.TAP_COORDINATE -> ActionId.TAP_SCREEN
ActionEntity.Type.SWIPE_COORDINATE -> ActionId.SWIPE_SCREEN
ActionEntity.Type.PINCH_COORDINATE -> ActionId.PINCH_SCREEN
ActionEntity.Type.INTENT -> ActionId.INTENT
ActionEntity.Type.PHONE_CALL -> ActionId.PHONE_CALL
ActionEntity.Type.SOUND -> ActionId.SOUND
Expand Down Expand Up @@ -149,6 +151,60 @@ object ActionDataEntityMapper {
)
}

ActionId.PINCH_SCREEN -> {
val splitData = entity.data.trim().split(',')

var x = 0
var y = 0
var pinchType = PinchScreenType.PINCH_IN
var distance = 0
var fingerCount = 2
var duration = 250

if (splitData.isNotEmpty()) {
x = splitData[0].trim().toInt()
}

if (splitData.size >= 2) {
y = splitData[1].trim().toInt()
}

if (splitData.size >= 3) {
distance = splitData[2].trim().toInt()
}

if (splitData.size >= 4) {
val tempType = splitData[3].trim()

pinchType = if (tempType == PinchScreenType.PINCH_IN.name) {
PinchScreenType.PINCH_IN
} else {
PinchScreenType.PINCH_OUT
}
}

if (splitData.size >= 5) {
fingerCount = splitData[4].trim().toInt().coerceAtLeast(2)
}

if (splitData.size >= 6) {
duration = splitData[5].trim().toInt()
}

val description = entity.extras.getData(ActionEntity.EXTRA_COORDINATE_DESCRIPTION)
.valueOrNull()

ActionData.PinchScreen(
x = x,
y = y,
distance = distance,
pinchType = pinchType,
fingerCount = fingerCount,
duration = duration,
description = description
)
}

ActionId.INTENT -> {
val target = entity.extras.getData(ActionEntity.EXTRA_INTENT_TARGET).then {
INTENT_TARGET_MAP.getKey(it).success()
Expand Down Expand Up @@ -424,6 +480,7 @@ object ActionDataEntityMapper {
is ActionData.PhoneCall -> ActionEntity.Type.PHONE_CALL
is ActionData.TapScreen -> ActionEntity.Type.TAP_COORDINATE
is ActionData.SwipeScreen -> ActionEntity.Type.SWIPE_COORDINATE
is ActionData.PinchScreen -> ActionEntity.Type.PINCH_COORDINATE
is ActionData.Text -> ActionEntity.Type.TEXT_BLOCK
is ActionData.Url -> ActionEntity.Type.URL
is ActionData.Sound -> ActionEntity.Type.SOUND
Expand Down Expand Up @@ -464,6 +521,7 @@ object ActionDataEntityMapper {
is ActionData.PhoneCall -> data.number
is ActionData.TapScreen -> "${data.x},${data.y}"
is ActionData.SwipeScreen -> "${data.xStart},${data.yStart},${data.xEnd},${data.yEnd},${data.fingerCount},${data.duration}"
is ActionData.PinchScreen -> "${data.x},${data.y},${data.distance},${data.pinchType},${data.fingerCount},${data.duration}"
is ActionData.Text -> data.text
is ActionData.Url -> data.url
is ActionData.Sound -> data.soundUid
Expand Down Expand Up @@ -562,6 +620,12 @@ object ActionDataEntityMapper {
}
}.toList()

is ActionData.PinchScreen -> sequence {
if (!data.description.isNullOrBlank()) {
yield(Extra(ActionEntity.EXTRA_COORDINATE_DESCRIPTION, data.description))
}
}.toList()

is ActionData.Text -> emptyList()
is ActionData.Url -> emptyList()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ enum class ActionId {
KEY_EVENT,
TAP_SCREEN,
SWIPE_SCREEN,
PINCH_SCREEN,
TEXT,
URL,
INTENT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ object ActionUtils {
ActionId.KEY_EVENT -> ActionCategory.INPUT
ActionId.TAP_SCREEN -> ActionCategory.INPUT
ActionId.SWIPE_SCREEN -> ActionCategory.INPUT
ActionId.PINCH_SCREEN -> ActionCategory.INPUT
ActionId.TEXT -> ActionCategory.INPUT

ActionId.OPEN_VOICE_ASSISTANT -> ActionCategory.APPS
Expand Down Expand Up @@ -257,6 +258,7 @@ object ActionUtils {
ActionId.KEY_EVENT -> R.string.action_input_key_event
ActionId.TAP_SCREEN -> R.string.action_tap_screen
ActionId.SWIPE_SCREEN -> R.string.action_swipe_screen
ActionId.PINCH_SCREEN -> R.string.action_pinch_screen
ActionId.TEXT -> R.string.action_input_text
ActionId.URL -> R.string.action_open_url
ActionId.INTENT -> R.string.action_send_intent
Expand Down Expand Up @@ -366,7 +368,8 @@ object ActionUtils {
ActionId.KEY_CODE -> R.drawable.ic_q_24
ActionId.KEY_EVENT -> R.drawable.ic_q_24
ActionId.TAP_SCREEN -> R.drawable.ic_outline_touch_app_24
ActionId.SWIPE_SCREEN -> R.drawable.ic_outline_touch_app_24
ActionId.SWIPE_SCREEN -> R.drawable.ic_outline_swipe_app_24
ActionId.PINCH_SCREEN -> R.drawable.ic_outline_pinch_app_24
ActionId.TEXT -> R.drawable.ic_outline_short_text_24
ActionId.URL -> R.drawable.ic_outline_link_24
ActionId.INTENT -> null
Expand Down Expand Up @@ -604,6 +607,7 @@ fun ActionData.isEditable(): Boolean = when (this) {
is ActionData.Flashlight.Disable,
is ActionData.TapScreen,
is ActionData.SwipeScreen,
is ActionData.PinchScreen,
is ActionData.Text,
is ActionData.Url,
is ActionData.PhoneCall,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.github.sds100.keymapper.actions

import android.view.KeyEvent
import io.github.sds100.keymapper.R
import io.github.sds100.keymapper.actions.pinchscreen.PinchScreenType
import io.github.sds100.keymapper.mappings.DisplayActionUseCase
import io.github.sds100.keymapper.mappings.Mapping
import io.github.sds100.keymapper.system.camera.CameraLensUtils
Expand Down Expand Up @@ -318,6 +319,45 @@ abstract class BaseActionUiHelper<MAPPING : Mapping<A>, A : Action>(
)
}

is ActionData.PinchScreen -> if (action.description.isNullOrBlank()) {
val pinchTypeDisplayName = if (action.pinchType == PinchScreenType.PINCH_IN) {
getString(R.string.hint_coordinate_type_pinch_in)
} else {
getString(R.string.hint_coordinate_type_pinch_out)
}

getString(
R.string.description_pinch_coordinate_default,
arrayOf(
pinchTypeDisplayName,
action.fingerCount,
action.x,
action.y,
action.distance,
action.duration
)
)
} else {
val pinchTypeDisplayName = if (action.pinchType == PinchScreenType.PINCH_IN) {
getString(R.string.hint_coordinate_type_pinch_in)
} else {
getString(R.string.hint_coordinate_type_pinch_out)
}

getString(
R.string.description_pinch_coordinate_with_description,
arrayOf(
pinchTypeDisplayName,
action.fingerCount,
action.x,
action.y,
action.distance,
action.duration,
action.description
)
)
}

is ActionData.Text -> getString(R.string.description_text_block, action.text)
is ActionData.Url -> getString(R.string.description_url, action.url)
is ActionData.Sound -> getString(R.string.description_sound, action.soundDescription)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.github.sds100.keymapper.actions

import android.text.InputType
import io.github.sds100.keymapper.R
import io.github.sds100.keymapper.actions.pinchscreen.PinchPickCoordinateResult
import io.github.sds100.keymapper.actions.swipescreen.SwipePickCoordinateResult
import io.github.sds100.keymapper.actions.tapscreen.PickCoordinateResult
import io.github.sds100.keymapper.system.camera.CameraLens
Expand Down Expand Up @@ -371,6 +372,43 @@ class CreateActionViewModelImpl(
)
}

ActionId.PINCH_SCREEN -> {
val oldResult = if (oldData is ActionData.PinchScreen) {
PinchPickCoordinateResult(
oldData.x,
oldData.y,
oldData.distance,
oldData.pinchType,
oldData.fingerCount,
oldData.duration,
oldData.description ?: ""
)
} else {
null
}

val result = navigate(
"pick_pinch_coordinate_for_action",
NavDestination.PickPinchCoordinate(oldResult)
) ?: return null

val description = if (result.description.isEmpty()) {
null
} else {
result.description
}

return ActionData.PinchScreen(
result.x,
result.y,
result.distance,
result.pinchType,
result.fingerCount,
result.duration,
description
)
}

ActionId.TEXT -> {
val oldText = if (oldData is ActionData.Text) {
oldData.text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,18 @@ class PerformActionsUseCaseImpl(
)
}

is ActionData.PinchScreen -> {
result = accessibilityService.pinchScreen(
action.x,
action.y,
action.distance,
action.pinchType,
action.fingerCount,
action.duration,
inputEventType
)
}

is ActionData.Text -> {
keyMapperImeMessenger.inputText(action.text)
result = Success(Unit)
Expand Down
Loading

0 comments on commit e145b75

Please sign in to comment.