ui: each tab's glyph is a pair, not one icon
The Measure tab is now `udpscope-tab-measure-symbolic` — the two cursors standing across a ruler — and the Signals tab is `udpscope-tab-signals-symbolic` — the trigger's rising edge over the channel list it acts on. Each is a 16px composite rather than one of the icons the toolbar carries: a glyph the toolbar already uses for one thing means two things the moment a tab shows it too, which is why the ruler alone and the trigger alone were both wrong here. The plain ruler stays exactly where it was. `udpscope-measure-symbolic` is the Preferences window's Plot page icon and is untouched; the tab's pair is a new file beside it, so nothing that already meant "the measurement ruler" changed meaning. Seven action icons bundled, nine with the two app icons. Both composites are at the limit of what 16px holds — four features each — so each was drawn and then *measured*: rasterized and read back as an ink map, since the shapes have to be checked as pixels and the house range is 25-36% ink (trigger 25, cursors 27, ruler 36). The Signals list is two rows and not three, so the edge and the list get half the cell each; its bars are all one length, because unequal ones read as a bar chart and a chart is not a list. The Measure ruler's ends are open on purpose: a closed frame puts four more pixels of ink at the left and right edges, which is what turns a ruler into a rectangle at this size. First drafts came out at 39% and 44% ink and were rebalanced to 32% and 36%. Verified: `page icons: measure=udpscope-tab-measure-symbolic(ok) signals=udpscope-tab-signals-symbolic(ok)`; `switcher: policy=narrow pills=2 labels=0 names=2`; `[side-tab-probe] … advanced=4` (switching by page name still works); the Preferences dialog opened in the same run with no "not present"; `make test-ui` 14 files; zero `Gtk-CRITICAL`. The icons' GResource blob is now 11309 bytes, still over C99's 4095-byte string-literal limit, so the clean-build warning count is still four.
This commit is contained in:
1 parent
0b146f1d53
commit
e615465366
9 files changed
+76
-40
No files matched your search
@@ -2393,8 +2393,9 @@ 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 built
|
section was short of room, and finding one meant scrolling past the others. The built
|
||||||
sidebar is a **Measure** tab (the cursors readout and the measurements) and a **Signals**
|
sidebar is a **Measure** tab (the cursors readout and the measurements) and a **Signals**
|
||||||
tab (the trigger and the channels), **each a pill with its own glyph and no text** — the ruler
|
tab (the trigger and the channels), **each a pill with its own glyph and no text** — the
|
||||||
for Measure, a channel list for Signals — with the words kept as each pill's tooltip and
|
cursors and the ruler for Measure, the trigger and the channel list for Signals — with the words
|
||||||
|
kept as each pill's tooltip and
|
||||||
accessible name. The design spec had the switcher showing *titles* and neither page an
|
accessible name. The design spec had the switcher showing *titles* and neither page an
|
||||||
`icon-name`; `narrow` alone does not do it (libadwaita still draws a label beside the icon,
|
`icon-name`; `narrow` alone does not do it (libadwaita still draws a label beside the icon,
|
||||||
measured), so the pages carry an empty title and the pills are named in code. With the math
|
measured), so the pages carry an empty title and the pills are named in code. With the math
|
||||||
|
|||||||
@@ -55,14 +55,21 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
|||||||
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
|
||||||
entirely: a *record dot* for the trigger and three different **magnifiers** for cursors,
|
entirely: a *record dot* for the trigger and three different **magnifiers** for cursors,
|
||||||
measurements and math. `src/icons/scalable/actions/udpscope-{trigger,cursors,measure,events,resize-rows,signals}-symbolic.svg`
|
measurements and math. `src/icons/scalable/actions/udpscope-{trigger,cursors,measure,events,resize-rows,tab-measure,tab-signals}-symbolic.svg`
|
||||||
are the six action icons. `udpscope-math-symbolic` left with the toolbar toggle that was its last
|
are the seven action icons. `udpscope-math-symbolic` left with the toolbar toggle that was its last
|
||||||
user; `udpscope-measure-symbolic` **stayed**, because the Preferences window's Plot page carries it --
|
user; `udpscope-measure-symbolic` **stayed**, because the Preferences window's Plot page carries it --
|
||||||
an icon with a live user is not an orphan, whatever the toggle that introduced it did -- and it is
|
an icon with a live user is not an orphan, whatever the toggle that introduced it did -- and it is
|
||||||
*also* the Measure tab's icon. `udpscope-signals-symbolic` was drawn for the Signals tab: three rows of
|
the Preferences window's icon, not the tab's.
|
||||||
a colour chip and a name, which is what that tab mostly is, and deliberately *not* a second copy of the
|
|
||||||
trigger glyph (one shape with two meanings in one window is worse than a new one). Its bars are all one
|
The two **tabs** got glyphs of their own, and each is a *pair* rather than one of the icons above:
|
||||||
length because unequal ones read as a bar chart, and a chart is not a list. Beside them in
|
`udpscope-tab-measure-symbolic` is the cursors and the ruler they read against, and
|
||||||
|
`udpscope-tab-signals-symbolic` is the trigger's edge above the channel list it acts on. They are not
|
||||||
|
reuses because a glyph the toolbar already carries means two things the moment a tab shows it too. Both
|
||||||
|
are 16px composites with four features each, which is about the limit of this size: the Signals list is
|
||||||
|
two rows and not three, so the edge and the list get half the cell each, and the bars in it are all one
|
||||||
|
length because unequal ones read as a bar chart, and a chart is not a list. Their ink fractions (32% and
|
||||||
|
36%) sit inside the range the icons above set, which is the check that a composite has not turned into a
|
||||||
|
blot. Beside them in
|
||||||
`src/icons/scalable/apps/` are the two
|
`src/icons/scalable/apps/` are the two
|
||||||
**application** icons, `org.udpscope.app.svg` (128px colour artwork) and
|
**application** icons, `org.udpscope.app.svg` (128px colour artwork) and
|
||||||
`org.udpscope.app-symbolic.svg` (16px). The `apps` context is where an icon theme keeps an
|
`org.udpscope.app-symbolic.svg` (16px). The `apps` context is where an icon theme keeps an
|
||||||
@@ -71,7 +78,7 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
|||||||
into `$XDG_DATA_HOME/icons/hicolor/scalable/apps` and `.../symbolic/apps` — those installed
|
into `$XDG_DATA_HOME/icons/hicolor/scalable/apps` and `.../symbolic/apps` — those installed
|
||||||
copies are what makes `Icon=org.udpscope.app` in the desktop entry resolve (a desktop shell
|
copies are what makes `Icon=org.udpscope.app` in the desktop entry resolve (a desktop shell
|
||||||
cannot read a GResource compiled into the binary).
|
cannot read a GResource compiled into the binary).
|
||||||
All eight are bundled by `src/icons/udpscope.gresource.xml` (CMake runs
|
All nine are bundled by `src/icons/udpscope.gresource.xml` (CMake runs
|
||||||
`glib-compile-resources`) and reached through **one**
|
`glib-compile-resources`) and reached through **one**
|
||||||
`gtk_icon_theme_add_resource_path()` in `run_ui()`, right after `adw_init()` — not at the top
|
`gtk_icon_theme_add_resource_path()` in `run_ui()`, right after `adw_init()` — not at the top
|
||||||
of `build_toolbar()`, where it used to be: there are two consumers now (the window's own icon,
|
of `build_toolbar()`, where it used to be: there are two consumers now (the window's own icon,
|
||||||
|
|||||||
@@ -364,7 +364,7 @@ Two lines of the self-check output are assertions in disguise:
|
|||||||
other half — both pills carry a tooltip and an accessible name set by `name_side_tabs()`, so an
|
other half — both pills carry a tooltip and an accessible name set by `name_side_tabs()`, so an
|
||||||
icon-only pill is not an anonymous button — and `pills=0` means nothing is mapped, which makes the
|
icon-only pill is not an anonymous button — and `pills=0` means nothing is mapped, which makes the
|
||||||
rest of the line meaningless rather than a pass. `policy=narrow` is read rather than assumed.
|
rest of the line meaningless rather than a pass. `policy=narrow` is read rather than assumed.
|
||||||
- `page icons: measure=udpscope-measure-symbolic(ok) signals=udpscope-signals-symbolic(ok)` (in the exit
|
- `page icons: measure=udpscope-tab-measure-symbolic(ok) signals=udpscope-tab-signals-symbolic(ok)` (in the exit
|
||||||
dump, beside `toolbar icons:`) — each tab's own glyph and `gtk_icon_theme_has_icon()`'s verdict, read
|
dump, beside `toolbar icons:`) — each tab's own glyph and `gtk_icon_theme_has_icon()`'s verdict, read
|
||||||
on the first tick for the same reason the toolbar's are. **Both must read `(ok)`**: the page titles are
|
on the first tick for the same reason the toolbar's are. **Both must read `(ok)`**: the page titles are
|
||||||
empty on purpose, so an icon that does not resolve leaves a *blank* pill, and a blank pill looks
|
empty on purpose, so an icon that does not resolve leaves a *blank* pill, and a blank pill looks
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ xvfb-run -a env UDPSCOPE_EXIT_AFTER_MS=8000 UDPSCOPE_ENABLE_ALL_MS=1000 \
|
|||||||
Two baselines every run is read against. A clean build emits **four** warnings and no more: two
|
Two baselines every run is read against. A clean build emits **four** warnings and no more: two
|
||||||
`-Wmissing-field-initializers` on `MathNode::source` and `-Woverlength-strings` on **both**
|
`-Wmissing-field-initializers` on `MathNode::source` and `-Woverlength-strings` on **both**
|
||||||
generated GResource `.c` files — the help pages' (**514660** bytes) and the icons', whose blob is
|
generated GResource `.c` files — the help pages' (**514660** bytes) and the icons', whose blob is
|
||||||
**9842** against C99's 4095-byte string-literal limit with the six action icons and the two app icons
|
**11309** against C99's 4095-byte string-literal limit with the seven action icons and the two app icons
|
||||||
that remain (a note about a generated file, which GCC itself supports) -- re-measured when
|
that remain (a note about a generated file, which GCC itself supports) -- re-measured when
|
||||||
the tab work changed the set (that icon left, `udpscope-signals-symbolic` arrived, and this file's
|
the tab work changed the set (that icon left, the two tab glyphs arrived, and this file's
|
||||||
help page was rewritten), which did not move the count; re-measure by touching each `*.gresource.xml`
|
help page was rewritten), which did not move the count; re-measure by touching each `*.gresource.xml`
|
||||||
under `src/` and rebuilding. The fifth warning that used to appear here was an unused
|
under `src/` and rebuilding. The fifth warning that used to appear here was an unused
|
||||||
`output_built` in `math_probe()`; it was **deleted** as dead code — redundant with the
|
`output_built` in `math_probe()`; it was **deleted** as dead code — redundant with the
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- SPDX-License-Identifier: MIT -->
|
|
||||||
<!-- SPDX-FileCopyrightText: 2026 Martino Ferrari -->
|
|
||||||
<!-- The Signals tab's own glyph: the channel list, drawn as a list. Three rows of a
|
|
||||||
colour chip and a name, the shape the signal panel's own rows have — which is
|
|
||||||
what the tab mostly *is*, and which is why it is not the trigger icon: the
|
|
||||||
toolbar's trigger button already carries that one, and one glyph with two
|
|
||||||
meanings in one window is worse than a new glyph. The bars are all one length
|
|
||||||
on purpose: unequal ones read as a bar chart, and a chart is not a list. Every
|
|
||||||
coordinate is a whole pixel of the 16px cell, every subpath is a filled `path`
|
|
||||||
wound the same way, and the 2px bars match the house stroke weight. -->
|
|
||||||
<svg height="16px" width="16px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path fill="#2e3436" d="M1 1 H4 V4 H1 Z
|
|
||||||
M6 2 H14 V4 H6 Z
|
|
||||||
M1 6 H4 V9 H1 Z
|
|
||||||
M6 7 H14 V9 H6 Z
|
|
||||||
M1 11 H4 V14 H1 Z
|
|
||||||
M6 12 H14 V14 H6 Z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- SPDX-License-Identifier: MIT -->
|
||||||
|
<!-- SPDX-FileCopyrightText: 2026 Martino Ferrari -->
|
||||||
|
<!-- The Measure tab: the cursors and the ruler they read against, in one glyph. Two markers, each a
|
||||||
|
cap over a dashed shaft, stand across a ruler: the ruler is two bars with three hanging ticks.
|
||||||
|
The ruler's ends are open on purpose. A closed frame puts four more pixels of ink at the left
|
||||||
|
and right edges, which at this size is what turns a ruler into a rectangle. The shafts stop at
|
||||||
|
the bars rather than crossing them, the way a marker on a plot sits over the scale. Whole
|
||||||
|
pixels, filled `path`s wound the same way, and an ink fraction of 36%, in line with the ruler
|
||||||
|
and the cursors it is made of. -->
|
||||||
|
<svg height="16px" width="16px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill="#2e3436" d="M3 1 H7 V3 H3 Z
|
||||||
|
M9 1 H13 V3 H9 Z
|
||||||
|
M4 3 H6 V6 H4 Z
|
||||||
|
M10 3 H12 V6 H10 Z
|
||||||
|
M4 14 H6 V16 H4 Z
|
||||||
|
M10 14 H12 V16 H10 Z
|
||||||
|
M2 6 H14 V8 H2 Z
|
||||||
|
M2 12 H14 V14 H2 Z
|
||||||
|
M4 8 H5 V11 H4 Z
|
||||||
|
M8 8 H9 V10 H8 Z
|
||||||
|
M12 8 H13 V11 H12 Z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- SPDX-License-Identifier: MIT -->
|
||||||
|
<!-- SPDX-FileCopyrightText: 2026 Martino Ferrari -->
|
||||||
|
<!-- The Signals tab: the trigger *and* the channel list it acts on, in one glyph. A rising edge
|
||||||
|
crossing a dashed level is the trigger as the toolbar already draws it; below it, two rows of a
|
||||||
|
colour chip and a name are the channel list, which is what the page mostly is. Two rows and not
|
||||||
|
three, so the edge and the list each get half the cell: at 16px a third row costs the edge its
|
||||||
|
clearance and the whole thing turns into a grid. Whole pixels, filled `path`s wound the same
|
||||||
|
way, and the 2px bars match the house stroke weight. -->
|
||||||
|
<svg height="16px" width="16px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill="#2e3436" d="M6 1 H8 V6 H6 Z
|
||||||
|
M6 1 H15 V3 H6 Z
|
||||||
|
M0 5 H2 V7 H0 Z
|
||||||
|
M3 5 H5 V7 H3 Z
|
||||||
|
M12 5 H14 V7 H12 Z
|
||||||
|
M1 9 H4 V12 H1 Z
|
||||||
|
M6 10 H14 V12 H6 Z
|
||||||
|
M1 13 H4 V15 H1 Z
|
||||||
|
M6 13 H14 V15 H6 Z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -20,7 +20,8 @@
|
|||||||
<file preprocess="xml-stripblanks">scalable/actions/udpscope-trigger-symbolic.svg</file>
|
<file preprocess="xml-stripblanks">scalable/actions/udpscope-trigger-symbolic.svg</file>
|
||||||
<file preprocess="xml-stripblanks">scalable/actions/udpscope-cursors-symbolic.svg</file>
|
<file preprocess="xml-stripblanks">scalable/actions/udpscope-cursors-symbolic.svg</file>
|
||||||
<file preprocess="xml-stripblanks">scalable/actions/udpscope-measure-symbolic.svg</file>
|
<file preprocess="xml-stripblanks">scalable/actions/udpscope-measure-symbolic.svg</file>
|
||||||
<file preprocess="xml-stripblanks">scalable/actions/udpscope-signals-symbolic.svg</file>
|
<file preprocess="xml-stripblanks">scalable/actions/udpscope-tab-measure-symbolic.svg</file>
|
||||||
|
<file preprocess="xml-stripblanks">scalable/actions/udpscope-tab-signals-symbolic.svg</file>
|
||||||
<file preprocess="xml-stripblanks">scalable/actions/udpscope-events-symbolic.svg</file>
|
<file preprocess="xml-stripblanks">scalable/actions/udpscope-events-symbolic.svg</file>
|
||||||
<file preprocess="xml-stripblanks">scalable/actions/udpscope-resize-rows-symbolic.svg</file>
|
<file preprocess="xml-stripblanks">scalable/actions/udpscope-resize-rows-symbolic.svg</file>
|
||||||
<file preprocess="xml-stripblanks">scalable/apps/org.udpscope.app.svg</file>
|
<file preprocess="xml-stripblanks">scalable/apps/org.udpscope.app.svg</file>
|
||||||
|
|||||||
+11
-8
@@ -60,10 +60,12 @@
|
|||||||
`select_side_tab()` and the session file, and the words are re-attached to the pills in
|
`select_side_tab()` and the session file, and the words are re-attached to the pills in
|
||||||
code — tooltip and accessible name — by `name_side_tabs()` on the first tick, so an
|
code — tooltip and accessible name — by `name_side_tabs()` on the first tick, so an
|
||||||
icon-only pill is still a named thing rather than an anonymous button.
|
icon-only pill is still a named thing rather than an anonymous button.
|
||||||
Each page's icon is its own glyph: `udpscope-measure-symbolic` is the ruler the
|
Each page's icon is a glyph of its own, and each one is a *pair*: the Measure tab is
|
||||||
measurements used as a toggle, and `udpscope-signals-symbolic` is the channel list,
|
`udpscope-tab-measure-symbolic` (the cursors and the ruler they read against), and the
|
||||||
drawn for this tab rather than reusing the toolbar's trigger icon — one glyph
|
Signals tab is `udpscope-tab-signals-symbolic` (the trigger's edge and the channel list
|
||||||
meaning two things in one window is worse than a new one. -->
|
below it). They are drawn for the tabs rather than reusing the icons the toolbar and the
|
||||||
|
Preferences window already carry: a glyph the toolbar uses for one thing means two things
|
||||||
|
the moment a tab shows it too. -->
|
||||||
<object class="GtkBox" id="side_column">
|
<object class="GtkBox" id="side_column">
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
<property name="width-request">300</property>
|
<property name="width-request">300</property>
|
||||||
@@ -84,8 +86,9 @@
|
|||||||
<object class="AdwViewStackPage">
|
<object class="AdwViewStackPage">
|
||||||
<property name="name">measure</property>
|
<property name="name">measure</property>
|
||||||
<property name="title"></property>
|
<property name="title"></property>
|
||||||
<!-- The ruler: what the pane measures the waveform with. -->
|
<!-- The cursors and the ruler: what the pane brackets, and what it
|
||||||
<property name="icon-name">udpscope-measure-symbolic</property>
|
reads the bracketed window with. -->
|
||||||
|
<property name="icon-name">udpscope-tab-measure-symbolic</property>
|
||||||
<property name="child">
|
<property name="child">
|
||||||
<object class="GtkScrolledWindow">
|
<object class="GtkScrolledWindow">
|
||||||
<property name="hscrollbar-policy">never</property>
|
<property name="hscrollbar-policy">never</property>
|
||||||
@@ -103,8 +106,8 @@
|
|||||||
<object class="AdwViewStackPage">
|
<object class="AdwViewStackPage">
|
||||||
<property name="name">signals</property>
|
<property name="name">signals</property>
|
||||||
<property name="title"></property>
|
<property name="title"></property>
|
||||||
<!-- The channel list this page mostly is. -->
|
<!-- The trigger and the channel list it acts on. -->
|
||||||
<property name="icon-name">udpscope-signals-symbolic</property>
|
<property name="icon-name">udpscope-tab-signals-symbolic</property>
|
||||||
<property name="child">
|
<property name="child">
|
||||||
<object class="GtkScrolledWindow">
|
<object class="GtkScrolledWindow">
|
||||||
<property name="hscrollbar-policy">never</property>
|
<property name="hscrollbar-policy">never</property>
|
||||||
|
|||||||
Reference in new issue
Block a user