ui: the sidebar's tabs become one dock; Measure and Signals by keyboard section; session keeps the dock's state
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
31ff778e07
commit
4b65197f56
19 files changed
+421
-419
No files matched your search
@@ -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
|
||||
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
|
||||
is a *tab* of the sidebar, so there is nothing left to reveal or hide about it. The Arm/Disarm button in the trigger panel still has text.
|
||||
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.
|
||||
- **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
|
||||
measurement ruler, and the stock names those buttons used to carry said something else
|
||||
@@ -61,9 +61,9 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
||||
an icon with a live user is not an orphan, whatever the toggle that introduced it did -- and it is
|
||||
the Preferences window's icon.
|
||||
|
||||
The sidebar's **tabs have no icons any more**: two glyphs (`udpscope-tab-measure-symbolic`,
|
||||
The sidebar has **no tabs any more** (it is one dock): two tab glyphs (`udpscope-tab-measure-symbolic`,
|
||||
`udpscope-tab-signals-symbolic`, each a 32x16 pair) were drawn for them and judged not understandable
|
||||
enough, so the tabs are text and both SVGs were deleted. The *trigger's* own icon was redrawn to the
|
||||
enough, so the tabs were text, and both SVGs were deleted. The *trigger's* own icon was redrawn to the
|
||||
Signals glyph's picture at that time and kept it.
|
||||
- **A shortcut table row's `accel` is GTK accelerator syntax, and a pointer gesture has
|
||||
none.** `src/shortcuts.cpp`'s strings are handed to `AdwShortcutsItem`, which parses them
|
||||
@@ -229,11 +229,13 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
||||
instead of across. `gtk_widget_set_visible()` is what a layout honours, so anything that must not
|
||||
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.
|
||||
**The sidebar is a tab stack now, and has no `GtkRevealer` left in it**: an `AdwViewSwitcher`
|
||||
above an `AdwViewStack`, each page a `GtkScrolledWindow` of its own (the two pages are different
|
||||
heights, so one shared scroller would leave a switch scrolled where the new page never asked to
|
||||
be). The reason is the one this trap teaches: five sections competing for one 320 px column left
|
||||
every one of them short of room. A *feature's* on/off is no longer a visibility at all -- the
|
||||
**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
|
||||
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
|
||||
this trap teaches: sections competing for one 320 px column each left every one of them short of room, and
|
||||
a scroller gives each its natural height. `m` and `g` scroll the dock to the cursors and to the signal list
|
||||
(`dock_show_section()`). A *feature's* on/off is no longer a visibility at all -- the
|
||||
**cursors'** toggle sets its pane's **body** insensitive -- 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
|
||||
(see the next bullet). The **trigger's body is deliberately never disabled**: a trigger is configured
|
||||
@@ -241,23 +243,15 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
||||
ordinary way to work. It used to go insensitive with the mode, which left the settings unreachable
|
||||
exactly when a user wanted to change them; `trigger panel sensitive …=1` is the regression guard, and a
|
||||
`0` there means the configuration has been locked out again. The
|
||||
trap itself does not go away with the widget: a stack's hidden page measures 0x0 too and is still
|
||||
given the leftover width, so **ask about state, not about size** carries over unchanged. Every
|
||||
allocation read in the sidebar is a debug capture, and each reads 0 on the page that is *not*
|
||||
current -- a change in what the reading means, not a defect, and no functional code may depend on
|
||||
those numbers.
|
||||
- **The sidebar's tabs are text: `AdwViewSwitcherPolicy.wide`, a title on every page, no icon.** The
|
||||
built-in pages get their titles in the `.ui` and a source kind's pages from `SourcePanel::title`
|
||||
(`adw_view_stack_add_titled`); the page's *name* still identifies it to `select_side_tab()` and the
|
||||
session file. An icon-only version existed (policy `narrow`, empty titles, the pills named in code by
|
||||
`name_side_tabs()`, because `narrow` still draws a label beside an icon); it was reversed because the
|
||||
glyphs were not understandable. A page added with an empty title is a blank pill, and
|
||||
`switcher: … pills=N labels=N images=0 pages=N` reads it as `labels` below `pills`. **No icon at all**
|
||||
is not what "no `icon-name`" gives you: `AdwViewSwitcherButton` always builds a `GtkImage` and falls
|
||||
back to `image-missing` (the `[x]` placeholder, which also squeezed the title to "Meas..."), and no
|
||||
property turns it off. `keep_tabs_icon_free()` (`src/ui_source.cpp`) hides every image in the switcher,
|
||||
re-hides one that is shown again, and re-runs on the stack's `items-changed` (connected *after* the
|
||||
switcher's own, so the new button exists) and on the switcher's `map`; `images=0` is the reading.
|
||||
trap itself does not go away with the widget: a section scrolled out of view is still laid out, but
|
||||
**ask about state, not about size** still holds for anything a tick reads.
|
||||
- **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
|
||||
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
|
||||
schedules a save. There is no tab icon to keep clear any more: the `keep_tabs_icon_free()` workaround for
|
||||
`AdwViewSwitcherButton`'s placeholder `[x]` image went with the switcher, and `dock:` in the dump
|
||||
replaces the `switcher:` line.
|
||||
- **An *overlaid* sidebar covers the plot, so a drag out of it has nowhere to land.** `collapsed` in an
|
||||
`AdwOverlaySplitView` means the sidebar sits *on* the plot rather than beside it: the pointer is over the
|
||||
list, never over a drop target, and a signal can be dragged but not dropped. `row_drag_sidebar()` hides
|
||||
@@ -278,7 +272,7 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
||||
`sync_panel_switches()` re-reads each pair from the toolbar's state after any change — so clicking
|
||||
either end moves both, and `panel switches: trigger=1/1 cursors=1/1` is the reading. Two traps:
|
||||
a `GtkSwitch` emits `notify::active` for a *programmatic* write as well, so the sync holds a guard
|
||||
(`App::panel_switch_sync`) or the program's own write comes back as a click; and the switcher must
|
||||
(`App::panel_switch_sync`) or the program's own write comes back as a click; and the switch must
|
||||
stay *out* of what the pane disables, because a control inside an insensitive parent cannot be
|
||||
clicked — a switch that greyed out with its own pane could never turn it back on. That is why the
|
||||
sensitive target is the pane's **body** (`trigger_body`, `cursors_body`) and not the pane.
|
||||
|
||||
Reference in new issue
Block a user