From 51c33b0a5b5de52663a7a3d73cbb419a6598221a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Thu, 16 Feb 2017 14:17:56 +0100 Subject: [PATCH] [apps/sequence] Redesign list controller Change-Id: If114a643b0f682e98076cf1ec9f4479b3dafdfa6 --- apps/graph/Makefile | 1 - apps/graph/function_title_cell.cpp | 2 +- apps/graph/list/list_controller.cpp | 24 +- apps/graph/list/list_controller.h | 7 +- apps/sequence/Makefile | 5 +- .../list/change_type_parameter_controller.cpp | 90 ------- .../list/change_type_parameter_controller.h | 36 --- apps/sequence/list/list_controller.cpp | 232 +++++++++++++----- apps/sequence/list/list_controller.h | 24 +- .../list/list_parameter_controller.cpp | 37 +-- .../sequence/list/list_parameter_controller.h | 8 +- apps/sequence/list/sequence_cell.cpp | 74 ------ apps/sequence/list/sequence_cell.h | 32 --- .../list/sequence_expression_cell.cpp | 169 ------------- apps/sequence/list/sequence_expression_cell.h | 30 --- apps/sequence/list/sequence_title_cell.cpp | 128 ---------- apps/sequence/list/sequence_title_cell.h | 35 --- .../list/type_parameter_controller.cpp | 31 ++- .../sequence/list/type_parameter_controller.h | 6 +- apps/sequence/sequence.cpp | 59 ++++- apps/sequence/sequence.h | 7 + apps/sequence/sequence_title_cell.cpp | 51 ++++ apps/sequence/sequence_title_cell.h | 24 ++ apps/shared/Makefile | 1 + .../function_expression_cell.cpp | 2 +- .../function_expression_cell.h | 7 +- apps/shared/function_title_cell.cpp | 2 +- apps/shared/function_title_cell.h | 2 +- apps/shared/list_controller.cpp | 28 +-- apps/shared/list_controller.h | 3 +- apps/shared/list_parameter_controller.h | 2 +- 31 files changed, 419 insertions(+), 740 deletions(-) delete mode 100644 apps/sequence/list/change_type_parameter_controller.cpp delete mode 100644 apps/sequence/list/change_type_parameter_controller.h delete mode 100644 apps/sequence/list/sequence_cell.cpp delete mode 100644 apps/sequence/list/sequence_cell.h delete mode 100644 apps/sequence/list/sequence_expression_cell.cpp delete mode 100644 apps/sequence/list/sequence_expression_cell.h delete mode 100644 apps/sequence/list/sequence_title_cell.cpp delete mode 100644 apps/sequence/list/sequence_title_cell.h create mode 100644 apps/sequence/sequence_title_cell.cpp create mode 100644 apps/sequence/sequence_title_cell.h rename apps/{graph/list => shared}/function_expression_cell.cpp (98%) rename apps/{graph/list => shared}/function_expression_cell.h (82%) diff --git a/apps/graph/Makefile b/apps/graph/Makefile index e0791c3fa..5ee8f67c8 100644 --- a/apps/graph/Makefile +++ b/apps/graph/Makefile @@ -9,7 +9,6 @@ app_objs += $(addprefix apps/graph/,\ graph/graph_controller.o\ graph/graph_view.o\ graph/initialisation_parameter_controller.o\ - list/function_expression_cell.o\ list/list_controller.o\ values/abscissa_parameter_controller.o\ values/derivative_parameter_controller.o\ diff --git a/apps/graph/function_title_cell.cpp b/apps/graph/function_title_cell.cpp index f6d8aa8ee..3bf239b36 100644 --- a/apps/graph/function_title_cell.cpp +++ b/apps/graph/function_title_cell.cpp @@ -6,7 +6,7 @@ using namespace Shared; namespace Graph { FunctionTitleCell::FunctionTitleCell(Orientation orientation, KDText::FontSize size) : - Shared::FunctionTitleCell(orientation, size), + Shared::FunctionTitleCell(orientation), m_bufferTextView(size, 0.5f, 0.5f) { } diff --git a/apps/graph/list/list_controller.cpp b/apps/graph/list/list_controller.cpp index 90a807fa6..0e6f34ed4 100644 --- a/apps/graph/list/list_controller.cpp +++ b/apps/graph/list/list_controller.cpp @@ -18,6 +18,25 @@ const char * ListController::title() const { return "Fonctions"; } +int ListController::numberOfRows() { + if (m_functionStore->numberOfFunctions() == m_functionStore->maxNumberOfFunctions()) { + return m_functionStore->numberOfFunctions(); + } + return 1 + m_functionStore->numberOfFunctions(); +}; + +KDCoordinate ListController::rowHeight(int j) { + if (m_functionStore->numberOfFunctions() < m_functionStore->maxNumberOfFunctions() && j == numberOfRows() - 1) { + return k_emptyRowHeight; + } + Function * function = m_functionStore->functionAtIndex(j); + if (function->layout() == nullptr) { + return k_emptyRowHeight; + } + KDCoordinate functionSize = function->layout()->size().height(); + return functionSize + k_emptyRowHeight - KDText::stringSize(" ").height(); +} + bool ListController::handleEvent(Ion::Events::Event event) { if (Shared::ListController::handleEvent(event)) { return true; @@ -103,11 +122,6 @@ TableViewCell * ListController::expressionCells(int index) { return &m_expressionCells[index]; } -void ListController::configureFunction(Shared::Function * function) { - StackViewController * stack = stackController(); - parameterController()->setFunction(function); - stack->push(parameterController()); -} void ListController::willDisplayTitleCellAtIndex(TableViewCell * cell, int j) { FunctionTitleCell * myFunctionCell = (FunctionTitleCell *)cell; diff --git a/apps/graph/list/list_controller.h b/apps/graph/list/list_controller.h index 53b10b3a8..3969c191c 100644 --- a/apps/graph/list/list_controller.h +++ b/apps/graph/list/list_controller.h @@ -3,7 +3,7 @@ #include #include "../function_title_cell.h" -#include "function_expression_cell.h" +#include "../../shared/function_expression_cell.h" #include "../cartesian_function_store.h" #include "../../shared/new_function_cell.h" #include "../../shared/list_controller.h" @@ -15,6 +15,8 @@ class ListController : public Shared::ListController { public: ListController(Responder * parentResponder, CartesianFunctionStore * functionStore, HeaderViewController * header); const char * title() const override; + int numberOfRows() override; + KDCoordinate rowHeight(int j) override; bool handleEvent(Ion::Events::Event event) override; private: bool handleEnter(); @@ -23,12 +25,11 @@ private: int maxNumberOfRows() override; TableViewCell * titleCells(int index) override; TableViewCell * expressionCells(int index) override; - void configureFunction(Shared::Function * function); void willDisplayTitleCellAtIndex(TableViewCell * cell, int j) override; void willDisplayExpressionCellAtIndex(TableViewCell * cell, int j) override; constexpr static int k_maxNumberOfRows = 5; FunctionTitleCell m_functionTitleCells[k_maxNumberOfRows]; - FunctionExpressionCell m_expressionCells[k_maxNumberOfRows]; + Shared::FunctionExpressionCell m_expressionCells[k_maxNumberOfRows]; Shared::ListParameterController m_parameterController; }; diff --git a/apps/sequence/Makefile b/apps/sequence/Makefile index 77fb0b83f..f86d2de35 100644 --- a/apps/sequence/Makefile +++ b/apps/sequence/Makefile @@ -1,15 +1,12 @@ app_objs += $(addprefix apps/sequence/,\ app.o\ - list/change_type_parameter_controller.o\ list/list_controller.o\ list/list_parameter_controller.o\ list/type_parameter_controller.o\ - list/sequence_cell.o\ - list/sequence_expression_cell.o\ - list/sequence_title_cell.o\ values/values_controller.o\ sequence.o\ sequence_store.o\ + sequence_title_cell.o\ sequence_toolbox.o\ ) diff --git a/apps/sequence/list/change_type_parameter_controller.cpp b/apps/sequence/list/change_type_parameter_controller.cpp deleted file mode 100644 index 730e4d0ba..000000000 --- a/apps/sequence/list/change_type_parameter_controller.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "change_type_parameter_controller.h" -#include -#include "../../../poincare/src/layout/baseline_relative_layout.h" -#include "../../../poincare/src/layout/string_layout.h" - -using namespace Poincare; - -namespace Sequence { - -ChangeTypeParameterController::ChangeTypeParameterController(Responder * parentResponder) : - ViewController(parentResponder), - m_selectableTableView(SelectableTableView(this, this, Metric::TopMargin, Metric::RightMargin, - Metric::BottomMargin, Metric::LeftMargin)), - m_sequence(nullptr) -{ -} - -ChangeTypeParameterController::~ChangeTypeParameterController() { - for (int i = 0; i < k_totalNumberOfCell; i++) { - if (m_expressionLayouts[i]) { - delete m_expressionLayouts[i]; - m_expressionLayouts[i] = nullptr; - } - } -} - -const char * ChangeTypeParameterController::title() const { - return "Type de suite"; -} - -View * ChangeTypeParameterController::view() { - return &m_selectableTableView; -} - -void ChangeTypeParameterController::didBecomeFirstResponder() { - m_selectableTableView.reloadData(); - m_selectableTableView.selectCellAtLocation(0, 0); - app()->setFirstResponder(&m_selectableTableView); -} - -bool ChangeTypeParameterController::handleEvent(Ion::Events::Event event) { - if (event == Ion::Events::OK && m_sequence != nullptr) { - m_sequence->setType((Sequence::Type)m_selectableTableView.selectedRow()); - StackViewController * stack = stackController(); - stack->pop(); - return true; - } - return false; -} - -int ChangeTypeParameterController::numberOfRows() { - return k_totalNumberOfCell; -}; - -TableViewCell * ChangeTypeParameterController::reusableCell(int index) { - assert(index >= 0); - assert(index < k_totalNumberOfCell); - TableViewCell * cells[] = {&m_expliciteCell, &m_singleRecurrenceCell, &m_doubleRecurenceCell}; - return cells[index]; -} - -int ChangeTypeParameterController::reusableCellCount() { - return k_totalNumberOfCell; -} - -KDCoordinate ChangeTypeParameterController::cellHeight() { - return Metric::ParameterCellHeight; -} - -void ChangeTypeParameterController::willDisplayCellAtLocation(TableViewCell * cell, int i, int j) { - const char * name = m_sequence->name(); - const char * subscripts[3] = {"n", "n+1", "n+2"}; - if (m_expressionLayouts[j]) { - delete m_expressionLayouts[j]; - m_expressionLayouts[j] = nullptr; - } - m_expressionLayouts[j] = new BaselineRelativeLayout(new StringLayout(name, 1), new StringLayout(subscripts[j], strlen(subscripts[j]), KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript); - TextExpressionMenuListCell * myCell = (TextExpressionMenuListCell *)cell; - myCell->setExpression(m_expressionLayouts[j]); -} - -void ChangeTypeParameterController::setSequence(Sequence * sequence) { - m_sequence = sequence; -} - -StackViewController * ChangeTypeParameterController::stackController() const { - return (StackViewController *)parentResponder(); -} - -} diff --git a/apps/sequence/list/change_type_parameter_controller.h b/apps/sequence/list/change_type_parameter_controller.h deleted file mode 100644 index 90454a68e..000000000 --- a/apps/sequence/list/change_type_parameter_controller.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef SEQUENCE_CHANGE_TYPE_PARAMATER_CONTROLLER_H -#define SEQUENCE_CHANGE_TYPE_PARAMATER_CONTROLLER_H - -#include -#include "../sequence_store.h" - -namespace Sequence { - -class ChangeTypeParameterController : public ViewController, public SimpleListViewDataSource { -public: - ChangeTypeParameterController(Responder * parentResponder); - ~ChangeTypeParameterController(); - const char * title() const override; - View * view() override; - void didBecomeFirstResponder() override; - bool handleEvent(Ion::Events::Event event) override; - int numberOfRows() override; - KDCoordinate cellHeight() override; - TableViewCell * reusableCell(int index) override; - int reusableCellCount() override; - void willDisplayCellAtLocation(TableViewCell * cell, int i, int j) override; - void setSequence(Sequence * sequence); -private: - StackViewController * stackController() const; - constexpr static int k_totalNumberOfCell = 3; - ExpressionMenuListCell m_expliciteCell; - ExpressionMenuListCell m_singleRecurrenceCell; - ExpressionMenuListCell m_doubleRecurenceCell; - Poincare::ExpressionLayout * m_expressionLayouts[k_totalNumberOfCell]; - SelectableTableView m_selectableTableView; - Sequence * m_sequence; -}; - -} - -#endif diff --git a/apps/sequence/list/list_controller.cpp b/apps/sequence/list/list_controller.cpp index b2c2d11a1..4298a74bb 100644 --- a/apps/sequence/list/list_controller.cpp +++ b/apps/sequence/list/list_controller.cpp @@ -1,91 +1,153 @@ #include "list_controller.h" +#include "../app.h" #include using namespace Shared; +using namespace Poincare; namespace Sequence { ListController::ListController(Responder * parentResponder, SequenceStore * sequenceStore, HeaderViewController * header) : Shared::ListController(parentResponder, sequenceStore, header, "Ajouter une suite"), - m_functionTitleCells{SequenceTitleCell(&m_selectableTableView, &m_parameterController),SequenceTitleCell(&m_selectableTableView, &m_parameterController),SequenceTitleCell(&m_selectableTableView, &m_parameterController)}, - m_expressionCells{SequenceExpressionCell(&m_selectableTableView),SequenceExpressionCell(&m_selectableTableView),SequenceExpressionCell(&m_selectableTableView)}, + m_sequenceStore(sequenceStore), + m_sequenceTitleCells{SequenceTitleCell(FunctionTitleCell::Orientation::VerticalIndicator), SequenceTitleCell(FunctionTitleCell::Orientation::VerticalIndicator), SequenceTitleCell(FunctionTitleCell::Orientation::VerticalIndicator), + SequenceTitleCell(FunctionTitleCell::Orientation::VerticalIndicator), SequenceTitleCell(FunctionTitleCell::Orientation::VerticalIndicator), SequenceTitleCell(FunctionTitleCell::Orientation::VerticalIndicator), SequenceTitleCell(FunctionTitleCell::Orientation::VerticalIndicator), + SequenceTitleCell(FunctionTitleCell::Orientation::VerticalIndicator), SequenceTitleCell(FunctionTitleCell::Orientation::VerticalIndicator)}, m_parameterController(ListParameterController(this, sequenceStore)), m_typeParameterController(this, sequenceStore), m_typeStackController(StackViewController(nullptr, &m_typeParameterController, true, KDColorWhite, Palette::PurpleDark, Palette::PurpleDark)) { - m_selectableTableView.setDelegate(this); } const char * ListController::title() const { return "Suites"; } +int ListController::numberOfRows() { + int numberOfRows = 0; + for (int i = 0; i < m_sequenceStore->numberOfFunctions(); i++) { + Sequence * sequence = m_sequenceStore->functionAtIndex(i); + numberOfRows += sequence->numberOfElements(); + } + if (m_sequenceStore->numberOfFunctions() == m_sequenceStore->maxNumberOfFunctions()) { + return numberOfRows; + } + return 1 + numberOfRows; +}; + KDCoordinate ListController::rowHeight(int j) { - if (m_functionStore->numberOfFunctions() < m_functionStore->maxNumberOfFunctions() && j == numberOfRows() - 1) { + if (m_sequenceStore->numberOfFunctions() < m_sequenceStore->maxNumberOfFunctions() && j == numberOfRows() - 1) { return k_emptyRowHeight; } - Sequence * sequence = ((SequenceStore *)m_functionStore)->functionAtIndex(j); - KDCoordinate height = 0; + Sequence * sequence = m_sequenceStore->functionAtIndex(sequenceIndexForRow(j)); KDCoordinate defaultHeight = sequence->type() == Sequence::Type::Explicite ? k_emptyRowHeight : k_emptySubRowHeight; - if (sequence->layout() == nullptr) { - height += defaultHeight; - } else { - KDCoordinate size = sequence->layout()->size().height(); - height += size + defaultHeight - KDText::stringSize(" ").height(); + ExpressionLayout * layout = sequence->layout(); + if (sequenceDefinitionForRow(j) == 1) { + layout = sequence->firstInitialConditionLayout(); } - if ((int)sequence->type() > 0) { - if (sequence->firstInitialConditionLayout() == nullptr) { - height += defaultHeight; - } else { - KDCoordinate size = sequence->firstInitialConditionLayout()->size().height(); - height += size + defaultHeight - KDText::stringSize(" ").height(); - } + if (sequenceDefinitionForRow(j) == 2) { + layout = sequence->secondInitialConditionLayout(); } - if ((int)sequence->type() > 1) { - if (sequence->secondInitialConditionLayout() == nullptr) { - height += defaultHeight; - } else { - KDCoordinate size = sequence->secondInitialConditionLayout()->size().height(); - height += size + defaultHeight - KDText::stringSize(" ").height(); - } + if (layout == nullptr) { + return defaultHeight; } - return height; + KDCoordinate sequenceSize = layout->size().height(); + return sequenceSize + defaultHeight - KDText::stringSize(" ").height(); +} + +void ListController::willDisplayCellAtLocation(TableViewCell * cell, int i, int j) { + Shared::ListController::willDisplayCellAtLocation(cell, i, j); + EvenOddCell * myCell = (EvenOddCell *)cell; + myCell->setEven(sequenceIndexForRow(j)%2 == 0); } bool ListController::handleEvent(Ion::Events::Event event) { if (Shared::ListController::handleEvent(event)) { return true; } - if (event == Ion::Events::OK && m_selectableTableView.selectedColumn() == 1 - && m_selectableTableView.selectedRow() == numberOfRows() - 1) { - m_selectableTableView.reloadData(); - app()->displayModalViewController(&m_typeStackController, 0.f, 0.f, 32, 20, 20, 20); - return true; + if (event == Ion::Events::OK) { + return handleEnter(); } - return false; + if ((!event.hasText() && event != Ion::Events::XNT) + || m_selectableTableView.selectedColumn() == 0 + || m_selectableTableView.selectedRow() == numberOfRows() - 1) { + return false; + } + Sequence * sequence = m_sequenceStore->functionAtIndex(sequenceIndexForRow(m_selectableTableView.selectedRow())); + editExpression(sequence, sequenceDefinitionForRow(m_selectableTableView.selectedRow()), event); + return true; } -void ListController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) { - if (m_functionStore->numberOfFunctions() == m_functionStore->maxNumberOfFunctions() || t->selectedRow() < numberOfRows() - 1) { - if (t->selectedRow() == -1) { - return; - } - SequenceCell * myCell = (SequenceCell *)t->cellAtLocation(t->selectedColumn(), t->selectedRow()); - app()->setFirstResponder(myCell); - if (t->selectedRow() == previousSelectedCellY) { - SequenceCell * otherCell = (SequenceCell *)t->cellAtLocation(previousSelectedCellX, previousSelectedCellY); - myCell->selectSubCell(otherCell->selectedSubCell()); - } else { - if (t->selectedRow() < previousSelectedCellY) { - myCell->selectSubCell(myCell->numberOfSubCells()-1); - } else { - myCell->selectSubCell(0); +bool ListController::handleEnter() { + switch (m_selectableTableView.selectedColumn()) { + case 0: + { + if (m_sequenceStore->numberOfFunctions() < m_sequenceStore->maxNumberOfFunctions() && + m_selectableTableView.selectedRow() == numberOfRows() - 1) { + return true; } + configureFunction(m_functionStore->functionAtIndex(sequenceIndexForRow(m_selectableTableView.selectedRow()))); + return true; } - } else { - if (app()->firstResponder() != t) { - app()->setFirstResponder(t); + case 1: + { + if (m_sequenceStore->numberOfFunctions() < m_sequenceStore->maxNumberOfFunctions() && + m_selectableTableView.selectedRow() == numberOfRows() - 1) { + app()->displayModalViewController(&m_typeStackController, 0.f, 0.f, 32, 20, 20, 20); + return true; + } + Sequence * sequence = m_sequenceStore->functionAtIndex(sequenceIndexForRow(m_selectableTableView.selectedRow())); + editExpression(sequence, sequenceDefinitionForRow(m_selectableTableView.selectedRow()), Ion::Events::OK); + return true; } + default: + { + return false; + } + } +} + +void ListController::editExpression(Sequence * sequence, int sequenceDefinition, Ion::Events::Event event) { + char * initialText = nullptr; + char initialTextContent[255]; + if (event == Ion::Events::OK) { + strlcpy(initialTextContent, sequence->text(), sizeof(initialTextContent)); + initialText = initialTextContent; + } + App * myApp = (App *)app(); + InputViewController * inputController = myApp->inputViewController(); + if (sequenceDefinition == 0) { + inputController->edit(this, event, sequence, initialText, + [](void * context, void * sender){ + Sequence * mySequence = (Sequence *)context; + InputViewController * myInputViewController = (InputViewController *)sender; + const char * textBody = myInputViewController->textBody(); + mySequence->setContent(textBody); + }, + [](void * context, void * sender){ + }); + } + if (sequenceDefinition == 1) { + inputController->edit(this, event, sequence, initialText, + [](void * context, void * sender){ + Sequence * mySequence = (Sequence *)context; + InputViewController * myInputViewController = (InputViewController *)sender; + const char * textBody = myInputViewController->textBody(); + mySequence->setFirstInitialConditionContent(textBody); + }, + [](void * context, void * sender){ + }); + } + if (sequenceDefinition == 2) { + inputController->edit(this, event, sequence, initialText, + [](void * context, void * sender){ + Sequence * mySequence = (Sequence *)context; + InputViewController * myInputViewController = (InputViewController *)sender; + const char * textBody = myInputViewController->textBody(); + mySequence->setSecondInitialConditionContent(textBody); + }, + [](void * context, void * sender){ + }); } } @@ -99,7 +161,7 @@ int ListController::maxNumberOfRows() { TableViewCell * ListController::titleCells(int index) { assert(index >= 0 && index < k_maxNumberOfRows); - return &m_functionTitleCells[index]; + return &m_sequenceTitleCells[index]; } TableViewCell * ListController::expressionCells(int index) { @@ -107,15 +169,75 @@ TableViewCell * ListController::expressionCells(int index) { return &m_expressionCells[index]; } + void ListController::willDisplayTitleCellAtIndex(TableViewCell * cell, int j) { SequenceTitleCell * myCell = (SequenceTitleCell *)cell; - Sequence * sequence = ((SequenceStore *)m_functionStore)->functionAtIndex(j); - myCell->setSequence(sequence); + Sequence * sequence = m_sequenceStore->functionAtIndex(sequenceIndexForRow(j)); + if (sequenceDefinitionForRow(j) == 0) { + myCell->setExpression(sequence->definitionName()); + } + if (sequenceDefinitionForRow(j) == 1) { + myCell->setExpression(sequence->firstInitialConditionName()); + } + if (sequenceDefinitionForRow(j) == 2) { + myCell->setExpression(sequence->secondInitialConditionName()); + } + KDColor nameColor = sequence->isActive() ? sequence->color() : Palette::GreyDark; + myCell->setColor(nameColor); } void ListController::willDisplayExpressionCellAtIndex(TableViewCell * cell, int j) { - SequenceExpressionCell * myCell = (SequenceExpressionCell *)cell; - myCell->setSequence(((SequenceStore *)m_functionStore)->functionAtIndex(j)); + FunctionExpressionCell * myCell = (FunctionExpressionCell *)cell; + Sequence * sequence = m_sequenceStore->functionAtIndex(sequenceIndexForRow(j)); + if (sequenceDefinitionForRow(j) == 0) { + myCell->setExpression(sequence->layout()); + } + if (sequenceDefinitionForRow(j) == 1) { + myCell->setExpression(sequence->firstInitialConditionLayout()); + } + if (sequenceDefinitionForRow(j) == 2) { + myCell->setExpression(sequence->secondInitialConditionLayout()); + } + bool active = sequence->isActive(); + KDColor textColor = active ? KDColorBlack : Palette::GreyDark; + myCell->setTextColor(textColor); +} + +int ListController::sequenceIndexForRow(int j) { + if (j < 0) { + return j; + } + if (m_sequenceStore->numberOfFunctions() < m_sequenceStore->maxNumberOfFunctions() && + j == numberOfRows() - 1) { + return j; + } + int rowIndex = 0; + int sequenceIndex = -1; + do { + sequenceIndex++; + Sequence * sequence = m_sequenceStore->functionAtIndex(sequenceIndex); + rowIndex += sequence->numberOfElements(); + } while (rowIndex <= j); + return sequenceIndex; +} + +int ListController::sequenceDefinitionForRow(int j) { + if (j < 0) { + return j; + } + if (m_sequenceStore->numberOfFunctions() < m_sequenceStore->maxNumberOfFunctions() && + j == numberOfRows() - 1) { + return 0; + } + int rowIndex = 0; + int sequenceIndex = -1; + Sequence * sequence = nullptr; + do { + sequenceIndex++; + sequence = m_sequenceStore->functionAtIndex(sequenceIndex); + rowIndex += sequence->numberOfElements(); + } while (rowIndex <= j); + return sequence->numberOfElements()-rowIndex+j; } } diff --git a/apps/sequence/list/list_controller.h b/apps/sequence/list/list_controller.h index 8849288de..1d3d72e46 100644 --- a/apps/sequence/list/list_controller.h +++ b/apps/sequence/list/list_controller.h @@ -2,9 +2,9 @@ #define SEQUENCE_LIST_CONTROLLER_H #include -#include "sequence_title_cell.h" +#include "../sequence_title_cell.h" #include "../sequence_store.h" -#include "sequence_expression_cell.h" +#include "../../shared/function_expression_cell.h" #include "type_parameter_controller.h" #include "../../shared/new_function_cell.h" #include "../../shared/list_controller.h" @@ -12,24 +12,30 @@ namespace Sequence { -class ListController : public Shared::ListController, public SelectableTableViewDelegate { +class ListController : public Shared::ListController { public: ListController(Responder * parentResponder, SequenceStore * sequenceStore, HeaderViewController * header); const char * title() const override; - KDCoordinate rowHeight(int j) override; + int numberOfRows() override; + virtual KDCoordinate rowHeight(int j) override; + void willDisplayCellAtLocation(TableViewCell * cell, int i, int j) override; bool handleEvent(Ion::Events::Event event) override; - void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) override; private: - static constexpr KDCoordinate k_emptySubRowHeight = 30; + bool handleEnter(); + void editExpression(Sequence * sequence, int sequenceDefinitionIndex, Ion::Events::Event event); ListParameterController * parameterController() override; int maxNumberOfRows() override; TableViewCell * titleCells(int index) override; TableViewCell * expressionCells(int index) override; void willDisplayTitleCellAtIndex(TableViewCell * cell, int j) override; void willDisplayExpressionCellAtIndex(TableViewCell * cell, int j) override; - constexpr static int k_maxNumberOfRows = 3; - SequenceTitleCell m_functionTitleCells[k_maxNumberOfRows]; - SequenceExpressionCell m_expressionCells[k_maxNumberOfRows]; + int sequenceIndexForRow(int j); + int sequenceDefinitionForRow(int j); + static constexpr KDCoordinate k_emptySubRowHeight = 30; + constexpr static int k_maxNumberOfRows = 9; + SequenceStore * m_sequenceStore; + SequenceTitleCell m_sequenceTitleCells[k_maxNumberOfRows]; + Shared::FunctionExpressionCell m_expressionCells[k_maxNumberOfRows]; ListParameterController m_parameterController; TypeParameterController m_typeParameterController; StackViewController m_typeStackController; diff --git a/apps/sequence/list/list_parameter_controller.cpp b/apps/sequence/list/list_parameter_controller.cpp index 205a079ea..c72bd80b2 100644 --- a/apps/sequence/list/list_parameter_controller.cpp +++ b/apps/sequence/list/list_parameter_controller.cpp @@ -1,6 +1,4 @@ #include "list_parameter_controller.h" -#include "../../../poincare/src/layout/baseline_relative_layout.h" -#include "../../../poincare/src/layout/string_layout.h" using namespace Poincare; using namespace Shared; @@ -10,31 +8,25 @@ namespace Sequence { ListParameterController::ListParameterController(Responder * parentResponder, SequenceStore * sequenceStore) : Shared::ListParameterController(parentResponder, sequenceStore), m_typeCell(ChevronExpressionMenuListCell((char *)"Type de suite")), - m_changeTypeParameterController(this) + m_typeParameterController(TypeParameterController(this, sequenceStore, Metric::TopMargin, Metric::RightMargin, + Metric::BottomMargin, Metric::LeftMargin)) { } -ListParameterController::~ListParameterController() { - if (m_typeLayout) { - delete m_typeLayout; - m_typeLayout = nullptr; - } -} - const char * ListParameterController::title() const { return "Options de la suite"; } -void ListParameterController::setSequence(Sequence * sequence) { - setFunction(sequence); - m_sequence = sequence; +void ListParameterController::setFunction(Shared::Function * function) { + Shared::ListParameterController::setFunction(function); + m_sequence = (Sequence *)function; } bool ListParameterController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::OK && m_selectableTableView.selectedRow() == 3) { StackViewController * stack = (StackViewController *)(parentResponder()); - m_changeTypeParameterController.setSequence(m_sequence); - stack->push(&m_changeTypeParameterController); + m_typeParameterController.setSequence(m_sequence); + stack->push(&m_typeParameterController); return true; } if (event == Ion::Events::OK && m_selectableTableView.selectedRow() == 2) { @@ -66,20 +58,7 @@ int ListParameterController::reusableCellCount() { void ListParameterController::willDisplayCellForIndex(TableViewCell * cell, int index) { Shared::ListParameterController::willDisplayCellForIndex(cell, index); if (cell == &m_typeCell && m_sequence != nullptr) { - if (m_typeLayout != nullptr) { - delete m_typeLayout; - m_typeLayout = nullptr; - } - if (m_sequence->type() == Sequence::Type::Explicite) { - m_typeLayout = new BaselineRelativeLayout(new StringLayout(m_sequence->name(), 1), new StringLayout("n", 1, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript); - } - if (m_sequence->type() == Sequence::Type::SingleRecurrence) { - m_typeLayout = new BaselineRelativeLayout(new StringLayout(m_sequence->name(), 1), new StringLayout("n+1", 3, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript); - } - if (m_sequence->type() == Sequence::Type::DoubleRecurrence) { - m_typeLayout = new BaselineRelativeLayout(new StringLayout(m_sequence->name(), 1), new StringLayout("n+2", 3, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript); - } - m_typeCell.setExpression(m_typeLayout); + m_typeCell.setExpression(m_sequence->definitionName()); } } diff --git a/apps/sequence/list/list_parameter_controller.h b/apps/sequence/list/list_parameter_controller.h index b5d06cb7e..fcf0d3c41 100644 --- a/apps/sequence/list/list_parameter_controller.h +++ b/apps/sequence/list/list_parameter_controller.h @@ -4,17 +4,16 @@ #include "../../shared/list_parameter_controller.h" #include "../sequence.h" #include "../sequence_store.h" -#include "change_type_parameter_controller.h" +#include "type_parameter_controller.h" namespace Sequence { class ListParameterController : public Shared::ListParameterController { public: ListParameterController(Responder * parentResponder, SequenceStore * sequenceStore); - ~ListParameterController(); const char * title() const override; bool handleEvent(Ion::Events::Event event) override; - void setSequence(Sequence * sequence); + void setFunction(Shared::Function * function) override; int numberOfRows() override; TableViewCell * reusableCell(int index) override; int reusableCellCount() override; @@ -22,8 +21,7 @@ public: private: constexpr static int k_totalNumberOfCell = 4; ChevronExpressionMenuListCell m_typeCell; - Poincare::ExpressionLayout * m_typeLayout; - ChangeTypeParameterController m_changeTypeParameterController; + TypeParameterController m_typeParameterController; Sequence * m_sequence; }; diff --git a/apps/sequence/list/sequence_cell.cpp b/apps/sequence/list/sequence_cell.cpp deleted file mode 100644 index 1ba8bb972..000000000 --- a/apps/sequence/list/sequence_cell.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "sequence_cell.h" - -namespace Sequence { - -SequenceCell::SequenceCell(Responder * parentResponder) : - EvenOddCell(), - Responder(parentResponder), - m_numberOfSubCells(1), - m_selectedSubCell(0), - m_sequence(nullptr) -{ -} - -int SequenceCell::numberOfSubCells() { - return m_numberOfSubCells; -} - -int SequenceCell::selectedSubCell() { - return m_selectedSubCell; -} - -void SequenceCell::selectSubCell(int selectedSubCell) { - m_selectedSubCell = selectedSubCell; - viewAtIndex(0)->setHighlighted(selectedSubCell == 0); - viewAtIndex(1)->setHighlighted(selectedSubCell == 1); - viewAtIndex(2)->setHighlighted(selectedSubCell == 2); - reloadCell(); -} - -void SequenceCell::setSequence(Sequence * sequence) { - m_sequence = sequence; - m_numberOfSubCells = (int)m_sequence->type()+1; - layoutSubviews(); -} - -void SequenceCell::setHighlighted(bool highlight) { - TableViewCell::setHighlighted(highlight); - viewAtIndex(0)->setHighlighted(false); - viewAtIndex(1)->setHighlighted(false); - viewAtIndex(2)->setHighlighted(false); - TableViewCell::setHighlighted(highlight); - if (isHighlighted()) { - viewAtIndex(m_selectedSubCell)->setHighlighted(true); - } - reloadCell(); -} - -void SequenceCell::setEven(bool even) { - EvenOddCell::setEven(even); - viewAtIndex(0)->setEven(even); - viewAtIndex(1)->setEven(even); - viewAtIndex(2)->setEven(even); - reloadCell(); -} - -int SequenceCell::numberOfSubviews() const { - return m_numberOfSubCells; -} - -View * SequenceCell::subviewAtIndex(int index) { - return viewAtIndex(index); -} - -void SequenceCell::layoutSubviews() { - KDCoordinate cellHeight = (bounds().height()-(m_numberOfSubCells-1)*k_separatorThickness)/m_numberOfSubCells; - KDRect expressionFrame(k_separatorThickness, 0, bounds().width() - k_separatorThickness, cellHeight); - viewAtIndex(0)->setFrame(expressionFrame); - expressionFrame = KDRect(k_separatorThickness, cellHeight+k_separatorThickness, bounds().width() - k_separatorThickness, cellHeight); - viewAtIndex(1)->setFrame(expressionFrame); - expressionFrame = KDRect(k_separatorThickness, 2*cellHeight+2*k_separatorThickness, bounds().width() - k_separatorThickness, cellHeight); - viewAtIndex(2)->setFrame(expressionFrame); -} - -} diff --git a/apps/sequence/list/sequence_cell.h b/apps/sequence/list/sequence_cell.h deleted file mode 100644 index 566d3b0c4..000000000 --- a/apps/sequence/list/sequence_cell.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef SEQUENCE_SEQUENCE_CELL_H -#define SEQUENCE_SEQUENCE_CELL_H - -#include "../sequence.h" -#include - -namespace Sequence { - -class SequenceCell : public EvenOddCell, public Responder { -public: - SequenceCell(Responder * parentResponder); - virtual void setSequence(Sequence * sequence); - int numberOfSubCells(); - int selectedSubCell(); - void selectSubCell(int index); - void setHighlighted(bool highlight) override; - void setEven(bool even) override; - int numberOfSubviews() const override; - View * subviewAtIndex(int index) override; - void layoutSubviews() override; -protected: - constexpr static KDCoordinate k_separatorThickness = 1; - int m_numberOfSubCells; - int m_selectedSubCell; - Sequence * m_sequence; -private: - virtual EvenOddCell * viewAtIndex(int index) = 0; -}; - -} - -#endif diff --git a/apps/sequence/list/sequence_expression_cell.cpp b/apps/sequence/list/sequence_expression_cell.cpp deleted file mode 100644 index 89f0aa0fd..000000000 --- a/apps/sequence/list/sequence_expression_cell.cpp +++ /dev/null @@ -1,169 +0,0 @@ -#include "sequence_expression_cell.h" -#include "../app.h" - -using namespace Shared; - -namespace Sequence { - -SequenceExpressionCell::SequenceExpressionCell(Responder * parentResponder) : - SequenceCell(parentResponder), - m_expressionView(EvenOddExpressionCell()), - m_firstInitialConditionView(EvenOddExpressionCell()), - m_secondInitialConditionView(EvenOddExpressionCell()) -{ -} - -void SequenceExpressionCell::setSequence(Sequence * sequence) { - SequenceCell::setSequence(sequence); - bool active = m_sequence->isActive(); - KDColor textColor = active ? KDColorBlack : Palette::GreyDark; - m_expressionView.setExpression(m_sequence->layout()); - m_expressionView.setTextColor(textColor); - if (m_numberOfSubCells > 1) { - m_firstInitialConditionView.setExpression(m_sequence->firstInitialConditionLayout()); - m_firstInitialConditionView.setTextColor(textColor); - } - if (m_numberOfSubCells > 2) { - m_secondInitialConditionView.setExpression(m_sequence->secondInitialConditionLayout()); - m_secondInitialConditionView.setTextColor(textColor); - } -} - -Sequence * SequenceExpressionCell::sequence() { - return m_sequence; -} - -void SequenceExpressionCell::drawRect(KDContext * ctx, KDRect rect) const { - KDColor separatorColor = m_even ? Palette::WallScreen : KDColorWhite; - // Color the separators - ctx->fillRect(KDRect(0, 0, k_separatorThickness, bounds().height()), Palette::GreyBright); - KDCoordinate cellHeight = (bounds().height()-(m_numberOfSubCells-1)*k_separatorThickness)/m_numberOfSubCells; - if (m_numberOfSubCells > 1) { - ctx->fillRect(KDRect(k_separatorThickness, cellHeight, bounds().width() - k_separatorThickness, k_separatorThickness), separatorColor); - } - if (m_numberOfSubCells > 2) { - ctx->fillRect(KDRect(k_separatorThickness, 2*cellHeight+k_separatorThickness, bounds().width() - k_separatorThickness, k_separatorThickness), separatorColor); - } -} - -bool SequenceExpressionCell::handleEvent(Ion::Events::Event event) { - if (m_selectedSubCell < m_numberOfSubCells - 1 && event == Ion::Events::Down) { - selectSubCell(m_selectedSubCell+1); - return true; - } - if (m_selectedSubCell > 0 && event == Ion::Events::Up) { - selectSubCell(m_selectedSubCell-1); - return true; - } - if (event == Ion::Events::OK) { - editExpression(event); - return true; - } - if (event.hasText() || event == Ion::Events::XNT) { - editExpression(event); - return true; - } - return false; -} - -Toolbox * SequenceExpressionCell::toolboxForTextField(TextField * textField) { - SequenceToolbox * toolbox = ((App *)app())->sequenceToolbox(); - SequenceStore * sequenceStore = ((App *)app())->sequenceStore(); - int numberOfToolboxAddedCells = 0; - char * toolboxCellNames[6]; - char * toolboxCellSubscript[6]; - int recurrenceDepth = 0; - if (m_selectedSubCell == 0) { - recurrenceDepth = m_numberOfSubCells-1; - } - for (int k = 0; k < sequenceStore->numberOfFunctions(); k++) { - Sequence * s = sequenceStore->functionAtIndex(k); - for (int j = 0; j < recurrenceDepth; j++) { - toolboxCellNames[numberOfToolboxAddedCells] = (char *)s->name(); - toolboxCellSubscript[numberOfToolboxAddedCells] = (char *)(j == 0? "n" : "n+1"); - numberOfToolboxAddedCells++; - } - } - toolbox->addCells(numberOfToolboxAddedCells, toolboxCellNames, toolboxCellSubscript); - return toolbox; -} - -TextFieldDelegateApp * SequenceExpressionCell::textFieldDelegateApp() { - return (App *)app(); -} - -EvenOddCell * SequenceExpressionCell::viewAtIndex(int index) { - if (index == 0) { - return &m_expressionView; - } - if (index == 1) { - return &m_firstInitialConditionView; - } - return &m_secondInitialConditionView; -} - -void SequenceExpressionCell::editExpression(Ion::Events::Event event) { - char * initialText = nullptr; - char initialTextContent[255]; - if (event == Ion::Events::OK) { - char * text = (char *)m_sequence->text(); - if (m_selectedSubCell == 1) { - text = (char *)m_sequence->firstInitialConditionText(); - } - if (m_selectedSubCell == 2) { - text = (char *)m_sequence->secondInitialConditionText(); - } - strlcpy(initialTextContent, text, sizeof(initialTextContent)); - initialText = initialTextContent; - } - App * myApp = (App *)app(); - InputViewController * inputController = myApp->inputViewController(); - inputController->setTextFieldDelegate(this); - if (m_selectedSubCell == 0) { - inputController->edit(this, event, this, initialText, - [](void * context, void * sender){ - SequenceExpressionCell * myCell = (SequenceExpressionCell *) context; - Sequence * sequence = myCell->sequence(); - InputViewController * myInputViewController = (InputViewController *)sender; - const char * textBody = myInputViewController->textBody(); - sequence->setContent(textBody); - myCell->reloadCell(); - SelectableTableView * table = (SelectableTableView *)myCell->parentResponder(); - table->reloadData(); - }, - [](void * context, void * sender){} - ); - } - if (m_selectedSubCell == 1) { - inputController->edit(this, event, this, initialText, - [](void * context, void * sender){ - SequenceExpressionCell * myCell = (SequenceExpressionCell *) context; - Sequence * sequence = myCell->sequence(); - InputViewController * myInputViewController = (InputViewController *)sender; - const char * textBody = myInputViewController->textBody(); - sequence->setFirstInitialConditionContent(textBody); - myCell->reloadCell(); - SelectableTableView * table = (SelectableTableView *)myCell->parentResponder(); - table->reloadData(); - }, - [](void * context, void * sender){} - ); - } - if (m_selectedSubCell == 2) { - inputController->edit(this, event, this, initialText, - [](void * context, void * sender){ - SequenceExpressionCell * myCell = (SequenceExpressionCell *) context; - Sequence * sequence = myCell->sequence(); - InputViewController * myInputViewController = (InputViewController *)sender; - const char * textBody = myInputViewController->textBody(); - sequence->setSecondInitialConditionContent(textBody); - myCell->reloadCell(); - SelectableTableView * table = (SelectableTableView *)myCell->parentResponder(); - table->reloadData(); - }, - [](void * context, void * sender){} - ); - } -} - -} diff --git a/apps/sequence/list/sequence_expression_cell.h b/apps/sequence/list/sequence_expression_cell.h deleted file mode 100644 index 9132d4ab8..000000000 --- a/apps/sequence/list/sequence_expression_cell.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef SEQUENCE_SEQUENCE_EXPRESSION_CELL_H -#define SEQUENCE_SEQUENCE_EXPRESSION_CELL_H - -#include "../sequence.h" -#include "sequence_cell.h" -#include "../../shared/text_field_delegate.h" -#include - -namespace Sequence { - -class SequenceExpressionCell : public SequenceCell, public Shared::TextFieldDelegate { -public: - SequenceExpressionCell(Responder * parentResponder); - void setSequence(Sequence * sequence) override; - Sequence * sequence(); - void drawRect(KDContext * ctx, KDRect rect) const override; - bool handleEvent(Ion::Events::Event event) override; - Toolbox * toolboxForTextField(TextField * textField) override; -private: - Shared::TextFieldDelegateApp * textFieldDelegateApp() override; - EvenOddCell * viewAtIndex(int index) override; - void editExpression(Ion::Events::Event event); - EvenOddExpressionCell m_expressionView; - EvenOddExpressionCell m_firstInitialConditionView; - EvenOddExpressionCell m_secondInitialConditionView; -}; - -} - -#endif diff --git a/apps/sequence/list/sequence_title_cell.cpp b/apps/sequence/list/sequence_title_cell.cpp deleted file mode 100644 index ec1da4cff..000000000 --- a/apps/sequence/list/sequence_title_cell.cpp +++ /dev/null @@ -1,128 +0,0 @@ -#include "sequence_title_cell.h" -#include "../../../poincare/src/layout/baseline_relative_layout.h" -#include "../../../poincare/src/layout/string_layout.h" - -using namespace Shared; -using namespace Poincare; - -namespace Sequence { - -SequenceTitleCell::SequenceTitleCell(Responder * parentResponder, ListParameterController * listParameterController) : - SequenceCell(parentResponder), - m_backgroungCell(FunctionTitleCell(FunctionTitleCell::Orientation::VerticalIndicator)), - m_definitionView(0.5f, 0.5f), - m_firstInitialConditionView(0.5f, 0.5f), - m_secondInitialConditionView(0.5f, 0.5f), - m_listParameterController(listParameterController) -{ -} - -SequenceTitleCell::~SequenceTitleCell() { - for (int i = 0; i < 3; i++) { - if (m_expressionLayouts[i]) { - delete m_expressionLayouts[i]; - m_expressionLayouts[i] = nullptr; - } - } -} - -void SequenceTitleCell::setSequence(Sequence * sequence) { - SequenceCell::setSequence(sequence); - for (int i = 0; i < 3; i++) { - if (m_expressionLayouts[i]!= nullptr) { - delete m_expressionLayouts[i]; - m_expressionLayouts[i] = nullptr; - } - } - if (m_numberOfSubCells == 1) { - m_expressionLayouts[0] = new BaselineRelativeLayout(new StringLayout(sequence->name(), 1), new StringLayout("n", 1, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript); - m_definitionView.setExpression(m_expressionLayouts[0]); - } - if (m_numberOfSubCells == 2) { - m_expressionLayouts[0] = new BaselineRelativeLayout(new StringLayout(sequence->name(), 1), new StringLayout("n+1", 3, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript); - m_definitionView.setExpression(m_expressionLayouts[0]); - m_expressionLayouts[1] = new BaselineRelativeLayout(new StringLayout(sequence->name(), 1), new StringLayout("0", 1, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript); - m_firstInitialConditionView.setExpression(m_expressionLayouts[1]); - } - if (m_numberOfSubCells == 3) { - m_expressionLayouts[0] = new BaselineRelativeLayout(new StringLayout(sequence->name(), 1), new StringLayout("n+2", 3, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript); - m_definitionView.setExpression(m_expressionLayouts[0]); - m_expressionLayouts[1] = new BaselineRelativeLayout(new StringLayout(sequence->name(), 1), new StringLayout("0", 1, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript); - m_firstInitialConditionView.setExpression(m_expressionLayouts[1]); - m_expressionLayouts[2] = new BaselineRelativeLayout(new StringLayout(sequence->name(), 1), new StringLayout("1", 1, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript); - m_secondInitialConditionView.setExpression(m_expressionLayouts[2]); - } - KDColor nameColor = sequence->isActive() ? sequence->color() : Palette::GreyDark; - setColor(nameColor); - layoutSubviews(); -} - -void SequenceTitleCell::setColor(KDColor color) { - m_backgroungCell.setColor(color); - m_definitionView.setTextColor(color); - m_firstInitialConditionView.setTextColor(color); - m_secondInitialConditionView.setTextColor(color); -} - -int SequenceTitleCell::numberOfSubviews() const { - return SequenceCell::numberOfSubviews() + 1; -} - -View * SequenceTitleCell::subviewAtIndex(int index) { - if (index == SequenceCell::numberOfSubviews()) { - return &m_backgroungCell; - } - return SequenceCell::subviewAtIndex(index); -} - -void SequenceTitleCell::layoutSubviews() { - m_backgroungCell.setFrame(bounds()); - SequenceCell::layoutSubviews(); -} - -void SequenceTitleCell::drawRect(KDContext * ctx, KDRect rect) const { - KDColor separatorColor = m_even ? Palette::WallScreen : KDColorWhite; - KDCoordinate cellHeight = (bounds().height()-(m_numberOfSubCells-1)*k_separatorThickness)/m_numberOfSubCells; - if (m_numberOfSubCells > 1) { - ctx->fillRect(KDRect(0, cellHeight, bounds().width(), k_separatorThickness), separatorColor); - } - if (m_numberOfSubCells > 2) { - ctx->fillRect(KDRect(0, 2*cellHeight+k_separatorThickness, bounds().width(), k_separatorThickness), separatorColor); - } -} - -bool SequenceTitleCell::handleEvent(Ion::Events::Event event) { - if (m_selectedSubCell < m_numberOfSubCells-1 && event == Ion::Events::Down) { - selectSubCell(m_selectedSubCell+1); - return true; - } - if (m_selectedSubCell > 0 && event == Ion::Events::Up) { - selectSubCell(m_selectedSubCell-1); - return true; - } - if (event == Ion::Events::OK) { - StackViewController * stack = stackController(); - m_listParameterController->setSequence(m_sequence); - stack->push(m_listParameterController); - SelectableTableView * table = (SelectableTableView *)parentResponder(); - table->reloadData(); - return true; - } - return false; -} - -EvenOddCell * SequenceTitleCell::viewAtIndex(int index) { - if (index == 0) { - return &m_definitionView; - } - if (index == 1) { - return &m_firstInitialConditionView; - } - return &m_secondInitialConditionView; -} - -StackViewController * SequenceTitleCell::stackController() { - return (StackViewController *)parentResponder()->parentResponder()->parentResponder()->parentResponder(); -} - -} diff --git a/apps/sequence/list/sequence_title_cell.h b/apps/sequence/list/sequence_title_cell.h deleted file mode 100644 index 7fa7e7cde..000000000 --- a/apps/sequence/list/sequence_title_cell.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef SEQUENCE_SEQUENCE_TITLE_CELL_H -#define SEQUENCE_SEQUENCE_TITLE_CELL_H - -#include "../../shared/function_title_cell.h" -#include "list_parameter_controller.h" -#include "../sequence.h" -#include "sequence_cell.h" - -namespace Sequence { - -class SequenceTitleCell : public SequenceCell { -public: - SequenceTitleCell(Responder * parentResponder, ListParameterController * listParameterController); - ~SequenceTitleCell(); - void setSequence(Sequence * sequence) override; - void setColor(KDColor color); - int numberOfSubviews() const override; - View * subviewAtIndex(int index) override; - void layoutSubviews() override; - void drawRect(KDContext * ctx, KDRect rect) const override; - bool handleEvent(Ion::Events::Event event) override; -private: - EvenOddCell * viewAtIndex(int index) override; - StackViewController * stackController(); - Shared::FunctionTitleCell m_backgroungCell; - EvenOddExpressionCell m_definitionView; - EvenOddExpressionCell m_firstInitialConditionView; - EvenOddExpressionCell m_secondInitialConditionView; - Poincare::ExpressionLayout * m_expressionLayouts[3]; - ListParameterController * m_listParameterController; -}; - -} - -#endif diff --git a/apps/sequence/list/type_parameter_controller.cpp b/apps/sequence/list/type_parameter_controller.cpp index 92e489b59..42ac01951 100644 --- a/apps/sequence/list/type_parameter_controller.cpp +++ b/apps/sequence/list/type_parameter_controller.cpp @@ -7,13 +7,15 @@ using namespace Poincare; namespace Sequence { -TypeParameterController::TypeParameterController(Responder * parentResponder, SequenceStore * sequenceStore) : +TypeParameterController::TypeParameterController(Responder * parentResponder, SequenceStore * sequenceStore, + KDCoordinate topMargin, KDCoordinate rightMargin, KDCoordinate bottomMargin, KDCoordinate leftMargin) : ViewController(parentResponder), m_expliciteCell(TextExpressionMenuListCell((char*)"Explicite")), m_singleRecurrenceCell(TextExpressionMenuListCell((char*)"Recurrence d'ordre 1")), m_doubleRecurenceCell(TextExpressionMenuListCell((char*)"Recurrence d'ordre 2")), - m_selectableTableView(SelectableTableView(this, this)), - m_sequenceStore(sequenceStore) + m_selectableTableView(SelectableTableView(this, this, topMargin, rightMargin, bottomMargin, leftMargin)), + m_sequenceStore(sequenceStore), + m_sequence(nullptr) { } @@ -27,6 +29,9 @@ TypeParameterController::~TypeParameterController() { } const char * TypeParameterController::title() const { + if (m_sequence) { + return "Type de suite"; + } return "Choisir le type de suite"; } @@ -42,6 +47,12 @@ void TypeParameterController::didBecomeFirstResponder() { bool TypeParameterController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::OK) { + if (m_sequence) { + m_sequence->setType((Sequence::Type)m_selectableTableView.selectedRow()); + StackViewController * stack = stackController(); + stack->pop(); + return true; + } Sequence * newSequence = m_sequenceStore->addEmptyFunction(); newSequence->setType((Sequence::Type)m_selectableTableView.selectedRow()); app()->dismissModalViewController(); @@ -66,21 +77,33 @@ int TypeParameterController::reusableCellCount() { } KDCoordinate TypeParameterController::cellHeight() { + if (m_sequence) { + return Metric::ParameterCellHeight; + } return 50; } void TypeParameterController::willDisplayCellAtLocation(TableViewCell * cell, int i, int j) { const char * nextName = m_sequenceStore->firstAvailableName(); + KDText::FontSize size = KDText::FontSize::Large; + if (m_sequence) { + nextName = m_sequence->name(); + size = KDText::FontSize::Small; + } const char * subscripts[3] = {"n", "n+1", "n+2"}; if (m_expressionLayouts[j]) { delete m_expressionLayouts[j]; m_expressionLayouts[j] = nullptr; } - m_expressionLayouts[j] = new BaselineRelativeLayout(new StringLayout(nextName, 1), new StringLayout(subscripts[j], strlen(subscripts[j]), KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript); + m_expressionLayouts[j] = new BaselineRelativeLayout(new StringLayout(nextName, 1, size), new StringLayout(subscripts[j], strlen(subscripts[j]), KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript); TextExpressionMenuListCell * myCell = (TextExpressionMenuListCell *)cell; myCell->setExpression(m_expressionLayouts[j]); } +void TypeParameterController::setSequence(Sequence * sequence) { + m_sequence = sequence; +} + StackViewController * TypeParameterController::stackController() const { return (StackViewController *)parentResponder(); } diff --git a/apps/sequence/list/type_parameter_controller.h b/apps/sequence/list/type_parameter_controller.h index 294cff241..732ccb3d9 100644 --- a/apps/sequence/list/type_parameter_controller.h +++ b/apps/sequence/list/type_parameter_controller.h @@ -8,7 +8,9 @@ namespace Sequence { class TypeParameterController : public ViewController, public SimpleListViewDataSource { public: - TypeParameterController(Responder * parentResponder, SequenceStore * sequenceStore); + TypeParameterController(Responder * parentResponder, SequenceStore * sequenceStore, + KDCoordinate topMargin = 0, KDCoordinate rightMargin = 0, KDCoordinate bottomMargin = 0, + KDCoordinate leftMargin = 0); ~TypeParameterController(); const char * title() const override; View * view() override; @@ -19,6 +21,7 @@ public: TableViewCell * reusableCell(int index) override; int reusableCellCount() override; void willDisplayCellAtLocation(TableViewCell * cell, int i, int j) override; + void setSequence(Sequence * sequence); private: StackViewController * stackController() const; constexpr static int k_totalNumberOfCell = 3; @@ -28,6 +31,7 @@ private: Poincare::ExpressionLayout * m_expressionLayouts[k_totalNumberOfCell]; SelectableTableView m_selectableTableView; SequenceStore * m_sequenceStore; + Sequence * m_sequence; }; } diff --git a/apps/sequence/sequence.cpp b/apps/sequence/sequence.cpp index 95d730780..689098ca9 100644 --- a/apps/sequence/sequence.cpp +++ b/apps/sequence/sequence.cpp @@ -1,4 +1,6 @@ #include "sequence.h" +#include "../../poincare/src/layout/baseline_relative_layout.h" +#include "../../poincare/src/layout/string_layout.h" #include using namespace Shared; @@ -14,7 +16,10 @@ Sequence::Sequence(const char * text, KDColor color) : m_firstInitialConditionExpression(nullptr), m_secondInitialConditionExpression(nullptr), m_firstInitialConditionLayout(nullptr), - m_secondInitialConditionLayout(nullptr) + m_secondInitialConditionLayout(nullptr), + m_definitionName(nullptr), + m_firstInitialConditionName(nullptr), + m_secondInitialConditionName(nullptr) { } @@ -36,6 +41,18 @@ Sequence::~Sequence() { delete m_secondInitialConditionExpression; m_secondInitialConditionExpression = nullptr; } + if (m_definitionName != nullptr) { + delete m_definitionName; + m_definitionName = nullptr; + } + if (m_firstInitialConditionName != nullptr) { + delete m_firstInitialConditionName; + m_firstInitialConditionName = nullptr; + } + if (m_secondInitialConditionName != nullptr) { + delete m_secondInitialConditionName; + m_secondInitialConditionName = nullptr; + } } const char * Sequence::firstInitialConditionText() { @@ -52,6 +69,30 @@ Sequence::Type Sequence::type() { void Sequence::setType(Type type) { m_type = type; + if (m_definitionName != nullptr) { + delete m_definitionName; + m_definitionName = nullptr; + } + if (m_firstInitialConditionName != nullptr) { + delete m_firstInitialConditionName; + m_firstInitialConditionName = nullptr; + } + if (m_secondInitialConditionName != nullptr) { + delete m_secondInitialConditionName; + m_secondInitialConditionName = nullptr; + } + if (m_type == Type::Explicite) { + m_definitionName = new BaselineRelativeLayout(new StringLayout(name(), 1), new StringLayout("n", 1, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript); + } + if (m_type == Type::SingleRecurrence) { + m_definitionName = new BaselineRelativeLayout(new StringLayout(name(), 1), new StringLayout("n+1", 3, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript); + m_firstInitialConditionName = new BaselineRelativeLayout(new StringLayout(name(), 1), new StringLayout("0", 1, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript); + } + if (m_type == Type::DoubleRecurrence) { + m_definitionName = new BaselineRelativeLayout(new StringLayout(name(), 1), new StringLayout("n+2", 3, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript); + m_firstInitialConditionName = new BaselineRelativeLayout(new StringLayout(name(), 1), new StringLayout("0", 1, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript); + m_secondInitialConditionName = new BaselineRelativeLayout(new StringLayout(name(), 1), new StringLayout("1", 1, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript); + } } Poincare::Expression * Sequence::firstInitialConditionExpression() { @@ -104,4 +145,20 @@ char Sequence::symbol() const { return 'n'; } +int Sequence::numberOfElements() { + return (int)m_type + 1; +} + +Poincare::ExpressionLayout * Sequence::definitionName() { + return m_definitionName; +} + +Poincare::ExpressionLayout * Sequence::firstInitialConditionName() { + return m_firstInitialConditionName; +} + +Poincare::ExpressionLayout * Sequence::secondInitialConditionName() { + return m_secondInitialConditionName; +} + } diff --git a/apps/sequence/sequence.h b/apps/sequence/sequence.h index 30940f190..b47ab0e1a 100644 --- a/apps/sequence/sequence.h +++ b/apps/sequence/sequence.h @@ -25,6 +25,10 @@ public: void setFirstInitialConditionContent(const char * c); void setSecondInitialConditionContent(const char * c); char symbol() const override; + int numberOfElements(); + Poincare::ExpressionLayout * definitionName(); + Poincare::ExpressionLayout * firstInitialConditionName(); + Poincare::ExpressionLayout * secondInitialConditionName(); private: Type m_type; char m_firstInitialConditionText[Shared::Function::k_bodyLength]; @@ -33,6 +37,9 @@ private: Poincare::Expression * m_secondInitialConditionExpression; Poincare::ExpressionLayout * m_firstInitialConditionLayout; Poincare::ExpressionLayout * m_secondInitialConditionLayout; + Poincare::ExpressionLayout * m_definitionName; + Poincare::ExpressionLayout * m_firstInitialConditionName; + Poincare::ExpressionLayout * m_secondInitialConditionName; }; } diff --git a/apps/sequence/sequence_title_cell.cpp b/apps/sequence/sequence_title_cell.cpp new file mode 100644 index 000000000..48968194b --- /dev/null +++ b/apps/sequence/sequence_title_cell.cpp @@ -0,0 +1,51 @@ +#include "sequence_title_cell.h" +#include + +using namespace Shared; +using namespace Poincare; + +namespace Sequence { + +SequenceTitleCell::SequenceTitleCell(Orientation orientation) : + Shared::FunctionTitleCell(orientation), + m_titleTextView(0.5f, 0.5f) +{ +} + +void SequenceTitleCell::setExpression(Poincare::ExpressionLayout * expressionLayout) { + m_titleTextView.setExpression(expressionLayout); +} + +void SequenceTitleCell::setHighlighted(bool highlight) { + EvenOddCell::setHighlighted(highlight); + m_titleTextView.setHighlighted(highlight); +} + +void SequenceTitleCell::setEven(bool even) { + EvenOddCell::setEven(even); + m_titleTextView.setEven(even); +} + +void SequenceTitleCell::setColor(KDColor color) { + Shared::FunctionTitleCell::setColor(color); + m_titleTextView.setTextColor(color); +} + +int SequenceTitleCell::numberOfSubviews() const { + return 1; +} + +View * SequenceTitleCell::subviewAtIndex(int index) { + assert(index == 0); + return &m_titleTextView; +} + +void SequenceTitleCell::layoutSubviews() { + KDRect textFrame(0, k_colorIndicatorThickness, bounds().width(), bounds().height() - k_colorIndicatorThickness); + if (m_orientation == Orientation::VerticalIndicator){ + textFrame = KDRect(k_colorIndicatorThickness, 0, bounds().width() - k_colorIndicatorThickness, bounds().height()); + } + m_titleTextView.setFrame(textFrame); +} + +} diff --git a/apps/sequence/sequence_title_cell.h b/apps/sequence/sequence_title_cell.h new file mode 100644 index 000000000..253c43902 --- /dev/null +++ b/apps/sequence/sequence_title_cell.h @@ -0,0 +1,24 @@ +#ifndef SEQUENCE_SEQUENCE_TITLE_CELL_H +#define SEQUENCE_SEQUENCE_TITLE_CELL_H + +#include "../shared/function_title_cell.h" + +namespace Sequence { + +class SequenceTitleCell : public Shared::FunctionTitleCell { +public: + SequenceTitleCell(Orientation orientation); + void setExpression(Poincare::ExpressionLayout * expressionLayout); + void setEven(bool even) override; + void setHighlighted(bool highlight) override; + void setColor(KDColor color) override; + int numberOfSubviews() const override; + View * subviewAtIndex(int index) override; + void layoutSubviews() override; +private: + EvenOddExpressionCell m_titleTextView; +}; + +} + +#endif diff --git a/apps/shared/Makefile b/apps/shared/Makefile index 0c0d86f82..00831079a 100644 --- a/apps/shared/Makefile +++ b/apps/shared/Makefile @@ -9,6 +9,7 @@ app_objs += $(addprefix apps/shared/,\ float_parameter_controller.o\ function.o\ function_store.o\ + function_expression_cell.o\ function_title_cell.o\ interactive_curve_view_controller.o\ interactive_curve_view_range.o\ diff --git a/apps/graph/list/function_expression_cell.cpp b/apps/shared/function_expression_cell.cpp similarity index 98% rename from apps/graph/list/function_expression_cell.cpp rename to apps/shared/function_expression_cell.cpp index 8e8e6a06c..349b0f223 100644 --- a/apps/graph/list/function_expression_cell.cpp +++ b/apps/shared/function_expression_cell.cpp @@ -3,7 +3,7 @@ using namespace Poincare; -namespace Graph { +namespace Shared { FunctionExpressionCell::FunctionExpressionCell() : EvenOddCell(), diff --git a/apps/graph/list/function_expression_cell.h b/apps/shared/function_expression_cell.h similarity index 82% rename from apps/graph/list/function_expression_cell.h rename to apps/shared/function_expression_cell.h index 2a7101270..d48b72102 100644 --- a/apps/graph/list/function_expression_cell.h +++ b/apps/shared/function_expression_cell.h @@ -1,9 +1,10 @@ -#ifndef GRAPH_FUNCTION_EXPRESSION_CELL_H -#define GRAPH_FUNCTION_EXPRESSION_CELL_H +#ifndef SHARED_FUNCTION_EXPRESSION_CELL_H +#define SHARED_FUNCTION_EXPRESSION_CELL_H #include +#include "function.h" -namespace Graph { +namespace Shared { class FunctionExpressionCell : public EvenOddCell { public: diff --git a/apps/shared/function_title_cell.cpp b/apps/shared/function_title_cell.cpp index 21b4548f5..29e62e68f 100644 --- a/apps/shared/function_title_cell.cpp +++ b/apps/shared/function_title_cell.cpp @@ -3,7 +3,7 @@ namespace Shared { -FunctionTitleCell::FunctionTitleCell(Orientation orientation, KDText::FontSize size) : +FunctionTitleCell::FunctionTitleCell(Orientation orientation) : EvenOddCell(), m_orientation(orientation) { diff --git a/apps/shared/function_title_cell.h b/apps/shared/function_title_cell.h index 54c315c81..ffe628bf7 100644 --- a/apps/shared/function_title_cell.h +++ b/apps/shared/function_title_cell.h @@ -11,7 +11,7 @@ public: HorizontalIndicator, VerticalIndicator }; - FunctionTitleCell(Orientation orientation, KDText::FontSize size = KDText::FontSize::Large); + FunctionTitleCell(Orientation orientation); virtual void setColor(KDColor color); void drawRect(KDContext * ctx, KDRect rect) const override; protected: diff --git a/apps/shared/list_controller.cpp b/apps/shared/list_controller.cpp index fa1bd5480..01c83d3b4 100644 --- a/apps/shared/list_controller.cpp +++ b/apps/shared/list_controller.cpp @@ -16,29 +16,10 @@ View * ListController::view() { return &m_selectableTableView; } -int ListController::numberOfRows() { - if (m_functionStore->numberOfFunctions() == m_functionStore->maxNumberOfFunctions()) { - return m_functionStore->numberOfFunctions(); - } - return 1 + m_functionStore->numberOfFunctions(); -}; - int ListController::numberOfColumns() { return 2; }; -KDCoordinate ListController::rowHeight(int j) { - if (m_functionStore->numberOfFunctions() < m_functionStore->maxNumberOfFunctions() && j == numberOfRows() - 1) { - return k_emptyRowHeight; - } - Function * function = m_functionStore->functionAtIndex(j); - if (function->layout() == nullptr) { - return k_emptyRowHeight; - } - KDCoordinate functionSize = function->layout()->size().height(); - return functionSize + k_emptyRowHeight - KDText::stringSize(" ").height(); -} - KDCoordinate ListController::columnWidth(int i) { switch (i) { case 0: @@ -146,6 +127,9 @@ void ListController::didBecomeFirstResponder() { } else { m_selectableTableView.selectCellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow()); } + if (m_selectableTableView.selectedRow() >= numberOfRows()) { + m_selectableTableView.selectCellAtLocation(m_selectableTableView.selectedColumn(), numberOfRows()-1); + } app()->setFirstResponder(&m_selectableTableView); } @@ -167,6 +151,12 @@ StackViewController * ListController::stackController() const{ return (StackViewController *)(parentResponder()->parentResponder()); } +void ListController::configureFunction(Shared::Function * function) { + StackViewController * stack = stackController(); + parameterController()->setFunction(function); + stack->push(parameterController()); +} + Responder * ListController::tabController() const{ return (parentResponder()->parentResponder()->parentResponder()); } diff --git a/apps/shared/list_controller.h b/apps/shared/list_controller.h index 3ddeda2df..e500879c5 100644 --- a/apps/shared/list_controller.h +++ b/apps/shared/list_controller.h @@ -12,9 +12,7 @@ class ListController : public ViewController, public HeaderViewDelegate, public public: ListController(Responder * parentResponder, FunctionStore * functionStore, HeaderViewController * header, const char * text); View * view() override; - int numberOfRows() override; int numberOfColumns() override; - virtual KDCoordinate rowHeight(int j) override; KDCoordinate columnWidth(int i) override; KDCoordinate cumulatedWidthFromIndex(int i) override; KDCoordinate cumulatedHeightFromIndex(int j) override; @@ -30,6 +28,7 @@ public: protected: static constexpr KDCoordinate k_emptyRowHeight = 50; StackViewController * stackController() const; + void configureFunction(Shared::Function * function); SelectableTableView m_selectableTableView; FunctionStore * m_functionStore; private: diff --git a/apps/shared/list_parameter_controller.h b/apps/shared/list_parameter_controller.h index 21caed44e..d670c999b 100644 --- a/apps/shared/list_parameter_controller.h +++ b/apps/shared/list_parameter_controller.h @@ -14,7 +14,7 @@ public: View * view() override; const char * title() const override; bool handleEvent(Ion::Events::Event event) override; - void setFunction(Function * function); + virtual void setFunction(Function * function); void didBecomeFirstResponder() override; int numberOfRows() override; KDCoordinate cellHeight() override;