[apps/graph] Take cursor into account for Y range

Additional checks have been added to ensure that the first move of the
cursor from the center of the graph would not cause the window to pan up
or down.

Change-Id: I44d7e86223941076cbf03db7a221e9c0427a64e4
This commit is contained in:
Gabriel Ozouf
2020-08-05 14:07:02 +02:00
committed by Émilie Feral
parent 0ed0cc56e9
commit 17f39e5e39
4 changed files with 40 additions and 24 deletions

View File

@@ -39,23 +39,21 @@ bool GraphController::defaultRangeIsNormalized() const {
return functionStore()->displaysNonCartesianFunctions();
}
void GraphController::interestingRanges(float * xm, float * xM, float * ym, float * yM) const {
privateComputeRanges(true, xm, xM, ym, yM);
void GraphController::interestingRanges(InteractiveCurveViewRange * range) const {
privateComputeRanges(true, range);
}
Shared::InteractiveCurveViewRangeDelegate::Range GraphController::computeYRange(Shared::InteractiveCurveViewRange * interactiveCurveViewRange) {
float xm = interactiveCurveViewRange->xMin(),
xM = interactiveCurveViewRange->xMax(),
ym = FLT_MAX,
yM = -FLT_MAX;
privateComputeRanges(false, &xm, &xM, &ym, &yM);
return Shared::InteractiveCurveViewRangeDelegate::Range{.min = ym, .max = yM};
InteractiveCurveViewRange tempRange = *interactiveCurveViewRange;
tempRange.setYAuto(false);
privateComputeRanges(false, &tempRange);
return Shared::InteractiveCurveViewRangeDelegate::Range{.min = tempRange.yMin(), .max = tempRange.yMax()};
}
void GraphController::privateComputeRanges(bool tuneXRange, float * xm, float * xM, float * ym, float * yM) const {
void GraphController::privateComputeRanges(bool tuneXRange, InteractiveCurveViewRange * range) const {
Poincare::Context * context = textFieldDelegateApp()->localContext();
float resultXMin = tuneXRange ? FLT_MAX : *xm;
float resultXMax = tuneXRange ? -FLT_MAX : *xM;
float resultXMin = tuneXRange ? FLT_MAX : range->xMin();
float resultXMax = tuneXRange ? -FLT_MAX : range->xMax();
float resultYMin = FLT_MAX;
float resultYMax = -FLT_MAX;
assert(functionStore()->numberOfActiveFunctions() > 0);
@@ -65,10 +63,32 @@ void GraphController::privateComputeRanges(bool tuneXRange, float * xm, float *
f->rangeForDisplay(&resultXMin, &resultXMax, &resultYMin, &resultYMax, context, tuneXRange);
}
*xm = resultXMin;
*xM = resultXMax;
*ym = resultYMin;
*yM = resultYMax;
range->setXMin(resultXMin);
range->setXMax(resultXMax);
range->setYMin(resultYMin);
range->setYMax(resultYMax);
/* We can only call this method once the X range has been fully computed. */
yRangeForCursorFirstMove(range);
}
void GraphController::yRangeForCursorFirstMove(InteractiveCurveViewRange * range) const {
Poincare::Context * context = textFieldDelegateApp()->localContext();
assert(functionStore()->numberOfActiveFunctions() > 0);
int functionsCount = functionStore()->numberOfActiveFunctions();
float cursorStep = range->xGridUnit() / k_numberOfCursorStepsInGradUnit;
float yN, yP;
for (int i = 0; i < functionsCount; i++) {
ExpiringPointer<ContinuousFunction> f = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(i));
if (f->plotType() != ContinuousFunction::PlotType::Cartesian) {
continue;
}
yN = f->evaluateXYAtParameter(range->xCenter() - cursorStep, context).x2();
yP = f->evaluateXYAtParameter(range->xCenter() + cursorStep, context).x2();
range->setYMin(std::min(range->yMin(), std::min(yN, yP)));
range->setYMax(std::max(range->yMax(), std::max(yN, yP)));
}
}
void GraphController::selectFunctionWithCursor(int functionIndex) {

View File

@@ -20,7 +20,7 @@ public:
void viewWillAppear() override;
bool displayDerivativeInBanner() const { return m_displayDerivativeInBanner; }
void setDisplayDerivativeInBanner(bool displayDerivative) { m_displayDerivativeInBanner = displayDerivative; }
void interestingRanges(float * xm, float * xM, float * ym, float * yM) const override;
void interestingRanges(Shared::InteractiveCurveViewRange * range) const override;
private:
int estimatedBannerNumberOfLines() const override { return 1 + m_displayDerivativeInBanner; }
void selectFunctionWithCursor(int functionIndex) override;
@@ -38,7 +38,8 @@ private:
bool shouldSetDefaultOnModelChange() const override;
void jumpToLeftRightCurve(double t, int direction, int functionsCount, Ion::Storage::Record record) override;
Range computeYRange(Shared::InteractiveCurveViewRange * interactiveCurveViewRange) override;
void privateComputeRanges(bool tuneXRange, float * xm, float * xM, float * ym, float * yM) const;
void privateComputeRanges(bool tuneXRange, Shared::InteractiveCurveViewRange * range) const;
void yRangeForCursorFirstMove(Shared::InteractiveCurveViewRange * range) const;
Shared::RoundCursorView m_cursorView;
BannerView m_bannerView;

View File

@@ -135,12 +135,7 @@ void InteractiveCurveViewRange::setDefault() {
// Compute the interesting range
m_yAuto = false;
float xm, xM, ym, yM;
m_delegate->interestingRanges(&xm, &xM, &ym, &yM);
m_xRange.setMin(xm, k_lowerMaxFloat, k_upperMaxFloat);
m_xRange.setMax(xM, k_lowerMaxFloat, k_upperMaxFloat);
m_yRange.setMin(ym, k_lowerMaxFloat, k_upperMaxFloat);
m_yRange.setMax(yM, k_lowerMaxFloat, k_upperMaxFloat);
m_delegate->interestingRanges(this);
// Add margins
float xRange = xMax() - xMin();

View File

@@ -13,7 +13,7 @@ public:
virtual float interestingXMin() const { return -interestingXHalfRange(); }
virtual float interestingXHalfRange() const { return 10.0f; }
virtual bool defaultRangeIsNormalized() const { return false; }
virtual void interestingRanges(float * xm, float * xM, float * ym, float * yM) const { assert(false); }
virtual void interestingRanges(InteractiveCurveViewRange * range) const { assert(false); }
virtual float addMargin(float x, float range, bool isVertical, bool isMin) = 0;
protected:
struct Range {