ui: a measurement's noise band and HF reject are settable and persisted

Two rows in the measure dialog, built the way the threshold and side rows are and appended
beside them: the band as a percentage of the window's own peak-to-peak (the unit the engine
takes), the corner in Hz with 0 off. They are seeded when editing, shown only where they do
something -- the band for the crossing types, since it moves the edge decision and nothing
else, the reject for all of them, since it sits before both walks -- and read into
`MeasureOptions` on apply.

They persist as two *named* keys, `noise` and `hf`, on the same `o <<` chain as the keys
beside them and read back through the same keyed reader, so a session written before this
change loads with 10.0 and 0.0: today's behaviour exactly, with no version check.

[configs] now proves the round trip rather than assuming it. The probe sets the first
measurement's band and corner to 7.5 and 250 before saving, so a key that never reached the
file reads back as the defaults:

    [configs] round trip read=1 comment='written by the configs probe' ... measures=4 math=0 noise=7.5 hf=250

The rest of that line is unchanged, and the run is free of Gtk-CRITICAL.
This commit is contained in:
Martino Ferrari committed 2026-10-13 15:42:26 +02:00
1 parent 380ddb9a77
commit 84aebf4116
6 files changed
+63 -7

No files matched your search

+22 -3
View File
@@ -1678,15 +1678,32 @@ void open_measure_dialog(App& app, int edit_index) {
GtkWidget* side_row = labelled_row("pulse above level", above, &side_label);
gtk_box_append(GTK_BOX(box), side_row);
// A percentage of the window's own peak-to-peak, which is the unit the engine takes.
GtkWidget* noise = spin(0.0, 50.0, 1.0, 1, 10.0);
// `labelled_row()` writes the label out unconditionally, and these two never retitle, so the
// out-parameters are named and then explicitly unused rather than passed as nullptr.
GtkWidget* noise_label = nullptr;
GtkWidget* noise_row = labelled_row("noise band %", noise, &noise_label);
gtk_box_append(GTK_BOX(box), noise_row);
(void)noise_label;
// 0 is off. The engine clamps to just under the stream's Nyquist, which the dialog cannot know.
GtkWidget* hf = spin(0.0, 1.0e7, 1.0, 3, 0.0);
GtkWidget* hf_label = nullptr;
GtkWidget* hf_row = labelled_row("HF reject Hz", hf, &hf_label);
gtk_box_append(GTK_BOX(box), hf_row);
(void)hf_label;
GtkWidget* show = gtk_check_button_new_with_label("show on plot");
gtk_widget_set_tooltip_text(show,
"draw the result on the plot: a ruler at the level, a marker "
"at the time it happened, the pulse's edges as markers");
gtk_box_append(GTK_BOX(box), show);
auto* d = new MeasureDialog{&app, edit_index, signal_drop, type_drop,
threshold, above, show, window,
threshold_row, threshold_label, side_row, side_label,
auto* d = new MeasureDialog{&app, edit_index, signal_drop, type_drop,
threshold, above, show, window,
threshold_row, threshold_label, side_row, side_label,
noise, noise_row, hf, hf_row,
sig_names};
app.measure_dialog = window;
g_signal_connect(window, "destroy", G_CALLBACK(+[](GtkWidget*, gpointer user) {
@@ -1709,6 +1726,8 @@ void open_measure_dialog(App& app, int edit_index) {
}
}
gtk_spin_button_set_value(GTK_SPIN_BUTTON(threshold), editing->options.threshold_pct);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(noise), editing->options.noise_pct);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(hf), editing->options.hf_fc);
gtk_switch_set_active(GTK_SWITCH(above), editing->options.above);
gtk_check_button_set_active(GTK_CHECK_BUTTON(show), editing->options.show_on_plot);
} else {