ui: the events list is a slide-over page; the left pane, its divider and the header toggle are gone

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Martino FerrariandClaude Sonnet 4.6 committed 2026-11-03 07:07:57 +01:00
1 parent cb098eff75
commit 8c866300d8
12 files changed
+244 -350

No files matched your search

+37 -42
View File
@@ -5653,12 +5653,15 @@ gboolean events_probe_step(gpointer user) {
if (a->window == nullptr) return G_SOURCE_REMOVE;
if (a->dbg_events_step == 0) {
// Before anything: streaming, no trigger, recording **off** (the default) -- so no button, no
// pane, and nothing written to disk that the user did not ask to have written.
// Before anything: streaming, no trigger, recording **off** (the default) -- so the dock's block and
// the page are insensitive (on screen, not hidden), and nothing is written to disk that the user did
// not ask to have written. The plot's width is taken here, with no event yet: `plot_w_stable` compares
// it with the width after the first latch.
a->dbg_events_plot_w = a->area_widget != nullptr ? gtk_widget_get_width(a->area_widget) : -1;
report_events_availability(*a, "live, recording off");
// The three clicks a user makes: recording on in the trigger panel, trigger mode on, then the
// history button (which is only there once the first two have happened -- that is the item's rule,
// and this is where it is asserted).
// The clicks a user makes: recording on in the trigger panel, trigger mode on, then the dock's
// Manage button (the `events` page is reachable at any time; it is insensitive until something is
// recorded or cached, and this is where that rule is asserted).
gtk_switch_set_active(GTK_SWITCH(a->events_record_switch), TRUE);
// An 80% pre-trigger share, so the event that latches is *not* symmetric: the window a click
// opens must be the event's own span, and with a symmetric event the live window would look
@@ -5671,27 +5674,19 @@ gboolean events_probe_step(gpointer user) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(a->trigger_toggle), TRUE);
}
report_events_availability(*a, "after trigger on");
if (a->events_toggle != nullptr) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(a->events_toggle), TRUE);
}
// Read straight after the click, before anything else can call the availability rule: this is the
// reading that says the *button* opens the pane, and it is the one a later replay used to mask.
report_events_availability(*a, "after history button");
// ... and again a few frames later, still with no replay in the way: this is the *click alone*
slideover_open(*a, "events");
// Read straight after the open, before anything else can call the availability rule.
report_events_availability(*a, "after events page opened");
// ... and again a few frames later, still with no replay in the way: this is the *open alone*
// path a user takes, which a later replay's own availability call used to mask.
events_probe_next(*a, 5, 500);
return G_SOURCE_REMOVE;
}
if (a->dbg_events_step == 5) {
GtkWidget* box = a->events_revealer != nullptr
? gtk_revealer_get_child(GTK_REVEALER(a->events_revealer))
: nullptr;
std::fprintf(stderr, "[events] click alone: pane=%d pane_w=%d pane_box=%d\n",
a->events_revealer != nullptr && gtk_widget_get_visible(a->events_revealer) ? 1 : 0,
a->events_divider != nullptr ? gtk_paned_get_position(GTK_PANED(a->events_divider))
: -1,
box != nullptr ? gtk_widget_get_width(box) : -1);
std::fprintf(stderr, "[events] open alone: page=%s page_box=%d\n",
slideover_page(*a).empty() ? "none" : slideover_page(*a).c_str(),
a->events_box != nullptr ? gtk_widget_get_width(a->events_box) : -1);
events_probe_next(*a, 1, 2500);
return G_SOURCE_REMOVE;
}
@@ -5748,11 +5743,15 @@ gboolean events_probe_step(gpointer user) {
}
std::fprintf(stderr,
" newest: stem=%s dur=%.6f pre=%.6f post=%.6f edge=%.6f signals=%zu samples=%zu "
"rate=%.6g seq=%llu thumb_bytes=%ld recorded=%d pane=%d",
"rate=%.6g seq=%llu thumb_bytes=%ld recorded=%d page=%d",
r.stem.c_str(), r.duration_s, r.pre_s, r.post_s, r.edge, r.signals, r.samples,
r.rate_hz, static_cast<unsigned long long>(r.seq), thumb_bytes,
a->event_recording ? 1 : 0,
gtk_revealer_get_reveal_child(GTK_REVEALER(a->events_revealer)) ? 1 : 0);
a->event_recording ? 1 : 0, slideover_page(*a) == "events" ? 1 : 0);
// The first latch must not have moved the plot: the list is a slide-over page over the plot's
// edge, and the dock is a fixed column, so nothing about an event changes the plot's width.
const int plot_w_now = a->area_widget != nullptr ? gtk_widget_get_width(a->area_widget) : -1;
std::fprintf(stderr, " plot_w_stable=%d plot_w=%d/%d", plot_w_now == a->dbg_events_plot_w ? 1 : 0,
a->dbg_events_plot_w, plot_w_now);
}
std::fprintf(stderr, "\n");
std::fflush(stderr);
@@ -5799,18 +5798,14 @@ gboolean events_probe_step(gpointer user) {
const int selected_now = int(g_list_length(still));
g_list_free(still);
std::fprintf(stderr,
"[events] activated row0: replaying=%d pane=%d pane_w=%d pane_box=%d tick=%d "
"[events] activated row0: replaying=%d page=%s page_box=%d tick=%d "
"window=%.3f axis=[%.3f,%.3f] marker=%.3f "
"thumbnail=%d thumb_size=%dx%d thumb_visible=%d rows_kept=%d selected=%d/%d\n",
a->replaying ? 1 : 0,
a->events_revealer != nullptr && gtk_widget_get_visible(a->events_revealer) ? 1 : 0,
a->events_divider != nullptr ? gtk_paned_get_position(GTK_PANED(a->events_divider))
: -1,
// The pane's *rendered* width: the position is what we asked for, this is what the
// pane actually got -- a divider at 240 with a zero-width pane is still no pane.
a->events_revealer != nullptr && gtk_revealer_get_child(GTK_REVEALER(a->events_revealer)) != nullptr
? gtk_widget_get_width(gtk_revealer_get_child(GTK_REVEALER(a->events_revealer)))
: -1,
slideover_page(*a).empty() ? "none" : slideover_page(*a).c_str(),
// The page's *rendered* width: what it actually got -- an open page with a zero-width
// list is still no list.
a->events_box != nullptr ? gtk_widget_get_width(a->events_box) : -1,
signal_tick_visible(*a), a->rows->time_window(),
a->rows->row(0).plot != nullptr
? a->rows->row(0).plot->x_range(a->rows->row(0).axis_x).min
@@ -5873,9 +5868,9 @@ gboolean events_probe_step(gpointer user) {
std::fprintf(stderr, "[events] live again: replaying=%d waveform=%d\n", a->replaying ? 1 : 0,
a->waveform_name.empty() ? 0 : 1);
report_live_restored(*a, "after replay");
// The pane's *other* precondition, through the real switch, in both trigger states: disabling
// recording has to take the button and the pane with it, and arming the trigger afterwards must not
// bring back a pane over an empty cache.
// The block's *other* precondition, through the real switch, in both trigger states: disabling
// recording with an empty cache has to grey the dock's block and the page, and arming the trigger
// afterwards must not wake them over an empty cache.
gtk_switch_set_active(GTK_SWITCH(a->events_record_switch), FALSE);
report_events_availability(*a, "recording off, trigger off");
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(a->trigger_toggle), TRUE);
@@ -5901,11 +5896,11 @@ gboolean events_group_probe_step(gpointer user) {
return G_SOURCE_REMOVE;
}
a->dbg_events_wait = 0;
// Open the pane first: its list is only rebuilt while the pane is *up*, so a selection made against
// a collapsed pane selects rows that are not there.
if (a->events_toggle != nullptr &&
!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(a->events_toggle))) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(a->events_toggle), TRUE);
// Open the page first: its list is only rebuilt while the page is *open* (or by the Manage button), so
// a selection made against a closed page selects rows that are not current.
if (slideover_page(*a) != "events") {
refresh_events_pane(*a);
slideover_open(*a, "events");
}
// The selection *is* the input, so select the two newest rows the way a user does and press the
// button: `on_group_clicked()` reads the list, not a parameter.
@@ -5937,13 +5932,13 @@ gboolean events_group_probe_step(gpointer user) {
std::lock_guard<std::mutex> lock(a->model->mutex());
std::fprintf(stderr,
"[events] compare: kind=%d rows=%d channels=%zu samples0=%llu traces0=%d traces1=%d "
"window=%.3f recording=%d pane=%d\n",
"window=%.3f recording=%d page=%s\n",
static_cast<int>(a->group_kind), a->rows->row_count(),
a->model->channels().size(),
static_cast<unsigned long long>(a->model->live().values(0).produced()),
group_visible_traces(*a, 0), group_visible_traces(*a, 1), a->rows->time_window(),
a->event_recording ? 1 : 0,
a->events_revealer != nullptr && gtk_widget_get_visible(a->events_revealer) ? 1 : 0);
slideover_page(*a).empty() ? "none" : slideover_page(*a).c_str());
report_dock_events(*a, "comparison up");
events_group_probe_next(*a, 46, 400);
return G_SOURCE_REMOVE;