diff --git a/apps/graph/graph/calculation_graph_controller.cpp b/apps/graph/graph/calculation_graph_controller.cpp index b5849d74d..73c95a9e0 100644 --- a/apps/graph/graph/calculation_graph_controller.cpp +++ b/apps/graph/graph/calculation_graph_controller.cpp @@ -30,7 +30,7 @@ void CalculationGraphController::viewWillAppear() { m_isActive = true; assert(App::app()->functionStore()->modelForRecord(m_record)->plotType() == Shared::ContinuousFunction::PlotType::Cartesian); m_cursor->moveTo(pointOfInterest.x1(), pointOfInterest.x1(), pointOfInterest.x2()); - m_graphRange->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); + m_graphRange->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio, curveView()->pixelWidth()); m_bannerView->setNumberOfSubviews(Shared::XYBannerView::k_numberOfSubviews); reloadBannerView(); } diff --git a/apps/graph/graph/tangent_graph_controller.cpp b/apps/graph/graph/tangent_graph_controller.cpp index afc41f941..5edf674d8 100644 --- a/apps/graph/graph/tangent_graph_controller.cpp +++ b/apps/graph/graph/tangent_graph_controller.cpp @@ -24,7 +24,7 @@ const char * TangentGraphController::title() { void TangentGraphController::viewWillAppear() { Shared::SimpleInteractiveCurveViewController::viewWillAppear(); - m_graphRange->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); + m_graphRange->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio, curveView()->pixelWidth()); m_graphView->drawTangent(true); m_graphView->setOkView(nullptr); m_graphView->selectMainView(true); @@ -51,7 +51,7 @@ bool TangentGraphController::textFieldDidFinishEditing(TextField * textField, co assert(function->plotType() == Shared::ContinuousFunction::PlotType::Cartesian); double y = function->evaluate2DAtParameter(floatBody, myApp->localContext()).x2(); m_cursor->moveTo(floatBody, floatBody, y); - interactiveCurveViewRange()->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); + interactiveCurveViewRange()->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio, curveView()->pixelWidth()); reloadBannerView(); curveView()->reload(); return true; diff --git a/apps/regression/graph_controller.cpp b/apps/regression/graph_controller.cpp index 519713002..dec921c63 100644 --- a/apps/regression/graph_controller.cpp +++ b/apps/regression/graph_controller.cpp @@ -262,7 +262,7 @@ void GraphController::initCursorParameters() { double y = m_store->meanOfColumn(*m_selectedSeriesIndex, 1); m_cursor->moveTo(x, x, y); if (m_store->yAuto()) { - m_store->panToMakePointVisible(x, y, cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); + m_store->panToMakePointVisible(x, y, cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio, curveView()->pixelWidth()); } *m_selectedDotIndex = m_store->numberOfPairsOfSeries(*m_selectedSeriesIndex); } diff --git a/apps/sequence/graph/graph_controller.cpp b/apps/sequence/graph/graph_controller.cpp index 76a7d771a..a0552361e 100644 --- a/apps/sequence/graph/graph_controller.cpp +++ b/apps/sequence/graph/graph_controller.cpp @@ -67,7 +67,7 @@ bool GraphController::textFieldDidFinishEditing(TextField * textField, const cha floatBody = std::fmax(0, std::round(floatBody)); double y = xyValues(selectedCurveIndex(), floatBody, myApp->localContext()).x2(); m_cursor->moveTo(floatBody, floatBody, y); - interactiveCurveViewRange()->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); + interactiveCurveViewRange()->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio, curveView()->pixelWidth()); reloadBannerView(); m_view.reload(); return true; diff --git a/apps/shared/function_graph_controller.cpp b/apps/shared/function_graph_controller.cpp index 21b3c652b..04a08dec4 100644 --- a/apps/shared/function_graph_controller.cpp +++ b/apps/shared/function_graph_controller.cpp @@ -146,7 +146,7 @@ void FunctionGraphController::initCursorParameters() { } m_cursor->moveTo(t, xy.x1(), xy.x2()); if (interactiveCurveViewRange()->yAuto()) { - interactiveCurveViewRange()->panToMakePointVisible(xy.x1(), xy.x2(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); + interactiveCurveViewRange()->panToMakePointVisible(xy.x1(), xy.x2(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio, curveView()->pixelWidth()); } selectFunctionWithCursor(functionIndex); } diff --git a/apps/shared/interactive_curve_view_controller.cpp b/apps/shared/interactive_curve_view_controller.cpp index c6b736296..1d2f23bae 100644 --- a/apps/shared/interactive_curve_view_controller.cpp +++ b/apps/shared/interactive_curve_view_controller.cpp @@ -93,7 +93,8 @@ bool InteractiveCurveViewController::handleEvent(Ion::Events::Event event) { if (moveCursorVertically(direction)) { interactiveCurveViewRange()->panToMakePointVisible( m_cursor->x(), m_cursor->y(), - cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio + cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio, + curveView()->pixelWidth() ); reloadBannerView(); curveView()->reload(); @@ -220,7 +221,7 @@ bool InteractiveCurveViewController::textFieldDidFinishEditing(TextField * textF } Coordinate2D xy = xyValues(selectedCurveIndex(), floatBody, textFieldDelegateApp()->localContext()); m_cursor->moveTo(floatBody, xy.x1(), xy.x2()); - interactiveCurveViewRange()->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); + interactiveCurveViewRange()->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio, curveView()->pixelWidth()); reloadBannerView(); curveView()->reload(); return true; diff --git a/apps/shared/interactive_curve_view_range.cpp b/apps/shared/interactive_curve_view_range.cpp index 9e733b874..4b09d3b97 100644 --- a/apps/shared/interactive_curve_view_range.cpp +++ b/apps/shared/interactive_curve_view_range.cpp @@ -199,20 +199,23 @@ void InteractiveCurveViewRange::centerAxisAround(Axis axis, float position) { } } -void InteractiveCurveViewRange::panToMakePointVisible(float x, float y, float topMarginRatio, float rightMarginRatio, float bottomMarginRatio, float leftMarginRatio) { +void InteractiveCurveViewRange::panToMakePointVisible(float x, float y, float topMarginRatio, float rightMarginRatio, float bottomMarginRatio, float leftMarginRatio, float pixelWidth) { if (!std::isinf(x) && !std::isnan(x)) { const float xRange = xMax() - xMin(); const float leftMargin = leftMarginRatio * xRange; if (x < xMin() + leftMargin) { m_yAuto = false; - const float newXMin = x - leftMargin; + /* The panning increment is a whole number of pixels so that the caching + * for cartesian functions is not invalidated. */ + const float newXMin = std::floor((x - leftMargin - xMin()) / pixelWidth) * pixelWidth + xMin(); m_xRange.setMax(newXMin + xRange, k_lowerMaxFloat, k_upperMaxFloat); MemoizedCurveViewRange::protectedSetXMin(newXMin, k_lowerMaxFloat, k_upperMaxFloat); } const float rightMargin = rightMarginRatio * xRange; if (x > xMax() - rightMargin) { m_yAuto = false; - m_xRange.setMax(x + rightMargin, k_lowerMaxFloat, k_upperMaxFloat); + const float newXMax = std::ceil((x + rightMargin - xMax()) / pixelWidth) * pixelWidth + xMax(); + m_xRange.setMax(newXMax, k_lowerMaxFloat, k_upperMaxFloat); MemoizedCurveViewRange::protectedSetXMin(xMax() - xRange, k_lowerMaxFloat, k_upperMaxFloat); } } diff --git a/apps/shared/interactive_curve_view_range.h b/apps/shared/interactive_curve_view_range.h index f6484017a..1c6d308a2 100644 --- a/apps/shared/interactive_curve_view_range.h +++ b/apps/shared/interactive_curve_view_range.h @@ -37,7 +37,7 @@ public: virtual void setTrigonometric(); virtual void setDefault(); void centerAxisAround(Axis axis, float position); - void panToMakePointVisible(float x, float y, float topMarginRatio, float rightMarginRatio, float bottomMarginRation, float leftMarginRation); + void panToMakePointVisible(float x, float y, float topMarginRatio, float rightMarginRatio, float bottomMarginRation, float leftMarginRation, float pixelWidth); protected: constexpr static float k_upperMaxFloat = 1E+8f; constexpr static float k_lowerMaxFloat = 9E+7f; diff --git a/apps/shared/simple_interactive_curve_view_controller.cpp b/apps/shared/simple_interactive_curve_view_controller.cpp index c9220f3d9..10d079984 100644 --- a/apps/shared/simple_interactive_curve_view_controller.cpp +++ b/apps/shared/simple_interactive_curve_view_controller.cpp @@ -31,7 +31,8 @@ bool SimpleInteractiveCurveViewController::handleLeftRightEvent(Ion::Events::Eve if (moveCursorHorizontally(direction, Ion::Events::repetitionFactor())) { interactiveCurveViewRange()->panToMakePointVisible( m_cursor->x(), m_cursor->y(), - cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio + cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio, + curveView()->pixelWidth() ); reloadBannerView(); curveView()->reload(); diff --git a/apps/shared/sum_graph_controller.cpp b/apps/shared/sum_graph_controller.cpp index ac5ce035e..5a3282914 100644 --- a/apps/shared/sum_graph_controller.cpp +++ b/apps/shared/sum_graph_controller.cpp @@ -26,7 +26,7 @@ SumGraphController::SumGraphController(Responder * parentResponder, InputEventHa void SumGraphController::viewWillAppear() { SimpleInteractiveCurveViewController::viewWillAppear(); - m_graphRange->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); + m_graphRange->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio, curveView()->pixelWidth()); m_graphView->setBannerView(&m_legendView); m_graphView->setCursorView(&m_cursorView); m_graphView->setOkView(nullptr); @@ -77,7 +77,7 @@ bool SumGraphController::moveCursorHorizontallyToPosition(double x) { m_graphView->setAreaHighlight(m_startSum, m_cursor->x()); } m_legendView.setEditableZone(m_cursor->x()); - m_graphRange->panToMakePointVisible(x, y, cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); + m_graphRange->panToMakePointVisible(x, y, cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio, curveView()->pixelWidth()); m_graphView->reload(); return true; }