diff --git a/components/SplitPane/demo/src/jvmMain/kotlin/org/jetbrains/compose/splitpane/demo/Main.kt b/components/SplitPane/demo/src/jvmMain/kotlin/org/jetbrains/compose/splitpane/demo/Main.kt index 226bb5c343..dd14048434 100644 --- a/components/SplitPane/demo/src/jvmMain/kotlin/org/jetbrains/compose/splitpane/demo/Main.kt +++ b/components/SplitPane/demo/src/jvmMain/kotlin/org/jetbrains/compose/splitpane/demo/Main.kt @@ -1,17 +1,34 @@ package org.jetbrains.compose.splitpane.demo import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material.Button import androidx.compose.material.MaterialTheme -import androidx.compose.runtime.* +import androidx.compose.material.OutlinedTextField +import androidx.compose.material.Text +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color 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.dp import androidx.compose.ui.window.singleWindowApplication -import org.jetbrains.compose.splitpane.* +import org.jetbrains.compose.splitpane.ExperimentalSplitPaneApi +import org.jetbrains.compose.splitpane.HorizontalSplitPane +import org.jetbrains.compose.splitpane.VerticalSplitPane +import org.jetbrains.compose.splitpane.rememberSplitPaneState import java.awt.Cursor private fun Modifier.cursorForHorizontalResize(): Modifier = @@ -24,40 +41,69 @@ fun main() = singleWindowApplication( MaterialTheme { val splitterState = rememberSplitPaneState() val hSplitterState = rememberSplitPaneState() - HorizontalSplitPane( - splitPaneState = splitterState - ) { - first(20.dp) { - Box(Modifier.background(Color.Red).fillMaxSize()) - } - second(50.dp) { - VerticalSplitPane(splitPaneState = hSplitterState) { - first(50.dp) { - Box(Modifier.background(Color.Blue).fillMaxSize()) - } - second(20.dp) { - Box(Modifier.background(Color.Green).fillMaxSize()) - } + var delta by remember { mutableStateOf("20") } + var percentage by remember { mutableStateOf("0.20") } + Row { + Column(verticalArrangement = Arrangement.spacedBy(10.dp), modifier = Modifier.padding(10.dp).width(180.dp)) { + Text("Action panel", fontWeight = FontWeight.Bold) + Button(onClick = { splitterState.moveEnabled = !splitterState.moveEnabled }) { + Text(if (splitterState.moveEnabled) "Freeze V" else "Unfreeze V") + } + Button(onClick = { hSplitterState.moveEnabled = !hSplitterState.moveEnabled }) { + Text(if (hSplitterState.moveEnabled) "Freeze H" else "Unfreeze H") + } + + OutlinedTextField(value = delta, onValueChange = { delta = it }, label = { Text("Delta") }) + Button(onClick = { delta.toFloatOrNull()?.let { splitterState.dispatchRawMovement(it) } }) { + Text("Add delta V") + } + Button(onClick = { delta.toFloatOrNull()?.let { hSplitterState.dispatchRawMovement(it) } }) { + Text("Add delta H") + } + + OutlinedTextField(value = percentage, onValueChange = { percentage = it }, label = { Text("Fraction") }) + Button(onClick = { percentage.toFloatOrNull()?.let { splitterState.positionPercentage = it } }) { + Text("Set fraction V") + } + Button(onClick = { percentage.toFloatOrNull()?.let { hSplitterState.positionPercentage = it } }) { + Text("Set fraction H") } } - splitter { - visiblePart { - Box( - Modifier - .width(1.dp) - .fillMaxHeight() - .background(MaterialTheme.colors.background) - ) + HorizontalSplitPane( + splitPaneState = splitterState + ) { + first(20.dp) { + Box(Modifier.background(Color.Red).fillMaxSize()) } - handle { - Box( - Modifier - .markAsHandle() - .cursorForHorizontalResize() - .background(SolidColor(Color.Gray), alpha = 0.50f) - .width(9.dp) - .fillMaxHeight() - ) + second(50.dp) { + VerticalSplitPane(splitPaneState = hSplitterState) { + first(50.dp) { + Box(Modifier.background(Color.Blue).fillMaxSize()) + } + second(20.dp) { + Box(Modifier.background(Color.Green).fillMaxSize()) + } + } + } + splitter { + visiblePart { + Box( + Modifier + .width(1.dp) + .fillMaxHeight() + .background(MaterialTheme.colors.background) + ) + } + handle { + Box( + Modifier + .markAsHandle() + .cursorForHorizontalResize() + .background(SolidColor(Color.Gray), alpha = 0.50f) + .width(9.dp) + .fillMaxHeight() + ) + } } } } diff --git a/components/SplitPane/library/src/commonMain/kotlin/org/jetbrains/compose/splitpane/SplitPaneState.kt b/components/SplitPane/library/src/commonMain/kotlin/org/jetbrains/compose/splitpane/SplitPaneState.kt index 6d9d8815c3..7bf1a10881 100644 --- a/components/SplitPane/library/src/commonMain/kotlin/org/jetbrains/compose/splitpane/SplitPaneState.kt +++ b/components/SplitPane/library/src/commonMain/kotlin/org/jetbrains/compose/splitpane/SplitPaneState.kt @@ -11,10 +11,18 @@ class SplitPaneState( ) { var moveEnabled by mutableStateOf(moveEnabled) - internal set - var positionPercentage by mutableStateOf(initialPositionPercentage) - internal set + private var _positionPercentage by mutableStateOf(initialPositionPercentage) + var positionPercentage: Float + get() = _positionPercentage + set(value) { + if (maxPosition == Float.POSITIVE_INFINITY) { + _positionPercentage = value + } else { + val movableArea = maxPosition - minPosition + _positionPercentage = (movableArea * value).coerceIn(0f, movableArea) / movableArea + } + } internal var minPosition: Float = 0f