From b2da9687f141e7471e71e4e556d4bfadbf18a342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Thu, 17 Nov 2016 11:06:42 +0100 Subject: [PATCH] [escher] make an independent class alternate empty view to handle empty store and add a delegate to the header view controller class Change-Id: I7c4e8342876e9273270772d4bad0db9424276a98 --- apps/graph/app.cpp | 16 ++- apps/graph/app.h | 4 + apps/graph/graph/graph_controller.cpp | 17 +-- apps/graph/graph/graph_controller.h | 4 +- apps/graph/list/list_controller.cpp | 18 ++- apps/graph/list/list_controller.h | 6 +- apps/graph/values/values_controller.cpp | 111 +++++++----------- apps/graph/values/values_controller.h | 30 ++--- escher/Makefile | 2 + escher/include/escher.h | 3 + .../escher/alternate_empty_view_controller.h | 33 ++++++ .../escher/alternate_empty_view_delegate.h | 15 +++ .../include/escher/header_view_controller.h | 19 ++- escher/include/escher/header_view_delegate.h | 18 +++ .../src/alternate_empty_view_controller.cpp | 78 ++++++++++++ escher/src/header_view_controller.cpp | 58 ++++----- escher/src/header_view_delegate.cpp | 20 ++++ 17 files changed, 292 insertions(+), 160 deletions(-) create mode 100644 escher/include/escher/alternate_empty_view_controller.h create mode 100644 escher/include/escher/alternate_empty_view_delegate.h create mode 100644 escher/include/escher/header_view_delegate.h create mode 100644 escher/src/alternate_empty_view_controller.cpp create mode 100644 escher/src/header_view_delegate.cpp diff --git a/apps/graph/app.cpp b/apps/graph/app.cpp index ba07327c7..4a8871790 100644 --- a/apps/graph/app.cpp +++ b/apps/graph/app.cpp @@ -8,12 +8,16 @@ App::App(Container * container, Context * context) : ExpressionTextFieldDelegate(), m_functionStore(FunctionStore()), m_evaluateContext(EvaluateContext(context)), - m_listController(ListController(nullptr, &m_functionStore)), - m_listStackViewController(StackViewController(&m_tabViewController, &m_listController)), - m_graphController(GraphController(nullptr, &m_functionStore)), - m_valuesController(nullptr, &m_functionStore), - m_valuesStackViewController(StackViewController(&m_tabViewController, &m_valuesController)), - m_tabViewController(&m_inputViewController, &m_listStackViewController, &m_graphController, &m_valuesStackViewController), + m_listController(ListController(&m_listHeader, &m_functionStore, &m_listHeader)), + m_listHeader(HeaderViewController(nullptr, &m_listController, &m_listController)), + m_listStackViewController(StackViewController(&m_tabViewController, &m_listHeader)), + m_graphController(GraphController(&m_graphHeader, &m_functionStore, &m_graphHeader)), + m_graphHeader(HeaderViewController(nullptr, &m_graphController, &m_graphController)), + m_valuesController(&m_valuesHeader, &m_functionStore, &m_valuesHeader), + m_valuesHeader(HeaderViewController(&m_valuesAlternateEmptyViewController, &m_valuesController, &m_valuesController)), + m_valuesAlternateEmptyViewController(AlternateEmptyViewController(nullptr, &m_valuesHeader, &m_valuesController)), + m_valuesStackViewController(StackViewController(&m_tabViewController, &m_valuesAlternateEmptyViewController)), + m_tabViewController(&m_inputViewController, &m_listStackViewController, &m_graphHeader, &m_valuesStackViewController), m_inputViewController(&m_modalViewController, &m_tabViewController, this) { } diff --git a/apps/graph/app.h b/apps/graph/app.h index 308170edf..ab3061561 100644 --- a/apps/graph/app.h +++ b/apps/graph/app.h @@ -20,9 +20,13 @@ private: FunctionStore m_functionStore; EvaluateContext m_evaluateContext; ListController m_listController; + HeaderViewController m_listHeader; StackViewController m_listStackViewController; GraphController m_graphController; + HeaderViewController m_graphHeader; ValuesController m_valuesController; + HeaderViewController m_valuesHeader; + AlternateEmptyViewController m_valuesAlternateEmptyViewController; StackViewController m_valuesStackViewController; TabViewController m_tabViewController; InputViewController m_inputViewController; diff --git a/apps/graph/graph/graph_controller.cpp b/apps/graph/graph/graph_controller.cpp index fbd8b5456..195b89de3 100644 --- a/apps/graph/graph/graph_controller.cpp +++ b/apps/graph/graph/graph_controller.cpp @@ -4,8 +4,9 @@ namespace Graph { -GraphController::GraphController(Responder * parentResponder, FunctionStore * functionStore) : - HeaderViewController(parentResponder, &m_view), +GraphController::GraphController(Responder * parentResponder, FunctionStore * functionStore, HeaderViewController * header) : + ViewController(parentResponder), + HeaderViewDelegate(header), m_view(GraphView(functionStore)), m_headerSelected(false), m_windowButton(Button(this, "Fenetre", Invocation([](void * context, void * sender) {}, this))), @@ -18,7 +19,7 @@ View * GraphController::view() { App * graphApp = (Graph::App *)app(); m_view.setContext(graphApp->evaluateContext()); } - return HeaderViewController::view(); + return &m_view; } const char * GraphController::title() const { @@ -26,7 +27,7 @@ const char * GraphController::title() const { } Responder * GraphController::tabController() const{ - return (parentResponder()); + return (parentResponder()->parentResponder()); } int GraphController::numberOfButtons() const { @@ -52,22 +53,22 @@ void GraphController::didBecomeFirstResponder() { bool GraphController::handleEvent(Ion::Events::Event event) { if (m_headerSelected) { if (event == Ion::Events::Down) { - setSelectedButton(-1); + headerViewController()->setSelectedButton(-1); m_headerSelected = false; return true; } if (event == Ion::Events::Up) { - setSelectedButton(-1); + headerViewController()->setSelectedButton(-1); app()->setFirstResponder(tabController()); } - return HeaderViewController::handleEvent(event); + return headerViewController()->handleEvent(event); } else { if (event == Ion::Events::OK) { m_view.moveCursorRight(); return true; } if (event == Ion::Events::Up) { - setSelectedButton(0); + headerViewController()->setSelectedButton(0); m_headerSelected = true; return true; } diff --git a/apps/graph/graph/graph_controller.h b/apps/graph/graph/graph_controller.h index ccfd74203..da14ac536 100644 --- a/apps/graph/graph/graph_controller.h +++ b/apps/graph/graph/graph_controller.h @@ -6,9 +6,9 @@ #include "../function_store.h" namespace Graph { -class GraphController : public HeaderViewController { +class GraphController : public ViewController, public HeaderViewDelegate { public: - GraphController(Responder * parentResponder, FunctionStore * functionStore); + GraphController(Responder * parentResponder, FunctionStore * functionStore, HeaderViewController * header); const char * title() const override; View * view() override; bool handleEvent(Ion::Events::Event event) override; diff --git a/apps/graph/list/list_controller.cpp b/apps/graph/list/list_controller.cpp index 5eb3781e7..1eb66db5f 100644 --- a/apps/graph/list/list_controller.cpp +++ b/apps/graph/list/list_controller.cpp @@ -4,21 +4,29 @@ namespace Graph { -ListController::ListController(Responder * parentResponder, FunctionStore * functionStore) : - HeaderViewController(parentResponder, &m_selectableTableView), +ListController::ListController(Responder * parentResponder, FunctionStore * functionStore, HeaderViewController * header) : + ViewController(parentResponder), + HeaderViewDelegate(header), m_selectableTableView(SelectableTableView(this, this)), m_functionStore(functionStore), m_parameterController(ParameterController(this, functionStore)) { - setVisibleHeader(false); } const char * ListController::title() const { return "Fonctions"; } +View * ListController::view() { + return &m_selectableTableView; +} + Responder * ListController::tabController() const{ - return (parentResponder()->parentResponder()); + return (parentResponder()->parentResponder()->parentResponder()); +} + +StackViewController * ListController::stackController() const{ + return (StackViewController *)(parentResponder()->parentResponder()); } int ListController::numberOfRows() { @@ -106,7 +114,7 @@ void ListController::didBecomeFirstResponder() { } void ListController::configureFunction(Function * function) { - StackViewController * stack = ((StackViewController *)parentResponder()); + StackViewController * stack = stackController(); m_parameterController.setFunction(function); stack->push(&m_parameterController); } diff --git a/apps/graph/list/list_controller.h b/apps/graph/list/list_controller.h index a4c50bb88..90e71b68b 100644 --- a/apps/graph/list/list_controller.h +++ b/apps/graph/list/list_controller.h @@ -10,13 +10,14 @@ namespace Graph { -class ListController : public HeaderViewController, public TableViewDataSource { +class ListController : public ViewController, public HeaderViewDelegate, public TableViewDataSource { public: - ListController(Responder * parentResponder, FunctionStore * functionStore); + ListController(Responder * parentResponder, FunctionStore * functionStore, HeaderViewController * header); const char * title() const override; bool handleEvent(Ion::Events::Event event) override; bool handleEnter(); void didBecomeFirstResponder() override; + virtual View * view() override; int numberOfRows() override; int numberOfColumns() override; @@ -38,6 +39,7 @@ private: static constexpr KDCoordinate k_functionNameWidth = 65; static constexpr KDCoordinate k_emptyRowHeight = 50; Responder * tabController() const; + StackViewController * stackController() const; constexpr static int k_maxNumberOfRows = 6; // !!! CAUTION: The order here is important // The cells should be initialized *before* the TableView! diff --git a/apps/graph/values/values_controller.cpp b/apps/graph/values/values_controller.cpp index caec278c4..80ec232cd 100644 --- a/apps/graph/values/values_controller.cpp +++ b/apps/graph/values/values_controller.cpp @@ -6,50 +6,9 @@ namespace Graph { -/* Content View */ - -ValuesController::ContentView::ContentView(View * mainView) : - m_noFunctionSelected(PointerTextView("Aucune fonction selectionnee", 0.5f, 0.5f, KDColorBlack, Palette::BackgroundColor)), - m_mainView(mainView), - m_tableState(TableState::Empty) -{ -} - -void ValuesController::ContentView::drawRect(KDContext * ctx, KDRect rect) const { - if (m_tableState == TableState::Empty) { - ctx->fillRect(bounds(), Palette::BackgroundColor); - } -} - -int ValuesController::ContentView::numberOfSubviews() const { - return 1; -} - -View * ValuesController::ContentView::subviewAtIndex(int index) { - assert(index == 0); - if (m_tableState == TableState::Empty) { - return &m_noFunctionSelected; - } - return m_mainView; -} - -void ValuesController::ContentView::layoutSubviews() { - m_noFunctionSelected.setFrame(bounds()); - m_mainView->setFrame(bounds()); -} - -void ValuesController::ContentView::setTableState(TableState tableState) { - m_tableState = tableState; -} - -ValuesController::ContentView::TableState ValuesController::ContentView::tableState() { - return m_tableState; -} - -/* Value Controller */ - -ValuesController::ValuesController(Responder * parentResponder, FunctionStore * functionStore) : - HeaderViewController(parentResponder, &m_contentView), +ValuesController::ValuesController(Responder * parentResponder, FunctionStore * functionStore, HeaderViewController * header) : + ViewController(parentResponder), + HeaderViewDelegate(header), m_selectableTableView(SelectableTableView(this, this, k_topMargin, k_rightMargin, k_bottomMargin, k_leftMargin)), m_functionStore(functionStore), m_parameterController(ValuesParameterController(this, &m_interval)), @@ -58,20 +17,41 @@ ValuesController::ValuesController(Responder * parentResponder, FunctionStore * m_derivativeParameterController(DerivativeParameterController(this)), m_setIntervalButton(Button(this, "Regler l'intervalle",Invocation([](void * context, void * sender) { ValuesController * valuesController = (ValuesController *) context; - StackViewController * stack = ((StackViewController *)valuesController->parentResponder()); + StackViewController * stack = ((StackViewController *)valuesController->stackController()); stack->push(valuesController->parameterController()); - }, this))), - m_contentView(&m_selectableTableView) + }, this))) { m_interval.setStart(0); m_interval.setEnd(10); m_interval.setStep(1); } +View * ValuesController::view() { + return &m_selectableTableView; +} + const char * ValuesController::title() const { return "Valeurs"; } +bool ValuesController::isEmpty() { + if (m_functionStore->numberOfActiveFunctions() == 0) { + return true; + } + return false; +} + +const char * ValuesController::emptyMessage() { + if (m_functionStore->numberOfDefinedFunctions() == 0) { + return "Aucune fonction"; + } + return "Aucune fonction selectionnee"; +} + +Responder * ValuesController::defaultController() { + return tabController(); +} + int ValuesController::numberOfButtons() const { return 1; } @@ -81,7 +61,11 @@ Button * ValuesController::buttonAtIndex(int index) { } Responder * ValuesController::tabController() const { - return (parentResponder()->parentResponder()); + return (parentResponder()->parentResponder()->parentResponder()->parentResponder()); +} + +StackViewController * ValuesController::stackController() const { + return (StackViewController *)(parentResponder()->parentResponder()->parentResponder()); } ViewController * ValuesController::parameterController() { @@ -165,12 +149,7 @@ ValueCell * ValuesController::abscisseCellAtRow(int rowIndex) { } void ValuesController::didBecomeFirstResponder() { - if (m_functionStore->numberOfDefinedFunctions() == 0 || m_functionStore->numberOfActiveFunctions() == 0) { - m_contentView.setTableState(ValuesController::ContentView::TableState::Empty); - return; - } - m_contentView.setTableState(ContentView::TableState::NonEmpty); - setSelectedButton(-1); + headerViewController()->setSelectedButton(-1); if (m_selectableTableView.selectedRow() == -1) { m_selectableTableView.selectCellAtLocation(0, 0); } else { @@ -184,17 +163,9 @@ void ValuesController::didBecomeFirstResponder() { } bool ValuesController::handleEvent(Ion::Events::Event event) { - if (m_contentView.tableState() == ContentView::TableState::Empty) { - if (event == Ion::Events::Up) { - app()->setFirstResponder(tabController()); - return true; - } - return false; - } - if (event == Ion::Events::Down) { if (activeRow() == -1) { - setSelectedButton(-1); + headerViewController()->setSelectedButton(-1); m_selectableTableView.selectCellAtLocation(0,0); app()->setFirstResponder(&m_selectableTableView); return true; @@ -204,18 +175,18 @@ bool ValuesController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::Up) { if (activeRow() == -1) { - setSelectedButton(-1); + headerViewController()->setSelectedButton(-1); app()->setFirstResponder(tabController()); return true; } m_selectableTableView.deselectTable(); - setSelectedButton(0); + headerViewController()->setSelectedButton(0); return true; } if (event == Ion::Events::OK) { if (activeRow() == -1) { - return HeaderViewController::handleEvent(event); + return headerViewController()->handleEvent(event); } if (activeRow() == 0) { if (activeColumn() == 0) { @@ -237,7 +208,7 @@ bool ValuesController::handleEvent(Ion::Events::Event event) { } if (activeRow() == -1) { - return HeaderViewController::handleEvent(event); + return headerViewController()->handleEvent(event); } if (event.hasText()) { if (activeColumn() == 0 && activeRow() > 0) { @@ -251,21 +222,21 @@ bool ValuesController::handleEvent(Ion::Events::Event event) { void ValuesController::configureAbscissa() { - StackViewController * stack = ((StackViewController *)parentResponder()); + StackViewController * stack = stackController(); stack->push(&m_abscissaParameterController); } void ValuesController::configureFunction() { Function * function = functionAtColumn(activeColumn()); m_functionParameterController.setFunction(function); - StackViewController * stack = ((StackViewController *)parentResponder()); + StackViewController * stack = stackController(); stack->push(&m_functionParameterController); } void ValuesController::configureDerivativeFunction() { Function * function = functionAtColumn(activeColumn()); m_derivativeParameterController.setFunction(function); - StackViewController * stack = ((StackViewController *)parentResponder()); + StackViewController * stack = stackController(); stack->push(&m_derivativeParameterController); } diff --git a/apps/graph/values/values_controller.h b/apps/graph/values/values_controller.h index 69633069d..182c6c8fd 100644 --- a/apps/graph/values/values_controller.h +++ b/apps/graph/values/values_controller.h @@ -14,9 +14,9 @@ namespace Graph { -class ValuesController : public HeaderViewController, public TableViewDataSource { +class ValuesController : public ViewController, public HeaderViewDelegate, public TableViewDataSource, public AlternateEmptyViewDelegate { public: - ValuesController(Responder * parentResponder, FunctionStore * functionStore); + ValuesController(Responder * parentResponder, FunctionStore * functionStore, HeaderViewController * header); int activeRow(); int activeColumn(); @@ -24,6 +24,7 @@ public: ValueCell * abscisseCellAtRow(int rowIndex); void editValue(const char * initialText = nullptr); + View * view() override; const char * title() const override; bool handleEvent(Ion::Events::Event event) override; void didBecomeFirstResponder() override; @@ -44,6 +45,10 @@ public: int reusableCellCount(int type) override; int typeAtLocation(int i, int j) override; + bool isEmpty() override; + const char * emptyMessage() override; + Responder * defaultController() override; + static constexpr KDCoordinate k_topMargin = 10; static constexpr KDCoordinate k_bottomMargin = 5; static constexpr KDCoordinate k_leftMargin = 1; @@ -53,28 +58,10 @@ public: static constexpr KDCoordinate k_ordinateCellWidth = 100; private: - class ContentView : public View { - public: - enum class TableState { - Empty, - NonEmpty - }; - ContentView(View * mainView); - void drawRect(KDContext * ctx, KDRect rect) const override; - void setTableState(TableState tableState); - TableState tableState(); - private: - PointerTextView m_noFunctionSelected; - View * m_mainView; - TableState m_tableState; - int numberOfSubviews() const override; - View * subviewAtIndex(int index) override; - void layoutSubviews() override; - }; - Function * functionAtColumn(int i); bool isDerivativeColumn(int i); Responder * tabController() const; + StackViewController * stackController() const; void configureAbscissa(); void configureFunction(); void configureDerivativeFunction(); @@ -93,7 +80,6 @@ private: FunctionParameterController m_functionParameterController; DerivativeParameterController m_derivativeParameterController; Button m_setIntervalButton; - ContentView m_contentView; }; } diff --git a/escher/Makefile b/escher/Makefile index 6ba63d174..b09245828 100644 --- a/escher/Makefile +++ b/escher/Makefile @@ -1,6 +1,7 @@ SFLAGS += -Iescher/include objs += $(addprefix escher/src/,\ + alternate_empty_view_controller.o\ app.o\ buffer_text_view.o\ button.o\ @@ -10,6 +11,7 @@ objs += $(addprefix escher/src/,\ even_odd_cell.o\ expression_view.o\ header_view_controller.o\ + header_view_delegate.o\ image_view.o\ invocation.o\ input_view_controller.o\ diff --git a/escher/include/escher.h b/escher/include/escher.h index 5962b0fa9..49331e542 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 @@ -10,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/escher/include/escher/alternate_empty_view_controller.h b/escher/include/escher/alternate_empty_view_controller.h new file mode 100644 index 000000000..530fd1d1a --- /dev/null +++ b/escher/include/escher/alternate_empty_view_controller.h @@ -0,0 +1,33 @@ +#ifndef ESCHER_ALTERNATE_EMPTY_VIEW_H +#define ESCHER_ALTERNATE_EMPTY_VIEW_H + +#include +#include +#include + +class AlternateEmptyViewController : public ViewController { +public: + AlternateEmptyViewController(Responder * parentResponder, ViewController * mainViewController, AlternateEmptyViewDelegate * delegate); + View * view() override; + const char * title() const override; + bool handleEvent(Ion::Events::Event event) override; + void didBecomeFirstResponder() override; +private: + class ContentView : public View { + public: + ContentView(ViewController * mainViewController, AlternateEmptyViewDelegate * delegate); + void drawRect(KDContext * ctx, KDRect rect) const override; + ViewController * mainViewController() const; + AlternateEmptyViewDelegate * alternateEmptyViewDelegate() const; + private: + int numberOfSubviews() const override; + View * subviewAtIndex(int index) override; + void layoutSubviews() override; + PointerTextView m_message; + ViewController * m_mainViewController; + AlternateEmptyViewDelegate * m_delegate; + }; + ContentView m_contentView; +}; + +#endif diff --git a/escher/include/escher/alternate_empty_view_delegate.h b/escher/include/escher/alternate_empty_view_delegate.h new file mode 100644 index 000000000..3d64bfc00 --- /dev/null +++ b/escher/include/escher/alternate_empty_view_delegate.h @@ -0,0 +1,15 @@ +#ifndef ESCHER_ALTERNATE_EMPTY_VIEW_DELEGATE_H +#define ESCHER_ALTERNATE_EMPTY_VIEW_DELEGATE_H + +#include + +class AlternateEmptyViewController; + +class AlternateEmptyViewDelegate { +public: + virtual bool isEmpty() = 0; + virtual const char * emptyMessage() = 0; + virtual Responder * defaultController() = 0; +}; + +#endif diff --git a/escher/include/escher/header_view_controller.h b/escher/include/escher/header_view_controller.h index 99f5671a0..73fb8d94b 100644 --- a/escher/include/escher/header_view_controller.h +++ b/escher/include/escher/header_view_controller.h @@ -6,42 +6,39 @@ #include #include #include +#include class HeaderViewController : public ViewController { public: - HeaderViewController(Responder * parentResponder, View * mainView); + HeaderViewController(Responder * parentResponder, ViewController * mainViewController, HeaderViewDelegate * delegate); View * view() override; const char * title() const override; + void didBecomeFirstResponder() override; bool handleEvent(Ion::Events::Event event) override; - void setVisibleHeader(bool isVisibleHeader); - virtual int numberOfButtons() const; - virtual Button * buttonAtIndex(int index); -protected: bool setSelectedButton(int selectedButton); private: class ContentView : public View { public: - ContentView(View * subview, HeaderViewController * headerViewController); + ContentView(ViewController * mainViewController, HeaderViewDelegate * delegate); int numberOfButtons() const; Button * buttonAtIndex(int index); int numberOfSubviews() const override; View * subviewAtIndex(int index) override; void layoutSubviews() override; void drawRect(KDContext * ctx, KDRect rect) const override; - void setVisibleHeader(bool isVisibleHeader); bool setSelectedButton(int selectedButton, App * app); int selectedButton(); + ViewController * mainViewController() const; + HeaderViewDelegate * headerViewDelegate() const; private: constexpr static KDCoordinate k_headerHeight = 20; constexpr static KDColor k_separatorHeaderColor = KDColor::RGB24(0xDEE0E2); constexpr static KDColor k_selectedBackgroundColor = KDColor::RGB24(0x426DA7); - View * m_mainView; - bool m_visibleHeader; + ViewController * m_mainViewController; int m_selectedButton; - HeaderViewController * m_headerViewController; + HeaderViewDelegate * m_delegate; }; ContentView m_contentView; - }; #endif diff --git a/escher/include/escher/header_view_delegate.h b/escher/include/escher/header_view_delegate.h new file mode 100644 index 000000000..fe7fe4986 --- /dev/null +++ b/escher/include/escher/header_view_delegate.h @@ -0,0 +1,18 @@ +#ifndef ESCHER_HEADER_VIEW_DELEGATE_H +#define ESCHER_HEADER_VIEW_DELEGATE_H + +#include + +class HeaderViewController; + +class HeaderViewDelegate { +public: + HeaderViewDelegate(HeaderViewController * headerViewController); + virtual int numberOfButtons() const; + virtual Button * buttonAtIndex(int index); + HeaderViewController * headerViewController(); +private: + HeaderViewController * m_headerViewController; +}; + +#endif diff --git a/escher/src/alternate_empty_view_controller.cpp b/escher/src/alternate_empty_view_controller.cpp new file mode 100644 index 000000000..847c79ee3 --- /dev/null +++ b/escher/src/alternate_empty_view_controller.cpp @@ -0,0 +1,78 @@ +#include +#include +#include +#include + +/* ContentView */ + +AlternateEmptyViewController::ContentView::ContentView(ViewController * mainViewController, AlternateEmptyViewDelegate * delegate) : + m_message(PointerTextView(nullptr, 0.5f, 0.5f, KDColorBlack, Palette::BackgroundColor)), + m_mainViewController(mainViewController), + m_delegate(delegate) +{ +} + +void AlternateEmptyViewController::ContentView::drawRect(KDContext * ctx, KDRect rect) const { + if (m_delegate->isEmpty()) { + ctx->fillRect(bounds(), Palette::BackgroundColor); + } +} + +int AlternateEmptyViewController::ContentView::numberOfSubviews() const { + return 1; +} + +View * AlternateEmptyViewController::ContentView::subviewAtIndex(int index) { + assert(index == 0); + if (m_delegate->isEmpty()) { + m_message.setText(m_delegate->emptyMessage()); + return &m_message; + } + return m_mainViewController->view(); +} + +void AlternateEmptyViewController::ContentView::layoutSubviews() { + m_message.setFrame(bounds()); + m_mainViewController->view()->setFrame(bounds()); +} + +ViewController * AlternateEmptyViewController::ContentView::mainViewController() const { + return m_mainViewController; +} + +AlternateEmptyViewDelegate * AlternateEmptyViewController::ContentView::alternateEmptyViewDelegate() const { + return m_delegate; +} + +/* AlternateEmptyViewController */ + +AlternateEmptyViewController::AlternateEmptyViewController(Responder * parentResponder, ViewController * mainViewController, AlternateEmptyViewDelegate * delegate) : + ViewController(parentResponder), + m_contentView(ContentView(mainViewController, delegate)) +{ +} + +View * AlternateEmptyViewController::view() { + return &m_contentView; +} + +const char * AlternateEmptyViewController::title() const { + return m_contentView.mainViewController()->title(); +} + +bool AlternateEmptyViewController::handleEvent(Ion::Events::Event event) { + if (m_contentView.alternateEmptyViewDelegate()->isEmpty()) { + if (event != Ion::Events::Home) { + app()->setFirstResponder(m_contentView.alternateEmptyViewDelegate()->defaultController()); + return true; + } + return false; + } + return false; +} + +void AlternateEmptyViewController::didBecomeFirstResponder() { + if (!m_contentView.alternateEmptyViewDelegate()->isEmpty()) { + app()->setFirstResponder(m_contentView.mainViewController()); + } +} diff --git a/escher/src/header_view_controller.cpp b/escher/src/header_view_controller.cpp index 51a96ebfd..61c982905 100644 --- a/escher/src/header_view_controller.cpp +++ b/escher/src/header_view_controller.cpp @@ -4,32 +4,29 @@ constexpr KDColor HeaderViewController::ContentView::k_separatorHeaderColor; constexpr KDColor HeaderViewController::ContentView::k_selectedBackgroundColor; -HeaderViewController::ContentView::ContentView(View * subview, HeaderViewController * headerViewController) : +HeaderViewController::ContentView::ContentView(ViewController * mainViewController, HeaderViewDelegate * delegate) : View(), - m_mainView(subview), - m_visibleHeader(true), + m_mainViewController(mainViewController), m_selectedButton(-1), - m_headerViewController(headerViewController) + m_delegate(delegate) { } int HeaderViewController::ContentView::numberOfButtons() const { - return m_headerViewController->numberOfButtons(); + return m_delegate->numberOfButtons(); } + Button * HeaderViewController::ContentView::buttonAtIndex(int index) { - return m_headerViewController->buttonAtIndex(index); + return m_delegate->buttonAtIndex(index); } int HeaderViewController::ContentView::numberOfSubviews() const { - if (m_visibleHeader) { - return numberOfButtons() + 1; - } - return 1; + return numberOfButtons() + 1; } View * HeaderViewController::ContentView::subviewAtIndex(int index) { if (index == 0) { - return m_mainView; + return m_mainViewController->view(); } else { return buttonAtIndex(index - 1); } @@ -38,11 +35,11 @@ View * HeaderViewController::ContentView::subviewAtIndex(int index) { void HeaderViewController::ContentView::layoutSubviews() { if (numberOfButtons() == 0) { KDRect mainViewFrame(0, 1, bounds().width(), bounds().height() - 1); - m_mainView->setFrame(mainViewFrame); + m_mainViewController->view()->setFrame(mainViewFrame); return; } KDRect mainViewFrame(0, k_headerHeight + 1, bounds().width(), bounds().height() - k_headerHeight - 1); - m_mainView->setFrame(mainViewFrame); + m_mainViewController->view()->setFrame(mainViewFrame); int currentXOrigin = 0; for (int i = 0; i < numberOfButtons(); i++) { Button * button = buttonAtIndex(i); @@ -54,7 +51,7 @@ void HeaderViewController::ContentView::layoutSubviews() { } void HeaderViewController::ContentView::drawRect(KDContext * ctx, KDRect rect) const { - if (m_visibleHeader) { + if (numberOfButtons() > 0) { ctx->fillRect(KDRect(0, 0, bounds().width(), k_headerHeight), KDColorWhite); ctx->fillRect(KDRect(0, k_headerHeight, bounds().width(), 1), k_separatorHeaderColor); } else { @@ -62,12 +59,6 @@ void HeaderViewController::ContentView::drawRect(KDContext * ctx, KDRect rect) c } } -void HeaderViewController::ContentView::setVisibleHeader(bool isVisibleHeader) { - m_visibleHeader = isVisibleHeader; - markRectAsDirty(KDRect(0, 0, bounds().width(), bounds().height())); - layoutSubviews(); -} - bool HeaderViewController::ContentView::setSelectedButton(int selectedButton, App * application) { if (selectedButton < -1 || selectedButton >= numberOfButtons() || selectedButton == m_selectedButton) { return false; @@ -90,31 +81,30 @@ int HeaderViewController::ContentView::selectedButton() { return m_selectedButton; } -HeaderViewController::HeaderViewController(Responder * parentResponder, View * mainView) : +ViewController * HeaderViewController::ContentView::mainViewController() const { + return m_mainViewController; +} + +HeaderViewDelegate * HeaderViewController::ContentView::headerViewDelegate() const { + return m_delegate; +} + +HeaderViewController::HeaderViewController(Responder * parentResponder, ViewController * mainViewController, HeaderViewDelegate * delegate) : ViewController(parentResponder), - m_contentView(ContentView(mainView, this)) + m_contentView(ContentView(mainViewController, delegate)) { } -int HeaderViewController::numberOfButtons() const { - return 0; -} - -Button * HeaderViewController::buttonAtIndex(int index) { - assert(false); - return nullptr; -} - View * HeaderViewController::view() { return &m_contentView; } const char * HeaderViewController::title() const { - return "HeaderViewController"; + return m_contentView.mainViewController()->title(); } -void HeaderViewController::setVisibleHeader(bool isVisibleHeader) { - m_contentView.setVisibleHeader(isVisibleHeader); +void HeaderViewController::didBecomeFirstResponder(){ + app()->setFirstResponder(m_contentView.mainViewController()); } bool HeaderViewController::setSelectedButton(int selectedButton) { diff --git a/escher/src/header_view_delegate.cpp b/escher/src/header_view_delegate.cpp new file mode 100644 index 000000000..2b704c929 --- /dev/null +++ b/escher/src/header_view_delegate.cpp @@ -0,0 +1,20 @@ +#include +#include + +HeaderViewDelegate::HeaderViewDelegate(HeaderViewController * headerViewController) : + m_headerViewController(headerViewController) +{ +} + +int HeaderViewDelegate::numberOfButtons() const { + return 0; +} + +Button * HeaderViewDelegate::buttonAtIndex(int index) { + assert(false); + return nullptr; +} + +HeaderViewController * HeaderViewDelegate::headerViewController() { + return m_headerViewController; +}