diff --git a/apps/graph/list/domain_parameter_controller.cpp b/apps/graph/list/domain_parameter_controller.cpp index 851c58a4f..26853b4ea 100644 --- a/apps/graph/list/domain_parameter_controller.cpp +++ b/apps/graph/list/domain_parameter_controller.cpp @@ -89,10 +89,18 @@ void DomainParameterController::buttonAction() { stack->pop(); } -Shared::ExpiringPointer DomainParameterController::function() { +Shared::ExpiringPointer DomainParameterController::function() const { assert(!m_record.isNull()); App * myApp = App::app(); return myApp->functionStore()->modelForRecord(m_record); } +FloatParameterController::InfinityTolerance DomainParameterController::infinityAllowanceForRow(int row) const { + Shared::CartesianFunction::PlotType plotType = function()->plotType(); + if (plotType == Shared::CartesianFunction::PlotType::Cartesian) { + return row == 0 ? FloatParameterController::InfinityTolerance::MinusInfinity : FloatParameterController::InfinityTolerance::PlusInfinity; + } + return FloatParameterController::InfinityTolerance::None; +} + } diff --git a/apps/graph/list/domain_parameter_controller.h b/apps/graph/list/domain_parameter_controller.h index 4d4078239..738afd3c8 100644 --- a/apps/graph/list/domain_parameter_controller.h +++ b/apps/graph/list/domain_parameter_controller.h @@ -29,7 +29,8 @@ private: bool setParameterAtIndex(int parameterIndex, float f) override; float parameterAtIndex(int index) override; void buttonAction() override; - Shared::ExpiringPointer function(); + InfinityTolerance infinityAllowanceForRow(int row) const override; + Shared::ExpiringPointer function() const; MessageTableCellWithEditableText m_domainCells[k_totalNumberOfCell]; Ion::Storage::Record m_record; }; diff --git a/apps/shared/float_parameter_controller.cpp b/apps/shared/float_parameter_controller.cpp index c1725835d..4ddeac476 100644 --- a/apps/shared/float_parameter_controller.cpp +++ b/apps/shared/float_parameter_controller.cpp @@ -137,16 +137,18 @@ bool FloatParameterController::textFieldShouldFinishEditing(TextField * textF template bool FloatParameterController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { T floatBody; - if (textFieldDelegateApp()->hasUndefinedValue(text, floatBody)) { + int row = selectedRow(); + InfinityTolerance infTolerance = infinityAllowanceForRow(row); + if (textFieldDelegateApp()->hasUndefinedValue(text, floatBody, infTolerance == InfinityTolerance::PlusInfinity, infTolerance == InfinityTolerance::MinusInfinity)) { return false; } - if (!setParameterAtIndex(selectedRow(), floatBody)) { + if (!setParameterAtIndex(row, floatBody)) { return false; } m_selectableTableView.reloadCellAtLocation(0, activeCell()); m_selectableTableView.reloadData(); if (event == Ion::Events::EXE || event == Ion::Events::OK) { - m_selectableTableView.selectCellAtLocation(selectedColumn(), selectedRow()+1); + m_selectableTableView.selectCellAtLocation(selectedColumn(), row + 1); } else { m_selectableTableView.handleEvent(event); } diff --git a/apps/shared/float_parameter_controller.h b/apps/shared/float_parameter_controller.h index cc34d3fbc..21dc7f94b 100644 --- a/apps/shared/float_parameter_controller.h +++ b/apps/shared/float_parameter_controller.h @@ -30,6 +30,11 @@ public: bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override; bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override; protected: + enum class InfinityTolerance { + None, + PlusInfinity, + MinusInfinity + }; int activeCell(); StackViewController * stackController(); virtual T parameterAtIndex(int index) = 0; @@ -38,6 +43,7 @@ protected: private: constexpr static int k_buttonMargin = 6; virtual void buttonAction(); + virtual InfinityTolerance infinityAllowanceForRow(int row) const { return InfinityTolerance::None; } virtual int reusableParameterCellCount(int type) = 0; virtual HighlightCell * reusableParameterCell(int index, int type) = 0; virtual bool setParameterAtIndex(int parameterIndex, T f) = 0; diff --git a/apps/shared/text_field_delegate_app.cpp b/apps/shared/text_field_delegate_app.cpp index 7d8595e72..16ffd32c3 100644 --- a/apps/shared/text_field_delegate_app.cpp +++ b/apps/shared/text_field_delegate_app.cpp @@ -41,9 +41,11 @@ bool TextFieldDelegateApp::isAcceptableText(const char * text) { } template -bool TextFieldDelegateApp::hasUndefinedValue(const char * text, T & value) { +bool TextFieldDelegateApp::hasUndefinedValue(const char * text, T & value, bool enablePlusInfinity, bool enableMinusInfinity) { value = PoincareHelpers::ApproximateToScalar(text, localContext()); - bool isUndefined = std::isnan(value) || std::isinf(value); + bool isUndefined = std::isnan(value) + || (!enablePlusInfinity && value > 0 && std::isinf(value)) + || (!enableMinusInfinity && value < 0 && std::isinf(value)); if (isUndefined) { displayWarning(I18n::Message::UndefinedValue); } @@ -116,7 +118,7 @@ bool TextFieldDelegateApp::ExpressionCanBeSerialized(const Expression expression return true; } -template bool TextFieldDelegateApp::hasUndefinedValue(const char * text, float & value); -template bool TextFieldDelegateApp::hasUndefinedValue(const char * text, double & value); +template bool TextFieldDelegateApp::hasUndefinedValue(const char *, float &, bool, bool); +template bool TextFieldDelegateApp::hasUndefinedValue(const char *, double &, bool, bool); } diff --git a/apps/shared/text_field_delegate_app.h b/apps/shared/text_field_delegate_app.h index 482df4d1e..f59a9eba9 100644 --- a/apps/shared/text_field_delegate_app.h +++ b/apps/shared/text_field_delegate_app.h @@ -19,7 +19,7 @@ public: virtual bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override; bool isAcceptableText(const char * text); template - bool hasUndefinedValue(const char * text, T & value); + bool hasUndefinedValue(const char * text, T & value, bool enablePlusInfinity = false, bool enableMinusInfinity = false); protected: TextFieldDelegateApp(Snapshot * snapshot, ViewController * rootViewController); bool fieldDidReceiveEvent(EditableField * field, Responder * responder, Ion::Events::Event event);