[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
This commit is contained in:
Gabriel Ozouf
2020-09-21 18:02:09 +02:00
committed by Émilie Feral
parent 6105f44a46
commit 2e2845370a
5 changed files with 31 additions and 11 deletions

View File

@@ -1,4 +1,5 @@
#include "math_toolbox.h"
#include "global_preferences.h"
#include "./shared/toolbox_helpers.h"
#include <assert.h>
#include <string.h>
@@ -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;
}

View File

@@ -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];
};

View File

@@ -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. */

View File

@@ -15,23 +15,23 @@ public:
stripInsertedText);
};
template <int N>
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 <int N>
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),

View File

@@ -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<const ToolboxMessageTree *>(m_messageTreeModel->childAtIndex(selectedRow));
if (m_messageTreeModel->isFork()) {
assert(m_messageTreeModel->numberOfChildren() < 0);
m_messageTreeModel = static_cast<const ToolboxMessageTree *>(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();