mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[apps/graph] Enable infinite values as domain bounds for cartesian
functions
This commit is contained in:
@@ -89,10 +89,18 @@ void DomainParameterController::buttonAction() {
|
||||
stack->pop();
|
||||
}
|
||||
|
||||
Shared::ExpiringPointer<Shared::CartesianFunction> DomainParameterController::function() {
|
||||
Shared::ExpiringPointer<Shared::CartesianFunction> DomainParameterController::function() const {
|
||||
assert(!m_record.isNull());
|
||||
App * myApp = App::app();
|
||||
return myApp->functionStore()->modelForRecord(m_record);
|
||||
}
|
||||
|
||||
FloatParameterController<float>::InfinityTolerance DomainParameterController::infinityAllowanceForRow(int row) const {
|
||||
Shared::CartesianFunction::PlotType plotType = function()->plotType();
|
||||
if (plotType == Shared::CartesianFunction::PlotType::Cartesian) {
|
||||
return row == 0 ? FloatParameterController<float>::InfinityTolerance::MinusInfinity : FloatParameterController<float>::InfinityTolerance::PlusInfinity;
|
||||
}
|
||||
return FloatParameterController<float>::InfinityTolerance::None;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ private:
|
||||
bool setParameterAtIndex(int parameterIndex, float f) override;
|
||||
float parameterAtIndex(int index) override;
|
||||
void buttonAction() override;
|
||||
Shared::ExpiringPointer<Shared::CartesianFunction> function();
|
||||
InfinityTolerance infinityAllowanceForRow(int row) const override;
|
||||
Shared::ExpiringPointer<Shared::CartesianFunction> function() const;
|
||||
MessageTableCellWithEditableText m_domainCells[k_totalNumberOfCell];
|
||||
Ion::Storage::Record m_record;
|
||||
};
|
||||
|
||||
@@ -137,16 +137,18 @@ bool FloatParameterController<T>::textFieldShouldFinishEditing(TextField * textF
|
||||
template<typename T>
|
||||
bool FloatParameterController<T>::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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -41,9 +41,11 @@ bool TextFieldDelegateApp::isAcceptableText(const char * text) {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool TextFieldDelegateApp::hasUndefinedValue(const char * text, T & value) {
|
||||
bool TextFieldDelegateApp::hasUndefinedValue(const char * text, T & value, bool enablePlusInfinity, bool enableMinusInfinity) {
|
||||
value = PoincareHelpers::ApproximateToScalar<T>(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);
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
virtual bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override;
|
||||
bool isAcceptableText(const char * text);
|
||||
template<typename T>
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user