fix: a statistics line elides its own text, the toggle handler is guarded, and the doc comment names both labels

- The statistics label in measures_row() now carries PANGO_ELLIPSIZE_END,
  matching the kind label's own treatment, so a long reading cannot widen
  the pane beyond its measured minimum.
- The toggled handler on measures_stats_check now returns early when
  updating_panels is set; apply_layout() sets updating_panels around its
  gtk_check_button_set_active() call and then sets the Reset button's
  sensitivity directly, so the loaded state is fully applied without a
  spurious schedule_layout_save().
- The measures_row() header comment now names both labels that
  update_measures() rewrites and explains the two-line layout.
- gtk_widget_set_sensitive on measures_stats_reset is null-checked in the
  toggled handler, matching every neighbouring handler in the file.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Martino FerrariandClaude Sonnet 4.6 committed 2026-10-08 09:44:04 +02:00
1 parent 4f496b14b7
commit 2cee85c52b
1 file changed
+15 -2
+15 -2
View File
@@ -817,10 +817,17 @@ void apply_layout(App& app, const LayoutState& st) {
apply_math_channels(app);
app.measures = st.measures;
app.measure_stats_on = st.measure_stats;
app.updating_panels = true;
if (app.measures_stats_check != nullptr) {
gtk_check_button_set_active(GTK_CHECK_BUTTON(app.measures_stats_check),
app.measure_stats_on);
}
// The toggled handler is guarded by updating_panels, so the Reset button's sensitivity
// and the stats-label visibility are set directly from the loaded state here; the labels'
// visibility is also set per-row inside rebuild_measures_pane via measures_row().
if (app.measures_stats_reset != nullptr)
gtk_widget_set_sensitive(app.measures_stats_reset, app.measure_stats_on);
app.updating_panels = false;
rebuild_measures_pane(app);
int rows = static_cast<int>(st.rows.size());
@@ -2615,8 +2622,9 @@ void update_measures(App& app, bool force);
void open_measure_dialog(App& app, int edit_index);
/// One pane row: the measurement's badge, its type, its value and an `edit` button. The value
/// label is the one widget `update_measures()` rewrites; everything else is rebuilt with the
/// list.
/// label and the statistics line below it are the two widgets `update_measures()` rewrites;
/// everything else is rebuilt with the list. The row is two visual lines so that the
/// statistics figures do not push the reading itself off a narrow pane.
GtkWidget* measures_row(App& app, std::size_t index, const Measure& m) {
// The row is two lines: the reading, and the statistics under it. A vertical wrapper
// rather than more columns, because the statistics line is four figures wide and would
@@ -2683,6 +2691,9 @@ GtkWidget* measures_row(App& app, std::size_t index, const Measure& m) {
gtk_widget_set_halign(stats, GTK_ALIGN_END);
gtk_widget_add_css_class(stats, "dim-label");
gtk_label_set_selectable(GTK_LABEL(stats), true);
// Ellipsize so the label's minimum width is bounded: without this, a long reading would
// widen the pane just as the `kind` label would without its own ellipsize.
gtk_label_set_ellipsize(GTK_LABEL(stats), PANGO_ELLIPSIZE_END);
gtk_widget_set_tooltip_text(stats,
"how this reading has varied since the last reset: the number "
"of passes, the mean, the standard deviation, and the extremes");
@@ -5140,12 +5151,14 @@ GtkWidget* build_measures_panel(App& app) {
g_signal_connect(app.measures_stats_check, "toggled",
G_CALLBACK(+[](GtkCheckButton* b, gpointer user) {
App* a = static_cast<App*>(user);
if (a->updating_panels) return;
a->measure_stats_on = gtk_check_button_get_active(b);
// Deliberately *not* a rebuild: that would reset the statistics the
// user just asked to look at. The rows are already there and hidden.
for (GtkWidget* w : a->measure_stats_labels) {
if (w != nullptr) gtk_widget_set_visible(w, a->measure_stats_on);
}
if (a->measures_stats_reset != nullptr)
gtk_widget_set_sensitive(a->measures_stats_reset, a->measure_stats_on);
update_measures(*a, true);
schedule_layout_save(*a);