feat: a signal's chip is clickable, so a trace's colour is the user's to choose

Clicking the coloured chip in the signal list opens a GtkColorDialog and the
colour it returns overrides that signal's palette entry. Held by name, like
every other identity here, and persisted as a session `[[color]]` table.

RowSet::signal_color() becomes the one resolver: install() builds the trace
through it and all three chip sites read it, because a chip exists to say which
trace a row is about and an override is exactly the state in which two routes to
a colour would disagree. A grey chip names no trace and so is not clickable, and
the way back is `Default colour` in the signal's menu -- a setting with no undo
is a trap.

The gesture sits on the existing label rather than in a GtkButton: padding on
this row is what made the signal list twice as tall once. It claims its sequence
so a click on the chip cannot become the start of a row drag.

UDPSCOPE_PROBE_COLOR_MS reads the result out of plot::Plot::trace() and out of
the chip's own markup, with an override in no palette slot, so neither leg can
pass by asking the resolver what it already said.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Martino FerrariandClaude Opus 4.6 committed 2026-10-07 08:22:32 +02:00
1 parent 8bc1fe8b5c
commit 4003084648
11 files changed
+406 -24

No files matched your search

+17 -2
View File
@@ -250,8 +250,9 @@ A sample exactly *at* a threshold is still on neither side, so a signal that mer
does not count every sample as an event.
Each measurement's row carries **two badges**: its own colour (the same one its marks use on
the plot) and the signal's chip, in the palette colour every other view names that signal
with. The dialog's fields and their wording follow the type — the split row is absent for
the plot) and the signal's chip, in the colour every other view names that signal with —
through `RowSet::signal_color()`, so a signal the user re-coloured is re-coloured here too and
not left at the palette entry. The dialog's fields and their wording follow the type — the split row is absent for
`average`, `min` and `max`, the side row only for `pulse duration`, and the "show on plot"
line says what would be drawn.
@@ -1203,6 +1204,20 @@ shape and the column of chips reads as a legend. Because `plot::Plot` fixes a tr
colour at `add_trace()`, the index is stored on the row (`Row::color_index`) and a
colour change goes through a figure rebuild, which a drop already forces.
**Clicking the chip of a signal that is on a plot opens a colour chooser** (`GtkColorDialog`,
with the alpha slider off — a trace is stroked opaque, so a transparency setting would do
nothing), and the colour it returns *overrides* the palette entry for that signal. The chip of
a signal on no plot is not clickable: a grey chip names no trace, so there is nothing to
recolour. A chosen colour is held by signal **name** (`RowSet::set_signal_color()`), saved in
the session file's `[[color]]` tables and resolved — for the trace and for every chip — by the
one call `RowSet::signal_color()`, so a chip cannot claim a colour the trace is not drawn in.
The way back is **Default colour** in the signal's `⋯` menu, sensitive only while an override
exists; it is there rather than on the chip because a second gesture on a one-glyph target is
not something anybody would find. The chooser is opened by a `GtkGestureClick` on the existing
label rather than by wrapping it in a `GtkButton`, because a button's padding is exactly what
made this row twice as tall once (below), and the gesture claims its sequence so a click on the
chip cannot become the start of a row drag.
A `GtkSwitch` and two
always-visible buttons made a row about twice as tall (46 px against 26 px now),
which is what turned a four-signal stream into a panel you have to scroll; Adwaita's