mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[apps][poincare] Add matrix variables M0-M9
Change-Id: I09d82633ac9ffafc616c2be1e16575f2a5b730f7
This commit is contained in:
@@ -13,14 +13,18 @@ const ToolboxNode probabilityChildren[2] = {ToolboxNode(I18n::Message::BinomialC
|
||||
const ToolboxNode arithmeticChildren[4] = {ToolboxNode(I18n::Message::GcdCommandWithArg, I18n::Message::GreatCommonDivisor, I18n::Message::GcdCommand),ToolboxNode(I18n::Message::LcmCommandWithArg, I18n::Message::LeastCommonMultiple, I18n::Message::LcmCommand), ToolboxNode(I18n::Message::RemCommandWithArg, I18n::Message::Remainder, I18n::Message::RemCommand), ToolboxNode(I18n::Message::QuoCommandWithArg, I18n::Message::Quotient, I18n::Message::QuoCommand)};
|
||||
#if MATRICES_ARE_DEFINED
|
||||
const ToolboxNode matricesChildren[5] = {ToolboxNode(I18n::Message::InverseCommandWithArg, I18n::Message::Inverse, I18n::Message::InverseCommand), ToolboxNode(I18n::Message::DeterminantCommandWithArg, I18n::Message::Determinant, I18n::Message::DeterminantCommand), ToolboxNode(I18n::Message::TransposeCommandWithArg, I18n::Message::Transpose, I18n::Message::TransposeCommand), ToolboxNode(I18n::Message::TraceCommandWithArg, I18n::Message::Trace, I18n::Message::TraceCommand), ToolboxNode(I18n::Message::DimensionCommandWithArg, I18n::Message::Dimension, I18n::Message::DimensionCommand)};
|
||||
#endif
|
||||
#if LIST_ARE_DEFINED
|
||||
const ToolboxNode listesChildren[5] = {ToolboxNode(I18n::Message::SortCommandWithArg, I18n::Message::Sort, I18n::Message::SortCommand), ToolboxNode(I18n::Message::InvSortCommandWithArg, I18n::Message::InvSort, I18n::Message::InvSortCommand), ToolboxNode(I18n::Message::MaxCommandWithArg, I18n::Message::Maximum, I18n::Message::MaxCommand), ToolboxNode(I18n::Message::MinCommandWithArg, I18n::Message::Minimum, I18n::Message::MinCommand), ToolboxNode(I18n::Message::DimensionCommandWithArg, I18n::Message::Dimension, I18n::Message::DimensionCommand)};
|
||||
#endif
|
||||
const ToolboxNode approximationChildren[4] = {ToolboxNode(I18n::Message::FloorCommandWithArg, I18n::Message::Floor, I18n::Message::FloorCommand), ToolboxNode(I18n::Message::FracCommandWithArg, I18n::Message::FracPart, I18n::Message::FracCommand), ToolboxNode(I18n::Message::CeilCommandWithArg, I18n::Message::Ceiling, I18n::Message::CeilCommand), ToolboxNode(I18n::Message::RoundCommandWithArg, I18n::Message::Rounding, I18n::Message::RoundCommand)};
|
||||
const ToolboxNode trigonometryChildren[6] = {ToolboxNode(I18n::Message::CoshCommandWithArg, I18n::Message::Cosh, I18n::Message::CoshCommand), ToolboxNode(I18n::Message::SinhCommandWithArg, I18n::Message::Sinh, I18n::Message::SinhCommand), ToolboxNode(I18n::Message::TanhCommandWithArg, I18n::Message::Tanh, I18n::Message::TanhCommand), ToolboxNode(I18n::Message::AcoshCommandWithArg, I18n::Message::Acosh, I18n::Message::AcoshCommand), ToolboxNode(I18n::Message::AsinhCommandWithArg, I18n::Message::Asinh, I18n::Message::AsinhCommand), ToolboxNode(I18n::Message::AtanhCommandWithArg, I18n::Message::Atanh, I18n::Message::AtanhCommand)};
|
||||
const ToolboxNode predictionChildren[3] = {ToolboxNode(I18n::Message::Prediction95CommandWithArg, I18n::Message::Prediction95, I18n::Message::Prediction95Command), ToolboxNode(I18n::Message::PredictionCommandWithArg, I18n::Message::Prediction, I18n::Message::PredictionCommand), ToolboxNode(I18n::Message::ConfidenceCommandWithArg, I18n::Message::Confidence, I18n::Message::ConfidenceCommand)};
|
||||
|
||||
#if MATRICES_ARE_DEFINED
|
||||
#if LIST_ARE_DEFINED
|
||||
const ToolboxNode menu[12] = {ToolboxNode(I18n::Message::AbsCommandWithArg, I18n::Message::AbsoluteValue, I18n::Message::AbsCommand),
|
||||
#elif MATRICES_ARE_DEFINED
|
||||
const ToolboxNode menu[11] = {ToolboxNode(I18n::Message::AbsCommandWithArg, I18n::Message::AbsoluteValue, I18n::Message::AbsCommand),
|
||||
#else
|
||||
const ToolboxNode menu[10] = {ToolboxNode(I18n::Message::AbsCommandWithArg, I18n::Message::AbsoluteValue, I18n::Message::AbsCommand),
|
||||
#endif
|
||||
@@ -32,13 +36,17 @@ const ToolboxNode menu[10] = {ToolboxNode(I18n::Message::AbsCommandWithArg, I18n
|
||||
ToolboxNode(I18n::Message::Arithmetic, I18n::Message::Default, I18n::Message::Default, arithmeticChildren, 4),
|
||||
#if MATRICES_ARE_DEFINED
|
||||
ToolboxNode(I18n::Message::Matrices, I18n::Message::Default, I18n::Message::Default, matricesChildren, 5),
|
||||
#endif
|
||||
#if LIST_ARE_DEFINED
|
||||
ToolboxNode(I18n::Message::Lists, I18n::Message::Default, I18n::Message::Default, listesChildren, 5),
|
||||
#endif
|
||||
ToolboxNode(I18n::Message::Approximation, I18n::Message::Default, I18n::Message::Default, approximationChildren, 4),
|
||||
ToolboxNode(I18n::Message::HyperbolicTrigonometry, I18n::Message::Default, I18n::Message::Default, trigonometryChildren, 6),
|
||||
ToolboxNode(I18n::Message::Fluctuation, I18n::Message::Default, I18n::Message::Default, predictionChildren, 3)};
|
||||
#if MATRICES_ARE_DEFINED
|
||||
#if LIST_ARE_DEFINED
|
||||
const ToolboxNode toolboxModel = ToolboxNode(I18n::Message::Toolbox, I18n::Message::Default, I18n::Message::Default, menu, 12);
|
||||
#elif MATRICES_ARE_DEFINED
|
||||
const ToolboxNode toolboxModel = ToolboxNode(I18n::Message::Toolbox, I18n::Message::Default, I18n::Message::Default, menu, 11);
|
||||
#else
|
||||
const ToolboxNode toolboxModel = ToolboxNode(I18n::Message::Toolbox, I18n::Message::Default, I18n::Message::Default, menu, 10);
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef APPS_MATH_TOOLBOX_H
|
||||
#define APPS_MATH_TOOLBOX_H
|
||||
|
||||
#define MATRICES_ARE_DEFINED 1
|
||||
#include <escher.h>
|
||||
#include "toolbox_node.h"
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ void VariableBoxController::ContentViewController::didBecomeFirstResponder() {
|
||||
}
|
||||
|
||||
bool VariableBoxController::ContentViewController::handleEvent(Ion::Events::Event event) {
|
||||
#if MATRIX_LIST_VARIABLES
|
||||
#if MATRIX_VARIABLES
|
||||
if (event == Ion::Events::Back && m_currentPage == Page::RootMenu) {
|
||||
#else
|
||||
if (event == Ion::Events::Back && m_currentPage == Page::Scalar) {
|
||||
@@ -43,17 +43,19 @@ bool VariableBoxController::ContentViewController::handleEvent(Ion::Events::Even
|
||||
}
|
||||
if (event == Ion::Events::Back || event == Ion::Events::Left) {
|
||||
m_firstSelectedRow = m_previousSelectedRow;
|
||||
#if MATRIX_LIST_VARIABLES
|
||||
#if MATRIX_VARIABLES
|
||||
m_selectableTableView.deselectTable();
|
||||
m_currentPage = Page::RootMenu;
|
||||
#endif
|
||||
app()->setFirstResponder(this);
|
||||
return true;
|
||||
}
|
||||
if (event == Ion::Events::OK || event == Ion::Events::EXE || (event == Ion::Events::Right && m_currentPage == Page::RootMenu)) {
|
||||
if (m_currentPage == Page::RootMenu) {
|
||||
if (m_currentPage == Page::RootMenu) {
|
||||
m_previousSelectedRow = selectedRow();
|
||||
m_firstSelectedRow = 0;
|
||||
m_currentPage = pageAtIndex(selectedRow());
|
||||
m_selectableTableView.deselectTable();
|
||||
m_currentPage = pageAtIndex(m_previousSelectedRow);
|
||||
app()->setFirstResponder(this);
|
||||
return true;
|
||||
}
|
||||
@@ -66,7 +68,8 @@ bool VariableBoxController::ContentViewController::handleEvent(Ion::Events::Even
|
||||
}
|
||||
m_textFieldCaller->insertTextAtLocation(editedText, m_textFieldCaller->cursorLocation());
|
||||
m_textFieldCaller->setCursorLocation(m_textFieldCaller->cursorLocation() + strlen(editedText));
|
||||
#if MATRIX_LIST_VARIABLES
|
||||
#if MATRIX_VARIABLES
|
||||
m_selectableTableView.deselectTable();
|
||||
m_currentPage = Page::RootMenu;
|
||||
#endif
|
||||
app()->dismissModalViewController();
|
||||
@@ -78,11 +81,13 @@ bool VariableBoxController::ContentViewController::handleEvent(Ion::Events::Even
|
||||
int VariableBoxController::ContentViewController::numberOfRows() {
|
||||
switch (m_currentPage) {
|
||||
case Page::RootMenu:
|
||||
return 3;
|
||||
return k_numberOfMenuRows;
|
||||
case Page::Scalar:
|
||||
return GlobalContext::k_maxNumberOfScalarExpressions;
|
||||
#if LIST_VARIABLES
|
||||
case Page::List:
|
||||
return GlobalContext::k_maxNumberOfListExpressions;
|
||||
#endif
|
||||
case Page::Matrix:
|
||||
return GlobalContext::k_maxNumberOfMatrixExpressions;
|
||||
default:
|
||||
@@ -130,16 +135,17 @@ void VariableBoxController::ContentViewController::willDisplayCellForIndex(Highl
|
||||
}
|
||||
myCell->displayExpression(true);
|
||||
if (expression) {
|
||||
/* TODO: implement matrix and list contexts */
|
||||
//myCell->setExpression(expression->createLayout());
|
||||
// TODO: display the dimensgion of the list/matrice as subtitle
|
||||
/* char buffer[4];
|
||||
* buffer[0] = (Matrice *)expression->dim(0);
|
||||
* buffer[1] = 'x';
|
||||
* buffer[2] = (Matrice *)expression->dim(1)
|
||||
* buffer[3] = 0;
|
||||
* myCell->setSubtitle(buffer);*/
|
||||
assert(expression->type() == Expression::Type::Matrix);
|
||||
Matrix * m = (Matrix *)expression;
|
||||
/* TODO: implement list contexts */
|
||||
myCell->setExpression((Expression *)expression);
|
||||
char buffer[2*Complex::bufferSizeForFloatsWithPrecision(2)+1];
|
||||
int numberOfChars = Complex::convertFloatToText(m->numberOfRows(), buffer, Complex::bufferSizeForFloatsWithPrecision(2), 2, Expression::FloatDisplayMode::Decimal);
|
||||
buffer[numberOfChars++] = 'x';
|
||||
Complex::convertFloatToText(m->numberOfColumns(), buffer+numberOfChars, Complex::bufferSizeForFloatsWithPrecision(2), 2, Expression::FloatDisplayMode::Decimal);
|
||||
myCell->setSubtitle(buffer);
|
||||
} else {
|
||||
myCell->setExpression(nullptr);
|
||||
myCell->setSubtitle("Vide");
|
||||
}
|
||||
}
|
||||
@@ -153,8 +159,10 @@ KDCoordinate VariableBoxController::ContentViewController::rowHeight(int index)
|
||||
}
|
||||
const Expression * expression = expressionForIndex(index);
|
||||
if (expression) {
|
||||
KDCoordinate expressionHeight = expression->createLayout()->size().height();
|
||||
return expressionHeight;
|
||||
ExpressionLayout * layout = expression->createLayout();
|
||||
KDCoordinate expressionHeight = layout->size().height();
|
||||
delete layout;
|
||||
return expressionHeight+k_leafMargin;
|
||||
}
|
||||
return k_leafRowHeight;
|
||||
}
|
||||
@@ -189,16 +197,23 @@ const Expression * VariableBoxController::ContentViewController::expressionForIn
|
||||
return m_context->expressionForSymbol(&symbol);
|
||||
}
|
||||
if (m_currentPage == Page::Matrix) {
|
||||
return nullptr;
|
||||
const Symbol symbol = Symbol::matrixSymbol('0'+(char)index);
|
||||
return m_context->expressionForSymbol(&symbol);
|
||||
}
|
||||
#if LIST_VARIABLES
|
||||
if (m_currentPage == Page::List) {
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
VariableBoxController::ContentViewController::Page VariableBoxController::ContentViewController::pageAtIndex(int index) {
|
||||
#if LIST_VARIABLES
|
||||
Page pages[3] = {Page::Scalar, Page::List, Page::Matrix};
|
||||
#else
|
||||
Page pages[2] = {Page::Scalar, Page::Matrix};
|
||||
#endif
|
||||
return pages[index];
|
||||
}
|
||||
|
||||
@@ -207,11 +222,13 @@ void VariableBoxController::ContentViewController::putLabelAtIndexInBuffer(int i
|
||||
buffer[0] = 'A' + index;
|
||||
buffer[1] = 0;
|
||||
}
|
||||
#if LIST_VARIABLES
|
||||
if (m_currentPage == Page::List) {
|
||||
buffer[0] = 'L';
|
||||
buffer[1] = '0' + index;
|
||||
buffer[2] = 0;
|
||||
}
|
||||
#endif
|
||||
if (m_currentPage == Page::Matrix) {
|
||||
buffer[0] = 'M';
|
||||
buffer[1] = '0' + index;
|
||||
@@ -221,7 +238,11 @@ void VariableBoxController::ContentViewController::putLabelAtIndexInBuffer(int i
|
||||
|
||||
I18n::Message VariableBoxController::ContentViewController::nodeLabelAtIndex(int index) {
|
||||
assert(m_currentPage == Page::RootMenu);
|
||||
#if LIST_VARIABLES
|
||||
I18n::Message labels[3] = {I18n::Message::Number, I18n::Message::List, I18n::Message::Matrix};
|
||||
#else
|
||||
I18n::Message labels[2] = {I18n::Message::Number, I18n::Message::Matrix};
|
||||
#endif
|
||||
return labels[index];
|
||||
}
|
||||
|
||||
@@ -234,13 +255,18 @@ void VariableBoxController::ContentViewController::reloadData() {
|
||||
}
|
||||
|
||||
void VariableBoxController::ContentViewController::resetPage() {
|
||||
#if MATRIX_LIST_VARIABLES
|
||||
#if MATRIX_VARIABLES
|
||||
m_currentPage = Page::RootMenu;
|
||||
#else
|
||||
m_currentPage = Page::Scalar;
|
||||
#endif
|
||||
}
|
||||
|
||||
void VariableBoxController::ContentViewController::viewDidDisappear() {
|
||||
m_selectableTableView.deselectTable();
|
||||
ViewController::viewDidDisappear();
|
||||
}
|
||||
|
||||
VariableBoxController::VariableBoxController(Context * context) :
|
||||
StackViewController(nullptr, &m_contentViewController, true, KDColorWhite, Palette::PurpleBright, Palette::PurpleDark),
|
||||
m_contentViewController(this, context)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef APPS_VARIABLE_BOX_CONTROLLER_H
|
||||
#define APPS_VARIABLE_BOX_CONTROLLER_H
|
||||
|
||||
#define MATRIX_VARIABLES 1
|
||||
|
||||
#include <escher.h>
|
||||
#include <poincare.h>
|
||||
#include "variable_box_leaf_cell.h"
|
||||
@@ -32,16 +34,24 @@ private:
|
||||
void setTextFieldCaller(TextField * textField);
|
||||
void reloadData();
|
||||
void resetPage();
|
||||
void viewDidDisappear() override;
|
||||
private:
|
||||
enum class Page {
|
||||
RootMenu,
|
||||
Scalar,
|
||||
#if LIST_VARIABLES
|
||||
List,
|
||||
#endif
|
||||
Matrix
|
||||
};
|
||||
constexpr static int k_maxNumberOfDisplayedRows = 6; //240/40
|
||||
constexpr static int k_numberOfMenuRows = 3; //240/40
|
||||
#if LIST_VARIABLES
|
||||
constexpr static int k_numberOfMenuRows = 3;
|
||||
#else
|
||||
constexpr static int k_numberOfMenuRows = 2;
|
||||
#endif
|
||||
constexpr static KDCoordinate k_leafRowHeight = 40;
|
||||
constexpr static KDCoordinate k_leafMargin = 10;
|
||||
constexpr static KDCoordinate k_nodeRowHeight = 40;
|
||||
Page pageAtIndex(int index);
|
||||
void putLabelAtIndexInBuffer(int index, char * buffer);
|
||||
|
||||
@@ -5,12 +5,20 @@ using namespace Poincare;
|
||||
|
||||
VariableBoxLeafCell::VariableBoxLeafCell() :
|
||||
HighlightCell(),
|
||||
m_expressionLayout(nullptr),
|
||||
m_labelView(KDText::FontSize::Small, 0, 0.5, KDColorBlack, KDColorWhite),
|
||||
m_subtitleView(KDText::FontSize::Small, 0, 0.5, Palette::GreyDark, KDColorWhite),
|
||||
m_expressionView(1.0f, 0.5f),
|
||||
m_displayExpression(false)
|
||||
{
|
||||
}
|
||||
|
||||
VariableBoxLeafCell::~VariableBoxLeafCell() {
|
||||
if (m_expressionLayout != nullptr) {
|
||||
delete m_expressionLayout;
|
||||
m_expressionLayout = nullptr;
|
||||
}
|
||||
}
|
||||
void VariableBoxLeafCell::displayExpression(bool displayExpression) {
|
||||
m_displayExpression = displayExpression;
|
||||
}
|
||||
@@ -37,10 +45,19 @@ void VariableBoxLeafCell::layoutSubviews() {
|
||||
KDCoordinate width = bounds().width();
|
||||
KDCoordinate height = bounds().height();
|
||||
if (numberOfSubviews() == 3) {
|
||||
m_labelView.setFrame(KDRect(k_separatorThickness+k_widthMargin, k_separatorThickness, width/2-k_separatorThickness-k_widthMargin, height/2 - k_separatorThickness));
|
||||
m_subtitleView.setFrame(KDRect(k_separatorThickness+k_widthMargin, height/2, width/2-k_widthMargin-k_separatorThickness, height/2-k_separatorThickness));
|
||||
KDSize labelSize = m_labelView.minimalSizeForOptimalDisplay();
|
||||
KDSize subtitleSize = m_subtitleView.minimalSizeForOptimalDisplay();
|
||||
m_labelView.setFrame(KDRect(k_separatorThickness+k_widthMargin, k_separatorThickness, labelSize.width(), height/2 - k_separatorThickness));
|
||||
m_subtitleView.setFrame(KDRect(k_separatorThickness+k_widthMargin, height/2, subtitleSize.width(), height/2-k_separatorThickness));
|
||||
m_subtitleView.setAlignment(0.0f, 0.5f);
|
||||
m_expressionView.setFrame(KDRect(width/2, k_separatorThickness, width/2-k_separatorThickness-k_widthMargin, height-2*k_separatorThickness));
|
||||
KDCoordinate maxTextSize = subtitleSize.width() > labelSize.width() ? subtitleSize.width() : labelSize.width();
|
||||
KDCoordinate expressionAvailableSize = width-k_separatorThickness-3*k_widthMargin-maxTextSize;
|
||||
m_expressionView.setFrame(KDRect(width - expressionAvailableSize - k_widthMargin, k_separatorThickness, expressionAvailableSize, height-2*k_separatorThickness));
|
||||
if (m_expressionView.minimalSizeForOptimalDisplay().width() > expressionAvailableSize) {
|
||||
m_expressionView.setAlignment(0.0f, 0.5f);
|
||||
} else {
|
||||
m_expressionView.setAlignment(1.0f, 0.5f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
m_labelView.setFrame(KDRect(k_separatorThickness+k_widthMargin, k_separatorThickness, width/2-k_separatorThickness-k_widthMargin, height-2*k_separatorThickness));
|
||||
@@ -66,8 +83,15 @@ void VariableBoxLeafCell::setSubtitle(const char * text) {
|
||||
layoutSubviews();
|
||||
}
|
||||
|
||||
void VariableBoxLeafCell::setExpression(ExpressionLayout * expressionLayout) {
|
||||
m_expressionView.setExpression(expressionLayout);
|
||||
void VariableBoxLeafCell::setExpression(Expression * expression) {
|
||||
if(m_expressionLayout != nullptr) {
|
||||
delete m_expressionLayout;
|
||||
m_expressionLayout = nullptr;
|
||||
}
|
||||
if (expression) {
|
||||
m_expressionLayout = expression->createLayout();
|
||||
}
|
||||
m_expressionView.setExpression(m_expressionLayout);
|
||||
}
|
||||
|
||||
void VariableBoxLeafCell::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
|
||||
@@ -2,15 +2,17 @@
|
||||
#define APPS_VARIABLE_BOX_LEAF_CELL_H
|
||||
|
||||
#include <escher.h>
|
||||
#include <poincare.h>
|
||||
|
||||
class VariableBoxLeafCell : public HighlightCell {
|
||||
public:
|
||||
VariableBoxLeafCell();
|
||||
~VariableBoxLeafCell();
|
||||
void displayExpression(bool displayExpression);
|
||||
void reloadCell() override;
|
||||
void setLabel(const char * text);
|
||||
void setSubtitle(const char * text);
|
||||
void setExpression(Poincare::ExpressionLayout * expressionLayout);
|
||||
void setExpression(Poincare::Expression * expression);
|
||||
void drawRect(KDContext * ctx, KDRect rect) const override;
|
||||
private:
|
||||
constexpr static KDCoordinate k_separatorThickness = 1;
|
||||
@@ -18,6 +20,9 @@ private:
|
||||
int numberOfSubviews() const override;
|
||||
View * subviewAtIndex(int index) override;
|
||||
void layoutSubviews() override;
|
||||
/* The cell is responsible to delete the layout that may be created by its
|
||||
* dynamic method 'setExpression'.*/
|
||||
Poincare::ExpressionLayout * m_expressionLayout;
|
||||
BufferTextView m_labelView;
|
||||
BufferTextView m_subtitleView;
|
||||
ExpressionView m_expressionView;
|
||||
|
||||
@@ -29,6 +29,7 @@ public:
|
||||
private:
|
||||
int symbolIndex(const Symbol * symbol) const;
|
||||
Expression * m_expressions[k_maxNumberOfScalarExpressions];
|
||||
Expression * m_matrixExpressions[k_maxNumberOfMatrixExpressions];
|
||||
Complex m_pi;
|
||||
Complex m_e;
|
||||
};
|
||||
|
||||
@@ -8,19 +8,33 @@ namespace Poincare {
|
||||
class Symbol : public LeafExpression {
|
||||
public:
|
||||
enum SpecialSymbols : char {
|
||||
Ans = '^',
|
||||
un = 1,
|
||||
un1 = 2,
|
||||
vn = 3,
|
||||
vn1 = 4,
|
||||
wn = 5,
|
||||
wn1 = 6
|
||||
/* We can use characters from 1 to 31 as they do not correspond to usual
|
||||
* characters but events as 'end of text', 'backspace'... */
|
||||
Ans = 1,
|
||||
un = 2,
|
||||
un1 = 3,
|
||||
vn = 4,
|
||||
vn1 = 5,
|
||||
wn = 6,
|
||||
wn1 = 7,
|
||||
M0 = 8,
|
||||
M1 = 9,
|
||||
M2,
|
||||
M3,
|
||||
M4,
|
||||
M5,
|
||||
M6,
|
||||
M7,
|
||||
M8,
|
||||
M9 = 17
|
||||
};
|
||||
static SpecialSymbols matrixSymbol(char index);
|
||||
Symbol(char name);
|
||||
Type type() const override;
|
||||
const char name() const;
|
||||
Expression * clone() const override;
|
||||
bool valueEquals(const Expression * e) const override;
|
||||
bool isMatrixSymbol() const;
|
||||
private:
|
||||
float privateApproximate(Context& context, AngleUnit angleUnit) const override;
|
||||
Expression * privateEvaluate(Context& context, AngleUnit angleUnit) const override;
|
||||
|
||||
@@ -84,6 +84,7 @@ using namespace Poincare;
|
||||
[0-9]+ { poincare_expression_yylval.string.address = yytext; poincare_expression_yylval.string.length = yyleng; return DIGITS; }
|
||||
[A-Zxn] { poincare_expression_yylval.character = yytext[0]; return SYMBOL; }
|
||||
[a-z;:"_=<>] { return UNDEFINED_SYMBOL; }
|
||||
M[0-9] { poincare_expression_yylval.character = Symbol::matrixSymbol(yytext[1]); return SYMBOL; }
|
||||
u\(n\) { poincare_expression_yylval.character = Symbol::SpecialSymbols::un; return SYMBOL; }
|
||||
u\(n\+1\) { poincare_expression_yylval.character = Symbol::SpecialSymbols::un1; return SYMBOL; }
|
||||
v\(n\) { poincare_expression_yylval.character = Symbol::SpecialSymbols::vn; return SYMBOL; }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <poincare/global_context.h>
|
||||
#include <poincare/matrix.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <ion.h>
|
||||
@@ -12,6 +13,9 @@ GlobalContext::GlobalContext() :
|
||||
for (int i = 0; i < k_maxNumberOfScalarExpressions; i++) {
|
||||
m_expressions[i] = nullptr;
|
||||
}
|
||||
for (int i = 0; i < k_maxNumberOfMatrixExpressions ; i++) {
|
||||
m_matrixExpressions[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
GlobalContext::~GlobalContext() {
|
||||
@@ -21,6 +25,12 @@ GlobalContext::~GlobalContext() {
|
||||
}
|
||||
m_expressions[i] = nullptr;
|
||||
}
|
||||
for (int i = 0; i < k_maxNumberOfMatrixExpressions; i++) {
|
||||
if (m_matrixExpressions[i] != nullptr) {
|
||||
delete m_matrixExpressions[i];
|
||||
}
|
||||
m_matrixExpressions[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Complex * GlobalContext::defaultExpression() {
|
||||
@@ -40,6 +50,10 @@ const Expression * GlobalContext::expressionForSymbol(const Symbol * symbol) {
|
||||
if (symbol->name() == Ion::Charset::Exponential) {
|
||||
return &m_e;
|
||||
}
|
||||
if (symbol->isMatrixSymbol()) {
|
||||
int indexMatrix = symbol->name() - (char)Symbol::SpecialSymbols::M0;
|
||||
return m_matrixExpressions[indexMatrix];
|
||||
}
|
||||
int index = symbolIndex(symbol);
|
||||
if (index < 0 || index >= k_maxNumberOfScalarExpressions) {
|
||||
return nullptr;
|
||||
@@ -51,6 +65,18 @@ const Expression * GlobalContext::expressionForSymbol(const Symbol * symbol) {
|
||||
}
|
||||
|
||||
void GlobalContext::setExpressionForSymbolName(Expression * expression, const Symbol * symbol) {
|
||||
if (symbol->isMatrixSymbol()) {
|
||||
int indexMatrix = symbol->name() - (char)Symbol::SpecialSymbols::M0;
|
||||
assert(indexMatrix >= 0 && indexMatrix < k_maxNumberOfMatrixExpressions);
|
||||
if (m_expressions[indexMatrix] != nullptr) {
|
||||
delete m_matrixExpressions[indexMatrix];
|
||||
m_matrixExpressions[indexMatrix] = nullptr;
|
||||
}
|
||||
if (expression->type() == Expression::Type::Matrix) {
|
||||
m_matrixExpressions[indexMatrix] = expression->clone();
|
||||
}
|
||||
return;
|
||||
}
|
||||
int index = symbolIndex(symbol);
|
||||
if (index < 0 || index >= k_maxNumberOfScalarExpressions) {
|
||||
return;
|
||||
|
||||
@@ -10,6 +10,34 @@ extern "C" {
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
Symbol::SpecialSymbols Symbol::matrixSymbol(char index) {
|
||||
switch (index - '0') {
|
||||
case 0:
|
||||
return SpecialSymbols::M0;
|
||||
case 1:
|
||||
return SpecialSymbols::M1;
|
||||
case 2:
|
||||
return SpecialSymbols::M2;
|
||||
case 3:
|
||||
return SpecialSymbols::M3;
|
||||
case 4:
|
||||
return SpecialSymbols::M4;
|
||||
case 5:
|
||||
return SpecialSymbols::M5;
|
||||
case 6:
|
||||
return SpecialSymbols::M6;
|
||||
case 7:
|
||||
return SpecialSymbols::M7;
|
||||
case 8:
|
||||
return SpecialSymbols::M8;
|
||||
case 9:
|
||||
return SpecialSymbols::M9;
|
||||
default:
|
||||
assert(false);
|
||||
return SpecialSymbols::M0;
|
||||
}
|
||||
}
|
||||
|
||||
Symbol::Symbol(char name) :
|
||||
m_name(name)
|
||||
{
|
||||
@@ -64,6 +92,11 @@ ExpressionLayout * Symbol::privateCreateLayout(FloatDisplayMode floatDisplayMode
|
||||
if (m_name == SpecialSymbols::wn1) {
|
||||
return new BaselineRelativeLayout(new StringLayout("w", 1), new StringLayout("n+1",3, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript);
|
||||
}
|
||||
if (isMatrixSymbol()) {
|
||||
char mi[3] = "M0";
|
||||
mi[1] = m_name-(char)SpecialSymbols::M0+'0';
|
||||
return new StringLayout(mi, 2);
|
||||
}
|
||||
return new StringLayout(&m_name, 1);
|
||||
}
|
||||
|
||||
@@ -76,4 +109,11 @@ bool Symbol::valueEquals(const Expression * e) const {
|
||||
return (m_name == ((Symbol *)e)->m_name);
|
||||
}
|
||||
|
||||
bool Symbol::isMatrixSymbol() const {
|
||||
if (m_name >= (char)SpecialSymbols::M0 && m_name <= (char)SpecialSymbols::M9) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user