diff --git a/apps/math_toolbox.cpp b/apps/math_toolbox.cpp index 00a32610a..f5dd35a86 100644 --- a/apps/math_toolbox.cpp +++ b/apps/math_toolbox.cpp @@ -1,4 +1,5 @@ #include "math_toolbox.h" +#include "global_preferences.h" #include "./shared/toolbox_helpers.h" #include #include @@ -384,3 +385,13 @@ MessageTableCellWithChevron* MathToolbox::nodeCellAtIndex(int index) { int MathToolbox::maxNumberOfDisplayedRows() { return k_maxNumberOfDisplayedRows; } + +int MathToolbox::indexAfterFork() const { + Preferences::UnitFormat unitFormat = GlobalPreferences::sharedGlobalPreferences()->unitFormat(); + if (unitFormat == Preferences::UnitFormat::Metric) { + return 0; + } + assert(unitFormat == Preferences::UnitFormat::Imperial); + return 1; +} + diff --git a/apps/math_toolbox.h b/apps/math_toolbox.h index 77bc6bd56..41eb996fa 100644 --- a/apps/math_toolbox.h +++ b/apps/math_toolbox.h @@ -15,6 +15,8 @@ protected: int maxNumberOfDisplayedRows() override; constexpr static int k_maxNumberOfDisplayedRows = 6; // = 240/40 private: + int indexAfterFork() const override; + MessageTableCellWithMessage m_leafCells[k_maxNumberOfDisplayedRows]; MessageTableCellWithChevron m_nodeCells[k_maxNumberOfDisplayedRows]; }; diff --git a/escher/include/escher/toolbox.h b/escher/include/escher/toolbox.h index e38df51ed..f128f54eb 100644 --- a/escher/include/escher/toolbox.h +++ b/escher/include/escher/toolbox.h @@ -25,9 +25,12 @@ protected: bool returnToPreviousMenu() override; virtual int maxNumberOfDisplayedRows() = 0; virtual const ToolboxMessageTree * rootModel() const = 0; + /* indexAfterFork is called when a fork-node is encountered to choose which + * of its children should be selected, based on external context. */ + virtual int indexAfterFork() const { assert(false); return 0; }; MessageTableCellWithMessage * leafCellAtIndex(int index) override = 0; MessageTableCellWithChevron * nodeCellAtIndex(int index) override = 0; - mutable ToolboxMessageTree * m_messageTreeModel; + mutable const ToolboxMessageTree * m_messageTreeModel; /* m_messageTreeModel points at the messageTree of the tree (describing the * whole model) where we are located. It enables to know which rows are leaves * and which are subtrees. */ diff --git a/escher/include/escher/toolbox_message_tree.h b/escher/include/escher/toolbox_message_tree.h index 1e17b83b0..ba8ac5005 100644 --- a/escher/include/escher/toolbox_message_tree.h +++ b/escher/include/escher/toolbox_message_tree.h @@ -15,23 +15,23 @@ public: stripInsertedText); }; template - constexpr static ToolboxMessageTree Node(I18n::Message label, const ToolboxMessageTree (&children)[N]) { + constexpr static ToolboxMessageTree Node(I18n::Message label, const ToolboxMessageTree (&children)[N], bool fork = false) { return ToolboxMessageTree( label, (I18n::Message)0, (I18n::Message)0, children, - N, + fork ? -N : N, true); } template - constexpr static ToolboxMessageTree Node(I18n::Message label, const ToolboxMessageTree * (&children)[N]) { + constexpr static ToolboxMessageTree Node(I18n::Message label, const ToolboxMessageTree * (&children)[N], bool fork = false) { return ToolboxMessageTree( label, (I18n::Message)0, (I18n::Message)0, children, - N, + fork ? -N : N, true); } const MessageTree * childAtIndex(int index) const override { @@ -40,6 +40,7 @@ public: I18n::Message text() const { return m_text; } I18n::Message insertedText() const { return m_insertedText; } bool stripInsertedText() const { return m_stripInsertedText; } + bool isFork() const { return numberOfChildren() < 0; } private: constexpr ToolboxMessageTree(I18n::Message label, I18n::Message text, I18n::Message insertedText, const ToolboxMessageTree * children, int numberOfChildren, bool stripInsertedText) : MessageTree(label, numberOfChildren), diff --git a/escher/src/toolbox.cpp b/escher/src/toolbox.cpp index e4848e8bd..9fe23d8b5 100644 --- a/escher/src/toolbox.cpp +++ b/escher/src/toolbox.cpp @@ -39,7 +39,7 @@ void Toolbox::willDisplayCellForIndex(HighlightCell * cell, int index) { } int Toolbox::typeAtLocation(int i, int j) { - MessageTree * messageTree = (MessageTree *)m_messageTreeModel->childAtIndex(j); + const MessageTree * messageTree = m_messageTreeModel->childAtIndex(j); if (messageTree->numberOfChildren() == 0) { return LeafCellType; } @@ -48,7 +48,11 @@ int Toolbox::typeAtLocation(int i, int j) { bool Toolbox::selectSubMenu(int selectedRow) { m_selectableTableView.deselectTable(); - m_messageTreeModel = (ToolboxMessageTree *)m_messageTreeModel->childAtIndex(selectedRow); + m_messageTreeModel = static_cast(m_messageTreeModel->childAtIndex(selectedRow)); + if (m_messageTreeModel->isFork()) { + assert(m_messageTreeModel->numberOfChildren() < 0); + m_messageTreeModel = static_cast(m_messageTreeModel->childAtIndex(indexAfterFork())); + } return NestedMenuController::selectSubMenu(selectedRow); } @@ -56,15 +60,14 @@ bool Toolbox::returnToPreviousMenu() { m_selectableTableView.deselectTable(); int currentDepth = m_stack.depth(); int index = 0; - // We want to get the current ToolboxMessageTree's parent ToolboxMessageTree, - // but there is no ToolboxMessageTree::getParent() method. We thus have to - // start from the root ToolboxMessageTree and sequentially get the selected - // child until it has the wanted depth. ToolboxMessageTree * parentMessageTree = (ToolboxMessageTree *)rootModel(); Stack::State * previousState = m_stack.stateAtIndex(index++); while (currentDepth-- > 1) { parentMessageTree = (ToolboxMessageTree *)parentMessageTree->childAtIndex(previousState->selectedRow()); previousState = m_stack.stateAtIndex(index++); + if (parentMessageTree->isFork()) { + parentMessageTree = (ToolboxMessageTree *)parentMessageTree->childAtIndex(indexAfterFork()); + } } m_messageTreeModel = parentMessageTree; return NestedMenuController::returnToPreviousMenu();