From f98c171d2acb5b9d50638c76ea97791f81e5beb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Fri, 17 Apr 2020 16:21:41 +0200 Subject: [PATCH] [apps/variable_box] Prepare for Code::VariableBox factorization --- apps/Makefile | 3 +- apps/apps_container.cpp | 2 +- apps/apps_container.h | 6 +- apps/graph/app.cpp | 4 +- ...r.cpp => math_variable_box_controller.cpp} | 56 ++++---- ...oller.h => math_variable_box_controller.h} | 15 +-- apps/math_variable_box_empty_controller.cpp | 53 ++++++++ apps/math_variable_box_empty_controller.h | 41 ++++++ .../input_event_handler_delegate_app.cpp | 4 +- apps/variable_box_empty_controller.cpp | 123 +++++++----------- apps/variable_box_empty_controller.h | 31 ++--- 11 files changed, 198 insertions(+), 140 deletions(-) rename apps/{variable_box_controller.cpp => math_variable_box_controller.cpp} (82%) rename apps/{variable_box_controller.h => math_variable_box_controller.h} (88%) create mode 100644 apps/math_variable_box_empty_controller.cpp create mode 100644 apps/math_variable_box_empty_controller.h diff --git a/apps/Makefile b/apps/Makefile index d6f4adef4..3d73f627b 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -34,10 +34,11 @@ apps_src += $(addprefix apps/,\ lock_view.cpp \ main.cpp \ math_toolbox.cpp \ + math_variable_box_controller.cpp \ + math_variable_box_empty_controller.cpp \ shift_alpha_lock_view.cpp \ suspend_timer.cpp \ title_bar_view.cpp \ - variable_box_controller.cpp \ variable_box_empty_controller.cpp \ ) diff --git a/apps/apps_container.cpp b/apps/apps_container.cpp index 894920888..cd5f56f5a 100644 --- a/apps/apps_container.cpp +++ b/apps/apps_container.cpp @@ -85,7 +85,7 @@ MathToolbox * AppsContainer::mathToolbox() { return &m_mathToolbox; } -VariableBoxController * AppsContainer::variableBoxController() { +MathVariableBoxController * AppsContainer::variableBoxController() { return &m_variableBoxController; } diff --git a/apps/apps_container.h b/apps/apps_container.h index 18d755512..482999103 100644 --- a/apps/apps_container.h +++ b/apps/apps_container.h @@ -8,7 +8,7 @@ #include "apps_window.h" #include "empty_battery_window.h" #include "math_toolbox.h" -#include "variable_box_controller.h" +#include "math_variable_box_controller.h" #include "exam_pop_up_controller.h" #include "exam_pop_up_controller_delegate.h" #include "battery_timer.h" @@ -34,7 +34,7 @@ public: void reset(); Poincare::Context * globalContext(); MathToolbox * mathToolbox(); - VariableBoxController * variableBoxController(); + MathVariableBoxController * variableBoxController(); void suspend(bool checkIfOnOffKeyReleased = false); bool dispatchEvent(Ion::Events::Event event) override; bool switchTo(App::Snapshot * snapshot) override; @@ -70,7 +70,7 @@ private: EmptyBatteryWindow m_emptyBatteryWindow; Shared::GlobalContext m_globalContext; MathToolbox m_mathToolbox; - VariableBoxController m_variableBoxController; + MathVariableBoxController m_variableBoxController; ExamPopUpController m_examPopUpController; OnBoarding::PopUpController m_promptController; BatteryTimer m_batteryTimer; diff --git a/apps/graph/app.cpp b/apps/graph/app.cpp index 227aa1c0e..464966cba 100644 --- a/apps/graph/app.cpp +++ b/apps/graph/app.cpp @@ -77,9 +77,9 @@ CodePoint App::XNT() { } NestedMenuController * App::variableBoxForInputEventHandler(InputEventHandler * textInput) { - VariableBoxController * varBox = AppsContainer::sharedAppsContainer()->variableBoxController(); + MathVariableBoxController * varBox = AppsContainer::sharedAppsContainer()->variableBoxController(); varBox->setSender(textInput); - varBox->lockDeleteEvent(VariableBoxController::Page::Function); + varBox->lockDeleteEvent(MathVariableBoxController::Page::Function); return varBox; } diff --git a/apps/variable_box_controller.cpp b/apps/math_variable_box_controller.cpp similarity index 82% rename from apps/variable_box_controller.cpp rename to apps/math_variable_box_controller.cpp index 4637220b3..7eb72b39e 100644 --- a/apps/variable_box_controller.cpp +++ b/apps/math_variable_box_controller.cpp @@ -1,4 +1,4 @@ -#include "variable_box_controller.h" +#include "math_variable_box_controller.h" #include "shared/global_context.h" #include "shared/continuous_function.h" #include @@ -14,7 +14,7 @@ using namespace Poincare; using namespace Shared; using namespace Ion; -VariableBoxController::VariableBoxController() : +MathVariableBoxController::MathVariableBoxController() : AlternateEmptyNestedMenuController(I18n::Message::Variables), m_currentPage(Page::RootMenu), m_lockPageDelete(Page::RootMenu), @@ -25,20 +25,20 @@ VariableBoxController::VariableBoxController() : } } -void VariableBoxController::viewWillAppear() { +void MathVariableBoxController::viewWillAppear() { assert(m_currentPage == Page::RootMenu); AlternateEmptyNestedMenuController::viewWillAppear(); } -void VariableBoxController::viewDidDisappear() { +void MathVariableBoxController::viewDidDisappear() { AlternateEmptyNestedMenuController::viewDidDisappear(); /* NestedMenuController::viewDidDisappear might need cell heights, which would - * use the VariableBoxController cell heights memoization. We thus reset the - * VariableBoxController layouts only after calling the parent's + * use the MathVariableBoxController cell heights memoization. We thus reset the + * MathVariableBoxController layouts only after calling the parent's * viewDidDisappear. */ - // Tidy the layouts displayed in the VariableBoxController to clean TreePool + // Tidy the layouts displayed in the MathVariableBoxController to clean TreePool for (int i = 0; i < k_maxNumberOfDisplayedRows; i++) { m_leafCells[i].setLayout(Layout()); m_leafCells[i].setAccessoryLayout(Layout()); @@ -49,7 +49,7 @@ void VariableBoxController::viewDidDisappear() { setPage(Page::RootMenu); } -bool VariableBoxController::handleEvent(Ion::Events::Event event) { +bool MathVariableBoxController::handleEvent(Ion::Events::Event event) { /* We do not want to handle backspace event if: * - On the root menu page * The deletion on the current page is locked @@ -68,7 +68,7 @@ bool VariableBoxController::handleEvent(Ion::Events::Event event) { return AlternateEmptyNestedMenuController::handleEvent(event); } -int VariableBoxController::numberOfRows() const { +int MathVariableBoxController::numberOfRows() const { switch (m_currentPage) { case Page::RootMenu: return k_numberOfMenuRows; @@ -81,7 +81,7 @@ int VariableBoxController::numberOfRows() const { } } -int VariableBoxController::reusableCellCount(int type) { +int MathVariableBoxController::reusableCellCount(int type) { assert(type < 2); if (type == 0) { return k_maxNumberOfDisplayedRows; @@ -89,7 +89,7 @@ int VariableBoxController::reusableCellCount(int type) { return k_numberOfMenuRows; } -void VariableBoxController::willDisplayCellForIndex(HighlightCell * cell, int index) { +void MathVariableBoxController::willDisplayCellForIndex(HighlightCell * cell, int index) { if (m_currentPage == Page::RootMenu) { I18n::Message label = nodeLabelAtIndex(index); MessageTableCell * myCell = (MessageTableCell *)cell; @@ -119,7 +119,7 @@ void VariableBoxController::willDisplayCellForIndex(HighlightCell * cell, int in myCell->reloadCell(); } -KDCoordinate VariableBoxController::rowHeight(int index) { +KDCoordinate MathVariableBoxController::rowHeight(int index) { if (m_currentPage != Page::RootMenu) { Layout layoutR = expressionLayoutForRecord(recordAtIndex(index), index); if (!layoutR.isUninitialized()) { @@ -129,34 +129,34 @@ KDCoordinate VariableBoxController::rowHeight(int index) { return AlternateEmptyNestedMenuController::rowHeight(index); } -int VariableBoxController::typeAtLocation(int i, int j) { +int MathVariableBoxController::typeAtLocation(int i, int j) { if (m_currentPage == Page::RootMenu) { return 1; } return 0; } -ExpressionTableCellWithExpression * VariableBoxController::leafCellAtIndex(int index) { +ExpressionTableCellWithExpression * MathVariableBoxController::leafCellAtIndex(int index) { assert(index >= 0 && index < k_maxNumberOfDisplayedRows); return &m_leafCells[index]; } -MessageTableCellWithChevron * VariableBoxController::nodeCellAtIndex(int index) { +MessageTableCellWithChevron * MathVariableBoxController::nodeCellAtIndex(int index) { assert(index >= 0 && index < k_numberOfMenuRows); return &m_nodeCells[index]; } -VariableBoxController::Page VariableBoxController::pageAtIndex(int index) { +MathVariableBoxController::Page MathVariableBoxController::pageAtIndex(int index) { Page pages[2] = {Page::Expression, Page::Function}; return pages[index]; } -void VariableBoxController::setPage(Page page) { +void MathVariableBoxController::setPage(Page page) { m_currentPage = page; resetMemoization(); } -bool VariableBoxController::selectSubMenu(int selectedRow) { +bool MathVariableBoxController::selectSubMenu(int selectedRow) { m_selectableTableView.deselectTable(); setPage(pageAtIndex(selectedRow)); bool selectSubMenu = AlternateEmptyNestedMenuController::selectSubMenu(selectedRow); @@ -166,7 +166,7 @@ bool VariableBoxController::selectSubMenu(int selectedRow) { return selectSubMenu; } -bool VariableBoxController::returnToPreviousMenu() { +bool MathVariableBoxController::returnToPreviousMenu() { if (isDisplayingEmptyController()) { pop(); } else { @@ -176,7 +176,7 @@ bool VariableBoxController::returnToPreviousMenu() { return AlternateEmptyNestedMenuController::returnToPreviousMenu(); } -bool VariableBoxController::selectLeaf(int selectedRow) { +bool MathVariableBoxController::selectLeaf(int selectedRow) { if (isDisplayingEmptyController()) { /* We do not want to handle OK/EXE events in that case. */ return false; @@ -210,13 +210,13 @@ bool VariableBoxController::selectLeaf(int selectedRow) { return true; } -I18n::Message VariableBoxController::nodeLabelAtIndex(int index) { +I18n::Message MathVariableBoxController::nodeLabelAtIndex(int index) { assert(m_currentPage == Page::RootMenu); I18n::Message labels[2] = {I18n::Message::Expressions, I18n::Message::Functions}; return labels[index]; } -Layout VariableBoxController::expressionLayoutForRecord(Storage::Record record, int index) { +Layout MathVariableBoxController::expressionLayoutForRecord(Storage::Record record, int index) { assert(m_currentPage != Page::RootMenu); assert(index >= 0); if (index >= m_firstMemoizedLayoutIndex+k_maxNumberOfDisplayedRows || index < m_firstMemoizedLayoutIndex) { @@ -246,30 +246,30 @@ Layout VariableBoxController::expressionLayoutForRecord(Storage::Record record, return m_layouts[index-m_firstMemoizedLayoutIndex]; } -const char * VariableBoxController::extension() const { +const char * MathVariableBoxController::extension() const { assert(m_currentPage != Page::RootMenu); return m_currentPage == Page::Function ? Ion::Storage::funcExtension : Ion::Storage::expExtension; } -Storage::Record VariableBoxController::recordAtIndex(int rowIndex) { +Storage::Record MathVariableBoxController::recordAtIndex(int rowIndex) { assert(m_currentPage != Page::RootMenu); assert(!Storage::sharedStorage()->recordWithExtensionAtIndex(extension(), rowIndex).isNull()); return Storage::sharedStorage()->recordWithExtensionAtIndex(extension(), rowIndex); } -ViewController * VariableBoxController::emptyViewController() { - m_emptyViewController.setType((VariableBoxEmptyController::Type)m_currentPage); +ViewController * MathVariableBoxController::emptyViewController() { + m_emptyViewController.setType((MathVariableBoxEmptyController::Type)m_currentPage); return &m_emptyViewController; } -void VariableBoxController::resetMemoization() { +void MathVariableBoxController::resetMemoization() { for (int i = 0; i < k_maxNumberOfDisplayedRows; i++) { m_layouts[i] = Layout(); } m_firstMemoizedLayoutIndex = 0; } -void VariableBoxController::destroyRecordAtRowIndex(int rowIndex) { +void MathVariableBoxController::destroyRecordAtRowIndex(int rowIndex) { // Destroy the record recordAtIndex(rowIndex).destroy(); // Shift the memoization if needed diff --git a/apps/variable_box_controller.h b/apps/math_variable_box_controller.h similarity index 88% rename from apps/variable_box_controller.h rename to apps/math_variable_box_controller.h index affb031fd..25bb29703 100644 --- a/apps/variable_box_controller.h +++ b/apps/math_variable_box_controller.h @@ -1,15 +1,13 @@ -#ifndef APPS_VARIABLE_BOX_CONTROLLER_H -#define APPS_VARIABLE_BOX_CONTROLLER_H - -#define MATRIX_VARIABLES 1 +#ifndef APPS_MATH_VARIABLE_BOX_CONTROLLER_H +#define APPS_MATH_VARIABLE_BOX_CONTROLLER_H #include "alternate_empty_nested_menu_controller.h" -#include "variable_box_empty_controller.h" +#include "math_variable_box_empty_controller.h" #include -class VariableBoxController : public AlternateEmptyNestedMenuController { +class MathVariableBoxController : public AlternateEmptyNestedMenuController { public: - VariableBoxController(); + MathVariableBoxController(); // View Controller void viewWillAppear() override; @@ -32,6 +30,7 @@ public: Function = 2 }; void lockDeleteEvent(Page page) { m_lockPageDelete = page; } + private: constexpr static int k_maxNumberOfDisplayedRows = (Ion::Display::Height - Metric::TitleBarHeight - Metric::PopUpTopMargin - Metric::StackTitleHeight) / Metric::ToolboxRowHeight + 2; // (240 - 18 - 50 - 20) / 40 = 3.8; the 0.8 cell can be above and below so we add +2 to get 5 constexpr static int k_numberOfMenuRows = 2; @@ -55,7 +54,7 @@ private: Page m_lockPageDelete; ExpressionTableCellWithExpression m_leafCells[k_maxNumberOfDisplayedRows]; MessageTableCellWithChevron m_nodeCells[k_numberOfMenuRows]; - VariableBoxEmptyController m_emptyViewController; + MathVariableBoxEmptyController m_emptyViewController; // Layout memoization // TODO: make a helper doing the RingMemoizationOfConsecutiveObjets to factorize this code and ExpressionModelStore code int m_firstMemoizedLayoutIndex; diff --git a/apps/math_variable_box_empty_controller.cpp b/apps/math_variable_box_empty_controller.cpp new file mode 100644 index 000000000..f36380d99 --- /dev/null +++ b/apps/math_variable_box_empty_controller.cpp @@ -0,0 +1,53 @@ +#include "math_variable_box_empty_controller.h" +#include +#include +#include + +MathVariableBoxEmptyController::MathVariableBoxEmptyView::MathVariableBoxEmptyView() : + VariableBoxEmptyView(), + m_layoutExample(0.5f, 0.5f, KDColorBlack, Palette::WallScreen) +{ + initMessageViews(); +} + +void MathVariableBoxEmptyController::MathVariableBoxEmptyView::setLayout(Poincare::Layout layout) { + m_layoutExample.setLayout(layout); +} + +void MathVariableBoxEmptyController::viewDidDisappear() { + m_view.setLayout(Poincare::Layout()); +} + +void MathVariableBoxEmptyController::setType(Type type) { + I18n::Message messages[MathVariableBoxEmptyView::k_numberOfMessages] = { + I18n::Message::Default, + I18n::Message::Default, + I18n::Message::Default, + I18n::Message::EnableCharacters + }; + Poincare::Layout layout; + switch (type) { + case Type::Expressions: + { + messages[0] = I18n::Message::EmptyExpressionBox0; + messages[1] = I18n::Message::EmptyExpressionBox1; + messages[2] = I18n::Message::EmptyExpressionBox2; + const char * storeExpression = "3→A"; + layout = Poincare::LayoutHelper::String(storeExpression, strlen(storeExpression), MathVariableBoxEmptyView::k_font); + break; + } + case Type::Functions: + { + messages[0] = I18n::Message::EmptyFunctionBox0; + messages[1] = I18n::Message::EmptyFunctionBox1; + messages[2] = I18n::Message::EmptyFunctionBox2; + const char * storeFunction = "3+x→f(x)"; + layout = Poincare::LayoutHelper::String(storeFunction, strlen(storeFunction), MathVariableBoxEmptyView::k_font); + break; + } + default: + assert(false); + } + m_view.setMessages(messages); + m_view.setLayout(layout); +} diff --git a/apps/math_variable_box_empty_controller.h b/apps/math_variable_box_empty_controller.h new file mode 100644 index 000000000..9083b3bca --- /dev/null +++ b/apps/math_variable_box_empty_controller.h @@ -0,0 +1,41 @@ +#ifndef APPS_MATH_VARIABLE_BOX_EMPTY_CONTROLLER_H +#define APPS_MATH_VARIABLE_BOX_EMPTY_CONTROLLER_H + +#include +#include "variable_box_empty_controller.h" + +class MathVariableBoxEmptyController : public VariableBoxEmptyController { +public: + MathVariableBoxEmptyController() : + VariableBoxEmptyController(), + m_view() + {} + enum class Type { + None = 0, + Expressions = 1, + Functions = 2 + }; + void setType(Type type); + // View Controller + View * view() override { return &m_view; } + void viewDidDisappear() override; +private: + class MathVariableBoxEmptyView : public VariableBoxEmptyView { + public: + constexpr static int k_numberOfMessages = 4; + MathVariableBoxEmptyView(); + void setLayout(Poincare::Layout layout); + private: + int numberOfMessageTextViews() const override { return k_numberOfMessages; } + MessageTextView * messageTextViewAtIndex(int index) override { + assert(index >= 0 && index < k_numberOfMessages); + return &m_messages[index]; + } + ExpressionView * expressionView() override { return &m_layoutExample; } + MessageTextView m_messages[k_numberOfMessages]; + ExpressionView m_layoutExample; + }; + MathVariableBoxEmptyView m_view; +}; + +#endif diff --git a/apps/shared/input_event_handler_delegate_app.cpp b/apps/shared/input_event_handler_delegate_app.cpp index cc9b5d525..53c49047c 100644 --- a/apps/shared/input_event_handler_delegate_app.cpp +++ b/apps/shared/input_event_handler_delegate_app.cpp @@ -20,9 +20,9 @@ Toolbox * InputEventHandlerDelegateApp::toolboxForInputEventHandler(InputEventHa } NestedMenuController * InputEventHandlerDelegateApp::variableBoxForInputEventHandler(InputEventHandler * textInput) { - VariableBoxController * varBox = AppsContainer::sharedAppsContainer()->variableBoxController(); + MathVariableBoxController * varBox = AppsContainer::sharedAppsContainer()->variableBoxController(); varBox->setSender(textInput); - varBox->lockDeleteEvent(VariableBoxController::Page::RootMenu); + varBox->lockDeleteEvent(MathVariableBoxController::Page::RootMenu); return varBox; } diff --git a/apps/variable_box_empty_controller.cpp b/apps/variable_box_empty_controller.cpp index 9f96fd021..a07a8d23d 100644 --- a/apps/variable_box_empty_controller.cpp +++ b/apps/variable_box_empty_controller.cpp @@ -3,29 +3,28 @@ #include #include -using namespace Poincare; -using namespace Ion; - -VariableBoxEmptyController::VariableBoxEmptyView::VariableBoxEmptyView() : - m_layoutExample(0.5f, 0.5f, KDColorBlack, Palette::WallScreen) -{ - for (int i = 0; i < k_numberOfMessages; i++) { - m_messages[i].setFont(k_font); - m_messages[i].setAlignment(0.5f, 0.5f); - m_messages[i].setBackgroundColor(Palette::WallScreen); - } - m_messages[0].setAlignment(0.5f,1.0f); - m_messages[k_numberOfMessages-1].setAlignment(0.5f,0.0f); -} - -void VariableBoxEmptyController::VariableBoxEmptyView::setMessages(I18n::Message * message) { - for (int i = 0; i < k_numberOfMessages; i++) { - m_messages[i].setMessage(message[i]); +// VariableBoxEmptyController::VariableBoxEmptyView +void VariableBoxEmptyController::VariableBoxEmptyView::initMessageViews() { + const int numberOfMessageViews = numberOfMessageTextViews(); + for (int i = 0; i < numberOfMessageViews; i++) { + MessageTextView * message = messageTextViewAtIndex(i); + message->setFont(k_font); + message->setBackgroundColor(Palette::WallScreen); + float verticalAlignment = 0.5f; + if (i == 0) { + verticalAlignment = 1.0f; + } else if (i == numberOfMessageViews - 1) { + verticalAlignment = 0.0f; + } + message->setAlignment(0.5f, verticalAlignment); } } -void VariableBoxEmptyController::VariableBoxEmptyView::setLayout(Poincare::Layout layout) { - m_layoutExample.setLayout(layout); +void VariableBoxEmptyController::VariableBoxEmptyView::setMessages(I18n::Message * message) { + const int numberOfMessageViews = numberOfMessageTextViews(); + for (int i = 0; i < numberOfMessageViews; i++) { + messageTextViewAtIndex(i)->setMessage(message[i]); + } } void VariableBoxEmptyController::VariableBoxEmptyView::drawRect(KDContext * ctx, KDRect rect) const { @@ -33,76 +32,48 @@ void VariableBoxEmptyController::VariableBoxEmptyView::drawRect(KDContext * ctx, } int VariableBoxEmptyController::VariableBoxEmptyView::numberOfSubviews() const { - return k_numberOfMessages+1; + return numberOfMessageTextViews() + hasExpressionView(); } View * VariableBoxEmptyController::VariableBoxEmptyView::subviewAtIndex(int index) { - if (index == k_layoutRowIndex) { - return &m_layoutExample; + if (hasExpressionView()) { + if (index == k_expressionViewRowIndex) { + return expressionView(); + } + return messageTextViewAtIndex(index + (index < k_expressionViewRowIndex ? 0 : -1)); } - if (index < k_layoutRowIndex) { - return &m_messages[index]; - } - return &m_messages[index-1]; + return messageTextViewAtIndex(index); } void VariableBoxEmptyController::VariableBoxEmptyView::layoutSubviews(bool force) { - KDCoordinate width = bounds().width() - 2*k_separatorThickness; - KDCoordinate height = bounds().height() - 2*k_separatorThickness; + const int numberOfMessageViews = numberOfMessageTextViews(); + const bool hasExpression = hasExpressionView(); + KDCoordinate width = bounds().width() - 2 * k_separatorThickness; + KDCoordinate height = bounds().height() - 2 * k_separatorThickness; KDCoordinate textHeight = k_font->glyphSize().height(); - KDCoordinate layoutHeight = m_layoutExample.minimalSizeForOptimalDisplay().height(); - KDCoordinate margin = (height - k_numberOfMessages*textHeight-layoutHeight)/2; - m_layoutExample.setFrame(KDRect(k_separatorThickness, k_separatorThickness+margin+k_layoutRowIndex*textHeight, width, layoutHeight), force); + KDCoordinate layoutHeight = hasExpression ? expressionView()->minimalSizeForOptimalDisplay().height() : 0; + KDCoordinate margin = (height - numberOfMessageViews * textHeight - layoutHeight) / 2; + if (hasExpression) { + expressionView()->setFrame(KDRect( + k_separatorThickness, + k_separatorThickness + margin + k_expressionViewRowIndex * textHeight, + width, + layoutHeight), + force); + } KDCoordinate currentHeight = k_separatorThickness; - for (uint8_t i = 0; i < k_numberOfMessages; i++) { - if (i == k_layoutRowIndex) { + for (uint8_t i = 0; i < numberOfMessageViews; i++) { + if (hasExpression && i == k_expressionViewRowIndex) { currentHeight += layoutHeight; } - KDCoordinate h = i == 0 || i == k_numberOfMessages - 1 ? textHeight+margin : textHeight; - m_messages[i].setFrame(KDRect(k_separatorThickness, currentHeight, width, h), force); + KDCoordinate h = (i == 0 || i == numberOfMessageViews - 1) ? textHeight + margin : textHeight; + messageTextViewAtIndex(i)->setFrame(KDRect(k_separatorThickness, currentHeight, width, h), force); currentHeight += h; } } -VariableBoxEmptyController::VariableBoxEmptyController() : - ViewController(nullptr), - m_view() -{ -} +// VariableBoxEmptyController -View * VariableBoxEmptyController::view() { - return &m_view; -} - -void VariableBoxEmptyController::viewDidDisappear() { - m_view.setLayout(Layout()); -} - -void VariableBoxEmptyController::setType(Type type) { - I18n::Message messages[VariableBoxEmptyView::k_numberOfMessages] = {I18n::Message::Default, I18n::Message::Default, I18n::Message::Default, I18n::Message::EnableCharacters}; - Layout layout; - switch (type) { - case Type::Expressions: - { - messages[0] = I18n::Message::EmptyExpressionBox0; - messages[1] = I18n::Message::EmptyExpressionBox1; - messages[2] = I18n::Message::EmptyExpressionBox2; - const char * storeExpression = "3→A"; - layout = LayoutHelper::String(storeExpression, strlen(storeExpression), VariableBoxEmptyView::k_font); - break; - } - case Type::Functions: - { - messages[0] = I18n::Message::EmptyFunctionBox0; - messages[1] = I18n::Message::EmptyFunctionBox1; - messages[2] = I18n::Message::EmptyFunctionBox2; - const char * storeFunction = "3+x→f(x)"; - layout = LayoutHelper::String(storeFunction, strlen(storeFunction), VariableBoxEmptyView::k_font); - break; - } - default: - assert(false); - } - m_view.setMessages(messages); - m_view.setLayout(layout); +void VariableBoxEmptyController::setMessages(I18n::Message * messages) { + static_cast(view())->setMessages(messages); } diff --git a/apps/variable_box_empty_controller.h b/apps/variable_box_empty_controller.h index 683c63a9b..4218801fb 100644 --- a/apps/variable_box_empty_controller.h +++ b/apps/variable_box_empty_controller.h @@ -9,36 +9,29 @@ class VariableBoxEmptyController : public ViewController { public: - VariableBoxEmptyController(); - enum class Type { - None = 0, - Expressions = 1, - Functions = 2 - }; + VariableBoxEmptyController() : ViewController(nullptr) {} + void setMessages(I18n::Message * messages); // View Controller - View * view() override; DisplayParameter displayParameter() override { return DisplayParameter::DoNotShowOwnTitle; } - void viewDidDisappear() override; - - void setType(Type type); -private: +protected: class VariableBoxEmptyView : public View, public Bordered { public: - static constexpr const KDFont * k_font = KDFont::SmallFont; - VariableBoxEmptyView(); + constexpr static const KDFont * k_font = KDFont::SmallFont; + void initMessageViews(); void setMessages(I18n::Message * message); - void setLayout(Poincare::Layout layout); void drawRect(KDContext * ctx, KDRect rect) const override; - constexpr static int k_numberOfMessages = 4; private: + constexpr static int k_expressionViewRowIndex = 2; int numberOfSubviews() const override; View * subviewAtIndex(int index) override; void layoutSubviews(bool force = false) override; - constexpr static int k_layoutRowIndex = 2; - MessageTextView m_messages[k_numberOfMessages]; - ExpressionView m_layoutExample; + virtual int numberOfMessageTextViews() const = 0; + virtual MessageTextView * messageTextViewAtIndex(int index) = 0; + bool hasExpressionView() const { + return const_cast(this)->expressionView() != nullptr; + } + virtual ExpressionView * expressionView() { return nullptr; } }; - VariableBoxEmptyView m_view; }; #endif