[apps/sequence] Redesign list controller

Change-Id: If114a643b0f682e98076cf1ec9f4479b3dafdfa6
This commit is contained in:
Émilie Feral
2017-02-16 14:17:56 +01:00
parent f605963588
commit 51c33b0a5b
31 changed files with 419 additions and 740 deletions

View File

@@ -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\

View File

@@ -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)
{
}

View File

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

View File

@@ -3,7 +3,7 @@
#include <escher.h>
#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;
};

View File

@@ -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\
)

View File

@@ -1,90 +0,0 @@
#include "change_type_parameter_controller.h"
#include <assert.h>
#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();
}
}

View File

@@ -1,36 +0,0 @@
#ifndef SEQUENCE_CHANGE_TYPE_PARAMATER_CONTROLLER_H
#define SEQUENCE_CHANGE_TYPE_PARAMATER_CONTROLLER_H
#include <escher.h>
#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

View File

@@ -1,91 +1,153 @@
#include "list_controller.h"
#include "../app.h"
#include <assert.h>
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;
}
}

View File

@@ -2,9 +2,9 @@
#define SEQUENCE_LIST_CONTROLLER_H
#include <escher.h>
#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;

View File

@@ -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());
}
}

View File

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

View File

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

View File

@@ -1,32 +0,0 @@
#ifndef SEQUENCE_SEQUENCE_CELL_H
#define SEQUENCE_SEQUENCE_CELL_H
#include "../sequence.h"
#include <escher.h>
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

View File

@@ -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){}
);
}
}
}

View File

@@ -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 <escher.h>
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

View File

@@ -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();
}
}

View File

@@ -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

View File

@@ -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();
}

View File

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

View File

@@ -1,4 +1,6 @@
#include "sequence.h"
#include "../../poincare/src/layout/baseline_relative_layout.h"
#include "../../poincare/src/layout/string_layout.h"
#include <string.h>
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;
}
}

View File

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

View File

@@ -0,0 +1,51 @@
#include "sequence_title_cell.h"
#include <assert.h>
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);
}
}

View File

@@ -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

View File

@@ -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\

View File

@@ -3,7 +3,7 @@
using namespace Poincare;
namespace Graph {
namespace Shared {
FunctionExpressionCell::FunctionExpressionCell() :
EvenOddCell(),

View File

@@ -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 <escher.h>
#include "function.h"
namespace Graph {
namespace Shared {
class FunctionExpressionCell : public EvenOddCell {
public:

View File

@@ -3,7 +3,7 @@
namespace Shared {
FunctionTitleCell::FunctionTitleCell(Orientation orientation, KDText::FontSize size) :
FunctionTitleCell::FunctionTitleCell(Orientation orientation) :
EvenOddCell(),
m_orientation(orientation)
{

View File

@@ -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:

View File

@@ -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());
}

View File

@@ -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:

View File

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