From e9974a216df6dc5948eb633e41e2e8259730633f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Mon, 23 Sep 2019 15:30:56 +0200 Subject: [PATCH] [apps/graph] If only cartesians, jump to next curve when out of range MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Scenario: -----------• ->press "right": the cursor goes on the lower curve -*-*-*-*-*- --- apps/graph/graph/graph_controller.cpp | 48 ++++++++++++++++++++ apps/graph/graph/graph_controller.h | 1 + apps/graph/graph/graph_controller_helper.cpp | 8 ++++ apps/graph/graph/graph_controller_helper.h | 1 + apps/shared/function_graph_controller.cpp | 2 +- 5 files changed, 59 insertions(+), 1 deletion(-) diff --git a/apps/graph/graph/graph_controller.cpp b/apps/graph/graph/graph_controller.cpp index 6dec7b2cd..48e842e5b 100644 --- a/apps/graph/graph/graph_controller.cpp +++ b/apps/graph/graph/graph_controller.cpp @@ -8,6 +8,8 @@ namespace Graph { static inline float minFloat(float x, float y) { return x < y ? x : y; } static inline float maxFloat(float x, float y) { return x > y ? x : y; } +static inline double minDouble(double x, double y) { return x < y ? x : y; } +static inline double maxDouble(double x, double y) { return x > y ? x : y; } GraphController::GraphController(Responder * parentResponder, ::InputEventHandlerDelegate * inputEventHandlerDelegate, Shared::InteractiveCurveViewRange * curveViewRange, CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * rangeVersion, Poincare::Preferences::AngleUnit * angleUnitVersion, ButtonRowController * header) : FunctionGraphController(parentResponder, inputEventHandlerDelegate, header, curveViewRange, &m_view, cursor, indexFunctionSelectedByCursor, modelVersion, rangeVersion, angleUnitVersion), @@ -172,4 +174,50 @@ bool GraphController::shouldSetDefaultOnModelChange() const { return functionStore()->displaysNonCartesianFunctions(); } +void GraphController::jumpToLeftRightCurve(double t, int direction, int functionsCount, Ion::Storage::Record record) { + if (functionsCount == 1) { + return; + } + int nextCurveIndex = -1; + double xDelta = DBL_MAX; + for (int i = 0; i < functionsCount; i++) { + Ion::Storage::Record currentRecord = functionStore()->activeRecordAtIndex(i); + if (currentRecord == record) { + continue; + } + ExpiringPointer f = functionStore()->modelForRecord(currentRecord); + assert(f->plotType() == ContinuousFunction::PlotType::Cartesian); + // Select the closest horizontal curve + double currentTMin = f->tMin(); + double currentTMax = f->tMax(); + assert(!std::isnan(currentTMin)); + assert(!std::isnan(currentTMax)); + if ((direction > 0 && currentTMax > t) + ||(direction < 0 && currentTMin < t)) + { + double currentXDelta = direction > 0 ? + (t >= currentTMin ? 0.0 : currentTMin - t) : + (t <= currentTMax ? 0.0 : t - currentTMax); + assert(currentXDelta >= 0.0); + if (currentXDelta < xDelta) { + nextCurveIndex = i; + xDelta = currentXDelta; + } + } + } + if (nextCurveIndex < 0) { + return; + } + Ion::Storage::Record currentRecord = functionStore()->activeRecordAtIndex(nextCurveIndex); + ExpiringPointer f = functionStore()->modelForRecord(currentRecord); + + double nextTMin = f->tMin(); + double nextTMax = f->tMax(); + double nextT = maxDouble(nextTMin, minDouble(nextTMax, t)); + Coordinate2D xy = f->evaluateXYAtParameter(nextT, App::app()->localContext()); + m_cursor->moveTo(nextT, xy.x1(), xy.x2()); + selectFunctionWithCursor(nextCurveIndex); + return; +} + } diff --git a/apps/graph/graph/graph_controller.h b/apps/graph/graph/graph_controller.h index 44231243f..74f2f1105 100644 --- a/apps/graph/graph/graph_controller.h +++ b/apps/graph/graph/graph_controller.h @@ -37,6 +37,7 @@ private: bool defautRangeIsNormalized() const override; void interestingFunctionRange(Shared::ExpiringPointer f, float tMin, float tMax, float step, float * xm, float * xM, float * ym, float * yM) const; bool shouldSetDefaultOnModelChange() const override; + void jumpToLeftRightCurve(double t, int direction, int functionsCount, Ion::Storage::Record record) override; Shared::RoundCursorView m_cursorView; BannerView m_bannerView; diff --git a/apps/graph/graph/graph_controller_helper.cpp b/apps/graph/graph/graph_controller_helper.cpp index f3e61fd8b..ef10258be 100644 --- a/apps/graph/graph/graph_controller_helper.cpp +++ b/apps/graph/graph/graph_controller_helper.cpp @@ -19,6 +19,14 @@ bool GraphControllerHelper::privateMoveCursorHorizontally(Shared::CurveViewCurso double t = tCursorPosition; double tMin = function->tMin(); double tMax = function->tMax(); + int functionsCount = -1; + if (((direction > 0 && std::abs(t-tMax) < DBL_EPSILON) + || (direction < 0 && std::abs(t-tMin) < DBL_EPSILON)) + && !App::app()->functionStore()->displaysNonCartesianFunctions(&functionsCount)) + { + jumpToLeftRightCurve(t, direction, functionsCount, record); + return true; + } double dir = (direction > 0 ? 1.0 : -1.0); ContinuousFunction::PlotType type = function->plotType(); if (type == ContinuousFunction::PlotType::Cartesian) { diff --git a/apps/graph/graph/graph_controller_helper.h b/apps/graph/graph/graph_controller_helper.h index 2a143e76f..8f8e2a7b7 100644 --- a/apps/graph/graph/graph_controller_helper.h +++ b/apps/graph/graph/graph_controller_helper.h @@ -16,6 +16,7 @@ protected: virtual BannerView * bannerView() = 0; private: static constexpr double k_definitionDomainDivisor = 96.0; + virtual void jumpToLeftRightCurve(double t, int direction, int functionsCount, Ion::Storage::Record record) {} }; } diff --git a/apps/shared/function_graph_controller.cpp b/apps/shared/function_graph_controller.cpp index 17156f3a8..3ed0261c2 100644 --- a/apps/shared/function_graph_controller.cpp +++ b/apps/shared/function_graph_controller.cpp @@ -157,9 +157,9 @@ bool FunctionGraphController::moveCursorVertically(int direction) { if (nextActiveFunctionIndex < 0) { return false; } - selectFunctionWithCursor(nextActiveFunctionIndex); Poincare::Coordinate2D cursorPosition = xyValues(nextActiveFunctionIndex, m_cursor->t(), context); m_cursor->moveTo(m_cursor->t(), cursorPosition.x1(), cursorPosition.x2()); + selectFunctionWithCursor(nextActiveFunctionIndex); return true; }