Skip to content

Commit

Permalink
LTR/RTL in PredictiveBackGestureOverlay
Browse files Browse the repository at this point in the history
(cherry picked from commit 086ba11)
  • Loading branch information
arkivanov committed Nov 25, 2023
1 parent 20a27b1 commit 5a4939c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ public final class com/arkivanov/decompose/extensions/compose/jetbrains/Predicti
}

public final class com/arkivanov/decompose/extensions/compose/jetbrains/PredictiveBackGestureOverlayKt {
public static final fun PredictiveBackGestureOverlay (Lcom/arkivanov/essenty/backhandler/BackDispatcher;Lkotlin/jvm/functions/Function4;Landroidx/compose/ui/Modifier;Ljava/util/Set;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V
public static final fun PredictiveBackGestureOverlay (Lcom/arkivanov/essenty/backhandler/BackDispatcher;Lkotlin/jvm/functions/Function4;Landroidx/compose/ui/Modifier;ZZLkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V
}

public final class com/arkivanov/decompose/extensions/compose/jetbrains/SubscribeAsStateKt {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ import androidx.compose.ui.input.pointer.PointerEventPass
import androidx.compose.ui.input.pointer.PointerInputChange
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.layout
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import com.arkivanov.decompose.ExperimentalDecomposeApi
import com.arkivanov.essenty.backhandler.BackCallback
Expand All @@ -35,8 +37,10 @@ import com.arkivanov.essenty.backhandler.BackEvent.SwipeEdge
* @param backIcon an icon to be shown while the gesture is being performed. A default icon can be shown
* using [PredictiveBackGestureIcon].
* @param modifier a [Modifier] to applied to the overlay.
* @param swipeEdges a [Set] of [SwipeEdge] where swipe gestures can be detected. Absolute, e.g. RTL mode
* should be handled manually.
* @param startEdgeEnabled controls whether the start edge is enabled or not,
* left in RTL mode and right in LTR mode.
* @param endEdgeEnabled controls whether the end edge is enabled or not,
* right in RTL mode and left in LTR mode.
* @param onClose If supplied, then the back gesture is also handled when there are no other enabled back
* callbacks registered in [backDispatcher], can be used to close the application.
* @param content a content to be shown under the overlay.
Expand All @@ -47,16 +51,25 @@ fun PredictiveBackGestureOverlay(
backDispatcher: BackDispatcher,
backIcon: (@Composable (progress: Float, edge: SwipeEdge) -> Unit)?,
modifier: Modifier = Modifier,
swipeEdges: Set<SwipeEdge> = setOf(SwipeEdge.LEFT, SwipeEdge.RIGHT),
startEdgeEnabled: Boolean = true,
endEdgeEnabled: Boolean = true,
onClose: (() -> Unit)? = null,
content: @Composable () -> Unit,
) {
val iconState: MutableState<IconState> = remember { mutableStateOf(IconState()) }
val layoutDirection = LocalLayoutDirection.current

Box(
modifier = modifier.handleBackGestures(
backDispatcher = backDispatcher,
swipeEdges = swipeEdges,
leftEdgeEnabled = when (layoutDirection) {
LayoutDirection.Ltr -> startEdgeEnabled
LayoutDirection.Rtl -> endEdgeEnabled
},
rightEdgeEnabled = when (layoutDirection) {
LayoutDirection.Ltr -> endEdgeEnabled
LayoutDirection.Rtl -> startEdgeEnabled
},
onIconMoved = { position, progress, edge ->
iconState.value =
IconState(
Expand Down Expand Up @@ -95,19 +108,20 @@ fun PredictiveBackGestureOverlay(

private fun Modifier.handleBackGestures(
backDispatcher: BackDispatcher,
swipeEdges: Set<SwipeEdge>,
leftEdgeEnabled: Boolean,
rightEdgeEnabled: Boolean,
onIconMoved: (position: Offset, progress: Float, BackGestureHandler.Edge) -> Unit,
onIconHidden: () -> Unit,
): Modifier =
pointerInput(backDispatcher, swipeEdges) {
pointerInput(backDispatcher, leftEdgeEnabled, rightEdgeEnabled) {
awaitEachGesture {
onIconHidden()

val down = awaitFirstDown(pass = PointerEventPass.Initial)
val startPosition = down.position

val isLeftInvalid = (SwipeEdge.LEFT !in swipeEdges) || (startPosition.x > 16.dp.toPx())
val isRightInvalid = (SwipeEdge.RIGHT !in swipeEdges) || (startPosition.x < size.width - 16.dp.toPx())
val isLeftInvalid = !leftEdgeEnabled || (startPosition.x > 16.dp.toPx())
val isRightInvalid = !rightEdgeEnabled || (startPosition.x < size.width - 16.dp.toPx())

if (isLeftInvalid && isRightInvalid) {
return@awaitEachGesture
Expand Down

0 comments on commit 5a4939c

Please sign in to comment.