ui: the cursors and measurements panels are slide-over pages; the dock is the readouts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Martino FerrariandClaude Sonnet 4.6 committed 2026-11-03 06:24:52 +01:00
1 parent a0fc0762d5
commit 3d307a0185
5 files changed
+91 -154

No files matched your search

+22 -32
View File
@@ -2866,20 +2866,6 @@ void on_right_click(GtkGestureClick* gesture, int, double x, double y, gpointer
open_row_menu(*app, row, x, y, widget);
}
/// Scrolls the dock to a section. The dock is one scroller (`App::dock_scroller`) holding the cursors and
/// the measurements top to bottom, so "measure" is the cursors panel's offset in the page. Nothing is
/// hidden or removed: both stay in the page. An unknown name (the signal list is a slide-over page now,
/// not a dock section) is a no-op, so a key bound to a section a later version drops cannot blank anything.
void dock_show_section(App& app, const char* section) {
if (app.dock_scroller == nullptr || app.dock_page == nullptr || section == nullptr) return;
GtkAdjustment* adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(app.dock_scroller));
if (std::strcmp(section, "measure") != 0 || app.cursors_panel == nullptr) return;
graphene_point_t zero = GRAPHENE_POINT_INIT(0.f, 0.f);
graphene_point_t at;
if (!gtk_widget_compute_point(app.cursors_panel, app.dock_page, &zero, &at)) return;
gtk_adjustment_set_value(adj, at.y);
}
/// The dock is on when the user's sidebar button is in -- from the start, with or without signals; the
/// two panel buttons appear as soon as a CONFIG describes any signal at all.
void update_side_visibility(App& app) {
@@ -3437,7 +3423,9 @@ gboolean tick(gpointer user) {
}
}
// Captured every frame so the dump has the last live value: see `dbg_measures_pane_w`.
if (app->measures_list != nullptr) {
// Only while the `measure` page is on screen: a closed page has no allocation, and the dump should
// keep the last real size rather than 0.
if (app->measures_list != nullptr && gtk_widget_get_width(app->measures_list) > 0) {
app->dbg_measures_pane_w = gtk_widget_get_width(app->measures_list);
app->dbg_measures_pane_h = gtk_widget_get_height(app->measures_list);
}
@@ -3993,7 +3981,7 @@ gboolean tick(gpointer user) {
// The one thing that has to be decided *per frame* about the dock: whether there is room for it
// beside the plot. Collapsed, the split view puts it *over* the plot rather than giving it a share of
// a width that is not there -- so a small window shows fewer pixels of plot, never a panel squeezed
// to nothing. `kSidebarRoom` is the sidebar's 320 plus the width below which the plot stops being
// to nothing. `kSidebarRoom` is the sidebar's 280 plus the width below which the plot stops being
// worth looking at.
if (app->side_view != nullptr && app->window != nullptr) {
// The split view writes `show-sidebar` itself (at startup and when it collapses), so the wish is
@@ -4656,7 +4644,7 @@ void run_app_action(App& app, AppAction action) {
case AppAction::CursorsPane:
toggle(app.cursors_toggle);
break;
case AppAction::ShowMeasure: dock_show_section(app, "measure"); break;
case AppAction::ShowMeasure: slideover_toggle(app, "measure"); break;
case AppAction::ShowSignals: {
// The `+` badge is insensitive without signals; so is its shortcut.
bool have_signals = false;
@@ -5038,7 +5026,7 @@ void on_activate(GtkApplication* application, gpointer user) {
// The size the window opens at, stated in code as well as in the `.ui`: `default-width` there is the
// size it *asks* for, and a window whose content has a larger minimum opens at that minimum instead --
// 756 px here, the plot column's own minimum plus the sidebar's 320. The old code set it explicitly;
// 756 px here, the plot column's own minimum plus the sidebar's 280. The old code set it explicitly;
// this is where it went when the window moved into the file, and it is why the window came up small.
gtk_window_set_default_size(GTK_WINDOW(app->window), 1280, 800);
@@ -5140,15 +5128,16 @@ void on_activate(GtkApplication* application, gpointer user) {
gtk_popover_set_has_arrow(GTK_POPOVER(app->status_popover), TRUE);
}
// The right-hand side is the dock: one scroller, the cursors then the measurements. Every section is
// always there -- "go to Measure" scrolls to it instead of switching a tab, so the measurements are as
// live as the cursors above them. The signal list is a slide-over page (reached by the `+` badge).
// The right-hand side is the dock: one scroller holding only the compact read-only readouts (the
// cursors table and the measurements). The full Cursors and Measurements panels are slide-over pages
// (`cursors`, `measure`), live whether or not they are open: the pages hold the same widgets and the
// tick writes them either way. The signal list is a page too (reached by the `+` badge).
// `side` and `dock_page`/`dock_scroller` are resolved above with the rest of the skeleton and checked
// by the null guard; assign the member here.
app->side_box = side;
// Built in the order the panels have always been (cursors, measurements, trigger, signals) and placed in
// the dock's: the trigger form goes to the slide-over (reached by the Trigger badge).
// Built in the order the panels have always been (cursors, measurements, trigger, signals); each is a
// page of the slide-over, reached by its badge, its key or the header's Cursors toggle.
app->cursors_panel = build_cursors_panel(*app);
GtkWidget* measures_panel = build_measures_panel(*app);
app->trigger_panel = build_trigger_panel(*app);
@@ -5160,13 +5149,14 @@ void on_activate(GtkApplication* application, gpointer user) {
// `build_slideover`, and registered once.
app->signal_panel = build_signal_panel(*app);
slideover_add_page(*app, "signals", "Signals", app->signal_panel);
gtk_box_append(GTK_BOX(app->dock_page), app->cursors_panel);
gtk_box_append(GTK_BOX(app->dock_page), gtk_separator_new(GTK_ORIENTATION_HORIZONTAL));
gtk_box_append(GTK_BOX(app->dock_page), measures_panel);
// The compact readouts above the full panels (which move to slide-over pages later), with their own
// separator: the first child of the dock.
gtk_box_prepend(GTK_BOX(app->dock_page), gtk_separator_new(GTK_ORIENTATION_HORIZONTAL));
gtk_box_prepend(GTK_BOX(app->dock_page), build_readouts_dock(*app));
// `c` / the header toggle drive the cursors themselves; this page is where they are configured and read
// in full. `m` toggles the measurements page.
gtk_widget_set_valign(app->cursors_panel, GTK_ALIGN_START);
gtk_widget_set_valign(measures_panel, GTK_ALIGN_START);
slideover_add_page(*app, "cursors", "Cursors", app->cursors_panel);
slideover_add_page(*app, "measure", "Measurements", measures_panel);
// The dock is the compact readouts alone (step 4 adds the events to it).
gtk_box_append(GTK_BOX(app->dock_page), build_readouts_dock(*app));
// The cursors start off, so their readout starts insensitive -- stated here by the one place that
// knows the default, and the *body* and not the panel, because the panel's heading carries the
@@ -5200,8 +5190,8 @@ void on_activate(GtkApplication* application, gpointer user) {
// 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.
// Nothing to state about the sidebar's size. It is the split view's: 320 px from the `.ui`, floored
// at 240, and never a number derived from the window -- which is what the removed
// Nothing to state about the sidebar's size. It is the split view's: 280 px from the `.ui` (min = max),
// and never a number derived from the window -- which is what the removed
// `gtk_paned_set_position(paned, 940)` was, and why a window narrower than 940 px gave the sidebar
// no width at all.