diff --git a/apps/geometry/Makefile b/apps/geometry/Makefile new file mode 100644 index 000000000..6063d097f --- /dev/null +++ b/apps/geometry/Makefile @@ -0,0 +1,17 @@ +apps += Geometry::App +app_headers += apps/geometry/app.h + +app_geometry_src = $(addprefix apps/geometry/,\ + app.cpp \ + figures_controller.cpp \ + definition_type_controller.cpp \ + figure_type_controller.cpp \ +) + +apps_src += $(app_geometry_src) + +app_images += apps/geometry/geometry_icon.png + +i18n_files += $(call i18n_without_universal_for,geometry/base) + +$(eval $(call depends_on_image,apps/geometry/app.cpp,apps/geometry/geometry_icon.png)) \ No newline at end of file diff --git a/apps/geometry/app.cpp b/apps/geometry/app.cpp new file mode 100644 index 000000000..33dfe487d --- /dev/null +++ b/apps/geometry/app.cpp @@ -0,0 +1,42 @@ +#include "app.h" +#include "geometry_icon.h" +#include "apps/apps_container.h" +#include "apps/i18n.h" + +namespace Geometry +{ + +I18n::Message App::Descriptor::name() +{ + return I18n::Message::GeometryApp; +} + +I18n::Message App::Descriptor::upperName() +{ + return I18n::Message::GeometryAppCapital; +} + +const Image * App::Descriptor::icon() +{ + return ImageStore::GeometryIcon; +} + +App * App::Snapshot::unpack(Container * container) +{ + return new (container->currentAppBuffer()) App(this); +} + +App::Descriptor * App::Snapshot::descriptor() +{ + static Descriptor descriptor; + return &descriptor; +} + +App::App(Snapshot * snapshot) : + ::App(snapshot, &m_stackViewController), + m_figuresController(&m_stackViewController), + m_stackViewController(&m_modalViewController, &m_figuresController) +{ +} + +} \ No newline at end of file diff --git a/apps/geometry/app.h b/apps/geometry/app.h new file mode 100644 index 000000000..5bd7c884b --- /dev/null +++ b/apps/geometry/app.h @@ -0,0 +1,35 @@ +#ifndef GEOMETRY_H +#define GEOMETRY_H + +#include +#include "figures_controller.h" + +namespace Geometry +{ + +class App : public ::App +{ +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: + App * unpack(Container * container) override; + Descriptor * descriptor() override; + }; +private: + App(Snapshot * snapshot); + + FiguresController m_figuresController; + StackViewController m_stackViewController; +}; + +} + +#endif \ No newline at end of file diff --git a/apps/geometry/base.de.i18n b/apps/geometry/base.de.i18n new file mode 100644 index 000000000..e02f696f1 --- /dev/null +++ b/apps/geometry/base.de.i18n @@ -0,0 +1,7 @@ +GeometryApp = "Geometry" +GeometryAppCapital = "GEOMETRY" +AddFigure = "Ajouter une figure" +Point = "Point" +Circle = "Cercle" +FigureType = "Type de figure" +DefinitionType = "Définition de la figure" diff --git a/apps/geometry/base.en.i18n b/apps/geometry/base.en.i18n new file mode 100644 index 000000000..e02f696f1 --- /dev/null +++ b/apps/geometry/base.en.i18n @@ -0,0 +1,7 @@ +GeometryApp = "Geometry" +GeometryAppCapital = "GEOMETRY" +AddFigure = "Ajouter une figure" +Point = "Point" +Circle = "Cercle" +FigureType = "Type de figure" +DefinitionType = "Définition de la figure" diff --git a/apps/geometry/base.es.i18n b/apps/geometry/base.es.i18n new file mode 100644 index 000000000..e02f696f1 --- /dev/null +++ b/apps/geometry/base.es.i18n @@ -0,0 +1,7 @@ +GeometryApp = "Geometry" +GeometryAppCapital = "GEOMETRY" +AddFigure = "Ajouter une figure" +Point = "Point" +Circle = "Cercle" +FigureType = "Type de figure" +DefinitionType = "Définition de la figure" diff --git a/apps/geometry/base.fr.i18n b/apps/geometry/base.fr.i18n new file mode 100644 index 000000000..e02f696f1 --- /dev/null +++ b/apps/geometry/base.fr.i18n @@ -0,0 +1,7 @@ +GeometryApp = "Geometry" +GeometryAppCapital = "GEOMETRY" +AddFigure = "Ajouter une figure" +Point = "Point" +Circle = "Cercle" +FigureType = "Type de figure" +DefinitionType = "Définition de la figure" diff --git a/apps/geometry/base.hu.i18n b/apps/geometry/base.hu.i18n new file mode 100644 index 000000000..e02f696f1 --- /dev/null +++ b/apps/geometry/base.hu.i18n @@ -0,0 +1,7 @@ +GeometryApp = "Geometry" +GeometryAppCapital = "GEOMETRY" +AddFigure = "Ajouter une figure" +Point = "Point" +Circle = "Cercle" +FigureType = "Type de figure" +DefinitionType = "Définition de la figure" diff --git a/apps/geometry/base.it.i18n b/apps/geometry/base.it.i18n new file mode 100644 index 000000000..e02f696f1 --- /dev/null +++ b/apps/geometry/base.it.i18n @@ -0,0 +1,7 @@ +GeometryApp = "Geometry" +GeometryAppCapital = "GEOMETRY" +AddFigure = "Ajouter une figure" +Point = "Point" +Circle = "Cercle" +FigureType = "Type de figure" +DefinitionType = "Définition de la figure" diff --git a/apps/geometry/base.nl.i18n b/apps/geometry/base.nl.i18n new file mode 100644 index 000000000..e02f696f1 --- /dev/null +++ b/apps/geometry/base.nl.i18n @@ -0,0 +1,7 @@ +GeometryApp = "Geometry" +GeometryAppCapital = "GEOMETRY" +AddFigure = "Ajouter une figure" +Point = "Point" +Circle = "Cercle" +FigureType = "Type de figure" +DefinitionType = "Définition de la figure" diff --git a/apps/geometry/base.pt.i18n b/apps/geometry/base.pt.i18n new file mode 100644 index 000000000..e02f696f1 --- /dev/null +++ b/apps/geometry/base.pt.i18n @@ -0,0 +1,7 @@ +GeometryApp = "Geometry" +GeometryAppCapital = "GEOMETRY" +AddFigure = "Ajouter une figure" +Point = "Point" +Circle = "Cercle" +FigureType = "Type de figure" +DefinitionType = "Définition de la figure" diff --git a/apps/geometry/definition_type_controller.cpp b/apps/geometry/definition_type_controller.cpp new file mode 100644 index 000000000..297f82699 --- /dev/null +++ b/apps/geometry/definition_type_controller.cpp @@ -0,0 +1,58 @@ +#include "figure_type_controller.h" + +namespace Geometry { + +static I18n::Message sMessages[] = { + I18n::Message::QuentinGuidee, + I18n::Message::JeanBaptisteBoric +}; + +DefinitionTypeController::DefinitionTypeController(Responder * parentResponder) : + ViewController(parentResponder), + m_selectableTableView(this) +{ + for (int i = 0; i < k_numberOfCells; i ++) { + m_cells[i].setMessageFont(KDFont::LargeFont); + } + m_messages = sMessages; +} + +const char * DefinitionTypeController::title() { + return I18n::translate(I18n::Message::DefinitionType); +} + +void DefinitionTypeController::viewWillAppear() { + selectRow(0); +} + +void DefinitionTypeController::didBecomeFirstResponder() { + //App::app()->snapshot()->setActivePage(App::Snapshot::Page::Distribution); + Container::activeApp()->setFirstResponder(&m_selectableTableView); +} + +bool DefinitionTypeController::handleEvent(Ion::Events::Event event) { + if (event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) { + StackViewController * stack = static_cast(parentResponder()->parentResponder()->parentResponder()); + stack->pop(); + return true; + } + if (event == Ion::Events::Back) { + StackViewController * stack = static_cast(parentResponder()->parentResponder()->parentResponder()); + stack->pop(); + return true; + } + return false; +} + +HighlightCell * DefinitionTypeController::reusableCell(int index) { + assert(index >= 0); + assert(index < k_numberOfCells); + return &m_cells[index]; +} + +void DefinitionTypeController::willDisplayCellForIndex(HighlightCell * cell, int index) { + MessageTableCellWithChevron * myCell = (MessageTableCellWithChevron *)cell; + myCell->setMessage(m_messages[index]); +} + +} diff --git a/apps/geometry/definition_type_controller.h b/apps/geometry/definition_type_controller.h new file mode 100644 index 000000000..88f8e6008 --- /dev/null +++ b/apps/geometry/definition_type_controller.h @@ -0,0 +1,39 @@ +#ifndef GEOMETRY_DEFINITION_TYPE_CONTROLLER_H +#define GEOMETRY_DEFINITION_TYPE_CONTROLLER_H + +#include +#include "apps/i18n.h" + +namespace Geometry { +/** + * \brief DefinitionTypeController is a controller to choose how the figure is defined + */ +class DefinitionTypeController : public ViewController, public SimpleListViewDataSource, public SelectableTableViewDataSource { +public: + DefinitionTypeController(Responder * parentResponder/*, FigureDefinitionController * definitionController*/); + + /* ViewController */ + View * view() override { return &m_selectableTableView; } + const char * title() override; + + bool handleEvent(Ion::Events::Event event) override; + void didBecomeFirstResponder() override; + void viewWillAppear() override; + TELEMETRY_ID("FigureType"); + int numberOfRows() const override { return 2; } + void willDisplayCellForIndex(HighlightCell * cell, int index) override; + KDCoordinate cellHeight() override { return k_cellHeight; } + HighlightCell * reusableCell(int index) override; + int reusableCellCount() const override { return k_numberOfCells; } +private: + constexpr static KDCoordinate k_cellHeight = Metric::ParameterCellHeight; + constexpr static int k_numberOfCells = 2; + MessageTableCellWithChevron m_cells[k_numberOfCells]; + SelectableTableView m_selectableTableView; + I18n::Message * m_messages; + /*FigureDefinitionController * m_FigureDefinitionController;*/ +}; + +} + +#endif diff --git a/apps/geometry/figure_type_controller.cpp b/apps/geometry/figure_type_controller.cpp new file mode 100644 index 000000000..2c2d80b34 --- /dev/null +++ b/apps/geometry/figure_type_controller.cpp @@ -0,0 +1,60 @@ +#include "figure_type_controller.h" +#include "apps/i18n.h" + +namespace Geometry { + +static I18n::Message sMessages[] = { + I18n::Message::Point, + I18n::Message::Circle +}; + +FigureTypeController::FigureTypeController(Responder * parentResponder, DefinitionTypeController * definitionTypeController) : + ViewController(parentResponder), + m_selectableTableView(this), + m_definitionTypeController(definitionTypeController) +{ + for (int i = 0; i < k_numberOfCells; i ++) { + m_cells[i].setMessageFont(KDFont::LargeFont); + } + m_messages = sMessages; +} + +const char * FigureTypeController::title() { + return I18n::translate(I18n::Message::FigureType); +} + +void FigureTypeController::viewWillAppear() { + selectRow(0); +} + +void FigureTypeController::didBecomeFirstResponder() { + //App::app()->snapshot()->setActivePage(App::Snapshot::Page::Distribution); + Container::activeApp()->setFirstResponder(&m_selectableTableView); +} + +bool FigureTypeController::handleEvent(Ion::Events::Event event) { + if (event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) { + StackViewController * stack = static_cast(parentResponder()); + stack->push(m_definitionTypeController); + return true; + } + if (event == Ion::Events::Back ) { + StackViewController * stack = static_cast(parentResponder()); + stack->pop(); + return true; + } + return false; +} + +HighlightCell * FigureTypeController::reusableCell(int index) { + assert(index >= 0); + assert(index < k_numberOfCells); + return &m_cells[index]; +} + +void FigureTypeController::willDisplayCellForIndex(HighlightCell * cell, int index) { + MessageTableCellWithChevron * myCell = (MessageTableCellWithChevron *)cell; + myCell->setMessage(m_messages[index]); +} + +} diff --git a/apps/geometry/figure_type_controller.h b/apps/geometry/figure_type_controller.h new file mode 100644 index 000000000..a054a4d06 --- /dev/null +++ b/apps/geometry/figure_type_controller.h @@ -0,0 +1,40 @@ +#ifndef GEOMETRY_FIGURE_TYPE_CONTROLLER_H +#define GEOMETRY_FIGURE_TYPE_CONTROLLER_H + +#include +#include "definition_type_controller.h" + +namespace Geometry { +/** + * \brief FigureTypeController is a controller that is used to select the type of + * figure to be created. + */ +class FigureTypeController : public ViewController, public SimpleListViewDataSource, public SelectableTableViewDataSource { +public: + FigureTypeController(Responder * parentResponder, DefinitionTypeController * definitionController); + + /* ViewController */ + View * view() override { return &m_selectableTableView; } + const char * title() override; + + bool handleEvent(Ion::Events::Event event) override; + void didBecomeFirstResponder() override; + void viewWillAppear() override; + TELEMETRY_ID("FigureType"); + int numberOfRows() const override { return 2; } + void willDisplayCellForIndex(HighlightCell * cell, int index) override; + KDCoordinate cellHeight() override { return k_cellHeight; } + HighlightCell * reusableCell(int index) override; + int reusableCellCount() const override { return k_numberOfCells; } +private: + constexpr static KDCoordinate k_cellHeight = Metric::ParameterCellHeight; + constexpr static int k_numberOfCells = 2; + MessageTableCellWithChevron m_cells[k_numberOfCells]; + SelectableTableView m_selectableTableView; + I18n::Message * m_messages; + DefinitionTypeController * m_definitionTypeController; +}; + +} + +#endif diff --git a/apps/geometry/figures_controller.cpp b/apps/geometry/figures_controller.cpp new file mode 100644 index 000000000..5a77e15f2 --- /dev/null +++ b/apps/geometry/figures_controller.cpp @@ -0,0 +1,70 @@ +#include "figures_controller.h" +#include "definition_type_controller.h" +#include + +namespace Geometry { + +FiguresController::FiguresController(Responder * parentResponder): + ViewController(parentResponder), + m_selectableTableView(this, this, this, this), + m_addFigureCell(), + m_emptyCell(), + m_figureTypeController(this, &m_definitionTypeController), + m_definitionTypeController(&m_figureTypeController) +{ + m_addFigureCell.setMessage(I18n::Message::AddFigure); +} + +bool FiguresController::handleEvent(Ion::Events::Event event) { + if (event == Ion::Events::OK || event == Ion::Events::EXE) { + if (isAddFigureRow(selectedRow())) { + StackViewController * stack = static_cast(parentResponder()); + stack->push(&m_figureTypeController); + return true; + } + } + return false; +} + +void FiguresController::didBecomeFirstResponder() { + Container::activeApp()->setFirstResponder(&m_selectableTableView); +} + + +HighlightCell * FiguresController::reusableCell(int index, int type) { + assert(index >= 0); + if (type == 2) { + return &m_emptyCell; + } + return &m_addFigureCell; +} + +void FiguresController::willDisplayCellAtLocation(HighlightCell * cell, int i, int j) { + if (i == 0) { + return; + } + EvenOddCell * myCell = (EvenOddCell *)cell; + myCell->setEven(j%2 == 0); + myCell->setHighlighted(i == selectedColumn() && j == selectedRow()); + myCell->reloadCell(); +} + +bool FiguresController::isAddFigureRow(int j) { + return j == 0; +} + +int FiguresController::reusableCellCount(int type) { + if (type > 1) { + return 1; + } + return 0; +} + +int FiguresController::typeAtLocation(int i, int j) { + if (isAddFigureRow(j)) { + return i + 2; + } + return i; +} + +} diff --git a/apps/geometry/figures_controller.h b/apps/geometry/figures_controller.h new file mode 100644 index 000000000..b7540d4ac --- /dev/null +++ b/apps/geometry/figures_controller.h @@ -0,0 +1,43 @@ +#ifndef FIGURES_CONTROLLER_H +#define FIGURES_CONTROLLER_H + +#include +#include "figure_type_controller.h" + +namespace Geometry +{ + +class FiguresController : public ViewController, public SelectableTableViewDataSource, public SelectableTableViewDelegate, public TableViewDataSource { +public: + FiguresController(Responder * parentResponder); + + /* ViewController */ + View * view() override { return &m_selectableTableView; } + + /* Responder */ + bool handleEvent(Ion::Events::Event event) override; // TO IMPLEMENT + void didBecomeFirstResponder() override; + + /* TableView */ + int numberOfRows() const override { return 1; } // TO IMPLEMENT + int numberOfColumns() const override { return 2; } // TO IMPLEMENT + KDCoordinate columnWidth(int i) { return i == 0 ? 50 : 150; } // TO IMPLEMENT + KDCoordinate rowHeight(int j) { return 50; } // TO IMPLEMENT + HighlightCell * reusableCell(int index, int type); // TO IMPLEMENT + void willDisplayCellAtLocation(HighlightCell * cell, int i, int j) override; // TO IMPLEMENT + int reusableCellCount(int type); + int typeAtLocation(int i, int j); // TO IMPLEMENT + +private: + /* Customs methods */ + bool isAddFigureRow(int j); // TO IMPLEMENT + + SelectableTableView m_selectableTableView; + EvenOddMessageTextCell m_addFigureCell; + EvenOddCell m_emptyCell; + FigureTypeController m_figureTypeController; + DefinitionTypeController m_definitionTypeController; +}; + +} +#endif \ No newline at end of file diff --git a/apps/geometry/geometry_icon.png b/apps/geometry/geometry_icon.png new file mode 100644 index 000000000..78e23e139 Binary files /dev/null and b/apps/geometry/geometry_icon.png differ diff --git a/apps/home/apps_layout.csv b/apps/home/apps_layout.csv index b17d33f7d..cb6c2f118 100644 --- a/apps/home/apps_layout.csv +++ b/apps/home/apps_layout.csv @@ -1,2 +1,2 @@ -Default,calculation,rpn,graph,code,statistics,probability,solver,atomic,sequence,regression,reader,settings -HidePython,calculation,rpn,graph,code,statistics,probability,solver,atomic,sequence,regression,reader,settings +Default,geometry,calculation,rpn,graph,code,statistics,probability,solver,atomic,sequence,regression,reader,settings +HidePython,geometry,calculation,rpn,graph,code,statistics,probability,solver,atomic,sequence,regression,reader,settings diff --git a/build/config.mak b/build/config.mak index 222cc244d..8210f080c 100644 --- a/build/config.mak +++ b/build/config.mak @@ -8,7 +8,7 @@ EPSILON_VERSION ?= 15.5.0 OMEGA_VERSION ?= 1.22.1 # OMEGA_USERNAME ?= N/A OMEGA_STATE ?= public -EPSILON_APPS ?= calculation rpn graph code statistics probability solver atomic sequence regression reader settings external +EPSILON_APPS ?= geometry calculation rpn graph code statistics probability solver atomic sequence regression reader settings external SUBMODULES_APPS = atomic rpn EPSILON_I18N ?= en fr nl pt it de es hu EPSILON_COUNTRIES ?= WW CA DE ES FR GB IT NL PT US diff --git a/themes/icons.json b/themes/icons.json index ee6985c86..8a31192a9 100644 --- a/themes/icons.json +++ b/themes/icons.json @@ -6,6 +6,7 @@ "apps/calculation/calculation_icon.png" : "apps/calculation_icon.png", "apps/code/code_icon.png" : "apps/code_icon.png", "apps/external/external_icon.png" : "apps/external_icon.png", + "apps/geometry/geometry_icon.png" : "apps/geometry_icon.png", "apps/graph/graph_icon.png" : "apps/graph_icon.png", "apps/probability/probability_icon.png" : "apps/probability_icon.png", "apps/regression/regression_icon.png" : "apps/regression_icon.png",