#include "app_manager.h" #include "app_keys.h" #include namespace roro { AppManager::AppManager(App& launcher) : launcher_(launcher), foreground_(&launcher) {} void AppManager::registerApp(const AppInfo& info) { apps_.push_back(info); } std::vector AppManager::visibleApps() const { std::vector visible; for (auto& info : apps_) if (!info.hidden) visible.push_back(&info); return visible; } void AppManager::begin() { foreground_ = &launcher_; launcher_.onEnter(); redraw_ = true; } App* AppManager::find(const char* id) const { for (auto& info : apps_) if (std::strcmp(info.id, id) == 0) return info.app; return nullptr; } bool AppManager::open(const char* id) { App* app = find(id); if (!app || modal_) return false; switchTo(*app); return true; } void AppManager::home() { if (!modal_) switchTo(launcher_); } bool AppManager::openModal(const char* id) { App* app = find(id); if (!app) return false; switchTo(*app); modal_ = true; return true; } void AppManager::endModal() { modal_ = false; switchTo(launcher_); } void AppManager::handleKey(const KeyEvent& event) { if (help_.isOpen()) { // scrolls or closes; nothing reaches the App, Home included help_.onKey(event); redraw_ = true; return; } if (event.key == Key::Help) { std::vector rows; foreground_->help(rows); rows.push_back({"Everywhere", nullptr}); keys::add(rows, keys::kEverywhere); const char* scope = foreground_->helpTitle(); const char* app = foregroundTitle(); help_.open(scope ? scope : app ? app : "Launcher", std::move(rows)); redraw_ = true; return; } if (modal_) { foreground_->onKey(event); return; } if (event.key == Key::Home) { home(); return; } bool consumed = foreground_->onKey(event); if (!consumed && event.key == Key::Back) home(); } std::string AppManager::commandFor(const char* id) { std::string command; for (const char* p = id; *p && *p != '-'; p++) command += *p; if (!command.empty() && command[0] >= 'a' && command[0] <= 'z') command[0] = static_cast(command[0] - 'a' + 'A'); return command; } const AppInfo* AppManager::byCommand(const std::string& command) const { for (auto& info : apps_) if (!info.hidden && commandFor(info.id) == command) return &info; return nullptr; } const char* AppManager::foregroundTitle() const { for (auto& info : apps_) if (info.app == foreground_) return info.title; return nullptr; } bool AppManager::takeRedraw() { bool r = redraw_ | foreground_->consumeRedraw(); redraw_ = false; return r; } void AppManager::switchTo(App& app) { help_.close(); // an App opened from elsewhere (a Notification, a command): its keys, not the last one's if (&app == foreground_) return; foreground_->onExit(); foreground_ = &app; foreground_->onEnter(); redraw_ = true; } } // namespace roro