pub struct ContainerBuilder<'a> { /* private fields */ }Expand description
Fluent builder for configuring containers before calling .col() or .row().
Obtain one via Context::container or Context::bordered. Chain the
configuration methods you need, then finalize with .col(|ui| { ... }) or
.row(|ui| { ... }).
§Example
use slt::{Border, Color};
ui.container()
.border(Border::Rounded)
.p(1)
.grow(1)
.col(|ui| {
ui.text("inside a bordered, padded, growing column");
});Implementations§
Source§impl<'a> ContainerBuilder<'a>
impl<'a> ContainerBuilder<'a>
Sourcepub fn apply(self, style: &ContainerStyle) -> Self
pub fn apply(self, style: &ContainerStyle) -> Self
Apply a reusable ContainerStyle recipe. Only set fields override
the builder’s current values. Chain multiple .apply() calls to compose.
If the style has an ContainerStyle::extends base, the base is applied
first, then the style’s own fields override.
ThemeColor fields (theme_bg, theme_text_color, theme_border_fg)
are resolved against the active theme at apply time.
Sourcepub fn border_top(self, show: bool) -> Self
pub fn border_top(self, show: bool) -> Self
Show or hide the top border.
Sourcepub fn border_right(self, show: bool) -> Self
pub fn border_right(self, show: bool) -> Self
Show or hide the right border.
Sourcepub fn border_bottom(self, show: bool) -> Self
pub fn border_bottom(self, show: bool) -> Self
Show or hide the bottom border.
Sourcepub fn border_left(self, show: bool) -> Self
pub fn border_left(self, show: bool) -> Self
Show or hide the left border.
Sourcepub fn border_sides(self, sides: BorderSides) -> Self
pub fn border_sides(self, sides: BorderSides) -> Self
Set which border sides are visible.
Sourcepub fn border_x(self) -> Self
pub fn border_x(self) -> Self
Show only left and right borders. Shorthand for horizontal border sides.
Sourcepub fn border_y(self) -> Self
pub fn border_y(self) -> Self
Show only top and bottom borders. Shorthand for vertical border sides.
Sourcepub fn border_style(self, style: Style) -> Self
pub fn border_style(self, style: Style) -> Self
Set the style applied to the border characters.
Sourcepub fn dark_border_style(self, style: Style) -> Self
pub fn dark_border_style(self, style: Style) -> Self
Border style used when dark mode is active.
Sourcepub fn text_color(self, color: Color) -> Self
pub fn text_color(self, color: Color) -> Self
Set the default text color for all child text elements in this container.
Individual .fg() calls on text elements will still override this.
Sourcepub fn group_hover_bg(self, color: Color) -> Self
pub fn group_hover_bg(self, color: Color) -> Self
Background color applied when the parent group is hovered.
Sourcepub fn group_hover_border_style(self, style: Style) -> Self
pub fn group_hover_border_style(self, style: Style) -> Self
Border style applied when the parent group is hovered.
Sourcepub fn pad(self, value: u32) -> Self
👎Deprecated since 0.20.0: Use p() instead
pub fn pad(self, value: u32) -> Self
Use p() instead
Set uniform padding on all sides. Deprecated alias for p.
Sourcepub fn w_at(self, bp: Breakpoint, value: u32) -> Self
pub fn w_at(self, bp: Breakpoint, value: u32) -> Self
Width applied only at the given breakpoint.
Sourcepub fn h_at(self, bp: Breakpoint, value: u32) -> Self
pub fn h_at(self, bp: Breakpoint, value: u32) -> Self
Height applied only at the given breakpoint.
Sourcepub fn min_w(self, value: u32) -> Self
pub fn min_w(self, value: u32) -> Self
Set the minimum width constraint. Shorthand for min_width.
Sourcepub fn xs_min_w(self, value: u32) -> Self
pub fn xs_min_w(self, value: u32) -> Self
Minimum width applied only at Xs breakpoint (< 40 cols).
Sourcepub fn sm_min_w(self, value: u32) -> Self
pub fn sm_min_w(self, value: u32) -> Self
Minimum width applied only at Sm breakpoint (40-79 cols).
Sourcepub fn md_min_w(self, value: u32) -> Self
pub fn md_min_w(self, value: u32) -> Self
Minimum width applied only at Md breakpoint (80-119 cols).
Sourcepub fn lg_min_w(self, value: u32) -> Self
pub fn lg_min_w(self, value: u32) -> Self
Minimum width applied only at Lg breakpoint (120-159 cols).
Sourcepub fn xl_min_w(self, value: u32) -> Self
pub fn xl_min_w(self, value: u32) -> Self
Minimum width applied only at Xl breakpoint (>= 160 cols).
Sourcepub fn min_w_at(self, bp: Breakpoint, value: u32) -> Self
pub fn min_w_at(self, bp: Breakpoint, value: u32) -> Self
Minimum width applied only at the given breakpoint.
Sourcepub fn max_w(self, value: u32) -> Self
pub fn max_w(self, value: u32) -> Self
Set the maximum width constraint. Shorthand for max_width.
Sourcepub fn xs_max_w(self, value: u32) -> Self
pub fn xs_max_w(self, value: u32) -> Self
Maximum width applied only at Xs breakpoint (< 40 cols).
Sourcepub fn sm_max_w(self, value: u32) -> Self
pub fn sm_max_w(self, value: u32) -> Self
Maximum width applied only at Sm breakpoint (40-79 cols).
Sourcepub fn md_max_w(self, value: u32) -> Self
pub fn md_max_w(self, value: u32) -> Self
Maximum width applied only at Md breakpoint (80-119 cols).
Sourcepub fn lg_max_w(self, value: u32) -> Self
pub fn lg_max_w(self, value: u32) -> Self
Maximum width applied only at Lg breakpoint (120-159 cols).
Sourcepub fn xl_max_w(self, value: u32) -> Self
pub fn xl_max_w(self, value: u32) -> Self
Maximum width applied only at Xl breakpoint (>= 160 cols).
Sourcepub fn max_w_at(self, bp: Breakpoint, value: u32) -> Self
pub fn max_w_at(self, bp: Breakpoint, value: u32) -> Self
Maximum width applied only at the given breakpoint.
Sourcepub fn min_h(self, value: u32) -> Self
pub fn min_h(self, value: u32) -> Self
Set the minimum height constraint. Shorthand for min_height.
Sourcepub fn xs_min_h(self, value: u32) -> Self
pub fn xs_min_h(self, value: u32) -> Self
Minimum height applied only at Xs breakpoint (< 40 cols).
Sourcepub fn sm_min_h(self, value: u32) -> Self
pub fn sm_min_h(self, value: u32) -> Self
Minimum height applied only at Sm breakpoint (40-79 cols).
Sourcepub fn md_min_h(self, value: u32) -> Self
pub fn md_min_h(self, value: u32) -> Self
Minimum height applied only at Md breakpoint (80-119 cols).
Sourcepub fn lg_min_h(self, value: u32) -> Self
pub fn lg_min_h(self, value: u32) -> Self
Minimum height applied only at Lg breakpoint (120-159 cols).
Sourcepub fn xl_min_h(self, value: u32) -> Self
pub fn xl_min_h(self, value: u32) -> Self
Minimum height applied only at Xl breakpoint (>= 160 cols).
Sourcepub fn min_h_at(self, bp: Breakpoint, value: u32) -> Self
pub fn min_h_at(self, bp: Breakpoint, value: u32) -> Self
Minimum height applied only at the given breakpoint.
Sourcepub fn max_h(self, value: u32) -> Self
pub fn max_h(self, value: u32) -> Self
Set the maximum height constraint. Shorthand for max_height.
Sourcepub fn xs_max_h(self, value: u32) -> Self
pub fn xs_max_h(self, value: u32) -> Self
Maximum height applied only at Xs breakpoint (< 40 cols).
Sourcepub fn sm_max_h(self, value: u32) -> Self
pub fn sm_max_h(self, value: u32) -> Self
Maximum height applied only at Sm breakpoint (40-79 cols).
Sourcepub fn md_max_h(self, value: u32) -> Self
pub fn md_max_h(self, value: u32) -> Self
Maximum height applied only at Md breakpoint (80-119 cols).
Sourcepub fn lg_max_h(self, value: u32) -> Self
pub fn lg_max_h(self, value: u32) -> Self
Maximum height applied only at Lg breakpoint (120-159 cols).
Sourcepub fn xl_max_h(self, value: u32) -> Self
pub fn xl_max_h(self, value: u32) -> Self
Maximum height applied only at Xl breakpoint (>= 160 cols).
Sourcepub fn max_h_at(self, bp: Breakpoint, value: u32) -> Self
pub fn max_h_at(self, bp: Breakpoint, value: u32) -> Self
Maximum height applied only at the given breakpoint.
Sourcepub fn min_width(self, value: u32) -> Self
👎Deprecated since 0.20.0: Use min_w() instead
pub fn min_width(self, value: u32) -> Self
Use min_w() instead
Set the minimum width constraint in cells. Deprecated alias for min_w.
Sourcepub fn max_width(self, value: u32) -> Self
👎Deprecated since 0.20.0: Use max_w() instead
pub fn max_width(self, value: u32) -> Self
Use max_w() instead
Set the maximum width constraint in cells. Deprecated alias for max_w.
Sourcepub fn min_height(self, value: u32) -> Self
👎Deprecated since 0.20.0: Use min_h() instead
pub fn min_height(self, value: u32) -> Self
Use min_h() instead
Set the minimum height constraint in rows. Deprecated alias for min_h.
Sourcepub fn max_height(self, value: u32) -> Self
👎Deprecated since 0.20.0: Use max_h() instead
pub fn max_height(self, value: u32) -> Self
Use max_h() instead
Set the maximum height constraint in rows. Deprecated alias for max_h.
Sourcepub fn h_pct(self, pct: u8) -> Self
pub fn h_pct(self, pct: u8) -> Self
Set height as a percentage (1-100) of the parent container.
Sourcepub fn constraints(self, constraints: Constraints) -> Self
pub fn constraints(self, constraints: Constraints) -> Self
Set all size constraints at once using a Constraints value.
Sourcepub fn gap_overlap(self, overlap: u32) -> Self
pub fn gap_overlap(self, overlap: u32) -> Self
Set a negative gap, causing adjacent children to overlap by overlap
cells on the main axis.
This is SLT’s analogue of ratatui’s Layout::spacing(-1). The common
use is collapsing the duplicate border between two adjacent bordered
panels: with gap_overlap(1) each panel’s shared edge lands in the
same column (row layout) or row (column layout), so the doubled border
┌────┐┌────┐
│ ││ │
└────┘└────┘collapses to a single shared edge.
gap_overlap(0) is identical to gap(0) (no overlap). It composes with
the existing gap family: the last call wins, so call exactly one of
gap / gap_overlap per builder.
§Rendering note
SLT does not (yet) merge the shared cells into junction glyphs (┬,
┼, ┴). When two bordered panels overlap, both write the shared
column/row and the later panel’s border character wins by buffer-diff
order. To get a clean seam, give the panels compatible border styles or
drop one panel’s shared side (e.g. border_sides without the left edge).
Large overlaps saturate gracefully — gap_overlap(N) past a child’s
extent never panics or wraps; positions clamp at 0.
§Example
use slt::Border;
// Two bordered panels sharing one border column.
ui.container().gap_overlap(1).row(|ui| {
ui.bordered(Border::Single).w(10).col(|ui| {
ui.text("left");
});
ui.bordered(Border::Single).w(10).col(|ui| {
ui.text("right");
});
});Sourcepub fn row_gap(self, value: u32) -> Self
pub fn row_gap(self, value: u32) -> Self
Set the gap between children for column layouts (vertical spacing).
Overrides .gap() when finalized with .col().
Sourcepub fn col_gap(self, value: u32) -> Self
pub fn col_gap(self, value: u32) -> Self
Set the gap between children for row layouts (horizontal spacing).
Overrides .gap() when finalized with .row().
Sourcepub fn gap_at(self, bp: Breakpoint, value: u32) -> Self
pub fn gap_at(self, bp: Breakpoint, value: u32) -> Self
Gap applied only at the given breakpoint.
Sourcepub fn grow(self, grow: u16) -> Self
pub fn grow(self, grow: u16) -> Self
Set the flex-grow factor. 1 means the container expands to fill available space.
Sourcepub fn fill(self) -> Self
pub fn fill(self) -> Self
Expand to fill remaining space on the main axis. Shorthand for
grow(1).
Equivalent to CSS flex: 1 and ratatui’s Constraint::Fill(1).
This is the most common case in flex layouts and reads more
naturally than grow(1) for new readers — the abstract “grow
factor” terminology is replaced by a self-documenting verb.
ui.container().fill().col(|ui| { ... });
// identical to:
ui.container().grow(1).col(|ui| { ... });For other weights (e.g. a 2:1 split between two siblings), use
grow(N) directly.
Sourcepub fn shrink(self) -> Self
pub fn shrink(self) -> Self
Opt this container into proportional flex-shrink.
Marks this container as a shrink participant. When the parent
row / column overflows (its children’s combined width or height
exceeds available space), shrink-flagged children scale their
fixed sizes by available / fixed_total (CSS flex-shrink-style).
Children without .shrink() keep their historic
overflow-by-design size and clip naturally.
Default for every container is false — opt in per child.
Equivalent to CSS flex-shrink: 1 (vs the SLT default of 0).
Closes #161.
§Example
Two siblings with combined fixed width 60 placed inside a
40-cell row. Without .shrink(), the row overflows; with
.shrink() on both, each scales to 40 * 30/60 = 20:
// Without shrink — overflows the parent.
ui.row(|ui| {
ui.container().w(30).col(|ui| { ui.text("left"); });
ui.container().w(30).col(|ui| { ui.text("right"); });
});
// With shrink on both — proportional fit, no clipping.
ui.row(|ui| {
ui.container().w(30).shrink().col(|ui| { ui.text("left"); });
ui.container().w(30).shrink().col(|ui| { ui.text("right"); });
});§Layout
Only fixed-width children with grow == 0 participate. Grow
children already absorb leftover space and ignore the shrink
flag. Mixing shrink and non-shrink siblings is supported — only
the flagged ones contribute to the shrink budget.
Sourcepub fn wrap(self) -> Self
pub fn wrap(self) -> Self
Allow row children to wrap onto subsequent lines on main-axis overflow.
When a .row() finalized with wrap() has children whose combined
width exceeds the available width, the overflowing children flow onto
the next line, and lines stack on the cross axis. This is the
immediate-mode primitive for tag clouds, chip lists, wrapping toolbars,
and responsive card grids that reflow as the terminal resizes — without
per-frame breakpoint math. Equivalent to CSS flex-wrap: wrap.
Spacing: within-line (main-axis) spacing uses gap / col_gap as
usual; between-line (cross-axis) spacing uses row_gap when set, else
gap. A child wider than the full available width occupies its own
line (clipped, as a single-line row would clip) rather than producing
an empty line.
Row only. On col() this is a documented no-op (vertical-axis wrap is
out of scope). Default: no wrap (single-line, current
overflow-by-design behavior). Closes #258.
§Example
// A chip list that reflows onto as many lines as the width needs.
ui.container().wrap().gap(1).row(|ui| {
for tag in ["rust", "tui", "flexbox", "wrap", "immediate-mode"] {
ui.container().p(1).col(|ui| { ui.text(tag); });
}
});Sourcepub fn basis(self, cells: u32) -> Self
pub fn basis(self, cells: u32) -> Self
Set the flex-basis: the initial main-axis size (in cells) that grow
grows from and shrink (#161) shrinks from.
CSS resolves flex sizing as basis (initial) → distribute free space
by grow → distribute the deficit by shrink. By default SLT uses a
child’s min size as that base; basis(n) overrides it so a child can
say “start at n cells, then grow / shrink from there”. None
(default, i.e. not calling this) falls back to the min size, preserving
current behavior. Equivalent to CSS flex-basis: <n>. Closes #258.
§Example
// Two cards that each start at 10 cells, then split the leftover.
ui.row(|ui| {
ui.container().basis(10).grow(1).col(|ui| { ui.text("a"); });
ui.container().basis(10).grow(1).col(|ui| { ui.text("b"); });
});Sourcepub fn xs_grow(self, value: u16) -> Self
pub fn xs_grow(self, value: u16) -> Self
Grow factor applied only at Xs breakpoint (< 40 cols).
Sourcepub fn sm_grow(self, value: u16) -> Self
pub fn sm_grow(self, value: u16) -> Self
Grow factor applied only at Sm breakpoint (40-79 cols).
Sourcepub fn md_grow(self, value: u16) -> Self
pub fn md_grow(self, value: u16) -> Self
Grow factor applied only at Md breakpoint (80-119 cols).
Sourcepub fn lg_grow(self, value: u16) -> Self
pub fn lg_grow(self, value: u16) -> Self
Grow factor applied only at Lg breakpoint (120-159 cols).
Sourcepub fn xl_grow(self, value: u16) -> Self
pub fn xl_grow(self, value: u16) -> Self
Grow factor applied only at Xl breakpoint (>= 160 cols).
Sourcepub fn grow_at(self, bp: Breakpoint, value: u16) -> Self
pub fn grow_at(self, bp: Breakpoint, value: u16) -> Self
Grow factor applied only at the given breakpoint.
Sourcepub fn xs_p(self, value: u32) -> Self
pub fn xs_p(self, value: u32) -> Self
Uniform padding applied only at Xs breakpoint (< 40 cols).
Sourcepub fn sm_p(self, value: u32) -> Self
pub fn sm_p(self, value: u32) -> Self
Uniform padding applied only at Sm breakpoint (40-79 cols).
Sourcepub fn md_p(self, value: u32) -> Self
pub fn md_p(self, value: u32) -> Self
Uniform padding applied only at Md breakpoint (80-119 cols).
Sourcepub fn lg_p(self, value: u32) -> Self
pub fn lg_p(self, value: u32) -> Self
Uniform padding applied only at Lg breakpoint (120-159 cols).
Sourcepub fn xl_p(self, value: u32) -> Self
pub fn xl_p(self, value: u32) -> Self
Uniform padding applied only at Xl breakpoint (>= 160 cols).
Sourcepub fn p_at(self, bp: Breakpoint, value: u32) -> Self
pub fn p_at(self, bp: Breakpoint, value: u32) -> Self
Padding applied only at the given breakpoint.
Sourcepub fn center(self) -> Self
pub fn center(self) -> Self
Center children on the cross axis. Shorthand for .align(Align::Center).
Sourcepub fn space_between(self) -> Self
pub fn space_between(self) -> Self
Distribute children with equal space between; first at start, last at end.
Sourcepub fn space_around(self) -> Self
pub fn space_around(self) -> Self
Distribute children with equal space around each child.
Sourcepub fn space_evenly(self) -> Self
pub fn space_evenly(self) -> Self
Distribute children with equal space between all children and edges.
Sourcepub fn flex_center(self) -> Self
pub fn flex_center(self) -> Self
Center children on both axes. Shorthand for .justify(Justify::Center).align(Align::Center).
Sourcepub fn align_self(self, align: Align) -> Self
pub fn align_self(self, align: Align) -> Self
Override the parent’s cross-axis alignment for this container only.
Like CSS align-self.
Sourcepub fn title(self, title: impl Into<String>) -> Self
pub fn title(self, title: impl Into<String>) -> Self
Set a plain-text title rendered in the top border.
Sourcepub fn title_styled(self, title: impl Into<String>, style: Style) -> Self
pub fn title_styled(self, title: impl Into<String>, style: Style) -> Self
Set a styled title rendered in the top border.
Sourcepub fn with_if(self, cond: bool, f: impl FnOnce(Self) -> Self) -> Self
pub fn with_if(self, cond: bool, f: impl FnOnce(Self) -> Self) -> Self
Apply f only if cond is true. Returns the builder for chaining.
Use this to attach a block of builder modifiers without breaking the
fluent chain. The closure takes the builder by value and must return
it (matching the rest of ContainerBuilder’s by-value API), so any
builder method (.border(), .title(), .bg(), etc.) can be chained
inside.
Zero allocation: the closure is inlined and skipped entirely when
cond is false.
§Example
use slt::Border;
let highlighted = true;
ui.container()
.p(1)
.with_if(highlighted, |c| c.border(Border::Single).title("Active"))
.col(|ui| {
ui.text("body");
});Sourcepub fn theme(self, theme: Theme) -> Self
pub fn theme(self, theme: Theme) -> Self
Override the active theme for all widgets rendered inside this container.
The override is scoped to the container body (the closure passed to
.col(), .row(), or .line()). The parent theme is restored when
the container closes — including on panic.
All built-in widgets read ctx.theme directly for color decisions,
so this swap propagates through every nested widget without requiring
them to opt in. Nested .theme(...) calls correctly nest: the
innermost theme wins inside its own subtree, and the outer theme
resumes once it closes.
Independent of Context::provide / Context::use_context —
this directly mutates the active theme used by SLT-owned widgets,
while provide/use_context is the general-purpose context
injection mechanism for user code.
§Example
use slt::{Border, Theme};
ui.container()
.theme(Theme::light())
.border(Border::Rounded)
.col(|ui| {
ui.text("This subtree renders with the light theme");
ui.button("Click me"); // also uses light theme colors
});Sourcepub fn with(self, f: impl FnOnce(Self) -> Self) -> Self
pub fn with(self, f: impl FnOnce(Self) -> Self) -> Self
Apply f unconditionally. Useful for factoring out a block of builder
modifier calls while keeping the fluent chain intact.
The closure takes the builder by value and must return it.
§Example
use slt::Border;
ui.container()
.with(|c| c.border(Border::Rounded).p(1))
.col(|ui| {
ui.text("body");
});Sourcepub fn cached(self, version_key: u64, f: impl FnOnce(&mut Context)) -> Response
pub fn cached(self, version_key: u64, f: impl FnOnce(&mut Context)) -> Response
Opt-in: declare a subtree stable when version_key is unchanged
from the previous frame at this call site.
This is an author-controlled cache, not reactive binding. Your
closure is still the app (Principle 2 — “Your Closure IS the App”):
f runs every frame exactly like .col(f), so the rendered output
is byte-for-byte identical to an uncached container — there is no
retained widget identity, no message passing, no reactive subscription,
and no behavior change whatsoever when you do not call cached.
What cached adds is a single, principle-preserving signal: it records
the version_key you supply (a value you already own — e.g. a hash of
the non-streaming inputs, or StreamingTextState::version of the
other panes) and compares it to the key this call site recorded last
frame. A match is a cache hit (the subtree is declared unchanged); a
change, a new call site, the first frame, or a terminal resize is a
miss. The hit/miss tally is exposed via
Context::region_cache_hits /
Context::region_cache_misses.
§Why output is identical even on a hit (current implementation)
Skipping f on a hit would require splicing the prior frame’s recorded
Commands, replaying its focus / hit-map / scroll / raw-draw feedback,
and reusing its rendered cells — without that full replay the immediate-
mode invariant breaks (focus and interaction would silently drop). That
replay is deliberately out of scope here (it risks reintroducing a
retained tree, the thing Principle 2 forbids). So cached keeps the
invariant absolute — f always runs — and instead lands the safe,
reversible half: a measured, author-keyed stability gate plus
diagnostics. The streaming benchmark bench_streaming_append_chat
(benches/benchmarks.rs) quantifies the upstream cost this gate is
designed to eventually elide; see docs/PERFORMANCE.md.
§Pattern: cache the chrome, not the stream
During token streaming, wrap the static surroundings (chat history, sidebar, status bar) keyed off everything except the stream, and leave the stream itself uncached — it changes every token:
ui.container().cached(history_version, |ui| {
ui.text("…long chat transcript…"); // unchanged this token
});
ui.streaming_text(&mut stream); // changes every tokenSourcepub fn col(self, f: impl FnOnce(&mut Context)) -> Response
pub fn col(self, f: impl FnOnce(&mut Context)) -> Response
Finalize the builder as a vertical (column) container.
The closure receives a &mut Context for rendering children.
Returns a Response with click/hover state for this container.
Sourcepub fn row(self, f: impl FnOnce(&mut Context)) -> Response
pub fn row(self, f: impl FnOnce(&mut Context)) -> Response
Finalize the builder as a horizontal (row) container.
The closure receives a &mut Context for rendering children.
Returns a Response with click/hover state for this container.
Sourcepub fn line(self, f: impl FnOnce(&mut Context)) -> Response
pub fn line(self, f: impl FnOnce(&mut Context)) -> Response
Finalize the builder as an inline text line.
Like row but gap is forced to zero
for seamless inline rendering of mixed-style text.
Sourcepub fn draw(self, f: impl FnOnce(&mut Buffer, Rect) + 'static)
pub fn draw(self, f: impl FnOnce(&mut Buffer, Rect) + 'static)
Finalize the builder as a raw-draw region with direct buffer access.
The closure receives (&mut Buffer, Rect) after layout is computed.
Use buf.set_char(), buf.set_string(), buf.get_mut() to write
directly into the terminal buffer. Writes outside rect are clipped.
The closure must be 'static because it is deferred until after layout.
To capture local data, clone or move it into the closure:
let data = my_vec.clone();
ui.container().w(40).h(20).draw(move |buf, rect| {
// use `data` here
});Sourcepub fn draw_with<D: 'static>(
self,
data: D,
f: impl FnOnce(&mut Buffer, Rect, &D) + 'static,
)
pub fn draw_with<D: 'static>( self, data: D, f: impl FnOnce(&mut Buffer, Rect, &D) + 'static, )
Like draw, but carries owned per-frame data through
to the deferred closure as a borrow.
Raw-draw closures must be 'static because they run after layout is
computed — which normally forces callers to snapshot any borrowed
state into an owned value before passing it in. draw_with makes
that explicit: hand the snapshot over, borrow it inside the closure.
§Example
let points: Vec<(u32, u32)> = (0..20).map(|i| (i, i * 2)).collect();
ui.container().w(40).h(20).draw_with(points, |buf, rect, points| {
for (x, y) in points {
if rect.contains(*x, *y) {
buf.set_char(*x, *y, '●', Style::new());
}
}
});Sourcepub fn draw_interactive(
self,
f: impl FnOnce(&mut Buffer, Rect) + 'static,
) -> Response
pub fn draw_interactive( self, f: impl FnOnce(&mut Buffer, Rect) + 'static, ) -> Response
Custom drawing with click and hover detection.
Like draw, but the returned Response reports
clicked and hovered based on the laid-out region — exactly like
.col() or .row().
§Example
let resp = ui.container()
.w(40).h(10)
.draw_interactive(|buf, rect| {
buf.set_string(rect.x, rect.y, "Click me!", slt::Style::new());
});
if resp.clicked {
// handle click
}