diff --git a/src/tui/shell.cpp b/src/tui/shell.cpp index e3e3fb8..2f70afa 100644 --- a/src/tui/shell.cpp +++ b/src/tui/shell.cpp @@ -299,6 +299,7 @@ void Tui::Source(const std::string &filename) { source_origin_screen = screen_idx; // a sourced line that leaves this screen aborts in_source = true; loading = true; + computing_open = true; // raise the global "Computing…" progress modal if (!screen_ptr) { // Headless fallback (e.g. tests): drain synchronously. @@ -352,6 +353,7 @@ void Tui::ProcessNextSourceLine() { + " is interactive (would open a screen) — aborting."); screen_idx = source_origin_screen; loading.store(false); + computing_open = false; tick_in_flight.store(false); in_source = loading_prev_in_source; return; @@ -364,6 +366,7 @@ void Tui::ProcessNextSourceLine() { Print("source: " + loading_filename + " (" + std::to_string(loading_executed) + " line(s))"); loading.store(false); + computing_open = false; tick_in_flight.store(false); in_source = loading_prev_in_source; } diff --git a/src/tui/tui.cpp b/src/tui/tui.cpp index a49db93..df209fc 100644 --- a/src/tui/tui.cpp +++ b/src/tui/tui.cpp @@ -59,31 +59,31 @@ void Tui::Run() { auto with_error = with_confirm | Modal(BuildErrorModal(), &error_open); - // 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; + // Global "Computing…" progress modal while a script loads — a proper Modal + // (like the palette / file dialog), so it shows on any screen, e.g. when a + // script is opened from the dashboard. The Renderer re-reads the live + // progress every frame. + auto computing_modal = Renderer([this] { 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}); + return vbox({ + text(" Computing… ") | bold | center, + separator(), + text(loading_filename) | center, + text(progress) | center, + }) | borderDouble | size(WIDTH, GREATER_THAN, 40); }); + auto with_loading = with_error | Modal(computing_modal, &computing_open); 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. + // (and before the modal guard) so `source` keeps running while the + // Computing modal is up. 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; + || sigtype_dialog_open || file_dialog.open || computing_open) return false; // Ctrl-P opens the palette from any screen. if (e == Event::CtrlP) { OpenPalette(); return true; } diff --git a/src/tui/tui.hpp b/src/tui/tui.hpp index ff01484..75e5ac0 100644 --- a/src/tui/tui.hpp +++ b/src/tui/tui.hpp @@ -104,6 +104,7 @@ class Tui { int loading_lineno; bool loading_prev_in_source; int source_origin_screen = 0; ///< screen a `source` started from; a sourced line that navigates away (opens an interactive screen) aborts it. + bool computing_open = false; ///< drives the global "Computing…" progress modal while a script loads. ftxui::ScreenInteractive *screen_ptr; ///< set in Run() so Source() can post events. // ---- Dashboard scroll state (0 = top; grows as the user scrolls down) ----