tui: global script progress + dashboard source/restore work
Opening a script from the dashboard did nothing visually: the tick driving the line-by-line loader was only handled in the console case, and the Computing… overlay was console-only. Move both to the global layer — ticks now process on any screen (the dashboard updates live as the script loads) and the Computing… box overlays whatever screen is active. Add an 'r' dashboard shortcut to restore a snapshot via the file picker (open mode, like 'o'). Dashboard help hints (loaded + empty state) updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -45,6 +45,7 @@ Component Tui::BuildDashboardScreen() {
|
|||||||
Element early_help = RenderHelpPanel("dashboard", {
|
Element early_help = RenderHelpPanel("dashboard", {
|
||||||
{"c", "console"},
|
{"c", "console"},
|
||||||
{"o", "open/run a script"},
|
{"o", "open/run a script"},
|
||||||
|
{"r", "restore a snapshot"},
|
||||||
{"a", "analyze"},
|
{"a", "analyze"},
|
||||||
{"h", "help screen"},
|
{"h", "help screen"},
|
||||||
{"q", "quit"},
|
{"q", "quit"},
|
||||||
@@ -57,8 +58,8 @@ Component Tui::BuildDashboardScreen() {
|
|||||||
separator(),
|
separator(),
|
||||||
hbox({
|
hbox({
|
||||||
vbox({
|
vbox({
|
||||||
text(" no system loaded — run 'new' or 'restore <file>'") | dim,
|
text(" no system loaded") | dim,
|
||||||
text(" (press 'o' to open a script, 'c' for the console, Ctrl-P for the palette)") | dim,
|
text(" (press 'o' open a script · 'r' restore a snapshot · 'c' console · Ctrl-P palette)") | dim,
|
||||||
filler(),
|
filler(),
|
||||||
}) | flex,
|
}) | flex,
|
||||||
separator(),
|
separator(),
|
||||||
@@ -312,6 +313,7 @@ Component Tui::BuildDashboardScreen() {
|
|||||||
{"x", "export"},
|
{"x", "export"},
|
||||||
{"o", "open/run a script"},
|
{"o", "open/run a script"},
|
||||||
{"s", "save system"},
|
{"s", "save system"},
|
||||||
|
{"r", "restore a snapshot"},
|
||||||
{"PgUp", "scroll up"},
|
{"PgUp", "scroll up"},
|
||||||
{"PgDn", "scroll down"},
|
{"PgDn", "scroll down"},
|
||||||
{"Home", "scroll top"},
|
{"Home", "scroll top"},
|
||||||
|
|||||||
@@ -89,18 +89,8 @@ Component Tui::BuildMainScreen(ScreenInteractive &screen) {
|
|||||||
}) | flex,
|
}) | flex,
|
||||||
}) | border;
|
}) | border;
|
||||||
|
|
||||||
if (loading) {
|
// The "Computing…" overlay is rendered globally in Run(), so it shows
|
||||||
int total = (int)loading_lines.size();
|
// on whatever screen is active while a script loads.
|
||||||
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});
|
|
||||||
}
|
|
||||||
return base;
|
return base;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <ftxui/component/component.hpp>
|
#include <ftxui/component/component.hpp>
|
||||||
#include <ftxui/component/event.hpp>
|
#include <ftxui/component/event.hpp>
|
||||||
#include <ftxui/component/screen_interactive.hpp>
|
#include <ftxui/component/screen_interactive.hpp>
|
||||||
|
#include <ftxui/dom/elements.hpp>
|
||||||
|
|
||||||
using namespace ftxui;
|
using namespace ftxui;
|
||||||
|
|
||||||
@@ -58,7 +59,28 @@ void Tui::Run() {
|
|||||||
auto with_error = with_confirm
|
auto with_error = with_confirm
|
||||||
| Modal(BuildErrorModal(), &error_open);
|
| 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.
|
// Modals own their events while open. Error modal sits on top.
|
||||||
if (error_open || confirm_open || palette_open
|
if (error_open || confirm_open || palette_open
|
||||||
|| sigtype_dialog_open || file_dialog.open) return false;
|
|| sigtype_dialog_open || file_dialog.open) return false;
|
||||||
@@ -119,6 +141,15 @@ void Tui::Run() {
|
|||||||
});
|
});
|
||||||
return true;
|
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;
|
return false;
|
||||||
|
|
||||||
case 3: // explore
|
case 3: // explore
|
||||||
@@ -153,7 +184,6 @@ void Tui::Run() {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
default: // 0: main (console / log view)
|
default: // 0: main (console / log view)
|
||||||
if (e == Event::Special("\x02tick")) { ProcessNextSourceLine(); return true; }
|
|
||||||
if (e == Event::Escape) {
|
if (e == Event::Escape) {
|
||||||
if (!pending.empty()) { CancelPending(); return true; }
|
if (!pending.empty()) { CancelPending(); return true; }
|
||||||
screen_idx = 4; return true;
|
screen_idx = 4; return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user