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 10 months ago committed by GitHub
parent
commit
a8e9486b9e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 12
      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. 13
      components/SplitPane/library/src/desktopMain/kotlin/org/jetbrains/compose/splitpane/DesktopSplitter.kt

12
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.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
/** Receiver scope which is used by [HorizontalSplitPane] and [VerticalSplitPane] */
@ -83,15 +86,20 @@ interface SplitterScope {
internal class HandleScopeImpl(
private val containerScope: SplitPaneScopeImpl
) : HandleScope {
override fun Modifier.markAsHandle(): Modifier = this.pointerInput(containerScope.splitPaneState) {
override fun Modifier.markAsHandle(): Modifier = composed {
val layoutDirection = LocalLayoutDirection.current
pointerInput(containerScope.splitPaneState) {
detectDragGestures { change, _ ->
change.consume()
containerScope.splitPaneState.dispatchRawMovement(
if (containerScope.isHorizontal) change.position.x else change.position.y
if (containerScope.isHorizontal)
if (layoutDirection == LayoutDirection.Ltr) change.position.x else -change.position.x
else change.position.y
)
}
}
}
}
@OptIn(ExperimentalSplitPaneApi::class)
internal class SplitterScopeImpl(

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) {
firstPlaceable.place(0, 0)
firstPlaceable.placeRelative(0, 0)
if (isHorizontal) {
secondPlaceable.place(secondPlaceablePosition, 0)
splitterPlaceable.place(position, 0)
secondPlaceable.placeRelative(secondPlaceablePosition, 0)
splitterPlaceable.placeRelative(position, 0)
if (moveEnabled) {
handlePlaceable.place(handlePosition, 0)
handlePlaceable.placeRelative(handlePosition, 0)
}
} else {
secondPlaceable.place(0, secondPlaceablePosition)
splitterPlaceable.place(0, position)
secondPlaceable.placeRelative(0, secondPlaceablePosition)
splitterPlaceable.placeRelative(0, position)
if (moveEnabled) {
handlePlaceable.place(0, handlePosition)
handlePlaceable.placeRelative(0, handlePosition)
}
}
}

13
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.Modifier
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 java.awt.Cursor
@ -20,14 +22,19 @@ private fun DesktopHandle(
splitPaneState: SplitPaneState
) = Box(
Modifier
.pointerInput(splitPaneState) {
.run {
val layoutDirection = LocalLayoutDirection.current
pointerInput(splitPaneState) {
detectDragGestures { change, _ ->
change.consumeAllChanges()
change.consume()
splitPaneState.dispatchRawMovement(
if (isHorizontal) change.position.x else change.position.y
if (isHorizontal)
if (layoutDirection == LayoutDirection.Ltr) change.position.x else -change.position.x
else change.position.y
)
}
}
}
.cursorForHorizontalResize(isHorizontal)
.run {
if (isHorizontal) {

Loading…
Cancel
Save