Files
Upsilon/apps/graph/graph/graph_controller_helper.cpp
Léa Saviot 1434158bee [apps/graph] Faster curve navigation after some time
If the user presses the LEft/Right keys for a long time, the cursor will
move faster.
2020-02-12 15:13:15 +01:00

61 lines
2.9 KiB
C++

#include "graph_controller_helper.h"
#include "../../shared/function_banner_delegate.h"
#include "../app.h"
#include "../../shared/poincare_helpers.h"
#include <poincare/preferences.h>
using namespace Shared;
using namespace Poincare;
namespace Graph {
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; }
bool GraphControllerHelper::privateMoveCursorHorizontally(Shared::CurveViewCursor * cursor, int direction, Shared::InteractiveCurveViewRange * range, int numberOfStepsInGradUnit, Ion::Storage::Record record, bool fast) {
ExpiringPointer<ContinuousFunction> function = App::app()->functionStore()->modelForRecord(record);
double tCursorPosition = cursor->t();
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;
}
function = App::app()->functionStore()->modelForRecord(record); // Reload the expiring pointer
double dir = (direction > 0 ? 1.0 : -1.0);
double step = function->plotType() == ContinuousFunction::PlotType::Cartesian ? range->xGridUnit()/numberOfStepsInGradUnit : (tMax-tMin)/k_definitionDomainDivisor;
if (fast) {
// TODO Navigate quicker the longer the user presses? (slow start)
step *= 5.0;
}
t += dir * step;
t = maxDouble(tMin, minDouble(tMax, t));
Coordinate2D<double> xy = function->evaluateXYAtParameter(t, App::app()->localContext());
cursor->moveTo(t, xy.x1(), xy.x2());
return true;
}
void GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(Shared::CurveViewCursor * cursor, Ion::Storage::Record record) {
ExpiringPointer<ContinuousFunction> function = App::app()->functionStore()->modelForRecord(record);
constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters+PrintFloat::charSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits);
char buffer[bufferSize];
const char * space = " ";
int numberOfChar = function->derivativeNameWithArgument(buffer, bufferSize);
const char * legend = "=";
assert(numberOfChar <= bufferSize);
numberOfChar += strlcpy(buffer+numberOfChar, legend, bufferSize-numberOfChar);
double y = function->approximateDerivative(cursor->x(), App::app()->localContext());
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(y, buffer + numberOfChar, bufferSize-numberOfChar, Preferences::ShortNumberOfSignificantDigits);
assert(numberOfChar <= bufferSize);
strlcpy(buffer+numberOfChar, space, bufferSize-numberOfChar);
bannerView()->derivativeView()->setText(buffer);
bannerView()->reload();
}
}