Expand description
The immediate-mode renderer for makeover_layout.
Named for the mode, not the library, the way makeover-tui is named for
the target and not for ratatui. Immediate mode is the constraint that
actually separates this renderer from the other two, and egui is the
backend it is written against.
It is the harshest renderer the description has to survive: no
box-shadow, no inset, no cascade, no retained tree to mutate, and
Visuals.widgets.*.bg_stroke is a single stroke with no per-side control.
A two-tone lit edge is not something egui can be configured into producing,
so it gets painted by hand here, once, instead of in every consuming app.
§What this crate does and does not own
It owns the expression: two mitred polylines for a bevel and a Frame
for a filled region. It owns no colours and no sizes, and no longer owns a
substitution: it briefly supplied the page for a well, which was a stand-in
for surface-well before makeover derived it, and every consumer reads the
real token now. Palette is supplied by the caller,
already resolved, and every radius, margin and stroke width arrives in
FrameStyle.
That split is why the crate has no dependency on makeover itself: the app
already resolves a theme, and coupling a renderer to a colour crate’s
version would buy nothing.
§The cascade is the real difference
A stylesheet can say “a pressed button inverts its bevel” once and let the
cascade carry it. An immediate-mode renderer has nowhere to put that, so
every call site decides. makeover_layout::Depth::pressed is what keeps
the decision from being re-derived per widget.
§0.11.0: the overlay becomes reachable
0.10.0 answered what overlaying means in immediate mode with
Palette::cast, and nothing could ask: the description had no
Depth::Overlay until makeover-layout 0.14.0, so the answer sat beside a
question that could not be posed. frame now hands the cast shadow to the
egui::Frame for any depth whose fill is Fill::Overlay, keyed off the
fill rather than the variant.
The same release brings makeover_layout::CellPart, which 0.11.0 carried
and did not draw. table draws it, below.
§0.12.0: the table
table is the vocabulary 0.11.0 took without using. The consumer is
audiofiles, whose file list is the only table in the tree exercising all four
of what the description says about one at once: sortable headings with
carets, fixed and remainder tracks, and buttons inside cells.
Two things it forces, both named where they land:
egui_extras, this crate’s first dependency past egui. egui has no table, andGridgives no per-column sizing, no sticky header and no scroll sync, which is why audiofiles reached foregui_extrasrather than building onGrid. A third answer here would reimplement that crate worse.Palette::action, on the footingPalette::contentarrived on: a link in a cell is the first thing here needing the action intent.
Narrowing works differently from the terminal’s and the module header says
why: a content column cannot be measured before the app’s closure has drawn
it, so egui_extras sizes it and the declared floor budgets it.
§0.13.0: what the adoption found missing
0.12.0 shipped table before audiofiles had taken it, and taking it found
three things the file list already did that the function could not say. All
three are host idiom rather than description, which is why they land here and
not in makeover-layout, and all three are answered on a handle the app
never sees: the egui_extras row and builder this crate owns. That is
table::cell’s reasoning again: what the app cannot reach, the renderer
owes it.
- A selected row.
table::Body::selected, a predicate asked per row, becauseset_selectedis a method on the row. Without it a file list has no way to show what is selected, which is most of what a file list does. - Scrolling a row into view.
table::Body::scroll_to, becausescroll_to_rowis a method on the builder. A keyboard cursor that moves off-screen and stays there is the bug this prevents. - Dragging a divider.
table::TableStyle::resizable, which passes the teststicky_headerfailed in 0.12.0: egui_extras offers two settings here and a renderer can honestly make either choice.
A fourth was found and is not a knob. Cells are centred on the row’s centre line, always, because there is no second honest answer and egui’s own default (top-aligned) is the one thing it cannot be.
table::Body is also what splits a table’s per-frame facts from its
description and from its style. A row count, a selection and a scroll request
are none of them style, and none of them survive the frame.
§Forms
0.5.0 adds the field vocabulary on top of the depth vocabulary:
makeover_layout::Field rendered to egui widgets, in field, and a set
of them laid down a column in group. Before it, a description saying
“text field, labelled, required, with this hint” had no way to become a
widget here, and audiofiles’ forms stayed hand-rolled.
makeover-webview got there first and its form emitter is the precedent
followed rather than re-derived, including the parts that are bug fixes: a
select handed a value none of its options carries keeps that value visible
instead of silently reading as the first option, which is a save-the-wrong-
thing bug goingson hit for real.
What differs is forced by the mode and not chosen:
- The value arrives as a
&mut.Fillingborrows the app’s own field and the widget writes through it. There is no DOM to read back out of, which is also why the description deliberately does not carry the value. - A text control is drawn as a well and a select is not. The description holds that a well is for anything the user looks into, and a text field is its own example; a select and a checkbox are pressed rather than looked into, so they keep egui’s own control painting.
makeover_layout::State::Focusis not drawn here. egui already paints exactly one focus stroke, and the description’s rule is one ring rather than a ring per primitive, so adding a second would break the rule it came from.makeover_layout::State::Disabledis drawn, because egui has no opinion about it until told.
Modules§
- table
- Columns, narrowing, cell parts and the sort caret, over
egui_extras. Columns, narrowing, cell parts and the sort caret, overegui_extras.
Structs§
- Field
Style - The geometry a field group is drawn with.
- Frame
Style - The geometry a framed region is drawn with.
- Palette
- The resolved colours this renderer needs, as flat values.
Enums§
- Filling
- What the field currently holds, borrowed from wherever the app keeps it.
Functions§
- field
- One field, as the column the app drops into its form.
- frame
- Draw a region at a given
Depth: its fill and its edge, together. - group
- A set of fields, laid down a column.
- paint_
bevel - Paint a two-tone edge just inside
rect.