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).
129 lines
7.0 KiB
XML
129 lines
7.0 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!-- SPDX-License-Identifier: MIT -->
|
|
<!-- SPDX-FileCopyrightText: 2026 Martino Ferrari -->
|
|
<!--
|
|
The preferences, as an AdwPreferencesDialog: pages of groups of rows, which is what every GNOME
|
|
application shows and what libadwaita's own widgets are for. The rows are AdwEntryRow, AdwSpinRow,
|
|
AdwSwitchRow, AdwComboRow and AdwButtonRow rather than a label and a bare GtkEntry in a GtkBox, so
|
|
they behave the way a reader expects — each one is a whole row, with its own title, an optional
|
|
subtitle underneath, and the editing widget on the right where a finger expects it.
|
|
|
|
**There is no Apply button, deliberately.** A preferences row applies as it changes, which is the
|
|
practice these widgets are designed around and why they carry an `apply` of their own (AdwEntryRow's
|
|
show-apply-button is off here: the write is a few bytes to one file, so a keystroke is not worth
|
|
batching). The two settings that cannot take effect immediately — the cache directory and relative
|
|
time, both of which are planned before any source is known — say so in their subtitles instead of
|
|
being held back by a button. The memory limit does take effect at once: a running buffer re-plans.
|
|
|
|
Nothing here carries a value: `ui_prefs.cpp` fills the rows from `Settings` when the dialog opens,
|
|
and writes it back on every change. This file is the shape, that is the state.
|
|
-->
|
|
<interface>
|
|
<object class="AdwPreferencesDialog" id="preferences">
|
|
<property name="title" translatable="yes">Preferences</property>
|
|
<property name="search-enabled">0</property>
|
|
<child>
|
|
<object class="AdwPreferencesPage">
|
|
<property name="title" translatable="yes">Event cache</property>
|
|
<property name="icon-name">udpscope-events-symbolic</property>
|
|
<property name="description" translatable="yes">Latches are written here as they happen; whether anything is written at all is the trigger panel's own switch.</property>
|
|
<child>
|
|
<object class="AdwPreferencesGroup">
|
|
<child>
|
|
<object class="AdwEntryRow" id="dir_row">
|
|
<property name="title" translatable="yes">_Directory</property>
|
|
<property name="use-underline">True</property>
|
|
<property name="tooltip-text" translatable="yes">One directory in which every source gets a folder of its own, never one directory between two sources</property>
|
|
</object>
|
|
</child>
|
|
<child>
|
|
<object class="AdwSpinRow" id="keep_row">
|
|
<property name="title" translatable="yes">Keep _events</property>
|
|
<property name="use-underline">True</property>
|
|
<property name="subtitle" translatable="yes">Per source; 0 keeps every event, which is a decision about the disk</property>
|
|
<property name="adjustment">
|
|
<object class="GtkAdjustment">
|
|
<property name="lower">0</property>
|
|
<property name="upper">100000</property>
|
|
<property name="step-increment">1</property>
|
|
<property name="value">32</property>
|
|
</object>
|
|
</property>
|
|
</object>
|
|
</child>
|
|
</object>
|
|
</child>
|
|
</object>
|
|
</child>
|
|
<child>
|
|
<object class="AdwPreferencesPage">
|
|
<property name="title" translatable="yes">Plot</property>
|
|
<property name="icon-name">udpscope-measure-symbolic</property>
|
|
<child>
|
|
<object class="AdwPreferencesGroup">
|
|
<child>
|
|
<object class="AdwSwitchRow" id="relative_row">
|
|
<property name="title" translatable="yes">_Relative time</property>
|
|
<property name="use-underline">True</property>
|
|
<property name="subtitle" translatable="yes">Take the plot's time from the sample rate and the packet counter rather than from the stream's own clock, so arrival and clock jitter cannot move a sample; absolute time is still kept for export. Read at start-up, because the buffers are planned before any source is known.</property>
|
|
</object>
|
|
</child>
|
|
<child>
|
|
<object class="AdwSwitchRow" id="crosshair_axis_labels_row">
|
|
<property name="title" translatable="yes">Crosshair _axis labels</property>
|
|
<property name="use-underline">True</property>
|
|
<property name="subtitle" translatable="yes">Show the value and the time where the crosshair's lines meet the axes, each in its axis' own format, in the strips the tick labels are written in. Applies at once.</property>
|
|
</object>
|
|
</child>
|
|
<child>
|
|
<object class="AdwComboRow" id="theme_row">
|
|
<property name="title" translatable="yes">_Theme</property>
|
|
<property name="use-underline">True</property>
|
|
<property name="subtitle" translatable="yes">What the interface looks like; auto follows the system</property>
|
|
</object>
|
|
</child>
|
|
</object>
|
|
</child>
|
|
<child>
|
|
<object class="AdwPreferencesGroup">
|
|
<property name="title" translatable="yes">Sample buffer</property>
|
|
<child>
|
|
<object class="AdwSpinRow" id="memory_row">
|
|
<property name="title" translatable="yes">_Memory limit (MB)</property>
|
|
<property name="use-underline">True</property>
|
|
<property name="subtitle" translatable="yes">Hard ceiling on the memory of the sample rings, all signals together. A source asks for a number of samples per signal; if that does not fit under this limit it is halved until it does, and the status line says so. Applies at once: a running buffer is re-planned, which clears its history.</property>
|
|
<property name="adjustment">
|
|
<object class="GtkAdjustment">
|
|
<property name="lower">16</property>
|
|
<property name="upper">1048576</property>
|
|
<property name="step-increment">256</property>
|
|
<property name="page-increment">1024</property>
|
|
<property name="value">8192</property>
|
|
</object>
|
|
</property>
|
|
</object>
|
|
</child>
|
|
</object>
|
|
</child>
|
|
</object>
|
|
</child>
|
|
<child>
|
|
<object class="AdwPreferencesPage">
|
|
<property name="title" translatable="yes">Reset</property>
|
|
<property name="icon-name">view-refresh-symbolic</property>
|
|
<child>
|
|
<object class="AdwPreferencesGroup">
|
|
<child>
|
|
<object class="AdwButtonRow" id="reset_row">
|
|
<property name="title" translatable="yes">_Reset to defaults</property>
|
|
<property name="use-underline">True</property>
|
|
<property name="start-icon-name">view-refresh-symbolic</property>
|
|
</object>
|
|
</child>
|
|
</object>
|
|
</child>
|
|
</object>
|
|
</child>
|
|
</object>
|
|
</interface>
|