Feature/source plugins #1
@@ -0,0 +1,175 @@
|
|||||||
|
# Badge bar, readouts dock and slide-over panel -- design
|
||||||
|
|
||||||
|
Date: 2026-11-02. Status: approved in conversation, awaiting written-spec review.
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Replace the sidebar's tab switcher and the separate events pane with a layout built the way bench
|
||||||
|
scopes build theirs: setup is reached by *the object it configures* (a badge under the plot), results
|
||||||
|
are always on screen (a compact dock), and anything bigger than a readout opens in one slide-over
|
||||||
|
panel. The sidebar tabs and the left events pane go away.
|
||||||
|
|
||||||
|
## Why (the problems, as found in the code)
|
||||||
|
|
||||||
|
- **Unreadable tab titles.** `side_view` is pinned at 320 px (`min-sidebar-width` = `max-sidebar-width`
|
||||||
|
in `main-window.ui`), so four text tabs ("Measure / Signals / Analog out / Digital I/O") ellipsize,
|
||||||
|
and a source can add more.
|
||||||
|
- **Hard to find things.** The Signals tab stacks a trigger form of up to 15 rows (plus two
|
||||||
|
expanders) on top of the signal list. Cursors and measurements are in Measure, source controls are
|
||||||
|
in their own tabs, the header is icon-only, and the trigger/cursor toggles live apart from their
|
||||||
|
panels.
|
||||||
|
- **The events pane is a different application.** A `GtkPaned` + `GtkRevealer` on the left with its
|
||||||
|
own bold title and header, a dragged width that is not saved, thumbnails the rest of the UI does
|
||||||
|
not have, and a header toggle that is hidden until events exist.
|
||||||
|
|
||||||
|
## State of the art this follows
|
||||||
|
|
||||||
|
- Tektronix 5/6 Series: a badge bar under the waveform (a badge per channel/math waveform, plus
|
||||||
|
Horizontal, Trigger, Acquisition badges); a tap opens *only that item's* settings; results
|
||||||
|
(measurements, cursors, search) are a separate bar that does not cover the waveform.
|
||||||
|
- Scopy and PicoScope 7: a channel list at the edge and a settings panel that slides in for the
|
||||||
|
selected item (PicoScope lets it overlay or squeeze the trace).
|
||||||
|
- Saleae Logic 2: one side panel at a time; decoded results also in a list beside the waveform.
|
||||||
|
- Keysight InfiniiVision: dialogs that can be undocked so cursor and measurement values show together.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
┌ header: [window 2 s ▾] [Trigger] [Pause] [Cursors] [Dock] [☰] ┐
|
||||||
|
├──────────────────────────────────────────────┬────────────────────┤
|
||||||
|
│ plot rows ┌───────────┐ │ READOUTS │
|
||||||
|
│ │ slide-over│ │ cursors, measures │
|
||||||
|
│ │ settings │ ├────────────────────┤
|
||||||
|
│ └───────────┘ │ EVENTS (n) │
|
||||||
|
├───────────────────────────────────────────────┴────────────────────┤
|
||||||
|
│ [●sine][●square][+] … [Trigger ▸][Source ▸]│
|
||||||
|
├ status line ───────────────────────────────────────────────────────┤
|
||||||
|
```
|
||||||
|
|
||||||
|
### Header bar
|
||||||
|
|
||||||
|
Keeps the time-window control, the Trigger, Pause and Cursors toggles and the overflow menu. The
|
||||||
|
Events toggle is removed (Events is always in the dock). The sidebar toggle becomes the **Dock**
|
||||||
|
toggle, so a narrow window can still hide the dock. There is no "Window" badge: the header's control
|
||||||
|
is the timebase, and a second one would duplicate it.
|
||||||
|
|
||||||
|
### Right dock ("Readouts" and "Events")
|
||||||
|
|
||||||
|
- Fixed width, about 280 px; always on screen, shown but insensitive until the stream has signals
|
||||||
|
("disable, do not hide"). It stays an `AdwOverlaySplitView` sidebar, which already gives it its
|
||||||
|
own fixed width, the hide toggle and the overlay behaviour on a narrow window
|
||||||
|
(`invariants-plot-and-layout.md`).
|
||||||
|
- **Readouts** (top): the active cursor values and measurement values, read-only, one compact line per
|
||||||
|
value, through the one formatter both panes share (`invariants-readouts-and-cursors.md`).
|
||||||
|
An "Edit" affordance opens the slide-over's `measure` or `cursors` page; clicking a measurement row
|
||||||
|
opens that measurement's editor.
|
||||||
|
- **Events** (bottom): compact rows -- title, time, a small marker; no thumbnails. Insensitive outside
|
||||||
|
trigger mode. A "Manage" affordance opens the slide-over's `events` page.
|
||||||
|
|
||||||
|
### Badge bar
|
||||||
|
|
||||||
|
A fixed-height row between the plot and the status line.
|
||||||
|
|
||||||
|
- **Signals** (left): one badge per enabled signal, up to 6; beyond that a single "N signals" badge.
|
||||||
|
A badge shows a colour dot and the name, is a drag handle (reorder, or drop on a plot row, which
|
||||||
|
replaces today's drag from the signal list), and opens that signal's page (colour, calibration,
|
||||||
|
row, math). A trailing `+` opens the `signals` page (the full list, to enable more; the math editor
|
||||||
|
entry).
|
||||||
|
- **System** (right): **Trigger** shows its state (off / armed / triggered) and opens the trigger
|
||||||
|
form; **Source** shows the connection state and the source name and opens that source's pages
|
||||||
|
(`SourcePanel` pages, behind a small segmented switch inside the panel when there are several, as
|
||||||
|
E-1608 has Analog out and Digital I/O).
|
||||||
|
|
||||||
|
### Slide-over panel
|
||||||
|
|
||||||
|
- Overlays the plot's right edge (about 360 px wide), never the dock; one page at a time; Esc or a
|
||||||
|
click outside closes it. The plot is not resized by it.
|
||||||
|
- Pages, by id: `trigger`, `signal:<name>`, `signals`, `measure`, `cursors`, `events`,
|
||||||
|
`source-<id>`. Each page has its own scroller, so a tall page does not leave a shorter one scrolled
|
||||||
|
(the reason the sidebar had a scroller per page).
|
||||||
|
- Content: the trigger form (conditional rows, Advanced, Search the buffer), signal and calibration
|
||||||
|
settings, measurement add/edit/remove and statistics, cursor options, event actions (Live, Compare,
|
||||||
|
Accumulate), the math editor entry, and source pages.
|
||||||
|
|
||||||
|
### Status line
|
||||||
|
|
||||||
|
Unchanged.
|
||||||
|
|
||||||
|
## Components
|
||||||
|
|
||||||
|
New files, because `ui.cpp` is already very large.
|
||||||
|
|
||||||
|
| Unit | File | Responsibility |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `BadgeBar` | `ui_badges.cpp` | Builds signal / Trigger / Source badges from the model; emits "open page X"; owns badge drag. |
|
||||||
|
| `SlideOver` | `ui_slideover.cpp` | A `GtkOverlay` child of the plot area: revealer + page stack keyed by id; Esc/click-away; open/close API. |
|
||||||
|
| `ReadoutsDock` | `ui_dock.cpp` | The compact readouts and the compact events list, reading the same model the panes read today. |
|
||||||
|
|
||||||
|
Reuse, not rewrite:
|
||||||
|
|
||||||
|
- The trigger form, signal list and calibration, measurement editor and cursor options are
|
||||||
|
**reparented** into slide-over pages.
|
||||||
|
- `SourcePanel{id, title, widget}` is unchanged, so the E-1608 and Flat UDP panels need no change.
|
||||||
|
- Only the events *list and actions* of the old pane move; the left `GtkPaned`/`GtkRevealer` and its
|
||||||
|
divider sync are deleted.
|
||||||
|
|
||||||
|
## Invariants kept
|
||||||
|
|
||||||
|
- **Layout must not depend on content** (`invariants-plot-and-layout.md`): the dock has a fixed width,
|
||||||
|
the badge bar a fixed height, and the slide-over overlays instead of resizing the plot. Rows that
|
||||||
|
appear by trigger condition appear inside the slide-over's scroller.
|
||||||
|
- **A `GtkOverlay` child is picked wherever its allocation is**: the slide-over is one opaque widget
|
||||||
|
aligned to the end edge by margin and width, never a full-area transparent child, so pan, drop and
|
||||||
|
hover on the rest of the plot are untouched.
|
||||||
|
- The header's Trigger/Cursors/Pause toggles keep their two-way mirroring with the panels.
|
||||||
|
|
||||||
|
## State and session file
|
||||||
|
|
||||||
|
- The session file drops `side_tab` and gains the dock's shown state and width. An old file's
|
||||||
|
`side_tab` is ignored (an unknown name is already harmless to `select_side_tab`).
|
||||||
|
- The open slide-over page is not saved.
|
||||||
|
- The tab ids `measure`, `signals` and `source-<id>` stop being a session format; they remain page ids.
|
||||||
|
|
||||||
|
## What must be rewritten around it
|
||||||
|
|
||||||
|
- **Tour and context help:** steps and help-figure surfaces that point at `side_switcher`,
|
||||||
|
`side_stack` and `side_box` (`ui_tour.cpp`, `ui_context_help.cpp`) are re-pointed at the badge bar,
|
||||||
|
slide-over and dock, and the tour text is rewritten.
|
||||||
|
- **Probes:** the `switcher: policy=... pills=... labels=... images=... pages=...` line and
|
||||||
|
`side_tab_probe` become probes that count badges, dock rows and the open slide-over page; the events
|
||||||
|
divider probe goes away with the divider.
|
||||||
|
- **Keyboard:** `SideTabMeasure` / `SideTabSignals` become "open the measure / signals page".
|
||||||
|
- **Docs:** `README.md`, `USER-GUIDE.md`, `docs/claude/*` (architecture, verification,
|
||||||
|
probe-readings, the plot-and-layout and gtk-and-chrome invariants), and the Mallard manual's
|
||||||
|
figures.
|
||||||
|
|
||||||
|
## Rollout
|
||||||
|
|
||||||
|
Four steps, each its own plan, each leaving the app building, passing the probes and usable.
|
||||||
|
|
||||||
|
1. **Shell.** The plot overlay, the badge bar with Trigger and Source, the slide-over holding the
|
||||||
|
existing trigger form and source pages. The sidebar tabs are removed; the existing Measure and
|
||||||
|
Signals panels move into a temporary dock so nothing is lost.
|
||||||
|
2. **Signal badges.** Per-signal badges, the `+` and "N signals" overflow, drag to reorder and to
|
||||||
|
move to a row.
|
||||||
|
3. **Compact readouts.** Read-only cursors and measurements in the dock; their editors in the
|
||||||
|
slide-over.
|
||||||
|
4. **Events.** The compact events section in the dock, the left pane and divider deleted, then the
|
||||||
|
tour / help / docs sweep.
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
|
||||||
|
- **Overlay above the GL plot.** The panel must composite and take input correctly above the
|
||||||
|
plotter's GL area. The layout editor already places overlay children over the plot, so this is
|
||||||
|
expected to work; step 1 confirms it before anything else is built on it.
|
||||||
|
- **Reparenting the trigger form.** Its two-way mirroring with the header toggle, `sync_trigger_rows`
|
||||||
|
and the locked summary view must keep working from a hidden-by-default page. Step 1 verifies it with
|
||||||
|
the existing trigger probes.
|
||||||
|
- **Many signals.** The badge bar's six-badge limit and horizontal behaviour are the one place the
|
||||||
|
E-1608 (up to about 17 signals) stresses the design; step 2 includes a run on it.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
User-arranged or undockable panels, saved layouts of the panels themselves, a touch-specific mode,
|
||||||
|
and any change to the plot, trigger, measurement or source engines. Per-source tab names do not
|
||||||
|
change.
|
||||||
Reference in new issue
Block a user