diff --git a/src/tui/screen_dashboard.cpp b/src/tui/screen_dashboard.cpp index 751b31f..124d99a 100644 --- a/src/tui/screen_dashboard.cpp +++ b/src/tui/screen_dashboard.cpp @@ -45,6 +45,7 @@ Component Tui::BuildDashboardScreen() { Element early_help = RenderHelpPanel("dashboard", { {"c", "console"}, {"o", "open/run a script"}, + {"r", "restore a snapshot"}, {"a", "analyze"}, {"h", "help screen"}, {"q", "quit"}, @@ -57,8 +58,8 @@ Component Tui::BuildDashboardScreen() { separator(), hbox({ vbox({ - text(" no system loaded — run 'new' or 'restore '") | dim, - text(" (press 'o' to open a script, 'c' for the console, Ctrl-P for the palette)") | dim, + text(" no system loaded") | dim, + text(" (press 'o' open a script · 'r' restore a snapshot · 'c' console · Ctrl-P palette)") | dim, filler(), }) | flex, separator(), @@ -312,6 +313,7 @@ Component Tui::BuildDashboardScreen() { {"x", "export"}, {"o", "open/run a script"}, {"s", "save system"}, + {"r", "restore a snapshot"}, {"PgUp", "scroll up"}, {"PgDn", "scroll down"}, {"Home", "scroll top"}, diff --git a/src/tui/screen_main.cpp b/src/tui/screen_main.cpp index 3526c08..b7db6d8 100644 --- a/src/tui/screen_main.cpp +++ b/src/tui/screen_main.cpp @@ -89,18 +89,8 @@ Component Tui::BuildMainScreen(ScreenInteractive &screen) { }) | flex, }) | border; - if (loading) { - int total = (int)loading_lines.size(); - std::string progress = std::to_string(loading_executed) + " / " - + std::to_string(total) + " lines"; - auto modal = vbox({ - text(" Computing… ") | bold | center, - separator(), - text(loading_filename) | center, - text(progress) | center, - }) | borderDouble | size(WIDTH, GREATER_THAN, 40); - return dbox({base, modal | center}); - } + // The "Computing…" overlay is rendered globally in Run(), so it shows + // on whatever screen is active while a script loads. return base; }); } diff --git a/src/tui/tui.cpp b/src/tui/tui.cpp index 3de1a5b..a49db93 100644 --- a/src/tui/tui.cpp +++ b/src/tui/tui.cpp @@ -5,6 +5,7 @@ #include #include #include +#include using namespace ftxui; @@ -58,7 +59,28 @@ void Tui::Run() { auto with_error = with_confirm | Modal(BuildErrorModal(), &error_open); - auto root = CatchEvent(with_error, [this](Event e) { + // Global "Computing…" overlay while a script loads — visible on any screen + // (not just the console), so opening a script from the dashboard shows + // progress instead of looking frozen. + auto with_loading = Renderer(with_error, [this, with_error] { + Element base = with_error->Render(); + if (!loading) return base; + std::string progress = std::to_string(loading_executed) + " / " + + std::to_string((int)loading_lines.size()) + " lines"; + Element modal = vbox({ + text(" Computing… ") | bold | center, + separator(), + text(loading_filename) | center, + text(progress) | center, + }) | borderDouble | size(WIDTH, GREATER_THAN, 40); + return dbox({base, modal | center}); + }); + + auto root = CatchEvent(with_loading, [this](Event e) { + // Source ticks drive the line-by-line loader; handle them on ANY screen + // so `source` works from the dashboard, not only the console. + if (e == Event::Special("\x02tick")) { ProcessNextSourceLine(); return true; } + // Modals own their events while open. Error modal sits on top. if (error_open || confirm_open || palette_open || sigtype_dialog_open || file_dialog.open) return false; @@ -119,6 +141,15 @@ void Tui::Run() { }); return true; } + if (e == Event::Character("r")) { // restore a saved system + OpenFileDialog("Restore system — load a snapshot", + "dashboard.restore", "", {}, + [this](const std::string &path) { + Dispatch("restore " + path); + }, + /*confirm_overwrite=*/false); // opening, not saving + return true; + } return false; case 3: // explore @@ -153,7 +184,6 @@ void Tui::Run() { return false; 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 = 4; return true;