diff --git a/apps/regression/app.cpp b/apps/regression/app.cpp index baba7059a..4f2aeaa58 100644 --- a/apps/regression/app.cpp +++ b/apps/regression/app.cpp @@ -45,6 +45,10 @@ App::Descriptor * App::Snapshot::descriptor() { return &descriptor; } +void App::Snapshot::tidy() { + m_store.setDelegate(nullptr); +} + App::App(Container * container, Snapshot * snapshot) : TextFieldDelegateApp(container, snapshot, &m_tabViewController), m_calculationController(&m_calculationAlternateEmptyViewController, &m_calculationHeader, snapshot->store()), diff --git a/apps/regression/app.h b/apps/regression/app.h index 061dccfae..f32116243 100644 --- a/apps/regression/app.h +++ b/apps/regression/app.h @@ -32,6 +32,7 @@ public: uint32_t * modelVersion() { return &m_modelVersion; } uint32_t * rangeVersion() { return &m_rangeVersion; } private: + void tidy() override; Store m_store; Shared::CurveViewCursor m_cursor; int m_graphSelectedDotIndex; diff --git a/apps/regression/graph_controller.cpp b/apps/regression/graph_controller.cpp index 7df88df87..96014daa0 100644 --- a/apps/regression/graph_controller.cpp +++ b/apps/regression/graph_controller.cpp @@ -1,10 +1,14 @@ #include "graph_controller.h" #include "../apps_container.h" +#include #include using namespace Poincare; using namespace Shared; +static inline float min(float x, float y) { return (xy ? x : y); } + namespace Regression { GraphController::GraphController(Responder * parentResponder, ButtonRowController * header, Store * store, CurveViewCursor * cursor, uint32_t * modelVersion, uint32_t * rangeVersion, int * selectedDotIndex, int * selectedSeriesIndex) : @@ -23,6 +27,7 @@ GraphController::GraphController(Responder * parentResponder, ButtonRowControlle m_modelType[i] = (Model::Type) -1; } m_store->setCursor(m_cursor); + m_store->setDelegate(this); } ViewController * GraphController::initialisationParameterController() { @@ -230,7 +235,7 @@ void GraphController::initCursorParameters() { double x = m_store->meanOfColumn(*m_selectedSeriesIndex, 0); double y = m_store->meanOfColumn(*m_selectedSeriesIndex, 1); m_cursor->moveTo(x, y); - m_store->panToMakePointVisible(x, y, k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio); + m_store->panToMakePointVisible(x, y, cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); *m_selectedDotIndex = m_store->numberOfPairsOfSeries(*m_selectedSeriesIndex); } @@ -240,13 +245,13 @@ bool GraphController::moveCursorHorizontally(int direction) { if (dotSelected >= 0 && dotSelected < m_store->numberOfPairsOfSeries(*m_selectedSeriesIndex)) { *m_selectedDotIndex = dotSelected; m_cursor->moveTo(m_store->get(*m_selectedSeriesIndex, 0, *m_selectedDotIndex), m_store->get(*m_selectedSeriesIndex, 1, *m_selectedDotIndex)); - m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio); + m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); return true; } if (dotSelected == m_store->numberOfPairsOfSeries(*m_selectedSeriesIndex)) { *m_selectedDotIndex = dotSelected; m_cursor->moveTo(m_store->meanOfColumn(*m_selectedSeriesIndex, 0), m_store->meanOfColumn(*m_selectedSeriesIndex, 1)); - m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio); + m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); return true; } return false; @@ -256,7 +261,7 @@ bool GraphController::moveCursorHorizontally(int direction) { Poincare::Context * globContext = const_cast(static_cast(app()->container()))->globalContext(); double y = m_store->yValueForXValue(*m_selectedSeriesIndex, x, globContext); m_cursor->moveTo(x, y); - m_store->panToMakePointVisible(x, y, k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio); + m_store->panToMakePointVisible(x, y, cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); return true; } @@ -317,7 +322,7 @@ bool GraphController::moveCursorVertically(int direction) { *m_selectedSeriesIndex = closestRegressionSeries; selectRegressionCurve(); m_cursor->moveTo(m_cursor->x(), m_store->yValueForXValue(*m_selectedSeriesIndex, m_cursor->x(), globContext)); - m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio); + m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); return true; } @@ -327,11 +332,11 @@ bool GraphController::moveCursorVertically(int direction) { *m_selectedDotIndex = dotSelected; if (dotSelected == m_store->numberOfPairsOfSeries(*m_selectedSeriesIndex)) { m_cursor->moveTo(m_store->meanOfColumn(*m_selectedSeriesIndex, 0), m_store->meanOfColumn(*m_selectedSeriesIndex, 1)); - m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio); + m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); return true; } m_cursor->moveTo(m_store->get(*m_selectedSeriesIndex, 0, *m_selectedDotIndex), m_store->get(*m_selectedSeriesIndex, 1, *m_selectedDotIndex)); - m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio); + m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); return true; } return false; @@ -346,7 +351,46 @@ uint32_t GraphController::rangeVersion() { } bool GraphController::isCursorVisible() { - return interactiveCurveViewRange()->isCursorVisible(k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio); + return interactiveCurveViewRange()->isCursorVisible(cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); +} + +float GraphController::cursorBottomMarginRatio() { + float f = (m_view.cursorView()->minimalSizeForOptimalDisplay().height()/2 + 2 + estimatedBannerHeight())/k_viewHeight; + return f; +} + +float GraphController::displayTopMarginRatio() { + return 0.12f; // cursorHeight/graphViewHeight +} + +float GraphController::displayBottomMarginRatio() { + float f = (m_view.cursorView()->minimalSizeForOptimalDisplay().height() + 2 + estimatedBannerHeight())/k_viewHeight; + return f; +} + +float GraphController::estimatedBannerHeight() const { + if (selectedSeriesIndex() < 0) { + return KDText::charSize(KDText::FontSize::Small).height() * 3; + } + float result = KDText::charSize(KDText::FontSize::Small).height() * m_store->modelForSeries(selectedSeriesIndex())->bannerLinesCount(); + return result; +} + +InteractiveCurveViewRangeDelegate::Range GraphController::computeYRange(InteractiveCurveViewRange * interactiveCurveViewRange) { + float minY = FLT_MAX; + float maxY = -FLT_MAX; + for (int series = 0; series < Store::k_numberOfSeries; series++) { + for (int k = 0; k < m_store->numberOfPairsOfSeries(series); k++) { + if (m_store->xMin() <= m_store->get(series, 0, k) && m_store->get(series, 0, k) <= m_store->xMax()) { + minY = min(minY, m_store->get(series, 1, k)); + maxY = max(maxY, m_store->get(series, 1, k)); + } + } + } + InteractiveCurveViewRangeDelegate::Range range; + range.min = minY; + range.max = maxY; + return range; } } diff --git a/apps/regression/graph_controller.h b/apps/regression/graph_controller.h index 4841cbab8..bf3abb67d 100644 --- a/apps/regression/graph_controller.h +++ b/apps/regression/graph_controller.h @@ -25,10 +25,9 @@ public: void selectRegressionCurve(); int selectedSeriesIndex() const { return *m_selectedSeriesIndex; } private: - constexpr static float k_cursorTopMarginRatio = 0.07f; // (cursorHeight/2)/graphViewHeight - constexpr static float k_cursorBottomMarginRatio = 0.3f; // (cursorHeight/2+bannerHeigh)/graphViewHeight constexpr static int k_maxLegendLength = 16; constexpr static int k_maxNumberOfCharacters = 50; + constexpr static float k_viewHeight = 174.0f; Shared::CurveView * curveView() override; Shared::InteractiveCurveViewRange * interactiveCurveViewRange() override; bool handleEnter() override; @@ -40,6 +39,18 @@ private: uint32_t modelVersion() override; uint32_t rangeVersion() override; bool isCursorVisible() override; + + // InteractiveCurveViewController + float displayTopMarginRatio() override; + float displayBottomMarginRatio() override; + + float cursorTopMarginRatio() { return 0.07f; } // (cursorHeight/2) / graphViewHeight + float cursorBottomMarginRatio(); + float estimatedBannerHeight() const; + + // InteractiveCurveViewRangeDelegate + Shared::InteractiveCurveViewRangeDelegate::Range computeYRange(Shared::InteractiveCurveViewRange * interactiveCurveViewRange) override; + Shared::CursorView m_crossCursorView; Shared::RoundCursorView m_roundCursorView; BannerView m_bannerView; diff --git a/apps/regression/model/cubic_model.h b/apps/regression/model/cubic_model.h index ff7405f3b..373d00129 100644 --- a/apps/regression/model/cubic_model.h +++ b/apps/regression/model/cubic_model.h @@ -15,6 +15,7 @@ public: double evaluate(double * modelCoefficients, double x) const override; double partialDerivate(double * modelCoefficients, int derivateCoefficientIndex, double x) const override; int numberOfCoefficients() const override { return 4; } + int bannerLinesCount() const override { return 4; } }; } diff --git a/apps/regression/model/exponential_model.h b/apps/regression/model/exponential_model.h index 93b176d4b..56bb30fa1 100644 --- a/apps/regression/model/exponential_model.h +++ b/apps/regression/model/exponential_model.h @@ -15,6 +15,7 @@ public: double levelSet(double * modelCoefficients, double xMin, double step, double xMax, double y, Poincare::Context * context) override; double partialDerivate(double * modelCoefficients, int derivateCoefficientIndex, double x) const override; int numberOfCoefficients() const override { return 2; } + int bannerLinesCount() const override { return 2; } }; } diff --git a/apps/regression/model/linear_model.h b/apps/regression/model/linear_model.h index 02bd357b9..69e6e3b57 100644 --- a/apps/regression/model/linear_model.h +++ b/apps/regression/model/linear_model.h @@ -16,6 +16,7 @@ public: virtual void fit(Store * store, int series, double * modelCoefficients, Poincare::Context * context) override; double partialDerivate(double * modelCoefficients, int derivateCoefficientIndex, double x) const override; int numberOfCoefficients() const override { return 2; } + int bannerLinesCount() const override { return 3; } }; } diff --git a/apps/regression/model/logarithmic_model.h b/apps/regression/model/logarithmic_model.h index 54b9c9053..8f429c822 100644 --- a/apps/regression/model/logarithmic_model.h +++ b/apps/regression/model/logarithmic_model.h @@ -15,6 +15,7 @@ public: double levelSet(double * modelCoefficients, double xMin, double step, double xMax, double y, Poincare::Context * context) override; double partialDerivate(double * modelCoefficients, int derivateCoefficientIndex, double x) const override; int numberOfCoefficients() const override { return 2; } + int bannerLinesCount() const override { return 2; } protected: virtual bool dataSuitableForFit(Store * store, int series) const override; }; diff --git a/apps/regression/model/logistic_model.h b/apps/regression/model/logistic_model.h index 3faffbe91..22934c214 100644 --- a/apps/regression/model/logistic_model.h +++ b/apps/regression/model/logistic_model.h @@ -15,6 +15,7 @@ public: double levelSet(double * modelCoefficients, double xMin, double step, double xMax, double y, Poincare::Context * context) override; double partialDerivate(double * modelCoefficients, int derivateCoefficientIndex, double x) const override; int numberOfCoefficients() const override { return 3; } + int bannerLinesCount() const override { return 3; } }; } diff --git a/apps/regression/model/model.h b/apps/regression/model/model.h index fbab15008..34df1fc04 100644 --- a/apps/regression/model/model.h +++ b/apps/regression/model/model.h @@ -34,6 +34,7 @@ public: virtual double levelSet(double * modelCoefficients, double xMin, double step, double xMax, double y, Poincare::Context * context); virtual void fit(Store * store, int series, double * modelCoefficients, Poincare::Context * context); virtual int numberOfCoefficients() const = 0; + virtual int bannerLinesCount() const { return 2; } protected: // Fit virtual bool dataSuitableForFit(Store * store, int series) const; diff --git a/apps/regression/model/power_model.h b/apps/regression/model/power_model.h index 8cc223cac..b9c2fafed 100644 --- a/apps/regression/model/power_model.h +++ b/apps/regression/model/power_model.h @@ -15,6 +15,7 @@ public: double levelSet(double * modelCoefficients, double xMin, double step, double xMax, double y, Poincare::Context * context) override; double partialDerivate(double * modelCoefficients, int derivateCoefficientIndex, double x) const override; int numberOfCoefficients() const override { return 2; } + int bannerLinesCount() const override { return 2; } protected: virtual bool dataSuitableForFit(Store * store, int series) const override; }; diff --git a/apps/regression/model/quadratic_model.h b/apps/regression/model/quadratic_model.h index c8481a87a..b7a73f38f 100644 --- a/apps/regression/model/quadratic_model.h +++ b/apps/regression/model/quadratic_model.h @@ -15,6 +15,7 @@ public: double evaluate(double * modelCoefficients, double x) const override; double partialDerivate(double * modelCoefficients, int derivateCoefficientIndex, double x) const override; int numberOfCoefficients() const override { return 3; } + int bannerLinesCount() const override { return 3; } }; } diff --git a/apps/regression/model/quartic_model.h b/apps/regression/model/quartic_model.h index 6c1d2ac46..c9d11db03 100644 --- a/apps/regression/model/quartic_model.h +++ b/apps/regression/model/quartic_model.h @@ -15,6 +15,7 @@ public: double evaluate(double * modelCoefficients, double x) const override; double partialDerivate(double * modelCoefficients, int derivateCoefficientIndex, double x) const override; int numberOfCoefficients() const override { return 5; } + int bannerLinesCount() const override { return 4; } }; } diff --git a/apps/regression/model/trigonometric_model.h b/apps/regression/model/trigonometric_model.h index 8d8602f67..e98a9d680 100644 --- a/apps/regression/model/trigonometric_model.h +++ b/apps/regression/model/trigonometric_model.h @@ -15,6 +15,7 @@ public: double evaluate(double * modelCoefficients, double x) const override; double partialDerivate(double * modelCoefficients, int derivateCoefficientIndex, double x) const override; int numberOfCoefficients() const override { return 4; } + int bannerLinesCount() const override { return 4; } }; } diff --git a/apps/regression/store.cpp b/apps/regression/store.cpp index 21380891a..bbd283767 100644 --- a/apps/regression/store.cpp +++ b/apps/regression/store.cpp @@ -26,7 +26,7 @@ static_assert(Model::k_numberOfModels == 9, "Number of models changed, Regressio static_assert(Store::k_numberOfSeries == 3, "Number of series changed, Regression::Store() needs to adapt (m_seriesChecksum)"); Store::Store() : - InteractiveCurveViewRange(nullptr, this), + InteractiveCurveViewRange(nullptr), DoublePairStore(), m_seriesChecksum{0, 0, 0}, m_angleUnit(Poincare::Expression::AngleUnit::Default) @@ -201,15 +201,15 @@ int Store::nextDot(int series, int direction, int dot) { void Store::setDefault() { float minX = FLT_MAX; float maxX = -FLT_MAX; - for (int series = 0; series < k_numberOfSeries; series ++) { + for (int series = 0; series < k_numberOfSeries; series++) { if (!seriesIsEmpty(series)) { minX = min(minX, minValueOfColumn(series, 0)); maxX = max(maxX, maxValueOfColumn(series, 0)); } } float range = maxX - minX; - setXMin(minX - k_displayLeftMarginRatio*range); - setXMax(maxX + k_displayRightMarginRatio*range); + setXMin(minX - k_displayHorizontalMarginRatio*range); + setXMax(maxX + k_displayHorizontalMarginRatio*range); setYAuto(true); } @@ -329,26 +329,4 @@ double Store::squaredCorrelationCoefficient(int series) const { return (v0 == 0.0 || v1 == 0.0) ? 1.0 : cov*cov/(v0*v1); } -InteractiveCurveViewRangeDelegate::Range Store::computeYRange(InteractiveCurveViewRange * interactiveCurveViewRange) { - float minY = FLT_MAX; - float maxY = -FLT_MAX; - for (int series = 0; series < k_numberOfSeries; series++) { - for (int k = 0; k < numberOfPairsOfSeries(series); k++) { - if (m_xMin <= m_data[series][0][k] && m_data[series][0][k] <= m_xMax) { - minY = min(minY, m_data[series][1][k]); - maxY = max(maxY, m_data[series][1][k]); - } - } - } - InteractiveCurveViewRangeDelegate::Range range; - range.min = minY; - range.max = maxY; - return range; -} - -float Store::addMargin(float x, float range, bool isMin) { - float ratio = isMin ? -k_displayBottomMarginRatio : k_displayTopMarginRatio; - return x+ratio*range; -} - } diff --git a/apps/regression/store.h b/apps/regression/store.h index 1e1a47b6d..1d360dbef 100644 --- a/apps/regression/store.h +++ b/apps/regression/store.h @@ -9,7 +9,7 @@ namespace Regression { -class Store : public Shared::InteractiveCurveViewRange, public Shared::DoublePairStore, public Shared::InteractiveCurveViewRangeDelegate { +class Store : public Shared::InteractiveCurveViewRange, public Shared::DoublePairStore { public: Store(); ~Store(); @@ -64,12 +64,7 @@ public: double correlationCoefficient(int series) const; double squaredCorrelationCoefficient(int series) const; private: - constexpr static float k_displayTopMarginRatio = 0.12f; - constexpr static float k_displayRightMarginRatio = 0.05f; - constexpr static float k_displayBottomMarginRatio = 0.5f; - constexpr static float k_displayLeftMarginRatio = 0.05f; - InteractiveCurveViewRangeDelegate::Range computeYRange(InteractiveCurveViewRange * interactiveCurveViewRange) override; - float addMargin(float x, float range, bool isMin) override; + constexpr static float k_displayHorizontalMarginRatio = 0.05f; float maxValueOfColumn(int series, int i) const; float minValueOfColumn(int series, int i) const; uint32_t m_seriesChecksum[k_numberOfSeries]; diff --git a/apps/shared/curve_view.h b/apps/shared/curve_view.h index a41bfa81b..cf5d42ac6 100644 --- a/apps/shared/curve_view.h +++ b/apps/shared/curve_view.h @@ -27,7 +27,9 @@ public: // When the main view is selected, the banner view is visible bool isMainViewSelected() const; void selectMainView(bool mainViewSelected); + View * cursorView() { return m_cursorView; } void setCursorView(View * cursorView); + View * bannerView() { return m_bannerView; } void setBannerView(View * bannerView); void setOkView(View * okView); void setForceOkDisplay(bool force) { m_forceOkDisplay = force; } diff --git a/apps/shared/function_graph_controller.cpp b/apps/shared/function_graph_controller.cpp index af03faebf..0f7b4fca9 100644 --- a/apps/shared/function_graph_controller.cpp +++ b/apps/shared/function_graph_controller.cpp @@ -97,11 +97,6 @@ InteractiveCurveViewRangeDelegate::Range FunctionGraphController::computeYRange( return range; } -float FunctionGraphController::addMargin(float x, float range, bool isMin) { - float ratio = isMin ? -k_displayBottomMarginRatio : k_displayTopMarginRatio; - return x+ratio*range; -} - void FunctionGraphController::initRangeParameters() { interactiveCurveViewRange()->setDefault(); initCursorParameters(); diff --git a/apps/shared/function_graph_controller.h b/apps/shared/function_graph_controller.h index 09eaffdf9..db7349e9a 100644 --- a/apps/shared/function_graph_controller.h +++ b/apps/shared/function_graph_controller.h @@ -11,12 +11,13 @@ namespace Shared { -class FunctionGraphController : public InteractiveCurveViewController, public InteractiveCurveViewRangeDelegate, public FunctionBannerDelegate { +class FunctionGraphController : public InteractiveCurveViewController, public FunctionBannerDelegate { public: FunctionGraphController(Responder * parentResponder, ButtonRowController * header, InteractiveCurveViewRange * interactiveRange, CurveView * curveView, CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * rangeVersion, Poincare::Expression::AngleUnit * angleUnitVersion); bool isEmpty() const override; ViewController * initialisationParameterController() override; void viewWillAppear() override; + protected: constexpr static float k_cursorTopMarginRatio = 0.068f; // (cursorHeight/2)/graphViewHeight constexpr static float k_cursorBottomMarginRatio = 0.15f; // (cursorHeight/2+bannerHeigh)/graphViewHeight @@ -33,8 +34,11 @@ private: constexpr static float k_displayTopMarginRatio = 0.09f; constexpr static float k_displayBottomMarginRatio = 0.2f; + // InteractiveCurveViewController + float displayTopMarginRatio() override { return k_displayTopMarginRatio; } + float displayBottomMarginRatio() override { return k_displayBottomMarginRatio; } + // InteractiveCurveViewRangeDelegate InteractiveCurveViewRangeDelegate::Range computeYRange(InteractiveCurveViewRange * interactiveCurveViewRange) override; - float addMargin(float x, float range, bool isMin) override; void initRangeParameters() override; void initCursorParameters() override; diff --git a/apps/shared/interactive_curve_view_controller.cpp b/apps/shared/interactive_curve_view_controller.cpp index 36de73321..242f0eee6 100644 --- a/apps/shared/interactive_curve_view_controller.cpp +++ b/apps/shared/interactive_curve_view_controller.cpp @@ -32,6 +32,11 @@ InteractiveCurveViewController::InteractiveCurveViewController(Responder * paren { } +float InteractiveCurveViewController::addMargin(float x, float range, bool isMin) { + float ratio = isMin ? -displayBottomMarginRatio() : displayTopMarginRatio(); + return x+ratio*range; +} + const char * InteractiveCurveViewController::title() { return I18n::translate(I18n::Message::GraphTab); } diff --git a/apps/shared/interactive_curve_view_controller.h b/apps/shared/interactive_curve_view_controller.h index 5ba889899..07dce8057 100644 --- a/apps/shared/interactive_curve_view_controller.h +++ b/apps/shared/interactive_curve_view_controller.h @@ -9,9 +9,15 @@ namespace Shared { -class InteractiveCurveViewController : public SimpleInteractiveCurveViewController, public ButtonRowDelegate, public AlternateEmptyViewDelegate { +class InteractiveCurveViewController : public SimpleInteractiveCurveViewController, public InteractiveCurveViewRangeDelegate, public ButtonRowDelegate, public AlternateEmptyViewDelegate { public: InteractiveCurveViewController(Responder * parentResponder, ButtonRowController * header, InteractiveCurveViewRange * interactiveRange, CurveView * curveView, CurveViewCursor * cursor, uint32_t * modelVersion, uint32_t * rangeVersion); + + // InteractiveCurveViewRangeDelegate + float addMargin(float x, float range, bool isMin) override; + virtual float displayTopMarginRatio() = 0; + virtual float displayBottomMarginRatio() = 0; + const char * title() override; bool handleEvent(Ion::Events::Event event) override; void didBecomeFirstResponder() override; diff --git a/apps/shared/interactive_curve_view_range_delegate.cpp b/apps/shared/interactive_curve_view_range_delegate.cpp index 33598fe08..017ed64bd 100644 --- a/apps/shared/interactive_curve_view_range_delegate.cpp +++ b/apps/shared/interactive_curve_view_range_delegate.cpp @@ -37,6 +37,7 @@ bool InteractiveCurveViewRangeDelegate::didChangeRange(InteractiveCurveViewRange float step = min != 0.0f ? interactiveCurveViewRange->computeGridUnit(CurveViewRange::Axis::Y, 0.0f, std::fabs(min)) : 1.0f; max = min+step; } + range = max - min; interactiveCurveViewRange->setYMin(addMargin(min, range, true)); interactiveCurveViewRange->setYMax(addMargin(max, range, false)); if (std::isinf(interactiveCurveViewRange->xMin())) {