Interactive net screen, main + per-screen title bars, focus highlight, help split.

- New `net` full-screen layout (`screen_net.cpp`, `screen_idx = 5`): three
  columns (module menu / signal filter + menu / live BFS result). Bare
  `net` opens the screen; `net <m> <s>` keeps the inline path.
- Main screen grows a title bar: " essim — system digital twin "
  (bold + dim) on the left, live "N module(s), M connection(s)" on
  the right.
- Every interactive screen now renders the same breadcrumb at the top:
  " essim → <name>  — <short description> ", followed by a separator.
- `tui_helpers.hpp` exports `FocusLabel(elem, focused)`. Every
  interactive screen wraps its field labels with it so the active
  field's label flips to inverted video. Buttons (Connect, Apply)
  invert as a whole.
- `CommandSpec` gains a `bool interactive`. `help` (no args) splits
  the listing into "Interactive (open a full-screen mode)" and
  "Other". `help <name>` tags interactive entries with [interactive]
  and explains the bare-vs-inline duality.
- `DESIGN.md` (renamed from `CLAUDE.md`): refreshed Layout, TUI, and
  screen-recipe sections to cover the new field, the title idiom,
  FocusLabel, the `net` screen, and the event-paced `Computing…`
  modal during `source`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-12 07:52:22 +02:00
parent c3bb00cb4d
commit fe2dc13c89
11 changed files with 309 additions and 38 deletions

View File

@@ -23,6 +23,7 @@ Tui::Tui()
explore_types{"parts", "signals", "connections"},
explore_type_idx(0), explore_child_idx(0),
explore_detail_idx(0), explore_focus_idx(0),
net_module_idx(0), net_sig_idx(0), net_focus_idx(0),
settype_m_idx(0), settype_p_idx(0), settype_focus_idx(0)
{
LoadHistory();
@@ -41,13 +42,21 @@ void Tui::Run() {
auto connect_screen = BuildConnectScreen();
auto settype_screen = BuildSettypeScreen();
auto explore_screen = BuildExploreScreen();
auto net_screen = BuildNetScreen();
auto tab = Container::Tab(
{main_screen, search_screen, connect_screen, settype_screen, explore_screen},
{main_screen, search_screen, connect_screen, settype_screen, explore_screen,
net_screen},
&screen_idx);
auto root = CatchEvent(tab, [this](Event e) {
switch (screen_idx) {
case 5: // net
if (e == Event::Escape) { screen_idx = 0; return true; }
if (e == Event::Tab) { net_focus_idx = (net_focus_idx + 1) % 3; return true; }
if (e == Event::TabReverse) { net_focus_idx = (net_focus_idx + 2) % 3; return true; }
return false;
case 4: // explore
if (e == Event::Escape) { screen_idx = 0; return true; }
if (e == Event::Tab) { explore_focus_idx = (explore_focus_idx + 1) % 6; return true; }