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:
1 parent
cb098eff75
commit
8c866300d8
12 files changed
+244
-350
No files matched your search
+24
-43
@@ -74,7 +74,6 @@ namespace ui_impl {
|
||||
/// fill, the bar does not.
|
||||
// --- persisted layout -------------------------------------------------------
|
||||
|
||||
/// Defined with the events pane; the trigger toggle reveals it.
|
||||
|
||||
|
||||
// Defined below; the configurations dialog opens a session with them, and it sits above all three.
|
||||
@@ -3007,8 +3006,7 @@ void note_panel_controls(App& app) {
|
||||
// widget tree walked in child order *is* the layout order, so this is the reading order of the
|
||||
// controls the user sees -- the only way to check an arrangement without a screenshot.
|
||||
const std::pair<GtkWidget*, const char*> named[] = {
|
||||
{app.trigger_toggle, "trigger"}, {app.events_toggle, "events"},
|
||||
{app.pause_button, "pause"},
|
||||
{app.trigger_toggle, "trigger"}, {app.pause_button, "pause"},
|
||||
{app.cursors_toggle, "cursors"}, {app.sidebar_toggle, "sidebar"},
|
||||
{app.menu_button, "menu"},
|
||||
};
|
||||
@@ -3631,7 +3629,6 @@ gboolean tick(gpointer user) {
|
||||
}
|
||||
// Outside the lock: it reads and writes the two plots' own windows, not the model.
|
||||
sync_compare_axes(*app);
|
||||
sync_events_divider(*app);
|
||||
// A file on screen is an event, and gets what a held capture gets: the axis pinned to the event's own
|
||||
// `[-pre, +post]` and the trigger instant marked at x = 0. That *is* the constraint -- the time base is
|
||||
// the event's, so no gesture can take the view outside it -- and the window control reads the event's
|
||||
@@ -4932,12 +4929,10 @@ GtkWidget* build_toolbar(App& app) {
|
||||
app.menu_button = GTK_WIDGET(gtk_builder_get_object(ui, "menu_button"));
|
||||
app.sidebar_toggle = GTK_WIDGET(gtk_builder_get_object(ui, "sidebar_toggle"));
|
||||
app.trigger_toggle = GTK_WIDGET(gtk_builder_get_object(ui, "trigger_toggle"));
|
||||
app.events_toggle = GTK_WIDGET(gtk_builder_get_object(ui, "events_toggle"));
|
||||
app.pause_button = GTK_WIDGET(gtk_builder_get_object(ui, "pause_button"));
|
||||
app.cursors_toggle = GTK_WIDGET(gtk_builder_get_object(ui, "cursors_toggle"));
|
||||
if (app.menu_button == nullptr || app.sidebar_toggle == nullptr || app.trigger_toggle == nullptr ||
|
||||
app.events_toggle == nullptr || app.pause_button == nullptr ||
|
||||
app.cursors_toggle == nullptr) {
|
||||
app.pause_button == nullptr || app.cursors_toggle == nullptr) {
|
||||
// A missing id is a mistake in the `.ui`: the bar comes up with the controls it got rather than taking
|
||||
// the window with it, and `[udpscope] header:` reads whatever geometry is left.
|
||||
return bar;
|
||||
@@ -4947,17 +4942,6 @@ GtkWidget* build_toolbar(App& app) {
|
||||
// What each control *does*, which a file cannot hold.
|
||||
g_signal_connect(app.sidebar_toggle, "toggled", G_CALLBACK(on_sidebar_toggled), &app);
|
||||
g_signal_connect(app.trigger_toggle, "toggled", G_CALLBACK(on_trigger_toggled), &app);
|
||||
// The event history is a *trigger* thing, and one click from the mode that produces it.
|
||||
g_signal_connect(app.events_toggle, "toggled", G_CALLBACK(+[](GtkToggleButton* b, gpointer user) {
|
||||
App* a = static_cast<App*>(user);
|
||||
const bool open = gtk_toggle_button_get_active(b);
|
||||
gtk_revealer_set_reveal_child(GTK_REVEALER(a->events_revealer), open);
|
||||
// Through the one function that decides *both*: revealing the child alone leaves an
|
||||
// invisible pane with no width, which is a button that appears to do nothing.
|
||||
sync_events_availability(*a);
|
||||
if (open) refresh_events_pane(*a);
|
||||
}),
|
||||
&app);
|
||||
g_signal_connect(app.pause_button, "toggled", G_CALLBACK(on_pause_toggled), &app);
|
||||
g_signal_connect(app.cursors_toggle, "toggled", G_CALLBACK(on_cursors_toggled), &app);
|
||||
return bar;
|
||||
@@ -4969,7 +4953,7 @@ void on_activate(GtkApplication* application, gpointer user) {
|
||||
install_css();
|
||||
// The window's skeleton is a `.ui` file: the window, its two panes, the plot column with the status
|
||||
// line under it, and the dock's scroller. Everything that depends on the
|
||||
// stream -- the events pane, the two plot areas, the dock's panels -- is built below and put
|
||||
// stream -- the events page, the two plot areas, the dock's panels -- is built below and put
|
||||
// into the slots by id.
|
||||
g_clear_object(&app->window_ui);
|
||||
app->window_ui = gtk_builder_new_from_resource("/org/udpscope/ui/main-window.ui");
|
||||
@@ -4977,7 +4961,6 @@ void on_activate(GtkApplication* application, gpointer user) {
|
||||
app->window = GTK_WIDGET(gtk_builder_get_object(app->window_ui, "main_window"));
|
||||
GtkWidget* side_view = GTK_WIDGET(gtk_builder_get_object(app->window_ui, "side_view"));
|
||||
app->side_view = side_view;
|
||||
GtkWidget* events_divider = GTK_WIDGET(gtk_builder_get_object(app->window_ui, "events_divider"));
|
||||
app->plot_box = GTK_WIDGET(gtk_builder_get_object(app->window_ui, "plot_box"));
|
||||
app->plot_split = GTK_WIDGET(gtk_builder_get_object(app->window_ui, "plot_split"));
|
||||
app->plot_overlay = GTK_WIDGET(gtk_builder_get_object(app->window_ui, "plot_overlay"));
|
||||
@@ -4995,7 +4978,7 @@ void on_activate(GtkApplication* application, gpointer user) {
|
||||
app->badge_system = GTK_WIDGET(gtk_builder_get_object(app->window_ui, "badge_system"));
|
||||
// A missing id is the one mistake neither the build nor `GtkBuilder` sees, and every use below would
|
||||
// be a null pointer.
|
||||
if (app->window == nullptr || side_view == nullptr || events_divider == nullptr ||
|
||||
if (app->window == nullptr || side_view == nullptr ||
|
||||
app->plot_box == nullptr || app->plot_overlay == nullptr || app->plot_split == nullptr ||
|
||||
app->status_badge == nullptr ||
|
||||
app->status_label == nullptr || app->status_info_button == nullptr ||
|
||||
@@ -5195,17 +5178,13 @@ void on_activate(GtkApplication* application, gpointer user) {
|
||||
// `build_source_panels()` has just registered: the Source badge opens the first of them.
|
||||
build_badge_bar(*app);
|
||||
|
||||
// The left side is the events pane *and* the plot, in one row: the pane is a column of its own
|
||||
// (the item's "collapsable pane on the left"), revealed by trigger mode.
|
||||
// A *paned*: the pane's width is the user's to choose, and the plot takes what is left.
|
||||
// The events pane is the one subtree of the inner divider that is built: whether it exists at all
|
||||
// depends on trigger mode.
|
||||
gtk_paned_set_start_child(GTK_PANED(events_divider), build_events_pane(*app));
|
||||
// Once, now that both the button and the pane exist: trigger mode is off, so the pane is closed and
|
||||
// its button is not on the bar -- stated by the one function that decides it rather than by whichever
|
||||
// The full events list is the `events` page of the slide-over (the dock's Manage button opens it), so
|
||||
// the plot is never squeezed by it. Once the page and the dock block both exist: nothing is cached yet,
|
||||
// so both start insensitive -- stated by the one function that decides it rather than by whichever
|
||||
// widget happened to be built with which default.
|
||||
build_events_pane(*app);
|
||||
slideover_add_page(*app, "events", "Events", app->events_box);
|
||||
sync_events_availability(*app);
|
||||
app->events_divider = events_divider;
|
||||
|
||||
// Two plots, in a paned so a comparison's divider can move: the primary takes everything while the
|
||||
// second is hidden, and the width is the user's once it is not.
|
||||
@@ -5715,14 +5694,17 @@ int group_visible_traces(App& app, int row) {
|
||||
return visible;
|
||||
}
|
||||
|
||||
/// The events block's availability as one reading: the rule, the dock block, the page, and the slide-over's
|
||||
/// open page. Every step that changes recording, replay or the cache prints all of them.
|
||||
void report_events_availability(App& a, const char* what) {
|
||||
std::fprintf(stderr, "[events] %s: button_visible=%d pane=%d pane_w=%d tick=%d recording=%d\n",
|
||||
what,
|
||||
a.events_toggle != nullptr && gtk_widget_get_visible(a.events_toggle) ? 1 : 0,
|
||||
a.events_revealer != nullptr &&
|
||||
gtk_revealer_get_reveal_child(GTK_REVEALER(a.events_revealer)) ? 1 : 0,
|
||||
a.events_divider != nullptr ? gtk_paned_get_position(GTK_PANED(a.events_divider)) : -1,
|
||||
signal_tick_visible(a), a.event_recording ? 1 : 0);
|
||||
// `available` is the rule `sync_events_availability()` states; the dock block and the page must both
|
||||
// follow it, and `page` is the slide-over's open page.
|
||||
const bool available = a.event_recording || a.replaying || a.events_cached;
|
||||
std::fprintf(stderr, "[events] %s: available=%d dock_sensitive=%d page_sensitive=%d page=%s\n", what,
|
||||
available ? 1 : 0,
|
||||
a.dock_events_box != nullptr && gtk_widget_get_sensitive(a.dock_events_box) ? 1 : 0,
|
||||
a.events_box != nullptr && gtk_widget_get_sensitive(a.events_box) ? 1 : 0,
|
||||
slideover_page(a).empty() ? "none" : slideover_page(a).c_str());
|
||||
}
|
||||
|
||||
|
||||
@@ -6241,9 +6223,9 @@ int run_ui(int argc, char** argv, const Config& cfg, ScopeModel& model, Acquisit
|
||||
app.dbg_signal_empty_label);
|
||||
}
|
||||
{
|
||||
// The events pane's frame, read from the window: the four widgets the `.ui` gives it, and the list
|
||||
// being inside the revealer the file builds. A control that lost its id reads 0 here rather than
|
||||
// showing as a pane missing a button, and `nested=0` is a list that is no longer in the pane at all.
|
||||
// The events page's frame, read from the window: the widgets the `.ui` gives it, and the list
|
||||
// being inside the box the file builds. A control that lost its id reads 0 here rather than
|
||||
// showing as a page missing a button, and `nested=0` is a list that is no longer in the page at all.
|
||||
const auto inside = [](GtkWidget* w, GtkWidget* root) {
|
||||
if (w == nullptr) return 0;
|
||||
for (GtkWidget* p = w; p != nullptr; p = gtk_widget_get_parent(p)) {
|
||||
@@ -6251,10 +6233,9 @@ int run_ui(int argc, char** argv, const Config& cfg, ScopeModel& model, Acquisit
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
std::printf("[udpscope] events pane: compare=%d accumulate=%d list=%d revealer=%d nested=%d\n",
|
||||
std::printf("[udpscope] events pane: compare=%d accumulate=%d list=%d nested=%d\n",
|
||||
app.events_compare != nullptr ? 1 : 0, app.events_accumulate != nullptr ? 1 : 0,
|
||||
app.events_list != nullptr ? 1 : 0, app.events_revealer != nullptr ? 1 : 0,
|
||||
inside(app.events_list, app.events_revealer));
|
||||
app.events_list != nullptr ? 1 : 0, inside(app.events_list, app.events_box));
|
||||
}
|
||||
std::printf("[udpscope] panels: side=%dx%d (visible=%d) signals=%dx%d row_h=%d "
|
||||
"(page_current=%d) trigger=%dx%d (sensitive=%d) "
|
||||
|
||||
Reference in new issue
Block a user