Feature/source plugins #1
No files matched your search
@@ -98,11 +98,20 @@ src/layout_store.* the per-source session layout file (TOML), written and read b
|
|||||||
src/event_series.hpp an immutable captured event as a plot::data::Series
|
src/event_series.hpp an immutable captured event as a plot::data::Series
|
||||||
src/ui.* the GTK4 window: toolbar, trigger form, signal list, plot box, the dock
|
src/ui.* the GTK4 window: toolbar, trigger form, signal list, plot box, the dock
|
||||||
src/ui_slideover.cpp the slide-over panel over the plot's right edge, one page at a time
|
src/ui_slideover.cpp the slide-over panel over the plot's right edge, one page at a time
|
||||||
src/ui_badges.cpp the badge bar under the plot: the Trigger and Source badges
|
src/ui_badges.cpp the badge bar under the plot: the signal badges, the + badge, Trigger and Source
|
||||||
|
src/ui_signal_page.cpp the per-signal slide-over pages (`signal:<name>`)
|
||||||
```
|
```
|
||||||
|
|
||||||
**The window.** The plot is the window. Under it sits a fixed-height **badge bar** (36 px) whose
|
**The window.** The plot is the window. Under it sits a fixed-height **badge bar** (36 px). Its left
|
||||||
right-hand end carries two words-only badges: **Trigger** (`off`, `armed`, `capturing`, `triggered`
|
part is the **signals**: one badge per *enabled* signal (a dot in the signal's colour, filled while the
|
||||||
|
signal is plotted, and its name), then a `+` badge that opens the full signal list (`g` does the same).
|
||||||
|
A signal badge opens that signal's own page in the slide-over -- colour, calibration 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
|
||||||
|
otherwise. The signal badges sit in a scroller, so the bar's minimum width, and with it the window's,
|
||||||
|
never depends on how many signals there are. The badge order is kept **for the session only**; it is not
|
||||||
|
written to the session file. The right-hand end carries two words-only badges: **Trigger** (`off`, `armed`, `capturing`, `triggered`
|
||||||
or `disarmed`) and **Source** (the kind's name and `connected`/`disconnected`; a read-out, not a button,
|
or `disarmed`) and **Source** (the kind's name and `connected`/`disconnected`; a read-out, not a button,
|
||||||
for a source with no controls of its own, and for a file). A badge opens the **slide-over**: a 360 px
|
for a source with no controls of its own, and for a file). A badge opens the **slide-over**: a 360 px
|
||||||
panel laid over the plot's right edge, opaque, with its own title, a *Close* button and one scroller per
|
panel laid over the plot's right edge, opaque, with its own title, a *Close* button and one scroller per
|
||||||
@@ -110,9 +119,9 @@ page. The Trigger badge opens the trigger form; the Source badge opens the sourc
|
|||||||
(the E-1608's *Analog out* and *Digital I/O*, behind a segmented switch at the top of the panel). It
|
(the E-1608's *Analog out* and *Digital I/O*, behind a segmented switch at the top of the panel). It
|
||||||
closes with a second click on its badge, with `Esc`, with *Close*, or with a click on the plot; it never
|
closes with a second click on its badge, with `Esc`, with *Close*, or with a click on the plot; it never
|
||||||
resizes the plot. The right-hand **dock** (the existing sidebar, 320 px) holds what is left of the old
|
resizes the plot. The right-hand **dock** (the existing sidebar, 320 px) holds what is left of the old
|
||||||
tabs in one scroller: the signal list, the cursors and the measurements, shown from the start and
|
tabs in one scroller: the cursors and the measurements, shown from the start and insensitive until
|
||||||
insensitive until the stream has signals. It is temporary -- see "Review findings not (yet)
|
the stream has signals (the signal list moved to the `signals` slide-over page). It is temporary -- see
|
||||||
implemented" for what the redesign still has to do with it.
|
"Review findings not (yet) implemented" for what the redesign still has to do with it.
|
||||||
|
|
||||||
Threading: one producer thread owns the data source (the UDPStreamer client is the built-in
|
Threading: one producer thread owns the data source (the UDPStreamer client is the built-in
|
||||||
one) and calls `poll()`; the GTK main thread owns every widget and the GL contexts.
|
one) and calls `poll()`; the GTK main thread owns every widget and the GL contexts.
|
||||||
@@ -2950,8 +2959,9 @@ now — they are listed so they are not mistaken for anything else:
|
|||||||
dock's *shown* state only, not a width -- the dock's width is fixed, so there is nothing to persist
|
dock's *shown* state only, not a width -- the dock's width is fixed, so there is nothing to persist
|
||||||
-- and does not store the open slide-over page. (3) The **Trigger badge** shows `off`, `armed` and
|
-- and does not store the open slide-over page. (3) The **Trigger badge** shows `off`, `armed` and
|
||||||
`triggered` as the spec says, and two more words, `capturing` (a post-trigger window is filling) and
|
`triggered` as the spec says, and two more words, `capturing` (a post-trigger window is filling) and
|
||||||
`disarmed` (trigger on, not armed), so the label never claims a state the engine is not in. Still to
|
`disarmed` (trigger on, not armed), so the label never claims a state the engine is not in. The signal badges, the
|
||||||
come, in the spec's order: the signal badges and drag (2), the compact readouts (3), the events
|
signal pages and the drag (step 2) are done. Still to
|
||||||
|
come, in the spec's order: the compact readouts (3), the events
|
||||||
section in the dock, the deletion of the left pane and the Events toggle, and `USER-GUIDE.md` and the
|
section in the dock, the deletion of the left pane and the Events toggle, and `USER-GUIDE.md` and the
|
||||||
manual's figures (4). Until then the events pane, the header's Events toggle and the manual still
|
manual's figures (4). Until then the events pane, the header's Events toggle and the manual still
|
||||||
describe the previous layout.
|
describe the previous layout.
|
||||||
|
|||||||
@@ -99,19 +99,23 @@ touching the data path.
|
|||||||
- **`SlideOver`** (`src/ui_slideover.cpp`) is one `GtkRevealer` holding a `GtkStack`, added as the second
|
- **`SlideOver`** (`src/ui_slideover.cpp`) is one `GtkRevealer` holding a `GtkStack`, added as the second
|
||||||
child placed *over* the plot (after the layout editor's buttons) in `GtkOverlay#plot_overlay`. A page is
|
child placed *over* the plot (after the layout editor's buttons) in `GtkOverlay#plot_overlay`. A page is
|
||||||
a `slideover_add_page(app, id, title, widget)`: the widget is wrapped in a `GtkScrolledWindow` of its
|
a `slideover_add_page(app, id, title, widget)`: the widget is wrapped in a `GtkScrolledWindow` of its
|
||||||
own and registered under its id (`trigger`, `source-<id>`; `signal:<name>`, `signals`, `measure`,
|
own and registered under its id (`trigger`, `source-<id>`, `signals` (the signal list) and
|
||||||
`cursors` and `events` are reserved for later steps). One page is open at a time and `App::slideover.page`
|
`signal:<name>` (one signal's page, `src/ui_signal_page.cpp`, created on demand by `signal_page_ensure()`
|
||||||
|
and pruned by `signal_pages_sync()`, which `rebuild_signal_panels()` ends with); `measure`, `cursors`
|
||||||
|
and `events` are reserved for later steps). One page is open at a time and `App::slideover.page`
|
||||||
is its id, empty when closed. The open page is **not** a session value. Esc, *Close*, a second click on the
|
is its id, empty when closed. The open page is **not** a session value. Esc, *Close*, a second click on the
|
||||||
badge and a click on the plot close it; the click-away is a capture-phase observer (see
|
badge and a click on the plot close it; the click-away is a capture-phase observer (see
|
||||||
[invariants-gtk-and-chrome.md](invariants-gtk-and-chrome.md)). With two or more `source-*` pages, an
|
[invariants-gtk-and-chrome.md](invariants-gtk-and-chrome.md)). With two or more `source-*` pages, an
|
||||||
`AdwToggleGroup` under the header is the segmented switch between them.
|
`AdwToggleGroup` under the header is the segmented switch between them.
|
||||||
- **`BadgeBar`** (`src/ui_badges.cpp`) is the fixed-height row between the plot and the status line
|
- **`BadgeBar`** (`src/ui_badges.cpp`) is the fixed-height row between the plot and the status line
|
||||||
(`main-window.ui` `badge_bar`, two slots: signals, left, empty until step 2; system, right, holding the
|
(`main-window.ui` `badge_bar`, two slots: signals, left, a scroller holding one badge per enabled signal
|
||||||
**Trigger** and **Source** badges). A badge is a flat button whose `page` is the slide-over page it
|
and the `+`, or a single "N signals" badge past six; system, right, holding the **Trigger** and
|
||||||
|
**Source** badges). `sync_signal_badges()` rebuilds the signal badges (from `rebuild_signal_panels()`);
|
||||||
|
their order is `App::badge_order`, in memory only. A badge is a flat button whose `page` is the slide-over page it
|
||||||
toggles; the Source badge's page is the first `source-*` page, and a kind with none (UDPS, Flat UDP, a
|
toggles; the Source badge's page is the first `source-*` page, and a kind with none (UDPS, Flat UDP, a
|
||||||
file) leaves it a read-out with `can_target` off.
|
file) leaves it a read-out with `can_target` off.
|
||||||
- **The dock** is the `AdwOverlaySplitView` sidebar (`side_box` > `dock_scroller` > `dock_page`): the
|
- **The dock** is the `AdwOverlaySplitView` sidebar (`side_box` > `dock_scroller` > `dock_page`): the
|
||||||
signal list, the cursors and the measurements in one scroller. It holds no tab switcher and no
|
cursors and the measurements only, in one scroller (the signal list is the `signals` page). It holds no tab switcher and no
|
||||||
revealer, and it does not hold a source kind's panels (those are slide-over pages).
|
revealer, and it does not hold a source kind's panels (those are slide-over pages).
|
||||||
|
|
||||||
**When each is built and when it is read.** `build_slideover()` runs in `on_activate` right after the tour
|
**When each is built and when it is read.** `build_slideover()` runs in `on_activate` right after the tour
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
|||||||
take room has to be hidden and not merely unrevealed; the revealer keeps the slide while the pane
|
take room has to be hidden and not merely unrevealed; the revealer keeps the slide while the pane
|
||||||
*is* open. The allocated width is how this was found -- the revealer's own measure said 0.
|
*is* open. The allocated width is how this was found -- the revealer's own measure said 0.
|
||||||
**The sidebar is one dock now, and has no `GtkRevealer` left in it**: a single `GtkScrolledWindow`
|
**The sidebar is one dock now, and has no `GtkRevealer` left in it**: a single `GtkScrolledWindow`
|
||||||
(`dock_scroller`) holding the signal list, the cursors and the measurements one under another. It
|
(`dock_scroller`) holding the cursors and the measurements one under another. It
|
||||||
replaced an `AdwViewSwitcher` over an `AdwViewStack`, whose four text tabs did not fit 320 px (and a source
|
replaced an `AdwViewSwitcher` over an `AdwViewStack`, whose four text tabs did not fit 320 px (and a source
|
||||||
can add more); a source kind's own panels are slide-over pages, not dock sections. The reason is the one
|
can add more); a source kind's own panels are slide-over pages, not dock sections. The reason is the one
|
||||||
this trap teaches: sections competing for one 320 px column each left every one of them short of room, and
|
this trap teaches: sections competing for one 320 px column each left every one of them short of room, and
|
||||||
|
|||||||
@@ -110,7 +110,9 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
|||||||
does not propagate its child's height), and content that is taller than the plot -- the trigger form
|
does not propagate its child's height), and content that is taller than the plot -- the trigger form
|
||||||
on a 470 px window -- scrolls inside the panel instead of growing it. The widgets that go in a page
|
on a 470 px window -- scrolls inside the panel instead of growing it. The widgets that go in a page
|
||||||
are reparented into it; their widths must fit 360 minus the border (the trigger form measures 267
|
are reparented into it; their widths must fit 360 minus the border (the trigger form measures 267
|
||||||
minimum, the E-1608's panels 197).
|
minimum, the E-1608's panels 197). **One page wider than that widens the panel
|
||||||
|
for all of them** (the stack measures every page): the signals page's hint line once did, unwrapped, and
|
||||||
|
`[slideover] panel=` read 376 instead of 360; the label now wraps.
|
||||||
- **The badge bar has a fixed height and sits outside the overlay.** `badge_bar` is 36 px
|
- **The badge bar has a fixed height and sits outside the overlay.** `badge_bar` is 36 px
|
||||||
(`height-request`) between `plot_overlay` and the status line, so the plot above it never moves when a
|
(`height-request`) between `plot_overlay` and the status line, so the plot above it never moves when a
|
||||||
badge's text changes (`bar_h` = `bar_h_after` in `[badges]`). This is "layout must not depend on
|
badge's text changes (`bar_h` = `bar_h_after` in `[badges]`). This is "layout must not depend on
|
||||||
@@ -119,8 +121,17 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
|||||||
spare on the right) and never its height. The badge labels are not ellipsized: a name long enough to
|
spare on the right) and never its height. The badge labels are not ellipsized: a name long enough to
|
||||||
need it would be a defect of the kind's `display_name()`. Rows that appear by trigger condition appear
|
need it would be a defect of the kind's `display_name()`. Rows that appear by trigger condition appear
|
||||||
inside the slide-over's scroller, never in the bar.
|
inside the slide-over's scroller, never in the bar.
|
||||||
|
- **The signal badges live in a scroller, so the bar's minimum width never depends on the signal count.**
|
||||||
|
The bar's signals slot holds a `GtkScrolledWindow` (horizontal `EXTERNAL`, vertical `NEVER`) around one
|
||||||
|
row of badges and the `+`, because a button row's minimum width is the sum of its children: nine badges
|
||||||
|
(the E-1608: eight inputs and the counter) would push the window's minimum width past a laptop screen.
|
||||||
|
Past `kMaxSignalBadges` (6) the row is replaced by one "N signals" badge, which also stands for the `+`.
|
||||||
|
The bar's height stays 36 px in every one of these states (`bar_h_fixed` in `[sigbadges]`), and
|
||||||
|
`bar_min_w` reads the same with one signal, nine signals and the overflow (329 on the E-1608, 336 on UDPS:
|
||||||
|
the Source badge of each kind reads differently). A change that makes it grow with the signal count has
|
||||||
|
taken the scroller out of the measurement.
|
||||||
- **The dock's width is fixed too** (`side_column` `width-request` 300, the split view's 320 px floor
|
- **The dock's width is fixed too** (`side_column` `width-request` 300, the split view's 320 px floor
|
||||||
and cap), and it holds one scroller with the signal list, the cursors and the measurements. A
|
and cap), and it holds one scroller with the cursors and the measurements. A
|
||||||
section's visibility is never what makes the dock taller; the scroller is what absorbs the extra.
|
section's visibility is never what makes the dock taller; the scroller is what absorbs the extra.
|
||||||
- **Trace slots are identified by signal name, not channel index.** Enabling a signal
|
- **Trace slots are identified by signal name, not channel index.** Enabling a signal
|
||||||
or a new CONFIG renumbers the channel list, so an index would silently re-point a
|
or a new CONFIG renumbers the channel list, so an index would silently re-point a
|
||||||
|
|||||||
@@ -987,7 +987,8 @@ two also catch a row whose accelerator went missing. `settings=` must be a real
|
|||||||
in the `[helpui]` entry above, where `raw`, `target` and `inside` are explained). `clear=0` is read as geometry, not
|
in the `[helpui]` entry above, where `raw`, `target` and `inside` are explained). `clear=0` is read as geometry, not
|
||||||
as a placement bug, on the plot stop (the target is the whole content) and on the trigger stop at the
|
as a placement bug, on the plot stop (the target is the whole content) and on the trigger stop at the
|
||||||
documented 756 px window (the panel is 360 px of it, so the card has no side wide enough and goes flush
|
documented 756 px window (the panel is 360 px of it, so the card has no side wide enough and goes flush
|
||||||
left over the plot, overlapping the panel's edge by a few pixels).
|
left over the plot, overlapping the panel's edge by a few pixels), and on the `signals` stop for the same
|
||||||
|
reason (the dock beside it is 320 px and the card has no side wide enough).
|
||||||
- `[toursurface] finished: running=0 slideover=none` -- the last Next ended the walk and **the panel is
|
- `[toursurface] finished: running=0 slideover=none` -- the last Next ended the walk and **the panel is
|
||||||
closed with it**.
|
closed with it**.
|
||||||
- `[toursurface] restarted at trigger: running=1 slideover=trigger` then
|
- `[toursurface] restarted at trigger: running=1 slideover=trigger` then
|
||||||
@@ -2664,7 +2665,7 @@ signals list while the title and the badge marker still name `trigger`; `-1` whe
|
|||||||
(`kMaxSignalBadges`); beyond that `badges=0 overflow=1 overflow_text=<N> signals plus_visible=0` (the "N signals" badge replaces the badges and the "+"). `dot_plotted` is the number of
|
(`kMaxSignalBadges`); beyond that `badges=0 overflow=1 overflow_text=<N> signals plus_visible=0` (the "N signals" badge replaces the badges and the "+"). `dot_plotted` is the number of
|
||||||
badges whose signal is on a plot (its dot is then the trace colour, not the unplotted grey). `bar_h` is the bar's allocated height and `bar_h_fixed=1` that neither it nor its natural
|
badges whose signal is on a plot (its dot is then the trace colour, not the unplotted grey). `bar_h` is the bar's allocated height and `bar_h_fixed=1` that neither it nor its natural
|
||||||
height moved while one signal was switched off and on again (`rebuild_signal_panels()` each time), and that the badge count followed; `0` is a bar whose height depends on its content.
|
height moved while one signal was switched off and on again (`rebuild_signal_panels()` each time), and that the badge count followed; `0` is a bar whose height depends on its content.
|
||||||
`bar_min_w` is only a record: the scroller must keep it the same however many signals there are (it reads 336 with the mock's 4 and with the overflow forced on). `opens=1`: clicking the
|
`bar_min_w` is only a record: the scroller must keep it the same however many signals there are (it reads 336 with the UDPS mock's 4 and with the overflow forced on, and 329 against the E-1608 mock with one signal and with nine -- the overflow, `enabled=9 badges=0 overflow=1 overflow_text=9 signals plus_visible=0 bar_h=36 bar_h_fixed=1`; a value that grows with the signal count is a scroller that has stopped constraining the bar). `opens=1`: clicking the
|
||||||
first signal badge opens `signal:<name>` with the badge marked open and a second click closes it (`-1` when overflowed, there being no signal badges); `plus_opens=1` the same for the "+"
|
first signal badge opens `signal:<name>` with the badge marked open and a second click closes it (`-1` when overflowed, there being no signal badges); `plus_opens=1` the same for the "+"
|
||||||
(the overflow badge when overflowed) and the `signals` page.
|
(the overflow badge when overflowed) and the `signals` page.
|
||||||
|
|
||||||
|
|||||||
@@ -447,6 +447,11 @@ precedent, not an exception.
|
|||||||
read `click_inside_closes=0 still_open=1 click_outside_closes=1 esc_closes=1 closed=1`. For a screenshot
|
read `click_inside_closes=0 still_open=1 click_outside_closes=1 esc_closes=1 closed=1`. For a screenshot
|
||||||
add `UDPSCOPE_PROBE_SLIDEOVER_HOLD=1`, which leaves the page open after line 1 (run with `GSK_RENDERER=cairo`
|
add `UDPSCOPE_PROBE_SLIDEOVER_HOLD=1`, which leaves the page open after line 1 (run with `GSK_RENDERER=cairo`
|
||||||
and `import -window root`): the panel must be drawn over the traces, opaque.
|
and `import -window root`): the panel must be drawn over the traces, opaque.
|
||||||
|
- **Slide-over and page probes (`SLIDEOVER`, `BADGES`, `SIGNAL_PAGES`, `SIGNAL_BADGES`) need a config that has already seen
|
||||||
|
the first-run tour**: a fresh `XDG_CONFIG_HOME` auto-starts the tour at about 1.5 s, and a tour stop with no page closes the
|
||||||
|
slide-over under the probe. Seed it with `mkdir -p $D/udpscope && printf 'tour_seen = true\n' > $D/udpscope/settings.toml`
|
||||||
|
(or one short throw-away run, which writes the key when the tour starts) and run with `XDG_CONFIG_HOME=$D`. Delete the
|
||||||
|
per-source subdirectory (`$D/udpscope/<host>_<port>`) between runs that must start from a first-run layout.
|
||||||
- `UDPSCOPE_PROBE_SIGNAL_PAGES_MS=1500` with `UDPSCOPE_EXIT_AFTER_MS=5000` and `UDPSCOPE_ENABLE_ALL_MS=500` -- the
|
- `UDPSCOPE_PROBE_SIGNAL_PAGES_MS=1500` with `UDPSCOPE_EXIT_AFTER_MS=5000` and `UDPSCOPE_ENABLE_ALL_MS=500` -- the
|
||||||
per-signal `signal:<name>` slide-over pages. **Against a config that has already seen the tour** (a first run's
|
per-signal `signal:<name>` slide-over pages. **Against a config that has already seen the tour** (a first run's
|
||||||
auto-tour closes the slide-over at about 1.5 s, which is when this probe opens its page). One `[signalpage]` line;
|
auto-tour closes the slide-over at about 1.5 s, which is when this probe opens its page). One `[signalpage]` line;
|
||||||
|
|||||||
@@ -55,6 +55,8 @@
|
|||||||
<object class="GtkLabel" id="signals_hint">
|
<object class="GtkLabel" id="signals_hint">
|
||||||
<property name="label" translatable="yes">click a signal for its page; drag its badge onto a plot</property>
|
<property name="label" translatable="yes">click a signal for its page; drag its badge onto a plot</property>
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="wrap">1</property>
|
||||||
<property name="hexpand">1</property>
|
<property name="hexpand">1</property>
|
||||||
<property name="css-classes">dim-label</property>
|
<property name="css-classes">dim-label</property>
|
||||||
</object>
|
</object>
|
||||||
|
|||||||
+4
-3
@@ -445,9 +445,10 @@ constexpr TourStep kTourSteps[] = {
|
|||||||
"zooms, a drag pans, and a right-click on a row opens that plot's own menu.",
|
"zooms, a drag pans, and a right-click on a row opens that plot's own menu.",
|
||||||
&App::area_overlay},
|
&App::area_overlay},
|
||||||
{"badges", nullptr, "The badges",
|
{"badges", nullptr, "The badges",
|
||||||
"Setup is reached by the thing it configures. The Trigger badge opens the trigger form; the "
|
"Setup is reached by the thing it configures. A badge per signal opens that signal's colour, "
|
||||||
"Source badge opens the source's own controls. Click it again, press Esc or click the plot to "
|
"calibration and plot; the + opens the full list; Trigger and Source open their own forms. Drag a "
|
||||||
"close the panel.",
|
"signal badge onto a plot to draw it there, or onto another badge to reorder. Click again, press "
|
||||||
|
"Esc or click the plot to close the panel.",
|
||||||
&App::badge_bar},
|
&App::badge_bar},
|
||||||
{"trigger", "trigger", "The trigger",
|
{"trigger", "trigger", "The trigger",
|
||||||
"Describe an event -- a signal, a condition, a level and the window around it -- and arm it: "
|
"Describe an event -- a signal, a condition, a level and the window around it -- and arm it: "
|
||||||
|
|||||||
Reference in new issue
Block a user