diff --git a/apps/graph/Makefile b/apps/graph/Makefile index 2cb2d88e3..fd5a258a0 100644 --- a/apps/graph/Makefile +++ b/apps/graph/Makefile @@ -12,6 +12,7 @@ app_objs += $(addprefix apps/graph/,\ graph/graph_controller.o\ graph/graph_controller_helper.o\ graph/graph_view.o\ + graph/tangent_graph_controller.o\ list/list_controller.o\ values/derivative_parameter_controller.o\ values/function_parameter_controller.o\ diff --git a/apps/graph/app.cpp b/apps/graph/app.cpp index b8db422f3..581877d5f 100644 --- a/apps/graph/app.cpp +++ b/apps/graph/app.cpp @@ -82,8 +82,4 @@ const char * App::XNT() { return "x"; } -Responder * App::graphControllerParent() { - return &m_graphAlternateEmptyViewController; -} - } diff --git a/apps/graph/app.h b/apps/graph/app.h index 426ea76d8..328579cf7 100644 --- a/apps/graph/app.h +++ b/apps/graph/app.h @@ -34,7 +34,6 @@ public: }; InputViewController * inputViewController() override; const char * XNT() override; - Responder * graphControllerParent(); private: App(Container * container, Snapshot * snapshot); ListController m_listController; diff --git a/apps/graph/graph/calculation_parameter_controller.cpp b/apps/graph/graph/calculation_parameter_controller.cpp index 0c0547300..3485d9b3f 100644 --- a/apps/graph/graph/calculation_parameter_controller.cpp +++ b/apps/graph/graph/calculation_parameter_controller.cpp @@ -7,12 +7,12 @@ using namespace Shared; namespace Graph { -CalculationParameterController::CalculationParameterController(Responder * parentResponder, GraphController * graphController) : +CalculationParameterController::CalculationParameterController(Responder * parentResponder, GraphView * graphView, BannerView * bannerView, InteractiveCurveViewRange * range, CurveViewCursor * cursor) : ViewController(parentResponder), m_selectableTableView(this, this, 0, 1, Metric::CommonTopMargin, Metric::CommonRightMargin, Metric::CommonBottomMargin, Metric::CommonLeftMargin, this), m_function(nullptr), - m_graphController(graphController) + m_tangentGraphController(nullptr, graphView, bannerView, range, cursor) { } @@ -34,11 +34,11 @@ bool CalculationParameterController::handleEvent(Ion::Events::Event event) { switch(selectedRow()) { case 4: { - m_graphController->setType(GraphView::Type::Tangent); + m_tangentGraphController.setFunction(m_function); StackViewController * stack = (StackViewController *)parentResponder(); stack->pop(); stack->pop(); - stack->push(m_graphController); + stack->push(&m_tangentGraphController); return true; } default: @@ -73,7 +73,7 @@ void CalculationParameterController::willDisplayCellForIndex(HighlightCell * cel myCell->setMessage(titles[index]); } -void CalculationParameterController::setFunction(Function * function) { +void CalculationParameterController::setFunction(CartesianFunction * function) { m_function = function; } diff --git a/apps/graph/graph/calculation_parameter_controller.h b/apps/graph/graph/calculation_parameter_controller.h index 4e81e93a3..0ef3b9657 100644 --- a/apps/graph/graph/calculation_parameter_controller.h +++ b/apps/graph/graph/calculation_parameter_controller.h @@ -2,16 +2,17 @@ #define GRAPH_CALCULATION_PARAMETER_CONTROLLER_H #include -#include "../../shared/function.h" +#include "../cartesian_function.h" +#include "tangent_graph_controller.h" +#include "graph_view.h" +#include "banner_view.h" #include "../../i18n.h" namespace Graph { -class GraphController; - class CalculationParameterController : public ViewController, public SimpleListViewDataSource, public SelectableTableViewDataSource { public: - CalculationParameterController(Responder * parentResponder, GraphController * graphController); + CalculationParameterController(Responder * parentResponder, GraphView * graphView, BannerView * bannerView, Shared::InteractiveCurveViewRange * range, Shared::CurveViewCursor * cursor); View * view() override; const char * title() override; bool handleEvent(Ion::Events::Event event) override; @@ -21,13 +22,13 @@ public: HighlightCell * reusableCell(int index) override; int reusableCellCount() override; void willDisplayCellForIndex(HighlightCell * cell, int index) override; - void setFunction(Shared::Function * function); + void setFunction(CartesianFunction * function); private: constexpr static int k_totalNumberOfCells = 6; MessageTableCell m_cells[k_totalNumberOfCells]; SelectableTableView m_selectableTableView; - Shared::Function * m_function; - GraphController * m_graphController; + CartesianFunction * m_function; + TangentGraphController m_tangentGraphController; }; } diff --git a/apps/graph/graph/curve_parameter_controller.cpp b/apps/graph/graph/curve_parameter_controller.cpp index 0b457c67e..a9310556f 100644 --- a/apps/graph/graph/curve_parameter_controller.cpp +++ b/apps/graph/graph/curve_parameter_controller.cpp @@ -7,13 +7,13 @@ using namespace Shared; namespace Graph { -CurveParameterController::CurveParameterController(InteractiveCurveViewRange * graphRange, BannerView * bannerView, CurveViewCursor * cursor, GraphController * graphController) : +CurveParameterController::CurveParameterController(InteractiveCurveViewRange * graphRange, BannerView * bannerView, CurveViewCursor * cursor, GraphView * graphView, GraphController * graphController) : FunctionCurveParameterController(graphRange, cursor), m_goToParameterController(this, graphRange, cursor, I18n::Message::X), m_graphController(graphController), m_calculationCell(I18n::Message::Compute), m_derivativeCell(I18n::Message::DerivateNumber), - m_calculationParameterController(this, graphController) + m_calculationParameterController(this, graphView, bannerView, graphRange, cursor) { } @@ -37,7 +37,7 @@ bool CurveParameterController::handleEvent(Ion::Events::Event event) { switch (selectedRow()) { case 0: { - m_calculationParameterController.setFunction(m_function); + m_calculationParameterController.setFunction(static_cast(m_function)); StackViewController * stack = (StackViewController *)parentResponder(); stack->push(&m_calculationParameterController); return true; diff --git a/apps/graph/graph/curve_parameter_controller.h b/apps/graph/graph/curve_parameter_controller.h index 07ca16851..717502693 100644 --- a/apps/graph/graph/curve_parameter_controller.h +++ b/apps/graph/graph/curve_parameter_controller.h @@ -11,7 +11,7 @@ class GraphController; class CurveParameterController : public Shared::FunctionCurveParameterController { public: - CurveParameterController(Shared::InteractiveCurveViewRange * graphRange, BannerView * bannerView, Shared::CurveViewCursor * cursor, GraphController * graphController); + CurveParameterController(Shared::InteractiveCurveViewRange * graphRange, BannerView * bannerView, Shared::CurveViewCursor * cursor, GraphView * graphView, GraphController * graphController); const char * title() override; bool handleEvent(Ion::Events::Event event) override; int numberOfRows() override; diff --git a/apps/graph/graph/graph_controller.cpp b/apps/graph/graph/graph_controller.cpp index cdce83cbf..b67a33bdb 100644 --- a/apps/graph/graph/graph_controller.cpp +++ b/apps/graph/graph/graph_controller.cpp @@ -11,22 +11,13 @@ GraphController::GraphController(Responder * parentResponder, CartesianFunctionS m_bannerView(), m_view(functionStore, curveViewRange, m_cursor, &m_bannerView, &m_cursorView), m_graphRange(curveViewRange), - m_curveParameterController(curveViewRange, &m_bannerView, m_cursor, this), + m_curveParameterController(curveViewRange, &m_bannerView, m_cursor, &m_view, this), m_functionStore(functionStore), m_displayDerivativeInBanner(false) { m_graphRange->setDelegate(this); } -const char * GraphController::title() { - switch(type()) { - case GraphView::Type::Tangent: - return I18n::translate(I18n::Message::Tangent); - default: - return I18n::translate(I18n::Message::GraphTab); - } -} - I18n::Message GraphController::emptyMessage() { if (m_functionStore->numberOfDefinedFunctions() == 0) { return I18n::Message::NoFunction; @@ -34,28 +25,9 @@ I18n::Message GraphController::emptyMessage() { return I18n::Message::NoActivatedFunction; } -bool GraphController::handleEvent(Ion::Events::Event event) { - if (type() == GraphView::Type::Default || event == Ion::Events::Left || event == Ion::Events::Right || event == Ion::Events::Plus || event == Ion::Events::Minus) { - return FunctionGraphController::handleEvent(event); - } - if (type() != GraphView::Type::Default && (event == Ion::Events::Back || event == Ion::Events::OK)) { - StackViewController * stack = stackController(); - setType(GraphView::Type::Default); - App * a = static_cast(app()); - stack->handleEvent(Ion::Events::Back); - setParentResponder(a->graphControllerParent()); - return true; - } - return false; -} - -void GraphController::setType(GraphView::Type t) { - m_view.setType(t); - if (type() != GraphView::Type::Default) { - m_view.selectFunction(m_functionStore->activeFunctionAtIndex(m_indexFunctionSelectedByCursor)); - } else { - m_view.selectFunction(nullptr); - } +void GraphController::viewWillAppear() { + m_view.setType(GraphView::Type::Default); + FunctionGraphController::viewWillAppear(); } bool GraphController::displayDerivativeInBanner() const { @@ -66,10 +38,6 @@ void GraphController::setDisplayDerivativeInBanner(bool displayDerivative) { m_displayDerivativeInBanner = displayDerivative; } -GraphView::Type GraphController::type() const { - return m_view.type(); -} - BannerView * GraphController::bannerView() { return &m_bannerView; } @@ -77,33 +45,12 @@ BannerView * GraphController::bannerView() { void GraphController::reloadBannerView() { FunctionGraphController::reloadBannerView(); m_bannerView.setNumberOfSubviews(2+m_displayDerivativeInBanner); - if (type() == GraphView::Type::Tangent) { - m_bannerView.setNumberOfSubviews(6); - } - if (m_functionStore->numberOfActiveFunctions() == 0) { + if (m_functionStore->numberOfActiveFunctions() == 0 || !m_displayDerivativeInBanner) { return; } CartesianFunction * f = m_functionStore->activeFunctionAtIndex(m_indexFunctionSelectedByCursor); TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app(); reloadDerivativeInBannerViewForCursorOnFunction(m_cursor, f, myApp); - - - char buffer[FunctionBannerDelegate::k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)]; - if (type() == GraphView::Type::Tangent) { - const char * legend = "a="; - int legendLength = strlen(legend); - strlcpy(buffer, legend, legendLength+1); - double y = f->approximateDerivative(m_cursor->x(), myApp->localContext()); - Complex::convertFloatToText(y, buffer + legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits); - m_bannerView.setLegendAtIndex(buffer, 4); - - legend = "b="; - legendLength = strlen(legend); - strlcpy(buffer, legend, legendLength+1); - y = -y*m_cursor->x()+f->evaluateAtAbscissa(m_cursor->x(), myApp->localContext()); - Complex::convertFloatToText(y, buffer + legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits); - m_bannerView.setLegendAtIndex(buffer, 5); - } } bool GraphController::moveCursorHorizontally(int direction) { @@ -142,11 +89,4 @@ CurveParameterController * GraphController::curveParameterController() { return &m_curveParameterController; } -StackViewController * GraphController::stackController() const{ - if (type() != GraphView::Type::Default) { - return (StackViewController *)(parentResponder()); - } - return FunctionGraphController::stackController(); -} - } diff --git a/apps/graph/graph/graph_controller.h b/apps/graph/graph/graph_controller.h index 75213a816..45b6e7de0 100644 --- a/apps/graph/graph/graph_controller.h +++ b/apps/graph/graph/graph_controller.h @@ -15,10 +15,8 @@ namespace Graph { class GraphController : public Shared::FunctionGraphController, public GraphControllerHelper { public: GraphController(Responder * parentResponder, CartesianFunctionStore * functionStore, Shared::InteractiveCurveViewRange * curveViewRange, Shared::CurveViewCursor * cursor, uint32_t * modelVersion, uint32_t * rangeVersion, Poincare::Expression::AngleUnit * angleUnitVersion, ButtonRowController * header); - const char * title() override; I18n::Message emptyMessage() override; - bool handleEvent(Ion::Events::Event event) override; - void setType(GraphView::Type type); + void viewWillAppear() override; bool displayDerivativeInBanner() const; void setDisplayDerivativeInBanner(bool displayDerivative); private: @@ -31,7 +29,6 @@ private: CartesianFunctionStore * functionStore() const override; GraphView * functionGraphView() override; CurveParameterController * curveParameterController() override; - StackViewController * stackController() const override; BannerView m_bannerView; GraphView m_view; Shared::InteractiveCurveViewRange * m_graphRange; diff --git a/apps/graph/graph/tangent_graph_controller.cpp b/apps/graph/graph/tangent_graph_controller.cpp new file mode 100644 index 000000000..a518b234f --- /dev/null +++ b/apps/graph/graph/tangent_graph_controller.cpp @@ -0,0 +1,65 @@ +#include "tangent_graph_controller.h" +#include "../app.h" + +using namespace Shared; +using namespace Poincare; + +namespace Graph { + +TangentGraphController::TangentGraphController(Responder * parentResponder, GraphView * graphView, BannerView * bannerView, Shared::InteractiveCurveViewRange * curveViewRange, CurveViewCursor * cursor) : + SimpleInteractiveCurveViewController(parentResponder, curveViewRange, graphView, cursor), + m_graphView(graphView), + m_bannerView(bannerView), + m_graphRange(curveViewRange), + m_function(nullptr) +{ +} + +const char * TangentGraphController::title() { + return I18n::translate(I18n::Message::Tangent); +} + +void TangentGraphController::viewWillAppear() { + m_graphRange->panToMakePointVisible(m_cursor->x(), m_cursor->y(), k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio); + m_graphView->setType(GraphView::Type::Tangent); + m_graphView->setOkView(nullptr); + m_graphView->selectMainView(true); + reloadBannerView(); + m_graphView->reload(); +} + +void TangentGraphController::setFunction(CartesianFunction * function) { + m_graphView->selectFunction(function); + m_function = function; +} + +void TangentGraphController::reloadBannerView() { + m_bannerView->setNumberOfSubviews(6); + if (m_function == nullptr) { + return; + } + FunctionBannerDelegate::reloadBannerViewForCursorOnFunction(m_cursor, m_function, 'x'); + TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app(); + GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(m_cursor, m_function, myApp); + char buffer[FunctionBannerDelegate::k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)]; + const char * legend = "a="; + int legendLength = strlen(legend); + strlcpy(buffer, legend, legendLength+1); + double y = m_function->approximateDerivative(m_cursor->x(), myApp->localContext()); + Complex::convertFloatToText(y, buffer + legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits); + m_bannerView->setLegendAtIndex(buffer, 4); + + legend = "b="; + legendLength = strlen(legend); + strlcpy(buffer, legend, legendLength+1); + y = -y*m_cursor->x()+m_function->evaluateAtAbscissa(m_cursor->x(), myApp->localContext()); + Complex::convertFloatToText(y, buffer + legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits); + m_bannerView->setLegendAtIndex(buffer, 5); +} + +bool TangentGraphController::moveCursorHorizontally(int direction) { + TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app(); + return privateMoveCursorHorizontally(m_cursor, direction, m_graphRange, k_numberOfCursorStepsInGradUnit, m_function, myApp, k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio); +} + +} diff --git a/apps/graph/graph/tangent_graph_controller.h b/apps/graph/graph/tangent_graph_controller.h new file mode 100644 index 000000000..320f7025b --- /dev/null +++ b/apps/graph/graph/tangent_graph_controller.h @@ -0,0 +1,37 @@ +#ifndef GRAPH_TANGENT_GRAPH_CONTROLLER_H +#define GRAPH_TANGENT_GRAPH_CONTROLLER_H + +#include "graph_view.h" +#include "banner_view.h" +#include "graph_controller_helper.h" +#include "../../shared/simple_interactive_curve_view_controller.h" +#include "../../shared/function_banner_delegate.h" +#include "../cartesian_function_store.h" + +namespace Graph { + +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; + void viewWillAppear() override; + void setFunction(CartesianFunction * function); +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.22f; // (cursorHeight/2+bannerHeigh)/graphViewHeight + constexpr static float k_cursorLeftMarginRatio = 0.04f; // (cursorWidth/2)/graphViewWidth + Shared::InteractiveCurveViewRange * interactiveCurveViewRange() override { return m_graphRange; } + Shared::CurveView * curveView() override { return m_graphView; } + BannerView * bannerView() override { return m_bannerView; }; + void reloadBannerView() override; + bool moveCursorHorizontally(int direction) override; + GraphView * m_graphView; + BannerView * m_bannerView; + Shared::InteractiveCurveViewRange * m_graphRange; + CartesianFunction * m_function; +}; + +} + +#endif