diff --git a/apps/graph/graph/calculation_parameter_controller.cpp b/apps/graph/graph/calculation_parameter_controller.cpp index 669215dcc..11acb3e45 100644 --- a/apps/graph/graph/calculation_parameter_controller.cpp +++ b/apps/graph/graph/calculation_parameter_controller.cpp @@ -37,7 +37,7 @@ bool CalculationParameterController::handleEvent(Ion::Events::Event event) { StackViewController * stack = (StackViewController *)parentResponder(); stack->pop(); stack->pop(); - m_graphController->setType(GraphController::Type::Tangent); + m_graphController->setType(GraphView::Type::Tangent); stack->push(m_graphController); return true; } diff --git a/apps/graph/graph/graph_controller.cpp b/apps/graph/graph/graph_controller.cpp index c9871604d..5bfd749e5 100644 --- a/apps/graph/graph/graph_controller.cpp +++ b/apps/graph/graph/graph_controller.cpp @@ -12,15 +12,14 @@ GraphController::GraphController(Responder * parentResponder, CartesianFunctionS m_view(functionStore, curveViewRange, m_cursor, &m_bannerView, &m_cursorView), m_graphRange(curveViewRange), m_curveParameterController(curveViewRange, &m_bannerView, m_cursor, this), - m_functionStore(functionStore), - m_type(Type::Default) + m_functionStore(functionStore) { m_graphRange->setDelegate(this); } const char * GraphController::title() { - switch(m_type) { - case Type::Tangent: + switch(type()) { + case GraphView::Type::Tangent: return I18n::translate(I18n::Message::Tangent); default: return I18n::translate(I18n::Message::GraphTab); @@ -35,21 +34,30 @@ I18n::Message GraphController::emptyMessage() { } bool GraphController::handleEvent(Ion::Events::Event event) { - if (m_type == Type::Default || event == Ion::Events::Left || event == Ion::Events::Right || event == Ion::Events::Plus || event == Ion::Events::Minus) { + 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); } - // TODO: handle for type != Type::Default - if (m_type != Type::Default && event == Ion::Events::Back) { - stackController()->handleEvent(event); - setType(Type::Default); - setParentResponder(static_cast(app())->graphControllerParent()); + if (type() != GraphView::Type::Default && (event == Ion::Events::Back || event == Ion::Events::OK)) { + App * a = static_cast(app()); + stackController()->handleEvent(Ion::Events::Back); + setType(GraphView::Type::Default); + setParentResponder(a->graphControllerParent()); return true; } return false; } -void GraphController::setType(Type type) { - m_type = type; +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); + } +} + +GraphView::Type GraphController::type() const { + return m_view.type(); } BannerView * GraphController::bannerView() { @@ -57,7 +65,7 @@ BannerView * GraphController::bannerView() { } void GraphController::reloadBannerView() { - // TODO: do something else if m_type == Type::tangent + // TODO: do something else if type() == GraphView::Type::tangent FunctionGraphController::reloadBannerView(); if (!m_bannerView.displayDerivative()) { return; @@ -121,7 +129,7 @@ CurveParameterController * GraphController::curveParameterController() { } StackViewController * GraphController::stackController() const{ - if (m_type != Type::Default) { + 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 ca9e4c9cd..df2cc4dd3 100644 --- a/apps/graph/graph/graph_controller.h +++ b/apps/graph/graph/graph_controller.h @@ -13,17 +13,13 @@ namespace Graph { class GraphController : public Shared::FunctionGraphController { public: - enum class Type { - Default, - Tangent, - Integral - }; 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(Type type); + void setType(GraphView::Type type); private: + GraphView::Type type() const; BannerView * bannerView() override; void reloadBannerView() override; bool moveCursorHorizontally(int direction) override; @@ -38,7 +34,6 @@ private: Shared::InteractiveCurveViewRange * m_graphRange; CurveParameterController m_curveParameterController; CartesianFunctionStore * m_functionStore; - Type m_type; }; } diff --git a/apps/graph/graph/graph_view.cpp b/apps/graph/graph/graph_view.cpp index 9ee339f00..8b8fe0726 100644 --- a/apps/graph/graph/graph_view.cpp +++ b/apps/graph/graph/graph_view.cpp @@ -7,10 +7,18 @@ namespace Graph { GraphView::GraphView(CartesianFunctionStore * functionStore, InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor, BannerView * bannerView, View * cursorView) : FunctionGraphView(graphRange, cursor, bannerView, cursorView), - m_functionStore(functionStore) + m_functionStore(functionStore), + m_type(Type::Default) { } +void GraphView::reload() { + if (m_type == Type::Tangent) { + markRectAsDirty(bounds()); + } + return FunctionGraphView::reload(); +} + void GraphView::drawRect(KDContext * ctx, KDRect rect) const { FunctionGraphView::drawRect(ctx, rect); for (int i = 0; i < m_functionStore->numberOfActiveFunctions(); i++) { @@ -20,6 +28,15 @@ void GraphView::drawRect(KDContext * ctx, KDRect rect) const { Poincare::Context * c = (Poincare::Context *)context; return f->evaluateAtAbscissa(t, c); }, f, context(), f->color()); + if (m_type == Type::Tangent && f == m_selectedFunction) { + float tangentParameter[2]; + tangentParameter[0] = f->approximateDerivative(m_curveViewCursor->x(), context()); + tangentParameter[1] = -tangentParameter[0]*m_curveViewCursor->x()+f->evaluateAtAbscissa(m_curveViewCursor->x(), context()); + drawCurve(ctx, rect, [](float t, void * model, void * context) { + float * tangent = (float *)model; + return tangent[0]*t+tangent[1]; + }, tangentParameter, nullptr, KDColorBlack); + } } } diff --git a/apps/graph/graph/graph_view.h b/apps/graph/graph/graph_view.h index 1692f681f..84a30e526 100644 --- a/apps/graph/graph/graph_view.h +++ b/apps/graph/graph/graph_view.h @@ -8,11 +8,20 @@ namespace Graph { class GraphView : public Shared::FunctionGraphView { public: + enum class Type { + Default, + Tangent, + Integral + }; GraphView(CartesianFunctionStore * functionStore, Shared::InteractiveCurveViewRange * graphRange, Shared::CurveViewCursor * cursor, Shared::BannerView * bannerView, View * cursorView); + void reload() override; void drawRect(KDContext * ctx, KDRect rect) const override; + Type type() const { return m_type; } + void setType(Type type) { m_type = type; } private: CartesianFunctionStore * m_functionStore; + Type m_type; }; } diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index e87df7956..7b1daa12a 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -13,8 +13,8 @@ CurveView::CurveView(CurveViewRange * curveViewRange, CurveViewCursor * curveVie View * cursorView, View * okView) : View(), m_bannerView(bannerView), - m_curveViewRange(curveViewRange), m_curveViewCursor(curveViewCursor), + m_curveViewRange(curveViewRange), m_cursorView(cursorView), m_okView(okView), m_mainViewSelected(false), diff --git a/apps/shared/curve_view.h b/apps/shared/curve_view.h index 610ddaed0..590a8d29f 100644 --- a/apps/shared/curve_view.h +++ b/apps/shared/curve_view.h @@ -56,6 +56,7 @@ protected: void drawLabels(KDContext * ctx, KDRect rect, Axis axis, bool shiftOrigin) const; virtual KDSize cursorSize(); View * m_bannerView; + CurveViewCursor * m_curveViewCursor; private: /* The window bounds are deduced from the model bounds but also take into account a margin (computed with k_marginFactor) */ @@ -80,7 +81,6 @@ private: /* m_curveViewRange has to be non null but the cursor model, the banner and * cursor views may be nullptr if not needed. */ CurveViewRange * m_curveViewRange; - CurveViewCursor * m_curveViewCursor; View * m_cursorView; View * m_okView; bool m_mainViewSelected;