Expand description
Columns, narrowing, cell parts and the sort caret, over egui_extras.
makeover-webview’s list module and makeover-tui’s table in the shape
immediate mode allows. It owns the same four things: which columns exist, how
wide they are, which ones survive a narrow viewport, and what each part of a
cell is. It does not own what goes in a cell, which here is not a policy but
a fact of the mode: a cell’s contents are drawn by the app’s own closure, the
way group already takes one per field.
§Why egui_extras and not egui
egui itself has no table. egui::Grid gives no per-column sizing, no
sticky header and no scroll sync, which is why audiofiles reached for
egui_extras::TableBuilder rather than building on Grid. Writing a third
answer here would be reimplementing that crate worse, so this is a mapping
layer over it.
It is the first dependency this crate has taken beyond egui itself, and it moves in lockstep with egui’s own version, which is the cost worth naming.
§What immediate mode costs the narrowing
The terminal renderer measures a Width::Content column from its cells,
because it holds every cell before it draws any. Here the cells do not exist
until the app’s closure runs, so nothing can be measured before the layout is
decided.
That splits the answer in two, and both halves are honest:
- Sizing hands a content column to
egui_extras::Column::auto, which measures it and holds the result between frames. This is better than the terminal gets, not worse. - Narrowing cannot wait for that, so it budgets every column at its
declared
floor, inchof the body face. A column that turns out wider than its floor is still drawn; it is the decision to drop that uses the declared number, and it is the number the terminal counts in cells and the webview hides a column under, so the three drop together.
§The table model
Wiki table-model, drawn the way makeover-webview draws it, since egui
paints the same pixels a browser does: a raised ground inside a hairline
frame, the header a sunken strip over a bevel-dark edge in secondary
capitals, rows 45 points tall with a hairline between them, a stripe on
every second row and a tone under the pointer. A table holding a
ColumnKind::Code column keeps the frame and the header and drops the
stripe, the hairlines and the tall row.
The row fills are painted here rather than by egui_extras, for two reasons
the crate cannot be configured past. Its stripe falls on the first row where
the model’s falls on the second, and its selection repaints the row’s text
in the selection stroke, which loses a failed row’s red on exactly the row
the user picked. A selected row takes row-selected behind its text and
nothing else.
§Why positions are the bug
Carried from the other two renderers, because the mistake is not a CSS
mistake and not a terminal one. goingson hides its mobile columns with
nth-child(n+5) against a seven-column table; insert a column left of the
cut and the wrong one disappears, silently. A renderer narrows by raising a
cutoff and never by counting.
Structs§
- Body
- The body’s own facts for this frame: how many rows, which are selected, and which one to bring into view.
- Sizing
- The lengths the description deferred, in points.
- Table
Style - The tones and metrics a table draws with.
Functions§
- cell
- Draw a cell’s contents with the tone its part takes.
- cutoff_
for - The weakest cutoff whose columns fit in
width. - heading
- The heading, in capitals, with the caret if the table is ordered by this column.
- part_
color - The colour a cell of this part takes.
- table
- A described table, narrowed for the width available.