From 2ca685984e35c861fbbd7b0845a88e18298ccdef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Thu, 24 May 2018 16:47:38 +0200 Subject: [PATCH] [solver] Add a modal with equation models when adding a new equation --- apps/shared.de.i18n | 1 + apps/shared.en.i18n | 1 + apps/shared.es.i18n | 1 + apps/shared.fr.i18n | 1 + apps/shared.pt.i18n | 1 + apps/solver/Makefile | 1 + apps/solver/base.de.i18n | 1 + apps/solver/base.en.i18n | 1 + apps/solver/base.es.i18n | 1 + apps/solver/base.fr.i18n | 1 + apps/solver/base.pt.i18n | 1 + .../equation_models_parameter_controller.cpp | 106 ++++++++++++++++++ .../equation_models_parameter_controller.h | 46 ++++++++ apps/solver/list_controller.cpp | 8 +- apps/solver/list_controller.h | 4 + apps/variables.de.i18n | 1 - apps/variables.en.i18n | 1 - apps/variables.es.i18n | 1 - apps/variables.fr.i18n | 1 - apps/variables.pt.i18n | 1 - 20 files changed, 174 insertions(+), 6 deletions(-) create mode 100644 apps/solver/equation_models_parameter_controller.cpp create mode 100644 apps/solver/equation_models_parameter_controller.h diff --git a/apps/shared.de.i18n b/apps/shared.de.i18n index 70c127c76..0dfa15f0e 100644 --- a/apps/shared.de.i18n +++ b/apps/shared.de.i18n @@ -11,6 +11,7 @@ DataTab = "Daten" DefaultSetting = "Grundeinstellungen" Deg = "gra" DisplayValues = "Werte anzeigen" +Empty = "Leer" ExitExamMode1 = "Wollen Sie den Testmodus " ExitExamMode2 = "verlassen?" ForbiddenValue = "Verbotener Wert" diff --git a/apps/shared.en.i18n b/apps/shared.en.i18n index a1f9ed2e9..adff13752 100644 --- a/apps/shared.en.i18n +++ b/apps/shared.en.i18n @@ -11,6 +11,7 @@ DataTab = "Data" DefaultSetting = "Basic settings" Deg = "deg" DisplayValues = "Display values" +Empty = "Empty" ExitExamMode1 = "Exit the exam " ExitExamMode2 = "mode?" ForbiddenValue = "Forbidden value" diff --git a/apps/shared.es.i18n b/apps/shared.es.i18n index c0c02ff46..bf7bc4eac 100644 --- a/apps/shared.es.i18n +++ b/apps/shared.es.i18n @@ -11,6 +11,7 @@ DataTab = "Datos" DefaultSetting = "Ajustes basicos" Deg = "gra" DisplayValues = "Visualizar los valores" +Empty = "Vacio" ExitExamMode1 = "Salir del modo " ExitExamMode2 = "examen ?" ForbiddenValue = "Valor prohibido" diff --git a/apps/shared.fr.i18n b/apps/shared.fr.i18n index 47cd17a61..96a2b3ce2 100644 --- a/apps/shared.fr.i18n +++ b/apps/shared.fr.i18n @@ -11,6 +11,7 @@ DataTab = "Donnees" DefaultSetting = "Reglages de base" Deg = "deg" DisplayValues = "Afficher les valeurs" +Empty = "Vide" ExitExamMode1 = "Voulez-vous sortir " ExitExamMode2 = "du mode examen ?" ForbiddenValue = "Valeur interdite" diff --git a/apps/shared.pt.i18n b/apps/shared.pt.i18n index e6c7263b2..b336ddeee 100644 --- a/apps/shared.pt.i18n +++ b/apps/shared.pt.i18n @@ -11,6 +11,7 @@ DataTab = "Dados" DefaultSetting = "Configuracoes basicas" Deg = "gra" DisplayValues = "Exibir os valores" +Empty = "Vacuo" ExitExamMode1 = "Voce quer sair do modo de " ExitExamMode2 = "exame ?" ForbiddenValue = "Valor proibida" diff --git a/apps/solver/Makefile b/apps/solver/Makefile index 7fa8dab15..0d4774bf8 100644 --- a/apps/solver/Makefile +++ b/apps/solver/Makefile @@ -3,6 +3,7 @@ snapshot_headers += apps/solver/app.h app_objs += $(addprefix apps/solver/,\ app.o\ + equation_models_parameter_controller.o\ equation_store.o\ list_controller.o\ ) diff --git a/apps/solver/base.de.i18n b/apps/solver/base.de.i18n index 9971efcfd..1935bf1e5 100644 --- a/apps/solver/base.de.i18n +++ b/apps/solver/base.de.i18n @@ -3,3 +3,4 @@ SolverAppCapital = "EQUATION" AddEquation = "Ajouter une équation" Resolve = "Résoudre" RequireEquation = "L'entrée doit être une équation" +UseEquationModel = "Utiliser le modèle d'équation" diff --git a/apps/solver/base.en.i18n b/apps/solver/base.en.i18n index 6b75ee061..62197814c 100644 --- a/apps/solver/base.en.i18n +++ b/apps/solver/base.en.i18n @@ -3,3 +3,4 @@ SolverAppCapital = "EQUATION" AddEquation = "Ajouter une équation" Resolve = "Résoudre l'équation" RequireEquation = "L'entrée doit être une équation" +UseEquationModel = "Utiliser le modèle d'équation" diff --git a/apps/solver/base.es.i18n b/apps/solver/base.es.i18n index 9971efcfd..1935bf1e5 100644 --- a/apps/solver/base.es.i18n +++ b/apps/solver/base.es.i18n @@ -3,3 +3,4 @@ SolverAppCapital = "EQUATION" AddEquation = "Ajouter une équation" Resolve = "Résoudre" RequireEquation = "L'entrée doit être une équation" +UseEquationModel = "Utiliser le modèle d'équation" diff --git a/apps/solver/base.fr.i18n b/apps/solver/base.fr.i18n index 6b75ee061..62197814c 100644 --- a/apps/solver/base.fr.i18n +++ b/apps/solver/base.fr.i18n @@ -3,3 +3,4 @@ SolverAppCapital = "EQUATION" AddEquation = "Ajouter une équation" Resolve = "Résoudre l'équation" RequireEquation = "L'entrée doit être une équation" +UseEquationModel = "Utiliser le modèle d'équation" diff --git a/apps/solver/base.pt.i18n b/apps/solver/base.pt.i18n index 9971efcfd..1935bf1e5 100644 --- a/apps/solver/base.pt.i18n +++ b/apps/solver/base.pt.i18n @@ -3,3 +3,4 @@ SolverAppCapital = "EQUATION" AddEquation = "Ajouter une équation" Resolve = "Résoudre" RequireEquation = "L'entrée doit être une équation" +UseEquationModel = "Utiliser le modèle d'équation" diff --git a/apps/solver/equation_models_parameter_controller.cpp b/apps/solver/equation_models_parameter_controller.cpp new file mode 100644 index 000000000..0e5e91454 --- /dev/null +++ b/apps/solver/equation_models_parameter_controller.cpp @@ -0,0 +1,106 @@ +#include "equation_models_parameter_controller.h" +#include +#include +#include "../i18n.h" + +using namespace Poincare; + +namespace Solver { + +constexpr const char * EquationModelsParameterController::k_models[k_numberOfModels]; + +EquationModelsParameterController::EquationModelsParameterController(Responder * parentResponder, EquationStore * equationStore) : + ViewController(parentResponder), + m_emptyModelCell(I18n::Message::Empty, KDText::FontSize::Large), + m_expressionLayouts{}, + m_selectableTableView(this), + m_equationStore(equationStore) +{ + m_selectableTableView.setMargins(0); + m_selectableTableView.setShowsIndicators(false); + for (int i = 0; i < k_numberOfExpressionCells; i++) { + Poincare::Expression * e = Expression::parse(k_models[i+1]); + m_expressionLayouts[i] = e->createLayout(Poincare::PrintFloat::Mode::Decimal, Poincare::Expression::ComplexFormat::Cartesian); + delete e; + m_modelCells[i].setExpressionLayout(m_expressionLayouts[i]); + } +} + +EquationModelsParameterController::~EquationModelsParameterController() { + for (int i = 0; i < k_numberOfExpressionCells; i++) { + if (m_expressionLayouts[i]) { + delete m_expressionLayouts[i]; + m_expressionLayouts[i] = nullptr; + } + } +} + +const char * EquationModelsParameterController::title() { + return I18n::translate(I18n::Message::UseEquationModel); +} + +View * EquationModelsParameterController::view() { + return &m_selectableTableView; +} + +void EquationModelsParameterController::viewWillAppear() { + ViewController::viewWillAppear(); + selectCellAtLocation(0, 0); +} + +void EquationModelsParameterController::didBecomeFirstResponder() { + app()->setFirstResponder(&m_selectableTableView); +} + +bool EquationModelsParameterController::handleEvent(Ion::Events::Event event) { + if (event == Ion::Events::OK || event == Ion::Events::EXE) { + Equation * newEquation = static_cast(m_equationStore->addEmptyModel()); + newEquation->setContent(k_models[selectedRow()]); + app()->dismissModalViewController(); + return true; + } + return false; +} + +int EquationModelsParameterController::numberOfRows() { + return k_numberOfExpressionCells+1; +}; + +KDCoordinate EquationModelsParameterController::rowHeight(int j) { + return Metric::ToolboxRowHeight; +} + +KDCoordinate EquationModelsParameterController::cumulatedHeightFromIndex(int j) { + return rowHeight(0) * j; +} + +int EquationModelsParameterController::indexFromCumulatedHeight(KDCoordinate offsetY) { + KDCoordinate height = rowHeight(0); + if (height == 0) { + return 0; + } + return (offsetY - 1) / height; +} + +HighlightCell * EquationModelsParameterController::reusableCell(int index, int type) { + if (type == 0) { + return &m_emptyModelCell; + } + return &m_modelCells[index]; +} + +int EquationModelsParameterController::reusableCellCount(int type) { + if (type == 0) { + return 1; + } + return k_numberOfExpressionCells; +} + +int EquationModelsParameterController::typeAtLocation(int i, int j) { + if (i == 0 && j == 0) { + return 0; + } + return 1; +} + +} diff --git a/apps/solver/equation_models_parameter_controller.h b/apps/solver/equation_models_parameter_controller.h new file mode 100644 index 000000000..15640303e --- /dev/null +++ b/apps/solver/equation_models_parameter_controller.h @@ -0,0 +1,46 @@ +#ifndef SOLVER_EQUATION_MODELS_PARAMETER_CONTROLLER_H +#define SOLVER_EQUATION_MODELS_PARAMETER_CONTROLLER_H + +#include +#include "equation_store.h" + +namespace Solver { + + +class EquationModelsParameterController : public ViewController, public ListViewDataSource, public SelectableTableViewDataSource { +public: + EquationModelsParameterController(Responder * parentResponder, EquationStore * equationStore); + ~EquationModelsParameterController(); + EquationModelsParameterController(const EquationModelsParameterController& other) = delete; + EquationModelsParameterController(EquationModelsParameterController&& other) = delete; + EquationModelsParameterController& operator=(const EquationModelsParameterController& other) = delete; + EquationModelsParameterController& operator=(EquationModelsParameterController&& other) = delete; + const char * title() override; + View * view() override; + void viewWillAppear() override; + void didBecomeFirstResponder() override; + bool handleEvent(Ion::Events::Event event) override; + int numberOfRows() override; + KDCoordinate rowHeight(int j) override; + KDCoordinate cumulatedHeightFromIndex(int j) override; + int indexFromCumulatedHeight(KDCoordinate offsetY) override; + HighlightCell * reusableCell(int index, int type) override; + int reusableCellCount(int type) override; + int typeAtLocation(int i, int j) override; +private: + constexpr static int k_numberOfModels = 6; + static constexpr const char * k_models[k_numberOfModels] = { + "", "x+y=0", "x^2+x+1=0", "x+y+z=0", "x^3+x^2+x+1=0", "x+y+z+t=0" + }; + StackViewController * stackController() const; + constexpr static int k_numberOfExpressionCells = k_numberOfModels-1; + MessageTableCell m_emptyModelCell; + ExpressionTableCell m_modelCells[k_numberOfExpressionCells]; + Poincare::ExpressionLayout * m_expressionLayouts[k_numberOfExpressionCells]; + SelectableTableView m_selectableTableView; + EquationStore * m_equationStore; +}; + +} + +#endif diff --git a/apps/solver/list_controller.cpp b/apps/solver/list_controller.cpp index 80c750392..67a63ca1b 100644 --- a/apps/solver/list_controller.cpp +++ b/apps/solver/list_controller.cpp @@ -15,7 +15,9 @@ ListController::ListController(Responder * parentResponder, EquationStore * equa StackViewController * stackController = list->stackController(); // TODO //stackController->push(list->solutionPage ??) - }, this), KDText::FontSize::Small, Palette::PurpleBright) + }, this), KDText::FontSize::Small, Palette::PurpleBright), + m_modelsParameterController(this, equationStore), + m_modelsStackController(nullptr, &m_modelsParameterController, KDColorWhite, Palette::PurpleDark, Palette::PurpleDark) { } @@ -140,6 +142,10 @@ bool ListController::expressionLayoutFieldDidReceiveEvent(ExpressionLayoutField return false; } +void ListController::addEmptyModel() { + app()->displayModalViewController(&m_modelsStackController, 0.f, 0.f, Metric::CommonTopMargin, Metric::CommonRightMargin, 0, Metric::CommonLeftMargin); +} + View * ListController::loadView() { for (int i = 0; i < k_maxNumberOfRows; i++) { m_expressionCells[i] = new ModelExpressionCell(); diff --git a/apps/solver/list_controller.h b/apps/solver/list_controller.h index 88a02a5ab..e2f645f26 100644 --- a/apps/solver/list_controller.h +++ b/apps/solver/list_controller.h @@ -7,6 +7,7 @@ #include "../shared/expression_layout_field_delegate.h" #include "../shared/text_field_delegate.h" #include "equation_store.h" +#include "equation_models_parameter_controller.h" #include "../i18n.h" namespace Solver { @@ -45,6 +46,7 @@ public: bool expressionLayoutFieldDidReceiveEvent(ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) override; private: constexpr static int k_maxNumberOfRows = 5; // Ion::Display::Height / Metric::StoreRowHeight = 4.8; + void addEmptyModel() override; View * loadView() override; void unloadView(View * view) override; Shared::ExpressionModelStore * modelStore() override { return m_equationStore; } @@ -55,6 +57,8 @@ private: EquationStore * m_equationStore; Shared::ModelExpressionCell * m_expressionCells[k_maxNumberOfRows]; Button m_resolveButton; + EquationModelsParameterController m_modelsParameterController; + StackViewController m_modelsStackController; }; } diff --git a/apps/variables.de.i18n b/apps/variables.de.i18n index 07d1b6b7f..6655c96d0 100644 --- a/apps/variables.de.i18n +++ b/apps/variables.de.i18n @@ -2,4 +2,3 @@ Variables = "Variablen" Number = "Zahlen" Matrix = "Matrizen" List = "Listen" -Empty = "Leer" diff --git a/apps/variables.en.i18n b/apps/variables.en.i18n index 67ccff286..51ad23383 100644 --- a/apps/variables.en.i18n +++ b/apps/variables.en.i18n @@ -2,4 +2,3 @@ Variables = "Variables" Number = "Numbers" Matrix = "Matrices" List = "Lists" -Empty = "Empty" diff --git a/apps/variables.es.i18n b/apps/variables.es.i18n index ec4e40f3c..0955a00c1 100644 --- a/apps/variables.es.i18n +++ b/apps/variables.es.i18n @@ -2,4 +2,3 @@ Variables = "Variables" Number = "Numeros" Matrix = "Matrices" List = "Listas" -Empty = "Vacio" diff --git a/apps/variables.fr.i18n b/apps/variables.fr.i18n index 6782333e3..68a1ef14e 100644 --- a/apps/variables.fr.i18n +++ b/apps/variables.fr.i18n @@ -2,4 +2,3 @@ Variables = "Variables" Number = "Nombres" Matrix = "Matrices" List = "Listes" -Empty = "Vide" diff --git a/apps/variables.pt.i18n b/apps/variables.pt.i18n index addb47da4..6cf69e5ef 100644 --- a/apps/variables.pt.i18n +++ b/apps/variables.pt.i18n @@ -2,4 +2,3 @@ Variables = "Variaveis" Number = "Numeros" Matrix = "Matrizes" List = "Listas" -Empty = "Vacuo"