splitter provides two resizable panes separated by a draggable divider.
Core behavior:
- Horizontal (
left/right) or vertical (top/bottom) orientation - Real-time drag resize
- Per-pane min/max size constraints
- Pane collapse/expand for first or second pane
- Keyboard resize/collapse support
- Nested splitters by composition
- Theme-driven styling for divider, grip, and collapse buttons
import gui
@[heap]
struct App {
pub mut:
main_split gui.SplitterState = gui.SplitterState{
ratio: 0.30
}
}
fn main_view(window &gui.Window) gui.View {
app := window.state[App]()
return gui.splitter(
id: 'main_split'
id_focus: 31
ratio: app.main_split.ratio
collapsed: app.main_split.collapsed
on_change: fn (ratio f32, collapsed gui.SplitterCollapsed, mut _e gui.Event, mut w gui.Window) {
w.state[App]().main_split = gui.splitter_state_normalize(gui.SplitterState{
ratio: ratio
collapsed: collapsed
})
}
first: gui.SplitterPaneCfg{
min_size: 140
content: [left_panel()]
}
second: gui.SplitterPaneCfg{
min_size: 220
content: [right_panel()]
}
)
}splitter is controlled: app state owns ratio and collapsed.
SplitterCfg main fields:
id string(required)id_focus u32keyboard focus idorientation SplitterOrientation(.horizontaldefault,.vertical)ratio f32split ratio (0..1)collapsed SplitterCollapsed(.none,.first,.second)on_change fn (f32, SplitterCollapsed, mut Event, mut Window)(required)first SplitterPaneCfg/second SplitterPaneCfg(required)handle_size f32drag_step f32/drag_step_large f32double_click_collapse boolshow_collapse_buttons bool- style fields (
color_*,size_border,radius,radius_border)
SplitterPaneCfg fields:
min_size f32max_size f32(0means no max)collapsible bool(truedefault)collapsed_size f32content []View
When splitter has focus:
Left/Rightresize horizontal splitterUp/Downresize vertical splitterShift + Arrowusedrag_step_largeHomecollapse first paneEndcollapse second paneEnterorSpacetoggle collapse target
collapsed: .nonemeans normal ratio-based split.collapsed: .firstcollapses first pane tofirst.collapsed_size.collapsed: .secondcollapses second pane tosecond.collapsed_size.- Only one pane can be collapsed at a time.
- If a pane is not collapsible, requests to collapse it are ignored.
For non-collapsed state, pane sizes are clamped by:
first.min_size/first.max_sizesecond.min_size/second.max_size
If constraints conflict, splitter clamps to the nearest feasible size.
Persistence is app-owned:
- Keep
SplitterStatein application state. - Update it in
on_change. - Save/load that state in app settings for cross-session restore.
Helpers:
SplitterState { ratio, collapsed }splitter_state_normalize(...)
Place a splitter inside a pane of another splitter:
gui.splitter(
id: 'outer'
// ...
second: gui.SplitterPaneCfg{
content: [
gui.splitter(
id: 'inner'
orientation: .vertical
// ...
),
]
}
)Theme support:
Theme.splitter_styleTheme.with_splitter_style(style)
Example:
mut style := gui.theme().splitter_style
style = gui.SplitterStyle{
...style
handle_size: 12
color_handle: gui.rgb(70, 70, 78)
color_handle_hover: gui.rgb(90, 90, 102)
color_handle_active: gui.rgb(110, 110, 128)
}
window.set_theme(gui.theme().with_splitter_style(style))