diff --git a/app/escher_demo.cpp b/app/escher_demo.cpp index acb80b8eb..978d3a025 100644 --- a/app/escher_demo.cpp +++ b/app/escher_demo.cpp @@ -1,9 +1,9 @@ extern "C" { #include -#include #include #include } +#include /* class App { @@ -66,6 +66,37 @@ void MyTextView::drawRect(KDRect frame) { } */ +class GraphView : public ChildlessView { +public: + void drawRect(KDRect rect) const override; +}; + +void GraphView::drawRect(KDRect rect) const { + KDColor bg = 0x99; + KDFillRect(rect, bg); + for (KDCoordinate x=rect.x; xsetFrame(window.bounds()); + MyTestApp myApp = MyTestApp(); + myApp.run(); + /* int i = 0; while(true) { +#if ESCHER_VIEW_LOGGING + std::cout << window << std::endl; +#endif tabVC.setActiveTab(i); ion_event_t event = ion_get_event(); tabVC.handleKeyEvent(event); i = (i+1)%2; } + */ diff --git a/escher/Makefile b/escher/Makefile index a0aef571b..de048714f 100644 --- a/escher/Makefile +++ b/escher/Makefile @@ -1,7 +1,9 @@ SFLAGS += -Iescher/include objs += $(addprefix escher/src/,\ + app.o\ childless_view.o\ + responder.o\ solid_color_view.o\ tab_view.o\ tab_view_cell.o\ diff --git a/escher/include/escher.h b/escher/include/escher.h index f1e032f67..b6d9a57ff 100644 --- a/escher/include/escher.h +++ b/escher/include/escher.h @@ -1,6 +1,8 @@ #ifndef ESCHER_H #define ESCHER_H +#include +#include #include #include #include diff --git a/escher/include/escher/app.h b/escher/include/escher/app.h new file mode 100644 index 000000000..faf1819e7 --- /dev/null +++ b/escher/include/escher/app.h @@ -0,0 +1,28 @@ +#ifndef ESCHER_APP_H +#define ESCHER_APP_H + +#include +#include + +class App { +public: + void run(); + void focus(Responder * responder); +protected: + virtual ViewController * rootViewController() = 0; +private: + void dispatchEvent(ion_event_t event); + Responder * m_focusedResponder; +}; + +/* + +void handleEvent(event) { + // BACK: I want to do stuff! + 1/ Reset my text to what it was "before" + 2/ dismiss + dismiss = app->focus(parentResponder()); +} +*/ + +#endif diff --git a/escher/include/escher/responder.h b/escher/include/escher/responder.h new file mode 100644 index 000000000..7a7ed7cd6 --- /dev/null +++ b/escher/include/escher/responder.h @@ -0,0 +1,20 @@ +#ifndef ESCHER_RESPONDER_H +#define ESCHER_RESPONDER_H + +extern "C" { +#include +} + +class Responder { +public: + Responder(); + virtual bool handleEvent(ion_event_t event); // Default implementation does nothing + virtual void setFocused(bool focused); // Default implementation does nothing. Used by subclasses to know when active or not + Responder * parentResponder(); +protected: + void setParentResponder(Responder * responder); +private: + Responder * m_parentResponder; +}; + +#endif diff --git a/escher/include/escher/tab_view_controller.h b/escher/include/escher/tab_view_controller.h index 726d2def4..7b5b994ec 100644 --- a/escher/include/escher/tab_view_controller.h +++ b/escher/include/escher/tab_view_controller.h @@ -6,7 +6,8 @@ class TabViewController : public ViewController { public: - TabViewController(ViewController ** children, uint8_t numberOfChildren); + TabViewController(ViewController * one, ViewController * two); + //TabViewController(ViewController ** children, uint8_t numberOfChildren); View * view() override; void handleKeyEvent(int key) override; @@ -14,6 +15,7 @@ public: uint8_t numberOfTabs(); const char * tabName(uint8_t index); + bool handleEvent(ion_event_t event) override; private: class ContentView : public View { public: @@ -36,7 +38,8 @@ private: ContentView m_view; - ViewController ** m_children; + static constexpr uint8_t k_maxNumberOfChildren = 4; + ViewController * m_children[k_maxNumberOfChildren]; uint8_t m_numberOfChildren; uint8_t m_activeChildIndex; }; diff --git a/escher/include/escher/view_controller.h b/escher/include/escher/view_controller.h index 00f7a9b5b..634e96ecf 100644 --- a/escher/include/escher/view_controller.h +++ b/escher/include/escher/view_controller.h @@ -12,8 +12,9 @@ extern "C" { */ #include +#include -class ViewController { +class ViewController : public Responder { public: ViewController(); virtual char * title(); diff --git a/escher/src/app.cpp b/escher/src/app.cpp new file mode 100644 index 000000000..3549fa387 --- /dev/null +++ b/escher/src/app.cpp @@ -0,0 +1,43 @@ +#include +#include +extern "C" { +#include +} + +void App::run() { + Window window; + window.setFrame({{0,0}, {200, 200}}); + View * rootView = rootViewController()->view(); + + focus(rootViewController()); + + window.setSubview(rootView, 0); + rootView->setFrame(window.bounds()); + + while (true) { + ion_event_t event = ion_get_event(); // This is a blocking call + dispatchEvent(event); + } +} + +void App::dispatchEvent(ion_event_t event) { + Responder * responder = m_focusedResponder; + bool didHandleEvent = false; + while (responder) { + didHandleEvent = responder->handleEvent(event); + if (didHandleEvent) { + break; + } + responder = responder->parentResponder(); + } +} + +void App::focus(Responder * responder) { + if (m_focusedResponder) { + m_focusedResponder->setFocused(false); + } + m_focusedResponder = responder; + if (m_focusedResponder) { + m_focusedResponder->setFocused(true); + } +} diff --git a/escher/src/responder.cpp b/escher/src/responder.cpp new file mode 100644 index 000000000..c543efe9c --- /dev/null +++ b/escher/src/responder.cpp @@ -0,0 +1,21 @@ +#include + +Responder::Responder() : + m_parentResponder(nullptr) +{ +} + +Responder * Responder::parentResponder() { + return m_parentResponder; +} + +void Responder::setParentResponder(Responder * responder) { + m_parentResponder = responder; +} + +bool Responder::handleEvent(ion_event_t event) { + return false; +} + +void Responder::setFocused(bool focused) { +} diff --git a/escher/src/tab_view_controller.cpp b/escher/src/tab_view_controller.cpp index da089f56d..9ac5a3a3c 100644 --- a/escher/src/tab_view_controller.cpp +++ b/escher/src/tab_view_controller.cpp @@ -58,6 +58,39 @@ const char * TabViewController::ContentView::className() const { } #endif +TabViewController::TabViewController(ViewController * one, ViewController * two) : + ViewController(), + m_numberOfChildren(2), + m_activeChildIndex(-1) +{ + m_children[0] = one; + m_children[1] = two; + + // TODO: This should be lazy loaded! + // So this code should live in view() + for (int i=0; ititle()); + } +} + +bool TabViewController::handleEvent(ion_event_t event) { + switch(event) { + case LEFT_ARROW: + if (m_activeChildIndex > 0) { + setActiveTab(m_activeChildIndex-1); + } + return true; + case RIGHT_ARROW: + if (m_activeChildIndex < m_numberOfChildren-1) { + setActiveTab(m_activeChildIndex+1); + } + return true; + default: + return false; + } +} + +/* TabViewController::TabViewController(ViewController ** children, uint8_t numberOfChildren) : m_children(children), m_numberOfChildren(numberOfChildren), @@ -67,6 +100,7 @@ TabViewController::TabViewController(ViewController ** children, uint8_t numberO m_view.m_tabView.addTabNamed(children[i]->title()); } } +*/ void TabViewController::setActiveTab(uint8_t i) { if (i == m_activeChildIndex) { diff --git a/escher/src/view_controller.cpp b/escher/src/view_controller.cpp index 587444d99..2abe9956c 100644 --- a/escher/src/view_controller.cpp +++ b/escher/src/view_controller.cpp @@ -1,6 +1,7 @@ #include -ViewController::ViewController() { +ViewController::ViewController() : + Responder() { } char * ViewController::title() {