add shell architecture with persistent status bar, nav bar, and content fragments

This commit is contained in:
2026-01-20 10:09:47 +01:00
parent 1f91d7508e
commit 2db7eea9f1
15 changed files with 1456 additions and 31 deletions

View File

@@ -19,6 +19,7 @@
#include <RmlUi/Lua/LuaType.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <filesystem>
#include <memory>
#include <chrono>
@@ -65,8 +66,10 @@ static std::ofstream g_log_file;
// Simulator mode
static bool g_simulator_mode = false;
static bool g_shell_mode = false; // Use persistent shell instead of direct documents
static std::string g_test_apps_path; // Path to test-apps directory
static std::string g_simulator_home_path; // Path to simulator home.rml
static std::string g_shell_path; // Path to shell.rml for shell mode
static std::string g_main_assets_path; // Path to main assets (for goHome)
static std::vector<mosis::AppInfo> g_discovered_apps;
static std::string g_current_app_id; // Currently running app (empty = home)
@@ -284,7 +287,8 @@ static void PrintUsage() {
<< " --log FILE Write all log messages to file\n"
<< " --hierarchy FILE Continuously dump UI hierarchy to JSON\n"
<< "\nSimulator mode:\n"
<< " --simulator Run in simulator mode (app launcher)\n"
<< " --simulator Run in simulator mode (uses shell by default)\n"
<< " --no-shell Disable shell (use direct document loading)\n"
<< " --test-apps PATH Path to test-apps directory (default: ./test-apps)\n"
<< "\nTest modes:\n"
<< " --record FILE Record user actions to JSON file\n"
@@ -343,6 +347,9 @@ int main(int argc, char* argv[]) {
g_test_output_path = argv[++i];
} else if (arg == "--simulator") {
g_simulator_mode = true;
g_shell_mode = true; // Shell mode is implicit in simulator mode
} else if (arg == "--no-shell") {
g_shell_mode = false; // Disable shell (use direct document loading)
} else if (arg == "--test-apps" && i + 1 < argc) {
g_test_apps_path = argv[++i];
} else if (arg[0] != '-') {
@@ -393,11 +400,27 @@ int main(int argc, char* argv[]) {
}
}
// Override document path to main home screen
// Override document path to main home screen or shell
if (!g_simulator_home_path.empty()) {
document_path = g_simulator_home_path;
// Also set the main assets path for proper resource loading
g_main_assets_path = fs::path(g_simulator_home_path).parent_path().parent_path().parent_path().string();
// If shell mode, use shell instead of home
if (g_shell_mode) {
g_shell_path = (fs::path(g_main_assets_path) / "apps" / "shell" / "shell.rml").string();
if (fs::exists(g_shell_path)) {
document_path = g_shell_path;
std::cout << "Shell mode enabled" << std::endl;
std::cout << "Shell: " << g_shell_path << std::endl;
} else {
std::cerr << "Warning: Could not find shell.rml, falling back to direct mode" << std::endl;
document_path = g_simulator_home_path;
g_shell_mode = false;
}
} else {
document_path = g_simulator_home_path;
}
std::cout << "Simulator mode enabled" << std::endl;
std::cout << "Test apps path: " << g_test_apps_path << std::endl;
std::cout << "Home screen: " << g_simulator_home_path << std::endl;
@@ -896,7 +919,50 @@ bool InitializeRmlUi(const std::string& assets_path, int fb_width, int fb_height
return 1;
});
lua_setglobal(L, "switchAppSandbox");
std::cout << "Registered Lua loadScreen, goHome, and switchAppSandbox functions" << std::endl;
// Register loadAppContent function for shell-based app loading
// loadAppContent(element, path) - loads RML content into an element's inner_rml
lua_pushcfunction(L, [](lua_State* L) -> int {
// Get element from first argument (RmlUi element userdata)
Rml::Element* element = Rml::Lua::LuaType<Rml::Element>::check(L, 1);
const char* path = luaL_checkstring(L, 2);
if (!element) {
std::cerr << "loadAppContent: Invalid element" << std::endl;
lua_pushboolean(L, false);
return 1;
}
// Resolve path relative to assets directory
std::string full_path;
if (fs::path(path).is_absolute()) {
full_path = path;
} else {
full_path = (fs::path(g_main_assets_path) / path).string();
}
// Read file content
std::ifstream file(full_path);
if (!file.is_open()) {
std::cerr << "loadAppContent: Cannot open file: " << full_path << std::endl;
lua_pushboolean(L, false);
return 1;
}
std::stringstream buffer;
buffer << file.rdbuf();
std::string content = buffer.str();
// Set as inner_rml
element->SetInnerRML(content);
Rml::Log::Message(Rml::Log::LT_INFO, "Loaded app content from: %s", path);
lua_pushboolean(L, true);
return 1;
});
lua_setglobal(L, "loadAppContent");
std::cout << "Registered Lua loadScreen, goHome, switchAppSandbox, and loadAppContent functions" << std::endl;
// Register simulator API (if in simulator mode)
if (g_simulator_mode) {