mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[shared] Rename classes:
ExpressionModelHandle --> ExpressionModel SingleExpressionModelHandle --> ExpressionModelHandle StorageFunction --> Function StorageCartesianFunction --> CartesianFunction StorageFunctionApp --> FunctionApp
This commit is contained in:
@@ -21,7 +21,7 @@ const Image * App::Descriptor::icon() {
|
||||
}
|
||||
|
||||
App::Snapshot::Snapshot() :
|
||||
Shared::StorageFunctionApp::Snapshot::Snapshot(),
|
||||
Shared::FunctionApp::Snapshot::Snapshot(),
|
||||
m_functionStore(),
|
||||
m_graphRange(&m_cursor)
|
||||
{
|
||||
@@ -50,7 +50,7 @@ void App::Snapshot::tidy() {
|
||||
}
|
||||
|
||||
App::App(Container * container, Snapshot * snapshot) :
|
||||
StorageFunctionApp(container, snapshot, &m_inputViewController),
|
||||
FunctionApp(container, snapshot, &m_inputViewController),
|
||||
m_listController(&m_listFooter, &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),
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
#include "graph/graph_controller.h"
|
||||
#include "list/storage_list_controller.h"
|
||||
#include "values/storage_values_controller.h"
|
||||
#include "../shared/storage_function_app.h"
|
||||
#include "../shared/function_app.h"
|
||||
|
||||
namespace Graph {
|
||||
|
||||
class App : public Shared::StorageFunctionApp {
|
||||
class App : public Shared::FunctionApp {
|
||||
public:
|
||||
class Descriptor : public ::App::Descriptor {
|
||||
public:
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
I18n::Message upperName() override;
|
||||
const Image * icon() override;
|
||||
};
|
||||
class Snapshot : public Shared::StorageFunctionApp::Snapshot {
|
||||
class Snapshot : public Shared::FunctionApp::Snapshot {
|
||||
public:
|
||||
Snapshot();
|
||||
App * unpack(Container * container) override;
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
InputViewController * inputViewController() override;
|
||||
char XNT() override;
|
||||
NestedMenuController * variableBoxForInputEventHandler(InputEventHandler * textInput) override;
|
||||
StorageCartesianFunctionStore * functionStore() override { return static_cast<StorageCartesianFunctionStore *>(Shared::StorageFunctionApp::functionStore()); }
|
||||
StorageCartesianFunctionStore * functionStore() override { return static_cast<StorageCartesianFunctionStore *>(Shared::FunctionApp::functionStore()); }
|
||||
private:
|
||||
App(Container * container, Snapshot * snapshot);
|
||||
StorageListController m_listController;
|
||||
|
||||
@@ -63,7 +63,7 @@ void CalculationGraphController::setRecord(Ion::Storage::Record record) {
|
||||
|
||||
void CalculationGraphController::reloadBannerView() {
|
||||
m_bannerView->setNumberOfSubviews(2);
|
||||
reloadBannerViewForCursorOnFunction(m_cursor, m_record, functionStore(), StorageCartesianFunction::Symbol());
|
||||
reloadBannerViewForCursorOnFunction(m_cursor, m_record, functionStore(), CartesianFunction::Symbol());
|
||||
}
|
||||
|
||||
bool CalculationGraphController::moveCursor(int direction) {
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Graph {
|
||||
|
||||
class App;
|
||||
|
||||
class CalculationGraphController : public ViewController, public Shared::StorageFunctionBannerDelegate {
|
||||
class CalculationGraphController : public ViewController, public Shared::FunctionBannerDelegate {
|
||||
public:
|
||||
CalculationGraphController(Responder * parentResponder, GraphView * graphView, BannerView * bannerView, Shared::InteractiveCurveViewRange * curveViewRange, Shared::CurveViewCursor * cursor, I18n::Message defaultMessage);
|
||||
View * view() override;
|
||||
|
||||
@@ -8,7 +8,7 @@ using namespace Shared;
|
||||
namespace Graph {
|
||||
|
||||
CurveParameterController::CurveParameterController(InputEventHandlerDelegate * inputEventHandlerDelegate, InteractiveCurveViewRange * graphRange, BannerView * bannerView, CurveViewCursor * cursor, GraphView * graphView, GraphController * graphController) :
|
||||
StorageFunctionCurveParameterController(graphRange, cursor),
|
||||
FunctionCurveParameterController(graphRange, cursor),
|
||||
m_goToParameterController(this, inputEventHandlerDelegate, graphRange, cursor, I18n::Message::X),
|
||||
m_graphController(graphController),
|
||||
m_calculationCell(I18n::Message::Compute),
|
||||
@@ -68,7 +68,7 @@ int CurveParameterController::reusableCellCount() {
|
||||
return k_totalNumberOfCells;
|
||||
}
|
||||
|
||||
StorageFunctionGoToParameterController * CurveParameterController::goToParameterController() {
|
||||
FunctionGoToParameterController * CurveParameterController::goToParameterController() {
|
||||
return &m_goToParameterController;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Graph {
|
||||
|
||||
class GraphController;
|
||||
|
||||
class CurveParameterController : public Shared::StorageFunctionCurveParameterController {
|
||||
class CurveParameterController : public Shared::FunctionCurveParameterController {
|
||||
public:
|
||||
CurveParameterController(InputEventHandlerDelegate * inputEventHandlerDelegate, Shared::InteractiveCurveViewRange * graphRange, BannerView * bannerView, Shared::CurveViewCursor * cursor, GraphView * graphView, GraphController * graphController);
|
||||
const char * title() override;
|
||||
@@ -19,8 +19,8 @@ public:
|
||||
int reusableCellCount() override;
|
||||
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
|
||||
private:
|
||||
Shared::StorageFunctionGoToParameterController * goToParameterController() override;
|
||||
Shared::StorageFunctionGoToParameterController m_goToParameterController;
|
||||
Shared::FunctionGoToParameterController * goToParameterController() override;
|
||||
Shared::FunctionGoToParameterController m_goToParameterController;
|
||||
GraphController * m_graphController;
|
||||
constexpr static int k_totalNumberOfCells = 3;
|
||||
MessageTableCellWithChevron m_calculationCell;
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Graph {
|
||||
static inline float maxFloat(float x, float y) { return x > y ? x : y; }
|
||||
|
||||
GraphController::GraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, StorageCartesianFunctionStore * functionStore, Shared::InteractiveCurveViewRange * curveViewRange, CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * rangeVersion, Poincare::Preferences::AngleUnit * angleUnitVersion, ButtonRowController * header) :
|
||||
StorageFunctionGraphController(parentResponder, inputEventHandlerDelegate, header, curveViewRange, &m_view, cursor, indexFunctionSelectedByCursor, modelVersion, rangeVersion, angleUnitVersion),
|
||||
FunctionGraphController(parentResponder, inputEventHandlerDelegate, header, curveViewRange, &m_view, cursor, indexFunctionSelectedByCursor, modelVersion, rangeVersion, angleUnitVersion),
|
||||
m_bannerView(),
|
||||
m_view(functionStore, curveViewRange, m_cursor, &m_bannerView, &m_cursorView),
|
||||
m_graphRange(curveViewRange),
|
||||
@@ -27,7 +27,7 @@ I18n::Message GraphController::emptyMessage() {
|
||||
|
||||
void GraphController::viewWillAppear() {
|
||||
m_view.drawTangent(false);
|
||||
StorageFunctionGraphController::viewWillAppear();
|
||||
FunctionGraphController::viewWillAppear();
|
||||
selectFunctionWithCursor(indexFunctionSelectedByCursor()); // update the color of the cursor
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ float GraphController::interestingXHalfRange() const {
|
||||
float characteristicRange = 0.0f;
|
||||
TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app();
|
||||
for (int i = 0; i < functionStore()->numberOfActiveFunctions(); i++) {
|
||||
ExpiringPointer<StorageCartesianFunction> f = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(i));
|
||||
ExpiringPointer<CartesianFunction> f = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(i));
|
||||
float fRange = f->expressionReduced(myApp->localContext()).characteristicXRange(*(myApp->localContext()), Poincare::Preferences::sharedPreferences()->angleUnit());
|
||||
if (!std::isnan(fRange)) {
|
||||
characteristicRange = maxFloat(fRange, characteristicRange);
|
||||
@@ -57,8 +57,8 @@ int GraphController::estimatedBannerNumberOfLines() const {
|
||||
}
|
||||
|
||||
void GraphController::selectFunctionWithCursor(int functionIndex) {
|
||||
StorageFunctionGraphController::selectFunctionWithCursor(functionIndex);
|
||||
ExpiringPointer<StorageCartesianFunction> f = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(indexFunctionSelectedByCursor()));
|
||||
FunctionGraphController::selectFunctionWithCursor(functionIndex);
|
||||
ExpiringPointer<CartesianFunction> f = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(indexFunctionSelectedByCursor()));
|
||||
m_cursorView.setColor(f->color());
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ BannerView * GraphController::bannerView() {
|
||||
}
|
||||
|
||||
void GraphController::reloadBannerView() {
|
||||
StorageFunctionGraphController::reloadBannerView();
|
||||
FunctionGraphController::reloadBannerView();
|
||||
m_bannerView.setNumberOfSubviews(2+m_displayDerivativeInBanner);
|
||||
if (functionStore()->numberOfActiveFunctions() == 0 || !m_displayDerivativeInBanner) {
|
||||
return;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
namespace Graph {
|
||||
|
||||
class GraphController : public Shared::StorageFunctionGraphController, public GraphControllerHelper {
|
||||
class GraphController : public Shared::FunctionGraphController, public GraphControllerHelper {
|
||||
public:
|
||||
GraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, StorageCartesianFunctionStore * functionStore, Shared::InteractiveCurveViewRange * curveViewRange, Shared::CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * rangeVersion, Poincare::Preferences::AngleUnit * angleUnitVersion, ButtonRowController * header);
|
||||
I18n::Message emptyMessage() override;
|
||||
@@ -33,7 +33,7 @@ private:
|
||||
return &m_cursorView;
|
||||
}
|
||||
CurveParameterController * curveParameterController() override;
|
||||
StorageCartesianFunctionStore * functionStore() const override { return static_cast<StorageCartesianFunctionStore *>(Shared::StorageFunctionGraphController::functionStore()); }
|
||||
StorageCartesianFunctionStore * functionStore() const override { return static_cast<StorageCartesianFunctionStore *>(Shared::FunctionGraphController::functionStore()); }
|
||||
Shared::RoundCursorView m_cursorView;
|
||||
BannerView m_bannerView;
|
||||
GraphView m_view;
|
||||
|
||||
@@ -10,7 +10,7 @@ using namespace Poincare;
|
||||
namespace Graph {
|
||||
|
||||
bool GraphControllerHelper::privateMoveCursorHorizontally(Shared::CurveViewCursor * cursor, int direction, Shared::InteractiveCurveViewRange * range, int numberOfStepsInGradUnit, Ion::Storage::Record record, App * app, float cursorTopMarginRatio, float cursorRightMarginRatio, float cursorBottomMarginRatio, float cursorLeftMarginRatio) {
|
||||
ExpiringPointer<StorageCartesianFunction> function = app->functionStore()->modelForRecord(record);
|
||||
ExpiringPointer<CartesianFunction> function = app->functionStore()->modelForRecord(record);
|
||||
double xCursorPosition = cursor->x();
|
||||
double x = direction > 0 ? xCursorPosition + range->xGridUnit()/numberOfStepsInGradUnit : xCursorPosition - range->xGridUnit()/numberOfStepsInGradUnit;
|
||||
double y = function->evaluateAtAbscissa(x, app->localContext());
|
||||
@@ -20,11 +20,11 @@ bool GraphControllerHelper::privateMoveCursorHorizontally(Shared::CurveViewCurso
|
||||
}
|
||||
|
||||
void GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(Shared::CurveViewCursor * cursor, Ion::Storage::Record record, App * app) {
|
||||
ExpiringPointer<StorageCartesianFunction> function = app->functionStore()->modelForRecord(record);
|
||||
constexpr size_t bufferSize = StorageFunctionBannerDelegate::k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits);
|
||||
ExpiringPointer<CartesianFunction> function = app->functionStore()->modelForRecord(record);
|
||||
constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits);
|
||||
char buffer[bufferSize];
|
||||
const char * space = " ";
|
||||
int numberOfChar = function->derivativeNameWithArgument(buffer, bufferSize, StorageCartesianFunction::Symbol());
|
||||
int numberOfChar = function->derivativeNameWithArgument(buffer, bufferSize, CartesianFunction::Symbol());
|
||||
const char * legend = "=";
|
||||
numberOfChar += strlcpy(buffer+numberOfChar, legend, bufferSize-numberOfChar);
|
||||
double y = function->approximateDerivative(cursor->x(), app->localContext());
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Graph {
|
||||
|
||||
GraphView::GraphView(StorageCartesianFunctionStore * functionStore, InteractiveCurveViewRange * graphRange,
|
||||
CurveViewCursor * cursor, BannerView * bannerView, View * cursorView) :
|
||||
StorageFunctionGraphView(graphRange, cursor, bannerView, cursorView),
|
||||
FunctionGraphView(graphRange, cursor, bannerView, cursorView),
|
||||
m_functionStore(functionStore),
|
||||
m_tangent(false)
|
||||
{
|
||||
@@ -18,25 +18,25 @@ void GraphView::reload() {
|
||||
KDRect dirtyZone(KDRect(0, 0, bounds().width(), bounds().height()-m_bannerView->bounds().height()));
|
||||
markRectAsDirty(dirtyZone);
|
||||
}
|
||||
return StorageFunctionGraphView::reload();
|
||||
return FunctionGraphView::reload();
|
||||
}
|
||||
|
||||
void GraphView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
StorageFunctionGraphView::drawRect(ctx, rect);
|
||||
FunctionGraphView::drawRect(ctx, rect);
|
||||
for (int i = 0; i < m_functionStore->numberOfActiveFunctions(); i++) {
|
||||
Ion::Storage::Record record = m_functionStore->activeRecordAtIndex(i);
|
||||
ExpiringPointer<StorageCartesianFunction> f = m_functionStore->modelForRecord(record);;
|
||||
ExpiringPointer<CartesianFunction> f = m_functionStore->modelForRecord(record);;
|
||||
|
||||
/* Draw function (color the area under curve of the selected function) */
|
||||
if (record == m_selectedRecord) {
|
||||
drawCurve(ctx, rect, [](float t, void * model, void * context) {
|
||||
StorageCartesianFunction * f = (StorageCartesianFunction *)model;
|
||||
CartesianFunction * f = (CartesianFunction *)model;
|
||||
Poincare::Context * c = (Poincare::Context *)context;
|
||||
return f->evaluateAtAbscissa(t, c);
|
||||
}, f.operator->(), context(), f->color(), true, m_highlightedStart, m_highlightedEnd);
|
||||
} else {
|
||||
drawCurve(ctx, rect, [](float t, void * model, void * context) {
|
||||
StorageCartesianFunction * f = (StorageCartesianFunction *)model;
|
||||
CartesianFunction * f = (CartesianFunction *)model;
|
||||
Poincare::Context * c = (Poincare::Context *)context;
|
||||
return f->evaluateAtAbscissa(t, c);
|
||||
}, f.operator->(), context(), f->color());
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace Graph {
|
||||
|
||||
class GraphView : public Shared::StorageFunctionGraphView {
|
||||
class GraphView : public Shared::FunctionGraphView {
|
||||
public:
|
||||
|
||||
GraphView(StorageCartesianFunctionStore * functionStore, Shared::InteractiveCurveViewRange * graphRange,
|
||||
|
||||
@@ -36,11 +36,11 @@ double IntegralGraphController::cursorNextStep(double x, int direction) {
|
||||
return (direction > 0 ? x + m_graphRange->xGridUnit()/k_numberOfCursorStepsInGradUnit : x - m_graphRange->xGridUnit()/k_numberOfCursorStepsInGradUnit);
|
||||
}
|
||||
|
||||
Layout IntegralGraphController::createFunctionLayout(ExpiringPointer<StorageFunction> function) {
|
||||
Layout IntegralGraphController::createFunctionLayout(ExpiringPointer<Shared::Function> function) {
|
||||
constexpr size_t bufferSize = SymbolAbstract::k_maxNameSize+5; // f(x)dx
|
||||
char buffer[bufferSize];
|
||||
const char * dx = "dx";
|
||||
int numberOfChars = function->nameWithArgument(buffer, bufferSize-strlen(dx), StorageCartesianFunction::Symbol());
|
||||
int numberOfChars = function->nameWithArgument(buffer, bufferSize-strlen(dx), CartesianFunction::Symbol());
|
||||
strlcpy(buffer+numberOfChars, dx, bufferSize-numberOfChars);
|
||||
return LayoutHelper::String(buffer, strlen(buffer), KDFont::SmallFont);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ public:
|
||||
private:
|
||||
I18n::Message legendMessageAtStep(Step step) override;
|
||||
double cursorNextStep(double position, int direction) override;
|
||||
Poincare::Layout createFunctionLayout(Shared::ExpiringPointer<Shared::StorageFunction> function) override;
|
||||
Poincare::Layout createFunctionLayout(Shared::ExpiringPointer<Shared::Function> function) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -18,18 +18,18 @@ const char * IntersectionGraphController::title() {
|
||||
|
||||
void IntersectionGraphController::reloadBannerView() {
|
||||
m_bannerView->setNumberOfSubviews(2);
|
||||
reloadBannerViewForCursorOnFunction(m_cursor, m_record, functionStore(), StorageCartesianFunction::Symbol());
|
||||
constexpr size_t bufferSize = StorageFunctionBannerDelegate::k_maxNumberOfCharacters+Poincare::PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits);
|
||||
reloadBannerViewForCursorOnFunction(m_cursor, m_record, functionStore(), CartesianFunction::Symbol());
|
||||
constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters+Poincare::PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits);
|
||||
char buffer[bufferSize];
|
||||
const char * space = " ";
|
||||
const char * legend = "=";
|
||||
// 'f(x)=g(x)=', keep 2 chars for '='
|
||||
ExpiringPointer<StorageCartesianFunction> f = functionStore()->modelForRecord(m_record);
|
||||
int numberOfChar = f->nameWithArgument(buffer, bufferSize-2, StorageCartesianFunction::Symbol());
|
||||
ExpiringPointer<CartesianFunction> f = functionStore()->modelForRecord(m_record);
|
||||
int numberOfChar = f->nameWithArgument(buffer, bufferSize-2, CartesianFunction::Symbol());
|
||||
numberOfChar += strlcpy(buffer+numberOfChar, legend, bufferSize-numberOfChar);
|
||||
// keep 1 char for '=';
|
||||
ExpiringPointer<StorageCartesianFunction> g = functionStore()->modelForRecord(m_intersectedRecord);
|
||||
numberOfChar += g->nameWithArgument(buffer+numberOfChar, bufferSize-numberOfChar-1, StorageCartesianFunction::Symbol());
|
||||
ExpiringPointer<CartesianFunction> g = functionStore()->modelForRecord(m_intersectedRecord);
|
||||
numberOfChar += g->nameWithArgument(buffer+numberOfChar, bufferSize-numberOfChar-1, CartesianFunction::Symbol());
|
||||
numberOfChar += strlcpy(buffer+numberOfChar, legend, bufferSize-numberOfChar);
|
||||
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(m_cursor->y(), buffer+numberOfChar, bufferSize-numberOfChar, Constant::MediumNumberOfSignificantDigits);
|
||||
strlcpy(buffer+numberOfChar, space, bufferSize-numberOfChar);
|
||||
|
||||
@@ -40,13 +40,13 @@ void TangentGraphController::reloadBannerView() {
|
||||
return;
|
||||
}
|
||||
App * myApp = static_cast<App *>(app());
|
||||
StorageFunctionBannerDelegate::reloadBannerViewForCursorOnFunction(m_cursor, m_record, myApp->functionStore(), StorageCartesianFunction::Symbol());
|
||||
FunctionBannerDelegate::reloadBannerViewForCursorOnFunction(m_cursor, m_record, myApp->functionStore(), CartesianFunction::Symbol());
|
||||
GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(m_cursor, m_record, myApp);
|
||||
constexpr size_t bufferSize = StorageFunctionBannerDelegate::k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits);
|
||||
constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits);
|
||||
char buffer[bufferSize];
|
||||
const char * legend = "a=";
|
||||
int legendLength = strlcpy(buffer, legend, bufferSize);
|
||||
ExpiringPointer<StorageCartesianFunction> function = myApp->functionStore()->modelForRecord(m_record);
|
||||
ExpiringPointer<CartesianFunction> function = myApp->functionStore()->modelForRecord(m_record);
|
||||
double y = function->approximateDerivative(m_cursor->x(), myApp->localContext());
|
||||
PoincareHelpers::ConvertFloatToText<double>(y, buffer + legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits);
|
||||
m_bannerView->setLegendAtIndex(buffer, 4);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
namespace Graph {
|
||||
|
||||
class TangentGraphController : public Shared::SimpleInteractiveCurveViewController, public Shared::StorageFunctionBannerDelegate, public GraphControllerHelper {
|
||||
class TangentGraphController : public Shared::SimpleInteractiveCurveViewController, public Shared::FunctionBannerDelegate, public GraphControllerHelper {
|
||||
public:
|
||||
TangentGraphController(Responder * parentResponder, GraphView * graphView, BannerView * bannerView, Shared::InteractiveCurveViewRange * curveViewRange, Shared::CurveViewCursor * cursor);
|
||||
const char * title() override;
|
||||
|
||||
@@ -10,7 +10,7 @@ using namespace Shared;
|
||||
namespace Graph {
|
||||
|
||||
StorageListController::StorageListController(Responder * parentResponder, ButtonRowController * header, ButtonRowController * footer) :
|
||||
Shared::StorageFunctionListController(parentResponder, header, footer, I18n::Message::AddFunction),
|
||||
Shared::FunctionListController(parentResponder, header, footer, I18n::Message::AddFunction),
|
||||
m_functionTitleCells{ //TODO find better initialization
|
||||
TextFieldFunctionTitleCell(this),
|
||||
TextFieldFunctionTitleCell(this),
|
||||
@@ -49,14 +49,14 @@ bool StorageListController::textFieldDidFinishEditing(TextField * textField, con
|
||||
assert(textField != nullptr);
|
||||
// Compute the new name
|
||||
size_t textLength = strlen(text);
|
||||
size_t argumentLength = StorageFunction::k_parenthesedArgumentLength;
|
||||
constexpr int maxBaseNameSize = StorageFunction::k_maxNameWithArgumentSize;
|
||||
size_t argumentLength = Function::k_parenthesedArgumentLength;
|
||||
constexpr int maxBaseNameSize = Function::k_maxNameWithArgumentSize;
|
||||
char baseName[maxBaseNameSize];
|
||||
if (textLength <= argumentLength) {
|
||||
// The user entered an empty name. Use a default function name.
|
||||
StorageCartesianFunction::DefaultName(baseName, maxBaseNameSize);
|
||||
CartesianFunction::DefaultName(baseName, maxBaseNameSize);
|
||||
size_t defaultNameLength = strlen(baseName);
|
||||
strlcpy(baseName + defaultNameLength, StorageFunction::k_parenthesedArgument, maxBaseNameSize - defaultNameLength);
|
||||
strlcpy(baseName + defaultNameLength, Function::k_parenthesedArgument, maxBaseNameSize - defaultNameLength);
|
||||
textField->setText(baseName);
|
||||
baseName[defaultNameLength] = 0;
|
||||
} else {
|
||||
@@ -67,8 +67,8 @@ bool StorageListController::textFieldDidFinishEditing(TextField * textField, con
|
||||
GlobalContext::DestroyRecordsBaseNamedWithoutExtension(baseName, Ion::Storage::funcExtension);
|
||||
|
||||
// Set the name
|
||||
StorageFunction::NameNotCompliantError nameError = StorageFunction::NameNotCompliantError::None;
|
||||
Ion::Storage::Record::ErrorStatus error = StorageFunction::BaseNameCompliant(baseName, &nameError) ? modelStore()->recordAtIndex(m_selectableTableView.selectedRow()).setBaseNameWithExtension(baseName, Ion::Storage::funcExtension) : Ion::Storage::Record::ErrorStatus::NonCompliantName;
|
||||
Function::NameNotCompliantError nameError = Function::NameNotCompliantError::None;
|
||||
Ion::Storage::Record::ErrorStatus error = Function::BaseNameCompliant(baseName, &nameError) ? modelStore()->recordAtIndex(m_selectableTableView.selectedRow()).setBaseNameWithExtension(baseName, Ion::Storage::funcExtension) : Ion::Storage::Record::ErrorStatus::NonCompliantName;
|
||||
|
||||
// Handle any error
|
||||
if (error == Ion::Storage::Record::ErrorStatus::None) {
|
||||
@@ -96,13 +96,13 @@ bool StorageListController::textFieldDidFinishEditing(TextField * textField, con
|
||||
} else if (error == Ion::Storage::Record::ErrorStatus::NameTaken) {
|
||||
app()->displayWarning(I18n::Message::NameTaken);
|
||||
} else if (error == Ion::Storage::Record::ErrorStatus::NonCompliantName) {
|
||||
assert(nameError != StorageFunction::NameNotCompliantError::None);
|
||||
if (nameError == StorageFunction::NameNotCompliantError::CharacterNotAllowed) {
|
||||
assert(nameError != Function::NameNotCompliantError::None);
|
||||
if (nameError == Function::NameNotCompliantError::CharacterNotAllowed) {
|
||||
app()->displayWarning(I18n::Message::AllowedCharactersAZaz09);
|
||||
} else if (nameError == StorageFunction::NameNotCompliantError::NameCannotStartWithNumber) {
|
||||
} else if (nameError == Function::NameNotCompliantError::NameCannotStartWithNumber) {
|
||||
app()->displayWarning(I18n::Message::NameCannotStartWithNumber);
|
||||
} else {
|
||||
assert(nameError == StorageFunction::NameNotCompliantError::ReservedName);
|
||||
assert(nameError == Function::NameNotCompliantError::ReservedName);
|
||||
app()->displayWarning(I18n::Message::ReservedName);
|
||||
}
|
||||
} else {
|
||||
@@ -118,7 +118,7 @@ bool StorageListController::textFieldDidAbortEditing(TextField * textField) {
|
||||
// Put the name column back to normal size
|
||||
computeTitlesColumnWidth();
|
||||
selectableTableView()->reloadData();
|
||||
ExpiringPointer<StorageFunction> function = modelStore()->modelForRecord(modelStore()->recordAtIndex(selectedRow()));
|
||||
ExpiringPointer<Function> function = modelStore()->modelForRecord(modelStore()->recordAtIndex(selectedRow()));
|
||||
setFunctionNameInTextField(function, textField);
|
||||
m_selectableTableView.selectedCell()->setHighlighted(true);
|
||||
app()->setFirstResponder(&m_selectableTableView);
|
||||
@@ -165,7 +165,7 @@ void StorageListController::willDisplayTitleCellAtIndex(HighlightCell * cell, in
|
||||
titleCell->setBaseline(baseline(j));
|
||||
if (!titleCell->isEditing()) {
|
||||
// Set name and color if the name is not being edited
|
||||
ExpiringPointer<StorageFunction> function = modelStore()->modelForRecord(modelStore()->recordAtIndex(j));
|
||||
ExpiringPointer<Function> function = modelStore()->modelForRecord(modelStore()->recordAtIndex(j));
|
||||
setFunctionNameInTextField(function, titleCell->textField());
|
||||
KDColor functionNameColor = function->isActive() ? function->color() : Palette::GreyDark;
|
||||
titleCell->setColor(functionNameColor);
|
||||
@@ -175,14 +175,14 @@ void StorageListController::willDisplayTitleCellAtIndex(HighlightCell * cell, in
|
||||
void StorageListController::willDisplayExpressionCellAtIndex(HighlightCell * cell, int j) {
|
||||
assert(cell != nullptr);
|
||||
assert(j >= 0 && j < modelStore()->numberOfModels());
|
||||
Shared::StorageFunctionListController::willDisplayExpressionCellAtIndex(cell, j);
|
||||
Shared::FunctionListController::willDisplayExpressionCellAtIndex(cell, j);
|
||||
FunctionExpressionCell * myCell = (FunctionExpressionCell *)cell;
|
||||
ExpiringPointer<StorageFunction> f = modelStore()->modelForRecord(modelStore()->recordAtIndex(j));
|
||||
ExpiringPointer<Function> f = modelStore()->modelForRecord(modelStore()->recordAtIndex(j));
|
||||
KDColor textColor = f->isActive() ? KDColorBlack : Palette::GreyDark;
|
||||
myCell->setTextColor(textColor);
|
||||
}
|
||||
|
||||
void StorageListController::setFunctionNameInTextField(ExpiringPointer<StorageFunction> function, TextField * textField) {
|
||||
void StorageListController::setFunctionNameInTextField(ExpiringPointer<Function> function, TextField * textField) {
|
||||
assert(textField != nullptr);
|
||||
char bufferName[BufferTextView::k_maxNumberOfChar];
|
||||
function->nameWithArgument(bufferName, BufferTextView::k_maxNumberOfChar, modelStore()->symbol());
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace Graph {
|
||||
|
||||
class StorageListController : public Shared::StorageFunctionListController, public Shared::TextFieldDelegate {
|
||||
class StorageListController : public Shared::FunctionListController, public Shared::TextFieldDelegate {
|
||||
public:
|
||||
StorageListController(Responder * parentResponder, ButtonRowController * header, ButtonRowController * footer);
|
||||
const char * title() override;
|
||||
@@ -32,7 +32,7 @@ private:
|
||||
Shared::TextFieldDelegateApp * textFieldDelegateApp() override {
|
||||
return static_cast<Shared::TextFieldDelegateApp *>(app());
|
||||
}
|
||||
void setFunctionNameInTextField(Shared::ExpiringPointer<Shared::StorageFunction> function, TextField * textField);
|
||||
void setFunctionNameInTextField(Shared::ExpiringPointer<Shared::Function> function, TextField * textField);
|
||||
TextFieldFunctionTitleCell m_functionTitleCells[k_maxNumberOfDisplayableRows];
|
||||
Shared::FunctionExpressionCell m_expressionCells[k_maxNumberOfDisplayableRows];
|
||||
ListParameterController m_parameterController;
|
||||
|
||||
@@ -10,7 +10,7 @@ static inline float maxFloat(float x, float y) { return x > y ? x : y; }
|
||||
TextFieldFunctionTitleCell::TextFieldFunctionTitleCell(StorageListController * listController, Orientation orientation, const KDFont * font) :
|
||||
Shared::FunctionTitleCell(orientation),
|
||||
Responder(listController),
|
||||
m_textField(Shared::StorageFunction::k_parenthesedArgumentLength, this, m_textFieldBuffer, m_textFieldBuffer, k_textFieldBufferSize, nullptr, listController, false, font, 1.0f, 0.5f)
|
||||
m_textField(Shared::Function::k_parenthesedArgumentLength, this, m_textFieldBuffer, m_textFieldBuffer, k_textFieldBufferSize, nullptr, listController, false, font, 1.0f, 0.5f)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define GRAPH_LIST_TEXT_FIELD_FUNCTION_TITLE_CELL_H
|
||||
|
||||
#include <apps/shared/function_title_cell.h>
|
||||
#include <apps/shared/storage_function.h>
|
||||
#include <apps/shared/function.h>
|
||||
#include <apps/shared/text_field_with_extension.h>
|
||||
|
||||
namespace Graph {
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
void didBecomeFirstResponder() override;
|
||||
private:
|
||||
constexpr static KDCoordinate k_textFieldRightMargin = 4;
|
||||
constexpr static int k_textFieldBufferSize = Shared::StorageFunction::k_maxNameWithArgumentSize;
|
||||
constexpr static int k_textFieldBufferSize = Shared::Function::k_maxNameWithArgumentSize;
|
||||
float verticalAlignmentGivenExpressionBaselineAndRowHeight(KDCoordinate expressionBaseline, KDCoordinate rowHeight) const override;
|
||||
Shared::TextFieldWithExtension m_textField;
|
||||
char m_textFieldBuffer[k_textFieldBufferSize];
|
||||
|
||||
@@ -11,16 +11,16 @@ namespace Graph {
|
||||
|
||||
Ion::Storage::Record::ErrorStatus StorageCartesianFunctionStore::addEmptyModel() {
|
||||
Ion::Storage::Record::ErrorStatus error;
|
||||
StorageCartesianFunction newModel = StorageCartesianFunction::NewModel(&error);
|
||||
CartesianFunction newModel = CartesianFunction::NewModel(&error);
|
||||
return error;
|
||||
}
|
||||
|
||||
void StorageCartesianFunctionStore::setMemoizedModelAtIndex(int cacheIndex, Ion::Storage::Record record) const {
|
||||
assert(cacheIndex >= 0 && cacheIndex < maxNumberOfMemoizedModels());
|
||||
m_functions[cacheIndex] = StorageCartesianFunction(record);
|
||||
m_functions[cacheIndex] = CartesianFunction(record);
|
||||
}
|
||||
|
||||
SingleExpressionModelHandle * StorageCartesianFunctionStore::memoizedModelAtIndex(int cacheIndex) const {
|
||||
ExpressionModelHandle * StorageCartesianFunctionStore::memoizedModelAtIndex(int cacheIndex) const {
|
||||
assert(cacheIndex >= 0 && cacheIndex < maxNumberOfMemoizedModels());
|
||||
return &m_functions[cacheIndex];
|
||||
}
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
#ifndef GRAPH_STORAGE_CARTESIAN_FUNCTION_STORE_H
|
||||
#define GRAPH_STORAGE_CARTESIAN_FUNCTION_STORE_H
|
||||
|
||||
#include "../shared/storage_cartesian_function.h"
|
||||
#include "../shared/cartesian_function.h"
|
||||
#include "../shared/storage_function_store.h"
|
||||
#include <stdint.h>
|
||||
#include <escher.h>
|
||||
|
||||
namespace Graph {
|
||||
|
||||
class StorageCartesianFunctionStore : public Shared::StorageFunctionStore {
|
||||
class StorageCartesianFunctionStore : public Shared::FunctionStore {
|
||||
public:
|
||||
Shared::ExpiringPointer<Shared::StorageCartesianFunction> modelForRecord(Ion::Storage::Record record) const { return Shared::ExpiringPointer<Shared::StorageCartesianFunction>(static_cast<Shared::StorageCartesianFunction *>(privateModelForRecord(record))); }
|
||||
char symbol() const override { return Shared::StorageCartesianFunction::Symbol(); }
|
||||
Shared::ExpiringPointer<Shared::CartesianFunction> modelForRecord(Ion::Storage::Record record) const { return Shared::ExpiringPointer<Shared::CartesianFunction>(static_cast<Shared::CartesianFunction *>(privateModelForRecord(record))); }
|
||||
char symbol() const override { return Shared::CartesianFunction::Symbol(); }
|
||||
char unknownSymbol() const override { return Poincare::Symbol::SpecialSymbols::UnknownX; }
|
||||
private:
|
||||
Ion::Storage::Record::ErrorStatus addEmptyModel() override;
|
||||
const char * modelExtension() const override { return Ion::Storage::funcExtension; }
|
||||
void setMemoizedModelAtIndex(int cacheIndex, Ion::Storage::Record record) const override;
|
||||
Shared::SingleExpressionModelHandle * memoizedModelAtIndex(int cacheIndex) const override;
|
||||
mutable Shared::StorageCartesianFunction m_functions[k_maxNumberOfMemoizedModels];
|
||||
Shared::ExpressionModelHandle * memoizedModelAtIndex(int cacheIndex) const override;
|
||||
mutable Shared::CartesianFunction m_functions[k_maxNumberOfMemoizedModels];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ StorageDerivativeParameterController::StorageDerivativeParameterController(Stora
|
||||
}
|
||||
|
||||
void StorageDerivativeParameterController::viewWillAppear() {
|
||||
functionStore()->modelForRecord(m_record)->derivativeNameWithArgument(m_pageTitle, k_maxNumberOfCharsInTitle, Shared::StorageCartesianFunction::Symbol());
|
||||
functionStore()->modelForRecord(m_record)->derivativeNameWithArgument(m_pageTitle, k_maxNumberOfCharsInTitle, Shared::CartesianFunction::Symbol());
|
||||
}
|
||||
|
||||
const char * StorageDerivativeParameterController::title() {
|
||||
|
||||
@@ -31,7 +31,7 @@ private:
|
||||
#else
|
||||
constexpr static int k_totalNumberOfCell = 1;
|
||||
#endif
|
||||
constexpr static int k_maxNumberOfCharsInTitle = Shared::StorageFunction::k_maxNameWithArgumentSize + 1; // +1 for the ' of the derivative
|
||||
constexpr static int k_maxNumberOfCharsInTitle = Shared::Function::k_maxNameWithArgumentSize + 1; // +1 for the ' of the derivative
|
||||
char m_pageTitle[k_maxNumberOfCharsInTitle];
|
||||
MessageTableCell m_hideColumn;
|
||||
#if COPY_COLUMN
|
||||
|
||||
@@ -7,14 +7,14 @@ using namespace Shared;
|
||||
|
||||
namespace Graph {
|
||||
|
||||
StorageFunctionParameterController::StorageFunctionParameterController(StorageValuesController * valuesController) :
|
||||
StorageValuesFunctionParameterController(StorageCartesianFunction::Symbol()),
|
||||
FunctionParameterController::FunctionParameterController(StorageValuesController * valuesController) :
|
||||
StorageValuesFunctionParameterController(CartesianFunction::Symbol()),
|
||||
m_displayDerivativeColumn(I18n::Message::DerivativeFunctionColumn),
|
||||
m_valuesController(valuesController)
|
||||
{
|
||||
}
|
||||
|
||||
bool StorageFunctionParameterController::handleEvent(Ion::Events::Event event) {
|
||||
bool FunctionParameterController::handleEvent(Ion::Events::Event event) {
|
||||
if (event == Ion::Events::OK || event == Ion::Events::EXE) {
|
||||
switch (selectedRow()) {
|
||||
case 0:
|
||||
@@ -38,11 +38,11 @@ bool StorageFunctionParameterController::handleEvent(Ion::Events::Event event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int StorageFunctionParameterController::numberOfRows() {
|
||||
int FunctionParameterController::numberOfRows() {
|
||||
return k_totalNumberOfCell;
|
||||
};
|
||||
|
||||
HighlightCell * StorageFunctionParameterController::reusableCell(int index) {
|
||||
HighlightCell * FunctionParameterController::reusableCell(int index) {
|
||||
assert(index >= 0);
|
||||
assert(index < k_totalNumberOfCell);
|
||||
#if COPY_COLUMN
|
||||
@@ -53,23 +53,23 @@ HighlightCell * StorageFunctionParameterController::reusableCell(int index) {
|
||||
return cells[index];
|
||||
}
|
||||
|
||||
int StorageFunctionParameterController::reusableCellCount() {
|
||||
int FunctionParameterController::reusableCellCount() {
|
||||
return k_totalNumberOfCell;
|
||||
}
|
||||
|
||||
void StorageFunctionParameterController::viewWillAppear() {
|
||||
void FunctionParameterController::viewWillAppear() {
|
||||
StorageValuesFunctionParameterController::viewWillAppear();
|
||||
m_selectedFunctionColumn = m_valuesController->selectedColumn();
|
||||
}
|
||||
|
||||
void StorageFunctionParameterController::willDisplayCellForIndex(HighlightCell * cell, int index) {
|
||||
void FunctionParameterController::willDisplayCellForIndex(HighlightCell * cell, int index) {
|
||||
if (cell == &m_displayDerivativeColumn) {
|
||||
SwitchView * switchView = (SwitchView *)m_displayDerivativeColumn.accessoryView();
|
||||
switchView->setState(function()->displayDerivative());
|
||||
}
|
||||
}
|
||||
|
||||
ExpiringPointer<StorageCartesianFunction> StorageFunctionParameterController::function() {
|
||||
ExpiringPointer<CartesianFunction> FunctionParameterController::function() {
|
||||
App * a = static_cast<App *>(app());
|
||||
return a->functionStore()->modelForRecord(m_record);
|
||||
}
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
#define GRAPH_STORAGE_FUNCTION_PARAM_CONTROLLER_H
|
||||
|
||||
#include "../../shared/expiring_pointer.h"
|
||||
#include "../../shared/storage_cartesian_function.h"
|
||||
#include "../../shared/cartesian_function.h"
|
||||
#include "../../shared/storage_values_function_parameter_controller.h"
|
||||
|
||||
namespace Graph {
|
||||
|
||||
class StorageValuesController;
|
||||
|
||||
class StorageFunctionParameterController : public Shared::StorageValuesFunctionParameterController {
|
||||
class FunctionParameterController : public Shared::StorageValuesFunctionParameterController {
|
||||
public:
|
||||
StorageFunctionParameterController(StorageValuesController * valuesController);
|
||||
FunctionParameterController(StorageValuesController * valuesController);
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
int numberOfRows() override;
|
||||
HighlightCell * reusableCell(int index) override;
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
|
||||
void viewWillAppear() override;
|
||||
private:
|
||||
Shared::ExpiringPointer<Shared::StorageCartesianFunction> function();
|
||||
Shared::ExpiringPointer<Shared::CartesianFunction> function();
|
||||
#if COPY_COLUMN
|
||||
constexpr static int k_totalNumberOfCell = 2;
|
||||
#else
|
||||
|
||||
@@ -41,16 +41,16 @@ void StorageValuesController::willDisplayCellAtLocation(HighlightCell * cell, in
|
||||
// The cell is a function title cell:
|
||||
if (j == 0 && i > 0) {
|
||||
Shared::BufferFunctionTitleCell * myFunctionCell = (Shared::BufferFunctionTitleCell *)cell;
|
||||
const size_t bufferNameSize = Shared::StorageFunction::k_maxNameWithArgumentSize + 1;
|
||||
const size_t bufferNameSize = Shared::Function::k_maxNameWithArgumentSize + 1;
|
||||
char bufferName[bufferNameSize];
|
||||
bool isDerivative = isDerivativeColumn(i);
|
||||
/* isDerivativeColumn uses expiring pointers, so "function" must be created
|
||||
* after the isDerivativeColumn call, else it will expire. */
|
||||
Shared::ExpiringPointer<StorageCartesianFunction> function = functionStore()->modelForRecord(recordAtColumn(i));
|
||||
Shared::ExpiringPointer<CartesianFunction> function = functionStore()->modelForRecord(recordAtColumn(i));
|
||||
if (isDerivative) {
|
||||
function->derivativeNameWithArgument(bufferName, bufferNameSize, StorageCartesianFunction::Symbol());
|
||||
function->derivativeNameWithArgument(bufferName, bufferNameSize, CartesianFunction::Symbol());
|
||||
} else {
|
||||
function->nameWithArgument(bufferName, bufferNameSize, StorageCartesianFunction::Symbol());
|
||||
function->nameWithArgument(bufferName, bufferNameSize, CartesianFunction::Symbol());
|
||||
}
|
||||
myFunctionCell->setText(bufferName);
|
||||
myFunctionCell->setColor(function->color());
|
||||
@@ -73,7 +73,7 @@ Ion::Storage::Record StorageValuesController::recordAtColumn(int i) {
|
||||
int index = 1;
|
||||
for (int k = 0; k < functionStore()->numberOfDefinedModels(); k++) {
|
||||
Ion::Storage::Record record = functionStore()->definedRecordAtIndex(k);
|
||||
ExpiringPointer<StorageCartesianFunction> f = functionStore()->modelForRecord(record);
|
||||
ExpiringPointer<CartesianFunction> f = functionStore()->modelForRecord(record);
|
||||
if (f->isActive()) {
|
||||
if (i == index) {
|
||||
return record;
|
||||
@@ -95,7 +95,7 @@ bool StorageValuesController::isDerivativeColumn(int i) {
|
||||
assert(i >= 1);
|
||||
int index = 1;
|
||||
for (int k = 0; k < functionStore()->numberOfDefinedModels(); k++) {
|
||||
ExpiringPointer<StorageCartesianFunction> f = functionStore()->modelForRecord(functionStore()->definedRecordAtIndex(k));
|
||||
ExpiringPointer<CartesianFunction> f = functionStore()->modelForRecord(functionStore()->definedRecordAtIndex(k));
|
||||
if (f->isActive()) {
|
||||
if (i == index) {
|
||||
return false;
|
||||
@@ -137,7 +137,7 @@ EvenOddBufferTextCell * StorageValuesController::floatCells(int j) {
|
||||
return &m_floatCells[j];
|
||||
}
|
||||
|
||||
StorageFunctionParameterController * StorageValuesController::functionParameterController() {
|
||||
FunctionParameterController * StorageValuesController::functionParameterController() {
|
||||
return &m_functionParameterController;
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ double StorageValuesController::evaluationOfAbscissaAtColumn(double abscissa, in
|
||||
bool isDerivative = isDerivativeColumn(columnIndex);
|
||||
/* isDerivativeColumn uses expiring pointers, so "function" must be created
|
||||
* after the isDerivativeColumn call, else it will expire. */
|
||||
Shared::ExpiringPointer<StorageCartesianFunction> function = functionStore()->modelForRecord(recordAtColumn(columnIndex));
|
||||
Shared::ExpiringPointer<CartesianFunction> function = functionStore()->modelForRecord(recordAtColumn(columnIndex));
|
||||
if (isDerivative) {
|
||||
return function->approximateDerivative(abscissa, myApp->localContext());
|
||||
}
|
||||
@@ -156,7 +156,7 @@ double StorageValuesController::evaluationOfAbscissaAtColumn(double abscissa, in
|
||||
void StorageValuesController::updateNumberOfColumns() {
|
||||
int result = 1;
|
||||
for (int i = 0; i < functionStore()->numberOfActiveFunctions(); i++) {
|
||||
ExpiringPointer<StorageCartesianFunction> f = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(i));
|
||||
ExpiringPointer<CartesianFunction> f = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(i));
|
||||
if (f->isActive()) {
|
||||
result += 1 + f->displayDerivative();
|
||||
}
|
||||
|
||||
@@ -30,11 +30,11 @@ private:
|
||||
StorageCartesianFunctionStore * functionStore() const override { return static_cast<StorageCartesianFunctionStore *>(Shared::StorageValuesController::functionStore()); }
|
||||
Shared::BufferFunctionTitleCell * functionTitleCells(int j) override;
|
||||
EvenOddBufferTextCell * floatCells(int j) override;
|
||||
StorageFunctionParameterController * functionParameterController() override;
|
||||
FunctionParameterController * functionParameterController() override;
|
||||
|
||||
Shared::BufferFunctionTitleCell m_functionTitleCells[k_maxNumberOfFunctions];
|
||||
EvenOddBufferTextCell m_floatCells[k_maxNumberOfCells];
|
||||
StorageFunctionParameterController m_functionParameterController;
|
||||
FunctionParameterController m_functionParameterController;
|
||||
Shared::IntervalParameterController m_intervalParameterController;
|
||||
StorageDerivativeParameterController m_derivativeParameterController;
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ const Image * App::Descriptor::icon() {
|
||||
}
|
||||
|
||||
App::Snapshot::Snapshot() :
|
||||
Shared::StorageFunctionApp::Snapshot::Snapshot(),
|
||||
Shared::FunctionApp::Snapshot::Snapshot(),
|
||||
m_sequenceStore(),
|
||||
m_graphRange(&m_cursor)
|
||||
{
|
||||
@@ -30,7 +30,7 @@ App * App::Snapshot::unpack(Container * container) {
|
||||
}
|
||||
|
||||
void App::Snapshot::reset() {
|
||||
StorageFunctionApp::Snapshot::reset();
|
||||
FunctionApp::Snapshot::reset();
|
||||
/* reset might be called when activating the exam mode from the settings or
|
||||
* when a memory exception occurs. In both cases, we do not want to
|
||||
* computeYAuto in GraphRange::setDefault, so we need to set its delegate to
|
||||
@@ -54,7 +54,7 @@ void App::Snapshot::tidy() {
|
||||
}
|
||||
|
||||
App::App(Container * container, Snapshot * snapshot) :
|
||||
StorageFunctionApp(container, snapshot, &m_inputViewController),
|
||||
FunctionApp(container, snapshot, &m_inputViewController),
|
||||
m_sequenceContext(((AppsContainer *)container)->globalContext(), snapshot->functionStore()),
|
||||
m_listController(&m_listFooter, this, &m_listHeader, &m_listFooter),
|
||||
m_listFooter(&m_listHeader, &m_listController, &m_listController, ButtonRowController::Position::Bottom, ButtonRowController::Style::EmbossedGrey),
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
#include "graph/curve_view_range.h"
|
||||
#include "list/list_controller.h"
|
||||
#include "values/values_controller.h"
|
||||
#include "../shared/storage_function_app.h"
|
||||
#include "../shared/function_app.h"
|
||||
|
||||
namespace Sequence {
|
||||
|
||||
class App : public Shared::StorageFunctionApp {
|
||||
class App : public Shared::FunctionApp {
|
||||
public:
|
||||
class Descriptor : public ::App::Descriptor {
|
||||
public:
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
I18n::Message upperName() override;
|
||||
const Image * icon() override;
|
||||
};
|
||||
class Snapshot : public Shared::StorageFunctionApp::Snapshot {
|
||||
class Snapshot : public Shared::FunctionApp::Snapshot {
|
||||
public:
|
||||
Snapshot();
|
||||
App * unpack(Container * container) override;
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
// NestedMenuController * variableBoxForInputEventHandler(InputEventHandler * textInput) override;
|
||||
char XNT() override;
|
||||
SequenceContext * localContext() override;
|
||||
SequenceStore * functionStore() override { return static_cast<SequenceStore *>(Shared::StorageFunctionApp::functionStore()); }
|
||||
SequenceStore * functionStore() override { return static_cast<SequenceStore *>(Shared::FunctionApp::functionStore()); }
|
||||
private:
|
||||
App(Container * container, Snapshot * snapshot);
|
||||
SequenceContext m_sequenceContext;
|
||||
|
||||
@@ -7,7 +7,7 @@ using namespace Shared;
|
||||
namespace Sequence {
|
||||
|
||||
CurveParameterController::CurveParameterController(InputEventHandlerDelegate * inputEventHandlerDelegate, GraphController * graphController, InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor) :
|
||||
StorageFunctionCurveParameterController(graphRange, cursor),
|
||||
FunctionCurveParameterController(graphRange, cursor),
|
||||
m_goToParameterController(this, inputEventHandlerDelegate, graphRange, cursor, I18n::Message::N),
|
||||
m_sumCell(I18n::Message::TermSum),
|
||||
m_graphController(graphController)
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Sequence {
|
||||
|
||||
class GraphController;
|
||||
|
||||
class CurveParameterController : public Shared::StorageFunctionCurveParameterController {
|
||||
class CurveParameterController : public Shared::FunctionCurveParameterController {
|
||||
public:
|
||||
CurveParameterController(InputEventHandlerDelegate * inputEventHandlerDelegate, GraphController * graphController, Shared::InteractiveCurveViewRange * graphRange, Shared::CurveViewCursor * cursor);
|
||||
const char * title() override;
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Sequence {
|
||||
|
||||
bool GoToParameterController::setParameterAtIndex(int parameterIndex, double f) {
|
||||
assert(parameterIndex == 0);
|
||||
return Shared::StorageFunctionGoToParameterController::setParameterAtIndex(parameterIndex, std::round(f));
|
||||
return Shared::FunctionGoToParameterController::setParameterAtIndex(parameterIndex, std::round(f));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
|
||||
namespace Sequence {
|
||||
|
||||
class GoToParameterController : public Shared::StorageFunctionGoToParameterController {
|
||||
class GoToParameterController : public Shared::FunctionGoToParameterController {
|
||||
public:
|
||||
using Shared::StorageFunctionGoToParameterController::StorageFunctionGoToParameterController;
|
||||
using Shared::FunctionGoToParameterController::FunctionGoToParameterController;
|
||||
private:
|
||||
bool setParameterAtIndex(int parameterIndex, double f) override;
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@ static inline int minInt(int x, int y) { return (x < y ? x : y); }
|
||||
static inline int maxInt(int x, int y) { return (x > y ? x : y); }
|
||||
|
||||
GraphController::GraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, SequenceStore * sequenceStore, CurveViewRange * graphRange, CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * rangeVersion, Preferences::AngleUnit * angleUnitVersion, ButtonRowController * header) :
|
||||
StorageFunctionGraphController(parentResponder, inputEventHandlerDelegate, header, graphRange, &m_view, cursor, indexFunctionSelectedByCursor, modelVersion, rangeVersion, angleUnitVersion),
|
||||
FunctionGraphController(parentResponder, inputEventHandlerDelegate, header, graphRange, &m_view, cursor, indexFunctionSelectedByCursor, modelVersion, rangeVersion, angleUnitVersion),
|
||||
m_bannerView(),
|
||||
m_view(sequenceStore, graphRange, m_cursor, &m_bannerView, &m_cursorView),
|
||||
m_graphRange(graphRange),
|
||||
@@ -40,7 +40,7 @@ float GraphController::interestingXMin() const {
|
||||
}
|
||||
|
||||
float GraphController::interestingXHalfRange() const {
|
||||
float standardRange = Shared::StorageFunctionGraphController::interestingXHalfRange();
|
||||
float standardRange = Shared::FunctionGraphController::interestingXHalfRange();
|
||||
int nmin = INT_MAX;
|
||||
int nmax = 0;
|
||||
int nbOfActiveModels = functionStore()->numberOfActiveFunctions();
|
||||
@@ -57,7 +57,7 @@ float GraphController::interestingXHalfRange() const {
|
||||
bool GraphController::handleEnter() {
|
||||
Ion::Storage::Record record = functionStore()->activeRecordAtIndex(indexFunctionSelectedByCursor());
|
||||
m_termSumController.setRecord(record);
|
||||
return StorageFunctionGraphController::handleEnter();
|
||||
return FunctionGraphController::handleEnter();
|
||||
}
|
||||
|
||||
bool GraphController::moveCursorHorizontally(int direction) {
|
||||
@@ -84,7 +84,7 @@ bool GraphController::moveCursorHorizontally(int direction) {
|
||||
}
|
||||
|
||||
double GraphController::defaultCursorAbscissa() {
|
||||
return std::round(Shared::StorageFunctionGraphController::defaultCursorAbscissa());
|
||||
return std::round(Shared::FunctionGraphController::defaultCursorAbscissa());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Sequence {
|
||||
|
||||
class GraphController final : public Shared::StorageFunctionGraphController {
|
||||
class GraphController final : public Shared::FunctionGraphController {
|
||||
public:
|
||||
GraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, SequenceStore * sequenceStore, CurveViewRange * graphRange, Shared::CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * rangeVersion, Poincare::Preferences::AngleUnit * angleUnitVersion, ButtonRowController * header);
|
||||
I18n::Message emptyMessage() override;
|
||||
@@ -28,7 +28,7 @@ private:
|
||||
bool moveCursorHorizontally(int direction) override;
|
||||
double defaultCursorAbscissa() override;
|
||||
CurveViewRange * interactiveCurveViewRange() override { return m_graphRange; }
|
||||
SequenceStore * functionStore() const override { return static_cast<SequenceStore *>(Shared::StorageFunctionGraphController::functionStore()); }
|
||||
SequenceStore * functionStore() const override { return static_cast<SequenceStore *>(Shared::FunctionGraphController::functionStore()); }
|
||||
GraphView * functionGraphView() override { return &m_view; }
|
||||
View * cursorView() override {
|
||||
return &m_cursorView;
|
||||
|
||||
@@ -7,13 +7,13 @@ namespace Sequence {
|
||||
|
||||
GraphView::GraphView(SequenceStore * sequenceStore, InteractiveCurveViewRange * graphRange,
|
||||
CurveViewCursor * cursor, BannerView * bannerView, View * cursorView) :
|
||||
StorageFunctionGraphView(graphRange, cursor, bannerView, cursorView),
|
||||
FunctionGraphView(graphRange, cursor, bannerView, cursorView),
|
||||
m_sequenceStore(sequenceStore)
|
||||
{
|
||||
}
|
||||
|
||||
void GraphView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
StorageFunctionGraphView::drawRect(ctx, rect);
|
||||
FunctionGraphView::drawRect(ctx, rect);
|
||||
for (int i = 0; i < m_sequenceStore->numberOfActiveFunctions(); i++) {
|
||||
Ion::Storage::Record record = m_sequenceStore->activeRecordAtIndex(i);
|
||||
Sequence * s = m_sequenceStore->modelForRecord(record);;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace Sequence {
|
||||
|
||||
class GraphView : public Shared::StorageFunctionGraphView {
|
||||
class GraphView : public Shared::FunctionGraphView {
|
||||
public:
|
||||
GraphView(SequenceStore * sequenceStore, Shared::InteractiveCurveViewRange * graphRange,
|
||||
Shared::CurveViewCursor * cursor, Shared::BannerView * bannerView, View * cursorView);
|
||||
|
||||
@@ -48,7 +48,7 @@ double TermSumController::cursorNextStep(double x, int direction) {
|
||||
return std::round(m_cursor->x()+delta);
|
||||
}
|
||||
|
||||
Layout TermSumController::createFunctionLayout(Shared::ExpiringPointer<Shared::StorageFunction> function) {
|
||||
Layout TermSumController::createFunctionLayout(Shared::ExpiringPointer<Shared::Function> function) {
|
||||
Sequence * sequence = static_cast<Sequence *>(function.pointer());
|
||||
return sequence->nameLayout();
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ private:
|
||||
bool moveCursorHorizontallyToPosition(double position) override;
|
||||
I18n::Message legendMessageAtStep(Step step) override;
|
||||
double cursorNextStep(double position, int direction) override;
|
||||
Poincare::Layout createFunctionLayout(Shared::ExpiringPointer<Shared::StorageFunction> function) override;
|
||||
Poincare::Layout createFunctionLayout(Shared::ExpiringPointer<Shared::Function> function) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { retur
|
||||
namespace Sequence {
|
||||
|
||||
ListController::ListController(Responder * parentResponder, ::InputEventHandlerDelegate * inputEventHandlerDelegate, ButtonRowController * header, ButtonRowController * footer) :
|
||||
Shared::StorageFunctionListController(parentResponder, header, footer, I18n::Message::AddSequence),
|
||||
Shared::FunctionListController(parentResponder, header, footer, I18n::Message::AddSequence),
|
||||
m_sequenceTitleCells{},
|
||||
m_expressionCells{},
|
||||
m_parameterController(inputEventHandlerDelegate, this),
|
||||
@@ -61,7 +61,7 @@ KDCoordinate ListController::expressionRowHeight(int j) {
|
||||
}
|
||||
|
||||
void ListController::willDisplayCellAtLocation(HighlightCell * cell, int i, int j) {
|
||||
Shared::StorageFunctionListController::willDisplayCellAtLocation(cell, i, j);
|
||||
Shared::FunctionListController::willDisplayCellAtLocation(cell, i, j);
|
||||
EvenOddCell * myCell = (EvenOddCell *)cell;
|
||||
myCell->setEven(modelIndexForRow(j)%2 == 0);
|
||||
}
|
||||
@@ -278,7 +278,7 @@ void ListController::editExpression(Ion::Events::Event event) {
|
||||
editExpression(sequenceDefinitionForRow(selectedRow()), event);
|
||||
}
|
||||
|
||||
void ListController::reinitSelectedExpression(ExpiringPointer<SingleExpressionModelHandle> model) {
|
||||
void ListController::reinitSelectedExpression(ExpiringPointer<ExpressionModelHandle> model) {
|
||||
// Invalidate the sequences context cache
|
||||
static_cast<App *>(app())->localContext()->resetCache();
|
||||
Sequence * sequence = static_cast<Sequence *>(model.pointer());
|
||||
@@ -306,7 +306,7 @@ void ListController::reinitSelectedExpression(ExpiringPointer<SingleExpressionMo
|
||||
}
|
||||
|
||||
bool ListController::removeModelRow(Ion::Storage::Record record) {
|
||||
Shared::StorageFunctionListController::removeModelRow(record);
|
||||
Shared::FunctionListController::removeModelRow(record);
|
||||
// Invalidate the sequences context cache
|
||||
static_cast<App *>(app())->localContext()->resetCache();
|
||||
return true;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
namespace Sequence {
|
||||
|
||||
class ListController : public Shared::StorageFunctionListController, public Shared::InputEventHandlerDelegate, public Shared::TextFieldDelegate, public Shared::LayoutFieldDelegate {
|
||||
class ListController : public Shared::FunctionListController, public Shared::InputEventHandlerDelegate, public Shared::TextFieldDelegate, public Shared::LayoutFieldDelegate {
|
||||
public:
|
||||
ListController(Responder * parentResponder, ::InputEventHandlerDelegate * inputEventHandlerDelegate, ButtonRowController * header, ButtonRowController * footer);
|
||||
const char * title() override;
|
||||
@@ -41,10 +41,10 @@ private:
|
||||
bool isAddEmptyRow(int j) override;
|
||||
int sequenceDefinitionForRow(int j);
|
||||
void addEmptyModel() override;
|
||||
void reinitSelectedExpression(Shared::ExpiringPointer<Shared::SingleExpressionModelHandle> model) override;
|
||||
void reinitSelectedExpression(Shared::ExpiringPointer<Shared::ExpressionModelHandle> model) override;
|
||||
void editExpression(Ion::Events::Event event) override;
|
||||
bool removeModelRow(Ion::Storage::Record record) override;
|
||||
SequenceStore * modelStore() override { return static_cast<SequenceStore *>(Shared::StorageFunctionListController::modelStore()); }
|
||||
SequenceStore * modelStore() override { return static_cast<SequenceStore *>(Shared::FunctionListController::modelStore()); }
|
||||
constexpr static int k_maxNumberOfRows = 3*MaxNumberOfSequences;
|
||||
SequenceTitleCell m_sequenceTitleCells[k_maxNumberOfRows];
|
||||
Shared::FunctionExpressionCell m_expressionCells[k_maxNumberOfRows];
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Sequence {
|
||||
|
||||
void Sequence::tidy() {
|
||||
m_definitionHandle.tidyName();
|
||||
StorageFunction::tidy(); // m_definitionName.tidy()
|
||||
Function::tidy(); // m_definitionName.tidy()
|
||||
m_firstInitialConditionHandle.tidy();
|
||||
m_firstInitialConditionHandle.tidyName();
|
||||
m_secondInitialConditionHandle.tidy();
|
||||
@@ -87,11 +87,11 @@ bool Sequence::isDefined() {
|
||||
SequenceRecordData * data = recordData();
|
||||
switch (type()) {
|
||||
case Type::Explicit:
|
||||
return StorageFunction::isDefined();
|
||||
return Function::isDefined();
|
||||
case Type::SingleRecurrence:
|
||||
return StorageFunction::isDefined() && data->firstInitialConditionSize() > 0;
|
||||
return Function::isDefined() && data->firstInitialConditionSize() > 0;
|
||||
default:
|
||||
return StorageFunction::isDefined() && data->firstInitialConditionSize() > 0 && data->secondInitialConditionSize() > 0;
|
||||
return Function::isDefined() && data->firstInitialConditionSize() > 0 && data->secondInitialConditionSize() > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,11 +99,11 @@ bool Sequence::isEmpty() {
|
||||
SequenceRecordData * data = recordData();
|
||||
switch (type()) {
|
||||
case Type::Explicit:
|
||||
return StorageFunction::isEmpty();
|
||||
return Function::isEmpty();
|
||||
case Type::SingleRecurrence:
|
||||
return StorageFunction::isEmpty() && data->firstInitialConditionSize() == 0;
|
||||
return Function::isEmpty() && data->firstInitialConditionSize() == 0;
|
||||
default:
|
||||
return StorageFunction::isEmpty() && data->firstInitialConditionSize() == 0 && data->secondInitialConditionSize() == 0;
|
||||
return Function::isEmpty() && data->firstInitialConditionSize() == 0 && data->secondInitialConditionSize() == 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef SEQUENCE_SEQUENCE_H
|
||||
#define SEQUENCE_SEQUENCE_H
|
||||
|
||||
#include "../shared/storage_function.h"
|
||||
#include "../shared/function.h"
|
||||
#include "sequence_context.h"
|
||||
#include <assert.h>
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Sequence {
|
||||
* or setSecondInitialConditionContent, the sequence context needs to
|
||||
* invalidate the cache because the sequences evaluations might have changed. */
|
||||
|
||||
class Sequence : public Shared::StorageFunction {
|
||||
class Sequence : public Shared::Function {
|
||||
friend class SequenceStore;
|
||||
public:
|
||||
enum class Type : uint8_t {
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
DoubleRecurrence = 2
|
||||
};
|
||||
Sequence(Ion::Storage::Record record = Record()) :
|
||||
StorageFunction(record),
|
||||
Function(record),
|
||||
m_nameLayout() {}
|
||||
static char Symbol() { return 'n'; }
|
||||
void tidy() override;
|
||||
@@ -94,9 +94,9 @@ private:
|
||||
uint16_t m_secondInitialConditionSize;
|
||||
};
|
||||
|
||||
class SequenceHandle : public Shared::ExpressionModelHandle {
|
||||
class SequenceHandle : public Shared::ExpressionModel {
|
||||
public:
|
||||
SequenceHandle() : Shared::ExpressionModelHandle(), m_name() {}
|
||||
SequenceHandle() : Shared::ExpressionModel(), m_name() {}
|
||||
void tidyName() { m_name = Poincare::Layout(); }
|
||||
virtual Poincare::Layout name(Sequence * sequence);
|
||||
protected:
|
||||
@@ -135,7 +135,7 @@ private:
|
||||
|
||||
template<typename T> T templatedApproximateAtAbscissa(T x, SequenceContext * sqctx) const;
|
||||
size_t metaDataSize() const override { return sizeof(SequenceRecordData); }
|
||||
const Shared::ExpressionModelHandle * handle() const override { return &m_definitionHandle; }
|
||||
const Shared::ExpressionModel * handle() const override { return &m_definitionHandle; }
|
||||
SequenceRecordData * recordData() const;
|
||||
DefinitionHandle m_definitionHandle;
|
||||
FirstInitialConditionHandle m_firstInitialConditionHandle;
|
||||
|
||||
@@ -42,7 +42,7 @@ void SequenceStore::setMemoizedModelAtIndex(int cacheIndex, Ion::Storage::Record
|
||||
m_sequences[cacheIndex] = Sequence(record);
|
||||
}
|
||||
|
||||
Shared::SingleExpressionModelHandle * SequenceStore::memoizedModelAtIndex(int cacheIndex) const {
|
||||
Shared::ExpressionModelHandle * SequenceStore::memoizedModelAtIndex(int cacheIndex) const {
|
||||
assert(cacheIndex >= 0 && cacheIndex < maxNumberOfMemoizedModels());
|
||||
return &m_sequences[cacheIndex];
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
namespace Sequence {
|
||||
|
||||
class SequenceStore : public Shared::StorageFunctionStore {
|
||||
class SequenceStore : public Shared::FunctionStore {
|
||||
public:
|
||||
using Shared::StorageFunctionStore::StorageFunctionStore;
|
||||
using Shared::FunctionStore::FunctionStore;
|
||||
char symbol() const override { return Sequence::Symbol(); }
|
||||
char unknownSymbol() const override { return Poincare::Symbol::SpecialSymbols::UnknownN; }
|
||||
/* Sequence Store hold all its Sequences in an array. The Sequence pointers
|
||||
@@ -34,7 +34,7 @@ private:
|
||||
/* We don't really use model memoization as the number of Sequence is limited
|
||||
* and we keep enough Sequences to store them all. */
|
||||
void setMemoizedModelAtIndex(int cacheIndex, Ion::Storage::Record record) const override;
|
||||
Shared::SingleExpressionModelHandle * memoizedModelAtIndex(int cacheIndex) const override;
|
||||
Shared::ExpressionModelHandle * memoizedModelAtIndex(int cacheIndex) const override;
|
||||
mutable Sequence m_sequences[MaxNumberOfSequences];
|
||||
};
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ app_src += $(addprefix apps/shared/,\
|
||||
buffer_function_title_cell.cpp \
|
||||
buffer_text_view_with_text_field.cpp \
|
||||
button_with_separator.cpp \
|
||||
cartesian_function.cpp\
|
||||
cursor_view.cpp \
|
||||
curve_view.cpp \
|
||||
curve_view_cursor.cpp \
|
||||
@@ -10,8 +11,11 @@ app_src += $(addprefix apps/shared/,\
|
||||
double_pair_store.cpp \
|
||||
editable_cell_table_view_controller.cpp \
|
||||
expression_field_delegate_app.cpp \
|
||||
expression_model.cpp \
|
||||
expression_model_handle.cpp \
|
||||
float_parameter_controller.cpp \
|
||||
function.cpp \
|
||||
function_app.cpp \
|
||||
function_expression_cell.cpp \
|
||||
function_title_cell.cpp \
|
||||
global_context.cpp \
|
||||
@@ -39,12 +43,8 @@ app_src += $(addprefix apps/shared/,\
|
||||
scrollable_exact_approximate_expressions_view.cpp \
|
||||
separator_even_odd_buffer_text_cell.cpp \
|
||||
simple_interactive_curve_view_controller.cpp \
|
||||
single_expression_model_handle.cpp\
|
||||
storage_cartesian_function.cpp \
|
||||
storage_expression_model_list_controller.cpp \
|
||||
storage_expression_model_store.cpp \
|
||||
storage_function.cpp \
|
||||
storage_function_app.cpp \
|
||||
storage_function_banner_delegate.cpp \
|
||||
storage_function_curve_parameter_controller.cpp \
|
||||
storage_function_go_to_parameter_controller.cpp \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "storage_cartesian_function.h"
|
||||
#include "cartesian_function.h"
|
||||
#include "storage_expression_model_store.h"
|
||||
#include "poincare_helpers.h"
|
||||
#include <poincare/derivative.h>
|
||||
@@ -12,7 +12,7 @@ using namespace Poincare;
|
||||
|
||||
namespace Shared {
|
||||
|
||||
void StorageCartesianFunction::DefaultName(char buffer[], size_t bufferSize) {
|
||||
void CartesianFunction::DefaultName(char buffer[], size_t bufferSize) {
|
||||
constexpr int k_maxNumberOfDefaultLetterNames = 4;
|
||||
static constexpr const char k_defaultLetterNames[k_maxNumberOfDefaultLetterNames] = {
|
||||
'f', 'g', 'h', 'p'
|
||||
@@ -43,7 +43,7 @@ void StorageCartesianFunction::DefaultName(char buffer[], size_t bufferSize) {
|
||||
assert(currentNumberLength >= 0 && currentNumberLength < availableBufferSize);
|
||||
}
|
||||
|
||||
StorageCartesianFunction StorageCartesianFunction::NewModel(Ion::Storage::Record::ErrorStatus * error, const char * baseName) {
|
||||
CartesianFunction CartesianFunction::NewModel(Ion::Storage::Record::ErrorStatus * error, const char * baseName) {
|
||||
static int s_colorIndex = 0;
|
||||
// Create the record
|
||||
char nameBuffer[SymbolAbstract::k_maxNameSize];
|
||||
@@ -57,15 +57,15 @@ StorageCartesianFunction StorageCartesianFunction::NewModel(Ion::Storage::Record
|
||||
|
||||
// Return if error
|
||||
if (*error != Ion::Storage::Record::ErrorStatus::None) {
|
||||
return StorageCartesianFunction();
|
||||
return CartesianFunction();
|
||||
}
|
||||
|
||||
// Return the StorageCartesianFunction withthe new record
|
||||
return StorageCartesianFunction(Ion::Storage::sharedStorage()->recordBaseNamedWithExtension(baseName, Ion::Storage::funcExtension));
|
||||
// Return the CartesianFunction withthe new record
|
||||
return CartesianFunction(Ion::Storage::sharedStorage()->recordBaseNamedWithExtension(baseName, Ion::Storage::funcExtension));
|
||||
}
|
||||
|
||||
int StorageCartesianFunction::derivativeNameWithArgument(char * buffer, size_t bufferSize, char arg) {
|
||||
// Fill buffer with f(x). Keep one char foderivativeSizer derivative sign.
|
||||
int CartesianFunction::derivativeNameWithArgument(char * buffer, size_t bufferSize, char arg) {
|
||||
// Fill buffer with f(x). Keep size for derivative sign.
|
||||
int derivativeSize = UTF8Decoder::CharSizeOfCodePoint('\'');
|
||||
int numberOfChars = nameWithArgument(buffer, bufferSize - derivativeSize, arg);
|
||||
assert(numberOfChars + derivativeSize < bufferSize);
|
||||
@@ -78,15 +78,15 @@ int StorageCartesianFunction::derivativeNameWithArgument(char * buffer, size_t b
|
||||
return numberOfChars + derivativeSize;
|
||||
}
|
||||
|
||||
bool StorageCartesianFunction::displayDerivative() const {
|
||||
bool CartesianFunction::displayDerivative() const {
|
||||
return recordData()->displayDerivative();
|
||||
}
|
||||
|
||||
void StorageCartesianFunction::setDisplayDerivative(bool display) {
|
||||
void CartesianFunction::setDisplayDerivative(bool display) {
|
||||
return recordData()->setDisplayDerivative(display);
|
||||
}
|
||||
|
||||
double StorageCartesianFunction::approximateDerivative(double x, Poincare::Context * context) const {
|
||||
double CartesianFunction::approximateDerivative(double x, Poincare::Context * context) const {
|
||||
Poincare::Derivative derivative = Poincare::Derivative::Builder(expressionReduced(context).clone(), Symbol::Builder(Symbol::SpecialSymbols::UnknownX), Poincare::Float<double>::Builder(x)); // derivative takes ownership of Poincare::Float<double>::Builder(x) and the clone of expression
|
||||
/* TODO: when we approximate derivative, we might want to simplify the
|
||||
* derivative here. However, we might want to do it once for all x (to avoid
|
||||
@@ -94,7 +94,7 @@ double StorageCartesianFunction::approximateDerivative(double x, Poincare::Conte
|
||||
return PoincareHelpers::ApproximateToScalar<double>(derivative, *context);
|
||||
}
|
||||
|
||||
double StorageCartesianFunction::sumBetweenBounds(double start, double end, Poincare::Context * context) const {
|
||||
double CartesianFunction::sumBetweenBounds(double start, double end, Poincare::Context * context) const {
|
||||
// TODO: this does not work yet because integral does not understand UnknownX
|
||||
Poincare::Integral integral = Poincare::Integral::Builder(expressionReduced(context).clone(), Symbol::Builder(Symbol::SpecialSymbols::UnknownX), Poincare::Float<double>::Builder(start), Poincare::Float<double>::Builder(end)); // Integral takes ownership of args
|
||||
/* TODO: when we approximate integral, we might want to simplify the integral
|
||||
@@ -103,35 +103,35 @@ double StorageCartesianFunction::sumBetweenBounds(double start, double end, Poin
|
||||
return PoincareHelpers::ApproximateToScalar<double>(integral, *context);
|
||||
}
|
||||
|
||||
Expression::Coordinate2D StorageCartesianFunction::nextMinimumFrom(double start, double step, double max, Context * context) const {
|
||||
Expression::Coordinate2D CartesianFunction::nextMinimumFrom(double start, double step, double max, Context * context) const {
|
||||
const char unknownX[2] = {Poincare::Symbol::UnknownX, 0};
|
||||
return PoincareHelpers::NextMinimum(expressionReduced(context), unknownX, start, step, max, *context);
|
||||
}
|
||||
|
||||
Expression::Coordinate2D StorageCartesianFunction::nextMaximumFrom(double start, double step, double max, Context * context) const {
|
||||
Expression::Coordinate2D CartesianFunction::nextMaximumFrom(double start, double step, double max, Context * context) const {
|
||||
const char unknownX[2] = {Poincare::Symbol::UnknownX, 0};
|
||||
return PoincareHelpers::NextMaximum(expressionReduced(context), unknownX, start, step, max, *context);
|
||||
}
|
||||
|
||||
double StorageCartesianFunction::nextRootFrom(double start, double step, double max, Context * context) const {
|
||||
double CartesianFunction::nextRootFrom(double start, double step, double max, Context * context) const {
|
||||
const char unknownX[2] = {Poincare::Symbol::UnknownX, 0};
|
||||
return PoincareHelpers::NextRoot(expressionReduced(context), unknownX, start, step, max, *context);
|
||||
}
|
||||
|
||||
Expression::Coordinate2D StorageCartesianFunction::nextIntersectionFrom(double start, double step, double max, Poincare::Context * context, Expression e) const {
|
||||
Expression::Coordinate2D CartesianFunction::nextIntersectionFrom(double start, double step, double max, Poincare::Context * context, Expression e) const {
|
||||
const char unknownX[2] = {Poincare::Symbol::UnknownX, 0};
|
||||
return PoincareHelpers::NextIntersection(expressionReduced(context), unknownX, start, step, max, *context, e);
|
||||
}
|
||||
|
||||
void * StorageCartesianFunction::Handle::expressionAddress(const Ion::Storage::Record * record) const {
|
||||
void * CartesianFunction::Model::expressionAddress(const Ion::Storage::Record * record) const {
|
||||
return (char *)record->value().buffer+sizeof(CartesianFunctionRecordData);
|
||||
}
|
||||
|
||||
size_t StorageCartesianFunction::Handle::expressionSize(const Ion::Storage::Record * record) const {
|
||||
size_t CartesianFunction::Model::expressionSize(const Ion::Storage::Record * record) const {
|
||||
return record->value().size-sizeof(CartesianFunctionRecordData);
|
||||
}
|
||||
|
||||
StorageCartesianFunction::CartesianFunctionRecordData * StorageCartesianFunction::recordData() const {
|
||||
CartesianFunction::CartesianFunctionRecordData * CartesianFunction::recordData() const {
|
||||
assert(!isNull());
|
||||
Ion::Storage::Record::Data d = value();
|
||||
return reinterpret_cast<CartesianFunctionRecordData *>(const_cast<void *>(d.buffer));
|
||||
@@ -1,19 +1,19 @@
|
||||
#ifndef SHARED_STORAGE_CARTESIAN_FUNCTION_H
|
||||
#define SHARED_STORAGE_CARTESIAN_FUNCTION_H
|
||||
#ifndef SHARED_CARTESIAN_FUNCTION_H
|
||||
#define SHARED_CARTESIAN_FUNCTION_H
|
||||
|
||||
#include "global_context.h"
|
||||
#include "storage_function.h"
|
||||
#include "function.h"
|
||||
#include <poincare/symbol.h>
|
||||
|
||||
namespace Shared {
|
||||
|
||||
class StorageCartesianFunction : public StorageFunction {
|
||||
class CartesianFunction : public Function {
|
||||
public:
|
||||
static void DefaultName(char buffer[], size_t bufferSize);
|
||||
static char Symbol() { return 'x'; }
|
||||
static StorageCartesianFunction NewModel(Ion::Storage::Record::ErrorStatus * error, const char * baseName = nullptr);
|
||||
StorageCartesianFunction(Ion::Storage::Record record = Record()) :
|
||||
StorageFunction(record)
|
||||
static CartesianFunction NewModel(Ion::Storage::Record::ErrorStatus * error, const char * baseName = nullptr);
|
||||
CartesianFunction(Ion::Storage::Record record = Record()) :
|
||||
Function(record)
|
||||
{}
|
||||
Ion::Storage::Record::ErrorStatus setContent(const char * c) override { return editableHandle()->setContent(this, c, Symbol(), Poincare::Symbol::SpecialSymbols::UnknownX); }
|
||||
|
||||
@@ -45,16 +45,16 @@ private:
|
||||
* the expression of the function, directly copied from the pool. */
|
||||
//char m_expression[0];
|
||||
};
|
||||
class Handle : public ExpressionModelHandle {
|
||||
class Model : public ExpressionModel {
|
||||
public:
|
||||
void * expressionAddress(const Ion::Storage::Record * record) const override;
|
||||
private:
|
||||
size_t expressionSize(const Ion::Storage::Record * record) const override;
|
||||
};
|
||||
size_t metaDataSize() const override { return sizeof(CartesianFunctionRecordData); }
|
||||
const ExpressionModelHandle * handle() const override { return &m_handle; }
|
||||
const ExpressionModel * handle() const override { return &m_model; }
|
||||
CartesianFunctionRecordData * recordData() const;
|
||||
Handle m_handle;
|
||||
Model m_model;
|
||||
};
|
||||
|
||||
}
|
||||
131
apps/shared/expression_model.cpp
Normal file
131
apps/shared/expression_model.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
#include "expression_model.h"
|
||||
#include "global_context.h"
|
||||
#include "poincare_helpers.h"
|
||||
#include <poincare/horizontal_layout.h>
|
||||
#include <string.h>
|
||||
#include <cmath>
|
||||
#include <assert.h>
|
||||
|
||||
using namespace Ion;
|
||||
using namespace Poincare;
|
||||
|
||||
namespace Shared {
|
||||
|
||||
static inline int maxInt(int x, int y) { return x > y ? x : y; }
|
||||
|
||||
ExpressionModel::ExpressionModel() :
|
||||
m_expression(),
|
||||
m_layout(),
|
||||
m_circular(-1)
|
||||
{
|
||||
}
|
||||
|
||||
void ExpressionModel::text(const Storage::Record * record, char * buffer, size_t bufferSize) const {
|
||||
Expression e = expressionClone(record);
|
||||
if (e.isUninitialized() && bufferSize > 0) {
|
||||
buffer[0] = 0;
|
||||
} else {
|
||||
e.serialize(buffer, bufferSize);
|
||||
}
|
||||
}
|
||||
|
||||
bool ExpressionModel::isCircularlyDefined(const Storage::Record * record, Poincare::Context * context) const {
|
||||
if (m_circular == -1) {
|
||||
m_circular = Expression::ExpressionWithoutSymbols(expressionClone(record), *context).isUninitialized();
|
||||
}
|
||||
return m_circular;
|
||||
}
|
||||
|
||||
Expression ExpressionModel::expressionReduced(const Storage::Record * record, Poincare::Context * context) const {
|
||||
if (m_expression.isUninitialized()) {
|
||||
assert(record->fullName() != nullptr);
|
||||
m_expression = Expression::ExpressionFromAddress(expressionAddress(record), expressionSize(record));
|
||||
PoincareHelpers::Simplify(&m_expression, *context);
|
||||
// simplify might return an uninitialized Expression if interrupted
|
||||
if (m_expression.isUninitialized()) {
|
||||
m_expression = Expression::ExpressionFromAddress(expressionAddress(record), expressionSize(record));
|
||||
}
|
||||
}
|
||||
return m_expression;
|
||||
}
|
||||
|
||||
Expression ExpressionModel::expressionClone(const Storage::Record * record) const {
|
||||
assert(record->fullName() != nullptr);
|
||||
/* A new Expression has to be created at each call (because it might be tempered with after calling) */
|
||||
return Expression::ExpressionFromAddress(expressionAddress(record), expressionSize(record));
|
||||
}
|
||||
|
||||
Layout ExpressionModel::layout(const Storage::Record * record) const {
|
||||
if (m_layout.isUninitialized()) {
|
||||
m_layout = PoincareHelpers::CreateLayout(expressionClone(record));
|
||||
if (m_layout.isUninitialized()) {
|
||||
m_layout = HorizontalLayout::Builder();
|
||||
}
|
||||
}
|
||||
return m_layout;
|
||||
}
|
||||
|
||||
Ion::Storage::Record::ErrorStatus ExpressionModel::setContent(Ion::Storage::Record * record, const char * c, char symbol, char unknownSymbol) {
|
||||
Expression e = ExpressionModel::BuildExpressionFromText(c, symbol, unknownSymbol);
|
||||
return setExpressionContent(record, e);
|
||||
}
|
||||
|
||||
Ion::Storage::Record::ErrorStatus ExpressionModel::setExpressionContent(Ion::Storage::Record * record, Expression & newExpression) {
|
||||
assert(record->fullName() != nullptr);
|
||||
// Prepare the new data to be stored
|
||||
Ion::Storage::Record::Data newData = record->value();
|
||||
size_t previousExpressionSize = expressionSize(record);
|
||||
size_t newExpressionSize = newExpression.isUninitialized() ? 0 : newExpression.size();
|
||||
size_t previousDataSize = newData.size;
|
||||
size_t newDataSize = previousDataSize - previousExpressionSize + newExpressionSize;
|
||||
void * expAddress = expressionAddress(record);
|
||||
// Update size of record to maximal size between previous and new data
|
||||
newData.size = maxInt(previousDataSize, newDataSize);
|
||||
Ion::Storage::Record::ErrorStatus error = record->setValue(newData);
|
||||
if (error != Ion::Storage::Record::ErrorStatus::None) {
|
||||
assert(error == Ion::Storage::Record::ErrorStatus::NotEnoughSpaceAvailable);
|
||||
return error;
|
||||
}
|
||||
// Prepare the new data content
|
||||
/* WARNING: expressionAddress() cannot be used while the metadata is invalid
|
||||
* (as it is sometimes computed from metadata). Thus, the expression address
|
||||
* is given as a parameter to updateNewDataWithExpression. */
|
||||
updateNewDataWithExpression(record, newExpression, expAddress, newExpressionSize, previousExpressionSize);
|
||||
// Set the data with the right size
|
||||
newData.size = newDataSize;
|
||||
error = record->setValue(newData);
|
||||
// Any error would have occured at the first call to setValue
|
||||
assert(error == Ion::Storage::Record::ErrorStatus::None);
|
||||
|
||||
/* Here we delete only the elements relative to the expression model kept in
|
||||
* this handle. */
|
||||
tidy();
|
||||
return error;
|
||||
}
|
||||
|
||||
void ExpressionModel::updateNewDataWithExpression(Ion::Storage::Record * record, Expression & expressionToStore, void * expressionAddress, size_t expressionToStoreSize, size_t previousExpressionSize) {
|
||||
if (!expressionToStore.isUninitialized()) {
|
||||
memmove(expressionAddress, expressionToStore.addressInPool(), expressionToStoreSize);
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionModel::tidy() const {
|
||||
m_layout = Layout();
|
||||
m_expression = Expression();
|
||||
m_circular = 0;
|
||||
}
|
||||
|
||||
Poincare::Expression ExpressionModel::BuildExpressionFromText(const char * c, char symbol, char unknownSymbol) {
|
||||
Expression expressionToStore;
|
||||
// if c = "", we want to reinit the Expression
|
||||
if (c && *c != 0) {
|
||||
// Compute the expression to store, without replacing symbols
|
||||
expressionToStore = Expression::Parse(c);
|
||||
if (!expressionToStore.isUninitialized() && symbol != 0) {
|
||||
expressionToStore = expressionToStore.replaceUnknown(Symbol::Builder(symbol), Symbol::Builder(unknownSymbol));
|
||||
}
|
||||
}
|
||||
return expressionToStore;
|
||||
}
|
||||
|
||||
}
|
||||
42
apps/shared/expression_model.h
Normal file
42
apps/shared/expression_model.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef SHARED_EXPRESSION_MODEL_H
|
||||
#define SHARED_EXPRESSION_MODEL_H
|
||||
|
||||
#include <poincare/context.h>
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/layout.h>
|
||||
|
||||
namespace Shared {
|
||||
|
||||
class ExpressionModel {
|
||||
public:
|
||||
ExpressionModel();
|
||||
|
||||
// Getters
|
||||
void text(const Ion::Storage::Record * record, char * buffer, size_t bufferSize) const;
|
||||
Poincare::Expression expressionReduced(const Ion::Storage::Record * record, Poincare::Context * context) const;
|
||||
Poincare::Expression expressionClone(const Ion::Storage::Record * record) const;
|
||||
Poincare::Layout layout(const Ion::Storage::Record * record) const;
|
||||
|
||||
// Setters
|
||||
virtual Ion::Storage::Record::ErrorStatus setContent(Ion::Storage::Record * record, const char * c, char symbol = 0, char unknownSymbol = 0);
|
||||
Ion::Storage::Record::ErrorStatus setExpressionContent(Ion::Storage::Record * record, Poincare::Expression & e);
|
||||
|
||||
// Property
|
||||
bool isCircularlyDefined(const Ion::Storage::Record * record, Poincare::Context * context) const;
|
||||
virtual void * expressionAddress(const Ion::Storage::Record * record) const = 0;
|
||||
|
||||
virtual void tidy() const;
|
||||
protected:
|
||||
// Setters helper
|
||||
static Poincare::Expression BuildExpressionFromText(const char * c, char symbol = 0, char unknownSymbol = 0);
|
||||
mutable Poincare::Expression m_expression;
|
||||
mutable Poincare::Layout m_layout;
|
||||
private:
|
||||
virtual void updateNewDataWithExpression(Ion::Storage::Record * record, Poincare::Expression & expressionToStore, void * expressionAddress, size_t expressionToStoreSize, size_t previousExpressionSize);
|
||||
virtual size_t expressionSize(const Ion::Storage::Record * record) const = 0;
|
||||
mutable int m_circular;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -13,119 +13,17 @@ namespace Shared {
|
||||
|
||||
static inline int maxInt(int x, int y) { return x > y ? x : y; }
|
||||
|
||||
ExpressionModelHandle::ExpressionModelHandle() :
|
||||
m_expression(),
|
||||
m_layout(),
|
||||
m_circular(-1)
|
||||
ExpressionModelHandle::ExpressionModelHandle(Storage::Record record) :
|
||||
Storage::Record(record)
|
||||
{
|
||||
}
|
||||
|
||||
void ExpressionModelHandle::text(const Storage::Record * record, char * buffer, size_t bufferSize) const {
|
||||
Expression e = expressionClone(record);
|
||||
if (e.isUninitialized() && bufferSize > 0) {
|
||||
buffer[0] = 0;
|
||||
} else {
|
||||
e.serialize(buffer, bufferSize);
|
||||
}
|
||||
bool ExpressionModelHandle::isDefined() {
|
||||
return !isEmpty();
|
||||
}
|
||||
|
||||
bool ExpressionModelHandle::isCircularlyDefined(const Storage::Record * record, Poincare::Context * context) const {
|
||||
if (m_circular == -1) {
|
||||
m_circular = Expression::ExpressionWithoutSymbols(expressionClone(record), *context).isUninitialized();
|
||||
}
|
||||
return m_circular;
|
||||
}
|
||||
|
||||
Expression ExpressionModelHandle::expressionReduced(const Storage::Record * record, Poincare::Context * context) const {
|
||||
if (m_expression.isUninitialized()) {
|
||||
assert(record->fullName() != nullptr);
|
||||
m_expression = Expression::ExpressionFromAddress(expressionAddress(record), expressionSize(record));
|
||||
PoincareHelpers::Simplify(&m_expression, *context);
|
||||
// simplify might return an uninitialized Expression if interrupted
|
||||
if (m_expression.isUninitialized()) {
|
||||
m_expression = Expression::ExpressionFromAddress(expressionAddress(record), expressionSize(record));
|
||||
}
|
||||
}
|
||||
return m_expression;
|
||||
}
|
||||
|
||||
Expression ExpressionModelHandle::expressionClone(const Storage::Record * record) const {
|
||||
assert(record->fullName() != nullptr);
|
||||
/* A new Expression has to be created at each call (because it might be tempered with after calling) */
|
||||
return Expression::ExpressionFromAddress(expressionAddress(record), expressionSize(record));
|
||||
}
|
||||
|
||||
Layout ExpressionModelHandle::layout(const Storage::Record * record) const {
|
||||
if (m_layout.isUninitialized()) {
|
||||
m_layout = PoincareHelpers::CreateLayout(expressionClone(record));
|
||||
if (m_layout.isUninitialized()) {
|
||||
m_layout = HorizontalLayout::Builder();
|
||||
}
|
||||
}
|
||||
return m_layout;
|
||||
}
|
||||
|
||||
Ion::Storage::Record::ErrorStatus ExpressionModelHandle::setContent(Ion::Storage::Record * record, const char * c, char symbol, char unknownSymbol) {
|
||||
Expression e = ExpressionModelHandle::BuildExpressionFromText(c, symbol, unknownSymbol);
|
||||
return setExpressionContent(record, e);
|
||||
}
|
||||
|
||||
Ion::Storage::Record::ErrorStatus ExpressionModelHandle::setExpressionContent(Ion::Storage::Record * record, Expression & newExpression) {
|
||||
assert(record->fullName() != nullptr);
|
||||
// Prepare the new data to be stored
|
||||
Ion::Storage::Record::Data newData = record->value();
|
||||
size_t previousExpressionSize = expressionSize(record);
|
||||
size_t newExpressionSize = newExpression.isUninitialized() ? 0 : newExpression.size();
|
||||
size_t previousDataSize = newData.size;
|
||||
size_t newDataSize = previousDataSize - previousExpressionSize + newExpressionSize;
|
||||
void * expAddress = expressionAddress(record);
|
||||
// Update size of record to maximal size between previous and new data
|
||||
newData.size = maxInt(previousDataSize, newDataSize);
|
||||
Ion::Storage::Record::ErrorStatus error = record->setValue(newData);
|
||||
if (error != Ion::Storage::Record::ErrorStatus::None) {
|
||||
assert(error == Ion::Storage::Record::ErrorStatus::NotEnoughSpaceAvailable);
|
||||
return error;
|
||||
}
|
||||
// Prepare the new data content
|
||||
/* WARNING: expressionAddress() cannot be used while the metadata is invalid
|
||||
* (as it is sometimes computed from metadata). Thus, the expression address
|
||||
* is given as a parameter to updateNewDataWithExpression. */
|
||||
updateNewDataWithExpression(record, newExpression, expAddress, newExpressionSize, previousExpressionSize);
|
||||
// Set the data with the right size
|
||||
newData.size = newDataSize;
|
||||
error = record->setValue(newData);
|
||||
// Any error would have occured at the first call to setValue
|
||||
assert(error == Ion::Storage::Record::ErrorStatus::None);
|
||||
|
||||
/* Here we delete only the elements relative to the expression model kept in
|
||||
* this handle. */
|
||||
tidy();
|
||||
return error;
|
||||
}
|
||||
|
||||
void ExpressionModelHandle::updateNewDataWithExpression(Ion::Storage::Record * record, Expression & expressionToStore, void * expressionAddress, size_t expressionToStoreSize, size_t previousExpressionSize) {
|
||||
if (!expressionToStore.isUninitialized()) {
|
||||
memmove(expressionAddress, expressionToStore.addressInPool(), expressionToStoreSize);
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionModelHandle::tidy() const {
|
||||
m_layout = Layout();
|
||||
m_expression = Expression();
|
||||
m_circular = 0;
|
||||
}
|
||||
|
||||
Poincare::Expression ExpressionModelHandle::BuildExpressionFromText(const char * c, char symbol, char unknownSymbol) {
|
||||
Expression expressionToStore;
|
||||
// if c = "", we want to reinit the Expression
|
||||
if (c && *c != 0) {
|
||||
// Compute the expression to store, without replacing symbols
|
||||
expressionToStore = Expression::Parse(c);
|
||||
if (!expressionToStore.isUninitialized() && symbol != 0) {
|
||||
expressionToStore = expressionToStore.replaceUnknown(Symbol::Builder(symbol), Symbol::Builder(unknownSymbol));
|
||||
}
|
||||
}
|
||||
return expressionToStore;
|
||||
bool ExpressionModelHandle::isEmpty() {
|
||||
return value().size <= metaDataSize();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,42 +1,41 @@
|
||||
#ifndef SHARED_EXPRESSION_MODEL_HANDLE_H
|
||||
#define SHARED_EXPRESSION_MODEL_HANDLE_H
|
||||
|
||||
#include <poincare/context.h>
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/layout.h>
|
||||
#include "expression_model.h"
|
||||
|
||||
namespace Shared {
|
||||
|
||||
// ExpressionModelHandle is a handle to Ion::Record
|
||||
//ExpressionModelHandle is a handle for Ion::Record
|
||||
|
||||
class ExpressionModelHandle {
|
||||
class ExpressionModelHandle : public Ion::Storage::Record {
|
||||
public:
|
||||
ExpressionModelHandle();
|
||||
|
||||
// Getters
|
||||
void text(const Ion::Storage::Record * record, char * buffer, size_t bufferSize) const;
|
||||
Poincare::Expression expressionReduced(const Ion::Storage::Record * record, Poincare::Context * context) const;
|
||||
Poincare::Expression expressionClone(const Ion::Storage::Record * record) const;
|
||||
Poincare::Layout layout(const Ion::Storage::Record * record) const;
|
||||
|
||||
// Setters
|
||||
virtual Ion::Storage::Record::ErrorStatus setContent(Ion::Storage::Record * record, const char * c, char symbol = 0, char unknownSymbol = 0);
|
||||
Ion::Storage::Record::ErrorStatus setExpressionContent(Ion::Storage::Record * record, Poincare::Expression & e);
|
||||
ExpressionModelHandle(Ion::Storage::Record record = Ion::Storage::Record());
|
||||
|
||||
// Property
|
||||
bool isCircularlyDefined(const Ion::Storage::Record * record, Poincare::Context * context) const;
|
||||
virtual void * expressionAddress(const Ion::Storage::Record * record) const = 0;
|
||||
|
||||
virtual void tidy() const;
|
||||
void text(char * buffer, size_t bufferSize) const { return handle()->text(this, buffer, bufferSize); }
|
||||
Poincare::Expression expressionReduced(Poincare::Context * context) const { return handle()->expressionReduced(this, context); }
|
||||
Poincare::Expression expressionClone() const { return handle()->expressionClone(this); }
|
||||
Poincare::Layout layout() { return handle()->layout(this); }
|
||||
/* Here, isDefined is the exact contrary of isEmpty. However, for Sequence
|
||||
* inheriting from ExpressionModelHandle, isEmpty and isDefined have not exactly
|
||||
* opposite meaning. For instance, u(n+1)=u(n) & u(0) = ... is not empty and
|
||||
* not defined. We thus have to keep both methods. */
|
||||
virtual bool isDefined();
|
||||
virtual bool isEmpty();
|
||||
virtual bool shouldBeClearedBeforeRemove() { return !isEmpty(); }
|
||||
/* tidy is responsible to tidy the whole model whereas tidyExpressionModel
|
||||
* tidies only the members associated with the ExpressionModel. In
|
||||
* ExpressionModel, tidy and tidyExpressionModel trigger the same
|
||||
* behaviour but it is not true for its child classes (for example, in
|
||||
* Sequence). */
|
||||
virtual void tidy() { handle()->tidy(); }
|
||||
virtual Ion::Storage::Record::ErrorStatus setContent(const char * c) { return editableHandle()->setContent(this, c); }
|
||||
Ion::Storage::Record::ErrorStatus setExpressionContent(Poincare::Expression & e) { return editableHandle()->setExpressionContent(this, e); }
|
||||
protected:
|
||||
// Setters helper
|
||||
static Poincare::Expression BuildExpressionFromText(const char * c, char symbol = 0, char unknownSymbol = 0);
|
||||
mutable Poincare::Expression m_expression;
|
||||
mutable Poincare::Layout m_layout;
|
||||
private:
|
||||
virtual void updateNewDataWithExpression(Ion::Storage::Record * record, Poincare::Expression & expressionToStore, void * expressionAddress, size_t expressionToStoreSize, size_t previousExpressionSize);
|
||||
virtual size_t expressionSize(const Ion::Storage::Record * record) const = 0;
|
||||
mutable int m_circular;
|
||||
bool isCircularlyDefined(Poincare::Context * context) const { return handle()->isCircularlyDefined(this, context); }
|
||||
ExpressionModel * editableHandle() { return const_cast<ExpressionModel *>(handle()); }
|
||||
virtual const ExpressionModel * handle() const = 0;
|
||||
virtual size_t metaDataSize() const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "storage_function.h"
|
||||
#include "function.h"
|
||||
#include "poincare_helpers.h"
|
||||
#include <poincare/serialization_helper.h>
|
||||
#include "poincare/src/parsing/parser.h"
|
||||
@@ -12,9 +12,9 @@ using namespace Poincare;
|
||||
|
||||
namespace Shared {
|
||||
|
||||
constexpr char StorageFunction::k_parenthesedArgument[];
|
||||
constexpr char Function::k_parenthesedArgument[];
|
||||
|
||||
bool StorageFunction::BaseNameCompliant(const char * baseName, NameNotCompliantError * error) {
|
||||
bool Function::BaseNameCompliant(const char * baseName, NameNotCompliantError * error) {
|
||||
assert(baseName[0] != 0);
|
||||
|
||||
UTF8Decoder decoder(baseName);
|
||||
@@ -52,19 +52,19 @@ bool StorageFunction::BaseNameCompliant(const char * baseName, NameNotCompliantE
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StorageFunction::isActive() const {
|
||||
bool Function::isActive() const {
|
||||
return recordData()->isActive();
|
||||
}
|
||||
|
||||
KDColor StorageFunction::color() const {
|
||||
KDColor Function::color() const {
|
||||
return recordData()->color();
|
||||
}
|
||||
|
||||
void StorageFunction::setActive(bool active) {
|
||||
void Function::setActive(bool active) {
|
||||
recordData()->setActive(active);
|
||||
}
|
||||
|
||||
int StorageFunction::nameWithArgument(char * buffer, size_t bufferSize, char arg) {
|
||||
int Function::nameWithArgument(char * buffer, size_t bufferSize, char arg) {
|
||||
const char * functionName = fullName();
|
||||
size_t baseNameLength = SymbolAbstract::TruncateExtension(buffer, functionName, bufferSize - k_parenthesedArgumentLength);
|
||||
int result = baseNameLength + strlcpy(&buffer[baseNameLength], k_parenthesedArgument, bufferSize-baseNameLength);
|
||||
@@ -75,7 +75,7 @@ int StorageFunction::nameWithArgument(char * buffer, size_t bufferSize, char arg
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T StorageFunction::templatedApproximateAtAbscissa(T x, Poincare::Context * context, char unknownSymbol) const {
|
||||
T Function::templatedApproximateAtAbscissa(T x, Poincare::Context * context, char unknownSymbol) const {
|
||||
if (isCircularlyDefined(context)) {
|
||||
return NAN;
|
||||
}
|
||||
@@ -85,7 +85,7 @@ T StorageFunction::templatedApproximateAtAbscissa(T x, Poincare::Context * conte
|
||||
return PoincareHelpers::ApproximateWithValueForSymbol(expressionReduced(context), unknownX, x, *context);
|
||||
}
|
||||
|
||||
StorageFunction::FunctionRecordData * StorageFunction::recordData() const {
|
||||
Function::FunctionRecordData * Function::recordData() const {
|
||||
assert(!isNull());
|
||||
Ion::Storage::Record::Data d = value();
|
||||
return reinterpret_cast<FunctionRecordData *>(const_cast<void *>(d.buffer));
|
||||
@@ -93,5 +93,5 @@ StorageFunction::FunctionRecordData * StorageFunction::recordData() const {
|
||||
|
||||
}
|
||||
|
||||
template float Shared::StorageFunction::templatedApproximateAtAbscissa<float>(float, Poincare::Context*, char) const;
|
||||
template double Shared::StorageFunction::templatedApproximateAtAbscissa<double>(double, Poincare::Context*, char) const;
|
||||
template float Shared::Function::templatedApproximateAtAbscissa<float>(float, Poincare::Context*, char) const;
|
||||
template double Shared::Function::templatedApproximateAtAbscissa<double>(double, Poincare::Context*, char) const;
|
||||
@@ -1,13 +1,13 @@
|
||||
#ifndef SHARED_STORAGE_FUNCTION_H
|
||||
#define SHARED_STORAGE_FUNCTION_H
|
||||
#ifndef SHARED_FUNCTION_H
|
||||
#define SHARED_FUNCTION_H
|
||||
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/symbol.h>
|
||||
#include "single_expression_model_handle.h"
|
||||
#include "expression_model_handle.h"
|
||||
|
||||
namespace Shared {
|
||||
|
||||
class StorageFunction : public SingleExpressionModelHandle {
|
||||
class Function : public ExpressionModelHandle {
|
||||
public:
|
||||
enum class NameNotCompliantError {
|
||||
None = 0,
|
||||
@@ -21,7 +21,7 @@ public:
|
||||
static bool BaseNameCompliant(const char * baseName, NameNotCompliantError * error = nullptr);
|
||||
|
||||
// Constructors
|
||||
StorageFunction(Ion::Storage::Record record) : SingleExpressionModelHandle(record){}
|
||||
Function(Ion::Storage::Record record) : ExpressionModelHandle(record){}
|
||||
|
||||
// Properties
|
||||
bool isActive() const;
|
||||
@@ -1,11 +1,11 @@
|
||||
#include "storage_function_app.h"
|
||||
#include "function_app.h"
|
||||
#include "../apps_container.h"
|
||||
|
||||
using namespace Poincare;
|
||||
|
||||
namespace Shared {
|
||||
|
||||
StorageFunctionApp::Snapshot::Snapshot() :
|
||||
FunctionApp::Snapshot::Snapshot() :
|
||||
m_cursor(),
|
||||
m_interval(),
|
||||
m_indexFunctionSelectedByCursor(0),
|
||||
@@ -18,7 +18,7 @@ StorageFunctionApp::Snapshot::Snapshot() :
|
||||
m_interval.setStep(1);
|
||||
}
|
||||
|
||||
void StorageFunctionApp::Snapshot::reset() {
|
||||
void FunctionApp::Snapshot::reset() {
|
||||
m_interval.setStart(0);
|
||||
m_interval.setEnd(10);
|
||||
m_interval.setStep(1);
|
||||
@@ -28,11 +28,11 @@ void StorageFunctionApp::Snapshot::reset() {
|
||||
setActiveTab(0);
|
||||
}
|
||||
|
||||
void StorageFunctionApp::Snapshot::storageDidChangeForRecord(const Ion::Storage::Record record) {
|
||||
void FunctionApp::Snapshot::storageDidChangeForRecord(const Ion::Storage::Record record) {
|
||||
functionStore()->storageDidChangeForRecord(record);
|
||||
}
|
||||
|
||||
void StorageFunctionApp::willBecomeInactive() {
|
||||
void FunctionApp::willBecomeInactive() {
|
||||
if (m_modalViewController.isDisplayingModal()) {
|
||||
m_modalViewController.dismissModalViewController();
|
||||
}
|
||||
@@ -42,7 +42,7 @@ void StorageFunctionApp::willBecomeInactive() {
|
||||
::App::willBecomeInactive();
|
||||
}
|
||||
|
||||
bool StorageFunctionApp::isAcceptableExpression(const Poincare::Expression expression) {
|
||||
bool FunctionApp::isAcceptableExpression(const Poincare::Expression expression) {
|
||||
if (!TextFieldDelegateApp::ExpressionCanBeSerialized(expression, false, Expression())) {
|
||||
return false;
|
||||
}
|
||||
@@ -10,7 +10,7 @@ class AppsContainer;
|
||||
|
||||
namespace Shared {
|
||||
|
||||
class StorageFunctionApp : public ExpressionFieldDelegateApp {
|
||||
class FunctionApp : public ExpressionFieldDelegateApp {
|
||||
public:
|
||||
class Snapshot : public ::App::Snapshot, public TabViewDataSource {
|
||||
public:
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
uint32_t * modelVersion() { return &m_modelVersion; }
|
||||
uint32_t * rangeVersion() { return &m_rangeVersion; }
|
||||
Poincare::Preferences::AngleUnit * angleUnitVersion() { return &m_angleUnitVersion; }
|
||||
virtual StorageFunctionStore * functionStore() = 0;
|
||||
virtual FunctionStore * functionStore() = 0;
|
||||
Interval * interval() { return &m_interval; }
|
||||
int * indexFunctionSelectedByCursor() { return &m_indexFunctionSelectedByCursor; }
|
||||
void reset() override;
|
||||
@@ -33,13 +33,13 @@ public:
|
||||
uint32_t m_rangeVersion;
|
||||
Poincare::Preferences::AngleUnit m_angleUnitVersion;
|
||||
};
|
||||
virtual ~StorageFunctionApp() = default;
|
||||
virtual StorageFunctionStore * functionStore() { return static_cast<StorageFunctionApp::Snapshot *>(snapshot())->functionStore(); }
|
||||
virtual ~FunctionApp() = default;
|
||||
virtual FunctionStore * functionStore() { return static_cast<FunctionApp::Snapshot *>(snapshot())->functionStore(); }
|
||||
virtual InputViewController * inputViewController() = 0;
|
||||
void willBecomeInactive() override;
|
||||
|
||||
protected:
|
||||
StorageFunctionApp(Container * container, Snapshot * snapshot, ViewController * rootViewController) :
|
||||
FunctionApp(Container * container, Snapshot * snapshot, ViewController * rootViewController) :
|
||||
ExpressionFieldDelegateApp(container, snapshot, rootViewController)
|
||||
{}
|
||||
// TextFieldDelegateApp
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "global_context.h"
|
||||
#include "storage_cartesian_function.h"
|
||||
#include "cartesian_function.h"
|
||||
#include <poincare/helpers.h>
|
||||
#include <poincare/undefined.h>
|
||||
#include <poincare/preferences.h>
|
||||
@@ -45,7 +45,7 @@ Poincare::Expression GlobalContext::ExpressionFromFunctionRecord(Ion::Storage::R
|
||||
}
|
||||
/* An function record value has metadata before the expression. To get the
|
||||
* expression, use the function record handle. */
|
||||
StorageCartesianFunction f = StorageCartesianFunction(record);
|
||||
CartesianFunction f = CartesianFunction(record);
|
||||
return f.expressionClone();
|
||||
}
|
||||
|
||||
@@ -116,13 +116,13 @@ Ion::Storage::Record::ErrorStatus GlobalContext::SetExpressionForFunctionRecord(
|
||||
if (!Ion::Storage::FullNameHasExtension(previousRecord.fullName(), Ion::Storage::funcExtension, strlen(Ion::Storage::funcExtension))) {
|
||||
// The previous record was not a function. Destroy it and create the new record.
|
||||
previousRecord.destroy();
|
||||
StorageCartesianFunction newModel = StorageCartesianFunction::NewModel(&error, baseName);
|
||||
CartesianFunction newModel = CartesianFunction::NewModel(&error, baseName);
|
||||
if (error != Ion::Storage::Record::ErrorStatus::None) {
|
||||
return error;
|
||||
}
|
||||
recordToSet = newModel;
|
||||
}
|
||||
error = StorageCartesianFunction(recordToSet).setExpressionContent(expressionToStore);
|
||||
error = CartesianFunction(recordToSet).setExpressionContent(expressionToStore);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#include "single_expression_model_handle.h"
|
||||
#include "global_context.h"
|
||||
#include "poincare_helpers.h"
|
||||
#include <poincare/horizontal_layout.h>
|
||||
#include <string.h>
|
||||
#include <cmath>
|
||||
#include <assert.h>
|
||||
|
||||
using namespace Ion;
|
||||
using namespace Poincare;
|
||||
|
||||
namespace Shared {
|
||||
|
||||
SingleExpressionModelHandle::SingleExpressionModelHandle(Storage::Record record) :
|
||||
Storage::Record(record)
|
||||
{
|
||||
}
|
||||
|
||||
bool SingleExpressionModelHandle::isDefined() {
|
||||
return !isEmpty();
|
||||
}
|
||||
|
||||
bool SingleExpressionModelHandle::isEmpty() {
|
||||
return value().size <= metaDataSize();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
#ifndef SHARED_SINGLE_EXPRESSION_MODEL_HANDLE_H
|
||||
#define SHARED_SINGLE_EXPRESSION_MODEL_HANDLE_H
|
||||
|
||||
#include "expression_model_handle.h"
|
||||
|
||||
namespace Shared {
|
||||
|
||||
|
||||
class SingleExpressionModelHandle : public Ion::Storage::Record {
|
||||
public:
|
||||
SingleExpressionModelHandle(Ion::Storage::Record record = Ion::Storage::Record());
|
||||
|
||||
// Property
|
||||
void text(char * buffer, size_t bufferSize) const { return handle()->text(this, buffer, bufferSize); }
|
||||
Poincare::Expression expressionReduced(Poincare::Context * context) const { return handle()->expressionReduced(this, context); }
|
||||
Poincare::Expression expressionClone() const { return handle()->expressionClone(this); }
|
||||
Poincare::Layout layout() { return handle()->layout(this); }
|
||||
/* TODO This comment will be true when Sequence inherits from this class
|
||||
* Here, isDefined is the exact contrary of isEmpty. However, for Sequence
|
||||
* inheriting from ExpressionModel, isEmpty and isDefined have not exactly
|
||||
* opposite meaning. For instance, u(n+1)=u(n) & u(0) = ... is not empty and
|
||||
* not defined. We thus have to keep both methods. */
|
||||
virtual bool isDefined();
|
||||
virtual bool isEmpty();
|
||||
virtual bool shouldBeClearedBeforeRemove() { return !isEmpty(); }
|
||||
/* tidy is responsible to tidy the whole model whereas tidyExpressionModel
|
||||
* tidies only the members associated with the ExpressionModel. In
|
||||
* ExpressionModelHandle, tidy and tidyExpressionModel trigger the same
|
||||
* behaviour but it is not true for its child classes (for example, in
|
||||
* Sequence). */
|
||||
virtual void tidy() { handle()->tidy(); }
|
||||
virtual Ion::Storage::Record::ErrorStatus setContent(const char * c) { return editableHandle()->setContent(this, c); }
|
||||
Ion::Storage::Record::ErrorStatus setExpressionContent(Poincare::Expression & e) { return editableHandle()->setExpressionContent(this, e); }
|
||||
protected:
|
||||
bool isCircularlyDefined(Poincare::Context * context) const { return handle()->isCircularlyDefined(this, context); }
|
||||
ExpressionModelHandle * editableHandle() { return const_cast<ExpressionModelHandle *>(handle()); }
|
||||
virtual const ExpressionModelHandle * handle() const = 0;
|
||||
virtual size_t metaDataSize() const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -145,7 +145,7 @@ KDCoordinate StorageExpressionModelListController::expressionRowHeight(int j) {
|
||||
if (isAddEmptyRow(j)) {
|
||||
return Metric::StoreRowHeight;
|
||||
}
|
||||
ExpiringPointer<SingleExpressionModelHandle> m = modelStore()->modelForRecord(modelStore()->recordAtIndex(j));
|
||||
ExpiringPointer<ExpressionModelHandle> m = modelStore()->modelForRecord(modelStore()->recordAtIndex(j));
|
||||
if (m->layout().isUninitialized()) {
|
||||
return Metric::StoreRowHeight;
|
||||
}
|
||||
@@ -156,7 +156,7 @@ KDCoordinate StorageExpressionModelListController::expressionRowHeight(int j) {
|
||||
|
||||
void StorageExpressionModelListController::willDisplayExpressionCellAtIndex(HighlightCell * cell, int j) {
|
||||
EvenOddExpressionCell * myCell = (EvenOddExpressionCell *)cell;
|
||||
ExpiringPointer<SingleExpressionModelHandle> m = modelStore()->modelForRecord(modelStore()->recordAtIndex(j));
|
||||
ExpiringPointer<ExpressionModelHandle> m = modelStore()->modelForRecord(modelStore()->recordAtIndex(j));
|
||||
myCell->setLayout(m->layout());
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ bool StorageExpressionModelListController::handleEventOnExpression(Ion::Events::
|
||||
}
|
||||
if (event == Ion::Events::Backspace && !isAddEmptyRow(selectedRow())) {
|
||||
Ion::Storage::Record record = modelStore()->recordAtIndex(modelIndexForRow(selectedRow()));
|
||||
ExpiringPointer<SingleExpressionModelHandle> model = modelStore()->modelForRecord(record);
|
||||
ExpiringPointer<ExpressionModelHandle> model = modelStore()->modelForRecord(record);
|
||||
if (model->shouldBeClearedBeforeRemove()) {
|
||||
reinitSelectedExpression(model);
|
||||
} else {
|
||||
@@ -206,7 +206,7 @@ void StorageExpressionModelListController::addEmptyModel() {
|
||||
editExpression(Ion::Events::OK);
|
||||
}
|
||||
|
||||
void StorageExpressionModelListController::reinitSelectedExpression(ExpiringPointer<SingleExpressionModelHandle> model) {
|
||||
void StorageExpressionModelListController::reinitSelectedExpression(ExpiringPointer<ExpressionModelHandle> model) {
|
||||
model->setContent("");
|
||||
// Reset memoization of the selected cell which always corresponds to the k_memoizedCellsCount/2 memoized cell
|
||||
resetMemoizationForIndex(k_memoizedCellsCount/2);
|
||||
@@ -230,7 +230,7 @@ void StorageExpressionModelListController::editExpression(Ion::Events::Event eve
|
||||
char initialTextContent[initialTextContentMaxSize];
|
||||
if (event == Ion::Events::OK || event == Ion::Events::EXE) {
|
||||
Ion::Storage::Record record = modelStore()->recordAtIndex(modelIndexForRow(selectedRow()));
|
||||
ExpiringPointer<SingleExpressionModelHandle> model = modelStore()->modelForRecord(record);
|
||||
ExpiringPointer<ExpressionModelHandle> model = modelStore()->modelForRecord(record);
|
||||
model->text(initialTextContent, initialTextContentMaxSize);
|
||||
initialText = initialTextContent;
|
||||
// Replace Poincare::Symbol::SpecialSymbols::UnknownX with 'x'
|
||||
@@ -252,7 +252,7 @@ bool StorageExpressionModelListController::editSelectedRecordWithText(const char
|
||||
// Reset memoization of the selected cell which always corresponds to the k_memoizedCellsCount/2 memoized cell
|
||||
resetMemoizationForIndex(k_memoizedCellsCount/2);
|
||||
Ion::Storage::Record record = modelStore()->recordAtIndex(modelIndexForRow(selectedRow()));
|
||||
ExpiringPointer<SingleExpressionModelHandle> model = modelStore()->modelForRecord(record);
|
||||
ExpiringPointer<ExpressionModelHandle> model = modelStore()->modelForRecord(record);
|
||||
return (model->setContent(text) == Ion::Storage::Record::ErrorStatus::None);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ protected:
|
||||
bool handleEventOnExpression(Ion::Events::Event event);
|
||||
virtual void addEmptyModel();
|
||||
virtual void didChangeModelsList() { resetMemoization(); }
|
||||
virtual void reinitSelectedExpression(ExpiringPointer<SingleExpressionModelHandle> model);
|
||||
virtual void reinitSelectedExpression(ExpiringPointer<ExpressionModelHandle> model);
|
||||
virtual void editExpression(Ion::Events::Event event);
|
||||
void replaceUnknownSymbolWithReadableSymbol(char * initialText);
|
||||
virtual bool editSelectedRecordWithText(const char * text);
|
||||
|
||||
@@ -15,14 +15,14 @@ Ion::Storage::Record StorageExpressionModelStore::recordAtIndex(int i) const {
|
||||
return Ion::Storage::sharedStorage()->recordWithExtensionAtIndex(modelExtension(), i);
|
||||
}
|
||||
|
||||
SingleExpressionModelHandle * StorageExpressionModelStore::privateModelForRecord(Ion::Storage::Record record) const {
|
||||
ExpressionModelHandle * StorageExpressionModelStore::privateModelForRecord(Ion::Storage::Record record) const {
|
||||
for (int i = 0; i < maxNumberOfMemoizedModels(); i++) {
|
||||
if (!memoizedModelAtIndex(i)->isNull() && *memoizedModelAtIndex(i) == record) {
|
||||
return memoizedModelAtIndex(i);
|
||||
}
|
||||
}
|
||||
setMemoizedModelAtIndex(m_oldestMemoizedIndex, record);
|
||||
SingleExpressionModelHandle * result = memoizedModelAtIndex(m_oldestMemoizedIndex);
|
||||
ExpressionModelHandle * result = memoizedModelAtIndex(m_oldestMemoizedIndex);
|
||||
m_oldestMemoizedIndex = (m_oldestMemoizedIndex+1) % maxNumberOfMemoizedModels();
|
||||
return result;
|
||||
}
|
||||
@@ -44,7 +44,7 @@ void StorageExpressionModelStore::tidy() {
|
||||
int StorageExpressionModelStore::numberOfModelsSatisfyingTest(ModelTest test) const {
|
||||
int result = 0;
|
||||
int i = 0;
|
||||
SingleExpressionModelHandle * m = privateModelForRecord(recordAtIndex(i++));
|
||||
ExpressionModelHandle * m = privateModelForRecord(recordAtIndex(i++));
|
||||
while (!m->isNull()) {
|
||||
if (test(m)) {
|
||||
result++;
|
||||
@@ -59,7 +59,7 @@ Ion::Storage::Record StorageExpressionModelStore::recordStatifyingTestAtIndex(in
|
||||
int index = 0;
|
||||
int currentModelIndex = 0;
|
||||
Ion::Storage::Record r = recordAtIndex(currentModelIndex++);
|
||||
SingleExpressionModelHandle * m = privateModelForRecord(r);
|
||||
ExpressionModelHandle * m = privateModelForRecord(r);
|
||||
while (!m->isNull()) {
|
||||
assert(currentModelIndex <= numberOfModels());
|
||||
if (test(m)) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef SHARED_STORAGE_EXPRESSION_MODEL_STORE_H
|
||||
#define SHARED_STORAGE_EXPRESSION_MODEL_STORE_H
|
||||
|
||||
#include "single_expression_model_handle.h"
|
||||
#include "expression_model_handle.h"
|
||||
#include "expiring_pointer.h"
|
||||
#include <ion/storage.h>
|
||||
#include <assert.h>
|
||||
@@ -21,10 +21,10 @@ public:
|
||||
// By default, the number of models is not bounded
|
||||
virtual int maxNumberOfModels() const { return -1; }
|
||||
int numberOfModels() const;
|
||||
int numberOfDefinedModels() const { return numberOfModelsSatisfyingTest([](SingleExpressionModelHandle * m) { return m->isDefined(); }); }
|
||||
int numberOfDefinedModels() const { return numberOfModelsSatisfyingTest([](ExpressionModelHandle * m) { return m->isDefined(); }); }
|
||||
Ion::Storage::Record recordAtIndex(int i) const;
|
||||
Ion::Storage::Record definedRecordAtIndex(int i) const { return recordStatifyingTestAtIndex(i, [](SingleExpressionModelHandle * m) { return m->isDefined(); }); }
|
||||
ExpiringPointer<SingleExpressionModelHandle> modelForRecord(Ion::Storage::Record record) const { return ExpiringPointer<SingleExpressionModelHandle>(privateModelForRecord(record)); }
|
||||
Ion::Storage::Record definedRecordAtIndex(int i) const { return recordStatifyingTestAtIndex(i, [](ExpressionModelHandle * m) { return m->isDefined(); }); }
|
||||
ExpiringPointer<ExpressionModelHandle> modelForRecord(Ion::Storage::Record record) const { return ExpiringPointer<ExpressionModelHandle>(privateModelForRecord(record)); }
|
||||
|
||||
// Add and Remove
|
||||
virtual Ion::Storage::Record::ErrorStatus addEmptyModel() = 0;
|
||||
@@ -37,14 +37,14 @@ public:
|
||||
protected:
|
||||
constexpr static int k_maxNumberOfMemoizedModels = 10;
|
||||
int maxNumberOfMemoizedModels() const { return maxNumberOfModels() < 0 ? k_maxNumberOfMemoizedModels : maxNumberOfModels(); }
|
||||
typedef bool (*ModelTest)(SingleExpressionModelHandle * model);
|
||||
typedef bool (*ModelTest)(ExpressionModelHandle * model);
|
||||
int numberOfModelsSatisfyingTest(ModelTest test) const;
|
||||
Ion::Storage::Record recordStatifyingTestAtIndex(int i, ModelTest test) const;
|
||||
SingleExpressionModelHandle * privateModelForRecord(Ion::Storage::Record record) const;
|
||||
ExpressionModelHandle * privateModelForRecord(Ion::Storage::Record record) const;
|
||||
private:
|
||||
void resetMemoizedModelsExceptRecord(const Ion::Storage::Record record = Ion::Storage::Record()) const;
|
||||
virtual void setMemoizedModelAtIndex(int cacheIndex, Ion::Storage::Record) const = 0;
|
||||
virtual SingleExpressionModelHandle * memoizedModelAtIndex(int cacheIndex) const = 0;
|
||||
virtual ExpressionModelHandle * memoizedModelAtIndex(int cacheIndex) const = 0;
|
||||
virtual const char * modelExtension() const = 0;
|
||||
/* Memoization of k_maxNumberOfMemoizedModels. When the required model is not
|
||||
* present, we override the m_oldestMemoizedIndex model. This actually
|
||||
|
||||
@@ -6,8 +6,8 @@ using namespace Poincare;
|
||||
|
||||
namespace Shared {
|
||||
|
||||
void StorageFunctionBannerDelegate::reloadBannerViewForCursorOnFunction(CurveViewCursor * cursor, Ion::Storage::Record record, StorageFunctionStore * functionStore, char symbol) {
|
||||
ExpiringPointer<StorageFunction> function = functionStore->modelForRecord(record);
|
||||
void FunctionBannerDelegate::reloadBannerViewForCursorOnFunction(CurveViewCursor * cursor, Ion::Storage::Record record, FunctionStore * functionStore, char symbol) {
|
||||
ExpiringPointer<Function> function = functionStore->modelForRecord(record);
|
||||
constexpr int bufferSize = k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits);
|
||||
char buffer[bufferSize];
|
||||
const char * space = " ";
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
|
||||
namespace Shared {
|
||||
|
||||
class StorageFunctionBannerDelegate {
|
||||
class FunctionBannerDelegate {
|
||||
public:
|
||||
constexpr static int k_maxNumberOfCharacters = 50;
|
||||
protected:
|
||||
void reloadBannerViewForCursorOnFunction(CurveViewCursor * cursor, Ion::Storage::Record record, StorageFunctionStore * functionStore, char symbol);
|
||||
void reloadBannerViewForCursorOnFunction(CurveViewCursor * cursor, Ion::Storage::Record record, FunctionStore * functionStore, char symbol);
|
||||
virtual BannerView * bannerView() = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
namespace Shared {
|
||||
|
||||
StorageFunctionCurveParameterController::StorageFunctionCurveParameterController(InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor) :
|
||||
FunctionCurveParameterController::FunctionCurveParameterController(InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor) :
|
||||
ViewController(nullptr),
|
||||
m_goToCell(I18n::Message::Goto),
|
||||
m_selectableTableView(this, this, this),
|
||||
@@ -11,18 +11,18 @@ StorageFunctionCurveParameterController::StorageFunctionCurveParameterController
|
||||
{
|
||||
}
|
||||
|
||||
View * StorageFunctionCurveParameterController::view() {
|
||||
View * FunctionCurveParameterController::view() {
|
||||
return &m_selectableTableView;
|
||||
}
|
||||
|
||||
void StorageFunctionCurveParameterController::didBecomeFirstResponder() {
|
||||
void FunctionCurveParameterController::didBecomeFirstResponder() {
|
||||
if (selectedRow() < 0) {
|
||||
selectCellAtLocation(0, 0);
|
||||
}
|
||||
app()->setFirstResponder(&m_selectableTableView);
|
||||
}
|
||||
|
||||
bool StorageFunctionCurveParameterController::handleGotoSelection() {
|
||||
bool FunctionCurveParameterController::handleGotoSelection() {
|
||||
if (m_record.isNull()) {
|
||||
return false;
|
||||
}
|
||||
@@ -32,11 +32,11 @@ bool StorageFunctionCurveParameterController::handleGotoSelection() {
|
||||
return true;
|
||||
}
|
||||
|
||||
KDCoordinate StorageFunctionCurveParameterController::cellHeight() {
|
||||
KDCoordinate FunctionCurveParameterController::cellHeight() {
|
||||
return Metric::ParameterCellHeight;
|
||||
}
|
||||
|
||||
void StorageFunctionCurveParameterController::setRecord(Ion::Storage::Record record) {
|
||||
void FunctionCurveParameterController::setRecord(Ion::Storage::Record record) {
|
||||
m_record = record;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||
namespace Shared {
|
||||
|
||||
class StorageFunctionCurveParameterController : public ViewController, public SimpleListViewDataSource, public SelectableTableViewDataSource {
|
||||
class FunctionCurveParameterController : public ViewController, public SimpleListViewDataSource, public SelectableTableViewDataSource {
|
||||
public:
|
||||
StorageFunctionCurveParameterController(InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor);
|
||||
FunctionCurveParameterController(InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor);
|
||||
View * view() override;
|
||||
void didBecomeFirstResponder() override;
|
||||
KDCoordinate cellHeight() override;
|
||||
@@ -21,7 +21,7 @@ protected:
|
||||
SelectableTableView m_selectableTableView;
|
||||
Ion::Storage::Record m_record;
|
||||
private:
|
||||
virtual StorageFunctionGoToParameterController * goToParameterController() = 0;
|
||||
virtual FunctionGoToParameterController * goToParameterController() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
#include "storage_function_go_to_parameter_controller.h"
|
||||
#include "storage_function_app.h"
|
||||
#include "function_app.h"
|
||||
#include <assert.h>
|
||||
#include <cmath>
|
||||
|
||||
namespace Shared {
|
||||
|
||||
StorageFunctionGoToParameterController::StorageFunctionGoToParameterController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor, I18n::Message symbol) :
|
||||
FunctionGoToParameterController::FunctionGoToParameterController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor, I18n::Message symbol) :
|
||||
GoToParameterController(parentResponder, inputEventHandlerDelegate, graphRange, cursor, symbol),
|
||||
m_record()
|
||||
{
|
||||
}
|
||||
|
||||
const char * StorageFunctionGoToParameterController::title() {
|
||||
const char * FunctionGoToParameterController::title() {
|
||||
return I18n::translate(I18n::Message::Goto);
|
||||
}
|
||||
|
||||
double StorageFunctionGoToParameterController::parameterAtIndex(int index) {
|
||||
double FunctionGoToParameterController::parameterAtIndex(int index) {
|
||||
assert(index == 0);
|
||||
return m_cursor->x();
|
||||
}
|
||||
|
||||
bool StorageFunctionGoToParameterController::setParameterAtIndex(int parameterIndex, double f) {
|
||||
bool FunctionGoToParameterController::setParameterAtIndex(int parameterIndex, double f) {
|
||||
assert(parameterIndex == 0);
|
||||
StorageFunctionApp * myApp = (StorageFunctionApp *)app();
|
||||
ExpiringPointer<StorageFunction> function = myApp->functionStore()->modelForRecord(m_record);
|
||||
FunctionApp * myApp = (FunctionApp *)app();
|
||||
ExpiringPointer<Function> function = myApp->functionStore()->modelForRecord(m_record);
|
||||
float y = function->evaluateAtAbscissa(f, myApp->localContext());
|
||||
if (std::fabs(f) > k_maxDisplayableFloat || std::fabs(y) > k_maxDisplayableFloat) {
|
||||
app()->displayWarning(I18n::Message::ForbiddenValue);
|
||||
@@ -39,7 +39,7 @@ bool StorageFunctionGoToParameterController::setParameterAtIndex(int parameterIn
|
||||
return true;
|
||||
}
|
||||
|
||||
void StorageFunctionGoToParameterController::setRecord(Ion::Storage::Record record) {
|
||||
void FunctionGoToParameterController::setRecord(Ion::Storage::Record record) {
|
||||
m_record = record;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
#define SHARED_STORAGE_FUNCTION_GO_TO_PARAMETER_CONTROLLER_H
|
||||
|
||||
#include "go_to_parameter_controller.h"
|
||||
#include "storage_function.h"
|
||||
#include "function.h"
|
||||
|
||||
namespace Shared {
|
||||
|
||||
class StorageFunctionGoToParameterController : public GoToParameterController {
|
||||
class FunctionGoToParameterController : public GoToParameterController {
|
||||
public:
|
||||
StorageFunctionGoToParameterController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor, I18n::Message symbol);
|
||||
FunctionGoToParameterController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor, I18n::Message symbol);
|
||||
const char * title() override;
|
||||
void setRecord(Ion::Storage::Record record);
|
||||
protected:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "storage_function_graph_controller.h"
|
||||
#include "storage_function_app.h"
|
||||
#include "function_app.h"
|
||||
#include <assert.h>
|
||||
#include <cmath>
|
||||
#include <float.h>
|
||||
@@ -8,7 +8,7 @@ using namespace Poincare;
|
||||
|
||||
namespace Shared {
|
||||
|
||||
StorageFunctionGraphController::StorageFunctionGraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, ButtonRowController * header, InteractiveCurveViewRange * interactiveRange, CurveView * curveView, CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * rangeVersion, Preferences::AngleUnit * angleUnitVersion) :
|
||||
FunctionGraphController::FunctionGraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, ButtonRowController * header, InteractiveCurveViewRange * interactiveRange, CurveView * curveView, CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * rangeVersion, Preferences::AngleUnit * angleUnitVersion) :
|
||||
InteractiveCurveViewController(parentResponder, inputEventHandlerDelegate, header, interactiveRange, curveView, cursor, modelVersion, rangeVersion),
|
||||
m_initialisationParameterController(this, interactiveRange),
|
||||
m_angleUnitVersion(angleUnitVersion),
|
||||
@@ -16,24 +16,24 @@ StorageFunctionGraphController::StorageFunctionGraphController(Responder * paren
|
||||
{
|
||||
}
|
||||
|
||||
bool StorageFunctionGraphController::isEmpty() const {
|
||||
bool FunctionGraphController::isEmpty() const {
|
||||
if (functionStore()->numberOfActiveFunctions() == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ViewController * StorageFunctionGraphController::initialisationParameterController() {
|
||||
ViewController * FunctionGraphController::initialisationParameterController() {
|
||||
return &m_initialisationParameterController;
|
||||
}
|
||||
|
||||
void StorageFunctionGraphController::viewWillAppear() {
|
||||
void FunctionGraphController::viewWillAppear() {
|
||||
functionGraphView()->setCursorView(cursorView());
|
||||
functionGraphView()->setBannerView(bannerView());
|
||||
functionGraphView()->setAreaHighlight(NAN,NAN);
|
||||
|
||||
if (functionGraphView()->context() == nullptr) {
|
||||
StorageFunctionApp * myApp = static_cast<StorageFunctionApp *>(app());
|
||||
FunctionApp * myApp = static_cast<FunctionApp *>(app());
|
||||
functionGraphView()->setContext(myApp->localContext());
|
||||
}
|
||||
Preferences::AngleUnit newAngleUnitVersion = Preferences::sharedPreferences()->angleUnit();
|
||||
@@ -44,7 +44,7 @@ void StorageFunctionGraphController::viewWillAppear() {
|
||||
InteractiveCurveViewController::viewWillAppear();
|
||||
}
|
||||
|
||||
bool StorageFunctionGraphController::handleEnter() {
|
||||
bool FunctionGraphController::handleEnter() {
|
||||
Ion::Storage::Record record = functionStore()->activeRecordAtIndex(indexFunctionSelectedByCursor());
|
||||
curveParameterController()->setRecord(record);
|
||||
StackViewController * stack = stackController();
|
||||
@@ -52,15 +52,15 @@ bool StorageFunctionGraphController::handleEnter() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void StorageFunctionGraphController::selectFunctionWithCursor(int functionIndex) {
|
||||
void FunctionGraphController::selectFunctionWithCursor(int functionIndex) {
|
||||
*m_indexFunctionSelectedByCursor = functionIndex;
|
||||
}
|
||||
|
||||
float StorageFunctionGraphController::cursorBottomMarginRatio() {
|
||||
float FunctionGraphController::cursorBottomMarginRatio() {
|
||||
return (cursorView()->minimalSizeForOptimalDisplay().height()/2+estimatedBannerHeight())/k_viewHeight;
|
||||
}
|
||||
|
||||
void StorageFunctionGraphController::reloadBannerView() {
|
||||
void FunctionGraphController::reloadBannerView() {
|
||||
if (functionStore()->numberOfActiveFunctions() == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -68,16 +68,16 @@ void StorageFunctionGraphController::reloadBannerView() {
|
||||
reloadBannerViewForCursorOnFunction(m_cursor, record, functionStore(), functionStore()->symbol());
|
||||
}
|
||||
|
||||
float StorageFunctionGraphController::displayBottomMarginRatio() {
|
||||
float FunctionGraphController::displayBottomMarginRatio() {
|
||||
return (cursorView()->minimalSizeForOptimalDisplay().height() + 2 + estimatedBannerHeight()) / k_viewHeight;
|
||||
}
|
||||
|
||||
float StorageFunctionGraphController::estimatedBannerHeight() const {
|
||||
float FunctionGraphController::estimatedBannerHeight() const {
|
||||
return BannerView::HeightGivenNumberOfLines(estimatedBannerNumberOfLines());
|
||||
}
|
||||
|
||||
InteractiveCurveViewRangeDelegate::Range StorageFunctionGraphController::computeYRange(InteractiveCurveViewRange * interactiveCurveViewRange) {
|
||||
StorageFunctionApp * myApp = static_cast<StorageFunctionApp *>(app());
|
||||
InteractiveCurveViewRangeDelegate::Range FunctionGraphController::computeYRange(InteractiveCurveViewRange * interactiveCurveViewRange) {
|
||||
FunctionApp * myApp = static_cast<FunctionApp *>(app());
|
||||
float min = FLT_MAX;
|
||||
float max = -FLT_MAX;
|
||||
float xMin = interactiveCurveViewRange->xMin();
|
||||
@@ -89,7 +89,7 @@ InteractiveCurveViewRangeDelegate::Range StorageFunctionGraphController::compute
|
||||
return range;
|
||||
}
|
||||
for (int i=0; i<functionStore()->numberOfActiveFunctions(); i++) {
|
||||
ExpiringPointer<StorageFunction> f = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(i));
|
||||
ExpiringPointer<Function> f = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(i));
|
||||
float y = 0.0f;
|
||||
float res = curveView()->resolution();
|
||||
/* Scan x-range from the middle to the extrema in order to get balanced
|
||||
@@ -109,28 +109,28 @@ InteractiveCurveViewRangeDelegate::Range StorageFunctionGraphController::compute
|
||||
return range;
|
||||
}
|
||||
|
||||
void StorageFunctionGraphController::initRangeParameters() {
|
||||
void FunctionGraphController::initRangeParameters() {
|
||||
interactiveCurveViewRange()->setDefault();
|
||||
initCursorParameters();
|
||||
selectFunctionWithCursor(0);
|
||||
}
|
||||
|
||||
double StorageFunctionGraphController::defaultCursorAbscissa() {
|
||||
double FunctionGraphController::defaultCursorAbscissa() {
|
||||
return (interactiveCurveViewRange()->xMin()+interactiveCurveViewRange()->xMax())/2.0f;
|
||||
}
|
||||
|
||||
StorageFunctionStore * StorageFunctionGraphController::functionStore() const {
|
||||
StorageFunctionApp * myApp = static_cast<StorageFunctionApp *>(app());
|
||||
FunctionStore * FunctionGraphController::functionStore() const {
|
||||
FunctionApp * myApp = static_cast<FunctionApp *>(app());
|
||||
return myApp->functionStore();
|
||||
}
|
||||
|
||||
void StorageFunctionGraphController::initCursorParameters() {
|
||||
void FunctionGraphController::initCursorParameters() {
|
||||
double x = defaultCursorAbscissa();
|
||||
StorageFunctionApp * myApp = static_cast<StorageFunctionApp *>(app());
|
||||
FunctionApp * myApp = static_cast<FunctionApp *>(app());
|
||||
int functionIndex = 0;
|
||||
double y = 0;
|
||||
do {
|
||||
ExpiringPointer<StorageFunction> firstFunction = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(functionIndex++));
|
||||
ExpiringPointer<Function> firstFunction = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(functionIndex++));
|
||||
y = firstFunction->evaluateAtAbscissa(x, myApp->localContext());
|
||||
} while ((std::isnan(y) || std::isinf(y)) && functionIndex < functionStore()->numberOfActiveFunctions());
|
||||
m_cursor->moveTo(x, y);
|
||||
@@ -141,9 +141,9 @@ void StorageFunctionGraphController::initCursorParameters() {
|
||||
}
|
||||
}
|
||||
|
||||
bool StorageFunctionGraphController::moveCursorVertically(int direction) {
|
||||
bool FunctionGraphController::moveCursorVertically(int direction) {
|
||||
int currentActiveFunctionIndex = indexFunctionSelectedByCursor();
|
||||
Poincare::Context * context = static_cast<StorageFunctionApp *>(app())->localContext();
|
||||
Poincare::Context * context = static_cast<FunctionApp *>(app())->localContext();
|
||||
|
||||
int nextActiveFunctionIndex = InteractiveCurveViewController::closestCurveIndexVertically(direction > 0, currentActiveFunctionIndex, context);
|
||||
if (nextActiveFunctionIndex < 0) {
|
||||
@@ -155,31 +155,31 @@ bool StorageFunctionGraphController::moveCursorVertically(int direction) {
|
||||
return true;
|
||||
}
|
||||
|
||||
CurveView * StorageFunctionGraphController::curveView() {
|
||||
CurveView * FunctionGraphController::curveView() {
|
||||
return functionGraphView();
|
||||
}
|
||||
|
||||
uint32_t StorageFunctionGraphController::modelVersion() {
|
||||
uint32_t FunctionGraphController::modelVersion() {
|
||||
return functionStore()->storeChecksum();
|
||||
}
|
||||
|
||||
uint32_t StorageFunctionGraphController::rangeVersion() {
|
||||
uint32_t FunctionGraphController::rangeVersion() {
|
||||
return interactiveCurveViewRange()->rangeChecksum();
|
||||
}
|
||||
|
||||
bool StorageFunctionGraphController::isCursorVisible() {
|
||||
bool FunctionGraphController::isCursorVisible() {
|
||||
return interactiveCurveViewRange()->isCursorVisible(cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio);
|
||||
}
|
||||
|
||||
bool StorageFunctionGraphController::closestCurveIndexIsSuitable(int newIndex, int currentIndex) const {
|
||||
bool FunctionGraphController::closestCurveIndexIsSuitable(int newIndex, int currentIndex) const {
|
||||
return newIndex != currentIndex;
|
||||
}
|
||||
|
||||
double StorageFunctionGraphController::yValue(int curveIndex, double x, Poincare::Context * context) const {
|
||||
double FunctionGraphController::yValue(int curveIndex, double x, Poincare::Context * context) const {
|
||||
return functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(curveIndex))->evaluateAtAbscissa(x, context);
|
||||
}
|
||||
|
||||
int StorageFunctionGraphController::numberOfCurves() const {
|
||||
int FunctionGraphController::numberOfCurves() const {
|
||||
return functionStore()->numberOfActiveFunctions();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
|
||||
namespace Shared {
|
||||
|
||||
class StorageFunctionGraphController : public InteractiveCurveViewController, public StorageFunctionBannerDelegate {
|
||||
class FunctionGraphController : public InteractiveCurveViewController, public FunctionBannerDelegate {
|
||||
public:
|
||||
StorageFunctionGraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, ButtonRowController * header, InteractiveCurveViewRange * interactiveRange, CurveView * curveView, CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * rangeVersion, Poincare::Preferences::AngleUnit * angleUnitVersion);
|
||||
FunctionGraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, ButtonRowController * header, InteractiveCurveViewRange * interactiveRange, CurveView * curveView, CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * rangeVersion, Poincare::Preferences::AngleUnit * angleUnitVersion);
|
||||
bool isEmpty() const override;
|
||||
ViewController * initialisationParameterController() override;
|
||||
void viewWillAppear() override;
|
||||
@@ -26,14 +26,14 @@ protected:
|
||||
int indexFunctionSelectedByCursor() const { return *m_indexFunctionSelectedByCursor; }
|
||||
virtual void selectFunctionWithCursor(int functionIndex);
|
||||
virtual double defaultCursorAbscissa();
|
||||
virtual StorageFunctionStore * functionStore() const;
|
||||
virtual FunctionStore * functionStore() const;
|
||||
|
||||
private:
|
||||
constexpr static float k_viewHeight = 174.0f; // TODO Taken from Regresssion/graph_controller. Maybe we should compute and/or put in common ?
|
||||
|
||||
virtual StorageFunctionGraphView * functionGraphView() = 0;
|
||||
virtual FunctionGraphView * functionGraphView() = 0;
|
||||
virtual View * cursorView() = 0;
|
||||
virtual StorageFunctionCurveParameterController * curveParameterController() = 0;
|
||||
virtual FunctionCurveParameterController * curveParameterController() = 0;
|
||||
|
||||
// InteractiveCurveViewController
|
||||
/* When y auto is ticked, we use a display margin to be ensure that the user
|
||||
|
||||
@@ -6,7 +6,7 @@ using namespace Poincare;
|
||||
|
||||
namespace Shared {
|
||||
|
||||
StorageFunctionGraphView::StorageFunctionGraphView(InteractiveCurveViewRange * graphRange,
|
||||
FunctionGraphView::FunctionGraphView(InteractiveCurveViewRange * graphRange,
|
||||
CurveViewCursor * cursor, BannerView * bannerView, View * cursorView) :
|
||||
CurveView(graphRange, cursor, bannerView, cursorView),
|
||||
m_selectedRecord(),
|
||||
@@ -19,29 +19,29 @@ StorageFunctionGraphView::StorageFunctionGraphView(InteractiveCurveViewRange * g
|
||||
{
|
||||
}
|
||||
|
||||
void StorageFunctionGraphView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
void FunctionGraphView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
ctx->fillRect(rect, KDColorWhite);
|
||||
drawGrid(ctx, rect);
|
||||
drawAxes(ctx, rect);
|
||||
simpleDrawBothAxesLabels(ctx, rect);
|
||||
}
|
||||
|
||||
void StorageFunctionGraphView::setContext(Context * context) {
|
||||
void FunctionGraphView::setContext(Context * context) {
|
||||
m_context = context;
|
||||
}
|
||||
|
||||
Context * StorageFunctionGraphView::context() const {
|
||||
Context * FunctionGraphView::context() const {
|
||||
return m_context;
|
||||
}
|
||||
|
||||
void StorageFunctionGraphView::selectRecord(Ion::Storage::Record record) {
|
||||
void FunctionGraphView::selectRecord(Ion::Storage::Record record) {
|
||||
if (m_selectedRecord != record) {
|
||||
m_selectedRecord = record;
|
||||
reloadBetweenBounds(m_highlightedStart, m_highlightedEnd);
|
||||
}
|
||||
}
|
||||
|
||||
void StorageFunctionGraphView::setAreaHighlight(float start, float end) {
|
||||
void FunctionGraphView::setAreaHighlight(float start, float end) {
|
||||
if (m_highlightedStart != start || m_highlightedEnd != end) {
|
||||
float dirtyStart = start > m_highlightedStart ? m_highlightedStart : start;
|
||||
float dirtyEnd = start > m_highlightedStart ? start : m_highlightedStart;
|
||||
@@ -60,18 +60,18 @@ void StorageFunctionGraphView::setAreaHighlight(float start, float end) {
|
||||
}
|
||||
}
|
||||
|
||||
void StorageFunctionGraphView::setAreaHighlightColor(bool highlightColor) {
|
||||
void FunctionGraphView::setAreaHighlightColor(bool highlightColor) {
|
||||
if (m_shouldColorHighlighted != highlightColor) {
|
||||
reloadBetweenBounds(m_highlightedStart, m_highlightedEnd);
|
||||
m_shouldColorHighlighted = highlightColor;
|
||||
}
|
||||
}
|
||||
|
||||
char * StorageFunctionGraphView::label(Axis axis, int index) const {
|
||||
char * FunctionGraphView::label(Axis axis, int index) const {
|
||||
return (axis == Axis::Horizontal ? (char *)m_xLabels[index] : (char *)m_yLabels[index]);
|
||||
}
|
||||
|
||||
void StorageFunctionGraphView::reloadBetweenBounds(float start, float end) {
|
||||
void FunctionGraphView::reloadBetweenBounds(float start, float end) {
|
||||
if (start == end) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
|
||||
#include <escher.h>
|
||||
#include "curve_view.h"
|
||||
#include "storage_function.h"
|
||||
#include "function.h"
|
||||
#include "../constant.h"
|
||||
#include "interactive_curve_view_range.h"
|
||||
|
||||
namespace Shared {
|
||||
|
||||
class StorageFunctionGraphView : public CurveView {
|
||||
class FunctionGraphView : public CurveView {
|
||||
public:
|
||||
StorageFunctionGraphView(InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor,
|
||||
FunctionGraphView(InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor,
|
||||
BannerView * bannerView, View * cursorView);
|
||||
void drawRect(KDContext * ctx, KDRect rect) const override;
|
||||
void setContext(Poincare::Context * context);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "storage_function_list_controller.h"
|
||||
#include "storage_function_app.h"
|
||||
#include "function_app.h"
|
||||
#include "function_expression_cell.h"
|
||||
|
||||
namespace Shared {
|
||||
@@ -7,19 +7,19 @@ namespace Shared {
|
||||
static inline int maxInt(int x, int y) { return x > y ? x : y; }
|
||||
static inline int minInt(int x, int y) { return x < y ? x : y; }
|
||||
|
||||
StorageFunctionListController::StorageFunctionListController(Responder * parentResponder, ButtonRowController * header, ButtonRowController * footer, I18n::Message text) :
|
||||
FunctionListController::FunctionListController(Responder * parentResponder, ButtonRowController * header, ButtonRowController * footer, I18n::Message text) :
|
||||
StorageExpressionModelListController(parentResponder, text),
|
||||
ButtonRowDelegate(header, footer),
|
||||
m_selectableTableView(this, this, this, this),
|
||||
m_emptyCell(),
|
||||
m_plotButton(this, I18n::Message::Plot, Invocation([](void * context, void * sender) {
|
||||
StorageFunctionListController * list = (StorageFunctionListController *)context;
|
||||
FunctionListController * list = (FunctionListController *)context;
|
||||
TabViewController * tabController = list->tabController();
|
||||
tabController->setActiveTab(1);
|
||||
return true;
|
||||
}, this), KDFont::SmallFont, Palette::PurpleBright),
|
||||
m_valuesButton(this, I18n::Message::DisplayValues, Invocation([](void * context, void * sender) {
|
||||
StorageFunctionListController * list = (StorageFunctionListController *)context;
|
||||
FunctionListController * list = (FunctionListController *)context;
|
||||
TabViewController * tabController = list->tabController();
|
||||
tabController->setActiveTab(2);
|
||||
return true;
|
||||
@@ -38,11 +38,11 @@ StorageFunctionListController::StorageFunctionListController(Responder * parentR
|
||||
|
||||
/* TableViewDataSource */
|
||||
|
||||
void StorageFunctionListController::viewWillAppear() {
|
||||
void FunctionListController::viewWillAppear() {
|
||||
computeTitlesColumnWidth();
|
||||
}
|
||||
|
||||
KDCoordinate StorageFunctionListController::columnWidth(int i) {
|
||||
KDCoordinate FunctionListController::columnWidth(int i) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
return m_titlesColumnWidth;
|
||||
@@ -54,7 +54,7 @@ KDCoordinate StorageFunctionListController::columnWidth(int i) {
|
||||
}
|
||||
}
|
||||
|
||||
KDCoordinate StorageFunctionListController::cumulatedWidthFromIndex(int i) {
|
||||
KDCoordinate FunctionListController::cumulatedWidthFromIndex(int i) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
return 0;
|
||||
@@ -68,7 +68,7 @@ KDCoordinate StorageFunctionListController::cumulatedWidthFromIndex(int i) {
|
||||
}
|
||||
}
|
||||
|
||||
int StorageFunctionListController::indexFromCumulatedWidth(KDCoordinate offsetX) {
|
||||
int FunctionListController::indexFromCumulatedWidth(KDCoordinate offsetX) {
|
||||
if (offsetX <= m_titlesColumnWidth) {
|
||||
return 0;
|
||||
} else {
|
||||
@@ -80,14 +80,14 @@ int StorageFunctionListController::indexFromCumulatedWidth(KDCoordinate offsetX)
|
||||
}
|
||||
}
|
||||
|
||||
int StorageFunctionListController::typeAtLocation(int i, int j) {
|
||||
int FunctionListController::typeAtLocation(int i, int j) {
|
||||
if (isAddEmptyRow(j)){
|
||||
return i + 2;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
HighlightCell * StorageFunctionListController::reusableCell(int index, int type) {
|
||||
HighlightCell * FunctionListController::reusableCell(int index, int type) {
|
||||
assert(index >= 0);
|
||||
assert(index < maxNumberOfDisplayableRows());
|
||||
switch (type) {
|
||||
@@ -105,14 +105,14 @@ HighlightCell * StorageFunctionListController::reusableCell(int index, int type)
|
||||
}
|
||||
}
|
||||
|
||||
int StorageFunctionListController::reusableCellCount(int type) {
|
||||
int FunctionListController::reusableCellCount(int type) {
|
||||
if (type > 1) {
|
||||
return 1;
|
||||
}
|
||||
return maxNumberOfDisplayableRows();
|
||||
}
|
||||
|
||||
void StorageFunctionListController::willDisplayCellAtLocation(HighlightCell * cell, int i, int j) {
|
||||
void FunctionListController::willDisplayCellAtLocation(HighlightCell * cell, int i, int j) {
|
||||
if (!isAddEmptyRow(j)) {
|
||||
if (i == 0) {
|
||||
willDisplayTitleCellAtIndex(cell, j);
|
||||
@@ -128,14 +128,14 @@ void StorageFunctionListController::willDisplayCellAtLocation(HighlightCell * ce
|
||||
|
||||
/* ButtonRowDelegate */
|
||||
|
||||
int StorageFunctionListController::numberOfButtons(ButtonRowController::Position position) const {
|
||||
int FunctionListController::numberOfButtons(ButtonRowController::Position position) const {
|
||||
if (position == ButtonRowController::Position::Bottom) {
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Button * StorageFunctionListController::buttonAtIndex(int index, ButtonRowController::Position position) const {
|
||||
Button * FunctionListController::buttonAtIndex(int index, ButtonRowController::Position position) const {
|
||||
if (position == ButtonRowController::Position::Top) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -145,7 +145,7 @@ Button * StorageFunctionListController::buttonAtIndex(int index, ButtonRowContro
|
||||
|
||||
/* Responder */
|
||||
|
||||
void StorageFunctionListController::didBecomeFirstResponder() {
|
||||
void FunctionListController::didBecomeFirstResponder() {
|
||||
if (selectedRow() == -1) {
|
||||
selectCellAtLocation(1, 0);
|
||||
} else {
|
||||
@@ -158,7 +158,7 @@ void StorageFunctionListController::didBecomeFirstResponder() {
|
||||
app()->setFirstResponder(selectableTableView());
|
||||
}
|
||||
|
||||
bool StorageFunctionListController::handleEvent(Ion::Events::Event event) {
|
||||
bool FunctionListController::handleEvent(Ion::Events::Event event) {
|
||||
if (event == Ion::Events::Up) {
|
||||
if (selectedRow() == -1) {
|
||||
footer()->setSelectedButton(-1);
|
||||
@@ -202,11 +202,11 @@ bool StorageFunctionListController::handleEvent(Ion::Events::Event event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void StorageFunctionListController::didEnterResponderChain(Responder * previousFirstResponder) {
|
||||
void FunctionListController::didEnterResponderChain(Responder * previousFirstResponder) {
|
||||
selectableTableView()->reloadData();
|
||||
}
|
||||
|
||||
void StorageFunctionListController::willExitResponderChain(Responder * nextFirstResponder) {
|
||||
void FunctionListController::willExitResponderChain(Responder * nextFirstResponder) {
|
||||
if (nextFirstResponder == tabController()) {
|
||||
selectableTableView()->deselectTable();
|
||||
footer()->setSelectedButton(-1);
|
||||
@@ -215,7 +215,7 @@ void StorageFunctionListController::willExitResponderChain(Responder * nextFirst
|
||||
|
||||
/* SelectableTableViewDelegate */
|
||||
|
||||
void StorageFunctionListController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) {
|
||||
void FunctionListController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) {
|
||||
// Update memoization of cell heights
|
||||
StorageExpressionModelListController::tableViewDidChangeSelection(t, previousSelectedCellX, previousSelectedCellY);
|
||||
// Do not select the cell left of the "addEmptyFunction" cell
|
||||
@@ -226,40 +226,40 @@ void StorageFunctionListController::tableViewDidChangeSelection(SelectableTableV
|
||||
|
||||
/* ExpressionModelListController */
|
||||
|
||||
StackViewController * StorageFunctionListController::stackController() const {
|
||||
StackViewController * FunctionListController::stackController() const {
|
||||
return static_cast<StackViewController *>(parentResponder()->parentResponder()->parentResponder());
|
||||
}
|
||||
|
||||
void StorageFunctionListController::configureFunction(Ion::Storage::Record record) {
|
||||
void FunctionListController::configureFunction(Ion::Storage::Record record) {
|
||||
StackViewController * stack = stackController();
|
||||
parameterController()->setRecord(record);
|
||||
stack->push(parameterController());
|
||||
}
|
||||
|
||||
void StorageFunctionListController::computeTitlesColumnWidth(bool forceMax) {
|
||||
void FunctionListController::computeTitlesColumnWidth(bool forceMax) {
|
||||
if (forceMax) {
|
||||
m_titlesColumnWidth = nameWidth(StorageFunction::k_maxNameWithArgumentSize - 1)+k_functionTitleSumOfMargins;
|
||||
m_titlesColumnWidth = nameWidth(Function::k_maxNameWithArgumentSize - 1)+k_functionTitleSumOfMargins;
|
||||
return;
|
||||
}
|
||||
KDCoordinate maxTitleWidth = maxFunctionNameWidth()+k_functionTitleSumOfMargins;
|
||||
m_titlesColumnWidth = maxInt(maxTitleWidth, k_minTitleColumnWidth);
|
||||
}
|
||||
|
||||
TabViewController * StorageFunctionListController::tabController() const {
|
||||
TabViewController * FunctionListController::tabController() const {
|
||||
return static_cast<TabViewController *>(parentResponder()->parentResponder()->parentResponder()->parentResponder());
|
||||
}
|
||||
|
||||
StorageFunctionStore * StorageFunctionListController::modelStore() {
|
||||
StorageFunctionApp * myApp = static_cast<StorageFunctionApp *>(app());
|
||||
FunctionStore * FunctionListController::modelStore() {
|
||||
FunctionApp * myApp = static_cast<FunctionApp *>(app());
|
||||
return myApp->functionStore();
|
||||
}
|
||||
|
||||
InputViewController * StorageFunctionListController::inputController() {
|
||||
StorageFunctionApp * myApp = static_cast<StorageFunctionApp *>(app());
|
||||
InputViewController * FunctionListController::inputController() {
|
||||
FunctionApp * myApp = static_cast<FunctionApp *>(app());
|
||||
return myApp->inputViewController();
|
||||
}
|
||||
|
||||
KDCoordinate StorageFunctionListController::maxFunctionNameWidth() {
|
||||
KDCoordinate FunctionListController::maxFunctionNameWidth() {
|
||||
int maxNameLength = 0;
|
||||
int numberOfModels = modelStore()->numberOfModels();
|
||||
for (int i = 0; i < numberOfModels; i++) {
|
||||
@@ -269,15 +269,15 @@ KDCoordinate StorageFunctionListController::maxFunctionNameWidth() {
|
||||
assert(dotPosition != nullptr);
|
||||
maxNameLength = maxInt(maxNameLength, dotPosition-functionName);
|
||||
}
|
||||
return nameWidth(maxNameLength + StorageFunction::k_parenthesedArgumentLength);
|
||||
return nameWidth(maxNameLength + Function::k_parenthesedArgumentLength);
|
||||
}
|
||||
|
||||
void StorageFunctionListController::didChangeModelsList() {
|
||||
void FunctionListController::didChangeModelsList() {
|
||||
StorageExpressionModelListController::didChangeModelsList();
|
||||
computeTitlesColumnWidth();
|
||||
}
|
||||
|
||||
KDCoordinate StorageFunctionListController::baseline(int j) {
|
||||
KDCoordinate FunctionListController::baseline(int j) {
|
||||
if (j < 0) {
|
||||
return -1;
|
||||
}
|
||||
@@ -293,13 +293,13 @@ KDCoordinate StorageFunctionListController::baseline(int j) {
|
||||
return privateBaseline(j);
|
||||
}
|
||||
|
||||
void StorageFunctionListController::resetMemoizationForIndex(int index) {
|
||||
void FunctionListController::resetMemoizationForIndex(int index) {
|
||||
assert(index >= 0 && index < k_memoizedCellsCount);
|
||||
m_memoizedCellBaseline[index] = -1;
|
||||
StorageExpressionModelListController::resetMemoizationForIndex(index);
|
||||
}
|
||||
|
||||
void StorageFunctionListController::shiftMemoization(bool newCellIsUnder) {
|
||||
void FunctionListController::shiftMemoization(bool newCellIsUnder) {
|
||||
if (newCellIsUnder) {
|
||||
for (int i = 0; i < k_memoizedCellsCount - 1; i++) {
|
||||
m_memoizedCellBaseline[i] = m_memoizedCellBaseline[i+1];
|
||||
@@ -312,19 +312,19 @@ void StorageFunctionListController::shiftMemoization(bool newCellIsUnder) {
|
||||
StorageExpressionModelListController::shiftMemoization(newCellIsUnder);
|
||||
}
|
||||
|
||||
KDCoordinate StorageFunctionListController::nameWidth(int nameLength) const {
|
||||
KDCoordinate FunctionListController::nameWidth(int nameLength) const {
|
||||
assert(nameLength >= 0);
|
||||
return nameLength * const_cast<StorageFunctionListController *>(this)->titleCells(0)->font()->glyphSize().width();
|
||||
return nameLength * const_cast<FunctionListController *>(this)->titleCells(0)->font()->glyphSize().width();
|
||||
}
|
||||
|
||||
KDCoordinate StorageFunctionListController::privateBaseline(int j) const {
|
||||
assert(j >= 0 && j < const_cast<StorageFunctionListController *>(this)->numberOfExpressionRows());
|
||||
KDCoordinate FunctionListController::privateBaseline(int j) const {
|
||||
assert(j >= 0 && j < const_cast<FunctionListController *>(this)->numberOfExpressionRows());
|
||||
FunctionExpressionCell * cell = static_cast<Shared::FunctionExpressionCell *>((const_cast<SelectableTableView *>(&m_selectableTableView))->cellAtLocation(1, j));
|
||||
Poincare::Layout layout = cell->layout();
|
||||
if (layout.isUninitialized()) {
|
||||
return -1; // Baseline < 0 triggers default behaviour (centered alignment)
|
||||
}
|
||||
return 0.5*(const_cast<StorageFunctionListController *>(this)->rowHeight(j)-layout.layoutSize().height())+layout.baseline();
|
||||
return 0.5*(const_cast<FunctionListController *>(this)->rowHeight(j)-layout.layoutSize().height())+layout.baseline();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
|
||||
namespace Shared {
|
||||
|
||||
class StorageFunctionListController : public StorageExpressionModelListController, public ButtonRowDelegate, public TableViewDataSource {
|
||||
class FunctionListController : public StorageExpressionModelListController, public ButtonRowDelegate, public TableViewDataSource {
|
||||
public:
|
||||
StorageFunctionListController(Responder * parentResponder, ButtonRowController * header, ButtonRowController * footer, I18n::Message text);
|
||||
FunctionListController(Responder * parentResponder, ButtonRowController * header, ButtonRowController * footer, I18n::Message text);
|
||||
|
||||
/* ViewController */
|
||||
void viewWillAppear() override;
|
||||
@@ -53,7 +53,7 @@ protected:
|
||||
StackViewController * stackController() const;
|
||||
void configureFunction(Ion::Storage::Record record);
|
||||
void computeTitlesColumnWidth(bool forceMax = false);
|
||||
StorageFunctionStore * modelStore() override;
|
||||
FunctionStore * modelStore() override;
|
||||
KDCoordinate baseline(int j);
|
||||
void resetMemoizationForIndex(int index) override;
|
||||
void shiftMemoization(bool newCellIsUnder) override;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#include "storage_function_store.h"
|
||||
#include "storage_cartesian_function.h"
|
||||
#include "cartesian_function.h"
|
||||
#include <assert.h>
|
||||
|
||||
namespace Shared {
|
||||
|
||||
uint32_t StorageFunctionStore::storeChecksum() {
|
||||
uint32_t FunctionStore::storeChecksum() {
|
||||
return Ion::Storage::sharedStorage()->checksum();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef SHARED_STORAGE_FUNCTION_STORE_H
|
||||
#define SHARED_STORAGE_FUNCTION_STORE_H
|
||||
|
||||
#include "storage_function.h"
|
||||
#include "function.h"
|
||||
#include "storage_expression_model_store.h"
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -9,15 +9,15 @@ namespace Shared {
|
||||
|
||||
/* FunctionStore storse functions and gives them a color. */
|
||||
|
||||
class StorageFunctionStore : public StorageExpressionModelStore {
|
||||
class FunctionStore : public StorageExpressionModelStore {
|
||||
public:
|
||||
StorageFunctionStore() : StorageExpressionModelStore() {}
|
||||
FunctionStore() : StorageExpressionModelStore() {}
|
||||
uint32_t storeChecksum();
|
||||
// An active function must be defined to be counted
|
||||
int numberOfActiveFunctions() const { return numberOfModelsSatisfyingTest([](SingleExpressionModelHandle * m) { return m->isDefined() && static_cast<StorageFunction *>(m)->isActive(); }); }
|
||||
Ion::Storage::Record activeRecordAtIndex(int i) const { return recordStatifyingTestAtIndex(i, [](SingleExpressionModelHandle * m) { return m->isDefined() && static_cast<StorageFunction *>(m)->isActive(); }); }
|
||||
int numberOfActiveFunctions() const { return numberOfModelsSatisfyingTest([](ExpressionModelHandle * m) { return m->isDefined() && static_cast<Function *>(m)->isActive(); }); }
|
||||
Ion::Storage::Record activeRecordAtIndex(int i) const { return recordStatifyingTestAtIndex(i, [](ExpressionModelHandle * m) { return m->isDefined() && static_cast<Function *>(m)->isActive(); }); }
|
||||
|
||||
ExpiringPointer<StorageFunction> modelForRecord(Ion::Storage::Record record) const { return ExpiringPointer<StorageFunction>(static_cast<StorageFunction *>(privateModelForRecord(record))); }
|
||||
ExpiringPointer<Function> modelForRecord(Ion::Storage::Record record) const { return ExpiringPointer<Function>(static_cast<Function *>(privateModelForRecord(record))); }
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "storage_list_parameter_controller.h"
|
||||
#include "storage_function_app.h"
|
||||
#include "function_app.h"
|
||||
#include <assert.h>
|
||||
|
||||
namespace Shared {
|
||||
@@ -94,12 +94,12 @@ bool StorageListParameterController::handleEnterOnRow(int rowIndex) {
|
||||
}
|
||||
}
|
||||
|
||||
ExpiringPointer<StorageFunction> StorageListParameterController::function() {
|
||||
ExpiringPointer<Function> StorageListParameterController::function() {
|
||||
return functionStore()->modelForRecord(m_record);
|
||||
}
|
||||
|
||||
StorageFunctionStore * StorageListParameterController::functionStore() {
|
||||
StorageFunctionApp * a = static_cast<StorageFunctionApp *>(app());
|
||||
FunctionStore * StorageListParameterController::functionStore() {
|
||||
FunctionApp * a = static_cast<FunctionApp *>(app());
|
||||
return a->functionStore();
|
||||
}
|
||||
|
||||
|
||||
@@ -31,8 +31,8 @@ protected:
|
||||
return 2;
|
||||
#endif
|
||||
}
|
||||
StorageFunctionStore * functionStore();
|
||||
ExpiringPointer<StorageFunction> function();
|
||||
FunctionStore * functionStore();
|
||||
ExpiringPointer<Function> function();
|
||||
SelectableTableView m_selectableTableView;
|
||||
Ion::Storage::Record m_record;
|
||||
private:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "storage_sum_graph_controller.h"
|
||||
#include "storage_function_app.h"
|
||||
#include "function_app.h"
|
||||
#include "../apps_container.h"
|
||||
#include <poincare_layouts.h>
|
||||
#include <poincare/layout_helper.h>
|
||||
@@ -13,7 +13,7 @@ using namespace Poincare;
|
||||
|
||||
namespace Shared {
|
||||
|
||||
StorageSumGraphController::StorageSumGraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, StorageFunctionGraphView * graphView, InteractiveCurveViewRange * range, CurveViewCursor * cursor, CodePoint sumSymbol) :
|
||||
StorageSumGraphController::StorageSumGraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, FunctionGraphView * graphView, InteractiveCurveViewRange * range, CurveViewCursor * cursor, CodePoint sumSymbol) :
|
||||
SimpleInteractiveCurveViewController(parentResponder, range, graphView, cursor),
|
||||
m_step(Step::FirstParameter),
|
||||
m_startSum(NAN),
|
||||
@@ -101,9 +101,9 @@ bool StorageSumGraphController::handleEvent(Ion::Events::Event event) {
|
||||
}
|
||||
|
||||
bool StorageSumGraphController::moveCursorHorizontallyToPosition(double x) {
|
||||
StorageFunctionApp * myApp = static_cast<StorageFunctionApp *>(app());
|
||||
FunctionApp * myApp = static_cast<FunctionApp *>(app());
|
||||
assert(!m_record.isNull());
|
||||
ExpiringPointer<StorageFunction> function = myApp->functionStore()->modelForRecord(m_record);
|
||||
ExpiringPointer<Function> function = myApp->functionStore()->modelForRecord(m_record);
|
||||
double y = function->evaluateAtAbscissa(x, myApp->localContext());
|
||||
m_cursor->moveTo(x, y);
|
||||
if (m_step == Step::FirstParameter) {
|
||||
@@ -189,9 +189,9 @@ bool StorageSumGraphController::handleEnter() {
|
||||
return true;
|
||||
}
|
||||
m_step = (Step)((int)m_step+1);
|
||||
StorageFunctionApp * myApp = static_cast<StorageFunctionApp *>(app());
|
||||
FunctionApp * myApp = static_cast<FunctionApp *>(app());
|
||||
assert(!m_record.isNull());
|
||||
ExpiringPointer<StorageFunction> function = myApp->functionStore()->modelForRecord(m_record);
|
||||
ExpiringPointer<Function> function = myApp->functionStore()->modelForRecord(m_record);
|
||||
double sum = function->sumBetweenBounds(m_startSum, m_endSum, myApp->localContext());
|
||||
m_legendView.setSumSymbol(m_step, m_startSum, m_endSum, sum, createFunctionLayout(function));
|
||||
m_legendView.setLegendMessage(I18n::Message::Default, m_step);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "vertical_cursor_view.h"
|
||||
#include "curve_view_cursor.h"
|
||||
#include "simple_interactive_curve_view_controller.h"
|
||||
#include "storage_function.h"
|
||||
#include "function.h"
|
||||
#include "text_field_delegate.h"
|
||||
#include "expiring_pointer.h"
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Shared {
|
||||
|
||||
class StorageSumGraphController : public SimpleInteractiveCurveViewController, public TextFieldDelegate {
|
||||
public:
|
||||
StorageSumGraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, StorageFunctionGraphView * curveView, InteractiveCurveViewRange * range, CurveViewCursor * cursor, CodePoint sumSymbol);
|
||||
StorageSumGraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, FunctionGraphView * curveView, InteractiveCurveViewRange * range, CurveViewCursor * cursor, CodePoint sumSymbol);
|
||||
void viewWillAppear() override;
|
||||
void didEnterResponderChain(Responder * previousFirstResponder) override;
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
@@ -40,7 +40,7 @@ private:
|
||||
constexpr static float k_cursorBottomMarginRatio = 0.28f; // (cursorHeight/2+bannerHeigh)/graphViewHeight
|
||||
virtual I18n::Message legendMessageAtStep(Step step) = 0;
|
||||
virtual double cursorNextStep(double position, int direction) = 0;
|
||||
virtual Poincare::Layout createFunctionLayout(ExpiringPointer<StorageFunction> function) = 0;
|
||||
virtual Poincare::Layout createFunctionLayout(ExpiringPointer<Function> function) = 0;
|
||||
Shared::InteractiveCurveViewRange * interactiveCurveViewRange() override { return m_graphRange; }
|
||||
Shared::CurveView * curveView() override { return m_graphView; }
|
||||
TextFieldDelegateApp * textFieldDelegateApp() override {
|
||||
@@ -78,7 +78,7 @@ private:
|
||||
char m_draftText[TextField::maxBufferSize()];
|
||||
CodePoint m_sumSymbol;
|
||||
};
|
||||
StorageFunctionGraphView * m_graphView;
|
||||
FunctionGraphView * m_graphView;
|
||||
LegendView m_legendView;
|
||||
VerticalCursorView m_cursorView;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "storage_values_controller.h"
|
||||
#include "storage_function_app.h"
|
||||
#include "function_app.h"
|
||||
#include "../constant.h"
|
||||
#include "../apps_container.h"
|
||||
#include "poincare_helpers.h"
|
||||
@@ -309,7 +309,7 @@ int StorageValuesController::maxNumberOfElements() const {
|
||||
}
|
||||
|
||||
double StorageValuesController::evaluationOfAbscissaAtColumn(double abscissa, int columnIndex) {
|
||||
ExpiringPointer<StorageFunction> function = functionStore()->modelForRecord(recordAtColumn(columnIndex));
|
||||
ExpiringPointer<Function> function = functionStore()->modelForRecord(recordAtColumn(columnIndex));
|
||||
TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app();
|
||||
return function->evaluateAtAbscissa(abscissa, myApp->localContext());
|
||||
}
|
||||
@@ -318,8 +318,8 @@ void StorageValuesController::updateNumberOfColumns() {
|
||||
m_numberOfColumns = 1+functionStore()->numberOfActiveFunctions();
|
||||
}
|
||||
|
||||
StorageFunctionStore * StorageValuesController::functionStore() const {
|
||||
StorageFunctionApp * myApp = static_cast<StorageFunctionApp *>(app());
|
||||
FunctionStore * StorageValuesController::functionStore() const {
|
||||
FunctionApp * myApp = static_cast<FunctionApp *>(app());
|
||||
return myApp->functionStore();
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ protected:
|
||||
StackViewController * stackController() const;
|
||||
bool setDataAtLocation(double floatBody, int columnIndex, int rowIndex) override;
|
||||
virtual void updateNumberOfColumns();
|
||||
virtual StorageFunctionStore * functionStore() const;
|
||||
virtual FunctionStore * functionStore() const;
|
||||
virtual Ion::Storage::Record recordAtColumn(int i);
|
||||
Interval * m_interval;
|
||||
int m_numberOfColumns;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "storage_values_function_parameter_controller.h"
|
||||
#include "storage_function_app.h"
|
||||
#include "function_app.h"
|
||||
#include <assert.h>
|
||||
|
||||
namespace Shared {
|
||||
@@ -9,8 +9,8 @@ const char * StorageValuesFunctionParameterController::title() {
|
||||
}
|
||||
|
||||
void StorageValuesFunctionParameterController::viewWillAppear() {
|
||||
StorageFunctionApp * myApp = static_cast<StorageFunctionApp *>(app());
|
||||
myApp->functionStore()->modelForRecord(m_record)->nameWithArgument(m_pageTitle, StorageFunction::k_maxNameWithArgumentSize, m_symbol);
|
||||
FunctionApp * myApp = static_cast<FunctionApp *>(app());
|
||||
myApp->functionStore()->modelForRecord(m_record)->nameWithArgument(m_pageTitle, Function::k_maxNameWithArgumentSize, m_symbol);
|
||||
}
|
||||
|
||||
void StorageValuesFunctionParameterController::didBecomeFirstResponder() {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define SHARED_STORAGE_VALUES_FUNCTION_PARAM_CONTROLLER_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "storage_function.h"
|
||||
#include "function.h"
|
||||
#include <apps/i18n.h>
|
||||
|
||||
namespace Shared {
|
||||
@@ -34,7 +34,7 @@ protected:
|
||||
SelectableTableView m_selectableTableView;
|
||||
Ion::Storage::Record m_record;
|
||||
private:
|
||||
char m_pageTitle[StorageFunction::k_maxNameWithArgumentSize];
|
||||
char m_pageTitle[Function::k_maxNameWithArgumentSize];
|
||||
char m_symbol;
|
||||
};
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ using namespace Shared;
|
||||
namespace Solver {
|
||||
|
||||
Equation::Equation(Ion::Storage::Record record) :
|
||||
SingleExpressionModelHandle(record)
|
||||
ExpressionModelHandle(record)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ Expression Equation::Handle::standardForm(const Storage::Record * record, Contex
|
||||
}
|
||||
|
||||
void Equation::Handle::tidy() const {
|
||||
ExpressionModelHandle::tidy();
|
||||
ExpressionModel::tidy();
|
||||
// Free the pool of the m_standardForm
|
||||
m_standardForm = Expression();
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#ifndef SOLVER_EQUATION_h
|
||||
#define SOLVER_EQUATION_h
|
||||
|
||||
#include "../shared/single_expression_model_handle.h"
|
||||
#include "../shared/expression_model_handle.h"
|
||||
|
||||
namespace Solver {
|
||||
|
||||
class Equation : public Shared::SingleExpressionModelHandle {
|
||||
class Equation : public Shared::ExpressionModelHandle {
|
||||
public:
|
||||
Equation(Ion::Storage::Record record = Record());
|
||||
bool shouldBeClearedBeforeRemove() override {
|
||||
@@ -15,7 +15,7 @@ public:
|
||||
bool containsIComplex(Poincare::Context * context) const;
|
||||
|
||||
private:
|
||||
class Handle : public Shared::ExpressionModelHandle {
|
||||
class Handle : public Shared::ExpressionModel {
|
||||
public:
|
||||
Poincare::Expression standardForm(const Ion::Storage::Record * record, Poincare::Context * context) const;
|
||||
void tidy() const override;
|
||||
@@ -25,7 +25,7 @@ private:
|
||||
mutable Poincare::Expression m_standardForm;
|
||||
};
|
||||
size_t metaDataSize() const override { return 0; }
|
||||
const Shared::ExpressionModelHandle * handle() const override { return &m_handle; }
|
||||
const Shared::ExpressionModel * handle() const override { return &m_handle; }
|
||||
Handle m_handle;
|
||||
};
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ void EquationStore::setMemoizedModelAtIndex(int cacheIndex, Ion::Storage::Record
|
||||
m_equations[cacheIndex] = Equation(record);
|
||||
}
|
||||
|
||||
SingleExpressionModelHandle * EquationStore::memoizedModelAtIndex(int cacheIndex) const {
|
||||
ExpressionModelHandle * EquationStore::memoizedModelAtIndex(int cacheIndex) const {
|
||||
assert(cacheIndex >= 0 && cacheIndex < maxNumberOfMemoizedModels());
|
||||
return &m_equations[cacheIndex];
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ private:
|
||||
/* We don't really use model memoization as the number of Equation is limited
|
||||
* and we keep enough Equations to store them all. */
|
||||
void setMemoizedModelAtIndex(int cacheIndex, Ion::Storage::Record record) const override;
|
||||
Shared::SingleExpressionModelHandle * memoizedModelAtIndex(int cacheIndex) const override;
|
||||
Shared::ExpressionModelHandle * memoizedModelAtIndex(int cacheIndex) const override;
|
||||
|
||||
Error resolveLinearSystem(Poincare::Expression solutions[k_maxNumberOfExactSolutions], Poincare::Expression solutionApproximations[k_maxNumberOfExactSolutions], Poincare::Expression coefficients[k_maxNumberOfEquations][Poincare::Expression::k_maxNumberOfVariables], Poincare::Expression constants[k_maxNumberOfEquations], Poincare::Context * context);
|
||||
Error oneDimensialPolynomialSolve(Poincare::Expression solutions[k_maxNumberOfExactSolutions], Poincare::Expression solutionApproximations[k_maxNumberOfExactSolutions], Poincare::Expression polynomialCoefficients[Poincare::Expression::k_maxNumberOfPolynomialCoefficients], int degree, Poincare::Context * context);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "variable_box_controller.h"
|
||||
#include "shared/global_context.h"
|
||||
#include "shared/poincare_helpers.h"
|
||||
#include "shared/storage_function.h"
|
||||
#include "shared/storage_cartesian_function.h"
|
||||
#include "shared/function.h"
|
||||
#include "shared/cartesian_function.h"
|
||||
#include "graph/storage_cartesian_function_store.h"
|
||||
#include "constant.h"
|
||||
#include <escher/metric.h>
|
||||
@@ -103,18 +103,18 @@ void VariableBoxController::willDisplayCellForIndex(HighlightCell * cell, int in
|
||||
}
|
||||
ExpressionTableCellWithExpression * myCell = (ExpressionTableCellWithExpression *)cell;
|
||||
Storage::Record record = recordAtIndex(index);
|
||||
assert(Shared::StorageFunction::k_maxNameWithArgumentSize > SymbolAbstract::k_maxNameSize);
|
||||
char symbolName[Shared::StorageFunction::k_maxNameWithArgumentSize];
|
||||
assert(Shared::Function::k_maxNameWithArgumentSize > SymbolAbstract::k_maxNameSize);
|
||||
char symbolName[Shared::Function::k_maxNameWithArgumentSize];
|
||||
size_t symbolLength = 0;
|
||||
if (m_currentPage == Page::Expression) {
|
||||
symbolLength = SymbolAbstract::TruncateExtension(symbolName, record.fullName(), SymbolAbstract::k_maxNameSize);
|
||||
} else {
|
||||
assert(m_currentPage == Page::Function);
|
||||
StorageCartesianFunction f(record);
|
||||
CartesianFunction f(record);
|
||||
symbolLength = f.nameWithArgument(
|
||||
symbolName,
|
||||
Shared::StorageFunction::k_maxNameWithArgumentSize,
|
||||
Shared::StorageCartesianFunction::Symbol());
|
||||
Shared::Function::k_maxNameWithArgumentSize,
|
||||
Shared::CartesianFunction::Symbol());
|
||||
}
|
||||
Layout symbolLayout = LayoutHelper::String(symbolName, symbolLength);
|
||||
myCell->setLayout(symbolLayout);
|
||||
@@ -191,9 +191,9 @@ bool VariableBoxController::selectLeaf(int selectedRow) {
|
||||
|
||||
// Get the name text to insert
|
||||
Storage::Record record = recordAtIndex(selectedRow);
|
||||
assert(Shared::StorageFunction::k_maxNameWithArgumentSize > 0);
|
||||
assert(Shared::StorageFunction::k_maxNameWithArgumentSize > SymbolAbstract::k_maxNameSize);
|
||||
constexpr size_t nameToHandleMaxSize = Shared::StorageFunction::k_maxNameWithArgumentSize;
|
||||
assert(Shared::Function::k_maxNameWithArgumentSize > 0);
|
||||
assert(Shared::Function::k_maxNameWithArgumentSize > SymbolAbstract::k_maxNameSize);
|
||||
constexpr size_t nameToHandleMaxSize = Shared::Function::k_maxNameWithArgumentSize;
|
||||
char nameToHandle[nameToHandleMaxSize];
|
||||
size_t nameLength = SymbolAbstract::TruncateExtension(nameToHandle, record.fullName(), nameToHandleMaxSize);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user