Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ToolBox

ToolBox preview

ToolBox — a vertical stack of collapsible sections, exactly one expanded at a time.

Semantic cousin of Qt's QToolBox and the collapsible groups in IntelliJ's Settings dialog. Differs from Accordion (single-item independent disclosure) and TabWidget (horizontal tab bar with dormant panes) by combining vertical layout, always-visible headers, and exclusive expansion in one widget.

Int UI visual language:

  • flat, borderless headers (no corner radius)
  • 1 dp accent indicator bar on the leading edge of the active header
  • color-only emphasis (selected / hover / pressed surface roles)
  • border IS the focus ring: 1 dp accent border appears on the focused header, no separate ring primitive
  • content swaps are instant — Int UI's house rule is to avoid decorative animation for inline transitions; see MotionTokens. Matches the existing TabWidget precedent where pane swaps have no transition.
let selected = ctx.signal(0_usize);
ToolBox::new(selected.clone())
    .item("Outline",    outline_widget)
    .item("Properties", properties_widget)
    .add(ToolBoxItem::new("Build", build_widget).enabled(false))

Builder methods at a glance

orientation, fill, collapsible, horizontal, on_header_drag, item, item_id, add, items, show_dividers

API reference

📖 Full rustdoc API for this module

pub enum ToolBoxOrientation

Orientation of a [ToolBox]: how its collapsible sections are arranged.

Vertical (the default) stacks sections top-to-bottom with horizontal headers and an up/down chevron — the classic QToolBox. Horizontal lays sections left-to-right; each header becomes a narrow vertical strip with its label rotated 90° and a left/right chevron. The horizontal form is used by side-docks anchored to the top/bottom edges (where the wide, short region calls for vertical header strips).

#![allow(unused)]
fn main() {
pub enum ToolBoxOrientation { /* variants */ }
}

Variants

  • Vertical — Sections stacked top-to-bottom; horizontal headers (default).
  • Horizontal — Sections arranged left-to-right; vertical header strips with rotated labels and left/right chevrons.

pub struct ToolBoxItem

One section of a ToolBox. Construct with ToolBoxItem::new and pass to ToolBox::add, or use the convenience ToolBox::item / ToolBox::item_id builders directly when leading / trailing slots and tooltip are not needed.

Layout of the header row:

[indicator] [leading?] [label] [spacer] [trailing?] [chevron]

Both leading and trailing accept any impl Widget — typical uses are a small IconWidget, a Checkbox (checkable section), a Badge (count), or a Button (per-row action).

#![allow(unused)]
fn main() {
pub struct ToolBoxItem { /* fields */ }
}

Methods

