From 961a751131e04cc5d90a7798392236e4df7a48ea Mon Sep 17 00:00:00 2001 From: Romain Goyet Date: Fri, 19 Aug 2016 15:25:06 +0200 Subject: [PATCH] [Escher] Implement a StackViewController Change-Id: I1b4ecc996a1af2bef1b8ce6cfa71457d3345c00e --- escher/Makefile | 2 + escher/include/escher.h | 1 + escher/include/escher/stack_view.h | 20 ++++ escher/include/escher/stack_view_controller.h | 51 +++++++++ escher/src/stack_view.cpp | 31 ++++++ escher/src/stack_view_controller.cpp | 100 ++++++++++++++++++ 6 files changed, 205 insertions(+) create mode 100644 escher/include/escher/stack_view.h create mode 100644 escher/include/escher/stack_view_controller.h create mode 100644 escher/src/stack_view.cpp create mode 100644 escher/src/stack_view_controller.cpp diff --git a/escher/Makefile b/escher/Makefile index d9e1d1b2d..c40d4efc0 100644 --- a/escher/Makefile +++ b/escher/Makefile @@ -8,6 +8,8 @@ objs += $(addprefix escher/src/,\ scroll_view.o\ scroll_view_indicator.o\ solid_color_view.o\ + stack_view.o\ + stack_view_controller.o\ tab_view.o\ tab_view_cell.o\ tab_view_controller.o\ diff --git a/escher/include/escher.h b/escher/include/escher.h index 13cfda6cc..2c0849c35 100644 --- a/escher/include/escher.h +++ b/escher/include/escher.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/escher/include/escher/stack_view.h b/escher/include/escher/stack_view.h new file mode 100644 index 000000000..b965a5bae --- /dev/null +++ b/escher/include/escher/stack_view.h @@ -0,0 +1,20 @@ +#ifndef ESCHER_STACK_VIEW_H +#define ESCHER_STACK_VIEW_H + +#include + +class StackView : public ChildlessView { +public: + StackView(); + void drawRect(KDContext * ctx, KDRect rect) const override; + void setName(const char * name); +protected: +#if ESCHER_VIEW_LOGGING + const char * className() const override; + void logAttributes(std::ostream &os) const override; +#endif +private: + const char * m_name; +}; + +#endif diff --git a/escher/include/escher/stack_view_controller.h b/escher/include/escher/stack_view_controller.h new file mode 100644 index 000000000..288c39e9f --- /dev/null +++ b/escher/include/escher/stack_view_controller.h @@ -0,0 +1,51 @@ +#ifndef ESCHER_STACK_VIEW_CONTROLLER_H +#define ESCHER_STACK_VIEW_CONTROLLER_H + +#include +#include + +constexpr uint8_t kMaxNumberOfStacks = 4; + +class StackViewController : public ViewController { +public: + StackViewController(Responder * parentResponder); + + /* Push creates a new StackView and adds it */ + void push(ViewController * vc); + void pop(); + + + View * view() override; + void handleKeyEvent(int key) override; + + bool handleEvent(ion_event_t event) override; +private: + class ControllerView : public View { + public: + ControllerView(); + void setContentView(View * view); + void pushStack(const char * name); + void popStack(); + protected: +#if ESCHER_VIEW_LOGGING + const char * className() const override; +#endif + private: + int numberOfSubviews() const override; + View * subviewAtIndex(int index) override; + void layoutSubviews() override; + + StackView m_stackViews[kMaxNumberOfStacks]; + View * m_contentView; + int8_t m_numberOfStacks; + }; + + ControllerView m_view; + + void setupActiveViewController(); + static constexpr uint8_t k_maxNumberOfChildren = 4; + ViewController * m_children[k_maxNumberOfChildren]; + uint8_t m_numberOfChildren; +}; + +#endif diff --git a/escher/src/stack_view.cpp b/escher/src/stack_view.cpp new file mode 100644 index 000000000..ac5545657 --- /dev/null +++ b/escher/src/stack_view.cpp @@ -0,0 +1,31 @@ +#include +extern "C" { +#include +} + +StackView::StackView() : + ChildlessView(), + m_name(nullptr) +{ +} + +void StackView::setName(const char * name) { + m_name = name; + markRectAsDirty(bounds()); +} + +void StackView::drawRect(KDContext * ctx, KDRect rect) const { + ctx->fillRect(rect, KDColor(0xFFCD50)); + ctx->drawString(m_name, {0,0}, true); +} + +#if ESCHER_VIEW_LOGGING +const char * StackView::className() const { + return "StackView"; +} + +void StackView::logAttributes(std::ostream &os) const { + View::logAttributes(os); + os << " name=\"" << m_name << "\""; +} +#endif diff --git a/escher/src/stack_view_controller.cpp b/escher/src/stack_view_controller.cpp new file mode 100644 index 000000000..de2fddbaa --- /dev/null +++ b/escher/src/stack_view_controller.cpp @@ -0,0 +1,100 @@ +extern "C" { +#include +} +#include +#include + +StackViewController::ControllerView::ControllerView() : + View(), + m_contentView(nullptr), + m_numberOfStacks(0) +{ +} + +void StackViewController::ControllerView::setContentView(View * view) { + m_contentView = view; + layoutSubviews(); + markRectAsDirty(bounds()); +} + +void StackViewController::ControllerView::pushStack(const char * name) { + m_stackViews[m_numberOfStacks].setName(name); + m_numberOfStacks++; +} + +void StackViewController::ControllerView::popStack() { + assert(m_numberOfStacks > 0); + m_numberOfStacks--; +} + +void StackViewController::ControllerView::layoutSubviews() { + KDCoordinate stackHeight = 20; + KDCoordinate width = m_frame.width(); + for (int i=0; isetFrame(contentViewFrame); + } +} + +int StackViewController::ControllerView::numberOfSubviews() const { + return m_numberOfStacks + (m_contentView == nullptr ? 0 : 1); +} + +View * StackViewController::ControllerView::subviewAtIndex(int index) { + if (index < m_numberOfStacks) { + assert(index >= 0); + return &m_stackViews[index]; + } else { + assert(index == m_numberOfStacks); + return m_contentView; + } +} + +#if ESCHER_VIEW_LOGGING +const char * StackViewController::ControllerView::className() const { + return "StackViewController::ControllerView"; +} +#endif + +StackViewController::StackViewController(Responder * parentResponder) : + ViewController(parentResponder), + m_numberOfChildren(0) +{ +} + +void StackViewController::push(ViewController * vc) { + m_view.pushStack("name"); + m_children[m_numberOfChildren++] = vc; + setupActiveViewController(); +} + +void StackViewController::pop() { + m_view.popStack(); + assert(m_numberOfChildren > 0); + m_numberOfChildren--; + setupActiveViewController(); +} + +void StackViewController::setupActiveViewController() { + ViewController * vc = m_children[m_numberOfChildren-1]; + //vc->setParentResponder(this); + m_view.setContentView(vc->view()); + app()->focus(vc); +} + +void StackViewController::handleKeyEvent(int key) { + // Switch tabs! +} + + +bool StackViewController::handleEvent(ion_event_t event) { + return false; +} + +View * StackViewController::view() { + return &m_view; +}