Files
udpscope/src/ui/measures-panel.ui
T
Martino Ferrari bdf0ff7ddc scope: full-screen figures, second windows, gated measurements, per-configuration events
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).
2026-11-05 17:58:59 +01:00

74 lines
3.2 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!-- SPDX-License-Identifier: MIT -->
<!-- SPDX-FileCopyrightText: 2026 Martino Ferrari -->
<!--
The measurements panel: a title row with the button that adds one, the one statistics switch the whole
panel shares, and the box the readings go into.
The readings are not here. Each one is a measurement the user placed — its name, its markers and its
readout row — so the rows are built and rebuilt in code, and this file holds the frame they land in
(`measures_list`) plus the three widgets whose state outlives them.
One statistics switch for the panel rather than one per reading: statistics are either what a user
is looking at or they are not, and a per-row switch is a column of chrome paid for on every row to
answer a question asked once. The gate is the opposite case — a per-measurement choice — so it
lives in the measurement dialog, not here.
-->
<interface>
<object class="GtkBox" id="measures_panel">
<property name="orientation">vertical</property>
<property name="spacing">4</property>
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<property name="margin-start">6</property>
<property name="margin-end">6</property>
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<property name="spacing">8</property>
<child>
<object class="GtkLabel" id="measures_title">
<property name="label" translatable="yes">Measurements</property>
<property name="halign">start</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkButton" id="measures_add">
<property name="icon-name">list-add-symbolic</property>
<property name="css-classes">flat</property>
<property name="tooltip-text" translatable="yes">add a measurement</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<property name="spacing">8</property>
<child>
<object class="GtkCheckButton" id="measures_stats_check">
<property name="label" translatable="yes">Statistics</property>
<property name="hexpand">1</property>
<property name="tooltip-text" translatable="yes">show how each reading has varied: passes, mean, standard deviation and extremes, under the reading itself</property>
</object>
</child>
<child>
<object class="GtkButton" id="measures_stats_reset">
<property name="label" translatable="yes">Reset</property>
<property name="css-classes">flat</property>
<property name="sensitive">0</property>
<property name="tooltip-text" translatable="yes">start every measurement's statistics again from the next pass</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="measures_list">
<property name="orientation">vertical</property>
<property name="spacing">2</property>
</object>
</child>
</object>
</interface>