Two reports on the PicoCalc's message paths, one root cause each. The graph drew an unnamed hop's hash — and the sender's name — as white, the "you" colour. MapCanvas emits its own bold for markers and labels, and its colours arrive already quantized to a palette slot; the kernel VT then draws bold as *brightness*, so anything that landed in the dim bank was promoted to its bright partner. Light grey became white. A purple repeater would have become pink the same way. The canvas now drops emphasis where bold is brightness — the colour is the load-bearing part. The same trap reaches the theme through inheritance: Rich merges a row's base style into every span, so a dim-slot span left silent about bold changes colour inside a selected row. Every dim-slot style now says which it means — `not bold` to keep its colour, `bold` where the promotion is the point (only title.muted) — and a test forbids staying silent. The pathline drew the same hop dark grey, because `muted` collapses onto the console's dark grey while the desktop's is light. That conflated two things: `muted` is chrome and may recede a step, but a node we can't identify is content you can still act on. It gets its own name, `node.unknown` — light grey, identical to today's desktop muted, so nothing moves there — and it is what `name_style` returns keyless, what an unlit `highlighted_hash` wears, and what the `○` ring is. Also fixes a crash from the previous commit: the graph's label colour resolved a marker through `parse_hex`, which the type marks' theme names are not. A repeater relay we couldn't name would have raised. The gallery's node-detail header spelled a marker hex by hand; it goes through the app's own styles now, so a palette bug can't hide behind it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
54 lines
2.5 KiB
Python
54 lines
2.5 KiB
Python
"""The shared mark constants: node-type glyphs, their colours, and path sentinels.
|
||
|
||
The app's spatial surfaces — the map, the path graph, the braille rasters, the node
|
||
rows — all pin nodes with the same marks in the same hues, and several of them need the
|
||
constants *without* the machinery around them. Before this module, ``ui.widgets`` pulled
|
||
``map_render``, ``mapcanvas`` and ``pathgraph`` onto the boot path for a handful of
|
||
tuples and type aliases (~60 ms of import on the PicoCalc); now the constants live here,
|
||
dependency-free, and the heavy modules import *from* the constants instead of hosting
|
||
them. ``map_render``/``mapcanvas``/``pathgraph`` re-export their old names, so existing
|
||
importers of those modules are untouched.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from typing import Callable, Optional
|
||
|
||
#: An ``(r, g, b)`` colour triple, 0–255 per channel (the raster/canvas colour type).
|
||
RGB = tuple[int, int, int]
|
||
|
||
|
||
def parse_hex(color: str) -> RGB:
|
||
"""Convert ``"#rrggbb"`` (or ``"rrggbb"``) to an ``(r, g, b)`` tuple."""
|
||
c = color.lstrip("#")
|
||
return (int(c[0:2], 16), int(c[2:4], 16), int(c[4:6], 16))
|
||
|
||
|
||
# Marker palette, shared across the whole app. The basemap is blue (water), green (parks)
|
||
# and warm amber (roads), so markers use the hues a map never contains — pink/violet — to
|
||
# stand out against it. Ordinary nodes are the loudest (bright pink); repeaters recede a
|
||
# step (a calmer violet); our own node stays the fixed yellow star; a node heard of but
|
||
# never identified is a light grey ring. Every glyph is in the PicoCalc console font.
|
||
#
|
||
# A mark's colour is whatever :func:`~meshterm.ui.theme.mark_rgb` takes — a literal hex, or
|
||
# a theme style name where the platform must pick the shade itself. The unknown ring is
|
||
# named (``node.unknown``) so the ring and the grey label beside it can never disagree.
|
||
SELF_MARK = ("★", "#facc15")
|
||
REPEATER_MARK = ("▲", "#a78bfa")
|
||
NODE_MARK = ("●", "#f472b6")
|
||
UNKNOWN_MARK = ("○", "node.unknown")
|
||
|
||
#: Sentinels naming a path's endpoints on the route graph. ``\x00`` never appears in a
|
||
#: node hash, so they can share the node-id namespace without colliding with one.
|
||
SRC_NODE = "\x00src"
|
||
DST_NODE = "\x00dst"
|
||
|
||
#: Maps a node id to its graph marker: a ``(glyph, colour)`` pair.
|
||
GlyphOf = Callable[[str], tuple[str, str]]
|
||
|
||
#: A node's graph label, or ``None``/``""`` to leave the marker bare.
|
||
LabelOf = Callable[[str], Optional[str]]
|
||
|
||
#: The colour a node's label is drawn in (usually the node's name hue).
|
||
LabelRgbOf = Callable[[str], RGB]
|