A batch of view and instrument work, with the probes and docs for each.
- **Full screen per figure row**: a toggle on each row's top-right corner, revealed by
pointer proximity (`kMaximizeRevealPx` around its placed rect, per row, read from an
overlay-level motion controller so a revealed button under the pointer cannot flicker);
the plot menu offers the same as *Full screen this figure* / *Restore the layout*. The
arrangement is saved and restored through `RowState`, so nothing plotted moves. A layout
of one figure carries no toggle.
- **Second window**: `open_scope_window()` copies a figure (cells, width shares, signals in
their colours) or opens an empty one, with its own `RowSet` and `PlotArea`; the main
window's tick binds, acquires and repaints it, mirroring the time window and pin. Entries:
the plot menu's *Open this plot in a new window* and the overflow menu's *New scope window*.
- **Layout editor from the plot**: the plot menu gains *Edit the layout...* / *Done editing
the layout*, flipping the app's one toggle.
- **Measurements gate**: `MeasureOptions::gate` restricts a measurement to the held/pause
snapshot (live falls back to the live ring), persisted with the session and shown in the
measure dialog.
- **Crosshair axis badges**: a preference (`crosshair_axis_labels`, on by default) and the
plotter's badges where the lines meet the axes, in the axes' own formats; the plot menu
and the probe read them.
- **Event cache per configuration**: `EventStore` is keyed `<source>/<configuration>/`,
`retarget_event_store()` follows every configuration switch, and a pre-configuration cache
(loose files) is adopted into the configuration's folder on first start.
- **GTK4 lifecycle**: the main window's handlers move from the non-existent `"destroy"`
signal to `close-request`; scope windows are closed with it and the application quits
explicitly (the exit run's hang). The exit probe closes with `gtk_window_close()`.
- Probes: `[maximize-probe]` (single-figure rule and the corner reveal), `[scope-probe]`,
`[split-probe]` cell crosshair leg, `[prefs-probe]` store keying, `[configs]` store key,
`[rowmenu]` layout-editor entry; docs, help pages, README and AGENT.md updated.
Also fixes a probe-only use-after-free: `toggle_maximize_figure_row` replaces the figure
object, so the area must be re-pointed (the button's path does; the probe's raw call did not).
The panel's shape -- the title row with its add button, the one statistics switch
the whole panel shares, and the box the readings go into -- now lives in
src/ui/measures-panel.ui. The readings stay in code: each row is a measurement a
user placed, rebuilt whenever the set or the mode changes.
A faithful move, not a redesign: the same margins, spacing, labels, tooltips, flat
classes and insensitive Reset button, the same two lambdas on the same two signals.
The frame is read back through the dump line, which grew the two fields that can
disagree with the code that drives them -- `measures pane: n=4 revealed=0
marks_shown=6 pane_rows=4 pane_w=0 pane_h=0 switch_on=1 reset_sensitive=1`. In that
reading pane_rows=4 is the four readout rows having landed in the frame's
`measures_list`, and switch_on/reset_sensitive are the switch widget and the Reset
button following measure_stats_on, which the probe set through the same signal a user
would. `check_ui` type-checks the file (8 ok, 0 failed) and the build stays at four
warnings.