Public Access
The Shell shows the replies to its own commands and nothing else. The console knows who each line is printed for (Console::As, Console::origin): a command run from the Shell prints as the Shell's, and what answers it later from another task carries that along (ls, tasks, du, cp, update check, sd list, screenshot, gemini get). Ctrl+b shows everything instead. This replaces the ten-second window, which was a guess. An App's name with a capital opens it (Notes, Irc, Wifi, Gnss, Gemini, Lora, Storage, Shell, System, Settings), from the Shell and from the consoles. rm needs -r for a folder, here and over the consoles. In the Shell a file, or a folder with something in it, is asked about unless -f; an empty folder with -r goes without a word. The Shell now hands its line to the main loop to run: run from inside the key handler, rm on a folder overflowed the loop's stack and crashed the device. `info` says which App is in front. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
67 lines
2.1 KiB
C++
67 lines
2.1 KiB
C++
#pragma once
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "app.h"
|
|
|
|
namespace roro {
|
|
|
|
struct AppInfo {
|
|
const char* id;
|
|
const char* title;
|
|
bool hidden; // not listed in the Launcher, but can still be opened
|
|
App* app;
|
|
};
|
|
|
|
// Owns which App is in the foreground and routes keys. Home always returns to the Launcher;
|
|
// Back is offered to the App first and returns to the Launcher if the App doesn't consume it.
|
|
class AppManager {
|
|
public:
|
|
explicit AppManager(App& launcher);
|
|
|
|
void registerApp(const AppInfo& info);
|
|
std::vector<const AppInfo*> visibleApps() const;
|
|
|
|
void begin();
|
|
bool open(const char* id); // refused while a modal App runs
|
|
void home();
|
|
|
|
// A modal App (e.g. the first-boot wizard) can't be left with Home or Back: those keys go to it,
|
|
// and it ends itself with endModal(), which returns to the Launcher.
|
|
bool openModal(const char* id);
|
|
void endModal();
|
|
|
|
void handleKey(const KeyEvent& event);
|
|
void update(uint32_t nowMs) { foreground_->update(nowMs); }
|
|
|
|
// The command that opens an App from the consoles and the Shell (issue #67): its id with a
|
|
// capital letter, up to the first dash. "notes" is Notes, "wifi-tools" is Wifi. The capital says
|
|
// "an App", where every command of the firmware is in small letters.
|
|
static std::string commandFor(const char* id);
|
|
// The App that command names, among the ones the Launcher lists; nullptr if there's none.
|
|
const AppInfo* byCommand(const std::string& command) const;
|
|
|
|
App& foreground() const { return *foreground_; }
|
|
const char* foregroundTitle() const; // nullptr for the Launcher
|
|
|
|
// The help panel (Fn+h): open, it takes every key, and the App sees none of them.
|
|
const HelpModel& help() const { return help_; }
|
|
|
|
// True once after the screen needs redrawing (App switch, or the App asked for it).
|
|
bool takeRedraw();
|
|
|
|
private:
|
|
void switchTo(App& app);
|
|
App* find(const char* id) const;
|
|
|
|
App& launcher_;
|
|
App* foreground_;
|
|
std::vector<AppInfo> apps_;
|
|
HelpModel help_;
|
|
bool redraw_ = true;
|
|
bool modal_ = false;
|
|
};
|
|
|
|
} // namespace roro
|