mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[apps/shared] Move partial classes from grpah/graph to shared to be used
by sequence Change-Id: I0e18be96cfaa92b6a51836ae8aa072fa6cf0f1af
This commit is contained in:
@@ -5,10 +5,8 @@ app_objs += $(addprefix apps/graph/,\
|
||||
function_title_cell.o\
|
||||
graph/banner_view.o\
|
||||
graph/curve_parameter_controller.o\
|
||||
graph/goto_parameter_controller.o\
|
||||
graph/graph_controller.o\
|
||||
graph/graph_view.o\
|
||||
graph/initialisation_parameter_controller.o\
|
||||
list/list_controller.o\
|
||||
values/abscissa_parameter_controller.o\
|
||||
values/derivative_parameter_controller.o\
|
||||
|
||||
@@ -6,15 +6,10 @@ using namespace Shared;
|
||||
namespace Graph {
|
||||
|
||||
CurveParameterController::CurveParameterController(InteractiveCurveViewRange * graphRange, BannerView * bannerView, CurveViewCursor * cursor) :
|
||||
ViewController(nullptr),
|
||||
FunctionCurveParameterController(graphRange, cursor),
|
||||
m_bannerView(bannerView),
|
||||
m_function(nullptr),
|
||||
m_calculationCell(PointerTableCellWithChevron((char*)"Calculer")),
|
||||
m_goToCell(PointerTableCellWithChevron((char*)"Aller a")),
|
||||
m_derivativeCell(PointerTableCellWithSwitch((char*)"Nombre derivee")),
|
||||
m_selectableTableView(SelectableTableView(this, this, Metric::CommonTopMargin, Metric::CommonRightMargin,
|
||||
Metric::CommonBottomMargin, Metric::CommonLeftMargin)),
|
||||
m_goToParameterController(GoToParameterController(this, graphRange, cursor))
|
||||
m_derivativeCell(PointerTableCellWithSwitch((char*)"Nombre derivee"))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -22,15 +17,6 @@ const char * CurveParameterController::title() const {
|
||||
return "Options de la courbe";
|
||||
}
|
||||
|
||||
View * CurveParameterController::view() {
|
||||
return &m_selectableTableView;
|
||||
}
|
||||
|
||||
void CurveParameterController::didBecomeFirstResponder() {
|
||||
m_selectableTableView.selectCellAtLocation(0, 0);
|
||||
app()->setFirstResponder(&m_selectableTableView);
|
||||
}
|
||||
|
||||
void CurveParameterController::willDisplayCellForIndex(HighlightCell * cell, int index) {
|
||||
if (cell == &m_derivativeCell) {
|
||||
SwitchView * switchView = (SwitchView *)m_derivativeCell.accessoryView();
|
||||
@@ -44,12 +30,7 @@ bool CurveParameterController::handleEvent(Ion::Events::Event event) {
|
||||
case 0:
|
||||
return true;
|
||||
case 1:
|
||||
{
|
||||
m_goToParameterController.setFunction(m_function);
|
||||
StackViewController * stack = (StackViewController *)parentResponder();
|
||||
stack->push(&m_goToParameterController);
|
||||
return true;
|
||||
}
|
||||
return handleGotoSelection();
|
||||
case 2:
|
||||
{
|
||||
m_bannerView->setDisplayDerivative(!m_bannerView->displayDerivative());
|
||||
@@ -78,12 +59,4 @@ int CurveParameterController::reusableCellCount() {
|
||||
return k_totalNumberOfCells;
|
||||
}
|
||||
|
||||
KDCoordinate CurveParameterController::cellHeight() {
|
||||
return Metric::ParameterCellHeight;
|
||||
}
|
||||
|
||||
void CurveParameterController::setFunction(CartesianFunction * function) {
|
||||
m_function = function;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,38 +1,25 @@
|
||||
#ifndef GRAPH_GRAPH_CURVE_PARAMETER_CONTROLLER_H
|
||||
#define GRAPH_GRAPH_CURVE_PARAMETER_CONTROLLER_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "goto_parameter_controller.h"
|
||||
#include "../../shared/function_curve_parameter_controller.h"
|
||||
#include "banner_view.h"
|
||||
#include "../cartesian_function.h"
|
||||
#include "../../shared/curve_view_cursor.h"
|
||||
#include "../../shared/interactive_curve_view_range.h"
|
||||
|
||||
namespace Graph {
|
||||
|
||||
class CurveParameterController : public ViewController, public SimpleListViewDataSource {
|
||||
class CurveParameterController : public Shared::FunctionCurveParameterController {
|
||||
public:
|
||||
CurveParameterController(Shared::InteractiveCurveViewRange * graphRange, BannerView * bannerView, Shared::CurveViewCursor * cursor);
|
||||
|
||||
View * view() override;
|
||||
const char * title() const override;
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
void didBecomeFirstResponder() override;
|
||||
int numberOfRows() override;
|
||||
KDCoordinate cellHeight() override;
|
||||
HighlightCell * reusableCell(int index) override;
|
||||
int reusableCellCount() override;
|
||||
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
|
||||
void setFunction(CartesianFunction * function);
|
||||
private:
|
||||
BannerView * m_bannerView;
|
||||
CartesianFunction * m_function;
|
||||
constexpr static int k_totalNumberOfCells = 3;
|
||||
PointerTableCellWithChevron m_calculationCell;
|
||||
PointerTableCellWithChevron m_goToCell;
|
||||
PointerTableCellWithSwitch m_derivativeCell;
|
||||
SelectableTableView m_selectableTableView;
|
||||
GoToParameterController m_goToParameterController;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
#ifndef GRAPH_GRAPH_GOTO_PARAMETER_CONTROLLER_H
|
||||
#define GRAPH_GRAPH_GOTO_PARAMETER_CONTROLLER_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "graph_view.h"
|
||||
#include "../../shared/float_parameter_controller.h"
|
||||
#include "../../shared/curve_view_cursor.h"
|
||||
#include "../../shared/interactive_curve_view_range.h"
|
||||
|
||||
namespace Graph {
|
||||
class GoToParameterController : public Shared::FloatParameterController {
|
||||
public:
|
||||
GoToParameterController(Responder * parentResponder, Shared::InteractiveCurveViewRange * graphRange, Shared::CurveViewCursor * cursor);
|
||||
const char * title() const override;
|
||||
int numberOfRows() override;
|
||||
HighlightCell * reusableCell(int index) override;
|
||||
int reusableCellCount() override;
|
||||
void setFunction(CartesianFunction * function);
|
||||
bool textFieldDidFinishEditing(TextField * textField, const char * text) override;
|
||||
private:
|
||||
float parameterAtIndex(int index) override;
|
||||
void setParameterAtIndex(int parameterIndex, float f) override;
|
||||
char m_draftTextBuffer[PointerTableCellWithEditableText::k_bufferLength];
|
||||
PointerTableCellWithEditableText m_abscisseCell;
|
||||
Shared::InteractiveCurveViewRange * m_graphRange;
|
||||
Shared::CurveViewCursor * m_cursor;
|
||||
CartesianFunction * m_function;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,172 +1,50 @@
|
||||
#include "graph_controller.h"
|
||||
#include "../app.h"
|
||||
#include "../../apps_container.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
using namespace Poincare;
|
||||
using namespace Shared;
|
||||
using namespace Poincare;
|
||||
|
||||
namespace Graph {
|
||||
|
||||
GraphController::GraphController(Responder * parentResponder, CartesianFunctionStore * functionStore, HeaderViewController * header) :
|
||||
InteractiveCurveViewController(parentResponder, header, &m_graphRange, &m_view),
|
||||
FunctionGraphController(parentResponder, header, &m_graphRange, &m_view),
|
||||
m_bannerView(BannerView()),
|
||||
m_view(GraphView(functionStore, &m_graphRange, &m_cursor, &m_bannerView, &m_cursorView)),
|
||||
m_graphRange(InteractiveCurveViewRange(&m_cursor, this)),
|
||||
m_initialisationParameterController(InitialisationParameterController(this, &m_graphRange)),
|
||||
m_curveParameterController(CurveParameterController(&m_graphRange, &m_bannerView, &m_cursor)),
|
||||
m_functionStore(functionStore),
|
||||
m_indexFunctionSelectedByCursor(0)
|
||||
m_functionStore(functionStore)
|
||||
{
|
||||
}
|
||||
|
||||
bool GraphController::isEmpty() const {
|
||||
if (m_functionStore->numberOfActiveFunctions() == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char * GraphController::emptyMessage() {
|
||||
if (m_functionStore->numberOfDefinedFunctions() == 0) {
|
||||
return "Aucune fonction";
|
||||
}
|
||||
return "Aucune fonction selectionnee";
|
||||
}
|
||||
|
||||
ViewController * GraphController::initialisationParameterController() {
|
||||
return &m_initialisationParameterController;
|
||||
}
|
||||
|
||||
void GraphController::viewWillAppear() {
|
||||
if (m_view.context() == nullptr) {
|
||||
App * graphApp = (Graph::App *)app();
|
||||
m_view.setContext(graphApp->localContext());
|
||||
}
|
||||
Expression::AngleUnit newAngleUnitVersion = Preferences::sharedPreferences()->angleUnit();
|
||||
if (m_angleUnitVersion != newAngleUnitVersion) {
|
||||
m_angleUnitVersion = newAngleUnitVersion;
|
||||
initCursorParameters();
|
||||
}
|
||||
InteractiveCurveViewController::viewWillAppear();
|
||||
}
|
||||
|
||||
bool GraphController::didChangeRange(InteractiveCurveViewRange * interactiveCurveViewRange) {
|
||||
if (!m_graphRange.yAuto()) {
|
||||
return false;
|
||||
}
|
||||
App * graphApp = (Graph::App *)app();
|
||||
if (m_functionStore->numberOfActiveFunctions() <= 0) {
|
||||
return false;
|
||||
}
|
||||
float min = FLT_MAX;
|
||||
float max = -FLT_MAX;
|
||||
float xMin = m_graphRange.xMin();
|
||||
float xMax = m_graphRange.xMax();
|
||||
float step = (xMax - xMin)/Ion::Display::Width;
|
||||
for (int i=0; i<m_functionStore->numberOfActiveFunctions(); i++) {
|
||||
CartesianFunction * f = m_functionStore->activeFunctionAtIndex(i);
|
||||
float y = 0.0f;
|
||||
for (int i = 0; i <= Ion::Display::Width; i++) {
|
||||
float x = xMin + i*step;
|
||||
y = f->evaluateAtAbscissa(x, graphApp->localContext());
|
||||
if (!isnan(y) && !isinf(y)) {
|
||||
min = min < y ? min : y;
|
||||
max = max > y ? max : y;
|
||||
}
|
||||
}
|
||||
}
|
||||
float range = max - min;
|
||||
if (m_graphRange.yMin() == min-k_displayBottomMarginRatio*range
|
||||
&& m_graphRange.yMax() == max+k_displayTopMarginRatio*range) {
|
||||
return false;
|
||||
}
|
||||
if (min == max) {
|
||||
min = min - 1;
|
||||
max = max + 1;
|
||||
}
|
||||
if (min == FLT_MAX && max == -FLT_MAX) {
|
||||
min = -1.0f;
|
||||
max = 1.0f;
|
||||
}
|
||||
if (min == FLT_MAX) {
|
||||
min = max-1.0f;
|
||||
}
|
||||
if (max == -FLT_MAX) {
|
||||
max = min+1.0f;
|
||||
}
|
||||
m_graphRange.setYMin(min-k_displayBottomMarginRatio*range);
|
||||
m_graphRange.setYMax(max+k_displayTopMarginRatio*range);
|
||||
if (isinf(m_graphRange.xMin())) {
|
||||
m_graphRange.setYMin(-FLT_MAX);
|
||||
}
|
||||
if (isinf(m_graphRange.xMax())) {
|
||||
m_graphRange.setYMax(FLT_MAX);
|
||||
}
|
||||
return true;
|
||||
return "Aucune fonction activee";
|
||||
}
|
||||
|
||||
BannerView * GraphController::bannerView() {
|
||||
return &m_bannerView;
|
||||
}
|
||||
|
||||
bool GraphController::handleEnter() {
|
||||
CartesianFunction * f = m_functionStore->activeFunctionAtIndex(m_indexFunctionSelectedByCursor);
|
||||
m_curveParameterController.setFunction(f);
|
||||
StackViewController * stack = stackController();
|
||||
stack->push(&m_curveParameterController);
|
||||
return true;
|
||||
}
|
||||
|
||||
void GraphController::reloadBannerView() {
|
||||
FunctionGraphController::reloadBannerView();
|
||||
if (!m_bannerView.displayDerivative()) {
|
||||
return;
|
||||
}
|
||||
char buffer[k_maxNumberOfCharacters+Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
|
||||
const char * legend = "x = ";
|
||||
const char * legend = "00(x) = ";
|
||||
int legendLength = strlen(legend);
|
||||
strlcpy(buffer, legend, legendLength+1);
|
||||
Complex::convertFloatToText(m_cursor.x(), buffer+ legendLength, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
|
||||
m_bannerView.setLegendAtIndex(buffer, 0);
|
||||
|
||||
legend = "00(x) = ";
|
||||
legendLength = strlen(legend);
|
||||
strlcpy(buffer, legend, legendLength+1);
|
||||
if (m_functionStore->numberOfActiveFunctions() == 0) {
|
||||
return;
|
||||
}
|
||||
CartesianFunction * f = m_functionStore->activeFunctionAtIndex(m_indexFunctionSelectedByCursor);
|
||||
buffer[1] = f->name()[0];
|
||||
Complex::convertFloatToText(m_cursor.y(), buffer+legendLength, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
|
||||
m_bannerView.setLegendAtIndex(buffer+1, 1);
|
||||
|
||||
if (m_bannerView.displayDerivative()) {
|
||||
buffer[0] = f->name()[0];
|
||||
buffer[1] = '\'';
|
||||
App * graphApp = (Graph::App *)app();
|
||||
float y = f->approximateDerivative(m_cursor.x(), graphApp->localContext());
|
||||
Complex::convertFloatToText(y, buffer + legendLength, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
|
||||
m_bannerView.setLegendAtIndex(buffer, 2);
|
||||
}
|
||||
}
|
||||
|
||||
void GraphController::initRangeParameters() {
|
||||
if (didChangeRange(&m_graphRange)) {
|
||||
initCursorParameters();
|
||||
}
|
||||
}
|
||||
|
||||
void GraphController::initCursorParameters() {
|
||||
float x = (m_graphRange.xMin()+m_graphRange.xMax())/2.0f;
|
||||
m_indexFunctionSelectedByCursor = 0;
|
||||
App * graphApp = (Graph::App *)app();
|
||||
int functionIndex = 0;
|
||||
float y = 0;
|
||||
do {
|
||||
CartesianFunction * firstFunction = m_functionStore->activeFunctionAtIndex(functionIndex++);
|
||||
y = firstFunction->evaluateAtAbscissa(x, graphApp->localContext());
|
||||
} while (isnan(y) && functionIndex < m_functionStore->numberOfActiveFunctions());
|
||||
m_cursor.moveTo(x, y);
|
||||
m_graphRange.panToMakePointVisible(x, y, k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio);
|
||||
buffer[0] = f->name()[0];
|
||||
buffer[1] = '\'';
|
||||
TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app();
|
||||
float y = f->approximateDerivative(m_cursor.x(), myApp->localContext());
|
||||
Complex::convertFloatToText(y, buffer + legendLength, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
|
||||
m_bannerView.setLegendAtIndex(buffer, 2);
|
||||
}
|
||||
|
||||
bool GraphController::moveCursorHorizontally(int direction) {
|
||||
@@ -174,51 +52,41 @@ bool GraphController::moveCursorHorizontally(int direction) {
|
||||
float x = direction > 0 ? xCursorPosition + m_graphRange.xGridUnit()/k_numberOfCursorStepsInGradUnit :
|
||||
xCursorPosition - m_graphRange.xGridUnit()/k_numberOfCursorStepsInGradUnit;
|
||||
CartesianFunction * f = m_functionStore->activeFunctionAtIndex(m_indexFunctionSelectedByCursor);
|
||||
App * graphApp = (Graph::App *)app();
|
||||
float y = f->evaluateAtAbscissa(x, graphApp->localContext());
|
||||
TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app();
|
||||
float y = f->evaluateAtAbscissa(x, myApp->localContext());
|
||||
m_cursor.moveTo(x, y);
|
||||
m_graphRange.panToMakePointVisible(x, y, k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GraphController::moveCursorVertically(int direction) {
|
||||
CartesianFunction * actualFunction = m_functionStore->activeFunctionAtIndex(m_indexFunctionSelectedByCursor);
|
||||
App * graphApp = (Graph::App *)app();
|
||||
float y = actualFunction->evaluateAtAbscissa(m_cursor.x(), graphApp->localContext());
|
||||
CartesianFunction * nextFunction = actualFunction;
|
||||
float nextY = direction > 0 ? FLT_MAX : -FLT_MAX;
|
||||
for (int i = 0; i < m_functionStore->numberOfActiveFunctions(); i++) {
|
||||
CartesianFunction * f = m_functionStore->activeFunctionAtIndex(i);
|
||||
float newY = f->evaluateAtAbscissa(m_cursor.x(), graphApp->localContext());
|
||||
bool isNextFunction = direction > 0 ? (newY > y && newY < nextY) : (newY < y && newY > nextY);
|
||||
if (isNextFunction) {
|
||||
m_indexFunctionSelectedByCursor = i;
|
||||
nextY = newY;
|
||||
nextFunction = f;
|
||||
}
|
||||
}
|
||||
if (nextFunction == actualFunction) {
|
||||
return false;
|
||||
}
|
||||
m_cursor.moveTo(m_cursor.x(), nextY);
|
||||
m_graphRange.panToMakePointVisible(m_cursor.x(), m_cursor.y(), k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t GraphController::modelVersion() {
|
||||
return m_functionStore->storeChecksum();
|
||||
}
|
||||
|
||||
uint32_t GraphController::rangeVersion() {
|
||||
return m_graphRange.rangeChecksum();
|
||||
void GraphController::initCursorParameters() {
|
||||
float x = (interactiveCurveViewRange()->xMin()+interactiveCurveViewRange()->xMax())/2.0f;
|
||||
m_indexFunctionSelectedByCursor = 0;
|
||||
TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app();
|
||||
int functionIndex = 0;
|
||||
float y = 0;
|
||||
do {
|
||||
CartesianFunction * firstFunction = functionStore()->activeFunctionAtIndex(functionIndex++);
|
||||
y = firstFunction->evaluateAtAbscissa(x, myApp->localContext());
|
||||
} while (isnan(y) && functionIndex < functionStore()->numberOfActiveFunctions());
|
||||
m_cursor.moveTo(x, y);
|
||||
interactiveCurveViewRange()->panToMakePointVisible(x, y, k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio);
|
||||
}
|
||||
|
||||
InteractiveCurveViewRange * GraphController::interactiveCurveViewRange() {
|
||||
return &m_graphRange;
|
||||
}
|
||||
|
||||
CurveView * GraphController::curveView() {
|
||||
CartesianFunctionStore * GraphController::functionStore() const {
|
||||
return m_functionStore;
|
||||
}
|
||||
|
||||
GraphView * GraphController::functionGraphView() {
|
||||
return &m_view;
|
||||
}
|
||||
|
||||
CurveParameterController * GraphController::curveParameterController() {
|
||||
return &m_curveParameterController;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,56 +1,32 @@
|
||||
#ifndef GRAPH_GRAPH_CONTROLLER_H
|
||||
#define GRAPH_GRAPH_CONTROLLER_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "graph_view.h"
|
||||
#include "banner_view.h"
|
||||
#include "curve_parameter_controller.h"
|
||||
#include "initialisation_parameter_controller.h"
|
||||
#include "../../shared/interactive_curve_view_controller.h"
|
||||
#include "../../shared/function_graph_controller.h"
|
||||
#include "../cartesian_function_store.h"
|
||||
|
||||
namespace Graph {
|
||||
class GraphController : public Shared::InteractiveCurveViewController, public Shared::InteractiveCurveViewRangeDelegate {
|
||||
|
||||
class GraphController : public Shared::FunctionGraphController {
|
||||
public:
|
||||
GraphController(Responder * parentResponder, CartesianFunctionStore * functionStore, HeaderViewController * header);
|
||||
void viewWillAppear() override;
|
||||
ViewController * initialisationParameterController() override;
|
||||
|
||||
bool isEmpty() const override;
|
||||
const char * emptyMessage() override;
|
||||
|
||||
bool didChangeRange(Shared::InteractiveCurveViewRange * interactiveCurveViewRange) override;
|
||||
private:
|
||||
constexpr static float k_cursorTopMarginRatio = 0.07f; // (cursorHeight/2)/graphViewHeight
|
||||
constexpr static float k_cursorRightMarginRatio = 0.04f; // (cursorWidth/2)/graphViewWidth
|
||||
constexpr static float k_cursorBottomMarginRatio = 0.15f; // (cursorHeight/2+bannerHeigh)/graphViewHeight
|
||||
constexpr static float k_cursorLeftMarginRatio = 0.04f; // (cursorWidth/2)/graphViewWidth
|
||||
|
||||
/* When y auto is ticked, we use a display margin to be ensure that the user
|
||||
* can move the cursor along the curve without panning the window */
|
||||
constexpr static float k_displayTopMarginRatio = 0.09f;
|
||||
constexpr static float k_displayBottomMarginRatio = 0.2f;
|
||||
|
||||
constexpr static int k_maxNumberOfCharacters = 8;
|
||||
BannerView * bannerView() override;
|
||||
bool handleEnter() override;
|
||||
void reloadBannerView() override;
|
||||
void initRangeParameters() override;
|
||||
void initCursorParameters() override;
|
||||
bool moveCursorHorizontally(int direction) override;
|
||||
bool moveCursorVertically(int direction) override;
|
||||
uint32_t modelVersion() override;
|
||||
uint32_t rangeVersion() override;
|
||||
void initCursorParameters() override;
|
||||
Shared::InteractiveCurveViewRange * interactiveCurveViewRange() override;
|
||||
Shared::CurveView * curveView() override;
|
||||
CartesianFunctionStore * functionStore() const override;
|
||||
GraphView * functionGraphView() override;
|
||||
CurveParameterController * curveParameterController() override;
|
||||
BannerView m_bannerView;
|
||||
GraphView m_view;
|
||||
Shared::InteractiveCurveViewRange m_graphRange;
|
||||
InitialisationParameterController m_initialisationParameterController;
|
||||
CurveParameterController m_curveParameterController;
|
||||
CartesianFunctionStore * m_functionStore;
|
||||
int m_indexFunctionSelectedByCursor;
|
||||
Poincare::Expression::AngleUnit m_angleUnitVersion;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,48 +1,27 @@
|
||||
#include "graph_view.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
using namespace Poincare;
|
||||
|
||||
using namespace Shared;
|
||||
|
||||
namespace Graph {
|
||||
|
||||
GraphView::GraphView(CartesianFunctionStore * functionStore, InteractiveCurveViewRange * graphRange,
|
||||
CurveViewCursor * cursor, BannerView * bannerView, View * cursorView) :
|
||||
CurveView(graphRange, cursor, bannerView, cursorView),
|
||||
m_functionStore(functionStore),
|
||||
m_context(nullptr)
|
||||
FunctionGraphView(graphRange, cursor, bannerView, cursorView),
|
||||
m_functionStore(functionStore)
|
||||
{
|
||||
}
|
||||
|
||||
void GraphView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
ctx->fillRect(rect, KDColorWhite);
|
||||
drawGrid(ctx, rect);
|
||||
drawAxes(ctx, rect, Axis::Horizontal);
|
||||
drawAxes(ctx, rect, Axis::Vertical);
|
||||
drawLabels(ctx, rect, Axis::Horizontal, true);
|
||||
drawLabels(ctx, rect, Axis::Vertical, true);
|
||||
FunctionGraphView::drawRect(ctx, rect);
|
||||
for (int i = 0; i < m_functionStore->numberOfActiveFunctions(); i++) {
|
||||
CartesianFunction * f = m_functionStore->activeFunctionAtIndex(i);
|
||||
drawCurve(ctx, rect, f, f->color());
|
||||
}
|
||||
}
|
||||
|
||||
void GraphView::setContext(Context * context) {
|
||||
m_context = context;
|
||||
}
|
||||
|
||||
Context * GraphView::context() const {
|
||||
return m_context;
|
||||
}
|
||||
|
||||
char * GraphView::label(Axis axis, int index) const {
|
||||
return (axis == Axis::Horizontal ? (char *)m_xLabels[index] : (char *)m_yLabels[index]);
|
||||
}
|
||||
|
||||
float GraphView::evaluateModelWithParameter(Model * curve, float abscissa) const {
|
||||
CartesianFunction * f = (CartesianFunction *)curve;
|
||||
return f->evaluateAtAbscissa(abscissa, m_context);
|
||||
return f->evaluateAtAbscissa(abscissa, context());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,28 +1,19 @@
|
||||
#ifndef GRAPH_GRAPH_VIEW_H
|
||||
#define GRAPH_GRAPH_VIEW_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "../../shared/curve_view.h"
|
||||
#include "../../constant.h"
|
||||
#include "../../shared/function_graph_view.h"
|
||||
#include "../cartesian_function_store.h"
|
||||
#include "../../shared/interactive_curve_view_range.h"
|
||||
|
||||
namespace Graph {
|
||||
|
||||
class GraphView : public Shared::CurveView {
|
||||
class GraphView : public Shared::FunctionGraphView {
|
||||
public:
|
||||
GraphView(CartesianFunctionStore * functionStore, Shared::InteractiveCurveViewRange * graphRange,
|
||||
Shared::CurveViewCursor * cursor, Shared::BannerView * bannerView, View * cursorView);
|
||||
void drawRect(KDContext * ctx, KDRect rect) const override;
|
||||
void setContext(Poincare::Context * context);
|
||||
Poincare::Context * context() const;
|
||||
private:
|
||||
char * label(Axis axis, int index) const override;
|
||||
float evaluateModelWithParameter(Model * expression, float abscissa) const override;
|
||||
char m_xLabels[k_maxNumberOfXLabels][Poincare::Complex::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
|
||||
char m_yLabels[k_maxNumberOfYLabels][Poincare::Complex::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
|
||||
CartesianFunctionStore * m_functionStore;
|
||||
Poincare::Context * m_context;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -8,9 +8,14 @@ app_objs += $(addprefix apps/shared/,\
|
||||
float_pair_store.o\
|
||||
float_parameter_controller.o\
|
||||
function.o\
|
||||
function_curve_parameter_controller.o\
|
||||
function_graph_view.o\
|
||||
function_graph_controller.o\
|
||||
function_store.o\
|
||||
function_expression_cell.o\
|
||||
function_title_cell.o\
|
||||
go_to_parameter_controller.o\
|
||||
initialisation_parameter_controller.o\
|
||||
interactive_curve_view_controller.o\
|
||||
interactive_curve_view_range.o\
|
||||
list_controller.o\
|
||||
|
||||
@@ -32,6 +32,7 @@ protected:
|
||||
constexpr static int k_maxNumberOfXLabels = CurveViewRange::k_maxNumberOfXGridUnits;
|
||||
constexpr static int k_maxNumberOfYLabels = CurveViewRange::k_maxNumberOfYGridUnits;
|
||||
constexpr static KDCoordinate k_cursorSize = 25;
|
||||
constexpr static int k_externRectMargin = 1;
|
||||
float pixelToFloat(Axis axis, KDCoordinate p) const;
|
||||
float floatToPixel(Axis axis, float f) const;
|
||||
void drawLine(KDContext * ctx, KDRect rect, Axis axis,
|
||||
@@ -50,7 +51,6 @@ protected:
|
||||
void drawLabels(KDContext * ctx, KDRect rect, Axis axis, bool shiftOrigin) const;
|
||||
|
||||
private:
|
||||
constexpr static int k_externRectMargin = 1;
|
||||
/* The window bounds are deduced from the model bounds but also take into
|
||||
account a margin (computed with k_marginFactor) */
|
||||
float min(Axis axis) const;
|
||||
|
||||
43
apps/shared/function_curve_parameter_controller.cpp
Normal file
43
apps/shared/function_curve_parameter_controller.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#include "function_curve_parameter_controller.h"
|
||||
#include <assert.h>
|
||||
|
||||
namespace Shared {
|
||||
|
||||
FunctionCurveParameterController::FunctionCurveParameterController(InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor) :
|
||||
ViewController(nullptr),
|
||||
m_goToCell(PointerTableCellWithChevron((char*)"Aller a")),
|
||||
m_selectableTableView(SelectableTableView(this, this, Metric::CommonTopMargin, Metric::CommonRightMargin,
|
||||
Metric::CommonBottomMargin, Metric::CommonLeftMargin)),
|
||||
m_goToParameterController(GoToParameterController(this, graphRange, cursor)),
|
||||
m_function(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
View * FunctionCurveParameterController::view() {
|
||||
return &m_selectableTableView;
|
||||
}
|
||||
|
||||
void FunctionCurveParameterController::didBecomeFirstResponder() {
|
||||
m_selectableTableView.selectCellAtLocation(0, 0);
|
||||
app()->setFirstResponder(&m_selectableTableView);
|
||||
}
|
||||
|
||||
bool FunctionCurveParameterController::handleGotoSelection() {
|
||||
if (m_function == nullptr) {
|
||||
return false;
|
||||
}
|
||||
m_goToParameterController.setFunction(m_function);
|
||||
StackViewController * stack = (StackViewController *)parentResponder();
|
||||
stack->push(&m_goToParameterController);
|
||||
return true;
|
||||
}
|
||||
|
||||
KDCoordinate FunctionCurveParameterController::cellHeight() {
|
||||
return Metric::ParameterCellHeight;
|
||||
}
|
||||
|
||||
void FunctionCurveParameterController::setFunction(Function * function) {
|
||||
m_function = function;
|
||||
}
|
||||
|
||||
}
|
||||
30
apps/shared/function_curve_parameter_controller.h
Normal file
30
apps/shared/function_curve_parameter_controller.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef SHARED_FUNCTION_CURVE_PARAMETER_CONTROLLER_H
|
||||
#define SHARED_FUNCTION_CURVE_PARAMETER_CONTROLLER_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "go_to_parameter_controller.h"
|
||||
#include "function.h"
|
||||
#include "curve_view_cursor.h"
|
||||
#include "interactive_curve_view_range.h"
|
||||
|
||||
namespace Shared {
|
||||
|
||||
class FunctionCurveParameterController : public ViewController, public SimpleListViewDataSource {
|
||||
public:
|
||||
FunctionCurveParameterController(InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor);
|
||||
View * view() override;
|
||||
void didBecomeFirstResponder() override;
|
||||
KDCoordinate cellHeight() override;
|
||||
void setFunction(Function * function);
|
||||
protected:
|
||||
bool handleGotoSelection();
|
||||
PointerTableCellWithChevron m_goToCell;
|
||||
SelectableTableView m_selectableTableView;
|
||||
private:
|
||||
GoToParameterController m_goToParameterController;
|
||||
Function * m_function;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
169
apps/shared/function_graph_controller.cpp
Normal file
169
apps/shared/function_graph_controller.cpp
Normal file
@@ -0,0 +1,169 @@
|
||||
#include "function_graph_controller.h"
|
||||
#include "text_field_delegate_app.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
using namespace Poincare;
|
||||
|
||||
namespace Shared {
|
||||
|
||||
FunctionGraphController::FunctionGraphController(Responder * parentResponder, HeaderViewController * header, InteractiveCurveViewRange * interactiveRange, CurveView * curveView) :
|
||||
InteractiveCurveViewController(parentResponder, header, interactiveRange, curveView),
|
||||
m_indexFunctionSelectedByCursor(0),
|
||||
m_initialisationParameterController(InitialisationParameterController(this, interactiveRange))
|
||||
{
|
||||
}
|
||||
|
||||
bool FunctionGraphController::isEmpty() const {
|
||||
if (functionStore()->numberOfActiveFunctions() == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ViewController * FunctionGraphController::initialisationParameterController() {
|
||||
return &m_initialisationParameterController;
|
||||
}
|
||||
|
||||
void FunctionGraphController::viewWillAppear() {
|
||||
if (functionGraphView()->context() == nullptr) {
|
||||
TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app();
|
||||
functionGraphView()->setContext(myApp->localContext());
|
||||
}
|
||||
Expression::AngleUnit newAngleUnitVersion = Preferences::sharedPreferences()->angleUnit();
|
||||
if (m_angleUnitVersion != newAngleUnitVersion) {
|
||||
m_angleUnitVersion = newAngleUnitVersion;
|
||||
initCursorParameters();
|
||||
}
|
||||
InteractiveCurveViewController::viewWillAppear();
|
||||
}
|
||||
|
||||
bool FunctionGraphController::didChangeRange(InteractiveCurveViewRange * interactiveCurveViewRange) {
|
||||
if (!interactiveCurveViewRange->yAuto()) {
|
||||
return false;
|
||||
}
|
||||
TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app();
|
||||
if (functionStore()->numberOfActiveFunctions() <= 0) {
|
||||
return false;
|
||||
}
|
||||
float min = FLT_MAX;
|
||||
float max = -FLT_MAX;
|
||||
float xMin = interactiveCurveViewRange->xMin();
|
||||
float xMax = interactiveCurveViewRange->xMax();
|
||||
float step = (xMax - xMin)/Ion::Display::Width;
|
||||
for (int i=0; i<functionStore()->numberOfActiveFunctions(); i++) {
|
||||
Function * f = functionStore()->activeFunctionAtIndex(i);
|
||||
float y = 0.0f;
|
||||
for (int i = 0; i <= Ion::Display::Width; i++) {
|
||||
float x = xMin + i*step;
|
||||
y = f->evaluateAtAbscissa(x, myApp->localContext());
|
||||
if (!isnan(y) && !isinf(y)) {
|
||||
min = min < y ? min : y;
|
||||
max = max > y ? max : y;
|
||||
}
|
||||
}
|
||||
}
|
||||
float range = max - min;
|
||||
if (interactiveCurveViewRange->yMin() == min-k_displayBottomMarginRatio*range
|
||||
&& interactiveCurveViewRange->yMax() == max+k_displayTopMarginRatio*range) {
|
||||
return false;
|
||||
}
|
||||
if (min == max) {
|
||||
min = min - 1;
|
||||
max = max + 1;
|
||||
}
|
||||
if (min == FLT_MAX && max == -FLT_MAX) {
|
||||
min = -1.0f;
|
||||
max = 1.0f;
|
||||
}
|
||||
if (min == FLT_MAX) {
|
||||
min = max-1.0f;
|
||||
}
|
||||
if (max == -FLT_MAX) {
|
||||
max = min+1.0f;
|
||||
}
|
||||
interactiveCurveViewRange->setYMin(min-k_displayBottomMarginRatio*range);
|
||||
interactiveCurveViewRange->setYMax(max+k_displayTopMarginRatio*range);
|
||||
if (isinf(interactiveCurveViewRange->xMin())) {
|
||||
interactiveCurveViewRange->setYMin(-FLT_MAX);
|
||||
}
|
||||
if (isinf(interactiveCurveViewRange->xMax())) {
|
||||
interactiveCurveViewRange->setYMax(FLT_MAX);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FunctionGraphController::handleEnter() {
|
||||
Function * f = functionStore()->activeFunctionAtIndex(m_indexFunctionSelectedByCursor);
|
||||
curveParameterController()->setFunction(f);
|
||||
StackViewController * stack = stackController();
|
||||
stack->push(curveParameterController());
|
||||
return true;
|
||||
}
|
||||
|
||||
void FunctionGraphController::reloadBannerView() {
|
||||
char buffer[k_maxNumberOfCharacters+Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
|
||||
const char * legend = "0 = ";
|
||||
int legendLength = strlen(legend);
|
||||
strlcpy(buffer, legend, legendLength+1);
|
||||
buffer[0] = functionStore()->symbol();
|
||||
Complex::convertFloatToText(m_cursor.x(), buffer+ legendLength, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
|
||||
bannerView()->setLegendAtIndex(buffer, 0);
|
||||
|
||||
legend = "0(x) = ";
|
||||
legendLength = strlen(legend);
|
||||
strlcpy(buffer, legend, legendLength+1);
|
||||
buffer[2] = functionStore()->symbol();
|
||||
if (functionStore()->numberOfActiveFunctions() == 0) {
|
||||
return;
|
||||
}
|
||||
Function * f = functionStore()->activeFunctionAtIndex(m_indexFunctionSelectedByCursor);
|
||||
buffer[0] = f->name()[0];
|
||||
Complex::convertFloatToText(m_cursor.y(), buffer+legendLength, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
|
||||
bannerView()->setLegendAtIndex(buffer, 1);
|
||||
}
|
||||
|
||||
void FunctionGraphController::initRangeParameters() {
|
||||
if (didChangeRange(interactiveCurveViewRange())) {
|
||||
initCursorParameters();
|
||||
}
|
||||
}
|
||||
|
||||
bool FunctionGraphController::moveCursorVertically(int direction) {
|
||||
Function * actualFunction = functionStore()->activeFunctionAtIndex(m_indexFunctionSelectedByCursor);
|
||||
TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app();
|
||||
float y = actualFunction->evaluateAtAbscissa(m_cursor.x(), myApp->localContext());
|
||||
Function * nextFunction = actualFunction;
|
||||
float nextY = direction > 0 ? FLT_MAX : -FLT_MAX;
|
||||
for (int i = 0; i < functionStore()->numberOfActiveFunctions(); i++) {
|
||||
Function * f = functionStore()->activeFunctionAtIndex(i);
|
||||
float newY = f->evaluateAtAbscissa(m_cursor.x(), myApp->localContext());
|
||||
bool isNextFunction = direction > 0 ? (newY > y && newY < nextY) : (newY < y && newY > nextY);
|
||||
if (isNextFunction) {
|
||||
m_indexFunctionSelectedByCursor = i;
|
||||
nextY = newY;
|
||||
nextFunction = f;
|
||||
}
|
||||
}
|
||||
if (nextFunction == actualFunction) {
|
||||
return false;
|
||||
}
|
||||
m_cursor.moveTo(m_cursor.x(), nextY);
|
||||
interactiveCurveViewRange()->panToMakePointVisible(m_cursor.x(), m_cursor.y(), k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio);
|
||||
return true;
|
||||
}
|
||||
|
||||
CurveView * FunctionGraphController::curveView() {
|
||||
return functionGraphView();
|
||||
}
|
||||
|
||||
uint32_t FunctionGraphController::modelVersion() {
|
||||
return functionStore()->storeChecksum();
|
||||
}
|
||||
|
||||
uint32_t FunctionGraphController::rangeVersion() {
|
||||
return interactiveCurveViewRange()->rangeChecksum();
|
||||
}
|
||||
|
||||
}
|
||||
49
apps/shared/function_graph_controller.h
Normal file
49
apps/shared/function_graph_controller.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#ifndef SHARED_FUNCTION_GRAPH_CONTROLLER_H
|
||||
#define SHARED_FUNCTION_GRAPH_CONTROLLER_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "initialisation_parameter_controller.h"
|
||||
#include "interactive_curve_view_controller.h"
|
||||
#include "function_store.h"
|
||||
#include "function_graph_view.h"
|
||||
#include "function_curve_parameter_controller.h"
|
||||
|
||||
namespace Shared {
|
||||
|
||||
class FunctionGraphController : public InteractiveCurveViewController, public InteractiveCurveViewRangeDelegate {
|
||||
public:
|
||||
FunctionGraphController(Responder * parentResponder, HeaderViewController * header, InteractiveCurveViewRange * interactiveRange, CurveView * curveView);
|
||||
bool isEmpty() const override;
|
||||
ViewController * initialisationParameterController() override;
|
||||
void viewWillAppear() override;
|
||||
bool didChangeRange(Shared::InteractiveCurveViewRange * interactiveCurveViewRange) override;
|
||||
protected:
|
||||
constexpr static float k_cursorTopMarginRatio = 0.07f; // (cursorHeight/2)/graphViewHeight
|
||||
constexpr static float k_cursorRightMarginRatio = 0.04f; // (cursorWidth/2)/graphViewWidth
|
||||
constexpr static float k_cursorBottomMarginRatio = 0.15f; // (cursorHeight/2+bannerHeigh)/graphViewHeight
|
||||
constexpr static float k_cursorLeftMarginRatio = 0.04f; // (cursorWidth/2)/graphViewWidth
|
||||
constexpr static int k_maxNumberOfCharacters = 8;
|
||||
void reloadBannerView() override;
|
||||
int m_indexFunctionSelectedByCursor;
|
||||
private:
|
||||
/* When y auto is ticked, we use a display margin to be ensure that the user
|
||||
* can move the cursor along the curve without panning the window */
|
||||
constexpr static float k_displayTopMarginRatio = 0.09f;
|
||||
constexpr static float k_displayBottomMarginRatio = 0.2f;
|
||||
|
||||
bool handleEnter() override;
|
||||
void initRangeParameters() override;
|
||||
bool moveCursorVertically(int direction) override;
|
||||
CurveView * curveView() override;
|
||||
uint32_t modelVersion() override;
|
||||
uint32_t rangeVersion() override;
|
||||
virtual FunctionStore * functionStore() const = 0;
|
||||
virtual FunctionGraphView * functionGraphView() = 0;
|
||||
virtual FunctionCurveParameterController * curveParameterController() = 0;
|
||||
InitialisationParameterController m_initialisationParameterController;
|
||||
Poincare::Expression::AngleUnit m_angleUnitVersion;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
37
apps/shared/function_graph_view.cpp
Normal file
37
apps/shared/function_graph_view.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "function_graph_view.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
using namespace Poincare;
|
||||
|
||||
namespace Shared {
|
||||
|
||||
FunctionGraphView::FunctionGraphView(InteractiveCurveViewRange * graphRange,
|
||||
CurveViewCursor * cursor, BannerView * bannerView, View * cursorView) :
|
||||
CurveView(graphRange, cursor, bannerView, cursorView),
|
||||
m_context(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void FunctionGraphView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
ctx->fillRect(rect, KDColorWhite);
|
||||
drawGrid(ctx, rect);
|
||||
drawAxes(ctx, rect, Axis::Horizontal);
|
||||
drawAxes(ctx, rect, Axis::Vertical);
|
||||
drawLabels(ctx, rect, Axis::Horizontal, true);
|
||||
drawLabels(ctx, rect, Axis::Vertical, true);
|
||||
}
|
||||
|
||||
void FunctionGraphView::setContext(Context * context) {
|
||||
m_context = context;
|
||||
}
|
||||
|
||||
Context * FunctionGraphView::context() const {
|
||||
return m_context;
|
||||
}
|
||||
|
||||
char * FunctionGraphView::label(Axis axis, int index) const {
|
||||
return (axis == Axis::Horizontal ? (char *)m_xLabels[index] : (char *)m_yLabels[index]);
|
||||
}
|
||||
|
||||
}
|
||||
27
apps/shared/function_graph_view.h
Normal file
27
apps/shared/function_graph_view.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef SHARED_FUNCTION_GRAPH_VIEW_H
|
||||
#define SHARED_FUNCTION_GRAPH_VIEW_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "curve_view.h"
|
||||
#include "../constant.h"
|
||||
#include "interactive_curve_view_range.h"
|
||||
|
||||
namespace Shared {
|
||||
|
||||
class FunctionGraphView : public CurveView {
|
||||
public:
|
||||
FunctionGraphView(InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor,
|
||||
BannerView * bannerView, View * cursorView);
|
||||
void drawRect(KDContext * ctx, KDRect rect) const override;
|
||||
void setContext(Poincare::Context * context);
|
||||
Poincare::Context * context() const;
|
||||
private:
|
||||
char * label(Axis axis, int index) const override;
|
||||
char m_xLabels[k_maxNumberOfXLabels][Poincare::Complex::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
|
||||
char m_yLabels[k_maxNumberOfYLabels][Poincare::Complex::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
|
||||
Poincare::Context * m_context;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,11 +1,8 @@
|
||||
#include "goto_parameter_controller.h"
|
||||
#include "../app.h"
|
||||
#include "../../apps_container.h"
|
||||
#include "go_to_parameter_controller.h"
|
||||
#include "text_field_delegate_app.h"
|
||||
#include <assert.h>
|
||||
|
||||
using namespace Shared;
|
||||
|
||||
namespace Graph {
|
||||
namespace Shared {
|
||||
|
||||
GoToParameterController::GoToParameterController(Responder * parentResponder, InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor) :
|
||||
FloatParameterController(parentResponder),
|
||||
@@ -27,8 +24,8 @@ float GoToParameterController::parameterAtIndex(int index) {
|
||||
|
||||
void GoToParameterController::setParameterAtIndex(int parameterIndex, float f) {
|
||||
assert(parameterIndex == 0);
|
||||
App * graphApp = (Graph::App *)app();
|
||||
float y = m_function->evaluateAtAbscissa(f, graphApp->localContext());
|
||||
TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app();
|
||||
float y = m_function->evaluateAtAbscissa(f, myApp->localContext());
|
||||
m_graphRange->centerAxisAround(CurveViewRange::Axis::X, f);
|
||||
m_graphRange->centerAxisAround(CurveViewRange::Axis::Y, y);
|
||||
m_cursor->moveTo(f, y);
|
||||
@@ -47,7 +44,7 @@ int GoToParameterController::reusableCellCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void GoToParameterController::setFunction(CartesianFunction * function) {
|
||||
void GoToParameterController::setFunction(Function * function) {
|
||||
m_function = function;
|
||||
}
|
||||
|
||||
33
apps/shared/go_to_parameter_controller.h
Normal file
33
apps/shared/go_to_parameter_controller.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef SHARED_GO_TO_PARAMETER_CONTROLLER_H
|
||||
#define SHARED_GO_TO_PARAMETER_CONTROLLER_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "float_parameter_controller.h"
|
||||
#include "curve_view_cursor.h"
|
||||
#include "interactive_curve_view_range.h"
|
||||
#include "function.h"
|
||||
|
||||
namespace Shared {
|
||||
|
||||
class GoToParameterController : public FloatParameterController {
|
||||
public:
|
||||
GoToParameterController(Responder * parentResponder, InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor);
|
||||
const char * title() const override;
|
||||
int numberOfRows() override;
|
||||
HighlightCell * reusableCell(int index) override;
|
||||
int reusableCellCount() override;
|
||||
void setFunction(Function * function);
|
||||
bool textFieldDidFinishEditing(TextField * textField, const char * text) override;
|
||||
private:
|
||||
float parameterAtIndex(int index) override;
|
||||
void setParameterAtIndex(int parameterIndex, float f) override;
|
||||
char m_draftTextBuffer[PointerTableCellWithEditableText::k_bufferLength];
|
||||
PointerTableCellWithEditableText m_abscisseCell;
|
||||
InteractiveCurveViewRange * m_graphRange;
|
||||
CurveViewCursor * m_cursor;
|
||||
Function * m_function;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,11 +1,8 @@
|
||||
#include "initialisation_parameter_controller.h"
|
||||
#include "../app.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
using namespace Shared;
|
||||
|
||||
namespace Graph {
|
||||
namespace Shared {
|
||||
|
||||
InitialisationParameterController::InitialisationParameterController(Responder * parentResponder, InteractiveCurveViewRange * graphRange) :
|
||||
ViewController(parentResponder),
|
||||
@@ -1,10 +1,10 @@
|
||||
#ifndef GRAPH_GRAPH_INITIALISATION_PARAMETER_CONTROLLER_H
|
||||
#define GRAPH_GRAPH_INITIALISATION_PARAMETER_CONTROLLER_H
|
||||
#ifndef SHARED_INITIALISATION_PARAMETER_CONTROLLER_H
|
||||
#define SHARED_INITIALISATION_PARAMETER_CONTROLLER_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "../../shared/interactive_curve_view_range.h"
|
||||
#include "interactive_curve_view_range.h"
|
||||
|
||||
namespace Graph {
|
||||
namespace Shared {
|
||||
|
||||
class InitialisationParameterController : public ViewController, public SimpleListViewDataSource {
|
||||
public:
|
||||
@@ -22,7 +22,7 @@ private:
|
||||
constexpr static int k_totalNumberOfCells = 4;
|
||||
PointerTableCell m_cells[k_totalNumberOfCells];
|
||||
SelectableTableView m_selectableTableView;
|
||||
Shared::InteractiveCurveViewRange * m_graphRange;
|
||||
InteractiveCurveViewRange * m_graphRange;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
#define ESCHER_APP_H
|
||||
|
||||
#include <escher/modal_view_controller.h>
|
||||
#include <escher/image.h>
|
||||
#include <escher/responder.h>
|
||||
#include <escher/view_controller.h>
|
||||
#include <escher/image.h>
|
||||
#include <escher/warning_controller.h>
|
||||
|
||||
/* An app is fed events and outputs drawing calls.
|
||||
|
||||
Reference in New Issue
Block a user