diff --git a/apps/regression/Makefile b/apps/regression/Makefile index fa4722579..4c1c202a1 100644 --- a/apps/regression/Makefile +++ b/apps/regression/Makefile @@ -15,6 +15,7 @@ app_objs += $(addprefix apps/regression/,\ levenberg_marquardt.o\ prediction_parameter_controller.o\ regression_context.o\ + regression_controller.o\ store.o\ store_controller.o\ store_parameter_controller.o\ diff --git a/apps/regression/base.de.i18n b/apps/regression/base.de.i18n index c638f2358..98e2d3717 100644 --- a/apps/regression/base.de.i18n +++ b/apps/regression/base.de.i18n @@ -11,3 +11,13 @@ ValueNotReachedByRegression = "Wert wird nicht von der Regression erreicht" NumberOfDots = "Punktanzahl" Covariance = "Kovarianz" ChangeRegression = "Change regression" +RegressionChoice = "Regression choice" +Linear = "Linear" +Quadratic = "Quadratic" +Cubic = "Cubic" +Quartic = "Quartic" +Logarithmic = "Logarithmic" +Exponential = "Exponential" +Power = "Power" +Trigonometric = "Trigonometric" +Logistic = "Logistic" diff --git a/apps/regression/base.en.i18n b/apps/regression/base.en.i18n index b03ceef92..40c0d2923 100644 --- a/apps/regression/base.en.i18n +++ b/apps/regression/base.en.i18n @@ -11,3 +11,13 @@ ValueNotReachedByRegression = "Value not reached by regression" NumberOfDots = "Number of points" Covariance = "Covariance" ChangeRegression = "Change regression" +RegressionChoice = "Regression choice" +Linear = "Linear" +Quadratic = "Quadratic" +Cubic = "Cubic" +Quartic = "Quartic" +Logarithmic = "Logarithmic" +Exponential = "Exponential" +Power = "Power" +Trigonometric = "Trigonometric" +Logistic = "Logistic" diff --git a/apps/regression/base.es.i18n b/apps/regression/base.es.i18n index 487485e28..307e052ad 100644 --- a/apps/regression/base.es.i18n +++ b/apps/regression/base.es.i18n @@ -11,3 +11,13 @@ ValueNotReachedByRegression = "No se alcanza este valor" NumberOfDots = "Numero de puntos" Covariance = "Covarianza" ChangeRegression = "Change regression" +RegressionChoice = "Regression choice" +Linear = "Linear" +Quadratic = "Quadratic" +Cubic = "Cubic" +Quartic = "Quartic" +Logarithmic = "Logarithmic" +Exponential = "Exponential" +Power = "Power" +Trigonometric = "Trigonometric" +Logistic = "Logistic" diff --git a/apps/regression/base.fr.i18n b/apps/regression/base.fr.i18n index ddb287afb..e39211a65 100644 --- a/apps/regression/base.fr.i18n +++ b/apps/regression/base.fr.i18n @@ -11,3 +11,13 @@ ValueNotReachedByRegression = "Valeur non atteinte par la regression" NumberOfDots = "Nombre de points" Covariance = "Covariance" ChangeRegression = "Change regression" +RegressionChoice = "Regression choice" +Linear = "Linear" +Quadratic = "Quadratic" +Cubic = "Cubic" +Quartic = "Quartic" +Logarithmic = "Logarithmic" +Exponential = "Exponential" +Power = "Power" +Trigonometric = "Trigonometric" +Logistic = "Logistic" diff --git a/apps/regression/base.pt.i18n b/apps/regression/base.pt.i18n index 9ae7191ba..2012fd5f1 100644 --- a/apps/regression/base.pt.i18n +++ b/apps/regression/base.pt.i18n @@ -11,3 +11,13 @@ ValueNotReachedByRegression = "Valor nao alcancado pela regressao" NumberOfDots = "Numero de pontos" Covariance = "Covariancia" ChangeRegression = "Change regression" +RegressionChoice = "Regression choice" +Linear = "Linear" +Quadratic = "Quadratic" +Cubic = "Cubic" +Quartic = "Quartic" +Logarithmic = "Logarithmic" +Exponential = "Exponential" +Power = "Power" +Trigonometric = "Trigonometric" +Logistic = "Logistic" diff --git a/apps/regression/regression_controller.cpp b/apps/regression/regression_controller.cpp new file mode 100644 index 000000000..1ef628bf2 --- /dev/null +++ b/apps/regression/regression_controller.cpp @@ -0,0 +1,73 @@ +#include "regression_controller.h" +#include + +using namespace Poincare; + +namespace Regression { + +RegressionController::RegressionController(Responder * parentResponder, Store * store) : + ViewController(parentResponder), + SimpleListViewDataSource(), + SelectableTableViewDataSource(), + m_selectableTableView(this, this, this), + m_store(store), + m_series(-1) +{ + /*// aX+b + m_regressionLayouts[0] = LayoutEngine::createStringLayout("aX+b"); + // aX^2+bX+c + const ExpressionLayout * const * quadraticLayoutOperands[] = { + + }; + m_regressionLayouts[1] + // aX^3+bX^2+cX+d + //TODO + // aX^4+bX^3+cX^2+dX+e + //TODO + // aln(X)+b + m_regressionLayouts[4] = LayoutEngine::createStringLayout("aln(X)+b"); + // ae^(bX) + //TODO + //aX^b + //TODO + // asin(bX+c) + m_regressionLayouts[7] = LayoutEngine::createStringLayout("asin(bX+c)"); + // c/(1+ae^(-bX) + //TODO*/ +} + +const char * RegressionController::title() { + return I18n::translate(I18n::Message::RegressionChoice); +} + +void RegressionController::didBecomeFirstResponder() { + selectCellAtLocation(0, 0); + app()->setFirstResponder(&m_selectableTableView); +} + +bool RegressionController::handleEvent(Ion::Events::Event event) { + if (event == Ion::Events::OK || event == Ion::Events::EXE) { + assert(m_series > -1); + m_store->setSeriesRegressionType(m_series, (Model::Type)selectedRow()); + StackViewController * stack = static_cast(parentResponder()); + stack->pop(); + return true; + } + return false; +} + +HighlightCell * RegressionController::reusableCell(int index) { + assert(index >= 0); + assert(index < k_numberOfCells); + return &m_regressionCells[index]; +} + +void RegressionController::willDisplayCellAtLocation(HighlightCell * cell, int i, int j) { + assert(i == 0); + assert(j >= 0 && j < k_numberOfRows); + I18n::Message messages[k_numberOfRows] = {I18n::Message::Linear, I18n::Message::Quadratic, I18n::Message::Cubic, I18n::Message::Quartic, I18n::Message::Logarithmic, I18n::Message::Exponential, I18n::Message::Power, I18n::Message::Trigonometric, I18n::Message::Logistic}; + MessageTableCellWithExpression * castedCell = static_cast(cell); + castedCell->setMessage(messages[j]); +} + +} diff --git a/apps/regression/regression_controller.h b/apps/regression/regression_controller.h new file mode 100644 index 000000000..3be2500a7 --- /dev/null +++ b/apps/regression/regression_controller.h @@ -0,0 +1,42 @@ +#ifndef REGRESSION_REGRESSION_CONTROLLER_H +#define REGRESSION_REGRESSION_CONTROLLER_H + +#include "store.h" +#include +#include "../i18n.h" + +namespace Regression { + +class RegressionController : public ViewController, public SimpleListViewDataSource, public SelectableTableViewDataSource { +public: + RegressionController(Responder * parentResponder, Store * store); + void setSeries(int series) { m_series = series; } + // ViewController + const char * title() override; + View * view() override { return &m_selectableTableView; } + + // Responder + bool handleEvent(Ion::Events::Event event) override; + void didBecomeFirstResponder() override; + + // SimpleListViewDataSource + KDCoordinate cellHeight() override { return Metric::ParameterCellHeight; } + HighlightCell * reusableCell(int index) override; + int reusableCellCount() override { return k_numberOfCells; } + + // TableViewDataSource + int numberOfRows() override { return k_numberOfRows; } + void willDisplayCellAtLocation(HighlightCell * cell, int i, int j) override; +private: + constexpr static int k_numberOfRows = 9; + constexpr static int k_numberOfCells = 6; // (240 - 70) / 35 + MessageTableCellWithExpression m_regressionCells[k_numberOfCells]; + //Poincare::ExpressionLayout * m_regressionLayouts[k_numberOfRows]; + SelectableTableView m_selectableTableView; + Store * m_store; + int m_series; +}; + +} + +#endif diff --git a/apps/regression/store.cpp b/apps/regression/store.cpp index 2444be186..291947aef 100644 --- a/apps/regression/store.cpp +++ b/apps/regression/store.cpp @@ -15,6 +15,9 @@ Store::Store() : InteractiveCurveViewRange(nullptr, this), DoublePairStore() { + for (int i = 0; i < k_numberOfSeries; i++) { + m_regressionTypes[i] = Model::Type::Linear; + } } /* Regressions */ diff --git a/apps/regression/store.h b/apps/regression/store.h index 06284e932..9fe91ac27 100644 --- a/apps/regression/store.h +++ b/apps/regression/store.h @@ -1,6 +1,7 @@ #ifndef REGRESSION_STORE_H #define REGRESSION_STORE_H +#include "model/model.h" #include "../shared/interactive_curve_view_range.h" #include "../shared/double_pair_store.h" extern "C" { @@ -14,6 +15,10 @@ public: Store(); // Regression + void setSeriesRegressionType(int series, Model::Type type) { + assert(series >= 0 && series < k_maxNumberOfSeries); + m_regressionTypes[series] = type; + } /* Return the series index of the closest regression at abscissa x, above * ordinate y if direction > 0, below otherwise */ int closestVerticalRegression(int direction, float x, float y, int currentRegressionSeries); @@ -54,6 +59,7 @@ private: float addMargin(float x, float range, bool isMin) override; float maxValueOfColumn(int series, int i) const; float minValueOfColumn(int series, int i) const; + Model::Type m_regressionTypes[k_numberOfSeries]; }; typedef double (Store::*ArgCalculPointer)(int, int) const; diff --git a/apps/regression/store_parameter_controller.cpp b/apps/regression/store_parameter_controller.cpp index 11732f3ab..0fcf5efb7 100644 --- a/apps/regression/store_parameter_controller.cpp +++ b/apps/regression/store_parameter_controller.cpp @@ -4,15 +4,17 @@ namespace Regression { -StoreParameterController::StoreParameterController(Responder * parentResponder, Shared::DoublePairStore * store, StoreController * storeController) : +StoreParameterController::StoreParameterController(Responder * parentResponder, Store * store, StoreController * storeController) : Shared::StoreParameterController(parentResponder, store, storeController), - m_changeRegression(I18n::Message::ChangeRegression) + m_changeRegression(I18n::Message::ChangeRegression), + m_regressionController(this, store) { } bool StoreParameterController::handleEvent(Ion::Events::Event event) { if ((event == Ion::Events::OK || event == Ion::Events::EXE) && selectedRow() == numberOfRows() - 1) { - //TODO + StackViewController * stack = static_cast(parentResponder()); + stack->push(&m_regressionController); return true; } return Shared::StoreParameterController::handleEvent(event); diff --git a/apps/regression/store_parameter_controller.h b/apps/regression/store_parameter_controller.h index dd2a4ee54..0970e15f5 100644 --- a/apps/regression/store_parameter_controller.h +++ b/apps/regression/store_parameter_controller.h @@ -1,6 +1,8 @@ #ifndef REGRESSION_STORE_PARAMETER_CONTROLLER_H #define REGRESSION_STORE_PARAMETER_CONTROLLER_H +#include "regression_controller.h" +#include "store.h" #include "../shared/store_parameter_controller.h" namespace Regression { @@ -9,13 +11,14 @@ class StoreController; class StoreParameterController : public Shared::StoreParameterController { public: - StoreParameterController(Responder * parentResponder, Shared::DoublePairStore * store, StoreController * storeController); + StoreParameterController(Responder * parentResponder, Store * store, StoreController * storeController); bool handleEvent(Ion::Events::Event event) override; int numberOfRows() override { return Shared::StoreParameterController::numberOfRows() + 1; } HighlightCell * reusableCell(int index) override; int reusableCellCount() override { return Shared::StoreParameterController::reusableCellCount() + 1; } private: MessageTableCell m_changeRegression; + RegressionController m_regressionController; }; } diff --git a/escher/Makefile b/escher/Makefile index 237f6ed2f..63b4e0bc5 100644 --- a/escher/Makefile +++ b/escher/Makefile @@ -36,6 +36,7 @@ objs += $(addprefix escher/src/,\ message_table_cell_with_chevron_and_message.o\ message_table_cell_with_chevron_and_expression.o\ message_table_cell_with_editable_text.o\ + message_table_cell_with_expression.o\ message_table_cell_with_gauge.o\ message_table_cell_with_message.o\ message_table_cell_with_switch.o\ diff --git a/escher/include/escher.h b/escher/include/escher.h index 578eb9585..159030356 100644 --- a/escher/include/escher.h +++ b/escher/include/escher.h @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include diff --git a/escher/include/escher/message_table_cell_with_expression.h b/escher/include/escher/message_table_cell_with_expression.h new file mode 100644 index 000000000..4d6c8c8c5 --- /dev/null +++ b/escher/include/escher/message_table_cell_with_expression.h @@ -0,0 +1,17 @@ +#ifndef ESCHER_MESSAGE_TABLE_CELL_WITH_EXPRESSION_H +#define ESCHER_MESSAGE_TABLE_CELL_WITH_EXPRESSION_H + +#include +#include + +class MessageTableCellWithExpression : public MessageTableCell { +public: + MessageTableCellWithExpression(I18n::Message message = (I18n::Message)0, KDText::FontSize size = KDText::FontSize::Small); + View * subAccessoryView() const override; + void setHighlighted(bool highlight) override; + void setExpressionLayout(Poincare::ExpressionLayout * expressionLayout); +private: + ExpressionView m_subtitleView; +}; + +#endif diff --git a/escher/src/message_table_cell_with_expression.cpp b/escher/src/message_table_cell_with_expression.cpp new file mode 100644 index 000000000..c75202473 --- /dev/null +++ b/escher/src/message_table_cell_with_expression.cpp @@ -0,0 +1,24 @@ +#include +#include + +MessageTableCellWithExpression::MessageTableCellWithExpression(I18n::Message message, KDText::FontSize size) : + MessageTableCell(message, size), + m_subtitleView(1.0f, 0.5f, Palette::GreyDark) +{ +} + +View * MessageTableCellWithExpression::subAccessoryView() const { + return (View *)&m_subtitleView; +} + +void MessageTableCellWithExpression::setHighlighted(bool highlight) { + MessageTableCell::setHighlighted(highlight); + KDColor backgroundColor = isHighlighted()? Palette::Select : KDColorWhite; + m_subtitleView.setBackgroundColor(backgroundColor); +} + +void MessageTableCellWithExpression::setExpressionLayout(Poincare::ExpressionLayout * expressionLayout) { + m_subtitleView.setExpressionLayout(expressionLayout); + reloadCell(); + layoutSubviews(); +}