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. 10
      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.PointerIcon
import androidx.compose.ui.input.pointer.pointerHoverIcon import androidx.compose.ui.input.pointer.pointerHoverIcon
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.WindowState
import androidx.compose.ui.window.singleWindowApplication import androidx.compose.ui.window.singleWindowApplication
import org.jetbrains.compose.splitpane.ExperimentalSplitPaneApi import org.jetbrains.compose.splitpane.ExperimentalSplitPaneApi
import org.jetbrains.compose.splitpane.HorizontalSplitPane import org.jetbrains.compose.splitpane.HorizontalSplitPane
@ -36,8 +38,12 @@ private fun Modifier.cursorForHorizontalResize(): Modifier =
@OptIn(ExperimentalSplitPaneApi::class) @OptIn(ExperimentalSplitPaneApi::class)
fun main() = singleWindowApplication( fun main() = singleWindowApplication(
state = WindowState(
size = DpSize(800.dp, 700.dp)
),
title = "SplitPane demo" title = "SplitPane demo"
) { ) {
MaterialTheme { MaterialTheme {
val splitterState = rememberSplitPaneState() val splitterState = rememberSplitPaneState()
val hSplitterState = rememberSplitPaneState() val hSplitterState = rememberSplitPaneState()
@ -53,6 +59,13 @@ fun main() = singleWindowApplication(
Text(if (hSplitterState.moveEnabled) "Freeze H" else "Unfreeze H") 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") }) OutlinedTextField(value = delta, onValueChange = { delta = it }, label = { Text("Delta") })
Button(onClick = { delta.toFloatOrNull()?.let { splitterState.dispatchRawMovement(it) } }) { Button(onClick = { delta.toFloatOrNull()?.let { splitterState.dispatchRawMovement(it) } }) {
Text("Add delta V") 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 @Composable
fun rememberSplitPaneState( fun rememberSplitPaneState(
initialPositionPercentage: Float = 0f, initialPositionPercentage: Float = 0f,
moveEnabled: Boolean = true moveEnabled: Boolean = true,
firstVisible: Boolean = true
): SplitPaneState { ): SplitPaneState {
return remember { return remember {
SplitPaneState( SplitPaneState(
moveEnabled = moveEnabled, moveEnabled = moveEnabled,
firstVisible = firstVisible,
initialPositionPercentage = initialPositionPercentage 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( class SplitPaneState(
initialPositionPercentage: Float, initialPositionPercentage: Float,
moveEnabled: Boolean, moveEnabled: Boolean,
firstVisible: Boolean = true
) { ) {
var moveEnabled by mutableStateOf(moveEnabled) var moveEnabled by mutableStateOf(moveEnabled)
var firstVisible by mutableStateOf(firstVisible)
private var _positionPercentage by mutableStateOf(initialPositionPercentage) private var _positionPercentage by mutableStateOf(initialPositionPercentage)
var positionPercentage: Float var positionPercentage: Float
get() = _positionPercentage get() = _positionPercentage

10
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) private fun Constraints.withUnconstrainedHeight() = copy(minHeight = 0, maxHeight = Constraints.Infinity)
@OptIn(ExperimentalSplitPaneApi::class)
@Composable @Composable
@OptIn(ExperimentalSplitPaneApi::class)
internal actual fun SplitPane( internal actual fun SplitPane(
modifier: Modifier, modifier: Modifier,
isHorizontal: Boolean, isHorizontal: Boolean,
@ -77,8 +77,10 @@ internal actual fun SplitPane(
minPosition = constrainedMin minPosition = constrainedMin
maxPosition = constrainedMax maxPosition = constrainedMax
val position = (constrainedMin * (1-positionPercentage) + constrainedMax * positionPercentage) val position =
.roundToInt() if (firstVisible) {
(constrainedMin * (1 - positionPercentage) + constrainedMax * positionPercentage).roundToInt()
} else 0
val firstPlaceable = firstMeasurable.measure( val firstPlaceable = firstMeasurable.measure(
if (isHorizontal) { 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 secondAvailableSize = (maxConstraintOnMainAxis - secondPlaceablePosition).coerceAtLeast(0)
val secondPlaceable = secondMeasurable.measure( val secondPlaceable = secondMeasurable.measure(

Loading…
Cancel
Save