ADR 0064: Виды индикаторов deck — визуальный язык, отрисовка и семантическая палитра¶
Статус: Accepted
Дата: 2026-04-19
Связанные ADR¶
| ADR | Роль |
|---|---|
| 0063 § типы | DeckPrimitiveKind, Presence / Dark Cockpit |
| 0055 | Стадия Render pipeline |
| 0021 | Dark Cockpit |
| 0046 | Инварианты layout |
| 0066 | Палитра кабины vs хром IDE |
Резюме¶
- Виды индикаторов deck: единая отрисовка + семантическая палитра.
DeckPrimitiveKind— каталог видов; без лишнего архитектурного слоя.
Код: Cockpit/PrimitivesKit/ — annunciator, лампы, токены semantic map.
Контекст¶
В 0063 § типы индикаторов зафиксирована продуктовая таксономия видов индикаторов: Lamp, Bar, Sign, Readout и т.д. — форма сигнала в ячейке deck или фрагменте Skia-инструмента.
Параллельно в коде и разговорах смешиваются разные смыслы (раньше их связывали со словом «примитив»):
- Вид индикатора — что показать оператору на уровне смысла: «лампа такого класса», «полоса отклонения», «краткая маркировка».
- Операции низкоуровневой графики — линия, заливка,
FormattedTextвDrawingContext/ команды Skia. - Токены сцены / метрики — viewport, шаг сетки, отступы целого инструмента (например semantic map); это не строка в
DeckPrimitiveKind, а общие константы компоновки.
Без явного разделения команды и фичи дублируют цвета и геометрию в XAML, в VM и в отрисовке: внимание уходит на соревнование оттенков и «новогоднюю ёлку», а не на задачу и иерархию состояний (0021 §6). Нужен норматив: один визуальный язык на вид индикатора и одна библиотека отрисовки, которая его реализует.
Решение¶
1) Виды индикаторов — высокоуровневые и с единым графическим воплощением¶
Вид индикатора в смысле 0063 — это атомарный glance: данные для UI формулируются как какой вид (DeckPrimitiveKind и профиль состояния) плюс минимальная полезная нагрузка (текст легенды, уровень серьёзности, число для readout и т.д.), а не как «нарисуй прямоугольник #rrggbb».
Инвариант: для каждого сочетания вид индикатора + семантика состояния (например Lamp + «ок / предупреждение / недоступно») в продукте существует ровно одно согласованное графическое воплощение в кабине (форма, толщина рамки, типографика подписи, семантический цвет — см. п. 3). Произвольное умножение вариантов «на вкус разработчика экрана» не допускается: иначе оператор тратит внимание на стиль, а не на состояние.
Фичи и deck-композиторы передают в библиотеку отрисовки семантику вида, а не набор низкоуровневых операций графики.
2) Библиотека отрисовки видов индикаторов (общий контур с 0055)¶
Чтобы инвариант из п. 1 соблюдался в коде, используется общая библиотека отрисовки (в репозитории — Cockpit/PrimitivesKit/ и стадия Render по 0055):
- для каждого поддерживаемого вида (или узкого семейства, например annunciator Lamp) — одна реализация «как нарисовать»: функции/типы, принимающие
DrawingContext(и при необходимости границы), без дублирования логики в контролах и инструментах; - для Skia-пайплайна тот же контракт мыслится как набор инструкций отрисовки той же семантики, без копипасты цветов и метрик из Avalonia-XAML.
Граница: библиотека отрисовки не подменяет композитор инструмента (Intent → Declutter → Layout) и не задаёт бизнес-логику; она только реализует согласованный вид по входным семантическим параметрам.
Имя папки PrimitivesKit — собирательное; см. лексикон и п. 4 про метрики целой сцены.
3) Единый цветовой язык (семантическая палитра)¶
Цвет в кабине для индикаторов deck и инструментов читается как смысл (уровень готовности, серьёзность отклонения, информационность), а не как украшение.
Инварианты:
- палитра задаётся семантическими ролями (например «штатно», «внимание», «инфо», «недоступно»), а не произвольными hex в каждой фиче;
- согласование с Dark Cockpit (0021, 0063 § Presence): в норме не размножать яркие пиксели и анимацию «для красоты»;
- при необходимости a11y (не только цвет) — расширения той же семантики (иконка, штриховка), а не отдельная «вторая палитра» без правил.
Конкретные значения токенов могут жить в теме/ресурсах, но маппинг «роль → отображение» остаётся единым и согласованным с слоем из п. 2. Соответствие EICAS W/C/A бытовым «Error / Warning / Information» и AnnunciatorLampLevel — таблица в 0021 §5.
4) Вид индикатора vs токены целой сцены¶
Вид индикатора и граница с инструментом — см. 0063 § примитив vs инструмент (термин «примитив» там — исторический заголовок раздела; по смыслу это вид индикатора vs инструмент).
Метрики / токены компоновки (viewport инструмента, шаг уровней графа, паддинги сцены) — не виды индикаторов deck; в коде допустимы имена вроде layout tokens, instrument geometry, чтобы не путать с DeckPrimitiveKind.
Не-цели (текущая фаза)¶
- Зафиксировать полный публичный контракт API отрисовки для сторонних плагинов (0063 открытые вопросы).
- Вынести всю палитру кабины в один TOML без стабилизации темы.
- Запретить исключения: локальные эксперименты за флагом возможны, но не задают второй «канон» без пересмотра ADR.
Последствия¶
- Продуктовые обсуждения и ревью опираются на цепочку: вид индикатора → единая отрисовка (п. 2) → композиция в инструменте/deck — без лишнего промежуточного «слоя» в архитектуре.
- Дублирование цветов/геометрии ламп, readout и т.д. считается техническим долгом, пока не перенесено в библиотеку п. 2 и не привязано к палитре п. 3.
- В тексте предпочтительны вид индикатора / форма сигнала; слово «примитив» — только при ссылке на имя
DeckPrimitiveKindили цитировании старых разделов 0063.
Альтернативы (кратко)¶
| Вариант | Минус |
|---|---|
| Только гайдлайны в Markdown без ADR | Нет стабильной ссылки в архитектурной политике |
| Один огромный «theme.json на всё» без слоя отрисовки | Семантика размазывается по биндингам, палитра расползается |
| Запретить любые числа вне PrimitivesKit | Жёстко для прототипов; достаточно явного разделения п. 4 |