From 2e2845370aba9e761b29ddb8efeff8691ea86b3e Mon Sep 17 00:00:00 2001 From: Gabriel Ozouf Date: Mon, 21 Sep 2020 18:02:09 +0200 Subject: [PATCH] [apps/math_toolbox] Add fork nodes in tree Some nodes of the ToolboxMessageTree can be marked as "forks", dispatching one branch or the other depending on preferences. They are used in the Unit menu to provide a different toolbox depending on the unit system. Change-Id: I591f7abc3d24e682e827a540a9defac1877871b5 --- apps/math_toolbox.cpp | 11 +++++++++++ apps/math_toolbox.h | 2 ++ escher/include/escher/toolbox.h | 5 ++++- escher/include/escher/toolbox_message_tree.h | 9 +++++---- escher/src/toolbox.cpp | 15 +++++++++------ 5 files changed, 31 insertions(+), 11 deletions(-) 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();