Browse Source

[SplitPane] Add ability to hide first pane

This commit adds the ability to hide the first pane in a SplitPane.

- Adds `firstVisible
` property to `SplitPaneState` to control the visibility of the first pane.
- Updates `SplitPane` layout to handle the visibility of the first pane.
- Adds buttons to the demo to toggle the visibility of the first pane.
pull/5051/head
Ahmed Hosny 5 months ago
parent
commit
68012ededa
  1. 13
      components/SplitPane/demo/src/jvmMain/kotlin/org/jetbrains/compose/splitpane/demo/Main.kt
  2. 4
      components/SplitPane/library/src/commonMain/kotlin/org/jetbrains/compose/splitpane/SplitPaneDSL.kt
  3. 3
      components/SplitPane/library/src/commonMain/kotlin/org/jetbrains/compose/splitpane/SplitPaneState.kt
  4. 12
      components/SplitPane/library/src/desktopMain/kotlin/org/jetbrains/compose/splitpane/DesktopSplitPane.kt

13
components/SplitPane/demo/src/jvmMain/kotlin/org/jetbrains/compose/splitpane/demo/Main.kt

@ -23,7 +23,9 @@ import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.input.pointer.PointerIcon
import androidx.compose.ui.input.pointer.pointerHoverIcon
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.WindowState
import androidx.compose.ui.window.singleWindowApplication
import org.jetbrains.compose.splitpane.ExperimentalSplitPaneApi
import org.jetbrains.compose.splitpane.HorizontalSplitPane
@ -36,8 +38,12 @@ private fun Modifier.cursorForHorizontalResize(): Modifier =
@OptIn(ExperimentalSplitPaneApi::class)
fun main() = singleWindowApplication(
state = WindowState(
size = DpSize(800.dp, 700.dp)
),
title = "SplitPane demo"
) {
MaterialTheme {
val splitterState = rememberSplitPaneState()
val hSplitterState = rememberSplitPaneState()
@ -53,6 +59,13 @@ fun main() = singleWindowApplication(
Text(if (hSplitterState.moveEnabled) "Freeze H" else "Unfreeze H")
}
Button(onClick = { splitterState.firstVisible = !splitterState.firstVisible }) {
Text(if (splitterState.firstVisible) "Hide V First" else "Show V First")
}
Button(onClick = { hSplitterState.firstVisible = !hSplitterState.firstVisible }) {
Text(if (hSplitterState.firstVisible) "Hide H First" else "Show H First")
}
OutlinedTextField(value = delta, onValueChange = { delta = it }, label = { Text("Delta") })
Button(onClick = { delta.toFloatOrNull()?.let { splitterState.dispatchRawMovement(it) } }) {
Text("Add delta V")

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

@ -183,11 +183,13 @@ internal class SplitPaneScopeImpl(
@Composable
fun rememberSplitPaneState(
initialPositionPercentage: Float = 0f,
moveEnabled: Boolean = true
moveEnabled: Boolean = true,
firstVisible: Boolean = true
): SplitPaneState {
return remember {
SplitPaneState(
moveEnabled = moveEnabled,
firstVisible = firstVisible,
initialPositionPercentage = initialPositionPercentage
)
}

3
components/SplitPane/library/src/commonMain/kotlin/org/jetbrains/compose/splitpane/SplitPaneState.kt

@ -8,10 +8,13 @@ import androidx.compose.runtime.setValue
class SplitPaneState(
initialPositionPercentage: Float,
moveEnabled: Boolean,
firstVisible: Boolean = true
) {
var moveEnabled by mutableStateOf(moveEnabled)
var firstVisible by mutableStateOf(firstVisible)
private var _positionPercentage by mutableStateOf(initialPositionPercentage)
var positionPercentage: Float
get() = _positionPercentage

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

@ -14,8 +14,8 @@ private fun Constraints.withUnconstrainedWidth() = copy(minWidth = 0, maxWidth =
private fun Constraints.withUnconstrainedHeight() = copy(minHeight = 0, maxHeight = Constraints.Infinity)
@OptIn(ExperimentalSplitPaneApi::class)
@Composable
@OptIn(ExperimentalSplitPaneApi::class)
internal actual fun SplitPane(
modifier: Modifier,
isHorizontal: Boolean,
@ -30,7 +30,7 @@ internal actual fun SplitPane(
second?.let { Box(modifier) { it() } }
return
}
Layout(
{
Box {
@ -77,8 +77,10 @@ internal actual fun SplitPane(
minPosition = constrainedMin
maxPosition = constrainedMax
val position = (constrainedMin * (1-positionPercentage) + constrainedMax * positionPercentage)
.roundToInt()
val position =
if (firstVisible) {
(constrainedMin * (1 - positionPercentage) + constrainedMax * positionPercentage).roundToInt()
} else 0
val firstPlaceable = firstMeasurable.measure(
if (isHorizontal) {
@ -94,7 +96,7 @@ internal actual fun SplitPane(
}
)
val secondPlaceablePosition = position + splitterSize
val secondPlaceablePosition = if (firstVisible) position + splitterSize else 0
val secondAvailableSize = (maxConstraintOnMainAxis - secondPlaceablePosition).coerceAtLeast(0)
val secondPlaceable = secondMeasurable.measure(

Loading…
Cancel
Save