ui: the signals panel's frame is a .ui file
src/ui/signals-panel.ui holds the panel's shape: the box and its margins, the heading, the hint that says what a signal is for, and the list. The rows stay in code -- one per signal, carrying that signal's switch, colour, calibration and drop targets, rebuilt whenever the stream's signals change -- so the file holds the frame, which is the shape the plan gives this slice. The list's width-only size request moved with it, comment and all: a height floor there made the list occupy 120 px whatever it held, which hid the compact rows' height behind it. Read back by a new dump line, `signals panel: labels=2 list=1`, where a lost id reads as `labels=1` or `list=0` instead of a panel quietly missing its hint; `panels: … row_h=26` still reads the list's geometry and the height a row takes. check_ui is at 10 ok.
This commit is contained in:
1 parent
1ccc70c5ac
commit
c37fbdde21
6 files changed
+88
-22
No files matched your search
+14
@@ -5409,6 +5409,20 @@ int run_ui(int argc, char** argv, const Config& cfg, ScopeModel& model, Acquisit
|
||||
static_cast<unsigned long long>(model.trigger_latches().load()),
|
||||
static_cast<unsigned long long>(app.dbg_latches_at_disarm));
|
||||
std::printf("[udpscope] window control: '%s'\n", app.dbg_window_text.c_str());
|
||||
{
|
||||
// The signals panel's frame, read from the window rather than from the `.ui`: the two labels and the
|
||||
// list the file gives it. A `.ui` that lost one of them reads here -- `labels=1` or `list=0` -- rather
|
||||
// than showing as a panel quietly missing its hint.
|
||||
GtkWidget* panel = app.signal_list != nullptr ? gtk_widget_get_parent(app.signal_list) : nullptr;
|
||||
int labels = 0;
|
||||
int lists = 0;
|
||||
for (GtkWidget* c = panel != nullptr ? gtk_widget_get_first_child(panel) : nullptr; c != nullptr;
|
||||
c = gtk_widget_get_next_sibling(c)) {
|
||||
if (GTK_IS_LABEL(c)) ++labels;
|
||||
if (GTK_IS_LIST_BOX(c)) ++lists;
|
||||
}
|
||||
std::printf("[udpscope] signals panel: labels=%d list=%d\n", labels, lists);
|
||||
}
|
||||
std::printf("[udpscope] panels: side=%dx%d (visible=%d) signals=%dx%d row_h=%d "
|
||||
"(revealed=%d) trigger=%dx%d (revealed=%d) toggles=%d cursors=%d window=%.3fs "
|
||||
"window_cap=%.1fs\n",
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- SPDX-License-Identifier: MIT -->
|
||||
<!-- SPDX-FileCopyrightText: 2026 Martino Ferrari -->
|
||||
<!--
|
||||
The signals panel: a heading, the hint that says what a signal is for, and the list they go in.
|
||||
|
||||
The rows are not here. There is one per signal in the stream, it carries the switch that decides whether
|
||||
that signal is acquired, its colour, its calibration and its drop targets, and the whole list is rebuilt
|
||||
whenever the stream's signals change — so the file holds the frame and the code holds the rows.
|
||||
|
||||
The list's size request is **width only**, deliberately. A height floor here made the list occupy 120 px
|
||||
whatever it held, which hid the compact rows' height behind it and wasted the space on an empty stream;
|
||||
the scroller this panel sits in already caps how tall it can grow.
|
||||
-->
|
||||
<interface>
|
||||
<object class="GtkBox" id="signal_panel">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<property name="margin-top">8</property>
|
||||
<property name="margin-bottom">8</property>
|
||||
<property name="margin-start">8</property>
|
||||
<property name="margin-end">8</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="signals_heading">
|
||||
<property name="label" translatable="yes">Signals</property>
|
||||
<property name="halign">start</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="signals_hint">
|
||||
<property name="label" translatable="yes">drag a signal onto a plot</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="css-classes">dim-label</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBox" id="signal_list">
|
||||
<property name="selection-mode">none</property>
|
||||
<property name="width-request">260</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -18,5 +18,6 @@
|
||||
<file preprocess="xml-stripblanks">cursors-panel.ui</file>
|
||||
<file preprocess="xml-stripblanks">measures-panel.ui</file>
|
||||
<file preprocess="xml-stripblanks">trigger-panel.ui</file>
|
||||
<file preprocess="xml-stripblanks">signals-panel.ui</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
+12
-22
@@ -382,28 +382,18 @@ void rebuild_signal_panels(App& app) {
|
||||
}
|
||||
|
||||
GtkWidget* build_signal_panel(App& app) {
|
||||
GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
|
||||
gtk_widget_set_margin_top(box, 8);
|
||||
gtk_widget_set_margin_bottom(box, 8);
|
||||
gtk_widget_set_margin_start(box, 8);
|
||||
gtk_widget_set_margin_end(box, 8);
|
||||
|
||||
GtkWidget* heading = gtk_label_new("Signals");
|
||||
gtk_widget_set_halign(heading, GTK_ALIGN_START);
|
||||
gtk_box_append(GTK_BOX(box), heading);
|
||||
|
||||
GtkWidget* hint = gtk_label_new("drag a signal onto a plot");
|
||||
gtk_widget_set_halign(hint, GTK_ALIGN_START);
|
||||
gtk_widget_add_css_class(hint, "dim-label");
|
||||
gtk_box_append(GTK_BOX(box), hint);
|
||||
|
||||
app.signal_list = gtk_list_box_new();
|
||||
gtk_list_box_set_selection_mode(GTK_LIST_BOX(app.signal_list), GTK_SELECTION_NONE);
|
||||
// Width only. A height floor here made the list occupy 120 px whatever it held,
|
||||
// which hid the compact rows' height behind it and wasted the space on an empty
|
||||
// stream; the scroller above it already caps how tall it can grow.
|
||||
gtk_widget_set_size_request(app.signal_list, 260, -1);
|
||||
gtk_box_append(GTK_BOX(box), app.signal_list);
|
||||
// The panel's frame -- the heading, the hint under it, and the list -- is a UI file. The rows are not:
|
||||
// there is one per signal, carrying that signal's switch, colour, calibration and drop targets, and the
|
||||
// whole list is rebuilt whenever the stream's signals change. `make test-ui` checks the file's types
|
||||
// against the GIR; the id below is what keeps the code and the file agreeing on the name.
|
||||
GtkBuilder* ui = ui_load(app, "/org/udpscope/ui/signals-panel.ui");
|
||||
GtkWidget* box = GTK_WIDGET(gtk_builder_get_object(ui, "signal_panel"));
|
||||
app.signal_list = GTK_WIDGET(gtk_builder_get_object(ui, "signal_list"));
|
||||
if (box == nullptr || app.signal_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] signals panel:` reads the difference.
|
||||
return box != nullptr ? box : gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
|
||||
}
|
||||
return box;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user