Skip to main content

max / audiofiles

Measure the file list's context menus against the vocabulary The measurement `0341c7b5` asked for, recorded in `quasi/files.rs`'s header. Three menus, 545 lines, and they split three ways rather than failing as one. `Row::menu` already is a context menu -- its header argues, correctly, that a menu belongs in the description because one description has to become a right-click, a long-press and a key-driven list. The file list is a `Node::Table`, and `Cells` has no counterpart. That asymmetry has been fixed once before in this exact place: `Cells::selected` records that it was deliberately absent "until 2026-08-15", when a consumer arrived. The 14-entry row menu is that sentence about the next field along. The other two menus have no container at all. A menu over the selection and a menu over the surface are not per-row, and `Outcome::Over` makes both app-modal -- which is what the toolbar port already recorded of the save-as-collection popover and what this pass took for the Import menu. Filed in quasicoherent as two tasks, not one: `Cells::menu` is a member with a precedent and a measured consumer, and the anchored menu is a design question with three candidate shapes and four consumers. Neither is implemented here. What is missing is never the contents -- five of the sixteen entries across the two unanchored menus are described at addresses of their own already. It is the gesture and the anchor, both times.
Author: Max Johnson <me@maxj.phd> · 2026-08-17 21:08 UTC
Signed with PGP, not checked
Commit: 012027b5d2a1a897ac340759debdc3fe2b63e3e3
Parent: e794b0f
1 file changed, +44 insertions, -3 deletions
@@ -35,9 +35,50 @@
35 35 //! drag-cooldown state machine so an OS drag that ends outside the window does
36 36 //! not leave egui's pointer state stale. That is a host input problem and
37 37 //! nothing about it is a fact about a sample.
38 - //! - **The waveform, the inline rename, the context menu.** Each is its own
39 - //! screen or its own affordance; folding them in here would make the port
40 - //! about size rather than about shape.
38 + //! - **The waveform and the inline rename.** Each is its own affordance;
39 + //! folding them in here would make the port about size rather than about
40 + //! shape.
41 + //!
42 + //! # The context menus, measured 2026-08-17, and they split three ways
43 + //!
44 + //! `ui/file_list_menus.rs` is 545 lines of three menus — one for the row under
45 + //! the cursor (14 entries), one for the selection (11), one for empty space (5)
46 + //! — and the question asked of them was whether a context menu can be described
47 + //! at all. It can, partly, and where it cannot is two members rather than one
48 + //! vague gap.
49 + //!
50 + //! **`Row::menu` is exactly the first one, on the wrong container.** Its own
51 + //! header says what it is for — "what it *offers*, reached by right-click on a
52 + //! pointer host, long-press on a touch one, and a key in a terminal" — and why
53 + //! that belongs to the description rather than to a renderer: one description
54 + //! has to become a context menu, an action sheet and a key-driven menu, and no
55 + //! single renderer can be where that is said. It is right, and the file list is
56 + //! a [`Node::Table`], whose [`Cells`] has no `menu`.
57 + //!
58 + //! That asymmetry has been corrected once before, in this exact place.
59 + //! `Cells::selected` says it was deliberately absent "on the grounds that no
60 + //! table asked for one and a member added because its sibling has it is a member
61 + //! with no consumer to tell us what it should mean", and that it "was correct
62 + //! until 2026-08-15". This is the same sentence about the next field along, and
63 + //! the consumer that ends it is here: 14 entries, branching on node type, with
64 + //! a submenu. Filed as `quasi:vocabulary:table-row-menu`.
65 + //!
66 + //! **The other two have no container at all.** A menu over the *selection* and a
67 + //! menu over the *surface* are not per-row, and nothing in the vocabulary holds
68 + //! acts back until a host asks for them except `Row::menu`. Described as
69 + //! [`Outcome::Over`](quasi_router::Outcome::Over) they become app-modal
70 + //! overlays, which is what [`toolbar`](super::toolbar) already recorded of the
71 + //! save-as-collection popover — "near enough and not exact" — and what
72 + //! [`importing`](super::importing) took for the Import menu as its second
73 + //! consumer. These are the third and fourth, and they are the ones that make the
74 + //! shape clear: an anchored menu is not a modal, and its subject is whatever it
75 + //! opened over. Filed as `quasi:vocabulary:anchored-menu`.
76 + //!
77 + //! Two of the eleven selection entries and three of the five background entries
78 + //! are described already, at addresses of their own —
79 + //! [`bulk`](super::bulk)'s three modals, [`naming`](super::naming)'s New Folder,
80 + //! [`importing`](super::importing)'s two doors. So what is missing is never the
81 + //! contents. It is the gesture and the anchor, both times.
41 82 //! - **Virtual scrolling.** Recorded in the findings note as renderer policy
42 83 //! from the start: windowing rows the app already holds is a performance
43 84 //! technique, not a described fact.