#include "app_keys.h" #include "demo_app.h" #include "ui/widgets.h" namespace roro { namespace { const char* const kMenu[] = {"Text view", "Line editor", "Dialog", "Toast: info", "Toast: warning", "Toast: burst of 5"}; const char* const kText = "Bienvenue sur roro9stack ! Ce texte teste le retour \xC3\xA0 la ligne automatique et les " "accents : \xC3\xA9t\xC3\xA9, \xC3\xA0 bient\xC3\xB4t, gar\xC3\xA7on, No\xC3\xABl, " "ma\xC3\xAEtre, o\xC3\xB9.\n\n" "Use ; and . to scroll, ` to go back. Fn+` always returns to the Launcher.\n\n" "Unbreakablewordthatislongerthanawholelineofthescreen to test hard breaks."; } // namespace void DemoApp::onEnter() { page_ = Page::Menu; dialog_.reset(); menu_.setCount(sizeof(kMenu) / sizeof(kMenu[0])); } void DemoApp::notify(const char* text, NotificationLevel level) { bus_.publish(Event::withText(EventType::Notification, text, static_cast(level))); } void DemoApp::help(std::vector& out) const { if (dialog_) return keys::add(out, keys::kDialog); if (page_ == Page::Editor) return keys::add(out, keys::kText); if (page_ == Page::Menu) keys::add(out, keys::kDemo); } bool DemoApp::onKey(const KeyEvent& e) { requestRedraw(); if (dialog_) { dialog_->onKey(e); int r = dialog_->result(); if (r != DialogModel::kPending) { notify(r == DialogModel::kCancelled ? "Dialog cancelled" : ("Chose " + dialog_->buttons()[r]).c_str(), NotificationLevel::Info); dialog_.reset(); } return true; } switch (page_) { case Page::Menu: return onMenuKey(e); case Page::Text: if (e.key == Key::Up && textScroll_ > 0) textScroll_--; else if (e.key == Key::Down && textScroll_ < textLineCount_ - 1) textScroll_++; else if (e.key == Key::Back) page_ = Page::Menu; return true; case Page::Editor: switch (e.key) { case Key::Char: editor_.insert(e.ch); break; case Key::Delete: editor_.backspace(); break; case Key::Left: editor_.left(); break; case Key::Right: editor_.right(); break; case Key::Up: editor_.home(); break; case Key::Down: editor_.end(); break; case Key::Select: if (!editor_.text().empty()) notify(editor_.text().c_str(), NotificationLevel::Message); break; case Key::Back: page_ = Page::Menu; break; default: break; } return true; } return false; } bool DemoApp::onMenuKey(const KeyEvent& e) { switch (e.key) { case Key::Up: menu_.up(); return true; case Key::Down: menu_.down(); return true; case Key::Select: break; default: return false; // Back leaves the App } switch (menu_.selected()) { case 0: page_ = Page::Text; textScroll_ = 0; break; case 1: page_ = Page::Editor; break; case 2: dialog_.reset(new DialogModel({"Cancel", "Maybe", "OK"})); break; case 3: notify("Hello from the demo", NotificationLevel::Info); break; case 4: notify("Something needs attention", NotificationLevel::Warning); break; case 5: for (int i = 1; i <= 5; i++) notify(("Burst " + std::to_string(i)).c_str(), NotificationLevel::Info); break; } return true; } void DemoApp::draw(Canvas& c) { const auto& area = theme::kContent; switch (page_) { case Page::Menu: widgets::list(c, menu_, area, [](int i) { return std::string(kMenu[i]); }); break; case Page::Text: { auto lines = wrapText(kText, area.w - 10, widgets::bodyMeasure(c)); textLineCount_ = static_cast(lines.size()); widgets::textLines(c, lines, textScroll_, area); break; } case Page::Editor: c.setTextColor(theme::kMuted); c.drawString("A line editor", 4, area.y + 4); widgets::lineEditor(c, editor_, {4, area.y + 22, area.w - 8, 0}); c.setTextColor(theme::kMuted); c.drawString((std::to_string(editor_.text().size()) + "/39 bytes").c_str(), 4, area.y + 44); break; } if (dialog_) widgets::dialog(c, "Dialog", "Left/Right or Tab to choose, Enter to confirm, ` to cancel.", *dialog_); } } // namespace roro