#ifndef _TUI_HPP_ #define _TUI_HPP_ #include #include #include #include #include #include #include #include #include #include class System; class Tui { enum class Completion { None, Path, Command }; struct Prompt { std::string question; std::function on_answer; Completion completion = Completion::None; }; struct CommandSpec { struct Param { std::string name; Completion completion = Completion::None; }; std::vector params; std::function &)> action; bool prompt_for_missing = true; std::string description; bool scriptable = true; bool interactive = false; ///< opens a full-screen mode when called bare }; // ---- Shell state ---- std::vector history; std::vector recorded; // commands since the last 'new', for script-save std::vector output; std::string input; int cursor_pos; int history_idx; int scroll_offset; ///< Lines scrolled up from the tail; 0 = follow newest output. bool quit; bool in_source; std::unique_ptr sys; std::deque pending; std::map commands; std::map vars; ///< $var-style substitution table. // ---- Screen orchestration ---- int screen_idx; // ---- Search screen state ---- std::vector search_modules; std::vector search_types; int search_module_idx; int search_type_idx; int search_focus_idx; std::string search_query; // ---- Connect screen state ---- std::vector connect_modules; int connect_m1_idx; int connect_m2_idx; std::string connect_p1_filter; std::string connect_p2_filter; std::vector connect_p1_list; std::vector connect_p2_list; int connect_p1_idx; int connect_p2_idx; int connect_focus_idx; // ---- Explore screen state ---- std::vector explore_modules; int explore_module_idx; std::vector explore_types; int explore_type_idx; std::vector explore_children; int explore_child_idx; std::string explore_child_filter; std::string explore_detail_filter; std::vector explore_detail; std::vector explore_detail_sig; ///< parallel: signal name per detail line (empty = no signal) int explore_detail_idx; std::string explore_header; int explore_focus_idx; // ---- Source-file loading (event-driven, one line per tick) ---- std::atomic loading; ///< true while a script is being processed; read by tick thread. std::atomic tick_in_flight; ///< main thread acks each tick by clearing this; ticker waits. std::string loading_filename; std::vector loading_lines; size_t loading_idx; int loading_executed; int loading_lineno; bool loading_prev_in_source; ftxui::ScreenInteractive *screen_ptr; ///< set in Run() so Source() can post events. // ---- Net screen state ---- std::vector net_modules; int net_module_idx; std::string net_sig_filter; std::vector net_sigs; ///< rebuilt every frame from filter int net_sig_idx; int net_focus_idx; // ---- Dashboard scroll state (0 = top; grows as the user scrolls down) ---- int dashboard_scroll_offset = 0; // ---- Analyze screen state (unified verify + analyze) ---- int analyze_focus_idx = 0; ///< 0=issues 1=groups 2=types std::vector analyze_issues; std::vector analyze_groups; std::vector analyze_types; int analyze_issue_idx = 0; int analyze_group_idx = 0; int analyze_type_idx = 0; // ---- Command palette (global, fuzzy-find over commands + objects) ---- bool palette_open = false; std::string palette_query; int palette_idx = 0; // Rebuilt every frame from : label shown to the user. std::vector palette_labels; // Parallel kind/payload for each label. kind: 'c'=command, 'm'=module, // 's'=signal. payload: command name / module name / "module\tsignal". std::vector> palette_items; // ---- Signal-type popup (shared between net + explore screens) ---- bool sigtype_dialog_open = false; std::string sigtype_dialog_mod; std::string sigtype_dialog_sig; std::vector sigtype_dialog_entries; ///< ["power","gnd","other"] int sigtype_dialog_choice = 0; // ---- Set-type screen state ---- std::vector settype_modules; int settype_m_idx; std::string settype_p_filter; std::vector settype_p_list; int settype_p_idx; std::string settype_type; std::string settype_status; int settype_focus_idx; public: Tui(); ~Tui(); void Run(); void DumpCommandsMd(std::ostream &out) const; private: // Lifecycle (commands.cpp) void RegisterCommands(); // Shell (shell.cpp) void Print(const std::string &line); void Submit(); void Dispatch(const std::string &raw); void Finalize(const std::string &name, const CommandSpec &spec, const std::vector &args); void HistoryUp(); void HistoryDown(); void CancelPending(); void LoadHistory(); void AppendHistory(const std::string &cmd); void Source(const std::string &filename); void ProcessNextSourceLine(); std::string ExpandVars(const std::string &s) const; // Completion (completion.cpp) void CompleteCommand(size_t start = 0); void CompletePath(size_t start = 0); void CompleteInline(); // Open the signal-type popup for / (no-op if names don't resolve). void OpenSignalTypeDialog(const std::string &mod_name, const std::string &sig_name); // Apply the selected type to the targeted signal, record a // `set-signal-type` line (deduping consecutive edits of the same signal), // and close the popup. void ApplySignalTypeChoice(); // Filtered part list rebuild (used by connect & set-type screens) void RefreshFilteredPartList(const std::vector &modules, int m_idx, const std::string &filter, std::vector &out, int &sel_idx); // Screen builders (screen_*.cpp) ftxui::Component BuildMainScreen(ftxui::ScreenInteractive &screen); ftxui::Component BuildSearchScreen(); ftxui::Component BuildConnectScreen(); ftxui::Component BuildSettypeScreen(); ftxui::Component BuildExploreScreen(); ftxui::Component BuildNetScreen(); ftxui::Component BuildDashboardScreen(); ftxui::Component BuildAnalyzeScreen(); ftxui::Component BuildSignalTypeModal(); ftxui::Component BuildPaletteModal(); // Open palette (resets query/index, builds initial list). void OpenPalette(); // Execute the currently-highlighted palette entry. void ActivatePaletteEntry(); }; #endif // _TUI_HPP_