mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[solver] First version of Solver app
This commit is contained in:
18
apps/solver/Makefile
Normal file
18
apps/solver/Makefile
Normal file
@@ -0,0 +1,18 @@
|
||||
snapshots += Solver::App::Snapshot
|
||||
snapshot_headers += apps/solver/app.h
|
||||
|
||||
app_objs += $(addprefix apps/solver/,\
|
||||
app.o\
|
||||
equation_store.o\
|
||||
list_controller.o\
|
||||
)
|
||||
|
||||
i18n_files += $(addprefix apps/solver/,\
|
||||
base.de.i18n\
|
||||
base.en.i18n\
|
||||
base.es.i18n\
|
||||
base.fr.i18n\
|
||||
base.pt.i18n\
|
||||
)
|
||||
|
||||
app_images += apps/solver/solver_icon.png
|
||||
68
apps/solver/app.cpp
Normal file
68
apps/solver/app.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
#include "app.h"
|
||||
#include "../i18n.h"
|
||||
#include "solver_icon.h"
|
||||
|
||||
using namespace Shared;
|
||||
|
||||
namespace Solver {
|
||||
|
||||
I18n::Message App::Descriptor::name() {
|
||||
return I18n::Message::SolverApp;
|
||||
}
|
||||
|
||||
I18n::Message App::Descriptor::upperName() {
|
||||
return I18n::Message::SolverAppCapital;
|
||||
}
|
||||
|
||||
const Image * App::Descriptor::icon() {
|
||||
return ImageStore::SolverIcon;
|
||||
}
|
||||
|
||||
App::Snapshot::Snapshot() :
|
||||
m_equationStore()
|
||||
{
|
||||
}
|
||||
|
||||
App * App::Snapshot::unpack(Container * container) {
|
||||
return new App(container, this);
|
||||
}
|
||||
|
||||
App::Descriptor * App::Snapshot::descriptor() {
|
||||
static Descriptor descriptor;
|
||||
return &descriptor;
|
||||
}
|
||||
|
||||
void App::Snapshot::reset() {
|
||||
// Delete all equations
|
||||
m_equationStore.removeAll();
|
||||
}
|
||||
|
||||
void App::Snapshot::tidy() {
|
||||
// Delete all expressions of equations
|
||||
m_equationStore.tidy();
|
||||
}
|
||||
|
||||
App::App(Container * container, Snapshot * snapshot) :
|
||||
ExpressionFieldDelegateApp(container, snapshot, &m_inputViewController),
|
||||
m_listController(&m_stackViewController, snapshot->equationStore(), &m_listFooter),
|
||||
m_listFooter(&m_stackViewController, &m_listController, &m_listController, ButtonRowController::Position::Bottom, ButtonRowController::Style::EmbossedGrey),
|
||||
m_stackViewController(&m_inputViewController, &m_listFooter),
|
||||
m_inputViewController(&m_modalViewController, &m_stackViewController, this, this)
|
||||
{
|
||||
}
|
||||
|
||||
void App::willBecomeInactive() {
|
||||
if (m_modalViewController.isDisplayingModal()) {
|
||||
m_modalViewController.dismissModalViewController();
|
||||
}
|
||||
if (inputViewController()->isDisplayingModal()) {
|
||||
inputViewController()->abortEditionAndDismiss();
|
||||
}
|
||||
::App::willBecomeInactive();
|
||||
}
|
||||
|
||||
const char * App::XNT() {
|
||||
return "x";
|
||||
}
|
||||
|
||||
}
|
||||
43
apps/solver/app.h
Normal file
43
apps/solver/app.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef SOLVER_SOLVER_APP_H
|
||||
#define SOLVER_SOLVER_APP_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "../shared/expression_field_delegate_app.h"
|
||||
#include "list_controller.h"
|
||||
#include "equation_store.h"
|
||||
|
||||
namespace Solver {
|
||||
|
||||
class App : public Shared::ExpressionFieldDelegateApp {
|
||||
public:
|
||||
class Descriptor : public ::App::Descriptor {
|
||||
public:
|
||||
I18n::Message name() override;
|
||||
I18n::Message upperName() override;
|
||||
const Image * icon() override;
|
||||
};
|
||||
class Snapshot : public ::App::Snapshot {
|
||||
public:
|
||||
Snapshot();
|
||||
App * unpack(Container * container) override;
|
||||
Descriptor * descriptor() override;
|
||||
void reset() override;
|
||||
EquationStore * equationStore() { return &m_equationStore; }
|
||||
private:
|
||||
void tidy() override;
|
||||
EquationStore m_equationStore;
|
||||
};
|
||||
InputViewController * inputViewController() { return &m_inputViewController; }
|
||||
void willBecomeInactive() override;
|
||||
const char * XNT() override;
|
||||
private:
|
||||
App(Container * container, Snapshot * snapshot);
|
||||
ListController m_listController;
|
||||
ButtonRowController m_listFooter;
|
||||
StackViewController m_stackViewController;
|
||||
InputViewController m_inputViewController;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
4
apps/solver/base.de.i18n
Normal file
4
apps/solver/base.de.i18n
Normal file
@@ -0,0 +1,4 @@
|
||||
SolverApp = "Equation"
|
||||
SolverAppCapital = "EQUATION"
|
||||
AddEquation = "Ajouter une équation"
|
||||
Resolve = "Résoudre"
|
||||
4
apps/solver/base.en.i18n
Normal file
4
apps/solver/base.en.i18n
Normal file
@@ -0,0 +1,4 @@
|
||||
SolverApp = "Equation"
|
||||
SolverAppCapital = "EQUATION"
|
||||
AddEquation = "Ajouter une équation"
|
||||
Resolve = "Résoudre l'équation"
|
||||
4
apps/solver/base.es.i18n
Normal file
4
apps/solver/base.es.i18n
Normal file
@@ -0,0 +1,4 @@
|
||||
SolverApp = "Equation"
|
||||
SolverAppCapital = "EQUATION"
|
||||
AddEquation = "Ajouter une équation"
|
||||
Resolve = "Résoudre"
|
||||
4
apps/solver/base.fr.i18n
Normal file
4
apps/solver/base.fr.i18n
Normal file
@@ -0,0 +1,4 @@
|
||||
SolverApp = "Equation"
|
||||
SolverAppCapital = "EQUATION"
|
||||
AddEquation = "Ajouter une équation"
|
||||
Resolve = "Résoudre l'équation"
|
||||
4
apps/solver/base.pt.i18n
Normal file
4
apps/solver/base.pt.i18n
Normal file
@@ -0,0 +1,4 @@
|
||||
SolverApp = "Equation"
|
||||
SolverAppCapital = "EQUATION"
|
||||
AddEquation = "Ajouter une équation"
|
||||
Resolve = "Résoudre"
|
||||
13
apps/solver/equation.h
Normal file
13
apps/solver/equation.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef SOLVER_EQUATION_h
|
||||
#define SOLVER_EQUATION_h
|
||||
|
||||
#include "../shared/expression_model.h"
|
||||
|
||||
namespace Solver {
|
||||
|
||||
class Equation : public Shared::ExpressionModel {
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
14
apps/solver/equation_store.cpp
Normal file
14
apps/solver/equation_store.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include "equation_store.h"
|
||||
|
||||
namespace Solver {
|
||||
|
||||
Equation * EquationStore::emptyModel() {
|
||||
static Equation e;
|
||||
return &e;
|
||||
}
|
||||
|
||||
void EquationStore::setModelAtIndex(Shared::ExpressionModel * e, int i) {
|
||||
m_equations[i] = *(static_cast<Equation *>(e));;
|
||||
}
|
||||
|
||||
}
|
||||
30
apps/solver/equation_store.h
Normal file
30
apps/solver/equation_store.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef SOLVER_EQUATION_STORE_H
|
||||
#define SOLVER_EQUATION_STORE_H
|
||||
|
||||
#include "equation.h"
|
||||
#include "../shared/expression_model_store.h"
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Solver {
|
||||
|
||||
class EquationStore : public Shared::ExpressionModelStore {
|
||||
public:
|
||||
EquationStore() {}
|
||||
Equation * modelAtIndex(int i) override {
|
||||
assert(i>=0 && i<m_numberOfModels);
|
||||
return &m_equations[i];
|
||||
}
|
||||
int maxNumberOfModels() const override { return k_maxNumberOfEquations; }
|
||||
private:
|
||||
Equation * emptyModel() override;
|
||||
Equation * nullModel() override {
|
||||
return emptyModel();
|
||||
}
|
||||
void setModelAtIndex(Shared::ExpressionModel * f, int i) override;
|
||||
static constexpr int k_maxNumberOfEquations = 6;
|
||||
Equation m_equations[k_maxNumberOfEquations];;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
131
apps/solver/list_controller.cpp
Normal file
131
apps/solver/list_controller.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
#include "list_controller.h"
|
||||
#include "app.h"
|
||||
#include <assert.h>
|
||||
|
||||
using namespace Shared;
|
||||
|
||||
namespace Solver {
|
||||
|
||||
ListController::ListController(Responder * parentResponder, EquationStore * equationStore, ButtonRowController * footer) :
|
||||
ExpressionModelListController(parentResponder, I18n::Message::AddEquation),
|
||||
ButtonRowDelegate(nullptr, footer),
|
||||
m_equationStore(equationStore),
|
||||
m_resolveButton(this, I18n::Message::Resolve, Invocation([](void * context, void * sender) {
|
||||
ListController * list = (ListController *)context;
|
||||
StackViewController * stackController = list->stackController();
|
||||
// TODO
|
||||
//stackController->push(list->solutionPage ??)
|
||||
}, this), KDText::FontSize::Small, Palette::PurpleBright)
|
||||
{
|
||||
}
|
||||
|
||||
int ListController::numberOfButtons(ButtonRowController::Position position) const {
|
||||
if (position == ButtonRowController::Position::Bottom) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Button * ListController::buttonAtIndex(int index, ButtonRowController::Position position) const {
|
||||
if (position == ButtonRowController::Position::Top) {
|
||||
return nullptr;
|
||||
}
|
||||
return const_cast<Button *>(&m_resolveButton);
|
||||
}
|
||||
|
||||
int ListController::typeAtLocation(int i, int j) {
|
||||
if (j == m_equationStore->numberOfModels()) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
HighlightCell * ListController::reusableCell(int index, int type) {
|
||||
assert(index >= 0);
|
||||
assert(index < k_maxNumberOfRows);
|
||||
switch (type) {
|
||||
case 0:
|
||||
return m_expressionCells[index];
|
||||
case 1:
|
||||
return m_addNewModel;
|
||||
default:
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int ListController::reusableCellCount(int type) {
|
||||
if (type == 1) {
|
||||
return 1;
|
||||
}
|
||||
return k_maxNumberOfRows;
|
||||
}
|
||||
|
||||
void ListController::willDisplayCellForIndex(HighlightCell * cell, int index) {
|
||||
if (index != m_equationStore->numberOfModels()) {
|
||||
willDisplayExpressionCellAtIndex(cell, index);
|
||||
}
|
||||
EvenOddCell * myCell = (EvenOddCell *)cell;
|
||||
myCell->setEven(index%2 == 0);
|
||||
myCell->setHighlighted(index == selectedRow());
|
||||
}
|
||||
|
||||
bool ListController::handleEvent(Ion::Events::Event event) {
|
||||
if (event == Ion::Events::Up && selectedRow() == -1) {
|
||||
footer()->setSelectedButton(-1);
|
||||
selectableTableView()->selectCellAtLocation(0, numberOfRows()-1);
|
||||
app()->setFirstResponder(selectableTableView());
|
||||
return true;
|
||||
}
|
||||
if (event == Ion::Events::Down) {
|
||||
if (selectedRow() == -1) {
|
||||
return false;
|
||||
}
|
||||
selectableTableView()->deselectTable();
|
||||
footer()->setSelectedButton(0);
|
||||
return true;
|
||||
}
|
||||
return handleEventOnExpression(event);
|
||||
}
|
||||
|
||||
void ListController::didBecomeFirstResponder() {
|
||||
if (selectedRow() == -1) {
|
||||
selectCellAtLocation(0, 0);
|
||||
} else {
|
||||
selectCellAtLocation(selectedColumn(), selectedRow());
|
||||
}
|
||||
if (selectedRow() >= numberOfRows()) {
|
||||
selectCellAtLocation(selectedColumn(), numberOfRows()-1);
|
||||
}
|
||||
footer()->setSelectedButton(-1);
|
||||
app()->setFirstResponder(selectableTableView());
|
||||
}
|
||||
|
||||
void ListController::didEnterResponderChain(Responder * previousFirstResponder) {
|
||||
selectableTableView()->reloadData();
|
||||
}
|
||||
|
||||
View * ListController::loadView() {
|
||||
for (int i = 0; i < k_maxNumberOfRows; i++) {
|
||||
m_expressionCells[i] = new ModelExpressionCell();
|
||||
}
|
||||
return Shared::ExpressionModelListController::loadView();
|
||||
}
|
||||
|
||||
void ListController::unloadView(View * view) {
|
||||
for (int i = 0; i < k_maxNumberOfRows; i++) {
|
||||
delete m_expressionCells[i];
|
||||
m_expressionCells[i] = nullptr;
|
||||
}
|
||||
Shared::ExpressionModelListController::unloadView(view);
|
||||
}
|
||||
|
||||
StackViewController * ListController::stackController() const {
|
||||
return static_cast<StackViewController *>(parentResponder()->parentResponder());
|
||||
}
|
||||
|
||||
InputViewController * ListController::inputController() {
|
||||
return static_cast<App *>(app())->inputViewController();
|
||||
}
|
||||
|
||||
}
|
||||
55
apps/solver/list_controller.h
Normal file
55
apps/solver/list_controller.h
Normal file
@@ -0,0 +1,55 @@
|
||||
#ifndef SOLVER_LIST_CONTROLLER_H
|
||||
#define SOLVER_LIST_CONTROLLER_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "../shared/expression_model_list_controller.h"
|
||||
#include "../shared/model_expression_cell.h"
|
||||
#include "equation_store.h"
|
||||
#include "../i18n.h"
|
||||
|
||||
namespace Solver {
|
||||
|
||||
class ListController : public Shared::ExpressionModelListController, public ButtonRowDelegate, public ListViewDataSource {
|
||||
public:
|
||||
ListController(Responder * parentResponder, EquationStore * equationStore, ButtonRowController * footer);
|
||||
/* ButtonRowDelegate */
|
||||
int numberOfButtons(ButtonRowController::Position position) const override;
|
||||
Button * buttonAtIndex(int index, ButtonRowController::Position position) const override;
|
||||
/* ListViewDataSource */
|
||||
int numberOfRows() override {
|
||||
return numberOfExpressionRows();
|
||||
}
|
||||
KDCoordinate cumulatedHeightFromIndex(int j) override {
|
||||
return cumulatedExpressionHeightFromIndex(j);
|
||||
}
|
||||
int indexFromCumulatedHeight(KDCoordinate offsetY) override {
|
||||
return indexFromCumulatedExpressionHeight(offsetY);
|
||||
}
|
||||
KDCoordinate rowHeight(int j) override {
|
||||
return expressionRowHeight(j);
|
||||
}
|
||||
int typeAtLocation(int i, int j) override;
|
||||
HighlightCell * reusableCell(int index, int type) override;
|
||||
int reusableCellCount(int type) override;
|
||||
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
|
||||
/* Responder */
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
void didBecomeFirstResponder() override;
|
||||
void didEnterResponderChain(Responder * previousFirstResponder) override;
|
||||
private:
|
||||
constexpr static int k_maxNumberOfRows = 5; // Ion::Display::Height / Metric::StoreRowHeight = 4.8;
|
||||
View * loadView() override;
|
||||
void unloadView(View * view) override;
|
||||
Shared::ExpressionModelStore * modelStore() override { return m_equationStore; }
|
||||
StackViewController * stackController() const;
|
||||
InputViewController * inputController() override;
|
||||
TableViewDataSource * tableDataSource() override { return this; }
|
||||
SelectableTableViewDelegate * selectableTableDelegate() override { return nullptr; }
|
||||
EquationStore * m_equationStore;
|
||||
Shared::ModelExpressionCell * m_expressionCells[k_maxNumberOfRows];
|
||||
Button m_resolveButton;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
BIN
apps/solver/solver_icon.png
Normal file
BIN
apps/solver/solver_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
@@ -6,7 +6,7 @@ DEBUG ?= 0
|
||||
EPSILON_VERSION ?= 1.5.0
|
||||
EPSILON_ONBOARDING_APP ?= 1
|
||||
EPSILON_SOFTWARE_UPDATE_PROMPT ?= 1
|
||||
EPSILON_APPS ?= calculation statistics graph probability sequence regression settings code
|
||||
EPSILON_APPS ?= calculation statistics graph probability sequence regression settings code solver
|
||||
EPSILON_I18N ?= en fr es de pt
|
||||
EPSILON_GETOPT ?= 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user