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).
This commit is contained in:
1 parent
bfe13630f9
commit
bdf0ff7ddc
39 files changed
+2267
-136
No files matched your search
+11
-1
@@ -573,6 +573,11 @@ bool load_layout(const std::string& path, LayoutState& out) {
|
||||
}
|
||||
} else if (key == "measure_stats") {
|
||||
st.measure_stats = value == "true";
|
||||
} else if (key == "gate_x0" || key == "gate_x1") {
|
||||
try {
|
||||
(key == "gate_x0" ? st.gate_x0 : st.gate_x1) = std::stod(value);
|
||||
} catch (...) {
|
||||
}
|
||||
} else if (key == "dock") {
|
||||
st.dock_shown = value == "true";
|
||||
} else if (key.rfind("trigger_", 0) == 0) {
|
||||
@@ -685,6 +690,8 @@ bool load_layout(const std::string& path, LayoutState& out) {
|
||||
m.options.above = value == "true";
|
||||
} else if (key == "show") {
|
||||
m.options.show_on_plot = value == "true";
|
||||
} else if (key == "gate") {
|
||||
m.options.gate = value == "true";
|
||||
}
|
||||
} else if (section == Section::Calibration && !st.calibration.empty()) {
|
||||
if (key == "name") {
|
||||
@@ -762,6 +769,8 @@ bool save_layout(const std::string& path, const LayoutState& state) {
|
||||
o << "]\n";
|
||||
}
|
||||
o << "measure_stats = " << (state.measure_stats ? "true" : "false") << "\n";
|
||||
o << "gate_x0 = " << state.gate_x0 << "\n";
|
||||
o << "gate_x1 = " << state.gate_x1 << "\n";
|
||||
o << "dock = " << (state.dock_shown ? "true" : "false") << "\n";
|
||||
// The trigger, settings and state both. Written even when it is off: that is the point of it.
|
||||
o << "trigger_enabled = " << (state.trigger.enabled ? "true" : "false") << "\n";
|
||||
@@ -841,7 +850,8 @@ bool save_layout(const std::string& path, const LayoutState& state) {
|
||||
<< "\nthreshold2 = " << m.options.threshold_pct2
|
||||
<< "\nabove = " << (m.options.above ? "true" : "false") << "\nshow = "
|
||||
<< (m.options.show_on_plot ? "true" : "false") << "\nnoise = " << m.options.noise_pct
|
||||
<< "\nhf = " << m.options.hf_fc << "\n";
|
||||
<< "\nhf = " << m.options.hf_fc
|
||||
<< "\ngate = " << (m.options.gate ? "true" : "false") << "\n";
|
||||
}
|
||||
|
||||
// A sibling temp file + rename: a crash mid-write leaves the old layout, not a
|
||||
|
||||
Reference in new issue
Block a user