diff --git a/escher/Makefile b/escher/Makefile index 20bc37ba6..2612e54a7 100644 --- a/escher/Makefile +++ b/escher/Makefile @@ -1,7 +1,12 @@ SFLAGS += -Iescher/include objs += $(addprefix escher/src/,\ + childless_view.o\ solid_color_view.o\ + tab_view.o\ + tab_view_controller.o\ text_view.o\ view.o\ + view_controller.o\ + window.o\ ) diff --git a/escher/include/escher.h b/escher/include/escher.h index 124e4d155..f1e032f67 100644 --- a/escher/include/escher.h +++ b/escher/include/escher.h @@ -3,6 +3,9 @@ #include #include +#include #include +#include +#include #endif diff --git a/escher/include/escher/childless_view.h b/escher/include/escher/childless_view.h index 2d09740c1..4dc34ee7d 100644 --- a/escher/include/escher/childless_view.h +++ b/escher/include/escher/childless_view.h @@ -4,9 +4,12 @@ #include class ChildlessView : public View { + using View::View; protected: int numberOfSubviews() override; View * subview(int index) override; + void storeSubviewAtIndex(View * v, int index) override; + void layoutSubviews() override; }; #endif diff --git a/escher/include/escher/menu_view.h b/escher/include/escher/menu_view.h new file mode 100644 index 000000000..693bfbce0 --- /dev/null +++ b/escher/include/escher/menu_view.h @@ -0,0 +1,14 @@ +#ifndef ESCHER_MENU_VIEW_H +#define ESCHER_MENU_VIEW_H + +#include + +class MenuView : public View { +public: + MenuView(Menu * menu); + //void drawRect(KDRect rect) override; +//private: + //KDColor m_color; +}; + +#endif diff --git a/escher/include/escher/solid_color_view.h b/escher/include/escher/solid_color_view.h index 03d63b5c2..258b2849e 100644 --- a/escher/include/escher/solid_color_view.h +++ b/escher/include/escher/solid_color_view.h @@ -1,11 +1,11 @@ #ifndef ESCHER_SOLID_COLOR_VIEW_H #define ESCHER_SOLID_COLOR_VIEW_H -#include +#include -class SolidColorView : public View { +class SolidColorView : public ChildlessView { public: - SolidColorView(KDRect frame, KDColor color); + SolidColorView(KDColor color); void drawRect(KDRect rect) override; private: KDColor m_color; diff --git a/escher/include/escher/tab_view.h b/escher/include/escher/tab_view.h new file mode 100644 index 000000000..4ca991ee2 --- /dev/null +++ b/escher/include/escher/tab_view.h @@ -0,0 +1,30 @@ +#ifndef ESCHER_TAB_VIEW_H +#define ESCHER_TAB_VIEW_H + +#include +#include + +class TabViewController; + +class TabView : public View { +public: + // We'll ask the TabViewController for its controllers + // and each controller know its name! + // and also the active index ! + TabView(TabViewController * tabViewController); + //void drawRect(KDRect rect) override; + int numberOfSubviews() override; + View * subview(int index) override; + void layoutSubviews() override; +protected: + void storeSubviewAtIndex(View * view, int index) override; +private: + TabViewController * m_tabViewController; + /* + static constexpr uint8_t k_maxNumberOfTabs = 4; + uint8_t m_numberOfTabs; + TabViewCell m_cells[k_maxNumberOfTabs]; + */ +}; + +#endif diff --git a/escher/include/escher/tab_view_cell.h b/escher/include/escher/tab_view_cell.h new file mode 100644 index 000000000..3ec4f276d --- /dev/null +++ b/escher/include/escher/tab_view_cell.h @@ -0,0 +1,18 @@ +#ifndef ESCHER_TAB_VIEW_CELL_H +#define ESCHER_TAB_VIEW_CELL_H + +#include +#include + +class TabViewCell : public View { +public: + TabViewCell(); + int numberOfSubviews() override; + View * subview(int index) override; + + void setName(const char * name); +private: + TextView m_textView; +}; + +#endif diff --git a/escher/include/escher/tab_view_controller.h b/escher/include/escher/tab_view_controller.h new file mode 100644 index 000000000..b386fb5a7 --- /dev/null +++ b/escher/include/escher/tab_view_controller.h @@ -0,0 +1,38 @@ +#ifndef ESCHER_TAB_VIEW_CONTROLLER_H +#define ESCHER_TAB_VIEW_CONTROLLER_H + +#include +#include + +class TabViewController : public ViewController { +public: + TabViewController(ViewController ** children); + View * view() override; + void handleKeyEvent(int key) override; + + void setActiveTab(uint8_t index); + uint8_t numberOfTabs(); + +private: + class ContentView : public View { + public: + ContentView(TabViewController * vc); + + int numberOfSubviews() override; + View * subview(int index) override; + void storeSubviewAtIndex(View * view, int index) override; + void layoutSubviews() override; + + void setActiveView(View * view); + private: + TabView m_tabView; + View * m_activeView; + }; + + ContentView m_view; + + ViewController ** m_children; + uint8_t m_activeChildIndex; +}; + +#endif diff --git a/escher/include/escher/table_view.h b/escher/include/escher/table_view.h new file mode 100644 index 000000000..135a0ebd1 --- /dev/null +++ b/escher/include/escher/table_view.h @@ -0,0 +1,18 @@ +#ifndef ESCHER_TABLE_VIEW_H +#define ESCHER_TABLE_VIEW_H + +#include + +class TableView : public View { +public: + TableView( + -> DataSource, + -> CellClass + ); + TextView(KDPoint origin, const char * text); + void drawRect(KDRect rect) override; +private: + const char * m_text; +}; + +#endif diff --git a/escher/include/escher/text_view.h b/escher/include/escher/text_view.h index 3ec4281a6..c3ab092de 100644 --- a/escher/include/escher/text_view.h +++ b/escher/include/escher/text_view.h @@ -3,9 +3,9 @@ #include -class TextView : public View { +class TextView : public ChildlessView { public: - TextView(KDPoint origin, const char * text); + TextView(const char * text); void drawRect(KDRect rect) override; private: const char * m_text; diff --git a/escher/include/escher/view.h b/escher/include/escher/view.h index aa92e020a..fa05f0b85 100644 --- a/escher/include/escher/view.h +++ b/escher/include/escher/view.h @@ -17,20 +17,24 @@ extern "C" { class View { public: - View(KDRect frame); - ~View(); + View(); virtual void drawRect(KDRect rect); // To be implemented. Draw ourself. //void addSubview(View * subview); //void removeFromSuperview(); void setFrame(KDRect frame); + void redraw(); + + void setSubview(View * v, int index); protected: KDRect bounds(); + virtual bool isOnScreen(); virtual int numberOfSubviews() = 0; virtual View * subview(int index) = 0; + virtual void storeSubviewAtIndex(View * v, int index) = 0; + virtual void layoutSubviews() = 0; private: - void redraw(); void redraw(KDRect rect); KDRect absoluteDrawingArea(); diff --git a/escher/include/escher/view_controller.h b/escher/include/escher/view_controller.h new file mode 100644 index 000000000..00f7a9b5b --- /dev/null +++ b/escher/include/escher/view_controller.h @@ -0,0 +1,24 @@ +#ifndef ESCHER_VIEW_CONTROLLER_H +#define ESCHER_VIEW_CONTROLLER_H + +extern "C" { +#include +#include +} + +/* ViewControllers are reponsible for + * - Building the view hierarchy + * - Handling user input + */ + +#include + +class ViewController { +public: + ViewController(); + virtual char * title(); + virtual void handleKeyEvent(int key); + virtual View * view() = 0; +}; + +#endif diff --git a/escher/include/escher/window.h b/escher/include/escher/window.h new file mode 100644 index 000000000..36c91943f --- /dev/null +++ b/escher/include/escher/window.h @@ -0,0 +1,19 @@ +#ifndef ESCHER_WINDOW_H +#define ESCHER_WINDOW_H + +#include + +class Window : public View { +public: + Window(); +protected: + bool isOnScreen() override; + int numberOfSubviews() override; + View * subview(int index) override; + void layoutSubviews() override; + void storeSubviewAtIndex(View * view, int index) override; +private: + View * m_contentView; +}; + +#endif diff --git a/escher/src/childless_view.cpp b/escher/src/childless_view.cpp new file mode 100644 index 000000000..01ee6bba6 --- /dev/null +++ b/escher/src/childless_view.cpp @@ -0,0 +1,20 @@ +#include +extern "C" { +#include +} + +int ChildlessView::numberOfSubviews() { + return 0; +} + +View * ChildlessView::subview(int index) { + assert(false); + return nullptr; +} + +void ChildlessView::layoutSubviews() { +} + +void ChildlessView::storeSubviewAtIndex(View * v, int index) { + assert(false); +} diff --git a/escher/src/solid_color_view.cpp b/escher/src/solid_color_view.cpp index 291ad3862..23e5bfdf9 100644 --- a/escher/src/solid_color_view.cpp +++ b/escher/src/solid_color_view.cpp @@ -1,7 +1,7 @@ #include -SolidColorView::SolidColorView(KDRect frame, KDColor color) : - View(frame), +SolidColorView::SolidColorView(KDColor color) : + ChildlessView(), m_color(color) { } diff --git a/escher/src/tab_view.cpp b/escher/src/tab_view.cpp new file mode 100644 index 000000000..50232bc2a --- /dev/null +++ b/escher/src/tab_view.cpp @@ -0,0 +1,31 @@ +#include +#include + +TabView::TabView(TabViewController * tabViewController) : + View(), + m_tabViewController(tabViewController) +{ + /* + m_numberOfTabs = tabViewController->numberOfTabs(); + for (uint8_t i=0; i +} +#include + +TabViewController::ContentView::ContentView(TabViewController * vc) : + View(), + m_tabView(TabView(vc)), + m_activeView(nullptr) +{ +}; + +void TabViewController::ContentView::setActiveView(View * view) { + setSubview(view, 1); +} + +void TabViewController::ContentView::layoutSubviews() { + if (m_activeView) { + m_activeView->setFrame(this->bounds()); + } +} + +int TabViewController::ContentView::numberOfSubviews() { + return 2; +} + +View * TabViewController::ContentView::subview(int index) { + if (index == 0) { + return &m_tabView; + } else { + assert(index == 1); + return m_activeView; + } +} + +void TabViewController::ContentView::ContentView::storeSubviewAtIndex(View * view, int index) { + assert(index == 1); + m_activeView = view; +} + +TabViewController::TabViewController(ViewController ** children) : + m_children(children), + m_activeChildIndex(0), + m_view(ContentView(this)) +{ + setActiveTab(0); +} + +void TabViewController::setActiveTab(uint8_t i) { + if (i == m_activeChildIndex) { + return; + } + //TODO assert(i <= m_numberOfchildren); + ViewController * activeVC = m_children[i]; + m_view.setActiveView(activeVC->view()); + m_activeChildIndex = i; + m_view.redraw(); + //m_tabView.redraw(); +} + +View * TabViewController::view() { + return &m_view; +} + +void TabViewController::handleKeyEvent(int key) { + // Switch tabs! +} diff --git a/escher/src/text_view.cpp b/escher/src/text_view.cpp index bad8a9b51..2f53ae9df 100644 --- a/escher/src/text_view.cpp +++ b/escher/src/text_view.cpp @@ -1,17 +1,21 @@ #include -KDRect ViewFrame(KDPoint origin, const char * text) { +/* +KDRect ViewFrame(const char * text) { KDRect r; r.origin = origin; r.size = KDStringSize(text); return r; } +*/ -TextView::TextView(KDPoint origin, const char * text) : - View(ViewFrame(origin, text)) { +TextView::TextView(const char * text) : + ChildlessView() { m_text = text; } +//TODO: implement "setFrame" + void TextView::drawRect(KDRect rect) { KDPoint zero = {0, 0}; KDDrawString(m_text, zero, 0); diff --git a/escher/src/view.cpp b/escher/src/view.cpp index 7049fed41..a39de593b 100644 --- a/escher/src/view.cpp +++ b/escher/src/view.cpp @@ -3,9 +3,9 @@ extern "C" { } #include -View::View(KDRect frame) : +View::View() : m_superview(nullptr), - m_frame(frame) + m_frame(KDRectZero) { /* for (uint8_t i=0; iisOnScreen(); + } +} + void View::redraw() { redraw(bounds()); } void View::redraw(KDRect rect) { + if (!isOnScreen()) { + return; + } // Fisrt, let's draw our own content by calling drawRect KDSetDrawingArea(absoluteDrawingArea()); this->drawRect(rect); @@ -46,6 +54,17 @@ void View::redraw(KDRect rect) { } } + void setSubview(View * v, int index); + + +void View::setSubview(View * view, int index) { + view->m_superview = this; + storeSubviewAtIndex(view, index); + assert(subview(index) == view); + layoutSubviews(); + redraw(); +} + /* void View::addSubview(View * subview) { // Let's find a spot for that subview @@ -80,6 +99,7 @@ void View::setFrame(KDRect frame) { * previously was. So let's redraw that part of the superview. */ m_superview->redraw(previousFrame); } + layoutSubviews(); // The view now needs to redraw itself entirely redraw(); } diff --git a/escher/src/view_controller.cpp b/escher/src/view_controller.cpp new file mode 100644 index 000000000..587444d99 --- /dev/null +++ b/escher/src/view_controller.cpp @@ -0,0 +1,12 @@ +#include + +ViewController::ViewController() { +} + +char * ViewController::title() { + return nullptr; +} + +void ViewController::handleKeyEvent(int key) { + // Do nothing +} diff --git a/escher/src/window.cpp b/escher/src/window.cpp new file mode 100644 index 000000000..05b6f914d --- /dev/null +++ b/escher/src/window.cpp @@ -0,0 +1,33 @@ +#include +extern "C" { +#include +} + +Window::Window() : + m_contentView(nullptr) +{ +} + +bool Window::isOnScreen() { + return true; +} + +int Window::numberOfSubviews() { + return (m_contentView == nullptr ? 0 : 1); +} + +View * Window::subview(int index) { + assert(m_contentView != nullptr && index == 0); + return m_contentView; +} + +void Window::layoutSubviews() { + if (m_contentView != nullptr) { + m_contentView->setFrame(this->bounds()); + } +} + +void Window::storeSubviewAtIndex(View * view, int index) { + assert(index == 0); + m_contentView = view; +}