ui: the math panel's frame is a .ui file

The first half of this plan row. src/ui/math-panel.ui holds the panel: the box and its
margins, the heading row with the title and the add button, and the list the channel rows
go in. The rows stay in code -- each is a channel with its name, unit, expression, colour
and its own edit and remove buttons -- so the file holds the frame, as in the measurements
and signals panels beside it.

Read back by a dump line that also reads the file's own text:
`math panel: head=2 buttons=1 list=1 title='Math channels'`, where buttons=0 is a lost
`+` and title='-' a lost label. `[math-probe]` still drives the add and opens the editor,
so the rows landing in the file's list is read as well as the frame.

The other half is the node editor's chrome, which is where least of that file is template:
the canvas is a GtkDrawingArea that is drawn rather than declared, and the gestures, the
parameter fields and the palette are code. That is its own change.
This commit is contained in:
Martino Ferrari committed 2026-10-12 15:53:35 +02:00
1 parent c37fbdde21
commit 90a17eb186
5 files changed
+92 -19

No files matched your search

+12 -19
View File
@@ -1033,29 +1033,22 @@ GtkWidget* math_row(const char* label, GtkWidget* widget, GtkWidget** row_out) {
}
GtkWidget* build_math_panel(App& app) {
GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4);
gtk_widget_set_margin_top(box, 6);
gtk_widget_set_margin_bottom(box, 6);
gtk_widget_set_margin_start(box, 6);
gtk_widget_set_margin_end(box, 6);
GtkWidget* head = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
GtkWidget* title = gtk_label_new("Math channels");
gtk_widget_set_halign(title, GTK_ALIGN_START);
gtk_widget_set_hexpand(title, true);
gtk_box_append(GTK_BOX(head), title);
GtkWidget* add = gtk_button_new_from_icon_name("list-add-symbolic");
gtk_widget_add_css_class(add, "flat");
gtk_widget_set_tooltip_text(add, "add a math channel");
// The panel's frame -- the heading row with its add button, and the list -- is a UI file; the rows are
// not, because each one is a channel and the whole list is rebuilt whenever the set changes. `make test-ui`
// checks the file's types against the GIR; the ids below are what keeps the code and the file agreeing.
GtkBuilder* ui = ui_load(app, "/org/udpscope/ui/math-panel.ui");
GtkWidget* box = GTK_WIDGET(gtk_builder_get_object(ui, "math_panel"));
GtkWidget* add = GTK_WIDGET(gtk_builder_get_object(ui, "math_add"));
app.math_list = GTK_WIDGET(gtk_builder_get_object(ui, "math_list"));
if (box == nullptr || add == nullptr || app.math_list == nullptr) {
// A missing id is a mistake in the `.ui`: the panel comes up empty rather than taking the window with
// it, and `[udpscope] math panel:` reads the difference.
return box != nullptr ? box : gtk_box_new(GTK_ORIENTATION_VERTICAL, 4);
}
g_signal_connect(add, "clicked", G_CALLBACK(+[](GtkButton*, gpointer user) {
add_math_channel(*static_cast<App*>(user));
}),
&app);
gtk_box_append(GTK_BOX(head), add);
gtk_box_append(GTK_BOX(box), head);
app.math_list = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
gtk_box_append(GTK_BOX(box), app.math_list);
return box;
}