Merge search and net screens into explore; drop both commands.
`explore` was already a superset of `search` (4 columns: module → type → filtered children → detail, with parts/signals/connections — vs search's 2 columns of parts/signals only). It now also subsumes the former `net` screen: when a signal entry is selected, the detail pane shows the local pins followed by a `Net members (across connections)` section listing every `(module, signal, type)` reachable through the BFS over `Connection::pin_map`, with the count + dominant type and an INCONSISTENT flag in the signal-detail header. Removed: - `src/tui/screen_search.cpp`, `src/tui/screen_net.cpp`. - `commands["search"]`, `commands["net"]` (including its textual inline form). The `find_net` / `Net` API stays for explore's BFS panel and the analyze screen's net-mix check. - `[s]` and `[n]` letter shortcuts on the dashboard. - `net_*` and `search_*` state members + builders + constructor inits. screen_idx renumbering (the slots vacated by search + net are removed, not left dead): 0 = console (unchanged) 1 = connect 2 = set-connector-type 3 = explore (unchanged number, but now subsumes search + net) 4 = dashboard (boot) 5 = analyze Palette signal items now jump to `explore` prefilled on the signals tab with the child filter seeded to the exact signal name; the BFS section in the detail pane is what shows the cross-module net. Net-member rows in the detail pane are deliberately read-only for now (Enter is a no-op): the signal-type popup is scoped to the currently selected module, so opening it on a peer-module member would mis-fire. Cross-module Enter navigation can come later if needed. DESIGN.md and user docs updated accordingly. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -13,10 +13,7 @@ Tui::Tui()
|
||||
loading(false), tick_in_flight(false),
|
||||
loading_idx(0), loading_executed(0), loading_lineno(0),
|
||||
loading_prev_in_source(false), screen_ptr(nullptr),
|
||||
screen_idx(6), // boot to the dashboard; shell (screen 0) is now a sub-screen
|
||||
|
||||
search_types{"parts", "signals"},
|
||||
search_module_idx(0), search_type_idx(0), search_focus_idx(0),
|
||||
screen_idx(4), // boot to the dashboard; console (screen 0) is now a sub-screen
|
||||
connect_m1_idx(0), connect_m2_idx(0),
|
||||
connect_p1_idx(0), connect_p2_idx(0),
|
||||
connect_focus_idx(0),
|
||||
@@ -24,7 +21,6 @@ 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();
|
||||
@@ -39,19 +35,16 @@ void Tui::Run() {
|
||||
screen_ptr = &screen;
|
||||
|
||||
auto main_screen = BuildMainScreen(screen);
|
||||
auto search_screen = BuildSearchScreen();
|
||||
auto connect_screen = BuildConnectScreen();
|
||||
auto settype_screen = BuildSettypeScreen();
|
||||
auto explore_screen = BuildExploreScreen() | Modal(BuildSignalTypeModal(),
|
||||
&sigtype_dialog_open);
|
||||
auto net_screen = BuildNetScreen() | Modal(BuildSignalTypeModal(),
|
||||
&sigtype_dialog_open);
|
||||
auto dashboard_screen = BuildDashboardScreen();
|
||||
auto analyze_screen = BuildAnalyzeScreen();
|
||||
|
||||
auto tab = Container::Tab(
|
||||
{main_screen, search_screen, connect_screen, settype_screen, explore_screen,
|
||||
net_screen, dashboard_screen, analyze_screen},
|
||||
{main_screen, connect_screen, settype_screen, explore_screen,
|
||||
dashboard_screen, analyze_screen},
|
||||
&screen_idx);
|
||||
|
||||
// Palette is a global Modal — overlays the tab on every screen.
|
||||
@@ -64,11 +57,11 @@ void Tui::Run() {
|
||||
// Ctrl-P opens the palette from any screen.
|
||||
if (e == Event::CtrlP) { OpenPalette(); return true; }
|
||||
|
||||
// screen_idx mapping: 0 = console, 1 = connect, 2 = set-connector-type,
|
||||
// 3 = explore, 4 = dashboard (home), 5 = analyze.
|
||||
switch (screen_idx) {
|
||||
case 7: // analyze
|
||||
if (e == Event::Escape) { screen_idx = 6; return true; }
|
||||
// Tab and ←/→ both switch the active tab. ↑/↓ stay with the
|
||||
// detail Menu so it can scroll.
|
||||
case 5: // analyze
|
||||
if (e == Event::Escape) { screen_idx = 4; return true; }
|
||||
if (e == Event::Tab || e == Event::ArrowRight) {
|
||||
analyze_focus_idx = (analyze_focus_idx + 1) % 3;
|
||||
return true;
|
||||
@@ -79,12 +72,8 @@ void Tui::Run() {
|
||||
}
|
||||
return false;
|
||||
|
||||
case 6: // dashboard (home)
|
||||
// Home has no parent — Esc is swallowed. Use 'q' to quit.
|
||||
case 4: // dashboard (home)
|
||||
if (e == Event::Escape) { return true; }
|
||||
// Scroll the dashboard when content overflows the viewport. The
|
||||
// upper bound is clamped inside the Renderer (we don't know the
|
||||
// line count from here).
|
||||
if (e == Event::PageDown) { dashboard_scroll_offset += 10; return true; }
|
||||
if (e == Event::PageUp) {
|
||||
dashboard_scroll_offset = std::max(0, dashboard_scroll_offset - 10);
|
||||
@@ -93,57 +82,36 @@ void Tui::Run() {
|
||||
if (e == Event::Home) { dashboard_scroll_offset = 0; return true; }
|
||||
if (e == Event::End) { dashboard_scroll_offset = 100000; return true; }
|
||||
if (e == Event::Character("q")) { Dispatch("quit"); return true; }
|
||||
// [c]onsole = the textual shell screen (former [l]og). [p]lug
|
||||
// = the `connect` command (UI rename only; the underlying
|
||||
// command stays `connect` for script + save/restore stability,
|
||||
// with `plug` registered as an alias so the palette finds it).
|
||||
if (e == Event::Character("c")) { screen_idx = 0; return true; }
|
||||
if (e == Event::Character("p")) { Dispatch("connect"); return true; }
|
||||
if (e == Event::Character("s")) { Dispatch("search"); return true; }
|
||||
if (e == Event::Character("t")) { Dispatch("set-connector-type"); return true; }
|
||||
if (e == Event::Character("e")) { Dispatch("explore"); return true; }
|
||||
if (e == Event::Character("n")) { Dispatch("net"); return true; }
|
||||
// [a]nalyze is the unified verify + analyze screen (issues +
|
||||
// groups + types). The textual `verify` and `analyze` commands
|
||||
// still exist for scripts.
|
||||
if (e == Event::Character("a")) { screen_idx = 7; return true; }
|
||||
if (e == Event::Character("a")) { screen_idx = 5; return true; }
|
||||
return false;
|
||||
|
||||
case 5: // net
|
||||
if (e == Event::Escape) { screen_idx = 6; 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 = 6; return true; }
|
||||
case 3: // explore
|
||||
if (e == Event::Escape) { screen_idx = 4; return true; }
|
||||
if (e == Event::Tab) { explore_focus_idx = (explore_focus_idx + 1) % 6; return true; }
|
||||
if (e == Event::TabReverse) { explore_focus_idx = (explore_focus_idx + 5) % 6; return true; }
|
||||
return false;
|
||||
|
||||
case 3: // set-connector-type
|
||||
if (e == Event::Escape) { screen_idx = 6; return true; }
|
||||
case 2: // set-connector-type
|
||||
if (e == Event::Escape) { screen_idx = 4; return true; }
|
||||
if (e == Event::Tab) { settype_focus_idx = (settype_focus_idx + 1) % 5; return true; }
|
||||
if (e == Event::TabReverse) { settype_focus_idx = (settype_focus_idx + 4) % 5; return true; }
|
||||
return false;
|
||||
|
||||
case 2: // connect
|
||||
if (e == Event::Escape) { screen_idx = 6; return true; }
|
||||
case 1: // connect
|
||||
if (e == Event::Escape) { screen_idx = 4; return true; }
|
||||
if (e == Event::Tab) { connect_focus_idx = (connect_focus_idx + 1) % 7; return true; }
|
||||
if (e == Event::TabReverse) { connect_focus_idx = (connect_focus_idx + 6) % 7; return true; }
|
||||
return false;
|
||||
|
||||
case 1: // search
|
||||
if (e == Event::Escape) { screen_idx = 6; return true; }
|
||||
if (e == Event::Tab) { search_focus_idx = (search_focus_idx + 1) % 3; return true; }
|
||||
if (e == Event::TabReverse) { search_focus_idx = (search_focus_idx + 2) % 3; return true; }
|
||||
return false;
|
||||
|
||||
default: // main (shell / log view)
|
||||
default: // 0: main (console / log view)
|
||||
if (e == Event::Special("\x02tick")) { ProcessNextSourceLine(); return true; }
|
||||
if (e == Event::Escape) {
|
||||
if (!pending.empty()) { CancelPending(); return true; }
|
||||
screen_idx = 6; return true;
|
||||
screen_idx = 4; return true;
|
||||
}
|
||||
if (e == Event::PageUp) { scroll_offset += 10; return true; }
|
||||
if (e == Event::PageDown) { scroll_offset = std::max(0, scroll_offset - 10); return true; }
|
||||
|
||||
Reference in New Issue
Block a user