Merge changes I12f5e15c,I59c703c4

* changes:
  [apps/graph/list] Simplify funciton expression cell to be used by sequence
  [apps/sequence] Temporary implementation of sequence toolbox
This commit is contained in:
Émilie Feral
2017-02-20 17:55:35 +01:00
committed by Gerrit
20 changed files with 222 additions and 33 deletions

View File

@@ -1,20 +1,21 @@
#include "function_expression_cell.h"
#include <assert.h>
using namespace Poincare;
namespace Graph {
FunctionExpressionCell::FunctionExpressionCell() :
EvenOddCell(),
m_function(nullptr),
m_expressionView(ExpressionView())
{
}
void FunctionExpressionCell::setFunction(CartesianFunction * f) {
m_function = f;
m_expressionView.setExpression(m_function->layout());
bool active = m_function->isActive();
KDColor textColor = active ? KDColorBlack : Palette::GreyDark;
void FunctionExpressionCell::setExpression(ExpressionLayout * expressionLayout) {
m_expressionView.setExpression(expressionLayout);
}
void FunctionExpressionCell::setTextColor(KDColor textColor) {
m_expressionView.setTextColor(textColor);
}
@@ -28,10 +29,6 @@ void FunctionExpressionCell::setHighlighted(bool highlight) {
m_expressionView.setBackgroundColor(backgroundColor());
}
CartesianFunction * FunctionExpressionCell::function() {
return m_function;
}
int FunctionExpressionCell::numberOfSubviews() const {
return 1;
}

View File

@@ -2,15 +2,14 @@
#define GRAPH_FUNCTION_EXPRESSION_CELL_H
#include <escher.h>
#include "../cartesian_function.h"
namespace Graph {
class FunctionExpressionCell : public EvenOddCell {
public:
FunctionExpressionCell();
virtual void setFunction(CartesianFunction * f);
CartesianFunction * function();
void setExpression(Poincare::ExpressionLayout * expressionLayout);
void setTextColor(KDColor color);
void setEven(bool even) override;
void setHighlighted(bool highlight) override;
int numberOfSubviews() const override;
@@ -19,7 +18,6 @@ public:
void drawRect(KDContext * ctx, KDRect rect) const override;
private:
constexpr static KDCoordinate k_separatorThickness = 1;
CartesianFunction * m_function;
ExpressionView m_expressionView;
};

View File

@@ -30,8 +30,8 @@ bool ListController::handleEvent(Ion::Events::Event event) {
|| m_selectableTableView.selectedRow() == numberOfRows() - 1) {
return false;
}
FunctionExpressionCell * functionCell = (FunctionExpressionCell *)(m_selectableTableView.cellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow()));
editExpression(functionCell, event);
Shared::Function * function = m_functionStore->functionAtIndex(m_selectableTableView.selectedRow());
editExpression(function, event);
return true;
}
@@ -54,8 +54,8 @@ bool ListController::handleEnter() {
m_selectableTableView.reloadData();
return true;
}
FunctionExpressionCell * functionCell = (FunctionExpressionCell *)(m_selectableTableView.cellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow()));
editExpression(functionCell, Ion::Events::OK);
Shared::Function * function = m_functionStore->functionAtIndex(m_selectableTableView.selectedRow());
editExpression(function, Ion::Events::OK);
return true;
}
default:
@@ -65,23 +65,21 @@ bool ListController::handleEnter() {
}
}
void ListController::editExpression(FunctionExpressionCell * functionCell, Ion::Events::Event event) {
void ListController::editExpression(Function * function, Ion::Events::Event event) {
char * initialText = nullptr;
char initialTextContent[255];
if (event == Ion::Events::OK) {
strlcpy(initialTextContent, functionCell->function()->text(), sizeof(initialTextContent));
strlcpy(initialTextContent, function->text(), sizeof(initialTextContent));
initialText = initialTextContent;
}
App * myApp = (App *)app();
InputViewController * inputController = myApp->inputViewController();
inputController->edit(this, event, functionCell, initialText,
inputController->edit(this, event, function, initialText,
[](void * context, void * sender){
FunctionExpressionCell * myCell = (FunctionExpressionCell *) context;
Shared::Function * myFunction = myCell->function();
Shared::Function * myFunction = (Shared::Function *)context;
InputViewController * myInputViewController = (InputViewController *)sender;
const char * textBody = myInputViewController->textBody();
myFunction->setContent(textBody);
myCell->reloadCell();
},
[](void * context, void * sender){
});
@@ -122,7 +120,12 @@ void ListController::willDisplayTitleCellAtIndex(TableViewCell * cell, int j) {
void ListController::willDisplayExpressionCellAtIndex(TableViewCell * cell, int j) {
FunctionExpressionCell * myCell = (FunctionExpressionCell *)cell;
myCell->setFunction(((CartesianFunctionStore *)m_functionStore)->functionAtIndex(j));
Function * f = m_functionStore->functionAtIndex(j);
myCell->setExpression(f->layout());
bool active = f->isActive();
KDColor textColor = active ? KDColorBlack : Palette::GreyDark;
myCell->setTextColor(textColor);
}
}

View File

@@ -18,7 +18,7 @@ public:
bool handleEvent(Ion::Events::Event event) override;
private:
bool handleEnter();
void editExpression(FunctionExpressionCell * functionCell, Ion::Events::Event event);
void editExpression(Shared::Function * function, Ion::Events::Event event);
Shared::ListParameterController * parameterController() override;
int maxNumberOfRows() override;
TableViewCell * titleCells(int index) override;

View File

@@ -122,6 +122,7 @@ MathToolbox::MathToolbox() :
void MathToolbox::didBecomeFirstResponder() {
m_nodeModel = (ToolboxNode *)rootModel();
m_selectableTableView.reloadData();
StackViewController::didBecomeFirstResponder();
m_stack.resetStack();
m_listController.setFirstSelectedRow(0);
@@ -158,7 +159,6 @@ TableViewCell * MathToolbox::reusableCell(int index, int type) {
}
int MathToolbox::reusableCellCount(int type) {
assert(type < 2);
return k_maxNumberOfDisplayedRows;
}
@@ -210,6 +210,10 @@ void MathToolbox::viewWillDisappear() {
m_selectableTableView.deselectTable();
}
int MathToolbox::stackDepth() {
return m_stack.depth();
}
TextField * MathToolbox::sender() {
return (TextField *)Toolbox::sender();
}

View File

@@ -25,6 +25,11 @@ public:
int typeAtLocation(int i, int j) override;
void viewWillDisappear() override;
protected:
int stackDepth();
TextField * sender() override;
SelectableTableView m_selectableTableView;
constexpr static int k_maxNumberOfDisplayedRows = 6; //240/40
private:
class Stack {
public:
@@ -60,8 +65,6 @@ private:
};
constexpr static KDCoordinate k_nodeRowHeight = 40;
constexpr static KDCoordinate k_leafRowHeight = 40;
constexpr static int k_maxNumberOfDisplayedRows = 6; //240/40
TextField * sender() override;
const ToolboxNode * rootModel();
bool selectLeaf(ToolboxNode * selectedNode);
bool selectSubMenu(ToolboxNode * selectedNode);
@@ -69,7 +72,6 @@ private:
Stack m_stack;
ToolboxLeafCell m_leafCells[k_maxNumberOfDisplayedRows];
ChevronMenuListCell m_nodeCells[k_maxNumberOfDisplayedRows];
SelectableTableView m_selectableTableView;
ListController m_listController;
ToolboxNode * m_nodeModel;
};

View File

@@ -10,6 +10,7 @@ app_objs += $(addprefix apps/sequence/,\
values/values_controller.o\
sequence.o\
sequence_store.o\
sequence_toolbox.o\
)
app_images += apps/sequence/sequence_icon.png

View File

@@ -7,6 +7,7 @@ namespace Sequence {
App::App(Container * container, Context * context) :
TextFieldDelegateApp(container, &m_inputViewController, "Suites", "SUITES", ImageStore::SequenceIcon),
m_sequenceToolbox(SequenceToolbox()),
m_sequenceStore(SequenceStore()),
m_nContext(VariableContext('n', context)),
m_listController(&m_listHeader, &m_sequenceStore, &m_listHeader),
@@ -37,4 +38,12 @@ const char * App::XNT() {
return "n";
}
SequenceToolbox * App::sequenceToolbox() {
return &m_sequenceToolbox;
}
SequenceStore * App::sequenceStore() {
return &m_sequenceStore;
}
}

View File

@@ -4,6 +4,7 @@
#include <escher.h>
#include <poincare.h>
#include "sequence_store.h"
#include "sequence_toolbox.h"
#include "list/list_controller.h"
#include "values/values_controller.h"
#include "../shared/text_field_delegate_app.h"
@@ -16,7 +17,10 @@ public:
InputViewController * inputViewController();
Poincare::Context * localContext() override;
const char * XNT() override;
SequenceToolbox * sequenceToolbox();
SequenceStore * sequenceStore();
private:
SequenceToolbox m_sequenceToolbox;
SequenceStore m_sequenceStore;
Poincare::VariableContext m_nContext;
ListController m_listController;

View File

@@ -67,11 +67,11 @@ bool ListController::handleEvent(Ion::Events::Event event) {
void ListController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) {
if (m_functionStore->numberOfFunctions() == m_functionStore->maxNumberOfFunctions() || t->selectedRow() < numberOfRows() - 1) {
SequenceCell * myCell = (SequenceCell *)t->cellAtLocation(t->selectedColumn(), t->selectedRow());
app()->setFirstResponder(myCell);
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());

View File

@@ -66,6 +66,32 @@ bool SequenceExpressionCell::handleEvent(Ion::Events::Event event) {
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;
@@ -92,6 +118,7 @@ void SequenceExpressionCell::editExpression(Ion::Events::Event event) {
}
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){

View File

@@ -3,18 +3,21 @@
#include "../sequence.h"
#include "sequence_cell.h"
#include "../../shared/text_field_delegate.h"
#include <escher.h>
namespace Sequence {
class SequenceExpressionCell : public SequenceCell {
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;

View File

@@ -0,0 +1,93 @@
#include "sequence_toolbox.h"
#include "../../poincare/src/layout/baseline_relative_layout.h"
#include "../../poincare/src/layout/string_layout.h"
#include <assert.h>
using namespace Poincare;
namespace Sequence {
SequenceToolbox::SequenceToolbox() :
MathToolbox(),
m_numberOfAddedCells(0)
{
}
bool SequenceToolbox::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::OK && stackDepth() == 0) {
int selectedRow = m_selectableTableView.selectedRow();
if (selectedRow < m_numberOfAddedCells) {
return selectAddedCell(selectedRow);
}
}
return MathToolbox::handleEvent(event);
}
int SequenceToolbox::numberOfRows() {
if (stackDepth() == 0) {
return MathToolbox::numberOfRows()+m_numberOfAddedCells;
}
return MathToolbox::numberOfRows();
}
TableViewCell * SequenceToolbox::reusableCell(int index, int type) {
assert(type < 3);
assert(index >= 0);
assert(index < k_maxNumberOfDisplayedRows);
if (type == 2) {
return &m_addedCells[index];
}
return MathToolbox::reusableCell(index, type);
}
void SequenceToolbox::willDisplayCellForIndex(TableViewCell * cell, int index) {
if (typeAtLocation(0, index) == 2) {
ExpressionMenuListCell * myCell = (ExpressionMenuListCell *)cell;
myCell->setExpression(m_addedCellLayout[index]);
return;
} else {
MathToolbox::willDisplayCellForIndex(cell, index);
}
}
KDCoordinate SequenceToolbox::rowHeight(int j) {
if (typeAtLocation(0, j) == 2) {
return k_addedRowHeight;
}
return MathToolbox::rowHeight(j);
}
int SequenceToolbox::typeAtLocation(int i, int j) {
if (stackDepth() == 0 && j < m_numberOfAddedCells) {
return 2;
}
return MathToolbox::typeAtLocation(i,j);
}
void SequenceToolbox::addCells(int numberOfAddedCells, char ** cellNames, char ** cellSubscript) {
m_numberOfAddedCells = numberOfAddedCells;
for (int i = 0; i < numberOfAddedCells; i++) {
m_addedCellLayout[i] = new BaselineRelativeLayout(new StringLayout(cellNames[i], 1, KDText::FontSize::Large), new StringLayout(cellSubscript[i], strlen(cellSubscript[i]), KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript);
}
}
bool SequenceToolbox::selectAddedCell(int selectedRow){
char buffer[10];
BaselineRelativeLayout * layout = (BaselineRelativeLayout *)m_addedCellLayout[selectedRow];
StringLayout * nameLayout = (StringLayout *)layout->baseLayout();
StringLayout * subscriptLayout = (StringLayout *)layout->indiceLayout();
int currentChar = 0;
strlcpy(buffer, nameLayout->text(), strlen(nameLayout->text())+1);
currentChar += strlen(nameLayout->text());
buffer[currentChar++] = '(';
strlcpy(buffer+currentChar, subscriptLayout->text(), strlen(subscriptLayout->text())+1);
currentChar += strlen(subscriptLayout->text());
buffer[currentChar++] = ')';
buffer[currentChar] = 0;
sender()->insertTextAtLocation(buffer, sender()->cursorLocation());
sender()->setCursorLocation(sender()->cursorLocation()+currentChar);
app()->dismissModalViewController();
return true;
}
}

View File

@@ -0,0 +1,28 @@
#ifndef SEQUENCE_SEQUENCE_TOOLBOX_H
#define SEQUENCE_SEQUENCE_TOOLBOX_H
#include "../math_toolbox.h"
namespace Sequence {
class SequenceToolbox : public MathToolbox {
public:
SequenceToolbox();
bool handleEvent(Ion::Events::Event event) override;
int numberOfRows() override;
TableViewCell * reusableCell(int index, int type) override;
void willDisplayCellForIndex(TableViewCell * cell, int index) override;
KDCoordinate rowHeight(int j) override;
int typeAtLocation(int i, int j) override;
void addCells(int numberOfAddedCells, char ** cellNames, char ** cellSubscripts);
private:
bool selectAddedCell(int selectedRow);
constexpr static KDCoordinate k_addedRowHeight = 20;
ExpressionMenuListCell m_addedCells[k_maxNumberOfDisplayedRows];
Poincare::ExpressionLayout * m_addedCellLayout[k_maxNumberOfDisplayedRows];
int m_numberOfAddedCells;
};
}
#endif

View File

@@ -12,6 +12,7 @@ public:
const char * title() const override;
void edit(Responder * caller, Ion::Events::Event event, void * context, const char * initialText, Invocation::Action successAction, Invocation::Action failureAction);
const char * textBody();
void setTextFieldDelegate(TextFieldDelegate * textFieldDelegate);
bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override;
bool textFieldDidFinishEditing(TextField * textField, const char * text) override;
bool textFieldDidAbortEditing(TextField * textField, const char * text) override;

View File

@@ -49,6 +49,10 @@ void InputViewController::edit(Responder * caller, Ion::Events::Event event, voi
}
}
void InputViewController::setTextFieldDelegate(TextFieldDelegate * textFieldDelegate) {
m_textFieldDelegate = textFieldDelegate;
}
bool InputViewController::textFieldDidFinishEditing(TextField * textField, const char * text) {
m_successAction.perform(this);
dismissModalViewController();

View File

@@ -21,6 +21,14 @@ BaselineRelativeLayout::~BaselineRelativeLayout() {
delete m_indiceLayout;
}
ExpressionLayout * BaselineRelativeLayout::baseLayout() {
return m_baseLayout;
}
ExpressionLayout * BaselineRelativeLayout::indiceLayout() {
return m_indiceLayout;
}
void BaselineRelativeLayout::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) {
// There is nothing to draw for a subscript/superscript, only the position of the children matters
}

View File

@@ -14,6 +14,8 @@ class BaselineRelativeLayout : public ExpressionLayout {
};
BaselineRelativeLayout(ExpressionLayout * baseLayout, ExpressionLayout * indiceLayout, Type type);
~BaselineRelativeLayout();
ExpressionLayout * baseLayout();
ExpressionLayout * indiceLayout();
protected:
void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) override;
KDSize computeSize() override;

View File

@@ -19,6 +19,10 @@ StringLayout::~StringLayout() {
free(m_string);
}
char * StringLayout::text() {
return m_string;
}
ExpressionLayout * StringLayout::child(uint16_t index) {
return nullptr;
}

View File

@@ -13,6 +13,7 @@ class StringLayout : public ExpressionLayout {
// sure about compatibility.
StringLayout(const char * string, size_t length, KDText::FontSize fontSize = KDText::FontSize::Large);
~StringLayout();
char * text();
protected:
void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) override;
KDSize computeSize() override;