mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[apps] Re implement variable box no to use node model
Change-Id: If7a75b900f0f2f5a152f7e28965555a12a14aba2
This commit is contained in:
@@ -1,84 +1,145 @@
|
||||
#include "variable_box_controller.h"
|
||||
#include "constant.h"
|
||||
#include "variable_box_node.h"
|
||||
#include <assert.h>
|
||||
|
||||
const VariableBoxNode numberChildren[10] = {VariableBoxNode("A"), VariableBoxNode("B"), VariableBoxNode("C"),
|
||||
VariableBoxNode("D"), VariableBoxNode("E"), VariableBoxNode("F"), VariableBoxNode("G"), VariableBoxNode("H"),
|
||||
VariableBoxNode("I"), VariableBoxNode("J")};
|
||||
const VariableBoxNode listChildren[10] = {VariableBoxNode("L1"), VariableBoxNode("L2"), VariableBoxNode("L3"),
|
||||
VariableBoxNode("L4"), VariableBoxNode("L5"), VariableBoxNode("L6"), VariableBoxNode("L7"), VariableBoxNode("L8"),
|
||||
VariableBoxNode("L9"), VariableBoxNode("L10")};
|
||||
const VariableBoxNode matriceChildren[10] = {VariableBoxNode("M1"), VariableBoxNode("M2"), VariableBoxNode("M3"),
|
||||
VariableBoxNode("M4"), VariableBoxNode("M5"), VariableBoxNode("M6"), VariableBoxNode("M7"), VariableBoxNode("M8"),
|
||||
VariableBoxNode("M9"), VariableBoxNode("M10")};
|
||||
const VariableBoxNode menu[3] = {VariableBoxNode("Nombres", numberChildren, 10), VariableBoxNode("Listes", listChildren, 10),
|
||||
VariableBoxNode("Matrices", matriceChildren, 10)};
|
||||
const VariableBoxNode variableBoxModel = VariableBoxNode("Variables", menu, 3);
|
||||
/* ContentViewController */
|
||||
|
||||
VariableBoxController::VariableBoxController(Context * context) :
|
||||
m_context(context)
|
||||
VariableBoxController::ContentViewController::ContentViewController(Responder * parentResponder, Context * context) :
|
||||
ViewController(parentResponder),
|
||||
m_context(context),
|
||||
m_firstSelectedRow(0),
|
||||
m_previousSelectedRow(0),
|
||||
m_currentPage(Page::RootMenu),
|
||||
m_selectableTableView(SelectableTableView(this, this))
|
||||
{
|
||||
}
|
||||
|
||||
const char * VariableBoxController::title() const {
|
||||
return "VariableBoxController";
|
||||
const char * VariableBoxController::ContentViewController::title() const {
|
||||
return "Variable";
|
||||
}
|
||||
|
||||
TableViewCell * VariableBoxController::leafCellAtIndex(int index) {
|
||||
return &m_leafCells[index];
|
||||
View * VariableBoxController::ContentViewController::view() {
|
||||
return &m_selectableTableView;
|
||||
}
|
||||
|
||||
TableViewCell * VariableBoxController::nodeCellAtIndex(int index) {
|
||||
void VariableBoxController::ContentViewController::didBecomeFirstResponder() {
|
||||
m_selectableTableView.reloadData();
|
||||
m_selectableTableView.selectCellAtLocation(0, m_firstSelectedRow);
|
||||
app()->setFirstResponder(&m_selectableTableView);
|
||||
}
|
||||
|
||||
bool VariableBoxController::ContentViewController::handleEvent(Ion::Events::Event event) {
|
||||
if (event == Ion::Events::Back) {
|
||||
if (m_currentPage == Page::RootMenu) {
|
||||
m_firstSelectedRow = 0;
|
||||
app()->dismissModalViewController();
|
||||
return true;
|
||||
}
|
||||
m_selectableTableView.deselectTable();
|
||||
m_firstSelectedRow = m_previousSelectedRow;
|
||||
m_currentPage = Page::RootMenu;
|
||||
app()->setFirstResponder(this);
|
||||
return true;
|
||||
}
|
||||
if (event == Ion::Events::OK) {
|
||||
int selectedRow = m_selectableTableView.selectedRow();
|
||||
m_selectableTableView.deselectTable();
|
||||
if (m_currentPage == Page::RootMenu) {
|
||||
m_previousSelectedRow = selectedRow;
|
||||
m_firstSelectedRow = 0;
|
||||
m_currentPage = pageAtIndex(selectedRow);
|
||||
app()->setFirstResponder(this);
|
||||
return true;
|
||||
}
|
||||
m_firstSelectedRow = 0;
|
||||
char label[3];
|
||||
putLabelAtIndexInBuffer(selectedRow, label);
|
||||
const char * editedText = label;
|
||||
m_textFieldCaller->insertTextAtLocation(editedText, m_textFieldCaller->cursorLocation());
|
||||
m_textFieldCaller->setCursorLocation(m_textFieldCaller->cursorLocation() + strlen(editedText));
|
||||
m_currentPage = Page::RootMenu;
|
||||
app()->dismissModalViewController();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int VariableBoxController::ContentViewController::numberOfRows() {
|
||||
switch (m_currentPage) {
|
||||
case Page::RootMenu:
|
||||
return 3;
|
||||
case Page::Scalar:
|
||||
return Context::k_maxNumberOfScalarExpressions;
|
||||
case Page::List:
|
||||
return Context::k_maxNumberOfListExpressions;
|
||||
case Page::Matrix:
|
||||
return Context::k_maxNumberOfMatrixExpressions;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
TableViewCell * VariableBoxController::ContentViewController::reusableCell(int index, int type) {
|
||||
assert(type < 2);
|
||||
assert(index >= 0);
|
||||
if (type == 0) {
|
||||
assert(index < k_maxNumberOfDisplayedRows);
|
||||
return &m_leafCells[index];
|
||||
}
|
||||
assert(index < k_numberOfMenuRows);
|
||||
return &m_nodeCells[index];
|
||||
}
|
||||
|
||||
void VariableBoxController::willDisplayCellForIndex(TableViewCell * cell, int index) {
|
||||
const Node * node = m_listViewController.nodeModel()->children(index);
|
||||
const char * label = node->label();
|
||||
if (node->numberOfChildren() > 0) {
|
||||
int VariableBoxController::ContentViewController::reusableCellCount(int type) {
|
||||
assert(type < 2);
|
||||
if (type == 0) {
|
||||
return k_maxNumberOfDisplayedRows;
|
||||
}
|
||||
return k_numberOfMenuRows;
|
||||
}
|
||||
|
||||
void VariableBoxController::ContentViewController::willDisplayCellForIndex(TableViewCell * cell, int index) {
|
||||
if (m_currentPage == Page::RootMenu) {
|
||||
const char * label = nodeLabelAtIndex(index);
|
||||
MenuListCell * myCell = (MenuListCell *)cell;
|
||||
myCell->setText(label);
|
||||
return;
|
||||
}
|
||||
const char * parentNodeLabel = m_listViewController.nodeModel()->label();
|
||||
VariableBoxLeafCell * myCell = (VariableBoxLeafCell *)cell;
|
||||
char label[3];
|
||||
putLabelAtIndexInBuffer(index, label);
|
||||
myCell->setLabel(label);
|
||||
const Expression * expression = m_context->scalarExpressionForIndex(index);
|
||||
if (strcmp(parentNodeLabel, "Matrices") == 0) {
|
||||
//expression = m_context->matrixExpressionForIndex(index);
|
||||
}
|
||||
if (strcmp(parentNodeLabel, "Listes") == 0) {
|
||||
//expression = m_context->listExpressionForIndex(index);
|
||||
const Expression * expression = expressionForIndex(index);
|
||||
if (m_currentPage == Page::Scalar) {
|
||||
myCell->displayExpression(false);
|
||||
char buffer[Constant::FloatBufferSizeInScientificMode];
|
||||
((Float *)expression)->convertFloatToText(buffer, Constant::FloatBufferSizeInScientificMode, Constant::NumberOfDigitsInMantissaInScientificMode);
|
||||
myCell->setSubtitle(buffer);
|
||||
return;
|
||||
}
|
||||
myCell->displayExpression(true);
|
||||
if (expression) {
|
||||
myCell->setExpression(expression->createLayout());
|
||||
}
|
||||
if (strcmp(parentNodeLabel, "Nombres") == 0) {
|
||||
myCell->setSubtitle("");
|
||||
} else {
|
||||
if (expression == nullptr) {
|
||||
myCell->setSubtitle("Vide");
|
||||
}
|
||||
// TODO: display the dimension of the list/matrice
|
||||
//myCell->setExpression(expression->createLayout());
|
||||
// TODO: display the dimensgion of the list/matrice as subtitle
|
||||
/* char buffer[4];
|
||||
* buffer[0] = (Matrice *)expression->dim(0);
|
||||
* buffer[1] = 'x';
|
||||
* buffer[2] = (Matrice *)expression->dim(1)
|
||||
* buffer[3] = 0;
|
||||
* myCell->setSubtitle(buffer);*/
|
||||
} else {
|
||||
myCell->setSubtitle("Vide");
|
||||
}
|
||||
}
|
||||
|
||||
KDCoordinate VariableBoxController::leafRowHeight(int index) {
|
||||
// TODO: add a constant to index if the node == matrice/liste
|
||||
const char * parentNodeLabel = m_listViewController.nodeModel()->label();
|
||||
const Expression * expression = m_context->scalarExpressionForIndex(index);
|
||||
if (strcmp(parentNodeLabel, "Matrices") == 0) {
|
||||
//expression = m_context->matrixExpressionForIndex(index);
|
||||
KDCoordinate VariableBoxController::ContentViewController::rowHeight(int index) {
|
||||
if (m_currentPage == Page::RootMenu) {
|
||||
return k_nodeRowHeight;
|
||||
}
|
||||
if (strcmp(parentNodeLabel, "Listes") == 0) {
|
||||
//expression = m_context->listExpressionForIndex(index);
|
||||
if (m_currentPage == Page::Scalar) {
|
||||
return k_leafRowHeight;
|
||||
}
|
||||
const Expression * expression = expressionForIndex(index);
|
||||
if (expression) {
|
||||
KDCoordinate expressionHeight = expression->createLayout()->size().height();
|
||||
return expressionHeight;
|
||||
@@ -86,15 +147,104 @@ KDCoordinate VariableBoxController::leafRowHeight(int index) {
|
||||
return k_leafRowHeight;
|
||||
}
|
||||
|
||||
Node * VariableBoxController::nodeModel() {
|
||||
return (Node *)&variableBoxModel;
|
||||
KDCoordinate VariableBoxController::ContentViewController::cumulatedHeightFromIndex(int j) {
|
||||
int result = 0;
|
||||
for (int k = 0; k < j; k++) {
|
||||
result += rowHeight(k);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool VariableBoxController::selectLeaf(Node * selectedNode){
|
||||
m_listViewController.deselectTable();
|
||||
const char * editedText = selectedNode->label();
|
||||
m_textFieldCaller->insertTextAtLocation(editedText, m_textFieldCaller->cursorLocation());
|
||||
m_textFieldCaller->setCursorLocation(m_textFieldCaller->cursorLocation() + strlen(editedText));
|
||||
app()->dismissModalViewController();
|
||||
return true;
|
||||
int VariableBoxController::ContentViewController::indexFromCumulatedHeight(KDCoordinate offsetY) {
|
||||
int result = 0;
|
||||
int j = 0;
|
||||
while (result < offsetY && j < numberOfRows()) {
|
||||
result += rowHeight(j++);
|
||||
}
|
||||
return (result < offsetY || offsetY == 0) ? j : j - 1;
|
||||
}
|
||||
|
||||
int VariableBoxController::ContentViewController::typeAtLocation(int i, int j) {
|
||||
if (m_currentPage == Page::RootMenu) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Expression * VariableBoxController::ContentViewController::expressionForIndex(int index) {
|
||||
if (m_currentPage == Page::Scalar) {
|
||||
const Symbol symbol = Symbol('A'+index);
|
||||
return m_context->expressionForSymbol(&symbol);
|
||||
}
|
||||
if (m_currentPage == Page::Matrix) {
|
||||
return nullptr;
|
||||
}
|
||||
if (m_currentPage == Page::List) {
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
VariableBoxController::ContentViewController::Page VariableBoxController::ContentViewController::pageAtIndex(int index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Page::Scalar;
|
||||
case 1:
|
||||
return Page::List;
|
||||
case 2:
|
||||
return Page::Matrix;
|
||||
default:
|
||||
assert(false);
|
||||
return Page::RootMenu;
|
||||
}
|
||||
}
|
||||
|
||||
void VariableBoxController::ContentViewController::putLabelAtIndexInBuffer(int index, char * buffer) {
|
||||
if (m_currentPage == Page::Scalar) {
|
||||
buffer[0] = 'A' + index;
|
||||
buffer[1] = 0;
|
||||
}
|
||||
if (m_currentPage == Page::List) {
|
||||
buffer[0] = 'L';
|
||||
buffer[1] = '0' + index;
|
||||
buffer[2] = 0;
|
||||
}
|
||||
if (m_currentPage == Page::Matrix) {
|
||||
buffer[0] = 'M';
|
||||
buffer[1] = '0' + index;
|
||||
buffer[2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const char * VariableBoxController::ContentViewController::nodeLabelAtIndex(int index) {
|
||||
assert(m_currentPage == Page::RootMenu);
|
||||
switch (index) {
|
||||
case 0:
|
||||
return "Nombre";
|
||||
case 1:
|
||||
return "Liste";
|
||||
case 2:
|
||||
return "Matrice";
|
||||
default:
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void VariableBoxController::ContentViewController::setTextFieldCaller(TextField * textField) {
|
||||
m_textFieldCaller = textField;
|
||||
}
|
||||
|
||||
VariableBoxController::VariableBoxController(Context * context) :
|
||||
StackViewController(nullptr, &m_contentViewController, true, KDColorWhite, Palette::BoxTitleBackgroundColor, Palette::BoxTitleBackgroundColor),
|
||||
m_contentViewController(ContentViewController(this, context))
|
||||
{
|
||||
}
|
||||
|
||||
void VariableBoxController::didBecomeFirstResponder() {
|
||||
app()->setFirstResponder(&m_contentViewController);
|
||||
}
|
||||
|
||||
void VariableBoxController::setTextFieldCaller(TextField * textField) {
|
||||
m_contentViewController.setTextFieldCaller(textField);
|
||||
}
|
||||
|
||||
@@ -3,24 +3,56 @@
|
||||
|
||||
#include <escher.h>
|
||||
#include <poincare.h>
|
||||
#include "node_navigation_controller.h"
|
||||
#include "variable_box_leaf_cell.h"
|
||||
|
||||
class VariableBoxController : public NodeNavigationController {
|
||||
class VariableBoxController : public StackViewController {
|
||||
public:
|
||||
VariableBoxController(Context * context);
|
||||
const char * title() const override;
|
||||
TableViewCell * leafCellAtIndex(int index) override;
|
||||
TableViewCell * nodeCellAtIndex(int index) override;
|
||||
void willDisplayCellForIndex(TableViewCell * cell, int index) override;
|
||||
KDCoordinate leafRowHeight(int index) override;
|
||||
void didBecomeFirstResponder() override;
|
||||
void setTextFieldCaller(TextField * textField);
|
||||
private:
|
||||
constexpr static KDCoordinate k_leafRowHeight = 40;
|
||||
Context * m_context;
|
||||
VariableBoxLeafCell m_leafCells[NodeListViewController::k_maxNumberOfDisplayedRows];
|
||||
ChevronMenuListCell m_nodeCells[NodeListViewController::k_maxNumberOfDisplayedRows];
|
||||
Node * nodeModel() override;
|
||||
bool selectLeaf(Node * selectedNode) override;
|
||||
class ContentViewController : public ViewController, public ListViewDataSource {
|
||||
public:
|
||||
ContentViewController(Responder * parentResponder, Context * context);
|
||||
View * view() override;
|
||||
const char * title() const override;
|
||||
void didBecomeFirstResponder() override;
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
int numberOfRows() override;
|
||||
TableViewCell * reusableCell(int index, int type) override;
|
||||
int reusableCellCount(int type) override;
|
||||
void willDisplayCellForIndex(TableViewCell * cell, int index) override;
|
||||
KDCoordinate rowHeight(int j) override;
|
||||
KDCoordinate cumulatedHeightFromIndex(int j) override;
|
||||
int indexFromCumulatedHeight(KDCoordinate offsetY) override;
|
||||
int typeAtLocation(int i, int j) override;
|
||||
void setTextFieldCaller(TextField * textField);
|
||||
private:
|
||||
enum class Page {
|
||||
RootMenu,
|
||||
Scalar,
|
||||
List,
|
||||
Matrix
|
||||
};
|
||||
constexpr static int k_maxNumberOfDisplayedRows = 6; //240/40
|
||||
constexpr static int k_numberOfMenuRows = 3; //240/40
|
||||
constexpr static KDCoordinate k_leafRowHeight = 40;
|
||||
constexpr static KDCoordinate k_nodeRowHeight = 40;
|
||||
Page pageAtIndex(int index);
|
||||
void putLabelAtIndexInBuffer(int index, char * buffer);
|
||||
const char * nodeLabelAtIndex(int index);
|
||||
const Expression * expressionForIndex(int index);
|
||||
|
||||
Context * m_context;
|
||||
TextField * m_textFieldCaller;
|
||||
int m_firstSelectedRow;
|
||||
int m_previousSelectedRow;
|
||||
Page m_currentPage;
|
||||
VariableBoxLeafCell m_leafCells[k_maxNumberOfDisplayedRows];
|
||||
ChevronMenuListCell m_nodeCells[k_numberOfMenuRows];
|
||||
SelectableTableView m_selectableTableView;
|
||||
};
|
||||
ContentViewController m_contentViewController;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,13 +3,18 @@
|
||||
|
||||
VariableBoxLeafCell::VariableBoxLeafCell() :
|
||||
TableViewCell(),
|
||||
m_labelView(PointerTextView(nullptr, 0, 0.5, KDColorBlack, Palette::CellBackgroundColor)),
|
||||
m_subtitleView(BufferTextView(0, 0.5, Palette::DesactiveTextColor, Palette::CellBackgroundColor))
|
||||
m_labelView(BufferTextView(0, 0.5, KDColorBlack, Palette::CellBackgroundColor)),
|
||||
m_subtitleView(BufferTextView(0, 0.5, Palette::DesactiveTextColor, Palette::CellBackgroundColor)),
|
||||
m_displayExpression(false)
|
||||
{
|
||||
}
|
||||
|
||||
void VariableBoxLeafCell::displayExpression(bool displayExpression) {
|
||||
m_displayExpression = displayExpression;
|
||||
}
|
||||
|
||||
int VariableBoxLeafCell::numberOfSubviews() const {
|
||||
if (strlen(m_subtitleView.text()) > 0) {
|
||||
if (m_displayExpression) {
|
||||
return 3;
|
||||
}
|
||||
return 2;
|
||||
@@ -20,22 +25,26 @@ View * VariableBoxLeafCell::subviewAtIndex(int index) {
|
||||
return &m_labelView;
|
||||
}
|
||||
if (index == 1) {
|
||||
return &m_expressionView;
|
||||
return &m_subtitleView;
|
||||
}
|
||||
assert(numberOfSubviews() == 3 && index == 2);
|
||||
return &m_subtitleView;
|
||||
return &m_expressionView;
|
||||
}
|
||||
|
||||
void VariableBoxLeafCell::layoutSubviews() {
|
||||
KDCoordinate width = bounds().width();
|
||||
KDCoordinate height = bounds().height();
|
||||
m_expressionView.setFrame(KDRect(width/2, 1, width/2-1, height-2));
|
||||
if (numberOfSubviews() == 3) {
|
||||
m_labelView.setFrame(KDRect(1, 1, width/2-1, height/2 - 1));
|
||||
m_subtitleView.setFrame(KDRect(1, height/2, width/2-1, height/2 - 1));
|
||||
m_subtitleView.setAlignment(0.0f, 0.5f);
|
||||
m_expressionView.setFrame(KDRect(width/2, 1, width/2-1, height-2));
|
||||
return;
|
||||
}
|
||||
m_labelView.setFrame(KDRect(1, 1, width/2-1, height-2));
|
||||
m_subtitleView.setFrame(KDRect(width/2, 1, width/2-1, height-2));
|
||||
m_subtitleView.setAlignment(1.0f, 0.5f);
|
||||
return;
|
||||
}
|
||||
|
||||
void VariableBoxLeafCell::reloadCell() {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
class VariableBoxLeafCell : public TableViewCell {
|
||||
public:
|
||||
VariableBoxLeafCell();
|
||||
void displayExpression(bool displayExpression);
|
||||
void reloadCell() override;
|
||||
void setLabel(const char * text);
|
||||
void setSubtitle(const char * text);
|
||||
@@ -15,9 +16,10 @@ private:
|
||||
int numberOfSubviews() const override;
|
||||
View * subviewAtIndex(int index) override;
|
||||
void layoutSubviews() override;
|
||||
PointerTextView m_labelView;
|
||||
BufferTextView m_labelView;
|
||||
BufferTextView m_subtitleView;
|
||||
ExpressionView m_expressionView;
|
||||
bool m_displayExpression;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user