docs: the readouts dock, the cursors and measurement pages
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
a2ce02db92
commit
ce3cc97b91
11 files changed
+205
-88
No files matched your search
@@ -146,10 +146,21 @@ panel laid over the plot's right edge, opaque, with its own title, a *Close* but
|
|||||||
page. The Trigger badge opens the trigger form; the Source badge (when shown) opens the source kind's own panels
|
page. The Trigger badge opens the trigger form; the Source badge (when shown) opens the source kind's own panels
|
||||||
(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 sidebar, **280 px**, fixed) holds the **readouts**: a
|
||||||
tabs in one scroller: the cursors and the measurements, shown from the start and insensitive until
|
compact, read-only copy of the cursors table (a header row `A B delta`, then one line per cursor
|
||||||
the stream has signals (the signal list moved to the `signals` slide-over page). It is temporary -- see
|
line) and of the measurements (one line each: the signal's colour chip, the type, the value). It is
|
||||||
"Review findings not (yet) implemented" for what the redesign still has to do with it.
|
shown from the start and insensitive until the stream has signals. Each of the two blocks has an
|
||||||
|
**Edit** button, which opens the full panel as a slide-over page -- `cursors` or `measure` -- over the
|
||||||
|
plot; `m` toggles the `measure` page, and a click on a measurement's line in the dock opens that
|
||||||
|
measurement's dialog. The header's **Cursors** toggle only switches the cursors on and off (it
|
||||||
|
mirrors the switch inside the `cursors` page); with the cursors off the dock's cursor lines are
|
||||||
|
insensitive, not hidden. Both pages are insensitive until the stream has signals, like the dock. The dock's
|
||||||
|
cells are a fixed number of characters wide and ellipsized, so the dock's width and height do not
|
||||||
|
depend on what a value reads: the **who** cell of a cursor line is 5 characters (the full text is its
|
||||||
|
tooltip), a value cell 9 (its tooltip is the full text). The dock and the pages show **one string**:
|
||||||
|
`update_cursors_pane()` and `update_measures()` format each value once and hand that variable to the
|
||||||
|
page's label and to the dock's, so the two cannot disagree. The remaining part of the redesign is
|
||||||
|
listed under "Review findings not (yet) implemented".
|
||||||
|
|
||||||
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.
|
||||||
@@ -1229,7 +1240,11 @@ decides which steps exist at all: a stop on a slide-over page is always kept, be
|
|||||||
reveals it, while one whose *pane is collapsed* (the dock, in a window too narrow to put it beside the
|
reveals it, while one whose *pane is collapsed* (the dock, in a window too narrow to put it beside the
|
||||||
plot) is dropped, because it is unmapped with its pane (a hidden page keeps its own *visible* flag
|
plot) is dropped, because it is unmapped with its pane (a hidden page keeps its own *visible* flag
|
||||||
true -- the widget's own flag, which is all `is_visible()` walks -- so the old test walked over
|
true -- the widget's own flag, which is all `is_visible()` walks -- so the old test walked over
|
||||||
surfaces that were not on screen); a narrow window therefore walks four steps. The chooser's
|
surfaces that were not on screen); a narrow window therefore walks five steps. The dock's stop
|
||||||
|
describes the readouts and the **Edit** buttons; it names no slide-over page, so it closes the panel
|
||||||
|
like the plot's. The cursors and measurements pages have no stop of their own, and their contextual
|
||||||
|
help "(i)" hints are attached to the pages' headings the way the trigger's and the signals' are: they
|
||||||
|
are drawn while the page is open, and the dock has none. The chooser's
|
||||||
tour works the same way over its own two pages: its tabs step shows the *Waveforms* page and
|
tour works the same way over its own two pages: its tabs step shows the *Waveforms* page and
|
||||||
stepping off it -- in either direction -- brings the *Sources* page back.
|
stepping off it -- in either direction -- brings the *Sources* page back.
|
||||||
|
|
||||||
@@ -1631,9 +1646,10 @@ it holds more than the window the bound became the whole ring, and a zoom-out wa
|
|||||||
view past the window into data the window was never set to show. A partly filled window
|
view past the window into data the window was never set to show. A partly filled window
|
||||||
simply has an empty left-hand side.
|
simply has an empty left-hand side.
|
||||||
|
|
||||||
**The panel switches are on the toolbar, and the panes own their own controls.** Cursors,
|
**The panel switches are on the toolbar, and the panes own their own controls.** (Since the
|
||||||
Measurements and Math channels are icon toggles in the header bar rather than rows in the overflow
|
slide-over redesign the toolbar keeps only the **Cursors** toggle of the three icons named here, and it
|
||||||
menu, and **Reset cursors** sits in the cursors pane beside the mode it resets (it acts on that
|
only enables the cursors; the measurements are reached by `m` or the dock's Edit button, and the math
|
||||||
|
editor from the signal list.) **Reset cursors** sits in the cursors page beside the mode it resets (it acts on that
|
||||||
pane's instruments and is only visible while they exist). The rows read, left to right: **window control, trigger, pause** — the trigger and the pause are
|
pane's instruments and is only visible while they exist). The rows read, left to right: **window control, trigger, pause** — the trigger and the pause are
|
||||||
read against the span on screen, so they sit with the control that sets it — then, on the right,
|
read against the span on screen, so they sit with the control that sets it — then, on the right,
|
||||||
**cursors, measurements, math, sidebar** and **the menu last**. With `HeaderBar::pack_end()` the
|
**cursors, measurements, math, sidebar** and **the menu last**. With `HeaderBar::pack_end()` the
|
||||||
@@ -2849,7 +2865,7 @@ reaches every widget). The full key table:
|
|||||||
| `Space` | pause / resume |
|
| `Space` | pause / resume |
|
||||||
| `t` | enable / disable trigger mode |
|
| `t` | enable / disable trigger mode |
|
||||||
| `c` | enable / disable the cursors |
|
| `c` | enable / disable the cursors |
|
||||||
| `m` | go to Measure (scroll the dock to the cursors and the measurements) |
|
| `m` | open or close the Measurements page (the `measure` slide-over page; the dock's Edit button for the cursors opens the `cursors` page) |
|
||||||
| `g` | go to Signals (open or close the signal list, the `signals` slide-over page, also reached by the `+` badge) |
|
| `g` | go to Signals (open or close the signal list, the `signals` slide-over page, also reached by the `+` badge) |
|
||||||
| `l` | show / hide the layout editor |
|
| `l` | show / hide the layout editor |
|
||||||
| `s` | show / hide the dock |
|
| `s` | show / hide the dock |
|
||||||
@@ -2970,9 +2986,10 @@ now — they are listed so they are not mistaken for anything else:
|
|||||||
signal list -- in one scrolling column; with four of them open in a 320 px sidebar every
|
signal list -- in one scrolling column; with four of them open in a 320 px sidebar every
|
||||||
section was short of room, and finding one meant scrolling past the others. The sidebar was then two
|
section was short of room, and finding one meant scrolling past the others. The sidebar was then two
|
||||||
text tabs (a **Measure** tab and a **Signals** tab, with a source kind's own tabs beside them), and four
|
text tabs (a **Measure** tab and a **Signals** tab, with a source kind's own tabs beside them), and four
|
||||||
tabs did not fit 320 px. It is **one dock** now, with no tab switcher: the cursors and the
|
tabs did not fit 320 px. It is **one dock** now, with no tab switcher: the **readouts** (a compact,
|
||||||
measurements in one scroller, shown from the start and insensitive until the stream has signals; `m`
|
read-only copy of the cursors and of the measurements, each block with an **Edit** button), shown from
|
||||||
scrolls it to the cursors; the **signal list** is the `signals` slide-over page (`g`, or the `+` badge). The **trigger form** and a **source's own
|
the start and insensitive until the stream has signals; the full cursors and measurements panels are the
|
||||||
|
`cursors` and `measure` slide-over pages (`m` toggles `measure`); the **signal list** is the `signals` slide-over page (`g`, or the `+` badge). The **trigger form** and a **source's own
|
||||||
controls** are pages of the slide-over, reached from the badge bar. The trigger pane also has a **locked** mode, which is what a returning user gets: it
|
controls** are pages of the slide-over, reached from the badge bar. The trigger pane also has a **locked** mode, which is what a returning user gets: it
|
||||||
shows one line saying what it is set to and offers no control that changes the configuration -- its
|
shows one line saying what it is set to and offers no control that changes the configuration -- its
|
||||||
heading has an `[edit]` button to switch to the full pane, and back. The signals have no lock: the
|
heading has an `[edit]` button to switch to the full pane, and back. The signals have no lock: the
|
||||||
@@ -2987,19 +3004,28 @@ now — they are listed so they are not mistaken for anything else:
|
|||||||
toggle hides a pane any more: cursors-off **disables** its readout and leaves it in place, and
|
toggle hides a pane any more: cursors-off **disables** its readout and leaves it in place, and
|
||||||
trigger-off leaves the trigger form fully editable -- a trigger is configured *before* it is
|
trigger-off leaves the trigger form fully editable -- a trigger is configured *before* it is
|
||||||
switched on, and the locked view says `stream (trigger off)` instead of the settings -- and the measurements' and math panes' toolbar toggles are gone with the panes.
|
switched on, and the locked view says `stream (trigger off)` instead of the settings -- and the measurements' and math panes' toolbar toggles are gone with the panes.
|
||||||
- **The badge bar / slide-over / dock redesign is in progress; this is its first step, and it deviates
|
- **The badge bar / slide-over / dock redesign is in progress; steps 1-3 are done, and they deviate
|
||||||
from `docs/superpowers/specs/2026-11-02-ui-badges-dock-design.md` in three known ways.**
|
from `docs/superpowers/specs/2026-11-02-ui-badges-dock-design.md` in these known ways.**
|
||||||
(1) The dock keeps the sidebar's **320 px**, not the spec's ~280: the panels it holds were built for
|
(1) The session file gains the dock's *shown* state only, not a width -- the dock's width is
|
||||||
320, and the width changes when they become compact readouts (step 3). (2) The session file gains the
|
fixed (**280 px**, as the spec says), so there is nothing to persist -- and does not store the open
|
||||||
dock's *shown* state only, not a width -- the dock's width is fixed, so there is nothing to persist
|
slide-over page. (2) The **Trigger badge** shows `off`, `armed` and `triggered` as the spec says, and
|
||||||
-- and does not store the open slide-over page. (3) The **Trigger badge** shows `off`, `armed` and
|
two more words, `capturing` (a post-trigger window is filling) and `disarmed` (trigger on, not
|
||||||
`triggered` as the spec says, and two more words, `capturing` (a post-trigger window is filling) and
|
armed), so the label never claims a state the engine is not in. (3) The **`cursors` and `measure`
|
||||||
`disarmed` (trigger on, not armed), so the label never claims a state the engine is not in. The signal badges, the
|
pages hold the existing panels unchanged** (the cursors table with its mode, its Reset and its
|
||||||
signal pages and the drag (step 2) are done. Still to
|
switch; the measurement list with its `+`, statistics and per-row edit), so the pages carry the
|
||||||
come, in the spec's order: the compact readouts (3), the events
|
panels' own controls, not a new form. (4) The **measurement editor stays a dialog**: the spec has the
|
||||||
section in the dock, the deletion of the left pane and the Events toggle, and `USER-GUIDE.md` and the
|
measurement add/edit/remove inside the `measure` page, but the dialog (`open_measure_dialog()`) is
|
||||||
manual's figures (4). Until then the events pane, the header's Events toggle and the manual still
|
what the `+`, a row's edit button and a click on a dock line all open; the page lists the measurements
|
||||||
describe the previous layout.
|
and hosts the dialog's entry points. (5) A **dock cursor line carries the full who / A / B / delta
|
||||||
|
cells** (not one value per line as the spec sketches), in a 5 + 3 x 9 character fixed-width grid: the
|
||||||
|
**who** cell ellipsizes at **5 characters** -- the width the 280 px pin allows; with 8 the readouts'
|
||||||
|
minimum width was 304 px and widened the sidebar -- and its tooltip carries the full text. (6) The dock and
|
||||||
|
the pages **share one string** for every value (see `docs/claude/invariants-readouts-and-cursors.md`).
|
||||||
|
The signal badges, the signal pages and the drag (step 2) are done. Still to come, in the spec's
|
||||||
|
order: the events 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 (which still describes the side panel's tabs, and the cursors and measurements as
|
||||||
|
panes of it) still describe the previous layout.
|
||||||
- **A plot holds at most eight signals** (`RowSet::kSlotsPerRow`), because a `Plot`
|
- **A plot holds at most eight signals** (`RowSet::kSlotsPerRow`), because a `Plot`
|
||||||
cannot give up a trace and the slots are therefore created up front.
|
cannot give up a trace and the slots are therefore created up front.
|
||||||
- **One toggle drives both cursor orientations.** The vertical markers and the
|
- **One toggle drives both cursor orientations.** The vertical markers and the
|
||||||
|
|||||||
@@ -101,8 +101,11 @@ touching the data path.
|
|||||||
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>`, `signals` (the signal list) and
|
own and registered under its id (`trigger`, `source-<id>`, `signals` (the signal list) and
|
||||||
`signal:<name>` (one signal's page, `src/ui_signal_page.cpp`, created on demand by `signal_page_ensure()`
|
`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 pruned by `signal_pages_sync()`, which `rebuild_signal_panels()` ends with), `cursors` (the cursors
|
||||||
and `events` are reserved for later steps). One page is open at a time and `App::slideover.page`
|
panel, unchanged) and `measure` (the measurements panel, unchanged; `m` toggles it); `events` is reserved
|
||||||
|
for a later step). Both of those are registered whether or not they are open (a closed page's widgets
|
||||||
|
exist, unmapped), and both are insensitive until the stream has signals, by the same
|
||||||
|
`update_signal_availability()` call that sets the dock's sensitivity. 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
|
||||||
@@ -116,9 +119,18 @@ touching the data path.
|
|||||||
file) leaves it **hidden** (the user asked for hide here, not the usual disable): `sync_badge_bar()` sets its visibility,
|
file) leaves it **hidden** (the user asked for hide here, not the usual disable): `sync_badge_bar()` sets its visibility,
|
||||||
pick and focus from `slideover.source_pages` being non-empty every tick, so anything that indexes the badge
|
pick and focus from `slideover.source_pages` being non-empty every tick, so anything that indexes the badge
|
||||||
(the tour's `badges` step targets the whole bar, `[badges]`) must tolerate it being absent.
|
(the tour's `badges` step targets the whole bar, `[badges]`) must tolerate it being absent.
|
||||||
- **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`), **280 px**
|
||||||
cursors and the measurements only, in one scroller (the signal list is the `signals` page). It holds no tab switcher and no
|
and fixed. It holds one thing, the **Readouts** box (`src/ui_dock.cpp`, `build_readouts_dock()`): a
|
||||||
revealer, and it does not hold a source kind's panels (those are slide-over pages).
|
**Cursors** block (heading, an **Edit** button that opens the `cursors` page, a `GtkGrid` of a header row
|
||||||
|
`A B delta` and one line per page line) and a **Measurements** block (heading, **Edit** opening the
|
||||||
|
`measure` page, one line per measurement: chip, type, value; a click on a line opens that measurement's
|
||||||
|
dialog; no measurements shows one dim "no measurements" line). It is read-only and **owns no formatting**:
|
||||||
|
`update_cursors_pane()` and `update_measures()` hand the string they wrote to the page's label to
|
||||||
|
`dock_cursor_cell()` / `dock_measure_value()` as well, and `rebuild_cursors_pane()` /
|
||||||
|
`rebuild_measures_pane()` end by rebuilding the dock's lines to match (`dock_rebuild_cursors()`,
|
||||||
|
`dock_rebuild_measures()`). It holds no tab switcher, no revealer and none of the full panels, nor a source
|
||||||
|
kind's panels (those are slide-over pages). The window's measurement editor is a dialog
|
||||||
|
(`open_measure_dialog()`), not part of the `measure` page.
|
||||||
|
|
||||||
**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
|
||||||
overlay is built (the tour's overlay wraps the whole window, so its dim rectangles cover the slide-over
|
overlay is built (the tour's overlay wraps the whole window, so its dim rectangles cover the slide-over
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
|||||||
runs after the window is destroyed and asking GTK about a widget then is four criticals, which is
|
runs after the window is destroyed and asking GTK about a widget then is four criticals, which is
|
||||||
how the first version of that line earned them. What stays in the menu is what acts on the *data*
|
how the first version of that line earned them. What stays in the menu is what acts on the *data*
|
||||||
(Fit, Export, Configurations) and the one editor that is not a pane (the layout editor): the signal list
|
(Fit, Export, Configurations) and the one editor that is not a pane (the layout editor): the signal list
|
||||||
is a section of the sidebar's dock, so there is nothing left to reveal or hide about it. The Arm/Disarm button in the trigger panel still has text.
|
is the `signals` slide-over page, so there is nothing left to reveal or hide about it. The Arm/Disarm button in the trigger panel still has text.
|
||||||
- **Five of this app's icons are its own, and they are a `GResource` compiled into the
|
- **Five of this app's icons are its own, and they are a `GResource` compiled into the
|
||||||
binary.** No icon theme has a glyph for an oscilloscope trigger, a pair of cursors or a
|
binary.** No icon theme has a glyph for an oscilloscope trigger, a pair of cursors or a
|
||||||
measurement ruler, and the stock names those buttons used to carry said something else
|
measurement ruler, and the stock names those buttons used to carry said something else
|
||||||
@@ -225,13 +225,15 @@ 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 cursors and the measurements one under another. It
|
(`dock_scroller`) holding only the compact **readouts** (`src/ui_dock.cpp`). 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: full panels competing for one narrow column each left every one of them short of room.
|
||||||
a scroller gives each its natural height. `m` scrolls the dock to the cursors (`dock_show_section()`); the signal list is
|
The full cursors and measurements panels are now the `cursors` and `measure` **slide-over pages**, reached
|
||||||
not a dock section but the `signals` slide-over page, which `g` and the `+` badge open. A *feature's* on/off is no longer a visibility at all -- the
|
by the readouts' **Edit** buttons, and `m` toggles `measure` (it no longer scrolls the dock;
|
||||||
**cursors'** toggle sets its pane's **body** insensitive -- the readout has nothing to show with the
|
`dock_show_section()` is gone); the signal list is the `signals` slide-over page, which `g` and the `+` badge
|
||||||
|
open. The header's Cursors toggle no longer opens anything: it only enables the cursors. A *feature's* on/off is no longer a visibility at all -- the
|
||||||
|
**cursors'** toggle sets its pane's **body** insensitive (and the dock's cursor grid beside it) -- the readout has nothing to show with the
|
||||||
instruments off -- and the *body* and not the pane, because the pane's heading carries its own switch
|
instruments off -- and the *body* and not the pane, because the pane's heading carries its own switch
|
||||||
(see the next bullet). The **trigger's body is deliberately never disabled**: a trigger is configured
|
(see the next bullet). The **trigger's body is deliberately never disabled**: a trigger is configured
|
||||||
*before* it is switched on, so switching it off to change it, or to read what it is set to, is the
|
*before* it is switched on, so switching it off to change it, or to read what it is set to, is the
|
||||||
@@ -243,7 +245,10 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
|||||||
- **The dock is shown but insensitive until the stream has signals ("disable, do not hide").**
|
- **The dock is shown but insensitive until the stream has signals ("disable, do not hide").**
|
||||||
`update_side_visibility()` and the tick's per-frame block set the column's visibility from the user's wish
|
`update_side_visibility()` and the tick's per-frame block set the column's visibility from the user's wish
|
||||||
alone (`sidebar_wanted`) and the dock's *sensitivity* from `have_signals`; the toolbar's Dock button stays
|
alone (`sidebar_wanted`) and the dock's *sensitivity* from `have_signals`; the toolbar's Dock button stays
|
||||||
sensitive throughout. The wish is persisted (`dock = true|false` in the session file) and a change of it
|
sensitive throughout. The `cursors` and `measure` **pages follow the same condition** through
|
||||||
|
`update_signal_availability()` (called from `update_side_visibility()` and the per-frame block), so a
|
||||||
|
page opened by `m` before the stream has signals is insensitive, not refused. `[readouts] ... pages_sensitive=`
|
||||||
|
reads it. The wish is persisted (`dock = true|false` in the session file) and a change of it
|
||||||
schedules a save. `dock:` in the dump reads the result.
|
schedules a save. `dock:` in the dump reads the result.
|
||||||
- **The signal badge is the drag handle, and a drop handler only moves widgets.** Dragging a signal onto a plot
|
- **The signal badge is the drag handle, and a drop handler only moves widgets.** Dragging a signal onto a plot
|
||||||
starts on its badge in the badge bar (a `GtkDragSource` on the badge's button, payload the signal index as a
|
starts on its badge in the badge bar (a `GtkDragSource` on the badge's button, payload the signal index as a
|
||||||
@@ -584,6 +589,18 @@ The `Help` submenu, the contextual help's "?" and the guided tour, and the traps
|
|||||||
`ui_impl::hint_button()` reached either by the table's `context_help_sync()` or by
|
`ui_impl::hint_button()` reached either by the table's `context_help_sync()` or by
|
||||||
`context_help_button()` for a window with no `App` (the source chooser) -- one button, two callers,
|
`context_help_button()` for a window with no `App` (the source chooser) -- one button, two callers,
|
||||||
so the two windows cannot drift into two affordances.
|
so the two windows cannot drift into two affordances.
|
||||||
|
- **A hint on a slide-over page's heading is attached all the time and drawn only while the page is open.**
|
||||||
|
The trigger's, signals', cursors' and measurements' headings (`trigger_head`, `signals_head`,
|
||||||
|
`cursors_head`, `measures_head`) live on pages that exist, unmapped, whether or not they are open, so
|
||||||
|
`context_help_sync()` attaches their "(i)" like any other and the count (`hints=12`) does not depend on
|
||||||
|
which page is up. There is **no second code path** and the dock's readouts carry no hint of their own: the
|
||||||
|
pages' hints say what the dock shows too (the cursors' and measurements' bodies mention the read-only copy
|
||||||
|
and the Edit button). A probe that must *see* one drawn needs its page open, like every other reading off a page.
|
||||||
|
- **The tour has one stop for the readouts and none for the pages behind them.** The dock's stop
|
||||||
|
(`side`, target `side_box`, no `page`, so it closes the panel) describes the readouts, the **Edit**
|
||||||
|
buttons and the click on a measurement; the `cursors` and `measure` pages are reached from there rather than
|
||||||
|
walked. A stop for either would be one more `TourStop::page` (see the next bullet), and the plan's
|
||||||
|
length is asserted (`steps=6`, `steps=5` with the dock put away) -- a new stop changes both.
|
||||||
- **The guided tour takes no grab, and that is the whole reason it is an overlay.** Four dim
|
- **The guided tour takes no grab, and that is the whole reason it is an overlay.** Four dim
|
||||||
rectangles around the hole are ordinary widgets that swallow the clicks that land on them and
|
rectangles around the hole are ordinary widgets that swallow the clicks that land on them and
|
||||||
nothing else; `Skip`, `Finish` and `Escape` hide them, and there is no popover, no gesture and no
|
nothing else; `Skip`, `Finish` and `Escape` hide them, and there is no popover, no gesture and no
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
|||||||
from the paned's own width, re-parenting the column, the property form of its children, size requests):
|
from the paned's own width, re-parenting the column, the property form of its children, size requests):
|
||||||
the *mechanism* was the fault. It is an **`AdwOverlaySplitView`** now — what a utility sidebar is in
|
the *mechanism* was the fault. It is an **`AdwOverlaySplitView`** now — what a utility sidebar is in
|
||||||
GNOME, as against `AdwNavigationSplitView`, which is for navigation lists — with `min-sidebar-width` =
|
GNOME, as against `AdwNavigationSplitView`, which is for navigation lists — with `min-sidebar-width` =
|
||||||
`max-sidebar-width` = 320 in **pixels**, so the width is its own at any window size, and `collapsed` (set
|
`max-sidebar-width` = 280 in **pixels**, so the width is its own at any window size, and `collapsed` (set
|
||||||
from the window's width in `tick()`) to *overlay* the plot when there is no room beside it rather than
|
from the window's width in `tick()`) to *overlay* the plot when there is no room beside it rather than
|
||||||
being squeezed. `[sidebar-probe]` reads both states: `window=756 sidebar=320` under a 2x scale is exactly
|
being squeezed. `[sidebar-probe]` reads both states: `window=756 sidebar=280` under a 2x scale is exactly
|
||||||
the case that used to be zero.
|
the case that used to be zero.
|
||||||
- **The sidebar's button is the only input; `AdwOverlaySplitView:show-sidebar` is an output.** The split
|
- **The sidebar's button is the only input; `AdwOverlaySplitView:show-sidebar` is an output.** The split
|
||||||
view writes that property *itself* — at startup, and when it collapses — with no user involved, so reading
|
view writes that property *itself* — at startup, and when it collapses — with no user involved, so reading
|
||||||
@@ -29,7 +29,7 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
|||||||
no-signals case must leave the wish alone, or a source connecting later finds a sidebar the user never closed.
|
no-signals case must leave the wish alone, or a source connecting later finds a sidebar the user never closed.
|
||||||
The wish is the session's `dock` key: a change of it (not a program's own write, and not a restore) schedules a save.
|
The wish is the session's `dock` key: a change of it (not a program's own write, and not a restore) schedules a save.
|
||||||
- **`AdwOverlaySplitView:sidebar-width-fraction` is a 0..1 fraction of the window, whatever
|
- **`AdwOverlaySplitView:sidebar-width-fraction` is a 0..1 fraction of the window, whatever
|
||||||
`sidebar-width-unit` says.** Setting a pixel count there (320) is a `GObject` critical, and it silently
|
`sidebar-width-unit` says.** Setting a pixel count there (280) is a `GObject` critical, and it silently
|
||||||
falls back to 0.25 — which reads as "the sidebar is mysteriously 560 px wide" on a wide window with no
|
falls back to 0.25 — which reads as "the sidebar is mysteriously 560 px wide" on a wide window with no
|
||||||
error anywhere the build would catch. Pin the width with `min-sidebar-width`/`max-sidebar-width`.
|
error anywhere the build would catch. Pin the width with `min-sidebar-width`/`max-sidebar-width`.
|
||||||
- **A `GtkPaned`'s position is stated after both its sides are filled**, and that is a fact about the
|
- **A `GtkPaned`'s position is stated after both its sides are filled**, and that is a fact about the
|
||||||
@@ -130,9 +130,16 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
|||||||
`bar_min_w` reads the same with one signal, nine signals and the overflow (244 on the E-1608, 124 on UDPS:
|
`bar_min_w` reads the same with one signal, nine signals and the overflow (244 on the E-1608, 124 on UDPS:
|
||||||
the Source badge is on screen for the E-1608 and hidden for UDPS, and its text differs by kind). A change that makes it grow with the signal count has
|
the Source badge is on screen for the E-1608 and hidden for UDPS, and its text differs by kind). A change that makes it grow with the signal count has
|
||||||
taken the scroller out of the measurement.
|
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, and it is the readouts' width that holds it there** (`side_column`
|
||||||
and cap), and it holds one scroller with the cursors and the measurements. A
|
`width-request` 260, the split view's 280 px floor and cap). The dock holds only the compact readouts, so 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 it taller; the scroller absorbs the rest. **The readouts' minimum
|
||||||
|
width is the sum of their cells' character widths, and it must stay under 280** (the Readouts box is 268:
|
||||||
|
280 less its 6 px margins): a cursor line is the `who` cell (5 characters) plus three value cells (9 each),
|
||||||
|
every one ellipsized at that width (`width-chars` = `max-width-chars`), so a long value is cut and its
|
||||||
|
tooltip carries the text and the layout never depends on what a value reads. The `who` cell was 8
|
||||||
|
characters, which made the readouts' minimum width 304 px; that pushed the sidebar to 304 px
|
||||||
|
(`dock_w=304`) and defeated the 280 pin. Widening any cell is the same
|
||||||
|
trap -- read `[readouts] ... dock_w=` (must be 280) and the `dock cursors:` / `dock measures:` `fits=`.
|
||||||
- **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
|
||||||
trace at another signal.
|
trace at another signal.
|
||||||
|
|||||||
@@ -41,6 +41,22 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
|||||||
window's **first sample** and never from history before the window, so a measurement never depends on data
|
window's **first sample** and never from history before the window, so a measurement never depends on data
|
||||||
outside the window it reports on: the left-edge step transient is removed by the seeding, not by priming
|
outside the window it reports on: the left-edge step transient is removed by the seeding, not by priming
|
||||||
from earlier samples.
|
from earlier samples.
|
||||||
|
- **The dock's readouts and the pages' panels are one string, never two.** The dock (`src/ui_dock.cpp`)
|
||||||
|
shows a read-only copy of the cursors table and of the measurement values, and it must not format
|
||||||
|
anything: `update_cursors_pane()` and `update_measures()` format each value **once**, into a local, and
|
||||||
|
hand that same variable to the page's label **and** to `dock_cursor_cell()` / `dock_measure_value()` --
|
||||||
|
on every branch, including the `"--"` blanking one (cursors off, no sample). A second formatter in the
|
||||||
|
dock would be two spellings of one reading that drift the first time `format_measure()` changes, and
|
||||||
|
the dock exists so that the two can be read side by side. The `who` cell is copied from the page's label
|
||||||
|
verbatim (markup chip and name), and the dock's lines are rebuilt from the page's whenever the page
|
||||||
|
rebuilds (`dock_rebuild_cursors()`, `dock_rebuild_measures()`), so the line counts agree by
|
||||||
|
construction. A cell is **ellipsized at a fixed character count** (who 5, values 9, measurement type 12) with
|
||||||
|
the full text in its tooltip: the dock is 280 px wide and its layout must not depend on what a value
|
||||||
|
reads, so a long value is cut and quoted whole in the tooltip rather than widening the column (the
|
||||||
|
`who` cell was 8 characters, which made the readouts 304 px wide and pushed the sidebar past its
|
||||||
|
pin). `[cursors-probe] ... dock cursors:` and `[measures-probe] ... dock measures:` assert it: `same_text=1`
|
||||||
|
compares `gtk_label_get_text()` (the untruncated text) of every dock label with the page's, and
|
||||||
|
`fits=1` that the Readouts box is no wider than the dock.
|
||||||
- **`format_measure()` is the one formatter for both panes, and its SI prefix does not depend on
|
- **`format_measure()` is the one formatter for both panes, and its SI prefix does not depend on
|
||||||
there being a unit.** The cursors pane's values and the measurements pane's `text=` go through
|
there being a unit.** The cursors pane's values and the measurements pane's `text=` go through
|
||||||
it, so a change reaches both. The prefix ladder used to be inside `if (!unit.empty())`, which
|
it, so a change reaches both. The prefix ladder used to be inside `if (!unit.empty())`, which
|
||||||
@@ -55,7 +71,7 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
|||||||
unit (`636.62 mV`). Below `1e-12` the ladder runs out, and `%.2f` would print `0.00` again, so
|
unit (`636.62 mV`). Below `1e-12` the ladder runs out, and `%.2f` would print `0.00` again, so
|
||||||
that range falls back to `%.3g`.
|
that range falls back to `%.3g`.
|
||||||
- **With the instruments off the readout blanks, and the panel stays on screen.** Cursors-off makes the
|
- **With the instruments off the readout blanks, and the panel stays on screen.** Cursors-off makes the
|
||||||
pane *insensitive* rather than hiding it -- a panel you can still see is a panel you can read, and the
|
pane *insensitive* (the page's body, and the dock's cursor grid beside it) rather than hiding it -- a panel you can still see is a panel you can read, and the
|
||||||
settings you are about to switch back on must not vanish while you look for them -- and every cell in
|
settings you are about to switch back on must not vanish while you look for them -- and every cell in
|
||||||
it is written `"--"`, the spelling an unavailable cell already uses. A readout quotes a stored sample;
|
it is written `"--"`, the spelling an unavailable cell already uses. A readout quotes a stored sample;
|
||||||
with nothing bracketing one there is no sample to quote, and keeping the last values would be quoting
|
with nothing bracketing one there is no sample to quote, and keeping the last values would be quoting
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
|||||||
toggle; written as a bare top-level boolean (`measure_stats = true/false`), defaults to `false`
|
toggle; written as a bare top-level boolean (`measure_stats = true/false`), defaults to `false`
|
||||||
when absent, and **`dock`** -- `LayoutState::dock_shown`, the Dock button's state (the user's last word on it,
|
when absent, and **`dock`** -- `LayoutState::dock_shown`, the Dock button's state (the user's last word on it,
|
||||||
`App::sidebar_wanted`): a bare top-level boolean written where `side_tab` used to be, default `true`.
|
`App::sidebar_wanted`): a bare top-level boolean written where `side_tab` used to be, default `true`.
|
||||||
It is the **only** thing the dock persists -- its 320 px width is fixed, so there is nothing to store --
|
It is the **only** thing the dock persists -- its 280 px width is fixed, so there is nothing to store --
|
||||||
and **the open slide-over page is deliberately not persisted** (a panel that opens by itself at start-up
|
and **the open slide-over page is deliberately not persisted** (a panel that opens by itself at start-up
|
||||||
is a surprise, and a page id from another source kind may not exist). The parser ignores unknown keys
|
is a surprise, and a page id from another source kind may not exist). The parser ignores unknown keys
|
||||||
(its key chain has no erroring final `else`), so a file written before the tabs became a dock
|
(its key chain has no erroring final `else`), so a file written before the tabs became a dock
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ Two lines of the self-check output are assertions in disguise:
|
|||||||
window slides over a round number. The companion `axes.w changes: N (last at frame F,
|
window slides over a round number. The companion `axes.w changes: N (last at frame F,
|
||||||
side panel up=S)` line separates the two readings: `0`, or a handful near the start,
|
side panel up=S)` line separates the two readings: `0`, or a handful near the start,
|
||||||
is a settled layout; a count near the frame count is the twitch. Runs far longer than
|
is a settled layout; a count near the frame count is the twitch. Runs far longer than
|
||||||
the documented probes have shown one ~320 px step — the side panel's width — that
|
the documented probes have shown one ~320 px step — the side panel's width, when it was 320 px — that
|
||||||
reverts; it is intermittent and unexplained, so read `changes` before calling a range
|
reverts; it is intermittent and unexplained, so read `changes` before calling a range
|
||||||
the twitch bug.
|
the twitch bug.
|
||||||
- `[trig-probe] ... trigger=on ... display=... epoch=...` (stderr,
|
- `[trig-probe] ... trigger=on ... display=... epoch=...` (stderr,
|
||||||
@@ -425,8 +425,8 @@ Two lines of the self-check output are assertions in disguise:
|
|||||||
— that is how it tells a gesture from its own echo — so a fit that wrote the group alone reads
|
— that is how it tells a gesture from its own echo — so a fit that wrote the group alone reads
|
||||||
back as the zoomed range one frame later.
|
back as the zoomed range one frame later.
|
||||||
- `[layout-probe] <action> rows=N buttons=B done=D done_box=[x,y,WxH] rows_y=[..] close=[..] add=[..] traces=[..]`
|
- `[layout-probe] <action> rows=N buttons=B done=D done_box=[x,y,WxH] rows_y=[..] close=[..] add=[..] traces=[..]`
|
||||||
`side_w` is the sidebar column's width and **must be its own request (320), never 0**: it read 0 while
|
`side_w` is the sidebar column's width and **must be its own request (280), never 0**: it read 0 while
|
||||||
the divider sat at the window's right edge, which is a panel that is not there. It was 320 during the
|
the divider sat at the window's right edge, which is a panel that is not there. It was 280 during the
|
||||||
first frames and 0 once the window had settled, so read it from a `placed` line rather than the first.
|
first frames and 0 once the window had settled, so read it from a `placed` line rather than the first.
|
||||||
(stderr, `UDPSCOPE_PROBE_LAYOUT_MS`) — **`buttons` must be `2N+1`** while the editor is
|
(stderr, `UDPSCOPE_PROBE_LAYOUT_MS`) — **`buttons` must be `2N+1`** while the editor is
|
||||||
up (one `×` per row, one `+` per boundary) and **0 on the `editor off` line**: the
|
up (one `×` per row, one `+` per boundary) and **0 on the `editor off` line**: the
|
||||||
@@ -479,16 +479,30 @@ Two lines of the self-check output are assertions in disguise:
|
|||||||
substitutes a missing-image placeholder, the button still works, and every other line of the
|
substitutes a missing-image placeholder, the button still works, and every other line of the
|
||||||
dump still passes. Changing an icon name is a one-line change in `build_toolbar()` and this
|
dump still passes. Changing an icon name is a one-line change in `build_toolbar()` and this
|
||||||
is the only check that it names something that exists.
|
is the only check that it names something that exists.
|
||||||
- `dock: shown=1 sensitive=1 w=320 scroller_pages=1` (in the exit dump, beside `panels:`) -- the sidebar's dock
|
- `dock: shown=1 sensitive=1 w=280 scroller_pages=1` (in the exit dump, beside `panels:`) -- the sidebar's dock
|
||||||
as the last tick found it. It replaces the old `switcher:` line: there is no tab switcher, the sidebar is
|
as the last tick found it. There is no tab switcher: the sidebar is one scroller (`dock_scroller`) holding the
|
||||||
one scroller (`dock_scroller`) holding the signal list, the cursors and the measurements. **`shown=1`
|
**readouts box only** -- a compact, read-only copy of the cursors and of the measurements, each with an Edit
|
||||||
|
button (`build_readouts_dock()` in `src/ui_dock.cpp`). The signal list, the full cursors table, the measurements
|
||||||
|
and the trigger are slide-over pages. **`shown=1`
|
||||||
always** (the dock is on screen from the start; `shown=0` only when the user hid it with the Dock button,
|
always** (the dock is on screen from the start; `shown=0` only when the user hid it with the Dock button,
|
||||||
which a probe does deliberately); **`sensitive=0` only before the stream has signals** ("disable, do not
|
which a probe does deliberately); **`sensitive=0` only before the stream has signals** ("disable, do not
|
||||||
hide") -- a run against a port with no sender reads `shown=1 sensitive=0`, a normal run `sensitive=1`;
|
hide") -- a run against a port with no sender reads `shown=1 sensitive=0`, a normal run `sensitive=1`;
|
||||||
`w=` is the sidebar's own width (320); **`scroller_pages=1`** counts the scrollers directly under the dock
|
`w=` is the sidebar's own width (**280**); **`scroller_pages=1`** counts the scrollers directly under the dock
|
||||||
column and says there is one scroller and no stack. These are captured on the tick or at the exit probe:
|
column and says there is one scroller and no stack. These are captured on the tick or at the exit probe:
|
||||||
the dump runs after the window is destroyed. A source with extra panels adds *no* dock section: its panels
|
the dump runs after the window is destroyed. A source with extra panels adds *no* dock section: its panels
|
||||||
are slide-over pages (`source-<id>`), so the line reads the same on the E-1608 and the probe kind.
|
are slide-over pages (`source-<id>`), so the line reads the same on the E-1608 and the probe kind.
|
||||||
|
- `[readouts] pages cursors=1 measure=1 dock_children=1 dock_w=280 pages_sensitive=1 signals=1` (in the exit
|
||||||
|
dump; `dock_children` counts the direct children of the dock page) -- the two pages and the dock against the
|
||||||
|
stream. **`cursors=1 measure=1`**: both slide-over pages are registered, always and from the start (not when
|
||||||
|
the stream has signals); `0` is a page that was never added, and then the dock's Edit buttons and the `m` key
|
||||||
|
open nothing. **`dock_w=280`** is the sidebar's width, as for `dock:`. **`pages_sensitive` must equal
|
||||||
|
`signals`**: both pages are insensitive until the stream has signals ("disable, do not hide";
|
||||||
|
`update_signal_availability()` writes them with the dock), so a run against a port with no sender reads
|
||||||
|
`pages_sensitive=0 signals=0`, a normal run `pages_sensitive=1 signals=1`. `pages_sensitive=1` with `signals=0`
|
||||||
|
is a page that can be opened and read with nothing to read; `pages_sensitive=0` with `signals=1` is a
|
||||||
|
stream whose pages never came back after the signal list arrived. **`dock_children=1`**: the dock
|
||||||
|
page holds the readouts box and nothing else (a second child is a section that crept back into the dock; 0 is a
|
||||||
|
dock that was built empty).
|
||||||
- `help layer: contextual=on hints=12 ids={events plot status cursors measures trigger trigger_advanced events_record trigger_search signals signals_config window} icon=dialog-information-symbolic(ok) hint=12x12; tour=idle steps=6 step=0 auto=1 requested=0` (in the exit
|
- `help layer: contextual=on hints=12 ids={events plot status cursors measures trigger trigger_advanced events_record trigger_search signals signals_config window} icon=dialog-information-symbolic(ok) hint=12x12; tour=idle steps=6 step=0 auto=1 requested=0` (in the exit
|
||||||
dump, beside `dock:`) — the help affordance layer as the last tick found it. **`hints=` must equal
|
dump, beside `dock:`) — the help affordance layer as the last tick found it. **`hints=` must equal
|
||||||
the number of ids**, and the ids are the surfaces the contextual help is on: eleven of the window
|
the number of ids**, and the ids are the surfaces the contextual help is on: eleven of the window
|
||||||
@@ -988,7 +1002,7 @@ two also catch a row whose accelerator went missing. `settings=` must be a real
|
|||||||
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), and on the `signals` stop for the same
|
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).
|
reason (the dock beside it is 280 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
|
||||||
@@ -999,8 +1013,8 @@ two also catch a row whose accelerator went missing. `settings=` must be a real
|
|||||||
is how a probe puts the dock away for good): the dock's own stop is dropped, **and the trigger and
|
is how a probe puts the dock away for good): the dock's own stop is dropped, **and the trigger and
|
||||||
signals stops are kept** because the slide-over does not depend on the dock -- five stops remain (plot,
|
signals stops are kept** because the slide-over does not depend on the dock -- five stops remain (plot,
|
||||||
badges, trigger, signals, status).
|
badges, trigger, signals, status).
|
||||||
- `[keys] a: armed 0->1 | space: paused 0->1 | t: trigger panel: 0->1 | c: cursors: 0->1 | m: dock 0->243 (cursors_y=243 reach=2256 at_cursors=1) | g: page=1 dock_still=1 closed=1 | … | esc: opened=1 handled=1 closed=1 idle_handled=0 | editable focused: 'm' refused=1` (stderr, `UDPSCOPE_PROBE_KEYS_MS`) — **every `X->Y` pair must differ** (`g` is not a pair: it opens the `signals` slide-over page and a second press closes it), **`refused` must be 1**, and the `esc:` reading must be `opened=1 handled=1 closed=1 idle_handled=0`.
|
- `[keys] a: armed 0->1 | space: paused 0->1 | t: trigger panel: 0->1 | c: cursors: 0->1 | m: page=1 dock_still=1 closed=1 | g: page=1 dock_still=1 closed=1 | … | esc: opened=1 handled=1 closed=1 idle_handled=0 | editable focused: 'm' refused=1` (stderr, `UDPSCOPE_PROBE_KEYS_MS`) — **every `X->Y` pair must differ** (`m` and `g` are not pairs: each opens a slide-over page, `measure` and `signals`, and a second press closes it), **`refused` must be 1**, and the `esc:` reading must be `opened=1 handled=1 closed=1 idle_handled=0`.
|
||||||
The `m`/`g` readings are the dock scroller's vertical adjustment before and after (the probe pads the dock to 3000 px so there is something to scroll, and undoes it at the end): **`m` must land on `cursors_y`, the cursors panel's y in the dock (`at_cursors=1`), and `g` must read `page=1 dock_still=1 closed=1`** (the `signals` page opened, the dock's scroll untouched, a second press closing it), which is what says `m` scrolls to a section and `g` opens the list's page rather than toggling a pane; a `reach` of 0 would mean the dock fit its viewport and the probe's padding was lost; `t`/`c` read the toolbar toggle's own state, because those two enable a feature and the button is where that state is visible. **The `esc:` reading goes through `on_app_key_pressed()` with `GDK_KEY_Escape`**, the handler the window's key controller calls, and not through `slideover_escape()`: the probe opens the `trigger` slide-over page (`opened=1`), sends the key (`handled=1`: it was consumed, and `closed=1`: the page is gone), then sends it again with nothing open (`idle_handled=0`: Escape is left alone when there is nothing for it to close, so a dialog or popover under it still gets it). `handled=0` or `closed=0` is the slide-over's Escape never reaching the panel from the window's key path -- a handler that returns before the slide-over test, or a controller in the wrong phase -- which the `[slideover] esc_closes=1` reading (a direct call to `slideover_escape()`) cannot see. **Limit of the `m`/`g` readings:** the padding is 3000 px at the end of the page, so `reach` is non-zero on any window shorter than that and the key has somewhere to scroll, but it does not push the cursors panel out of the viewport -- on a window whose dock viewport is taller than `cursors_y` (a tall window) the section is already in view at offset 0 and `m` still scrolls to it; `at_cursors=1` is the key landing the section's top at the viewport's top, which is the reading, not "the section was hidden before". The refusal is the whole reason the controller is in the bubble phase: every bare-letter accel is also a character, so an accel that fires while a `GtkEditable` has focus makes the window entry unusable. A pair reading `0->0` is an action whose dispatch does not reach the handler a click reaches. Note the format is `<key>: <widget-description>: <before>-><after>` — the name passed to `before_after()` includes the widget's description, so `t: trigger panel: 0->1` is the correct form (not `t: trigger panel 0->1` without the colon before the values).
|
The `m`/`g` readings are `page=P dock_still=D closed=C`: **all three must be 1 for both keys** -- `P` the page the key opens (`measure` for `m`, `signals` for `g`) is the slide-over's open page after the first press, `D` the dock scroller's vertical adjustment did not move (the dock holds only the readouts, so a key must not scroll it), and `C` a second press closes the page. This is what says `m` opens the measurements' page rather than scrolling the dock to a section (the old `m: dock 0->N (cursors_y=… at_cursors=1)` reading is gone with the dock sections), and that neither key toggles a pane. `m` does *not* turn the measurements on or off: the header Cursors toggle only enables cursors, and `m` only opens the page. `t`/`c` read the toolbar toggle's own state, because those two enable a feature and the button is where that state is visible. **The `esc:` reading goes through `on_app_key_pressed()` with `GDK_KEY_Escape`**, the handler the window's key controller calls, and not through `slideover_escape()`: the probe opens the `trigger` slide-over page (`opened=1`), sends the key (`handled=1`: it was consumed, and `closed=1`: the page is gone), then sends it again with nothing open (`idle_handled=0`: Escape is left alone when there is nothing for it to close, so a dialog or popover under it still gets it). `handled=0` or `closed=0` is the slide-over's Escape never reaching the panel from the window's key path -- a handler that returns before the slide-over test, or a controller in the wrong phase -- which the `[slideover] esc_closes=1` reading (a direct call to `slideover_escape()`) cannot see. The refusal is the whole reason the controller is in the bubble phase: every bare-letter accel is also a character, so an accel that fires while a `GtkEditable` has focus makes the window entry unusable. A pair reading `0->0` is an action whose dispatch does not reach the handler a click reaches. Note the format is `<key>: <widget-description>: <before>-><after>` — the name passed to `before_after()` includes the widget's description, so `t: trigger panel: 0->1` is the correct form (not `t: trigger panel 0->1` without the colon before the values).
|
||||||
- `[color] '<name>' at row R slot S: trace=#RRGGBB chip_agrees=1 (want 1)`, then `[color] override: trace=#123456 chip_agrees=1`, `[color] session: entries=1 rgb=#123456` and `[color] default: trace=#RRGGBB chip_agrees=1` (stderr, `UDPSCOPE_PROBE_COLOR_MS`) — **all three `chip_agrees` must be 1**, the override line's `trace` must be `#123456`, the session line must read `entries=1 rgb=#123456`, and the default line's `trace` must be back to the first line's. Run it with `UDPSCOPE_ENABLE_ALL_MS` ahead of it, or there is no bound trace and the probe prints `no bound trace to recolour` instead of asserting anything; on the standard mock the first line reads `'sine' at row 0 slot 0: trace=#4FA3FF`. Two things make this an assertion rather than a tautology. The colours are read out of **`plot::Plot::trace().color`** — what the renderer will stroke, reached through `Row::plot` *after* `relayout_areas()`, since a new colour is a new figure — and out of the chip's own `<span foreground="…">` markup, not by asking `RowSet::signal_color()` twice, which would pass against a chip that never reached the trace. And the override is `#123456`, deliberately in no palette slot: an override equal to the entry it replaces passes against an implementation that ignores overrides entirely. The session leg round-trips `collect_layout()` → `save_layout()` → `load_layout()` on a temp path and deletes it, because a probe must not leave a colour in the real session file for a later run to inherit.
|
- `[color] '<name>' at row R slot S: trace=#RRGGBB chip_agrees=1 (want 1)`, then `[color] override: trace=#123456 chip_agrees=1`, `[color] session: entries=1 rgb=#123456` and `[color] default: trace=#RRGGBB chip_agrees=1` (stderr, `UDPSCOPE_PROBE_COLOR_MS`) — **all three `chip_agrees` must be 1**, the override line's `trace` must be `#123456`, the session line must read `entries=1 rgb=#123456`, and the default line's `trace` must be back to the first line's. Run it with `UDPSCOPE_ENABLE_ALL_MS` ahead of it, or there is no bound trace and the probe prints `no bound trace to recolour` instead of asserting anything; on the standard mock the first line reads `'sine' at row 0 slot 0: trace=#4FA3FF`. Two things make this an assertion rather than a tautology. The colours are read out of **`plot::Plot::trace().color`** — what the renderer will stroke, reached through `Row::plot` *after* `relayout_areas()`, since a new colour is a new figure — and out of the chip's own `<span foreground="…">` markup, not by asking `RowSet::signal_color()` twice, which would pass against a chip that never reached the trace. And the override is `#123456`, deliberately in no palette slot: an override equal to the entry it replaces passes against an implementation that ignores overrides entirely. The session leg round-trips `collect_layout()` → `save_layout()` → `load_layout()` on a temp path and deletes it, because a probe must not leave a colour in the real session file for a later run to inherit.
|
||||||
- `[reseq-probe] reseq=N late=N stale=N overflows=N holes=N hole_slots=N backfilled=N
|
- `[reseq-probe] reseq=N late=N stale=N overflows=N holes=N hole_slots=N backfilled=N
|
||||||
gaps_refused=N open_holes=N bands=N bands_repaired=N nan_slots=N scanned=N trigger_in_hole=D`
|
gaps_refused=N open_holes=N bands=N bands_repaired=N nan_slots=N scanned=N trigger_in_hole=D`
|
||||||
@@ -1791,11 +1805,26 @@ disagree. The two lines are the claim, in both directions:
|
|||||||
- `trigger panel sensitive …=0` is the *panel body*, not the panel: the heading row, with its switch,
|
- `trigger panel sensitive …=0` is the *panel body*, not the panel: the heading row, with its switch,
|
||||||
stays live. `1` here while trigger mode is off is the pane not being disabled at all.
|
stays live. `1` here while trigger mode is off is the pane not being disabled at all.
|
||||||
|
|
||||||
|
## `dock cursors:` and `dock measures:`
|
||||||
|
|
||||||
|
```
|
||||||
|
[cursors-probe] <what> dock cursors: lines=1 page_lines=1 same_text=1 dock_w=268 side_w=280 fits=1 dock_sensitive=1
|
||||||
|
[measures-probe] <what> dock measures: lines=13 page_rows=13 same_text=1 dock_w=268 side_w=280 fits=1
|
||||||
|
```
|
||||||
|
|
||||||
|
These ride on the `[cursors-probe]` readings (every state line gets a `dock cursors:` beside it) and on the `[measures-probe]` readings (`added`, `settled`, `final`), and read the dock's compact copy against the page it copies. The dock never formats a value: `update_cursors_pane()` and `update_measures()` hand the same string to the page label and the dock label.
|
||||||
|
|
||||||
|
- **`same_text=1` is the assertion**: every dock label (the cursors' who, A, B, delta cells; the measurements' values) reads the same text as the page's label in the same position. `same_text=0` is a second formatter, or a value written to one view only; the two panes must never disagree. The probe compares `gtk_label_get_text()`, so the who cell compares as the text a user reads, markup stripped.
|
||||||
|
- **`lines` must equal `page_lines` / `page_rows`**: one dock line per page line. A shorter dock is a rebuild that was not mirrored (`dock_rebuild_cursors()` / `dock_rebuild_measures()` run from the pages' rebuilds); `same_text` reads 0 with it, so this names the cause.
|
||||||
|
- **`fits=1`** (`dock_w <= side_w`, `side_w > 0`): the readouts box fits inside the sidebar scroller. `dock_w` reads **268** inside the 280 px sidebar (the box's own margins and the fixed label widths: who 5 characters, each value 9, a measurement's type 12). **A who cell at 8 characters made the box 304 px and `fits=0`**, which is the defeat of the pin: the fixed-width ellipsis is what makes the dock's layout independent of what a value reads, so a cell given more characters widens the dock for every run, not only for a long name. `side_w=-1` or `dock_w=-1` is a probe that ran before the dock was built.
|
||||||
|
- **`dock_sensitive=1`** (cursors only): the dock's cursor grid is live whenever the stream has signals; `0` before them ("disable, do not hide"), `0` with signals is the dock never coming back.
|
||||||
|
- On a session with no cursors line, or with no measurements, `lines=0 page_lines=0 same_text=1` is correct: the dock then shows `no measurements` for the measurements (one non-value label, not counted in `lines`).
|
||||||
|
|
||||||
## `[sidebar-probe]`
|
## `[sidebar-probe]`
|
||||||
|
|
||||||
```
|
```
|
||||||
[sidebar-probe] beside window=756 sidebar=320 collapsed=1 shown=1 button=1(sens=1)
|
[sidebar-probe] beside window=756 sidebar=280 collapsed=1 shown=1 button=1(sens=1)
|
||||||
[sidebar-probe] regained window=756 sidebar=320 collapsed=1 shown=1 button=1(sens=1)
|
[sidebar-probe] regained window=756 sidebar=280 collapsed=1 shown=1 button=1(sens=1)
|
||||||
```
|
```
|
||||||
|
|
||||||
`UDPSCOPE_PROBE_SIDEBAR_MS` reads the sidebar in the two states a window can put it in, and against a hide
|
`UDPSCOPE_PROBE_SIDEBAR_MS` reads the sidebar in the two states a window can put it in, and against a hide
|
||||||
@@ -1806,7 +1835,7 @@ and `regained` reads 400 ms later.
|
|||||||
|
|
||||||
- **`sidebar` must never be 0.** It was, for every window narrower than the 940 px the divider used to sit
|
- **`sidebar` must never be 0.** It was, for every window narrower than the 940 px the divider used to sit
|
||||||
at, and the pane could only be found by dragging the divider back — the report this reading exists for.
|
at, and the pane could only be found by dragging the divider back — the report this reading exists for.
|
||||||
It must read its own width (320) in *both* states: `collapsed` changes where the sidebar is, never how
|
It must read its own width (280) in *both* states: `collapsed` changes where the sidebar is, never how
|
||||||
wide it is.
|
wide it is.
|
||||||
- **`shown` and `button` must agree, always.** They are the panel and the toolbar button, and a button that
|
- **`shown` and `button` must agree, always.** They are the panel and the toolbar button, and a button that
|
||||||
says "shown" over a hidden panel is the report this reading exists for. `shown=1 button=1` on `regained`
|
says "shown" over a hidden panel is the report this reading exists for. `shown=1 button=1` on `regained`
|
||||||
@@ -1822,24 +1851,22 @@ and `regained` reads 400 ms later.
|
|||||||
## `[side-tab-probe]`
|
## `[side-tab-probe]`
|
||||||
|
|
||||||
```
|
```
|
||||||
[side-tab-probe] section=cursors accums=4 baseline recorded (measure at scroll 2732 of 2732, outside_at_top=1)
|
[side-tab-probe] section=none accums=4 baseline recorded (measure page was_open=1, now closed=1)
|
||||||
[side-tab-probe] section=cursors rows=4 accums=4 advanced=4 min_n=18
|
[side-tab-probe] section=none rows=4 accums=4 advanced=4 min_n=18
|
||||||
```
|
```
|
||||||
|
|
||||||
`UDPSCOPE_PROBE_SIDE_TAB_MS` (the variable and the tag keep their pre-dock names; the function is `dock_section_probe`) is the one reading for the rule that **the statistics accumulator keeps running
|
`UDPSCOPE_PROBE_SIDE_TAB_MS` (the variable and the tag keep their pre-dock names; the function is `dock_section_probe`) is the one reading for the rule that **the statistics accumulator keeps running while the measurements' page is closed**. The measurements are a slide-over page (`measure`), not a dock section, so the old scroll-the-dock set-up is gone. The probe opens the page, forces one pass so there is a baseline, *closes* the page (its widgets stay in the tree, unmapped) and reads again two seconds later. It re-arms once after 400 ms so the first reading has the layout. **Run it against a config that has seen the first-run tour**, which would close the page it opens (`tour_seen = true`).
|
||||||
while the Measure section is out of view**. It scrolls the dock *to* the measurements (`dock_show_section("measure")` lands on the cursors panel, the dock's top, so the probe then moves to the measurements' heading itself), forces one pass so there is a baseline, then scrolls back to the top (the cursors) and reads again two seconds later. To make the scroll observable the probe pads `dock_page` **and the cursors panel** to 3000 px each (probe only, both undone in the report), and it re-arms once after 400 ms so the first reading has the layout.
|
|
||||||
|
|
||||||
- **`outside_at_top=1` is the precondition**: with the dock at offset 0, the Measure section (the measurements' heading, below the padded cursors panel) starts at or below the viewport's bottom edge, so the "away from the section" state really has the measurements out of view and `advanced=4` says something. `outside_at_top=0` means the probe's own set-up failed and the run proves nothing -- unpadded, the section's top sits a short way down and the dock's viewport is taller than that. **The limit is the 3000 px:** the guarantee holds for a dock viewport shorter than the padding (any real window); a viewport taller than the cursors panel's padding, about 3000 logical px, would read `0` again.
|
- **`was_open=1 closed=1` is the precondition**: the page really was open for the baseline and really is closed for the report, so `advanced=4` says something. `was_open=0` is the page never opening (the tour closed it, or the page is insensitive because the stream has no signals) and `closed=0` is `slideover_close()` not taking effect; either way the run proves nothing. `section=` is the slide-over's open page and **reads `none` on both lines**, because the page is closed.
|
||||||
|
- **`advanced=4` is the assertion**: every accumulator gained passes while the page was closed, and
|
||||||
- **`advanced=4` is the assertion**: every accumulator gained passes while its section was out of view, and
|
|
||||||
`min_n` (the smallest `n` seen) must be non-zero too. **`advanced=0` is the defect**: something gated the
|
`min_n` (the smallest `n` seen) must be non-zero too. **`advanced=0` is the defect**: something gated the
|
||||||
accumulation on the visible section, so the readout would gain a gap in its min/max/avg for exactly as long as
|
accumulation on the page being open, so the readout would gain a gap in its min/max/avg for exactly as long as
|
||||||
the trigger was on screen. A `Gtk-CRITICAL` here is the other half of the same rule -- a label or an
|
the page was shut. A `Gtk-CRITICAL` here is the other half of the same rule -- a label or an
|
||||||
allocation read on the unrealized page.
|
allocation read on the unmapped page.
|
||||||
- The probe enables a signal **and assigns it to a plot** itself, both deliberately. A signal starts disabled
|
- The probe enables a signal **and assigns it to a plot** itself, both deliberately. A signal starts disabled
|
||||||
(enabling is what starts acquisition), and a channel with no trace leaves the live window *still* -- and a
|
(enabling is what starts acquisition), and a channel with no trace leaves the live window *still* -- and a
|
||||||
still window is the state `update_measures()` is *supposed* to skip, so a probe that left it that way would
|
still window is the state `update_measures()` is *supposed* to skip, so a probe that left it that way would
|
||||||
read `advanced=0` for a reason that has nothing to do with the tab.
|
read `advanced=0` for a reason that has nothing to do with the page.
|
||||||
- `rows` is the measurement count and `accums` the accumulator count; the two must agree, because one
|
- `rows` is the measurement count and `accums` the accumulator count; the two must agree, because one
|
||||||
accumulator per measurement row is what makes `advanced` a statement about every row.
|
accumulator per measurement row is what makes `advanced` a statement about every row.
|
||||||
|
|
||||||
|
|||||||
+19
-10
@@ -423,15 +423,24 @@ precedent, not an exception.
|
|||||||
pauses, reports again with `dn=` per measurement, then resets and reports a third time. Three
|
pauses, reports again with `dn=` per measurement, then resets and reports a third time. Three
|
||||||
phases: `phase=0`, `phase=1` (after pause) and `phase=2` (after Reset). Needs
|
phases: `phase=0`, `phase=1` (after pause) and `phase=2` (after Reset). Needs
|
||||||
`UDPSCOPE_ENABLE_ALL_MS` ahead of it and `UDPSCOPE_PROBE_MEASURE_MS` to add measurements first.
|
`UDPSCOPE_ENABLE_ALL_MS` ahead of it and `UDPSCOPE_PROBE_MEASURE_MS` to add measurements first.
|
||||||
- `UDPSCOPE_PROBE_SIDE_TAB_MS=3000` with `UDPSCOPE_EXIT_AFTER_MS=11000` — the measurements in the
|
- `UDPSCOPE_PROBE_SIDE_TAB_MS=3000` with `UDPSCOPE_EXIT_AFTER_MS=11000` — the measurements while the
|
||||||
dock's Measure section, a forced pass, then the dock scrolled back to its top (the
|
`measure` page is **closed**: it adds four measurements, opens the page for a forced pass (the baseline),
|
||||||
measurements out of view) and read again two seconds later. The probe pads the dock page and the cursors panel to
|
closes it, and reads the accumulators again two seconds later. **`advanced=<rows>` is the assertion**
|
||||||
3000 px each so the Measure section really starts below the viewport (`outside_at_top=1`) on any real window. **`advanced=4`
|
(every accumulator gained passes while the page was off screen); `advanced=0` is the defect where the
|
||||||
is the assertion** (every accumulator gained passes while its section was out of view); `advanced=0` is the
|
accumulation is gated on what is visible, which would leave a gap in min/max/avg for exactly as long as the
|
||||||
defect where the accumulation is gated on the visible section, which would leave a gap in min/max/avg for
|
page was shut. It enables *and plots* its own signal, so it needs no other probe ahead of it, and it
|
||||||
exactly as long as the trigger was on screen. It enables *and plots* its own signal, so it needs no other
|
re-arms once after 400 ms (a buffer rebuild between baseline and report reads as a gated pass). It needs a
|
||||||
probe ahead of it. The reading's own entry is in `probe-readings.md`. (Probe name `dock_section_probe`; the
|
config that has seen the first-run tour, which would close the page it opens (see the next-but-one bullet).
|
||||||
variable and the `[side-tab-probe]` tag keep their old names so existing scripts keep working.)
|
The reading's own entry is in `probe-readings.md`. (Probe name `dock_section_probe`; the variable and the
|
||||||
|
`[side-tab-probe]` tag keep their old names so existing scripts keep working. The measurements used to be a
|
||||||
|
dock section the probe scrolled out of view, with padding; the dock now holds only readouts, so there is
|
||||||
|
no scroll and no padding.)
|
||||||
|
- `UDPSCOPE_PROBE_CURSORS_MS` and `UDPSCOPE_PROBE_MEASURES_MS` also print the dock's copy of what they read:
|
||||||
|
a `dock cursors:` line after every `[cursors-probe]` report and a `dock measures:` line at the
|
||||||
|
measures probe's added / settled / final stops. **`same_text=1` on every one** is the assertion that the
|
||||||
|
dock and the page show one string; `fits=1` that the Readouts box is no wider than the dock. Entries in
|
||||||
|
`probe-readings.md`. The exit chain also prints one `[readouts]` line (pages registered, the dock's one
|
||||||
|
child, the dock's width, the pages' sensitivity, whether the stream has signals) on every exit-dump run.
|
||||||
- `UDPSCOPE_PROBE_DOCK_SESSION_MS=2500` with `UDPSCOPE_EXIT_AFTER_MS=8000` -- the session file's `dock` key,
|
- `UDPSCOPE_PROBE_DOCK_SESSION_MS=2500` with `UDPSCOPE_EXIT_AFTER_MS=8000` -- the session file's `dock` key,
|
||||||
end to end: the dock hidden, saved and reloaded; shown again; and a file from the previous version
|
end to end: the dock hidden, saved and reloaded; shown again; and a file from the previous version
|
||||||
(`side_tab = "measure"`, no `dock`) loaded without an error. Three `[dock-session]` lines, each `ok=1`;
|
(`side_tab = "measure"`, no `dock`) loaded without an error. Three `[dock-session]` lines, each `ok=1`;
|
||||||
@@ -447,7 +456,7 @@ 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
|
- **Slide-over and page probes (`SLIDEOVER`, `BADGES`, `SIGNAL_PAGES`, `SIGNAL_BADGES`, `SIDE_TAB`, `KEYS`) 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
|
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`
|
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
|
(or one short throw-away run, which writes the key when the tour starts) and run with `XDG_CONFIG_HOME=$D`. Delete the
|
||||||
|
|||||||
@@ -25,8 +25,9 @@
|
|||||||
<p>Press the cursors button in the toolbar, or <key>c</key>.</p>
|
<p>Press the cursors button in the toolbar, or <key>c</key>.</p>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<p>The pane below the plot shows the readings and owns a <gui>Reset</gui> button.
|
<p>The readings are in the side panel (a read-only copy) and in the cursors panel, which
|
||||||
Drag a marker to move it.</p>
|
<gui>Edit</gui> beside <gui>Cursors</gui> opens over the plot and which owns a
|
||||||
|
<gui>Reset</gui> button. Drag a marker to move it.</p>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<p>The mode dropdown offers four modes: <gui>vertical</gui> (the shared time pair),
|
<p>The mode dropdown offers four modes: <gui>vertical</gui> (the shared time pair),
|
||||||
|
|||||||
@@ -28,10 +28,10 @@
|
|||||||
<title>How to reach it</title>
|
<title>How to reach it</title>
|
||||||
<steps>
|
<steps>
|
||||||
<item>
|
<item>
|
||||||
<p>Press the measurements button in the toolbar, or <key>m</key>.</p>
|
<p>Press <key>m</key>, or <gui>Edit</gui> beside <gui>Measurements</gui> in the side panel.</p>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<p>The pane's <gui>+</gui> adds one; clicking a row opens the dialog where the signal,
|
<p>The panel's <gui>+</gui> adds one; clicking a row opens the dialog where the signal,
|
||||||
the type, the threshold share or shares and the on-plot marks are set, with
|
the type, the threshold share or shares and the on-plot marks are set, with
|
||||||
<gui>Save</gui> and <gui>Delete</gui>.</p>
|
<gui>Save</gui> and <gui>Delete</gui>.</p>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -88,11 +88,13 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<title>The side panel</title>
|
<title>The side panel</title>
|
||||||
<p>Two tabs. <gui>Measure</gui> holds the cursors readout and the measurements
|
<p>A read-only copy of the cursors and of the measurements; the <gui>Edit</gui> button
|
||||||
derived from it; <gui>Signals</gui> holds the trigger and the channel list, where a
|
beside each heading opens that instrument's full panel over the plot. The channel
|
||||||
math channel is a row of that one list under a <gui>MATH</gui> heading whose
|
list and the trigger are panels of their own, opened from the badge bar and the
|
||||||
<gui>+</gui> creates one. One row per channel: its colour, an enable switch, its name
|
toolbar, where a math channel is a row of the one list under a <gui>MATH</gui>
|
||||||
and its unit. A channel's badge in the badge bar is dragged onto a plot row.</p>
|
heading whose <gui>+</gui> creates one. One row per channel: its colour, an enable
|
||||||
|
switch, its name and its unit. A channel's badge in the badge bar is dragged onto a
|
||||||
|
plot row.</p>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<title>The plot</title>
|
<title>The plot</title>
|
||||||
|
|||||||
Reference in new issue
Block a user