Skip to main content

GridLayout

Struct GridLayout 

Source
pub struct GridLayout {
    pub titles: HeaderTitles,
    pub cols: u32,
    pub sections: Vec<(u32, &'static str)>,
    pub widgets: Vec<GridWidget>,
    pub cell_size: f32,
    pub width: u32,
    pub height: u32,
    pub resizable: bool,
    pub maximizable: bool,
    pub min_size: (u32, u32),
    pub max_size: (u32, u32),
    pub rows: u32,
    /* private fields */
}
Expand description

Grid-based layout for a plugin UI.

Fields§

§titles: HeaderTitles

Header band titles. Both slots default to None, in which case no header is drawn and the grid starts at y = 0 (plus padding).

§cols: u32

Number of columns in the grid.

§sections: Vec<(u32, &'static str)>

Section labels positioned above specific rows: (row_index, label).

§widgets: Vec<GridWidget>

All widgets placed in the grid.

§cell_size: f32

Cell size in logical points (width and height of one grid cell).

§width: u32

Computed width in logical points.

§height: u32

Computed height in logical points.

§resizable: bool

Whether the host is allowed to drive a resize. Editors honour this via Editor::can_resize; false (default) keeps the layout at its built cols for fixed-size plugins.

§maximizable: bool

Whether the standalone host may maximize the window. Editors honour this via Editor::can_maximize; false (default) removes the maximize affordance so maximizing can’t grow the window past the grid’s max_size into an empty margin. Only meaningful for resizable layouts - a fixed-size layout is pinned regardless. Opt in with .maximizable(true) for layouts that render correctly at any size.

§min_size: (u32, u32)

Lower clamp on host-driven resize requests, as (cols, rows) cell counts. Surfaced via Editor::min_size (converted to logical points by compute_size at the requested cell extent). Defaults to (1, 1).

The call shape (.min_size((a, b))) mirrors truce-egui / truce-iced / truce-slint / truce-vizia so cross-backend editor() impls stay symmetric; the unit is different because the grid is fundamentally cell-snapped (pixels without a cell boundary would just be rounded to one anyway).

§max_size: (u32, u32)

Upper clamp on host-driven resize requests, as (cols, rows) cell counts. Defaults to (u32::MAX, u32::MAX) - effectively unbounded. Same units + call-shape contract as Self::min_size.

§rows: u32

Declared row extent. compute_size takes the larger of this and the widgets’ rightmost row edge, the same way cols works on the width axis - so refit_rows can grow the grid past the rightmost widget’s row with empty trailing space.

Implementations§

Source§

impl GridLayout

Source

pub fn build(entries: Vec<Section>) -> Self

Build a grid layout from sections containing widgets. No header is drawn, cols defaults to the widest section’s widget count (extended to fit any explicitly-positioned widget), and cell_size defaults to GRID_DEFAULT_CELL_SIZE. Override any of those via Self::with_titles / Self::with_cols / Self::with_cell_size.

Each entry is either a Section (created with section("LABEL", vec![...])) or a bare GridWidget (auto-wrapped via From). Example:

GridLayout::build(vec![
    section("LOW", vec![
        GridWidget::knob(P::Freq, "Freq"),
        GridWidget::knob(P::Gain, "Gain"),
    ]),
    GridWidget::knob(P::Output, "Output").into(),
])
Source

pub fn with_cols(self, cols: u32) -> Self

Override the default column count (which is the widest section’s widget count, or whatever explicit positions require - whichever is larger). Use to force wrapping: .with_cols(2) on a 4-widget section produces a 2×2 grid. Recomputes auto-flow placement and window size.

Source

pub fn with_cell_size(self, cell_size: f32) -> Self

Override the default cell size (GRID_DEFAULT_CELL_SIZE). The cell is square - this is both the width and height of one grid cell in logical points.

Source

pub fn with_grid(self, cols: u32, cell_size: f32) -> Self

Like Self::with_cols but accepts the cell size in the same call - useful when both are non-default. Equivalent to .with_cell_size(s).with_cols(c).

Source

pub fn with_titles(self, titles: HeaderTitles) -> Self

Set both header slots at once. Replaces any previously configured titles. Recomputes the height to account for the extra band - width stays the same since the header spans the full grid width.

use truce_gui_types::layout::{GridLayout, HeaderTitles};
GridLayout::build(sections).with_titles(HeaderTitles::pair("EQ", "v0.1"))
Source

pub fn with_title(self, title: &'static str) -> Self

Set the title slot (left, larger / brighter), preserving any previously configured subtitle.

GridLayout::build(sections).with_title("EQ")
Source

pub fn with_subtitle(self, subtitle: &'static str) -> Self

Set the subtitle slot (right, smaller / dimmer), preserving any previously configured title.

GridLayout::build(sections).with_subtitle("v0.1")
Source

pub fn resizable(self, value: bool) -> Self

Opt the layout into host-driven resize. Defaults to false so existing plugins stay pinned at their built column count. When true, the editor honours Editor::set_size by snapping the requested width to the nearest whole cell + gap and re-flowing widgets through Self::refit_cols.

Source

pub fn maximizable(self, value: bool) -> Self

Opt into the standalone host’s maximize button. Defaults to false: maximize is removed on a resizable layout so it can’t grow the window past the grid’s max_size and leave an empty margin around the clamped editor (edge-drag resize within bounds is unaffected). Pass true for layouts that render correctly at any size. Only the standalone host consults this (plugin formats let the DAW own the window frame), and only when resizable(true).

Source

pub fn min_size(self, cells: (u32, u32)) -> Self

Lower clamp on host-driven resize requests, as (min_cols, min_rows) - cell counts, not pixels. Default (1, 1). Set this to keep the editor wide enough for the widest explicitly-positioned widget so column drops don’t clip content, and tall enough for the bottommost widget’s row.

Call shape mirrors truce-egui / truce-iced / truce-slint / truce-vizia’s min_size (single tuple builder) so cross-backend editor() impls stay symmetric; the unit is cells because the grid is fundamentally cell-snapped. Editor::min_size reports the corresponding pixel size so hosts still see logical-point bounds.

Source

pub fn max_size(self, cells: (u32, u32)) -> Self

Upper clamp on host-driven resize requests, as (max_cols, max_rows) - cell counts, not pixels. Default (u32::MAX, u32::MAX). Cap this when the layout looks awkward past a certain stretch on either axis.

Same units / call-shape contract as Self::min_size.

Source

pub fn with_rows(self, rows: u32) -> Self

Pin the natural row extent (in cells, not pixels). Same role on the height axis as Self::with_cols on the width axis: the layout’s height is the larger of this and the rightmost row edge across all widgets, so the editor reserves N cell rows of vertical space even when the widgets don’t fill them all.

Distinct from Self::min_size / Self::max_size (resize bounds in logical points): with_rows declares the natural row count the editor opens at, while min_size / max_size clamp how far the host can resize away from that.

Source

pub fn refit_rows(&mut self, target_h: u32) -> (u32, u32)

Snap target_h to a whole row count and refresh the cached dimensions. Mirror of refit_cols on the height axis. The row count is derived from the height left over after the header band, sections, padding, and trailing label - so the snap is “row-precise” (each row is exactly cell_size + gap tall).

Source

pub fn resize_step(&self) -> u32

Logical-point size of one resize step on either axis - cell_size + GRID_GAP, the same step refit_cols / refit_rows snap to. Both axes share it. Drives the standalone X11 host’s WM resize-increment hint so edge-drags snap to whole cells. Floors at 1 so a degenerate step never produces a zero increment.

Source

pub fn min_snapped_size(&self) -> (u32, u32)

Editor::min_size value: the pixel size of the layout at the smallest allowed (cols, rows) extent declared by Self::min_size. Hosts see this via the format-specific resize-hint RPC (CLAP gui_get_resize_hints, VST3 checkSizeConstraint, etc.).

Source

pub fn max_snapped_size(&self) -> (u32, u32)

Editor::max_size value. u32::MAX per axis means “no cap” and probes at 64 cells - well past any plugin window a host would render, and small enough that the layout math doesn’t overflow.

Source

pub fn refit_cols(&mut self, target_w: u32) -> (u32, u32)

Reflow against a column count derived from the requested logical width: snap the width to the nearest whole cell_size + gap step (so the grid always ends on a cell boundary), clamp the result to [min_cols, max_cols], and re-run auto-flow against the new column count. Returns the resulting (width, height).

The cell pixel size stays put — only the column count changes, so widgets stay at their built size and just re-pack into a wider or narrower grid. Auto-positioned widgets reflow naturally; explicitly-positioned widgets stay at their declared (col, row) (so dropping below their column would clip them, hence the min_cols safeguard).

target_w is interpreted as logical points - same units Editor::set_size works in.

Source

pub fn compute_size(&self) -> (u32, u32)

Compute the window size from the grid.

Trait Implementations§

Source§

impl Clone for GridLayout

Source§

fn clone(&self) -> GridLayout

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for GridLayout

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<PluginLayout> for GridLayout

Source§

fn from(pl: PluginLayout) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.