From dc6acc0d482ec90cb1a8abb65fa78cdcd8def9ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Fri, 17 Mar 2017 16:42:44 +0100 Subject: [PATCH] [apps/shared] Clip displayed range in graph view in interactive curve view range Change-Id: I4654a1f9c06420d6ade8a86a13c0d89f025f324f --- apps/probability/parameters_controller.cpp | 5 +- apps/probability/parameters_controller.h | 2 +- .../regression/go_to_parameter_controller.cpp | 16 ++++- apps/regression/go_to_parameter_controller.h | 3 +- apps/shared/curve_view_cursor.cpp | 10 ++- apps/shared/curve_view_cursor.h | 2 + apps/shared/float_parameter_controller.cpp | 4 +- apps/shared/float_parameter_controller.h | 2 +- apps/shared/go_to_parameter_controller.cpp | 7 +- apps/shared/go_to_parameter_controller.h | 3 +- apps/shared/interactive_curve_view_range.cpp | 68 +++++++++++++------ apps/shared/interactive_curve_view_range.h | 3 + apps/shared/interval_parameter_controller.cpp | 3 +- apps/shared/interval_parameter_controller.h | 2 +- apps/shared/memoized_curve_view_range.h | 4 +- apps/shared/range_parameter_controller.cpp | 3 +- apps/shared/range_parameter_controller.h | 2 +- .../histogram_parameter_controller.cpp | 5 +- .../histogram_parameter_controller.h | 2 +- 19 files changed, 105 insertions(+), 41 deletions(-) diff --git a/apps/probability/parameters_controller.cpp b/apps/probability/parameters_controller.cpp index 72b16cfd0..be91ee4e7 100644 --- a/apps/probability/parameters_controller.cpp +++ b/apps/probability/parameters_controller.cpp @@ -138,12 +138,13 @@ float ParametersController::parameterAtIndex(int index) { return m_law->parameterValueAtIndex(index); } -void ParametersController::setParameterAtIndex(int parameterIndex, float f) { +bool ParametersController::setParameterAtIndex(int parameterIndex, float f) { if (!m_law->authorizedValueAtIndex(f, parameterIndex)) { app()->displayWarning(I18n::Message::ForbiddenValue); - return; + return false; } m_law->setParameterAtIndex(f, parameterIndex); + return true; } void ParametersController::buttonAction() { diff --git a/apps/probability/parameters_controller.h b/apps/probability/parameters_controller.h index 5964a9987..beda9fda9 100644 --- a/apps/probability/parameters_controller.h +++ b/apps/probability/parameters_controller.h @@ -23,7 +23,7 @@ private: void buttonAction() override; float previousParameterAtIndex(int index) override; float parameterAtIndex(int index) override; - void setParameterAtIndex(int parameterIndex, float f) override; + bool setParameterAtIndex(int parameterIndex, float f) override; class ContentView : public View { public: ContentView(Responder * parentResponder, SelectableTableView * selectableTableView); diff --git a/apps/regression/go_to_parameter_controller.cpp b/apps/regression/go_to_parameter_controller.cpp index ab30e5910..0e851622f 100644 --- a/apps/regression/go_to_parameter_controller.cpp +++ b/apps/regression/go_to_parameter_controller.cpp @@ -44,22 +44,32 @@ float GoToParameterController::parameterAtIndex(int index) { return m_cursor->y(); } -void GoToParameterController::setParameterAtIndex(int parameterIndex, float f) { +bool GoToParameterController::setParameterAtIndex(int parameterIndex, float f) { assert(parameterIndex == 0); + if (fabsf(f) > k_maxDisplayableFloat) { + app()->displayWarning(I18n::Message::ForbiddenValue); + return false; + } if (m_xPrediction) { float y = m_store->yValueForXValue(f); + if (fabsf(y) > k_maxDisplayableFloat) { + app()->displayWarning(I18n::Message::ForbiddenValue); + return false; + } m_store->centerAxisAround(CurveViewRange::Axis::X, f); m_store->centerAxisAround(CurveViewRange::Axis::Y, y); m_cursor->moveTo(f, y); } else { float x = m_store->xValueForYValue(f); - if (isnan(x)) { - return; + if (fabsf(x) > k_maxDisplayableFloat) { + app()->displayWarning(I18n::Message::ForbiddenValue); + return false; } m_store->centerAxisAround(CurveViewRange::Axis::X, x); m_store->centerAxisAround(CurveViewRange::Axis::Y, f); m_cursor->moveTo(x, f); } + return true; } HighlightCell * GoToParameterController::reusableParameterCell(int index, int type) { diff --git a/apps/regression/go_to_parameter_controller.h b/apps/regression/go_to_parameter_controller.h index 96798b724..4b57e2bc6 100644 --- a/apps/regression/go_to_parameter_controller.h +++ b/apps/regression/go_to_parameter_controller.h @@ -18,11 +18,12 @@ public: bool textFieldDidFinishEditing(TextField * textField, const char * text) override; void viewWillAppear() override; private: + constexpr static float k_maxDisplayableFloat = 1E7f; HighlightCell * reusableParameterCell(int index, int type) override; int reusableParameterCellCount(int type) override; float previousParameterAtIndex(int index) override; float parameterAtIndex(int index) override; - void setParameterAtIndex(int parameterIndex, float f) override; + bool setParameterAtIndex(int parameterIndex, float f) override; void buttonAction() override; char m_draftTextBuffer[MessageTableCellWithEditableText::k_bufferLength]; MessageTableCellWithEditableText m_abscisseCell; diff --git a/apps/shared/curve_view_cursor.cpp b/apps/shared/curve_view_cursor.cpp index fd8b3eb97..883636ce8 100644 --- a/apps/shared/curve_view_cursor.cpp +++ b/apps/shared/curve_view_cursor.cpp @@ -18,8 +18,14 @@ float CurveViewCursor::y() { } void CurveViewCursor::moveTo(float x, float y) { - m_x = x; - m_y = y; + m_x = clipped(x); + m_y = clipped(y); +} + +float CurveViewCursor::clipped(float x) { + float clippedX = x > k_maxFloat ? k_maxFloat : x; + clippedX = clippedX < - k_maxFloat ? -k_maxFloat : clippedX; + return clippedX; } } diff --git a/apps/shared/curve_view_cursor.h b/apps/shared/curve_view_cursor.h index f6b4af414..a6666533a 100644 --- a/apps/shared/curve_view_cursor.h +++ b/apps/shared/curve_view_cursor.h @@ -9,7 +9,9 @@ public: float x(); float y(); void moveTo(float x, float y); + static float clipped(float f); private: + constexpr static float k_maxFloat = 1E+8f; float m_x; float m_y; }; diff --git a/apps/shared/float_parameter_controller.cpp b/apps/shared/float_parameter_controller.cpp index 2f4eb76a1..3f74fac43 100644 --- a/apps/shared/float_parameter_controller.cpp +++ b/apps/shared/float_parameter_controller.cpp @@ -103,7 +103,9 @@ bool FloatParameterController::textFieldDidFinishEditing(TextField * textField, app()->displayWarning(I18n::Message::UndefinedValue); return false; } - setParameterAtIndex(m_selectableTableView.selectedRow(), floatBody); + if (!setParameterAtIndex(m_selectableTableView.selectedRow(), floatBody)) { + return false; + } willDisplayCellForIndex(m_selectableTableView.cellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow()), activeCell()); m_selectableTableView.selectCellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow()+1); diff --git a/apps/shared/float_parameter_controller.h b/apps/shared/float_parameter_controller.h index 04b4dc0da..5d2bf5955 100644 --- a/apps/shared/float_parameter_controller.h +++ b/apps/shared/float_parameter_controller.h @@ -40,7 +40,7 @@ private: TextFieldDelegateApp * textFieldDelegateApp() override; virtual float previousParameterAtIndex(int index) = 0; virtual float parameterAtIndex(int index) = 0; - virtual void setParameterAtIndex(int parameterIndex, float f) = 0; + virtual bool setParameterAtIndex(int parameterIndex, float f) = 0; ButtonWithSeparator m_okButton; }; diff --git a/apps/shared/go_to_parameter_controller.cpp b/apps/shared/go_to_parameter_controller.cpp index 5a7fff29a..a895d25b1 100644 --- a/apps/shared/go_to_parameter_controller.cpp +++ b/apps/shared/go_to_parameter_controller.cpp @@ -36,13 +36,18 @@ float GoToParameterController::parameterAtIndex(int index) { return m_cursor->x(); } -void GoToParameterController::setParameterAtIndex(int parameterIndex, float f) { +bool GoToParameterController::setParameterAtIndex(int parameterIndex, float f) { assert(parameterIndex == 0); TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app(); float y = m_function->evaluateAtAbscissa(f, myApp->localContext()); + if (fabsf(f) > k_maxDisplayableFloat || fabsf(y) > k_maxDisplayableFloat) { + app()->displayWarning(I18n::Message::ForbiddenValue); + return false; + } m_graphRange->centerAxisAround(CurveViewRange::Axis::X, f); m_graphRange->centerAxisAround(CurveViewRange::Axis::Y, y); m_cursor->moveTo(f, y); + return true; } HighlightCell * GoToParameterController::reusableParameterCell(int index, int type) { diff --git a/apps/shared/go_to_parameter_controller.h b/apps/shared/go_to_parameter_controller.h index e0f93b609..755b5d548 100644 --- a/apps/shared/go_to_parameter_controller.h +++ b/apps/shared/go_to_parameter_controller.h @@ -17,12 +17,13 @@ public: void setFunction(Function * function); int numberOfRows() override; private: + constexpr static float k_maxDisplayableFloat = 1E7f; void buttonAction() override; HighlightCell * reusableParameterCell(int index, int type) override; int reusableParameterCellCount(int type) override; float previousParameterAtIndex(int index) override; float parameterAtIndex(int index) override; - void setParameterAtIndex(int parameterIndex, float f) override; + bool setParameterAtIndex(int parameterIndex, float f) override; char m_draftTextBuffer[MessageTableCellWithEditableText::k_bufferLength]; MessageTableCellWithEditableText m_abscisseCell; float m_previousParameter; diff --git a/apps/shared/interactive_curve_view_range.cpp b/apps/shared/interactive_curve_view_range.cpp index f2b5a6a7f..535194590 100644 --- a/apps/shared/interactive_curve_view_range.cpp +++ b/apps/shared/interactive_curve_view_range.cpp @@ -33,19 +33,43 @@ bool InteractiveCurveViewRange::yAuto() { } void InteractiveCurveViewRange::setXMin(float xMin) { - MemoizedCurveViewRange::setXMin(xMin); + float newXMin = xMin; + if (m_xMax - m_xMin < k_minFloat) { + newXMin = m_xMax - k_minFloat; + } + MemoizedCurveViewRange::setXMin(CurveViewCursor::clipped(newXMin)); if (m_delegate) { m_delegate->didChangeRange(this); } } void InteractiveCurveViewRange::setXMax(float xMax) { - MemoizedCurveViewRange::setXMax(xMax); + float newXMax = xMax; + if (m_xMax - m_xMin < k_minFloat) { + newXMax = m_xMin + k_minFloat; + } + MemoizedCurveViewRange::setXMax(CurveViewCursor::clipped(newXMax)); if (m_delegate) { m_delegate->didChangeRange(this); } } +void InteractiveCurveViewRange::setYMin(float yMin) { + float newYMin = yMin; + if (m_yMax - m_yMin < k_minFloat) { + newYMin = m_yMax - k_minFloat; + } + MemoizedCurveViewRange::setYMin(CurveViewCursor::clipped(newYMin)); +} + +void InteractiveCurveViewRange::setYMax(float yMax) { + float newYMax = yMax; + if (m_yMax - m_yMin < k_minFloat) { + newYMax = m_yMin + k_minFloat; + } + MemoizedCurveViewRange::setYMax(CurveViewCursor::clipped(newYMax)); +} + void InteractiveCurveViewRange::setYAuto(bool yAuto) { m_yAuto = yAuto; if (m_delegate) { @@ -58,21 +82,27 @@ void InteractiveCurveViewRange::zoom(float ratio) { float xMax = m_xMax; float yMin = m_yMin; float yMax = m_yMax; - m_xMin = (xMax+xMin)/2.0f - ratio*fabsf(xMax-xMin); - m_xMax = (xMax+xMin)/2.0f + ratio*fabsf(xMax-xMin); + if (2.0f*ratio*fabsf(xMax-xMin) < k_minFloat || 2.0f*ratio*fabsf(yMax-yMin) < k_minFloat) { + return; + } + m_xMin = CurveViewCursor::clipped((xMax+xMin)/2.0f - ratio*fabsf(xMax-xMin)); + m_xMax = CurveViewCursor::clipped((xMax+xMin)/2.0f + ratio*fabsf(xMax-xMin)); m_xGridUnit = computeGridUnit(Axis::X, m_xMin, m_xMax); m_yAuto = false; - m_yMin = (yMax+yMin)/2.0f - ratio*fabsf(yMax-yMin); - m_yMax = (yMax+yMin)/2.0f + ratio*fabsf(yMax-yMin); + m_yMin = CurveViewCursor::clipped((yMax+yMin)/2.0f - ratio*fabsf(yMax-yMin)); + m_yMax = CurveViewCursor::clipped((yMax+yMin)/2.0f + ratio*fabsf(yMax-yMin)); m_yGridUnit = computeGridUnit(Axis::Y, m_yMin, m_yMax); } void InteractiveCurveViewRange::panWithVector(float x, float y) { m_yAuto = false; - m_xMin = m_xMin + x; - m_xMax = m_xMax + x; - m_yMin = m_yMin + y; - m_yMax = m_yMax + y; + if (CurveViewCursor::clipped(m_xMin + x) != m_xMin + x || CurveViewCursor::clipped(m_xMax + x) != m_xMax + x || CurveViewCursor::clipped(m_yMin + y) != m_yMin + y || CurveViewCursor::clipped(m_yMax + y) != m_yMax + y) { + return; + } + m_xMin = CurveViewCursor::clipped(m_xMin + x); + m_xMax = CurveViewCursor::clipped(m_xMax + x); + m_yMin = CurveViewCursor::clipped(m_yMin + y); + m_yMax = CurveViewCursor::clipped(m_yMax + y); m_xGridUnit = computeGridUnit(Axis::X, m_xMin, m_xMax); m_yGridUnit = computeGridUnit(Axis::Y, m_yMin, m_yMax); } @@ -126,15 +156,15 @@ void InteractiveCurveViewRange::setDefault() { void InteractiveCurveViewRange::centerAxisAround(Axis axis, float position) { if (axis == Axis::X) { float range = m_xMax - m_xMin; - m_xMin = position - range/2.0f; - m_xMax = position + range/2.0f; + m_xMin = CurveViewCursor::clipped(position - range/2.0f); + m_xMax = CurveViewCursor::clipped(position + range/2.0f); m_xGridUnit = computeGridUnit(Axis::X, m_xMin, m_xMax); } else { m_yAuto = false; float range = m_yMax - m_yMin; - m_yMin = position - range/2.0f; - m_yMax = position + range/2.0f; - m_yGridUnit = computeGridUnit(Axis::Y, m_yMin, m_yMax); + m_yMin = CurveViewCursor::clipped(position - range/2.0f); + m_yMax = CurveViewCursor::clipped(position + range/2.0f); + m_yGridUnit = CurveViewCursor::clipped(computeGridUnit(Axis::Y, m_yMin, m_yMax)); } } @@ -142,25 +172,25 @@ void InteractiveCurveViewRange::panToMakePointVisible(float x, float y, float to float xRange = m_xMax - m_xMin; float yRange = m_yMax - m_yMin; if (x < m_xMin + leftMarginRation*xRange && !isinf(x) && !isnan(x)) { - m_xMin = x - leftMarginRation*xRange; + m_xMin = CurveViewCursor::clipped(x - leftMarginRation*xRange); m_xMax = m_xMin + xRange; m_xGridUnit = computeGridUnit(Axis::X, m_xMin, m_xMax); m_yAuto = false; } if (x > m_xMax - rightMarginRatio*xRange && !isinf(x) && !isnan(x)) { - m_xMax = x + rightMarginRatio*xRange; + m_xMax = CurveViewCursor::clipped(x + rightMarginRatio*xRange); m_xMin = m_xMax - xRange; m_xGridUnit = computeGridUnit(Axis::X, m_xMin, m_xMax); m_yAuto = false; } if (y < m_yMin + bottomMarginRation*yRange && !isinf(y) && !isnan(y)) { - m_yMin = y - bottomMarginRation*yRange; + m_yMin = CurveViewCursor::clipped(y - bottomMarginRation*yRange); m_yMax = m_yMin + yRange; m_yGridUnit = computeGridUnit(Axis::Y, m_yMin, m_yMax); m_yAuto = false; } if (y > m_yMax - topMarginRatio*yRange && !isinf(y) && !isnan(y)) { - m_yMax = y + topMarginRatio*yRange; + m_yMax = CurveViewCursor::clipped(y + topMarginRatio*yRange); m_yMin = m_yMax - yRange; m_yGridUnit = computeGridUnit(Axis::Y, m_yMin, m_yMax); m_yAuto = false; diff --git a/apps/shared/interactive_curve_view_range.h b/apps/shared/interactive_curve_view_range.h index 17775a127..2aebff7fe 100644 --- a/apps/shared/interactive_curve_view_range.h +++ b/apps/shared/interactive_curve_view_range.h @@ -18,6 +18,8 @@ public: bool yAuto(); void setXMin(float f) override; void setXMax(float f) override; + void setYMin(float f) override; + void setYMax(float f) override; void setYAuto(bool yAuto); // Window @@ -32,6 +34,7 @@ public: protected: bool m_yAuto; private: + constexpr static float k_minFloat = 1E-8f; CurveViewCursor * m_cursor; InteractiveCurveViewRangeDelegate * m_delegate; }; diff --git a/apps/shared/interval_parameter_controller.cpp b/apps/shared/interval_parameter_controller.cpp index f049ff4bc..b2d0c3e2b 100644 --- a/apps/shared/interval_parameter_controller.cpp +++ b/apps/shared/interval_parameter_controller.cpp @@ -49,9 +49,10 @@ float IntervalParameterController::parameterAtIndex(int index) { return (m_interval->*getters[index])(); } -void IntervalParameterController::setParameterAtIndex(int parameterIndex, float f) { +bool IntervalParameterController::setParameterAtIndex(int parameterIndex, float f) { SetterPointer setters[k_totalNumberOfCell] = {&Interval::setStart, &Interval::setEnd, &Interval::setStep}; (m_interval->*setters[parameterIndex])(f); + return true; } HighlightCell * IntervalParameterController::reusableParameterCell(int index, int type) { diff --git a/apps/shared/interval_parameter_controller.h b/apps/shared/interval_parameter_controller.h index c4ca8bbc7..afd379078 100644 --- a/apps/shared/interval_parameter_controller.h +++ b/apps/shared/interval_parameter_controller.h @@ -20,7 +20,7 @@ private: int reusableParameterCellCount(int type) override; float previousParameterAtIndex(int index) override; float parameterAtIndex(int index) override; - void setParameterAtIndex(int parameterIndex, float f) override; + bool setParameterAtIndex(int parameterIndex, float f) override; constexpr static int k_totalNumberOfCell = 3; Interval * m_interval; char m_draftTextBuffer[MessageTableCellWithEditableText::k_bufferLength]; diff --git a/apps/shared/memoized_curve_view_range.h b/apps/shared/memoized_curve_view_range.h index 6136bba70..3b013cdf1 100644 --- a/apps/shared/memoized_curve_view_range.h +++ b/apps/shared/memoized_curve_view_range.h @@ -17,8 +17,8 @@ public: float yGridUnit() override; virtual void setXMin(float f); virtual void setXMax(float f); - void setYMin(float f); - void setYMax(float f); + virtual void setYMin(float f); + virtual void setYMax(float f); protected: // Window bounds of the data diff --git a/apps/shared/range_parameter_controller.cpp b/apps/shared/range_parameter_controller.cpp index d57c87d00..1ab55de63 100644 --- a/apps/shared/range_parameter_controller.cpp +++ b/apps/shared/range_parameter_controller.cpp @@ -116,11 +116,12 @@ float RangeParameterController::parameterAtIndex(int parameterIndex) { return (m_interactiveRange->*getters[index])(); } -void RangeParameterController::setParameterAtIndex(int parameterIndex, float f) { +bool RangeParameterController::setParameterAtIndex(int parameterIndex, float f) { ParameterSetterPointer setters[k_numberOfTextCell] = {&InteractiveCurveViewRange::setXMin, &InteractiveCurveViewRange::setXMax, &InteractiveCurveViewRange::setYMin, &InteractiveCurveViewRange::setYMax}; int index = parameterIndex > 2 ? parameterIndex - 1 : parameterIndex; (m_interactiveRange->*setters[index])(f); + return true; } HighlightCell * RangeParameterController::reusableParameterCell(int index, int type) { diff --git a/apps/shared/range_parameter_controller.h b/apps/shared/range_parameter_controller.h index 92e011ebe..5b717928a 100644 --- a/apps/shared/range_parameter_controller.h +++ b/apps/shared/range_parameter_controller.h @@ -23,7 +23,7 @@ private: int reusableParameterCellCount(int type) override; float previousParameterAtIndex(int index) override; float parameterAtIndex(int index) override; - void setParameterAtIndex(int parameterIndex, float f) override; + bool setParameterAtIndex(int parameterIndex, float f) override; constexpr static int k_numberOfTextCell = 4; InteractiveCurveViewRange * m_interactiveRange; char m_draftTextBuffer[MessageTableCellWithEditableText::k_bufferLength]; diff --git a/apps/statistics/histogram_parameter_controller.cpp b/apps/statistics/histogram_parameter_controller.cpp index e53351b33..535cc4394 100644 --- a/apps/statistics/histogram_parameter_controller.cpp +++ b/apps/statistics/histogram_parameter_controller.cpp @@ -50,17 +50,18 @@ float HistogramParameterController::previousParameterAtIndex(int index) { return m_previousParameters[index]; } -void HistogramParameterController::setParameterAtIndex(int parameterIndex, float f) { +bool HistogramParameterController::setParameterAtIndex(int parameterIndex, float f) { assert(parameterIndex >= 0 && parameterIndex < 2); if (parameterIndex == 0) { if (f <= 0.0f) { app()->displayWarning(I18n::Message::ForbiddenValue); - return; + return false; } m_store->setBarWidth(f); } else { m_store->setFirstDrawnBarAbscissa(f); } + return true; } HighlightCell * HistogramParameterController::reusableParameterCell(int index, int type) { diff --git a/apps/statistics/histogram_parameter_controller.h b/apps/statistics/histogram_parameter_controller.h index 07569d33b..d4acf2220 100644 --- a/apps/statistics/histogram_parameter_controller.h +++ b/apps/statistics/histogram_parameter_controller.h @@ -19,7 +19,7 @@ private: int reusableParameterCellCount(int type) override; float parameterAtIndex(int index) override; float previousParameterAtIndex(int index) override; - void setParameterAtIndex(int parameterIndex, float f) override; + bool setParameterAtIndex(int parameterIndex, float f) override; char m_draftTextBuffer[MessageTableCellWithEditableText::k_bufferLength]; MessageTableCellWithEditableText m_cells[2]; float m_previousParameters[2];