Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement - Add more click options #73

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,53 @@ import androidx.compose.ui.semantics.SemanticsPropertyKey
import androidx.compose.ui.test.*
import io.github.kakaocup.compose.intercept.delegate.ComposeDelegate
import io.github.kakaocup.compose.intercept.operation.ComposeOperationType
import io.github.kakaocup.compose.node.action.extension.createOffset
import io.github.kakaocup.compose.node.action.option.ClickConfig
import io.github.kakaocup.compose.node.action.option.DoubleClickConfig
import io.github.kakaocup.compose.node.action.option.LongClickConfig
import io.github.kakaocup.compose.node.action.option.Offsets

interface NodeActions {
val delegate: ComposeDelegate

/**
* Performs a click action on the element represented by the given semantics node.
*/
fun performClick() {
delegate.perform(ComposeBaseActionType.PERFORM_CLICK) { performClick() }
fun performClick(offset: Offsets = Offsets.CENTER, config: ClickConfig? = null) {
delegate.perform(ComposeBaseActionType.PERFORM_CLICK) {
performTouchInput {
click(position = createOffset(offset, config?.xOffset, config?.yOffset))
}
}
}

/**
* Performs a double click action on the element represented by the given semantics node.
*/
fun performDoubleClick(offset: Offsets = Offsets.CENTER, config: DoubleClickConfig? = null) {
delegate.perform(ComposeBaseActionType.PERFORM_DOUBLE_CLICK) {
performTouchInput {
doubleClick(
delayMillis = config?.delayMs
?: ((viewConfiguration.doubleTapMinTimeMillis + viewConfiguration.doubleTapTimeoutMillis) / 2),
position = createOffset(offset, config?.xOffset, config?.yOffset)
)
}
}
}

/**
* Performs a long click action on the element represented by the given semantics node.
*/
fun performLongClick(offset: Offsets = Offsets.CENTER, config: LongClickConfig? = null) {
delegate.perform(ComposeBaseActionType.PERFORM_LONG_CLICK) {
performTouchInput {
longClick(
position = createOffset(offset, config?.xOffset, config?.yOffset),
durationMillis = config?.durationMs ?: viewConfiguration.longPressTimeoutMillis
)
}
}
}

/**
Expand Down Expand Up @@ -252,14 +290,23 @@ interface NodeActions {
delegate.perform(ComposeBaseActionType.PERFORM_SEMANTICS_ACTION) { performSemanticsAction(key) }
}

fun performImeAction() {
delegate.perform(ComposeBaseActionType.PERFORM_IME_ACTION) {
performImeAction()
}
}

enum class ComposeBaseActionType : ComposeOperationType {
PERFORM_CLICK,
PERFORM_DOUBLE_CLICK,
PERFORM_LONG_CLICK,
PERFORM_SCROLL_TO,
PERFORM_SCROLL_TO_INDEX,
PERFORM_SCROLL_TO_KEY,
PERFORM_SCROLL_TO_NODE,
PERFORM_GESTURE,
PERFORM_TOUCH_INPUT,
PERFORM_SEMANTICS_ACTION,
PERFORM_IME_ACTION
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.github.kakaocup.compose.node.action.extension

import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.test.TouchInjectionScope
import io.github.kakaocup.compose.node.action.option.Offsets

internal fun TouchInjectionScope.createOffset(
offset: Offsets,
offsetX: Float? = null,
offsetY: Float? = null
): Offset {
return when (offset) {
Offsets.CENTER -> center
Offsets.CENTER_LEFT -> centerLeft.copy(x = 1f)
Offsets.CENTER_RIGHT -> centerRight
Offsets.TOP_CENTER -> topCenter.copy(y = 1f)
Offsets.TOP_LEFT -> topLeft.copy(x = 1f, y = 1f)
Offsets.TOP_RIGHT -> topRight.copy(y = 1f)
Offsets.BOTTOM_CENTER -> bottomCenter
Offsets.BOTTOM_LEFT -> bottomLeft.copy(x = 1f)
Offsets.BOTTOM_RIGHT -> bottomRight
}.run {
copy(x = x + (offsetX ?: 0F), y = y + (offsetY ?: 0F))
}
Comment on lines +7 to +24
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applying offsetX offsetY to existing offset looks misleading to me. sealed class with default objects + data class will be more clear IMO

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package io.github.kakaocup.compose.node.action.option

data class ClickConfig(val xOffset: Float = 0F, val yOffset: Float = 0F)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.github.kakaocup.compose.node.action.option

data class DoubleClickConfig(
val xOffset: Float = 0F,
val yOffset: Float = 0F,
val delayMs: Long? = null
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delayMs can be a first argument in performDoubleClick with default value.

)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.github.kakaocup.compose.node.action.option

data class LongClickConfig(
val xOffset: Float = 0F,
val yOffset: Float = 0F,
val durationMs: Long? = null
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

durationMs can be a first argument in performLongClick with default value. In most cases devs will prefer to override this parameter.

)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.github.kakaocup.compose.node.action.option

enum class Offsets {
CENTER, CENTER_LEFT, CENTER_RIGHT,
TOP_CENTER, TOP_LEFT, TOP_RIGHT,
BOTTOM_CENTER, BOTTOM_LEFT, BOTTOM_RIGHT
}
Comment on lines +3 to +7
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think will be better to use sealed class with objects for default offsets + data class for custom offsets to avoid duplication in LongClickConfig DoubleClickConfig and ClickConfig. As well it will be more straight forward.