Public Access
Fn+h on any screen, text fields included, and ? outside Text Entry, open a panel over the content area: the screen's own keys, then the ones that work everywhere. Every App declares its keys for the state it is in (pages, viewers, dialogs and text fields answer for themselves); the App manager opens the panel and takes every key while it is open. About 30 hint lines are gone, from every App. What stays on a screen is state. The first-start Setup keeps its hints and teaches the key; a device set up before gets one Toast, once. The guide and the FAQ open with it. `key help` over the consoles. 476 host tests (8 new). Checked on the device with key help and screenshots: the Launcher, all nine Apps and several of their states. 8.5 KB of flash and 40 bytes of static RAM. Decisions Q196 to Q203 in docs/milestones/U1.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
59 lines
1.6 KiB
C++
59 lines
1.6 KiB
C++
#pragma once
|
|
|
|
#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); }
|
|
|
|
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
|