[escher] [apps] Implement app snapshot

Change-Id: I24d7eed7cef964af8be1c85222e758c297dc0da1
This commit is contained in:
Émilie Feral
2017-05-17 14:44:00 +02:00
parent 06de0dd9db
commit 71284311bb
51 changed files with 568 additions and 340 deletions

View File

@@ -20,29 +20,23 @@ AppsContainer::AppsContainer() :
m_batteryTimer(BatteryTimer(this)),
m_USBTimer(USBTimer(this)),
m_suspendTimer(SuspendTimer(this)),
m_backlightDimmingTimer(BacklightDimmingTimer())
m_backlightDimmingTimer(BacklightDimmingTimer()),
m_hardwareTestSnapshot(),
m_onBoardingSnapshot(),
m_homeSnapshot(),
m_calculationSnapshot(),
m_graphSnapshot(),
m_sequenceSnapshot(),
m_settingsSnapshot(),
m_statisticsSnapshot(),
m_probabilitySnapshot(),
m_regressionSnapshot()
{
m_descriptors[0] = Home::App::buildDescriptor();
m_descriptors[1] = Calculation::App::buildDescriptor();
m_descriptors[2] = Graph::App::buildDescriptor();
m_descriptors[3] = Sequence::App::buildDescriptor();
m_descriptors[4] = Settings::App::buildDescriptor();
m_descriptors[5] = Statistics::App::buildDescriptor();
m_descriptors[6] = Probability::App::buildDescriptor();
m_descriptors[7] = Regression::App::buildDescriptor();
m_descriptors[8] = OnBoarding::App::buildDescriptor();
m_descriptors[9] = HardwareTest::App::buildDescriptor();
refreshPreferences();
m_emptyBatteryWindow.setFrame(KDRect(0, 0, Ion::Display::Width, Ion::Display::Height));
Poincare::Expression::setCircuitBreaker(AppsContainer::poincareCircuitBreaker);
}
AppsContainer::~AppsContainer() {
for (int i = 0; i < k_totalNumberOfApps; i++) {
delete m_descriptors[i];
}
}
bool AppsContainer::poincareCircuitBreaker(const Poincare::Expression * e) {
Ion::Keyboard::State state = Ion::Keyboard::scan();
return Ion::Keyboard::keyDown(Ion::Keyboard::Key::A6, state);
@@ -52,22 +46,38 @@ int AppsContainer::numberOfApps() {
return k_numberOfCommonApps;
}
App::Descriptor * AppsContainer::appDescriptorAtIndex(int index) {
App::Snapshot * AppsContainer::appSnapshotAtIndex(int index) {
if (index < 0) {
return nullptr;
}
App::Snapshot * snapshots[] = {
&m_homeSnapshot,
&m_calculationSnapshot,
&m_graphSnapshot,
&m_sequenceSnapshot,
&m_settingsSnapshot,
&m_statisticsSnapshot,
&m_probabilitySnapshot,
&m_regressionSnapshot,
};
assert(sizeof(snapshots)/sizeof(snapshots[0]) == k_numberOfCommonApps);
assert(index >= 0 && index < k_numberOfCommonApps);
return m_descriptors[index];
return snapshots[index];
}
App::Descriptor * AppsContainer::hardwareTestAppDescriptor() {
return m_descriptors[k_totalNumberOfApps-1];
App::Snapshot * AppsContainer::hardwareTestAppSnapshot() {
return &m_hardwareTestSnapshot;
}
App::Descriptor * AppsContainer::onBoardingAppDescriptor() {
return m_descriptors[k_totalNumberOfApps - 2];
App::Snapshot * AppsContainer::onBoardingAppSnapshot() {
return &m_onBoardingSnapshot;
}
void AppsContainer::reset() {
Clipboard::sharedClipboard()->reset();
//TODO: persitence->reset()
for (int i = 0; i < k_numberOfCommonApps; i++) {
appSnapshotAtIndex(i)->reset();
}
}
Poincare::Context * AppsContainer::globalContext() {
@@ -83,7 +93,7 @@ VariableBoxController * AppsContainer::variableBoxController() {
}
void AppsContainer::suspend(bool checkIfPowerKeyReleased) {
if (activeApp()->descriptor() != onBoardingAppDescriptor() && GlobalPreferences::sharedGlobalPreferences()->showUpdatePopUp()) {
if (activeApp()->snapshot()!= onBoardingAppSnapshot() && GlobalPreferences::sharedGlobalPreferences()->showUpdatePopUp()) {
activeApp()->displayModalViewController(&m_updateController, 0.f, 0.f);
}
Ion::Power::suspend(checkIfPowerKeyReleased);
@@ -103,12 +113,12 @@ bool AppsContainer::dispatchEvent(Ion::Events::Event event) {
bool alphaLockWantsRedraw = m_window.updateAlphaLock();
// Home and Power buttons are not sent to apps. We handle them straight away.
if (event == Ion::Events::Home && activeApp()->descriptor() != onBoardingAppDescriptor() && activeApp()->descriptor() != hardwareTestAppDescriptor() && activeApp()->descriptor() != appDescriptorAtIndex(0)) {
switchTo(appDescriptorAtIndex(0));
if (event == Ion::Events::Home && activeApp()->snapshot() != onBoardingAppSnapshot() && activeApp()->snapshot() != hardwareTestAppSnapshot()) {
switchTo(appSnapshotAtIndex(0));
return true;
}
if (event == Ion::Events::OnOff && activeApp()->descriptor() != hardwareTestAppDescriptor()) {
if (activeApp()->descriptor() == onBoardingAppDescriptor()) {
if (event == Ion::Events::OnOff && activeApp()->snapshot() != hardwareTestAppSnapshot()) {
if (activeApp()->snapshot() == onBoardingAppSnapshot()) {
((OnBoarding::App *)activeApp())->reinitOnBoarding();
}
suspend(true);
@@ -116,7 +126,7 @@ bool AppsContainer::dispatchEvent(Ion::Events::Event event) {
}
bool didProcessEvent = Container::dispatchEvent(event);
if (!didProcessEvent && event == Ion::Events::Back) {
switchTo(appDescriptorAtIndex(0));
switchTo(appSnapshotAtIndex(0));
return true;
}
if (!didProcessEvent && alphaLockWantsRedraw) {
@@ -126,17 +136,17 @@ bool AppsContainer::dispatchEvent(Ion::Events::Event event) {
return didProcessEvent;
}
void AppsContainer::switchTo(App::Descriptor * descriptor) {
if (descriptor == hardwareTestAppDescriptor() || descriptor == onBoardingAppDescriptor()) {
void AppsContainer::switchTo(App::Snapshot * snapshot) {
if (snapshot == hardwareTestAppSnapshot() || snapshot == onBoardingAppSnapshot()) {
m_window.hideTitleBarView(true);
} else {
m_window.hideTitleBarView(false);
}
if (descriptor) {
m_window.setTitle(descriptor->upperName());
if (snapshot) {
m_window.setTitle(snapshot->descriptor()->upperName());
}
Container::switchTo(descriptor);
if (activeApp()->descriptor() == onBoardingAppDescriptor()) {
Container::switchTo(snapshot);
if (activeApp() != nullptr && activeApp()->snapshot() == onBoardingAppSnapshot()) {
((OnBoarding::App *)activeApp())->reinitOnBoarding();
}
}
@@ -178,12 +188,12 @@ Window * AppsContainer::window() {
}
int AppsContainer::numberOfTimers() {
bool onBoardingTimer = activeApp()->descriptor() == onBoardingAppDescriptor() && ((OnBoarding::App *)activeApp())->hasTimer();
bool onBoardingTimer = activeApp()->snapshot() == onBoardingAppSnapshot() && ((OnBoarding::App *)activeApp())->hasTimer();
return 4+(GlobalPreferences::sharedGlobalPreferences()->examMode() == GlobalPreferences::ExamMode::Activate) + onBoardingTimer;
}
Timer * AppsContainer::timerAtIndex(int i) {
bool onBoardingTimer = activeApp()->descriptor() == onBoardingAppDescriptor() && ((OnBoarding::App *)activeApp())->hasTimer();
bool onBoardingTimer = activeApp()->snapshot() == onBoardingAppSnapshot() && ((OnBoarding::App *)activeApp())->hasTimer();
if (onBoardingTimer && i == 4) {
return ((OnBoarding::App *)activeApp())->timer();
}

View File

@@ -5,13 +5,13 @@
#include "graph/app.h"
#include "probability/app.h"
#include "calculation/app.h"
#include "hardware_test/app.h"
#include "on_boarding/app.h"
#include "on_boarding/update_controller.h"
#include "regression/app.h"
#include "sequence/app.h"
#include "settings/app.h"
#include "statistics/app.h"
#include "on_boarding/app.h"
#include "hardware_test/app.h"
#include "on_boarding/update_controller.h"
#include "apps_window.h"
#include "empty_battery_window.h"
#include "math_toolbox.h"
@@ -31,29 +31,18 @@
class AppsContainer : public Container {
public:
AppsContainer();
~AppsContainer();
/* Rule of 5: the copy constructor, move constructor, copy assignment
* operator and move assignment operator are deleted as their default
* implementation does not create new apps. The new object thus become
* obsolete as soon as the copy is deleted (because of our
* implementation of deletion). To avoid any use of obsolete object,
* we prevent to copy and assign. */
AppsContainer(const AppsContainer& other) = delete;
AppsContainer(AppsContainer&& other) = delete;
AppsContainer& operator=(const AppsContainer& other) = delete;
AppsContainer& operator=(AppsContainer&& other) = delete;
static bool poincareCircuitBreaker(const Poincare::Expression * e);
int numberOfApps();
App::Descriptor * appDescriptorAtIndex(int index);
App::Descriptor * hardwareTestAppDescriptor();
App::Descriptor * onBoardingAppDescriptor();
App::Snapshot * appSnapshotAtIndex(int index);
App::Snapshot * hardwareTestAppSnapshot();
App::Snapshot * onBoardingAppSnapshot();
void reset();
Poincare::Context * globalContext();
MathToolbox * mathToolbox();
VariableBoxController * variableBoxController();
void suspend(bool checkIfPowerKeyReleased = false);
virtual bool dispatchEvent(Ion::Events::Event event) override;
void switchTo(App::Descriptor * descriptor) override;
void switchTo(App::Snapshot * snapshot) override;
void updateBatteryState();
void refreshPreferences();
void displayExamModePopUp(bool activate);
@@ -81,7 +70,16 @@ private:
USBTimer m_USBTimer;
SuspendTimer m_suspendTimer;
BacklightDimmingTimer m_backlightDimmingTimer;
App::Descriptor * m_descriptors[k_totalNumberOfApps];
HardwareTest::App::Snapshot m_hardwareTestSnapshot;
OnBoarding::App::Snapshot m_onBoardingSnapshot;
Home::App::Snapshot m_homeSnapshot;
Calculation::App::Snapshot m_calculationSnapshot;
Graph::App::Snapshot m_graphSnapshot;
Sequence::App::Snapshot m_sequenceSnapshot;
Settings::App::Snapshot m_settingsSnapshot;
Statistics::App::Snapshot m_statisticsSnapshot;
Probability::App::Snapshot m_probabilitySnapshot;
Regression::App::Snapshot m_regressionSnapshot;
};
#endif

View File

@@ -2,16 +2,13 @@
#include "../apps_container.h"
#include "calculation_icon.h"
#include "../i18n.h"
using namespace Poincare;
using namespace Shared;
namespace Calculation {
App * App::Descriptor::build(Container * container) {
return new App(container, this);
}
I18n::Message App::Descriptor::name() {
return I18n::Message::CalculApp;
}
@@ -24,17 +21,33 @@ const Image * App::Descriptor::icon() {
return ImageStore::CalculationIcon;
}
App::App(Container * container, Descriptor * descriptor) :
TextFieldDelegateApp(container, &m_editExpressionController, descriptor),
m_localContext((GlobalContext *)((AppsContainer *)container)->globalContext(), &m_calculationStore),
m_calculationStore(),
m_historyController(&m_editExpressionController, &m_calculationStore),
m_editExpressionController(&m_modalViewController, &m_historyController, &m_calculationStore)
{
App * App::Snapshot::unpack(Container * container) {
return new App(container, this);
}
App::App::Descriptor * App::buildDescriptor() {
return new App::Descriptor();
void App::Snapshot::reset() {
m_calculationStore.deleteAll();
}
App::Descriptor * App::Snapshot::descriptor() {
static Descriptor descriptor;
return &descriptor;
}
CalculationStore * App::Snapshot::calculationStore() {
return &m_calculationStore;
}
void App::Snapshot::tidy() {
m_calculationStore.tidy();
}
App::App(Container * container, Snapshot * snapshot) :
TextFieldDelegateApp(container, snapshot, &m_editExpressionController),
m_localContext((GlobalContext *)((AppsContainer *)container)->globalContext(), snapshot->calculationStore()),
m_historyController(&m_editExpressionController, snapshot->calculationStore()),
m_editExpressionController(&m_modalViewController, &m_historyController, snapshot->calculationStore())
{
}
Context * App::localContext() {

View File

@@ -5,6 +5,7 @@
#include "local_context.h"
#include "history_controller.h"
#include "../shared/text_field_delegate_app.h"
#include "calculation_store.h"
#include <escher.h>
namespace Calculation {
@@ -13,17 +14,24 @@ class App : public Shared::TextFieldDelegateApp {
public:
class Descriptor : public ::App::Descriptor {
public:
App * build(Container * container) override;
I18n::Message name() override;
I18n::Message upperName() override;
const Image * icon() override;
};
static Descriptor * buildDescriptor();
class Snapshot : public ::App::Snapshot {
public:
App * unpack(Container * container) override;
void reset() override;
Descriptor * descriptor() override;
CalculationStore * calculationStore();
private:
void tidy() override;
CalculationStore m_calculationStore;
};
Poincare::Context * localContext() override;
private:
App(Container * container, Descriptor * descriptor);
App(Container * container, Snapshot * snapshot);
LocalContext m_localContext;
CalculationStore m_calculationStore;
HistoryController m_historyController;
EditExpressionController m_editExpressionController;
};

View File

@@ -34,6 +34,59 @@ Calculation::~Calculation() {
void Calculation::reset() {
m_inputText[0] = 0;
m_outputText[0] = 0;
tidy();
}
void Calculation::setContent(const char * c, Context * context) {
reset();
strlcpy(m_inputText, c, sizeof(m_inputText));
output(context)->writeTextInBuffer(m_outputText, sizeof(m_outputText));
}
const char * Calculation::inputText() {
return m_inputText;
}
const char * Calculation::outputText() {
return m_outputText;
}
Expression * Calculation::input() {
if (m_input == nullptr) {
m_input = Expression::parse(m_inputText);
}
return m_input;
}
ExpressionLayout * Calculation::inputLayout() {
if (m_inputLayout == nullptr && input() != nullptr) {
m_inputLayout = input()->createLayout(Expression::FloatDisplayMode::Decimal, Expression::ComplexFormat::Algebric);
}
return m_inputLayout;
}
Expression * Calculation::output(Context * context) {
if (m_output == nullptr && input() != nullptr) {
m_output = input()->evaluate(*context);
}
return m_output;
}
ExpressionLayout * Calculation::outputLayout(Context * context) {
if (m_outputLayout == nullptr && output(context) != nullptr) {
m_outputLayout = output(context)->createLayout();
}
return m_outputLayout;
}
bool Calculation::isEmpty() {
if (strlen(m_inputText) == 0) {
return true;
}
return false;
}
void Calculation::tidy() {
if (m_input != nullptr) {
delete m_input;
}
@@ -52,45 +105,4 @@ void Calculation::reset() {
m_outputLayout = nullptr;
}
void Calculation::setContent(const char * c, Context * context) {
reset();
strlcpy(m_inputText, c, sizeof(m_inputText));
m_input = Expression::parse(m_inputText);
m_inputLayout = m_input->createLayout(Expression::FloatDisplayMode::Decimal, Expression::ComplexFormat::Algebric);
m_output = m_input->evaluate(*context);
m_outputLayout = m_output->createLayout();
m_output->writeTextInBuffer(m_outputText, sizeof(m_outputText));
}
const char * Calculation::inputText() {
return m_inputText;
}
const char * Calculation::outputText() {
return m_outputText;
}
Expression * Calculation::input() {
return m_input;
}
ExpressionLayout * Calculation::inputLayout() {
return m_inputLayout;
}
Expression * Calculation::output() {
return m_output;
}
ExpressionLayout * Calculation::outputLayout() {
return m_outputLayout;
}
bool Calculation::isEmpty() {
if (m_output == nullptr) {
return true;
}
return false;
}
}

View File

@@ -20,10 +20,11 @@ public:
const char * outputText();
Poincare::Expression * input();
Poincare::ExpressionLayout * inputLayout();
Poincare::Expression * output();
Poincare::ExpressionLayout * outputLayout();
Poincare::Expression * output(Poincare::Context * context);
Poincare::ExpressionLayout * outputLayout(Poincare::Context * context);
void setContent(const char * c, Poincare::Context * context);
bool isEmpty();
void tidy();
private:
char m_inputText[::TextField::maxBufferSize()];
char m_outputText[::TextField::maxBufferSize()];

View File

@@ -61,4 +61,10 @@ void CalculationStore::deleteAll() {
}
}
void CalculationStore::tidy() {
for (int i = 0; i < k_maxNumberOfCalculations; i++) {
m_calculations[i].tidy();
}
}
}

View File

@@ -15,6 +15,7 @@ public:
void deleteCalculationAtIndex(int i);
void deleteAll();
int numberOfCalculations();
void tidy();
private:
static constexpr int k_maxNumberOfCalculations = 10;
Calculation * m_start;

View File

@@ -108,7 +108,6 @@ void HistoryController::tableViewDidChangeSelection(SelectableTableView * t, int
if (selectedCell == nullptr) {
return;
}
selectedCell->setParentResponder(t);
if (selectedRow() < previousSelectedCellY) {
selectedCell->setSelectedSubviewType(HistoryViewCell::SubviewType::Output);
}
@@ -147,7 +146,8 @@ void HistoryController::willDisplayCellForIndex(HighlightCell * cell, int index)
KDCoordinate HistoryController::rowHeight(int j) {
Calculation * calculation = m_calculationStore->calculationAtIndex(j);
KDCoordinate inputHeight = calculation->inputLayout()->size().height();
KDCoordinate outputHeight = calculation->outputLayout()->size().height();
App * calculationApp = (App *)app();
KDCoordinate outputHeight = calculation->outputLayout(calculationApp->localContext())->size().height();
return inputHeight + outputHeight + 3*HistoryViewCell::k_digitVerticalMargin;
}
@@ -181,10 +181,11 @@ CalculationSelectableTableView * HistoryController::selectableTableView() {
}
View * HistoryController::loadView() {
for (int i = 0; i < k_maxNumberOfDisplayedRows; i++) {
m_calculationHistory[i] = new HistoryViewCell();
CalculationSelectableTableView * tableView = new CalculationSelectableTableView(this, this, this);
for (int i = 0; i < k_maxNumberOfDisplayedRows; i++) {
m_calculationHistory[i] = new HistoryViewCell(tableView);
}
return new CalculationSelectableTableView(this, this, this);
return tableView;
}
void HistoryController::unloadView(View * view) {

View File

@@ -1,4 +1,5 @@
#include "history_view_cell.h"
#include "app.h"
#include "../constant.h"
#include "selectable_table_view.h"
#include <assert.h>
@@ -6,8 +7,8 @@
namespace Calculation {
HistoryViewCell::HistoryViewCell() :
Responder(nullptr),
HistoryViewCell::HistoryViewCell(Responder * parentResponder) :
Responder(parentResponder),
m_inputView(this),
m_outputView(this),
m_selectedSubviewType(HistoryViewCell::SubviewType::Output)
@@ -48,7 +49,8 @@ void HistoryViewCell::layoutSubviews() {
void HistoryViewCell::setCalculation(Calculation * calculation) {
m_inputView.setExpression(calculation->inputLayout());
m_outputView.setExpression(calculation->outputLayout());
App * calculationApp = (App *)app();
m_outputView.setExpression(calculation->outputLayout(calculationApp->localContext()));
}
void HistoryViewCell::reloadCell() {

View File

@@ -13,7 +13,7 @@ public:
Input,
Output
};
HistoryViewCell();
HistoryViewCell(Responder * parentResponder);
void reloadCell() override;
KDColor backgroundColor() const override;
void setCalculation(Calculation * calculation);

View File

@@ -15,7 +15,7 @@ Expression * LocalContext::ansValue() {
return m_parentContext->defaultExpression();
}
Calculation * lastCalculation = m_calculationStore->calculationAtIndex(m_calculationStore->numberOfCalculations()-1);
return lastCalculation->output();
return lastCalculation->output(m_parentContext);
}
void LocalContext::setExpressionForSymbolName(Expression * expression, const Symbol * symbol) {

View File

@@ -8,10 +8,6 @@ using namespace Shared;
namespace Graph {
App * App::Descriptor::build(Container * container) {
return new App(container, this);
}
I18n::Message App::Descriptor::name() {
return I18n::Message::FunctionApp;
}
@@ -24,19 +20,39 @@ const Image * App::Descriptor::icon() {
return ImageStore::GraphIcon;
}
App::App(Container * container, Descriptor * descriptor) :
FunctionApp(container, &m_inputViewController, descriptor),
m_functionStore(),
App * App::Snapshot::unpack(Container * container) {
return new App(container, this);
}
void App::Snapshot::reset() {
m_functionStore.removeAll();
}
App::Descriptor * App::Snapshot::descriptor() {
static Descriptor descriptor;
return &descriptor;
}
CartesianFunctionStore * App::Snapshot::functionStore() {
return &m_functionStore;
}
void App::Snapshot::tidy() {
m_functionStore.tidy();
}
App::App(Container * container, Snapshot * snapshot) :
FunctionApp(container, snapshot, &m_inputViewController),
m_xContext('x',((AppsContainer *)container)->globalContext()),
m_listController(&m_listFooter, &m_functionStore, &m_listHeader, &m_listFooter),
m_listController(&m_listFooter, snapshot->functionStore(), &m_listHeader, &m_listFooter),
m_listFooter(&m_listHeader, &m_listController, &m_listController, ButtonRowController::Position::Bottom, ButtonRowController::Style::EmbossedGrey),
m_listHeader(&m_listStackViewController, &m_listFooter, &m_listController),
m_listStackViewController(&m_tabViewController, &m_listHeader),
m_graphController(&m_graphAlternateEmptyViewController, &m_functionStore, &m_graphHeader),
m_graphController(&m_graphAlternateEmptyViewController, snapshot->functionStore(), &m_graphHeader),
m_graphAlternateEmptyViewController(&m_graphHeader, &m_graphController, &m_graphController),
m_graphHeader(&m_graphStackViewController, &m_graphAlternateEmptyViewController, &m_graphController),
m_graphStackViewController(&m_tabViewController, &m_graphHeader),
m_valuesController(&m_valuesAlternateEmptyViewController, &m_functionStore, &m_valuesHeader),
m_valuesController(&m_valuesAlternateEmptyViewController, snapshot->functionStore(), &m_valuesHeader),
m_valuesAlternateEmptyViewController(&m_valuesHeader, &m_valuesController, &m_valuesController),
m_valuesHeader(&m_valuesStackViewController, &m_valuesAlternateEmptyViewController, &m_valuesController),
m_valuesStackViewController(&m_tabViewController, &m_valuesHeader),
@@ -45,10 +61,6 @@ App::App(Container * container, Descriptor * descriptor) :
{
}
App::Descriptor * App::buildDescriptor() {
return new App::Descriptor();
}
InputViewController * App::inputViewController() {
return &m_inputViewController;
}

View File

@@ -15,12 +15,20 @@ class App : public Shared::FunctionApp {
public:
class Descriptor : public ::App::Descriptor {
public:
App * build(Container * container) override;
I18n::Message name() override;
I18n::Message upperName() override;
const Image * icon() override;
};
static Descriptor * buildDescriptor();
class Snapshot : public ::App::Snapshot {
public:
App * unpack(Container * container) override;
void reset() override;
Descriptor * descriptor() override;
CartesianFunctionStore * functionStore();
private:
void tidy() override;
CartesianFunctionStore m_functionStore;
};
InputViewController * inputViewController() override;
/* This local context can parse x. However, it always stores NAN
* as x value. When we need to evaluate expression with a specific x value, we
@@ -28,8 +36,7 @@ public:
* weird x values after drawing curves or displaying the value table. */
Poincare::Context * localContext() override;
private:
App(Container * container, Descriptor * descriptor);
CartesianFunctionStore m_functionStore;
App(Container * container, Snapshot * snapshot);
Poincare::VariableContext m_xContext;
ListController m_listController;
ButtonRowController m_listFooter;

View File

@@ -1,4 +1,5 @@
#include "curve_parameter_controller.h"
#include "../../i18n.h"
#include <assert.h>
using namespace Shared;

View File

@@ -7,18 +7,19 @@ extern "C" {
namespace HardwareTest {
App * App::Descriptor::build(Container * container) {
App * App::Snapshot::unpack(Container * container) {
return new App(container, this);
}
App::App(Container * container, Descriptor * descriptor) :
::App(container, &m_keyboardController, descriptor),
App::Descriptor * App::Snapshot::descriptor() {
static Descriptor descriptor;
return &descriptor;
}
App::App(Container * container, Snapshot * snapshot) :
::App(container, snapshot, &m_keyboardController),
m_keyboardController(&m_modalViewController)
{
}
App::Descriptor * App::buildDescriptor() {
return new App::Descriptor();
}
}

View File

@@ -10,13 +10,13 @@ namespace HardwareTest {
class App : public ::App {
public:
class Descriptor : public ::App::Descriptor {
class Snapshot : public ::App::Snapshot {
public:
App * build(Container * container) override;
App * unpack(Container * container) override;
Descriptor * descriptor() override;
};
static Descriptor * buildDescriptor();
private:
App(Container * container, Descriptor * descriptor);
App(Container * container, Snapshot * snapshot);
KeyboardController m_keyboardController;
};

View File

@@ -20,7 +20,7 @@ bool ColorController::handleEvent(Ion::Events::Event event) {
m_view.setColors(nextColor(m_view.fillColor()), nextColor(m_view.outlineColor()));
if (m_view.fillColor() == KDColorBlack) {
AppsContainer * container = (AppsContainer *)app()->container();
container->switchTo(container->appDescriptorAtIndex(0));
container->switchTo(container->appSnapshotAtIndex(0));
}
return true;
}

View File

@@ -1,6 +1,6 @@
#include "app.h"
#include "../apps_container.h"
#include "../i18n.h"
#include "../apps_container.h"
extern "C" {
#include <assert.h>
@@ -8,10 +8,6 @@ extern "C" {
namespace Home {
App * App::Descriptor::build(Container * container) {
return new App(container, this);
}
I18n::Message App::Descriptor::name() {
return I18n::Message::Apps;
}
@@ -20,14 +16,19 @@ I18n::Message App::Descriptor::upperName() {
return I18n::Message::AppsCapital;
}
App::App(Container * container, Descriptor * descriptor) :
::App(container, &m_controller, descriptor, I18n::Message::Warning),
App * App::Snapshot::unpack(Container * container) {
return new App(container, this);
}
App::Descriptor * App::Snapshot::descriptor() {
static Descriptor descriptor;
return &descriptor;
}
App::App(Container * container, Snapshot * snapshot) :
::App(container, snapshot, &m_controller, I18n::Message::Warning),
m_controller(&m_modalViewController, (AppsContainer *)container)
{
}
App::Descriptor * App::buildDescriptor() {
return new App::Descriptor();
}
}

View File

@@ -12,13 +12,16 @@ class App : public ::App {
public:
class Descriptor : public ::App::Descriptor {
public:
App * build(Container * container) override;
I18n::Message name() override;
I18n::Message upperName() override;
};
static Descriptor * buildDescriptor();
class Snapshot : public ::App::Snapshot {
public:
App * unpack(Container * container) override;
Descriptor * descriptor() override;
};
private:
App(Container * container, Descriptor * descriptor);
App(Container * container, Snapshot * snapshot);
Controller m_controller;
};

View File

@@ -47,7 +47,7 @@ Controller::Controller(Responder * parentResponder, ::AppsContainer * container)
bool Controller::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::OK || event == Ion::Events::EXE) {
m_container->switchTo(m_container->appDescriptorAtIndex(selectedRow()*k_numberOfColumns+selectedColumn()+1));
m_container->switchTo(m_container->appSnapshotAtIndex(selectedRow()*k_numberOfColumns+selectedColumn()+1));
return true;
}
return false;
@@ -101,7 +101,7 @@ void Controller::willDisplayCellAtLocation(HighlightCell * cell, int i, int j) {
appCell->setVisible(false);
} else {
appCell->setVisible(true);
::App::Descriptor * descriptor = m_container->appDescriptorAtIndex((j*k_numberOfColumns+i)+1);
::App::Descriptor * descriptor = m_container->appSnapshotAtIndex((j*k_numberOfColumns+i)+1)->descriptor();
appCell->setAppDescriptor(descriptor);
}
}

View File

@@ -3,7 +3,7 @@
AppsContainer container;
void ion_app() {
container.switchTo(container.onBoardingAppDescriptor());
container.switchTo(container.onBoardingAppSnapshot());
container.run();
container.switchTo(nullptr);
}

View File

@@ -3,21 +3,22 @@
namespace OnBoarding {
App * App::Descriptor::build(Container * container) {
App * App::Snapshot::unpack(Container * container) {
return new App(container, this);
}
App::App(Container * container, Descriptor * descriptor) :
::App(container, &m_languageController, descriptor),
App::Descriptor * App::Snapshot::descriptor() {
static Descriptor descriptor;
return &descriptor;
}
App::App(Container * container, Snapshot * snapshot) :
::App(container, snapshot, &m_languageController),
m_languageController(&m_modalViewController, &m_logoController, ((AppsContainer *)container)->updatePopUpController()),
m_logoController()
{
}
App::Descriptor * App::buildDescriptor() {
return new App::Descriptor();
}
void App::reinitOnBoarding() {
m_languageController.reinitOnBoarding();
}

View File

@@ -10,16 +10,16 @@ namespace OnBoarding {
class App : public ::App {
public:
class Descriptor : public ::App::Descriptor {
class Snapshot : public ::App::Snapshot {
public:
App * build(Container * container) override;
App * unpack(Container * container) override;
Descriptor * descriptor() override;
};
static Descriptor * buildDescriptor();
void reinitOnBoarding();
bool hasTimer();
Timer * timer();
private:
App(Container * container, Descriptor * descriptor);
App(Container * container, Snapshot * snapshot);
LanguageController m_languageController;
LogoController m_logoController;
};

View File

@@ -16,8 +16,8 @@ bool UpdateController::handleEvent(Ion::Events::Event event) {
if (event != Ion::Events::Back) {
app()->dismissModalViewController();
AppsContainer * appsContainer = (AppsContainer *)app()->container();
if (appsContainer->activeApp()->descriptor() == appsContainer->onBoardingAppDescriptor()) {
appsContainer->switchTo(appsContainer->appDescriptorAtIndex(0));
if (appsContainer->activeApp()->snapshot() == appsContainer->onBoardingAppSnapshot()) {
appsContainer->switchTo(appsContainer->appSnapshotAtIndex(0));
}
return true;
}

View File

@@ -1,14 +1,11 @@
#include "app.h"
#include "../i18n.h"
#include "probability_icon.h"
using namespace Shared;
namespace Probability {
App * App::Descriptor::build(Container * container) {
return new App(container, this);
}
I18n::Message App::Descriptor::name() {
return I18n::Message::ProbaApp;
}
@@ -21,15 +18,20 @@ const Image * App::Descriptor::icon() {
return ImageStore::ProbabilityIcon;
}
App::App(Container * container, Descriptor * descriptor) :
TextFieldDelegateApp(container, &m_stackViewController, descriptor),
App * App::Snapshot::unpack(Container * container) {
return new App(container, this);
}
App::Descriptor * App::Snapshot::descriptor() {
static Descriptor descriptor;
return &descriptor;
}
App::App(Container * container, Snapshot * snapshot) :
TextFieldDelegateApp(container, snapshot, &m_stackViewController),
m_lawController(nullptr),
m_stackViewController(&m_modalViewController, &m_lawController)
{
}
App::Descriptor * App::buildDescriptor() {
return new App::Descriptor();
}
}

View File

@@ -12,14 +12,17 @@ class App : public Shared::TextFieldDelegateApp {
public:
class Descriptor : public ::App::Descriptor {
public:
App * build(Container * container) override;
I18n::Message name() override;
I18n::Message upperName() override;
const Image * icon() override;
};
static Descriptor * buildDescriptor();
class Snapshot : public ::App::Snapshot {
public:
App * unpack(Container * container) override;
Descriptor * descriptor() override;
};
private:
App(Container * container, Descriptor * descriptor);
App(Container * container, Snapshot * snapshot);
LawController m_lawController;
StackViewController m_stackViewController;
};

View File

@@ -1,6 +1,7 @@
#include "calculation_controller.h"
#include "../constant.h"
#include "../apps_container.h"
#include "app.h"
#include "calculation/left_integral_calculation.h"
#include "calculation/right_integral_calculation.h"
#include "calculation/finite_integral_calculation.h"

View File

@@ -6,10 +6,6 @@ using namespace Shared;
namespace Regression {
App * App::Descriptor::build(Container * container) {
return new App(container, this);
}
I18n::Message App::Descriptor::name() {
return I18n::Message::RegressionApp;
}
@@ -22,25 +18,38 @@ const Image * App::Descriptor::icon() {
return ImageStore::RegressionIcon;
}
App::App(Container * container, Descriptor * descriptor) :
TextFieldDelegateApp(container, &m_tabViewController, descriptor),
m_store(),
m_calculationController(&m_calculationAlternateEmptyViewController, &m_calculationHeader, &m_store),
App * App::Snapshot::unpack(Container * container) {
return new App(container, this);
}
void App::Snapshot::reset() {
m_store.deleteAllPairs();
}
App::Descriptor * App::Snapshot::descriptor() {
static Descriptor descriptor;
return &descriptor;
}
Store * App::Snapshot::store() {
return &m_store;
}
App::App(Container * container, Snapshot * snapshot) :
TextFieldDelegateApp(container, snapshot, &m_tabViewController),
m_calculationController(&m_calculationAlternateEmptyViewController, &m_calculationHeader, snapshot->store()),
m_calculationAlternateEmptyViewController(&m_calculationHeader, &m_calculationController, &m_calculationController),
m_calculationHeader(&m_tabViewController, &m_calculationAlternateEmptyViewController, &m_calculationController),
m_graphController(&m_graphAlternateEmptyViewController, &m_graphHeader, &m_store),
m_graphController(&m_graphAlternateEmptyViewController, &m_graphHeader, snapshot->store()),
m_graphAlternateEmptyViewController(&m_graphHeader, &m_graphController, &m_graphController),
m_graphHeader(&m_graphStackViewController, &m_graphAlternateEmptyViewController, &m_graphController),
m_graphStackViewController(&m_tabViewController, &m_graphHeader),
m_storeController(&m_storeHeader, &m_store, &m_storeHeader),
m_storeController(&m_storeHeader, snapshot->store(), &m_storeHeader),
m_storeHeader(&m_storeStackViewController, &m_storeController, &m_storeController),
m_storeStackViewController(&m_tabViewController, &m_storeHeader),
m_tabViewController(&m_modalViewController, &m_storeStackViewController, &m_graphStackViewController, &m_calculationHeader)
{
}
App::Descriptor * App::buildDescriptor() {
return new App::Descriptor();
}
}

View File

@@ -14,15 +14,21 @@ class App : public Shared::TextFieldDelegateApp {
public:
class Descriptor : public ::App::Descriptor {
public:
App * build(Container * container) override;
I18n::Message name() override;
I18n::Message upperName() override;
const Image * icon() override;
};
static Descriptor * buildDescriptor();
class Snapshot : public ::App::Snapshot {
public:
App * unpack(Container * container) override;
void reset() override;
Descriptor * descriptor() override;
Store * store();
private:
Store m_store;
};
private:
App(Container * container, Descriptor * descriptor);
Store m_store;
App(Container * container, Snapshot * snapshot);
CalculationController m_calculationController;
AlternateEmptyViewController m_calculationAlternateEmptyViewController;
ButtonRowController m_calculationHeader;

View File

@@ -6,10 +6,6 @@ using namespace Poincare;
namespace Sequence {
App * App::Descriptor::build(Container * container) {
return new App(container, this);
}
I18n::Message App::Descriptor::name() {
return I18n::Message::SequenceApp;
}
@@ -22,19 +18,39 @@ const Image * App::Descriptor::icon() {
return ImageStore::SequenceIcon;
}
App::App(Container * container, Descriptor * descriptor) :
FunctionApp(container, &m_inputViewController, descriptor),
m_sequenceStore(),
App * App::Snapshot::unpack(Container * container) {
return new App(container, this);
}
void App::Snapshot::reset() {
m_sequenceStore.removeAll();
}
App::Descriptor * App::Snapshot::descriptor() {
static Descriptor descriptor;
return &descriptor;
}
SequenceStore * App::Snapshot::sequenceStore() {
return &m_sequenceStore;
}
void App::Snapshot::tidy() {
m_sequenceStore.tidy();
}
App::App(Container * container, Snapshot * snapshot) :
FunctionApp(container, snapshot, &m_inputViewController),
m_nContext(((AppsContainer *)container)->globalContext()),
m_listController(&m_listFooter, &m_sequenceStore, &m_listHeader, &m_listFooter),
m_listController(&m_listFooter, snapshot->sequenceStore(), &m_listHeader, &m_listFooter),
m_listFooter(&m_listHeader, &m_listController, &m_listController, ButtonRowController::Position::Bottom, ButtonRowController::Style::EmbossedGrey),
m_listHeader(nullptr, &m_listFooter, &m_listController),
m_listStackViewController(&m_tabViewController, &m_listHeader),
m_graphController(&m_graphAlternateEmptyViewController, &m_sequenceStore, &m_graphHeader),
m_graphController(&m_graphAlternateEmptyViewController, snapshot->sequenceStore(), &m_graphHeader),
m_graphAlternateEmptyViewController(&m_graphHeader, &m_graphController, &m_graphController),
m_graphHeader(&m_graphStackViewController, &m_graphAlternateEmptyViewController, &m_graphController),
m_graphStackViewController(&m_tabViewController, &m_graphHeader),
m_valuesController(&m_valuesAlternateEmptyViewController, &m_sequenceStore, &m_valuesHeader),
m_valuesController(&m_valuesAlternateEmptyViewController, snapshot->sequenceStore(), &m_valuesHeader),
m_valuesAlternateEmptyViewController(&m_valuesHeader, &m_valuesController, &m_valuesController),
m_valuesHeader(nullptr, &m_valuesAlternateEmptyViewController, &m_valuesController),
m_valuesStackViewController(&m_tabViewController, &m_valuesHeader),
@@ -43,10 +59,6 @@ App::App(Container * container, Descriptor * descriptor) :
{
}
App::Descriptor * App::buildDescriptor() {
return new App::Descriptor();
}
InputViewController * App::inputViewController() {
return &m_inputViewController;
}

View File

@@ -16,18 +16,25 @@ class App : public Shared::FunctionApp {
public:
class Descriptor : public ::App::Descriptor {
public:
App * build(Container * container) override;
I18n::Message name() override;
I18n::Message upperName() override;
const Image * icon() override;
};
static Descriptor * buildDescriptor();
class Snapshot : public ::App::Snapshot {
public:
App * unpack(Container * container) override;
void reset() override;
Descriptor * descriptor() override;
SequenceStore * sequenceStore();
private:
void tidy() override;
SequenceStore m_sequenceStore;
};
InputViewController * inputViewController() override;
Poincare::Context * localContext() override;
const char * XNT() override;
private:
App(Container * container, Descriptor * descriptor);
SequenceStore m_sequenceStore;
App(Container * container, Snapshot * snapshot);
LocalContext m_nContext;
ListController m_listController;
ButtonRowController m_listFooter;

View File

@@ -95,56 +95,40 @@ Sequence::Type Sequence::type() {
void Sequence::setType(Type type) {
m_type = type;
if (m_nameLayout != nullptr) {
delete m_nameLayout;
m_nameLayout = nullptr;
}
if (m_definitionName != nullptr) {
delete m_definitionName;
m_definitionName = nullptr;
}
if (m_firstInitialConditionName != nullptr) {
delete m_firstInitialConditionName;
m_firstInitialConditionName = nullptr;
}
if (m_secondInitialConditionName != nullptr) {
delete m_secondInitialConditionName;
m_secondInitialConditionName = nullptr;
}
tidy();
/* Reset all contents */
setContent("");
setFirstInitialConditionContent("");
setSecondInitialConditionContent("");
m_nameLayout = new BaselineRelativeLayout(new StringLayout(name(), 1), new StringLayout("n", 1, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript);
if (m_type == Type::Explicite) {
m_definitionName = new BaselineRelativeLayout(new StringLayout(name(), 1), new StringLayout("n ", 2, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript);
}
if (m_type == Type::SingleRecurrence) {
m_definitionName = new BaselineRelativeLayout(new StringLayout(name(), 1), new StringLayout("n+1 ", 4, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript);
m_firstInitialConditionName = new BaselineRelativeLayout(new StringLayout(name(), 1), new StringLayout("0", 1, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript);
}
if (m_type == Type::DoubleRecurrence) {
m_definitionName = new BaselineRelativeLayout(new StringLayout(name(), 1), new StringLayout("n+2 ", 4, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript);
m_firstInitialConditionName = new BaselineRelativeLayout(new StringLayout(name(), 1), new StringLayout("0", 1, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript);
m_secondInitialConditionName = new BaselineRelativeLayout(new StringLayout(name(), 1), new StringLayout("1", 1, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript);
}
m_indexBuffer[0] = -1;
m_indexBuffer[1] = -1;
}
Poincare::Expression * Sequence::firstInitialConditionExpression() {
if (m_firstInitialConditionExpression == nullptr) {
m_firstInitialConditionExpression = Poincare::Expression::parse(m_firstInitialConditionText);
}
return m_firstInitialConditionExpression;
}
Poincare::Expression * Sequence::secondInitialConditionExpression() {
if (m_secondInitialConditionExpression == nullptr) {
m_secondInitialConditionExpression = Poincare::Expression::parse(m_secondInitialConditionText);
}
return m_secondInitialConditionExpression;
}
Poincare::ExpressionLayout * Sequence::firstInitialConditionLayout() {
if (m_firstInitialConditionLayout == nullptr && firstInitialConditionExpression() != nullptr) {
m_firstInitialConditionLayout = firstInitialConditionExpression()->createLayout(Expression::FloatDisplayMode::Decimal);
}
return m_firstInitialConditionLayout;
}
Poincare::ExpressionLayout * Sequence::secondInitialConditionLayout() {
if (m_secondInitialConditionLayout == nullptr && secondInitialConditionExpression()) {
m_secondInitialConditionLayout = secondInitialConditionExpression()->createLayout(Expression::FloatDisplayMode::Decimal);
}
return m_secondInitialConditionLayout;
}
@@ -158,14 +142,11 @@ void Sequence::setFirstInitialConditionContent(const char * c) {
strlcpy(m_firstInitialConditionText, c, sizeof(m_firstInitialConditionText));
if (m_firstInitialConditionExpression != nullptr) {
delete m_firstInitialConditionExpression;
m_firstInitialConditionExpression = nullptr;
}
m_firstInitialConditionExpression = Poincare::Expression::parse(m_firstInitialConditionText);
if (m_firstInitialConditionLayout != nullptr) {
delete m_firstInitialConditionLayout;
}
m_firstInitialConditionLayout = nullptr;
if (m_firstInitialConditionExpression) {
m_firstInitialConditionLayout = m_firstInitialConditionExpression->createLayout(Expression::FloatDisplayMode::Decimal);
m_firstInitialConditionLayout = nullptr;
}
m_indexBuffer[0] = -1;
m_indexBuffer[1] = -1;
@@ -175,14 +156,11 @@ void Sequence::setSecondInitialConditionContent(const char * c) {
strlcpy(m_secondInitialConditionText, c, sizeof(m_secondInitialConditionText));
if (m_secondInitialConditionExpression != nullptr) {
delete m_secondInitialConditionExpression;
m_secondInitialConditionExpression = nullptr;
}
m_secondInitialConditionExpression = Poincare::Expression::parse(m_secondInitialConditionText);
if (m_secondInitialConditionLayout != nullptr) {
delete m_secondInitialConditionLayout;
}
m_secondInitialConditionLayout = nullptr;
if (m_secondInitialConditionExpression) {
m_secondInitialConditionLayout = m_secondInitialConditionExpression->createLayout(Expression::FloatDisplayMode::Decimal);
m_secondInitialConditionLayout = nullptr;
}
m_indexBuffer[0] = -1;
m_indexBuffer[1] = -1;
@@ -197,29 +175,57 @@ int Sequence::numberOfElements() {
}
Poincare::ExpressionLayout * Sequence::nameLayout() {
if (m_nameLayout == nullptr) {
m_nameLayout = new BaselineRelativeLayout(new StringLayout(name(), 1), new StringLayout("n", 1, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript);
}
return m_nameLayout;
}
Poincare::ExpressionLayout * Sequence::definitionName() {
if (m_definitionName == nullptr) {
if (m_type == Type::Explicite) {
m_definitionName = new BaselineRelativeLayout(new StringLayout(name(), 1), new StringLayout("n ", 2, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript);
}
if (m_type == Type::SingleRecurrence) {
m_definitionName = new BaselineRelativeLayout(new StringLayout(name(), 1), new StringLayout("n+1 ", 4, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript);
}
if (m_type == Type::DoubleRecurrence) {
m_definitionName = new BaselineRelativeLayout(new StringLayout(name(), 1), new StringLayout("n+2 ", 4, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript);
}
}
return m_definitionName;
}
Poincare::ExpressionLayout * Sequence::firstInitialConditionName() {
if (m_firstInitialConditionName == nullptr) {
if (m_type == Type::SingleRecurrence) {
m_firstInitialConditionName = new BaselineRelativeLayout(new StringLayout(name(), 1), new StringLayout("0", 1, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript);
}
if (m_type == Type::DoubleRecurrence) {
m_firstInitialConditionName = new BaselineRelativeLayout(new StringLayout(name(), 1), new StringLayout("0", 1, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript);
}
}
return m_firstInitialConditionName;
}
Poincare::ExpressionLayout * Sequence::secondInitialConditionName() {
if (m_secondInitialConditionName == nullptr) {
if (m_type == Type::DoubleRecurrence) {
m_secondInitialConditionName = new BaselineRelativeLayout(new StringLayout(name(), 1), new StringLayout("1", 1, KDText::FontSize::Small), BaselineRelativeLayout::Type::Subscript);
}
}
return m_secondInitialConditionName;
}
bool Sequence::isDefined() {
switch (m_type) {
case Type::Explicite:
return expression() != nullptr;
return strlen(text()) != 0;
case Type::SingleRecurrence:
return expression() != nullptr && m_firstInitialConditionExpression != nullptr;
return strlen(text()) != 0 && strlen(firstInitialConditionText()) != 0;
default:
return expression() != nullptr && m_firstInitialConditionExpression != nullptr && m_secondInitialConditionExpression != nullptr;
return strlen(text()) != 0 && strlen(firstInitialConditionText()) != 0 && strlen(secondInitialConditionText()) != 0;
}
}
@@ -319,4 +325,40 @@ float Sequence::sumOfTermsBetweenAbscissa(float start, float end, Context * cont
return result;
}
void Sequence::tidy() {
Function::tidy();
if (m_firstInitialConditionLayout != nullptr) {
delete m_firstInitialConditionLayout;
m_firstInitialConditionLayout = nullptr;
}
if (m_secondInitialConditionLayout != nullptr) {
delete m_secondInitialConditionLayout;
m_secondInitialConditionLayout = nullptr;
}
if (m_firstInitialConditionExpression != nullptr) {
delete m_firstInitialConditionExpression;
m_firstInitialConditionExpression = nullptr;
}
if (m_secondInitialConditionExpression != nullptr) {
delete m_secondInitialConditionExpression;
m_secondInitialConditionExpression = nullptr;
}
if (m_nameLayout != nullptr) {
delete m_nameLayout;
m_nameLayout = nullptr;
}
if (m_definitionName != nullptr) {
delete m_definitionName;
m_definitionName = nullptr;
}
if (m_firstInitialConditionName != nullptr) {
delete m_firstInitialConditionName;
m_firstInitialConditionName = nullptr;
}
if (m_secondInitialConditionName != nullptr) {
delete m_secondInitialConditionName;
m_secondInitialConditionName = nullptr;
}
}
}

View File

@@ -38,6 +38,7 @@ public:
bool isEmpty() override;
float evaluateAtAbscissa(float x, Poincare::Context * context) const override;
float sumOfTermsBetweenAbscissa(float start, float end, Poincare::Context * context);
void tidy() override;
private:
constexpr static int k_maxRecurrentRank = 10000;
constexpr static float k_maxNumberOfTermsInSum = 100000.0f;

View File

@@ -4,10 +4,6 @@
namespace Settings {
App * App::Descriptor::build(Container * container) {
return new App(container, this);
}
I18n::Message App::Descriptor::name() {
return I18n::Message::SettingsApp;
}
@@ -20,15 +16,20 @@ const Image * App::Descriptor::icon() {
return ImageStore::SettingsIcon;
}
App::App(Container * container, Descriptor * descriptor) :
::App(container, &m_stackViewController, descriptor, I18n::Message::Warning),
App * App::Snapshot::unpack(Container * container) {
return new App(container, this);
}
App::Descriptor * App::Snapshot::descriptor() {
static Descriptor descriptor;
return &descriptor;
}
App::App(Container * container, Snapshot * snapshot) :
::App(container, snapshot, &m_stackViewController, I18n::Message::Warning),
m_mainController(&m_stackViewController),
m_stackViewController(&m_modalViewController, &m_mainController)
{
}
App::Descriptor * App::buildDescriptor() {
return new App::Descriptor();
}
}

View File

@@ -10,14 +10,17 @@ class App : public ::App {
public:
class Descriptor : public ::App::Descriptor {
public:
App * build(Container * container) override;
I18n::Message name() override;
I18n::Message upperName() override;
const Image * icon() override;
};
static Descriptor * buildDescriptor();
class Snapshot : public ::App::Snapshot {
public:
App * unpack(Container * container) override;
Descriptor * descriptor() override;
};
private:
App(Container * container, Descriptor * descriptor);
App(Container * container, Snapshot * snapshot);
MainController m_mainController;
StackViewController m_stackViewController;
};

View File

@@ -60,7 +60,7 @@ bool SubController::handleEvent(Ion::Events::Event event) {
* clicking on '6' on the serial number row. */
if (event == Ion::Events::Six && m_nodeModel->label() == I18n::Message::About && selectedRow() == 1) {
AppsContainer * appsContainer = (AppsContainer *)app()->container();
appsContainer->switchTo(appsContainer->hardwareTestAppDescriptor());
appsContainer->switchTo(appsContainer->hardwareTestAppSnapshot());
return true;
}
if (event == Ion::Events::OK || event == Ion::Events::EXE) {

View File

@@ -27,16 +27,13 @@ Function& Function::operator=(const Function& other) {
void Function::setContent(const char * c) {
strlcpy(m_text, c, sizeof(m_text));
if (m_expression != nullptr) {
delete m_expression;
}
m_expression = Poincare::Expression::parse(m_text);
if (m_layout != nullptr) {
delete m_layout;
m_layout = nullptr;
}
m_layout = nullptr;
if (m_expression) {
m_layout = expression()->createLayout(Expression::FloatDisplayMode::Decimal);
if (m_expression != nullptr) {
delete m_expression;
m_expression = nullptr;
}
}
@@ -64,15 +61,21 @@ const char * Function::name() const {
}
Poincare::Expression * Function::expression() {
if (m_expression == nullptr) {
m_expression = Expression::parse(m_text);
}
return m_expression;
}
Poincare::ExpressionLayout * Function::layout() {
if (m_layout == nullptr && expression() != nullptr) {
m_layout = expression()->createLayout(Expression::FloatDisplayMode::Decimal);
}
return m_layout;
}
bool Function::isDefined() {
return m_expression != nullptr;
return strlen(m_text) != 0;
}
bool Function::isActive() {
@@ -95,4 +98,15 @@ float Function::evaluateAtAbscissa(float x, Poincare::Context * context) const {
return m_expression->approximate(variableContext);
}
void Function::tidy() {
if (m_layout != nullptr) {
delete m_layout;
m_layout = nullptr;
}
if (m_expression != nullptr) {
delete m_expression;
m_expression = nullptr;
}
}
}

View File

@@ -27,6 +27,7 @@ public:
virtual void setContent(const char * c);
void setColor(KDColor m_color);
virtual float evaluateAtAbscissa(float x, Poincare::Context * context) const;
virtual void tidy();
protected:
Poincare::Expression * m_expression;
private:

View File

@@ -5,8 +5,8 @@ using namespace Poincare;
namespace Shared {
FunctionApp::FunctionApp(Container * container, ViewController * rootViewController, Descriptor * descriptor) :
TextFieldDelegateApp(container, rootViewController, descriptor)
FunctionApp::FunctionApp(Container * container, Snapshot * snapshot, ViewController * rootViewController) :
TextFieldDelegateApp(container, snapshot, rootViewController)
{
}

View File

@@ -10,7 +10,8 @@ namespace Shared {
class FunctionApp : public TextFieldDelegateApp {
public:
FunctionApp(Container * container, ViewController * rootViewController, Descriptor * descriptor);
FunctionApp(Container * container, Snapshot * snapshot, ViewController * rootViewController);
virtual ~FunctionApp() = default;
virtual InputViewController * inputViewController() = 0;
void willBecomeInactive() override;
};

View File

@@ -62,4 +62,10 @@ int FunctionStore::numberOfDefinedFunctions() {
return result;
}
void FunctionStore::tidy() {
for (int i = 0; i < m_numberOfFunctions; i++) {
functionAtIndex(i)->tidy();
}
}
}

View File

@@ -26,6 +26,7 @@ public:
int numberOfActiveFunctions();
virtual int maxNumberOfFunctions() = 0;
virtual char symbol() const = 0;
void tidy();
protected:
int m_numberOfFunctions;
private:

View File

@@ -7,8 +7,8 @@ using namespace Poincare;
namespace Shared {
TextFieldDelegateApp::TextFieldDelegateApp(Container * container, ViewController * rootViewController, Descriptor * descriptor) :
::App(container, rootViewController, descriptor, I18n::Message::Warning),
TextFieldDelegateApp::TextFieldDelegateApp(Container * container, Snapshot * snapshot, ViewController * rootViewController) :
::App(container, snapshot, rootViewController, I18n::Message::Warning),
TextFieldDelegate()
{
}

View File

@@ -11,7 +11,8 @@ namespace Shared {
class TextFieldDelegateApp : public ::App, public TextFieldDelegate {
public:
TextFieldDelegateApp(Container * container, ViewController * rootViewController, Descriptor * descriptor);
TextFieldDelegateApp(Container * container, Snapshot * snapshot, ViewController * rootViewController);
virtual ~TextFieldDelegateApp() = default;
virtual Poincare::Context * localContext();
AppsContainer * container();
virtual const char * XNT();

View File

@@ -1,14 +1,11 @@
#include "app.h"
#include "stat_icon.h"
#include "../i18n.h"
using namespace Shared;
namespace Statistics {
App * App::Descriptor::build(Container * container) {
return new App(container, this);
}
I18n::Message App::Descriptor::name() {
return I18n::Message::StatsApp;
}
@@ -21,28 +18,40 @@ const Image * App::Descriptor::icon() {
return ImageStore::StatIcon;
}
App::App(Container * container, Descriptor * descriptor) :
TextFieldDelegateApp(container, &m_tabViewController, descriptor),
m_store(),
m_calculationController(&m_calculationAlternateEmptyViewController, &m_calculationHeader, &m_store),
App * App::Snapshot::unpack(Container * container) {
return new App(container, this);
}
void App::Snapshot::reset() {
m_store.deleteAllPairs();
}
App::Descriptor * App::Snapshot::descriptor() {
static Descriptor descriptor;
return &descriptor;
}
Store * App::Snapshot::store() {
return &m_store;
}
App::App(Container * container, Snapshot * snapshot) :
TextFieldDelegateApp(container, snapshot, &m_tabViewController),
m_calculationController(&m_calculationAlternateEmptyViewController, &m_calculationHeader, snapshot->store()),
m_calculationAlternateEmptyViewController(&m_calculationHeader, &m_calculationController, &m_calculationController),
m_calculationHeader(&m_tabViewController, &m_calculationAlternateEmptyViewController, &m_calculationController),
m_boxController(&m_boxAlternateEmptyViewController, &m_boxHeader, &m_store),
m_boxController(&m_boxAlternateEmptyViewController, &m_boxHeader, snapshot->store()),
m_boxAlternateEmptyViewController(&m_boxHeader, &m_boxController, &m_boxController),
m_boxHeader(&m_tabViewController, &m_boxAlternateEmptyViewController, &m_boxController),
m_histogramController(&m_histogramAlternateEmptyViewController, &m_histogramHeader, &m_store),
m_histogramController(&m_histogramAlternateEmptyViewController, &m_histogramHeader, snapshot->store()),
m_histogramAlternateEmptyViewController(&m_histogramHeader, &m_histogramController, &m_histogramController),
m_histogramHeader(&m_histogramStackViewController, &m_histogramAlternateEmptyViewController, &m_histogramController),
m_histogramStackViewController(&m_tabViewController, &m_histogramHeader),
m_storeController(&m_storeHeader, &m_store, &m_storeHeader),
m_storeController(&m_storeHeader, snapshot->store(), &m_storeHeader),
m_storeHeader(&m_storeStackViewController, &m_storeController, &m_storeController),
m_storeStackViewController(&m_tabViewController, &m_storeHeader),
m_tabViewController(&m_modalViewController, &m_storeStackViewController, &m_histogramStackViewController, &m_boxHeader, &m_calculationHeader)
m_tabViewController(&m_modalViewController, &m_storeStackViewController, &m_histogramStackViewController, &m_boxHeader, &m_calculationHeader)
{
}
App::Descriptor * App::buildDescriptor() {
return new App::Descriptor();
}
}

View File

@@ -15,15 +15,21 @@ class App : public Shared::TextFieldDelegateApp {
public:
class Descriptor : public ::App::Descriptor {
public:
App * build(Container * container) override;
I18n::Message name() override;
I18n::Message upperName() override;
const Image * icon() override;
};
static Descriptor * buildDescriptor();
class Snapshot : public ::App::Snapshot {
public:
App * unpack(Container * container) override;
void reset() override;
Descriptor * descriptor() override;
Store * store();
private:
Store m_store;
};
private:
App(Container * container, Descriptor * descriptor);
Store m_store;
App(Container * container, Snapshot * snapshot);
CalculationController m_calculationController;
AlternateEmptyViewController m_calculationAlternateEmptyViewController;
ButtonRowController m_calculationHeader;

View File

@@ -23,16 +23,24 @@ class App : public Responder {
public:
class Descriptor {
public:
virtual App * build(Container * container) = 0;
virtual I18n::Message name();
virtual I18n::Message upperName();
virtual const Image * icon();
};
/* Each App subclass must implement
* static Descriptor * builDescriptor(); */
Descriptor * descriptor();
class Snapshot {
public:
virtual App * unpack(Container * container) = 0;
void pack(App * app);
/* reset all instances to their initial values */
virtual void reset();
virtual Descriptor * descriptor() = 0;
private:
/* tidy clean all dynamically-allocated data */
virtual void tidy();
};
virtual ~App() = default;
constexpr static uint8_t Magic = 0xA8;
Snapshot * snapshot();
void setFirstResponder(Responder * responder);
Responder * firstResponder();
bool processEvent(Ion::Events::Event event);
@@ -46,12 +54,12 @@ public:
virtual void didBecomeActive(Window * window);
virtual void willBecomeInactive();
protected:
App(Container * container, ViewController * rootViewController, Descriptor * descriptor, I18n::Message warningMessage = (I18n::Message)0);
App(Container * container, Snapshot * snapshot, ViewController * rootViewController, I18n::Message warningMessage = (I18n::Message)0);
ModalViewController m_modalViewController;
private:
Descriptor * m_descriptor;
Container * m_container;
Responder * m_firstResponder;
Snapshot * m_snapshot;
WarningController m_warningController;
};

View File

@@ -26,7 +26,7 @@ public:
void run();
App * activeApp();
virtual bool dispatchEvent(Ion::Events::Event event) override;
virtual void switchTo(App::Descriptor * descriptor);
virtual void switchTo(App::Snapshot * snapshot);
protected:
virtual Window * window() = 0;
void windowRedraw() override;

View File

@@ -16,19 +16,30 @@ const Image * App::Descriptor::icon() {
return nullptr;
}
App::App(Container * container, ViewController * rootViewController, Descriptor * descriptor, I18n::Message warningMessage) :
void App::Snapshot::pack(App * app) {
tidy();
delete app;
}
void App::Snapshot::reset() {
}
void App::Snapshot::tidy() {
}
App::App(Container * container, Snapshot * snapshot, ViewController * rootViewController, I18n::Message warningMessage) :
Responder(nullptr),
m_magic(Magic),
m_modalViewController(this, rootViewController),
m_descriptor(descriptor),
m_container(container),
m_firstResponder(nullptr),
m_snapshot(snapshot),
m_warningController(this, warningMessage)
{
}
App::Descriptor * App::descriptor() {
return m_descriptor;
App::Snapshot * App::snapshot() {
return m_snapshot;
}
bool App::processEvent(Ion::Events::Event event) {

View File

@@ -13,13 +13,18 @@ Container::~Container() {
}
}
void Container::switchTo(App::Descriptor * descriptor) {
void Container::switchTo(App::Snapshot * snapshot) {
if (m_activeApp && snapshot == m_activeApp->snapshot()) {
return;
}
if (m_activeApp) {
m_activeApp->willBecomeInactive();
delete m_activeApp;
m_activeApp->snapshot()->pack(m_activeApp);
}
if (descriptor) {
m_activeApp = descriptor->build(this);
if (snapshot) {
m_activeApp = snapshot->unpack(this);
} else {
m_activeApp = nullptr;
}
if (m_activeApp) {
m_activeApp->didBecomeActive(window());