iced-cube

Layout

Resizable panel

Two or more panels in a row or column, separated by handles that resize them.

use iced_cube::layout::resizable_panel::{self, Event, Extent, State, panel, resizable_panel};
API reference
Horizontal: Three panels in a row with grips on the handles. Each shows its share of the width.Horizontal: Three panels in a row with grips on the handles. Each shows its share of the width.
Static preview
Horizontal. Three panels in a row with grips on the handles. Each shows its share of the width.

Usage

The app owns the sizes. They live in State as fractions of the space the panels share, so saving state.sizes() and passing it back to with_sizes restores the layout at any window size. Pixel limits are applied against the current size every time the group is laid out.

Dragging a handle moves the panels on either side of it. When the panel that is shrinking reaches its minimum, the panels beyond it shrink too. A collapsible panel snaps shut once it is dragged below its threshold and snaps open again, at its minimum, once it is dragged back past it. Event::Toggle collapses a panel or brings it back to the size it had before.

The group sends Event::Measure when its size changes, followed by the drag events. Pass them all to state.update.

Keyboard focus

iced 0.14 has no general focus model, but widgets can take part in its focus operations. Each handle is focusable: pressing it focuses it, just as a text field is focused, and iced::widget::operation::focus(id) or focus_next() reach it too. While a handle has focus the group resolves its own keymap and captures the keys it uses, so no subscription is needed. Escape or a press anywhere else takes the focus away.

Small screens

When the minimums do not fit, collapsible panels collapse, starting with the last one, and if that is not enough every panel shrinks in proportion. For a row that would be too cramped on a phone, .stack_below(480.0) turns it into a column below that width, keeping the same shares.

Examples

Vertical

A header and content stacked in a column.

Vertical: A header and content stacked in a column.Vertical: A header and content stacked in a column.
Static preview

Nested

A column of two panels inside a row. Below 480 pixels the row stacks into a column.

Nested: A column of two panels inside a row. Below 480 pixels the row stacks into a column.Nested: A column of two panels inside a row. Below 480 pixels the row stacks into a column.
Static preview

Collapsible with limits

A folder list between 140 pixels and half the width that snaps shut below its threshold, with a button that toggles it.

Collapsible with limits: A folder list between 140 pixels and half the width that snaps shut below its threshold, with a button that toggles it.Collapsible with limits: A folder list between 140 pixels and half the width that snaps shut below its threshold, with a button that toggles it.
Static preview

Keyboard shortcuts

A focused handle resolves the default keymap, with Page Up and Page Down added. A press focuses the handle, and so does widget::operation::focus with its id.

Keyboard shortcuts: A focused handle resolves the default keymap, with Page Up and Page Down added. A press focuses the handle, and so does widget::operation::focus with its id.Keyboard shortcuts: A focused handle resolves the default keymap, with Page Up and Page Down added. A press focuses the handle, and so does widget::operation::focus with its id.
Static preview

API

ItemDescription
panel(Extent)One panel's constraints, starting at a default size given as Extent::Fraction or Extent::Pixels.
.min(Extent) / .max(Extent)The smallest and largest the panel may get. The maximum is never below the minimum.
.collapsible(bool) / .collapsed_size(Extent) / .collapse_below(Extent)Lets the panel snap shut. It collapses to its collapsed size, 0 by default, when dragged below the threshold, which defaults to halfway between that size and the minimum.
.collapsed(bool)Starts a collapsible panel collapsed.
State::new(panels)Holds the panels and their sizes. Sizes are worked out when the group first measures itself.
.with_sizes(sizes) / state.set_sizes(sizes)Restores saved sizes. They are scaled to add up to 1 and fitted to the limits.
.step(Extent) / .large_step(Extent)How far the arrow keys and Shift with an arrow move a handle. Default 5% and 20%.
state.update(Event)Applies a drag, a keyboard step, Collapse, Expand, Toggle or Reset. Returns Output::Resized, Collapsed(i) or Expanded(i) when something changed.
state.sizes()Each panel's share of the space, adding up to 1, ready to save.
state.resolve(total) / state.is_collapsed(i) / state.dragging()The sizes in pixels for a length, whether a panel is collapsed, and the handle being dragged.
resizable_panel(&state, panes)Lays out one element per panel with handles between them. The handles do nothing until .on_event is set.
.axis(Axis)Horizontal for a row, the default, or Vertical for a column.
.stack_below(width)Turns a horizontal group into a column while it is narrower than the given width.
.grip(bool)Draws a grip on each handle.
.id(id)Gives the first handle an id, so widget::operation::focus can focus it.
.keymap(Keymap<Action>) / resizable_panel::default_keymap()The shortcuts a focused handle resolves. Bind, unbind or clear chords to change them.
action.event(&state, handle)The Event an Action sends for a handle, for apps that route keys themselves.
resizable_panel::resize / fit / defaultsThe pure size maths the state uses, for tests or custom layouts.

Keyboard

Default shortcuts. Every one can be changed or removed with a keymap; see Keyboard shortcuts.

KeysAction
ArrowLeft or ArrowUpDecrease Moves the focused handle one step towards the start.
ArrowRight or ArrowDownIncrease Moves the focused handle one step towards the end.
Shift+ArrowLeft or Shift+ArrowUpDecreaseMore Moves the focused handle a large step towards the start.
Shift+ArrowRight or Shift+ArrowDownIncreaseMore Moves the focused handle a large step towards the end.
HomeMin Shrinks the panel before the handle to its minimum.
EndMax Grows the panel before the handle to its maximum.
EnterToggle Collapses or expands the collapsible panel next to the handle.
EscapeRelease Takes the focus away from the handle.
Esc