Gated measurements #2
No files matched your search
@@ -149,7 +149,10 @@ divider's `+` for a new math channel; when every signal is acquired a dim "every
|
||||
stands in for the list. While the bar has overflowed into the "N signals" badge the page lists the acquired
|
||||
signals too, since their rows are then the only way to each signal's page. There is no signal lock: a
|
||||
signal's page and the list always allow acquire, colour, calibration, the math editor and delete.
|
||||
A signal badge opens that signal's own page in the slide-over -- the unit, gain and offset and the CONFIG's details directly under the name (aligned rows; a pencil beside the unit, gain and offset edits just that one -- a unit rename is stored per signal name, saved as `[[unit]]` and re-applied to every CONFIG), the colour and the *Plot on N*
|
||||
A signal badge opens that signal's own page in the slide-over -- its title is the **numbered name**
|
||||
(`2. sine`, the same number the badge and the measurements pane use) and the body carries the unit,
|
||||
gain and offset and the CONFIG's details directly under it, with no second copy of the name and no
|
||||
"back to the list" button (the header's Close is the way out) (aligned rows; a pencil beside the unit, gain and offset edits just that one -- a unit rename is stored per signal name, saved as `[[unit]]` and re-applied to every CONFIG), the colour and the *Plot on N*
|
||||
buttons -- and is also the drag handle: drag it onto a plot to draw the signal there, or onto another
|
||||
badge to reorder them. Past **six** signal badges the bar shows a single **"N signals"** badge in their
|
||||
place (it opens the list, and `+` is hidden): the E-1608's 8 analog inputs and counter would not fit
|
||||
|
||||
@@ -746,3 +746,14 @@ The `Help` submenu, the contextual help's "?" and the guided tour, and the traps
|
||||
each is a `GtkWindow` added to the application, and one left behind keeps the GApplication's
|
||||
main loop alive around a window that is gone -- the hang where the exit run never reached its
|
||||
dump.
|
||||
|
||||
- **A page's name lives in the slide-over header, once.** The header prints the open page's title
|
||||
(from the `GtkStackPage`) beside its **Close** button; a page body that repeats the name is the
|
||||
same word twice, and a body-level "back to the list" button duplicates a navigation the header
|
||||
already owns. Signal pages therefore carry **no** name label and **no** back button
|
||||
(`[signalpage] no_dup=1`), and their title is the **numbered** name -- `<channel number>. <name>`,
|
||||
the same `measure_channel_number()` the badges and the measurements pane use -- so the panel says
|
||||
*which acquired channel* this is rather than only what it is called. `slideover_set_title()`
|
||||
retitles a page in place (the open one included) because that number changes when the stream
|
||||
renumbers its channels; `fill()` sets it on every fill, and a page added by
|
||||
`slideover_add_page()` gets its final title from the `fill()` that follows.
|
||||
@@ -2889,7 +2889,7 @@ left the caller's `false` alone would read `dock_shown=0 default=1 ok=0`. The pr
|
||||
## `[signalpage]`
|
||||
|
||||
```
|
||||
[signalpage] name=sine open=1 pages=1 enable_visible=1 plot_buttons=1 plot_on_row0=1 plot_on_row0_disabled=1 removed=1 btn_row0=1 back_to_list=1 row_opens=1 pruned=1 other_page_kept=1 rows=1
|
||||
[signalpage] name=sine open=1 pages=1 enable_visible=1 plot_buttons=1 plot_on_row0=1 plot_on_row0_disabled=1 removed=1 btn_row0=1 title='1. sine' title_ok=1 no_dup=1 row_opens=1 pruned=1 other_page_kept=1 rows=1
|
||||
```
|
||||
|
||||
`UDPSCOPE_PROBE_SIGNAL_PAGES_MS` builds and drives the page of the first streamed signal. `open=1` (the slide-over shows `signal:<name>`), `pages=1`
|
||||
@@ -2897,8 +2897,11 @@ left the caller's `false` alone would read `dock_shown=0 default=1 ok=0`. The pr
|
||||
`rows=` (one "Plot on" button per figure row), `plot_on_row0=1` (`assign_signal_to_row()` returned true and the signal is plotted, from a state where the probe first took it off every plot), `plot_on_row0_disabled=1`
|
||||
(after the page refilled with the signal on plot 1, that plot's "Plot on" button is insensitive, "already on this plot"; `0` is a button that would put the signal in a second slot of
|
||||
the same plot), `removed=1`
|
||||
(the page's "Remove from plots" took it off), `btn_row0=1` (the "Plot on 1" button, the user's path, put it back), `back_to_list=1` ("Back to signals"
|
||||
target), `row_opens=1` (the probe switches the signal off so it is addable, activates its list row and the page opens; the signal is then switched back on), and `pruned=1`: a math channel's page was opened, its **Delete** button clicked, and
|
||||
(the page's "Remove from plots" took it off), `btn_row0=1` (the "Plot on 1" button, the user's path, put it back),
|
||||
`title=` the slide-over **header's** title while the page is open, `title_ok=1` when it is `<channel number>. <name>` -- the
|
||||
same numbering the badge carries (`measure_channel_number`), so a signal page says which acquired channel it is -- and
|
||||
`no_dup=1` when the page **body** carries neither a "Back to signals" button (the header's Close is the way out) nor a
|
||||
second copy of the name (a `title-3` label); `0` is either duplicate back, `row_opens=1` (the probe switches the signal off so it is addable, activates its list row and the page opens; the signal is then switched back on), and `pruned=1`: a math channel's page was opened, its **Delete** button clicked, and
|
||||
the slide-over closed and the page was dropped by `signal_pages_sync()`. `pruned=-1` means no math channel could be added; `0` is a stale page. `other_page_kept=1`: with the `trigger` page open, a signal page that is not on show was pruned (a math channel added, its page built, the
|
||||
channel removed) and the slide-over was still on `trigger`, both by `slideover_page()` and by the stack's visible child; `0` is `signal_pages_sync()` parking the stack on the
|
||||
signals list while the title and the badge marker still name `trigger`; `-1` when there is no `trigger` page or no math channel could be added.
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
</item>
|
||||
<item>
|
||||
<p>Once a signal is acquired its badge appears. Click it to open that signal's page: its
|
||||
details directly under its name — <gui>Unit</gui>, <gui>Gain</gui> and <gui>Offset</gui>,
|
||||
title carries the signal's name and its channel number (<code>2. sine</code>), and its
|
||||
details follow — <gui>Unit</gui>, <gui>Gain</gui> and <gui>Offset</gui>,
|
||||
each with a pencil button that edits that one value, then the type, size, range, sample
|
||||
rate and timing the stream declared — its colour and <gui>Plot on</gui> buttons for the
|
||||
rows.</p>
|
||||
|
||||
@@ -2161,6 +2161,9 @@ gboolean dock_session_probe(gpointer user); // UDPSCOPE_PROBE_DOCK_SESSION_MS
|
||||
/// per setup surface, each page in a scroller of its own.
|
||||
void build_slideover(App& app); // once, after the plot_overlay exists
|
||||
bool slideover_add_page(App& app, const std::string& id, const std::string& title, GtkWidget* content);
|
||||
/// Retitles a page in place (`slideover_add_page`'s title, for a page whose subject changed: a signal
|
||||
/// page carries its channel's number, and the stream can renumber). False when the id is unknown.
|
||||
bool slideover_set_title(App& app, const std::string& id, const std::string& title);
|
||||
bool slideover_has_page(const App& app, const std::string& id);
|
||||
/// The inverse of `slideover_add_page`: false when the id is unknown or is the open page.
|
||||
bool slideover_remove_page(App& app, const std::string& id);
|
||||
|
||||
+33
-17
@@ -194,20 +194,14 @@ void fill(App& app, const std::string& name, GtkWidget* page) {
|
||||
const bool enabled = app.model->signal_enabled(index);
|
||||
const bool plotted = signal_plotted(app, sig.name);
|
||||
|
||||
// Back to the list: a page reached from a list row has no other way home.
|
||||
GtkWidget* back = text_button("Back to signals", page);
|
||||
gtk_widget_set_halign(back, GTK_ALIGN_START);
|
||||
gtk_widget_add_css_class(back, "flat");
|
||||
g_signal_connect(back, "clicked", G_CALLBACK(+[](GtkButton*, gpointer user) {
|
||||
slideover_open(*static_cast<App*>(user), "signals");
|
||||
}),
|
||||
&app);
|
||||
|
||||
GtkWidget* title = gtk_label_new(sig.name.c_str());
|
||||
gtk_widget_add_css_class(title, "title-3");
|
||||
gtk_widget_set_halign(title, GTK_ALIGN_START);
|
||||
gtk_label_set_ellipsize(GTK_LABEL(title), PANGO_ELLIPSIZE_END);
|
||||
gtk_box_append(GTK_BOX(page), title);
|
||||
// The page's name is the panel header's, not the body's: the slide-over already prints it above the
|
||||
// content (with its **Close** button), so a second copy in the body is the same word twice. The
|
||||
// header's title carries the channel's number -- the same one the badge and the measurements pane
|
||||
// use -- so the panel says which acquired channel this is, not just what it is called.
|
||||
const int channel_number = measure_channel_number(app, sig.name);
|
||||
slideover_set_title(app, page_id(name),
|
||||
channel_number > 0 ? std::to_string(channel_number) + ". " + sig.name
|
||||
: sig.name);
|
||||
if (sig.math) {
|
||||
if (!sig.unit.empty()) {
|
||||
GtkWidget* unit = gtk_label_new(sig.unit.c_str());
|
||||
@@ -489,8 +483,29 @@ gboolean signal_page_probe(gpointer user) {
|
||||
: find_descendant(page_it->second, [](GtkWidget* w) { return is_button_labelled(w, "Remove from plots"); });
|
||||
if (off != nullptr) g_signal_emit_by_name(off, "clicked");
|
||||
}
|
||||
// The page's *header* names it -- numbered like the badge -- and the body carries no second copy of
|
||||
// the name and no "Back to signals" button: the header's Close is the way out, the badge bar and the
|
||||
// list the ways in. Read before switching to the list.
|
||||
const int channel_number = measure_channel_number(a, name);
|
||||
const std::string want_title =
|
||||
channel_number > 0 ? std::to_string(channel_number) + ". " + name : name;
|
||||
// Copied: the label's text is replaced when the probe switches pages below, and a `const char*` into
|
||||
// it would be read after the free (it printed as an empty title).
|
||||
const std::string shown_title =
|
||||
a.slideover.title != nullptr ? gtk_label_get_text(GTK_LABEL(a.slideover.title)) : "";
|
||||
const int title_ok = a.slideover.page == ("signal:" + name) && want_title == shown_title ? 1 : 0;
|
||||
// ...and the body really has lost the two duplicates: no "Back to signals" button (the header's
|
||||
// Close is the way out) and no second copy of the name (a `title-3` label; the header carries it).
|
||||
GtkWidget* body = page_it == a.signal_pages.end() ? nullptr : page_it->second;
|
||||
const int no_dup =
|
||||
body != nullptr &&
|
||||
find_descendant(body, [](GtkWidget* w) { return is_button_labelled(w, "Back to signals"); }) ==
|
||||
nullptr &&
|
||||
find_descendant(body, [](GtkWidget* w) { return gtk_widget_has_css_class(w, "title-3"); }) ==
|
||||
nullptr
|
||||
? 1
|
||||
: 0;
|
||||
slideover_open(a, "signals");
|
||||
const int back_to_list = slideover_page(a) == "signals" ? 1 : 0;
|
||||
|
||||
// Activating the signal's row in the list opens its page (the path a click takes). The list proposes what
|
||||
// can be added, so the signal has a row only while it is not acquired: switch it off for the leg and back
|
||||
@@ -660,9 +675,10 @@ gboolean signal_page_probe(gpointer user) {
|
||||
std::fprintf(stderr,
|
||||
"[signalpage] name=%s open=%d pages=%d enable_visible=%d plot_buttons=%d plot_on_row0=%d "
|
||||
"plot_on_row0_disabled=%d "
|
||||
"removed=%d btn_row0=%d back_to_list=%d row_opens=%d pruned=%d other_page_kept=%d rows=%d\n",
|
||||
"removed=%d btn_row0=%d title='%s' title_ok=%d no_dup=%d row_opens=%d pruned=%d "
|
||||
"other_page_kept=%d rows=%d\n",
|
||||
name.c_str(), open, pages, enable_visible, plot_buttons, plot_on_row0, plot_on_row0_disabled,
|
||||
removed, btn_row0, back_to_list, row_opens, pruned,
|
||||
removed, btn_row0, shown_title.c_str(), title_ok, no_dup, row_opens, pruned,
|
||||
other_page_kept, a.rows->row_count());
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
@@ -118,6 +118,23 @@ bool slideover_add_page(App& app, const std::string& id, const std::string& titl
|
||||
return true;
|
||||
}
|
||||
|
||||
bool slideover_set_title(App& app, const std::string& id, const std::string& title) {
|
||||
SlideOver& s = app.slideover;
|
||||
if (s.stack == nullptr || title.empty()) return false;
|
||||
GtkWidget* child = gtk_stack_get_child_by_name(GTK_STACK(s.stack), id.c_str());
|
||||
if (child == nullptr) return false;
|
||||
GtkStackPage* page = gtk_stack_get_page(GTK_STACK(s.stack), child);
|
||||
gtk_stack_page_set_title(page, title.c_str());
|
||||
if (is_source_page(id)) {
|
||||
AdwToggle* t = adw_toggle_group_get_toggle_by_name(ADW_TOGGLE_GROUP(s.source_switch), id.c_str());
|
||||
if (t != nullptr) adw_toggle_set_label(t, title.c_str());
|
||||
}
|
||||
// The header shows the *open* page's title, so a retitle of the page on show is visible at once --
|
||||
// a signal page's channel number can change under it when the stream renumbers its channels.
|
||||
if (s.page == id) gtk_label_set_text(GTK_LABEL(s.title), title.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool slideover_has_page(const App& app, const std::string& id) {
|
||||
return app.slideover.stack != nullptr &&
|
||||
gtk_stack_get_child_by_name(GTK_STACK(app.slideover.stack), id.c_str()) != nullptr;
|
||||
|
||||
Reference in new issue
Block a user