Skip to content

Commit

Permalink
New SplitLayout (#570)
Browse files Browse the repository at this point in the history
* replace SplitLayout

Signed-off-by: Ivan Morgillo <[email protected]>

* add splitlayout icon

Signed-off-by: Ivan Morgillo <[email protected]>

* add SplitLayout icon to the collection

Signed-off-by: Ivan Morgillo <[email protected]>

* create the SplitLayouts showcase in the Standalone

Signed-off-by: Ivan Morgillo <[email protected]>

* make it uglier but now the linter is happy

Signed-off-by: Ivan Morgillo <[email protected]>

* hoist the SplitLayout divider state

Signed-off-by: Ivan Morgillo <[email protected]>

* remove nested layout from SplitLayouts showcase

Signed-off-by: Ivan Morgillo <[email protected]>

* add responsive minimum width to SplitLayout

Signed-off-by: Ivan Morgillo <[email protected]>

* make the linter happy

Signed-off-by: Ivan Morgillo <[email protected]>

* iterate on SplitLayout icon

Signed-off-by: Ivan Morgillo <[email protected]>

* fix NaN operation in calculateAdjustedSizes()

Signed-off-by: Ivan Morgillo <[email protected]>

* iterate on SplitLayout draggable

Signed-off-by: Ivan Morgillo <[email protected]>

* replace a whens with ifs

Signed-off-by: Ivan Morgillo <[email protected]>

* iterate on draggable divider

Signed-off-by: Ivan Morgillo <[email protected]>

* tune the pointer icon while dragging

Signed-off-by: Ivan Morgillo <[email protected]>

* make the linter happy

Signed-off-by: Ivan Morgillo <[email protected]>

* add min width to SplitLayout in IDE sample

Signed-off-by: Ivan Morgillo <[email protected]>

* fix wrong params in SplitLayouts

reference: #570 (comment)
Signed-off-by: Ivan Morgillo <[email protected]>

* name params consistently in SplitLayout

reference: #570 (comment)
Signed-off-by: Ivan Morgillo <[email protected]>

* add missing KDOC

reference: #570 (comment)
Signed-off-by: Ivan Morgillo <[email protected]>

* add missing KDOC to public API

reference: #570 (comment)
Signed-off-by: Ivan Morgillo <[email protected]>

* remove redundant value

reference: #570 (comment)
Signed-off-by: Ivan Morgillo <[email protected]>

* inlined variable

reference: #570 (comment)
Signed-off-by: Ivan Morgillo <[email protected]>

* extract draggableState variable

reference: #570 (comment)
Signed-off-by: Ivan Morgillo <[email protected]>

* rename maxPositionPx

reference: #570 (comment)
Signed-off-by: Ivan Morgillo <[email protected]>

* simplify pointer icon management

reference: #570 (comment)
Signed-off-by: Ivan Morgillo <[email protected]>

* rename fillModifier

reference: #570 (comment)
Signed-off-by: Ivan Morgillo <[email protected]>

* remove redundant .then()

reference: #570 (comment)
Signed-off-by: Ivan Morgillo <[email protected]>

* add -Px suffix to a couple of values

reference: #570 (comment)
Signed-off-by: Ivan Morgillo <[email protected]>

* extract a couple of methods

reference: #570 (comment)
Signed-off-by: Ivan Morgillo <[email protected]>

* moved values into doLayout()

reference: #570 (comment)
Signed-off-by: Ivan Morgillo <[email protected]>

* iterate on windows resizing

Signed-off-by: Ivan Morgillo <[email protected]>

* iterate once more on divider positioning while dragging

Signed-off-by: Ivan Morgillo <[email protected]>

* Fix formatting

---------

Signed-off-by: Ivan Morgillo <[email protected]>
Co-authored-by: Sebastiano Poggi <[email protected]>
  • Loading branch information
hamen and rock3r authored Sep 6, 2024
1 parent 2a13606 commit 5efee37
Show file tree
Hide file tree
Showing 8 changed files with 606 additions and 185 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,18 +94,17 @@ import org.jetbrains.jewel.ui.util.thenIf
fun ReleasesSampleCompose(project: Project) {
var selectedItem: ContentItem? by remember { mutableStateOf(null) }
HorizontalSplitLayout(
first = { modifier ->
first = {
LeftColumn(
project = project,
modifier = modifier.fillMaxSize(),
modifier = Modifier.fillMaxSize(),
onSelectedItemChange = { selectedItem = it },
)
},
second = { modifier -> RightColumn(selectedItem = selectedItem, modifier = modifier.fillMaxSize()) },
Modifier.fillMaxSize(),
initialDividerPosition = 400.dp,
minRatio = .15f,
maxRatio = .7f,
second = { RightColumn(selectedItem = selectedItem, modifier = Modifier.fillMaxSize()) },
modifier = Modifier.fillMaxSize(),
firstPaneMinWidth = 300.dp,
secondPaneMinWidth = 300.dp,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ object StandaloneSampleIcons {
val scrollbar = PathIconKey("icons/components/scrollbar.svg", StandaloneSampleIcons::class.java)
val segmentedControls = PathIconKey("icons/components/segmentedControl.svg", StandaloneSampleIcons::class.java)
val slider = PathIconKey("icons/components/slider.svg", StandaloneSampleIcons::class.java)
val splitlayout = PathIconKey("icons/components/splitLayout.svg", StandaloneSampleIcons::class.java)
val tabs = PathIconKey("icons/components/tabs.svg", StandaloneSampleIcons::class.java)
val textArea = PathIconKey("icons/components/textArea.svg", StandaloneSampleIcons::class.java)
val textField = PathIconKey("icons/components/textField.svg", StandaloneSampleIcons::class.java)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.text.input.TextFieldState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import org.jetbrains.jewel.foundation.theme.JewelTheme
import org.jetbrains.jewel.ui.component.HorizontalSplitLayout
import org.jetbrains.jewel.ui.component.OutlinedButton
import org.jetbrains.jewel.ui.component.SplitLayoutState
import org.jetbrains.jewel.ui.component.Text
import org.jetbrains.jewel.ui.component.TextField
import org.jetbrains.jewel.ui.component.VerticalSplitLayout

@Composable
fun SplitLayouts(
outerSplitState: SplitLayoutState,
verticalSplitState: SplitLayoutState,
innerSplitState: SplitLayoutState,
onResetState: () -> Unit,
) {
Column(Modifier.fillMaxSize()) {
Row(verticalAlignment = Alignment.CenterVertically) {
Text("Reset split state:")
Spacer(Modifier.width(8.dp))
OutlinedButton(onClick = onResetState) { Text("Reset") }
}

Spacer(Modifier.height(16.dp))

HorizontalSplitLayout(
state = outerSplitState,
first = { FirstPane() },
second = { SecondPane(innerSplitState = innerSplitState, verticalSplitState = verticalSplitState) },
modifier = Modifier.fillMaxWidth().weight(1f).border(1.dp, color = JewelTheme.globalColors.borders.normal),
firstPaneMinWidth = 300.dp,
secondPaneMinWidth = 200.dp,
)
}
}

@Composable
private fun FirstPane() {
Box(modifier = Modifier.fillMaxSize().padding(16.dp), contentAlignment = Alignment.Center) {
val state by remember { mutableStateOf(TextFieldState()) }
TextField(state, placeholder = { Text("Placeholder") })
}
}

@Composable
private fun SecondPane(innerSplitState: SplitLayoutState, verticalSplitState: SplitLayoutState) {
VerticalSplitLayout(
state = verticalSplitState,
modifier = Modifier.fillMaxSize(),
first = {
val state by remember { mutableStateOf(TextFieldState()) }
Box(Modifier.fillMaxSize().padding(16.dp), contentAlignment = Alignment.Center) {
TextField(state, placeholder = { Text("Right Panel Content") })
}
},
second = {
HorizontalSplitLayout(
first = {
Box(Modifier.fillMaxSize().padding(16.dp), contentAlignment = Alignment.Center) {
Text("Second Pane left")
}
},
second = {
Box(Modifier.fillMaxSize().padding(16.dp), contentAlignment = Alignment.Center) {
Text("Second Pane right")
}
},
modifier = Modifier.fillMaxSize(),
state = innerSplitState,
firstPaneMinWidth = 100.dp,
secondPaneMinWidth = 100.dp,
)
},
firstPaneMinWidth = 300.dp,
secondPaneMinWidth = 100.dp,
)
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package org.jetbrains.jewel.samples.standalone.viewmodel

import SplitLayouts
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.SnapshotStateList
import org.jetbrains.jewel.samples.standalone.StandaloneSampleIcons
import org.jetbrains.jewel.samples.standalone.view.component.Borders
import org.jetbrains.jewel.samples.standalone.view.component.Buttons
Expand All @@ -21,49 +23,78 @@ import org.jetbrains.jewel.samples.standalone.view.component.Tabs
import org.jetbrains.jewel.samples.standalone.view.component.TextAreas
import org.jetbrains.jewel.samples.standalone.view.component.TextFields
import org.jetbrains.jewel.samples.standalone.view.component.Tooltips
import org.jetbrains.jewel.ui.component.SplitLayoutState

object ComponentsViewModel {
val views = componentsMenuItems
private var outerSplitState by mutableStateOf(SplitLayoutState(0.5f))
private var verticalSplitState by mutableStateOf(SplitLayoutState(0.5f))
private var innerSplitState by mutableStateOf(SplitLayoutState(0.5f))

val views: SnapshotStateList<ViewInfo> =
mutableStateListOf(
ViewInfo(title = "Buttons", iconKey = StandaloneSampleIcons.Components.button, content = { Buttons() }),
ViewInfo(
title = "Radio Buttons",
iconKey = StandaloneSampleIcons.Components.radioButton,
content = { RadioButtons() },
),
ViewInfo(
title = "Checkboxes",
iconKey = StandaloneSampleIcons.Components.checkbox,
content = { Checkboxes() },
),
ViewInfo(
title = "Dropdowns",
iconKey = StandaloneSampleIcons.Components.comboBox,
content = { Dropdowns() },
),
ViewInfo(
title = "Chips and trees",
iconKey = StandaloneSampleIcons.Components.tree,
content = { ChipsAndTrees() },
),
ViewInfo(
title = "Progressbar",
iconKey = StandaloneSampleIcons.Components.progressBar,
content = { ProgressBar() },
),
ViewInfo(title = "Icons", iconKey = StandaloneSampleIcons.Components.toolbar, content = { Icons() }),
ViewInfo(title = "Links", iconKey = StandaloneSampleIcons.Components.links, content = { Links() }),
ViewInfo(title = "Borders", iconKey = StandaloneSampleIcons.Components.borders, content = { Borders() }),
ViewInfo(
title = "Segmented Controls",
iconKey = StandaloneSampleIcons.Components.segmentedControls,
content = { SegmentedControls() },
),
ViewInfo(title = "Sliders", iconKey = StandaloneSampleIcons.Components.slider, content = { Sliders() }),
ViewInfo(title = "Tabs", iconKey = StandaloneSampleIcons.Components.tabs, content = { Tabs() }),
ViewInfo(title = "Tooltips", iconKey = StandaloneSampleIcons.Components.tooltip, content = { Tooltips() }),
ViewInfo(
title = "TextAreas",
iconKey = StandaloneSampleIcons.Components.textArea,
content = { TextAreas() },
),
ViewInfo(
title = "TextFields",
iconKey = StandaloneSampleIcons.Components.textField,
content = { TextFields() },
),
ViewInfo(
title = "Scrollbars",
iconKey = StandaloneSampleIcons.Components.scrollbar,
content = { Scrollbars() },
),
ViewInfo(
title = "SplitLayout",
iconKey = StandaloneSampleIcons.Components.splitlayout,
content = {
SplitLayouts(outerSplitState, verticalSplitState, innerSplitState) {
outerSplitState = SplitLayoutState(0.5f)
verticalSplitState = SplitLayoutState(0.5f)
innerSplitState = SplitLayoutState(0.5f)
}
},
),
)
var currentView by mutableStateOf(views.first())
}

private val componentsMenuItems =
mutableStateListOf(
ViewInfo(title = "Buttons", iconKey = StandaloneSampleIcons.Components.button, content = { Buttons() }),
ViewInfo(
title = "Radio Buttons",
iconKey = StandaloneSampleIcons.Components.radioButton,
content = { RadioButtons() },
),
ViewInfo(title = "Checkboxes", iconKey = StandaloneSampleIcons.Components.checkbox, content = { Checkboxes() }),
ViewInfo(title = "Dropdowns", iconKey = StandaloneSampleIcons.Components.comboBox, content = { Dropdowns() }),
ViewInfo(
title = "Chips and trees",
iconKey = StandaloneSampleIcons.Components.tree,
content = { ChipsAndTrees() },
),
ViewInfo(
title = "Progressbar",
iconKey = StandaloneSampleIcons.Components.progressBar,
content = { ProgressBar() },
),
ViewInfo(title = "Icons", iconKey = StandaloneSampleIcons.Components.toolbar, content = { Icons() }),
ViewInfo(title = "Links", iconKey = StandaloneSampleIcons.Components.links, content = { Links() }),
ViewInfo(title = "Borders", iconKey = StandaloneSampleIcons.Components.borders, content = { Borders() }),
ViewInfo(
title = "Segmented Controls",
iconKey = StandaloneSampleIcons.Components.segmentedControls,
content = { SegmentedControls() },
),
ViewInfo(title = "Sliders", iconKey = StandaloneSampleIcons.Components.slider, content = { Sliders() }),
ViewInfo(title = "Tabs", iconKey = StandaloneSampleIcons.Components.tabs, content = { Tabs() }),
ViewInfo(title = "Tooltips", iconKey = StandaloneSampleIcons.Components.tooltip, content = { Tooltips() }),
ViewInfo(title = "TextAreas", iconKey = StandaloneSampleIcons.Components.textArea, content = { TextAreas() }),
ViewInfo(
title = "TextFields",
iconKey = StandaloneSampleIcons.Components.textField,
content = { TextFields() },
),
ViewInfo(title = "Scrollbars", iconKey = StandaloneSampleIcons.Components.scrollbar, content = { Scrollbars() }),
)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 12 additions & 2 deletions ui/api/ui.api
Original file line number Diff line number Diff line change
Expand Up @@ -755,8 +755,18 @@ public final class org/jetbrains/jewel/ui/component/SliderState$Companion {
}

public final class org/jetbrains/jewel/ui/component/SplitLayoutKt {
public static final fun HorizontalSplitLayout-BssWTFQ (Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Landroidx/compose/ui/Modifier;JFFFFFFLandroidx/compose/runtime/Composer;II)V
public static final fun VerticalSplitLayout-BssWTFQ (Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Landroidx/compose/ui/Modifier;JFFFFFFLandroidx/compose/runtime/Composer;II)V
public static final fun HorizontalSplitLayout-Zv8xjqY (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Landroidx/compose/ui/Modifier;Lorg/jetbrains/jewel/ui/component/styling/DividerStyle;FFFLorg/jetbrains/jewel/ui/component/SplitLayoutState;Landroidx/compose/runtime/Composer;II)V
public static final fun VerticalSplitLayout-Zv8xjqY (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Landroidx/compose/ui/Modifier;Lorg/jetbrains/jewel/ui/component/styling/DividerStyle;FFFLorg/jetbrains/jewel/ui/component/SplitLayoutState;Landroidx/compose/runtime/Composer;II)V
public static final fun rememberSplitLayoutState (FLandroidx/compose/runtime/Composer;II)Lorg/jetbrains/jewel/ui/component/SplitLayoutState;
}

public final class org/jetbrains/jewel/ui/component/SplitLayoutState {
public static final field $stable I
public fun <init> (F)V
public final fun getDividerPosition ()F
public final fun getLayoutCoordinates ()Landroidx/compose/ui/layout/LayoutCoordinates;
public final fun setDividerPosition (F)V
public final fun setLayoutCoordinates (Landroidx/compose/ui/layout/LayoutCoordinates;)V
}

public abstract interface class org/jetbrains/jewel/ui/component/TabContentScope {
Expand Down
Loading

0 comments on commit 5efee37

Please sign in to comment.