Browse Source

Support Rtl in SplitPane (#4265)

This is related to issue:
https://github.com/JetBrains/compose-multiplatform/issues/4258

changes
- DesktopSplitPane.kt: placable.place() -> placable.placeRelative

- SplitePaneDSL.kt: change the delta direction to follow the layout
direction
```kotlin
 @Composable
    override fun Modifier.markAsHandle(): Modifier = this.run {
        val layoutDirection = LocalLayoutDirection.current
        pointerInput(containerScope.splitPaneState) {
            detectDragGestures { change, _ ->
                change.consume()
                containerScope.splitPaneState.dispatchRawMovement(
                    if (containerScope.isHorizontal)
                        if (layoutDirection == LayoutDirection.Ltr) change.position.x else -change.position.x
                    else change.position.y
                )
            }
        }
```

the problem with .onPointerEvent() Modifier, or onDrag also,  is
    whenever the layout direction is Ltr or Rtl:
moving to right always produce positive change, [expected negative if
dir =Rtl]
moving to left always produce negative change, [expected positive if dir
=Rtl]

the calculation of postion will fail if layoutDir is Rtl, because
positionPercentage will be out of range
```kotlin
fun dispatchRawMovement(delta: Float) {
        val movableArea = maxPosition - minPosition
        if (movableArea > 0) {
            positionPercentage =
                ((movableArea * positionPercentage) + delta).coerceIn(0f, movableArea) / movableArea
        }
    }
```
pull/4269/head
Ahmed Hosny 3 months ago committed by GitHub
parent
commit
a8e9486b9e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 20
      components/SplitPane/library/src/commonMain/kotlin/org/jetbrains/compose/splitpane/SplitPaneDSL.kt
  2. 14
      components/SplitPane/library/src/desktopMain/kotlin/org/jetbrains/compose/splitpane/DesktopSplitPane.kt
  3. 19
      components/SplitPane/library/src/desktopMain/kotlin/org/jetbrains/compose/splitpane/DesktopSplitter.kt

20
components/SplitPane/library/src/commonMain/kotlin/org/jetbrains/compose/splitpane/SplitPaneDSL.kt

@ -4,8 +4,11 @@ import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
/** Receiver scope which is used by [HorizontalSplitPane] and [VerticalSplitPane] */ /** Receiver scope which is used by [HorizontalSplitPane] and [VerticalSplitPane] */
@ -83,12 +86,17 @@ interface SplitterScope {
internal class HandleScopeImpl( internal class HandleScopeImpl(
private val containerScope: SplitPaneScopeImpl private val containerScope: SplitPaneScopeImpl
) : HandleScope { ) : HandleScope {
override fun Modifier.markAsHandle(): Modifier = this.pointerInput(containerScope.splitPaneState) { override fun Modifier.markAsHandle(): Modifier = composed {
detectDragGestures { change, _ -> val layoutDirection = LocalLayoutDirection.current
change.consume() pointerInput(containerScope.splitPaneState) {
containerScope.splitPaneState.dispatchRawMovement( detectDragGestures { change, _ ->
if (containerScope.isHorizontal) change.position.x else change.position.y change.consume()
) containerScope.splitPaneState.dispatchRawMovement(
if (containerScope.isHorizontal)
if (layoutDirection == LayoutDirection.Ltr) change.position.x else -change.position.x
else change.position.y
)
}
} }
} }
} }

14
components/SplitPane/library/src/desktopMain/kotlin/org/jetbrains/compose/splitpane/DesktopSplitPane.kt

@ -121,18 +121,18 @@ internal actual fun SplitPane(
} }
layout(constraints.maxWidth, constraints.maxHeight) { layout(constraints.maxWidth, constraints.maxHeight) {
firstPlaceable.place(0, 0) firstPlaceable.placeRelative(0, 0)
if (isHorizontal) { if (isHorizontal) {
secondPlaceable.place(secondPlaceablePosition, 0) secondPlaceable.placeRelative(secondPlaceablePosition, 0)
splitterPlaceable.place(position, 0) splitterPlaceable.placeRelative(position, 0)
if (moveEnabled) { if (moveEnabled) {
handlePlaceable.place(handlePosition, 0) handlePlaceable.placeRelative(handlePosition, 0)
} }
} else { } else {
secondPlaceable.place(0, secondPlaceablePosition) secondPlaceable.placeRelative(0, secondPlaceablePosition)
splitterPlaceable.place(0, position) splitterPlaceable.placeRelative(0, position)
if (moveEnabled) { if (moveEnabled) {
handlePlaceable.place(0, handlePosition) handlePlaceable.placeRelative(0, handlePosition)
} }
} }
} }

19
components/SplitPane/library/src/desktopMain/kotlin/org/jetbrains/compose/splitpane/DesktopSplitter.kt

@ -6,6 +6,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.input.pointer.* import androidx.compose.ui.input.pointer.*
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import java.awt.Cursor import java.awt.Cursor
@ -20,12 +22,17 @@ private fun DesktopHandle(
splitPaneState: SplitPaneState splitPaneState: SplitPaneState
) = Box( ) = Box(
Modifier Modifier
.pointerInput(splitPaneState) { .run {
detectDragGestures { change, _ -> val layoutDirection = LocalLayoutDirection.current
change.consumeAllChanges() pointerInput(splitPaneState) {
splitPaneState.dispatchRawMovement( detectDragGestures { change, _ ->
if (isHorizontal) change.position.x else change.position.y change.consume()
) splitPaneState.dispatchRawMovement(
if (isHorizontal)
if (layoutDirection == LayoutDirection.Ltr) change.position.x else -change.position.x
else change.position.y
)
}
} }
} }
.cursorForHorizontalResize(isHorizontal) .cursorForHorizontalResize(isHorizontal)

Loading…
Cancel
Save