pub fn new(label: impl Into<LocalizedString>, content: impl Widget + 'static) -> Self

Build an item with an inline content widget. The label may come from tr!(...) (translated) or lit!(...).

pub fn new_id(label: impl Into<LocalizedString>, content_id: WidgetId) -> Self

Build an item whose content is a pre-registered widget id.

pub fn leading(mut self, widget: impl Widget + 'static) -> Self

Attach a leading-slot widget rendered before the label (after the selection indicator bar). Use for a small IconWidget, a Checkbox for checkable sections, a Badge, or any other label-sized widget. The slot widget owns its own events — a Checkbox inside the leading slot toggles independently of the header's own tap.

pub fn trailing(mut self, widget: impl Widget + 'static) -> Self

Attach a trailing-slot widget rendered between the row's flexible spacer and the chevron. Use for per-row actions — a dismiss button, a badge, a secondary Toggle. The slot widget owns its own events: tapping a Button inside the trailing slot fires the button's action; gesture recognisers on the trailing widget stop the header's own tap from firing, so a close-button click does not also select the section.

pub fn tooltip(mut self, text: impl Into<LocalizedString>) -> Self

Attach a plain-text tooltip shown after a hover delay on the header row. The text may come from tr!(...) (translated, locale-reactive) or lit!(...). Mirrors .tooltip(...) on Button / IconButton / MenuItem. Clears any previously set rich or composite tooltip (the last tooltip setter called wins).

pub fn rich_tooltip(mut self, key: impl Into<String>) -> Self

Attach a rich tooltip resolved from the app-wide TooltipRegistry by key. Clears any previously set plain or composite tooltip (the last tooltip setter called wins).

pub fn rich_tooltip_content(mut self, content: TooltipContent) -> Self

Attach a rich tooltip driven by inline TooltipContent — for one-offs that don't belong in the registry. Clears any previously set plain or composite tooltip (the last tooltip setter called wins).

pub fn composite_tooltip(mut self, content: impl Widget + 'static) -> Self

Attach a composite tooltip — an arbitrary impl Widget body shown in a larger, scrollable overlay after a longer hover delay. Use for rich on-demand previews: charts, property tables, image thumbnails. Clears any previously set plain or rich tooltip (the last tooltip setter called wins).

pub fn enabled(mut self, enabled: impl Into<Prop<bool>>) -> Self

Disable the item: its header renders in the disabled text role, click and keyboard activation are ignored, and arrow navigation skips it. Accepts a static bool or a reactive Signal<bool>.

Forwarded to the arena via ctx.enabled_when(header_id, self.enabled.clone()) at build time; the arena is then the single source of truth and ANDs with ancestors — disabling the surrounding ToolBox (or any ancestor) disables every item regardless of this flag.

pub const TOOL_BOX_HEADER_MIN_HEIGHT

ToolBox design tokens.

#![allow(unused)]
fn main() {
pub const TOOL_BOX_HEADER_MIN_HEIGHT: f32 = 28.0;
}

pub const TOOL_BOX_HEADER_PADDING_HORIZONTAL

#![allow(unused)]
fn main() {
pub const TOOL_BOX_HEADER_PADDING_HORIZONTAL: f32 = 12.0;
}

pub const TOOL_BOX_ICON_TEXT_SPACING

#![allow(unused)]
fn main() {
pub const TOOL_BOX_ICON_TEXT_SPACING: f32 = 8.0;
}

pub const TOOL_BOX_CHEVRON_SIZE

#![allow(unused)]
fn main() {
pub const TOOL_BOX_CHEVRON_SIZE: f32 = 12.0;
}

pub const TOOL_BOX_INDICATOR_THICKNESS

#![allow(unused)]
fn main() {
pub const TOOL_BOX_INDICATOR_THICKNESS: f32 = 1.0;
}

pub struct ToolBox

A vertical container of collapsible sections with exactly one expanded at a time — the Int UI / QToolBox pattern.

The active section is driven by a caller-owned Signal<usize>; mirrors TabWidget::new so persistence, synchronised windows, and programmatic activation work identically.

#![allow(unused)]
fn main() {
pub struct ToolBox { /* fields */ }
}

Methods

pub fn new(selected: Signal<usize>) -> Self

Create a ToolBox driven by selected (visible section index). Set the signal to 0 to open the first section by default; modify it programmatically or share it across windows for synchronized state.

pub fn orientation(mut self, orientation: ToolBoxOrientation) -> Self

Set the section arrangement orientation (default ToolBoxOrientation::Vertical).

pub fn fill(mut self, fill: bool) -> Self

Make the active section's panel fill the ToolBox's allotted space rather than size to its content's natural extent.

With fill on, the active panel stretches to the full cross axis and flexes / shrinks (and clips) along the main axis, so a ToolBox placed in a bounded region lays its content out at exactly the available size — the QToolBox convention. A panel whose content carries a trailing Spacer therefore pins a bottom toolbar to the visible bottom edge instead of overflowing past it.

Default false (the panel keeps its content's natural size — the historical behaviour, appropriate when the ToolBox itself lives inside a scroll area).

pub fn collapsible(mut self, collapsible: bool) -> Self

Allow collapsing the active section: clicking (or Enter/Space on, or the AT Collapse action of) the already-expanded header closes it, so all sections can be collapsed at once. A subsequent click re-expands.

Default false — the classic "exactly one section open" behaviour. This is what makes a single-section ToolBox a plain collapsible panel (header toggles its content), e.g. a dock panel.

pub fn horizontal(mut self) -> Self

Shorthand for ToolBox::orientation``(``ToolBoxOrientation::Horizontal``).

pub fn on_header_drag(mut self, f: impl Fn(usize, &mut EventContext) + 'static) -> Self

Make each section header a drag source. f is invoked (with the section index) when a drag gesture starts on a header; it should begin a drag (e.g. ctx.start_drag(source, payload)). Tapping a header still selects it — the gesture arena tells a tap from a drag.

pub fn item(self, label: impl Into<LocalizedString>, content: impl Widget + 'static) -> Self

Append an item with an inline content widget. Convenience wrapper around ToolBox::add that skips the ToolBoxItem builder for the common label-plus-content case.

pub fn item_id(self, label: impl Into<LocalizedString>, content_id: WidgetId) -> Self

Append an item whose content is a pre-registered widget id.

pub fn add(mut self, item: ToolBoxItem) -> Self

Append a fully-built ToolBoxItem — required when an icon, tooltip, or disabled flag is needed.

pub fn items<I>(mut self, items: I) -> Self where I: IntoIterator<Item = ToolBoxItem>,

Append multiple items from an iterator.

pub fn show_dividers(mut self, show: bool) -> Self

Show a 1 dp BorderRole::Divider line between consecutive header / panel rows. Default: false — IntelliJ Settings-style collapsibles stack without explicit dividers, letting the flat background roles delineate the rows.