#include "MathFunctionModel.hpp" #include #include #include #include #include #include #include #include "ExpressionRangeData.hpp" #include #include MathFunctionModel:: MathFunctionModel() { createNameAndFunctions(); _widget = new QWidget(); auto l = new QFormLayout(); _functionComboBox = new QComboBox; for (auto const & f : _nameAndFunctions) { _functionComboBox->addItem(std::get<0>(f)); } _variableLabel = new QLabel(); _variableLabel->setMargin(3); _variableLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken); _rangeLabel = new QLabel(); _rangeLabel->setMargin(3); _rangeLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken); l->addRow("Function:", _functionComboBox); l->addRow("Variable:", _variableLabel); l->addRow("Range:", _rangeLabel); _widget->setLayout(l); connect(_functionComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onFunctionIndexChanged(int))); } void MathFunctionModel:: onFunctionIndexChanged(int index) { processData(); } QJsonObject MathFunctionModel:: save() const { QJsonObject modelJson = NodeDataModel::save(); if (_expression) modelJson["expression"] = _expression->expression(); return modelJson; } void MathFunctionModel:: restore(QJsonObject const &p) { QJsonValue v = p["expression"]; if (!v.isUndefined()) { QString str = v.toString(); std::vector d; d.push_back(0.0); _expression = std::make_shared(str, d); _variableLabel->setText(str); } } unsigned int MathFunctionModel:: nPorts(PortType portType) const { unsigned int result = 1; switch (portType) { case PortType::In: result = 1; break; case PortType::Out: result = 1; default: break; } return result; } NodeDataType MathFunctionModel:: dataType(PortType, PortIndex) const { return ExpressionRangeData().type(); } std::shared_ptr MathFunctionModel:: outData(PortIndex) { return _expression; } QString MathFunctionModel:: convertRangeToText(std::vector const &range) const { QString result("("); for (std::size_t i = 0; i < range.size() - 1; ++i) { result = result + QString::number(range[i]) + ", "; } result = result + QString::number(range.back()) + ")"; return result; } std::vector MathFunctionModel:: applyFunction(std::vector const &range) const { std::vector result; FunctionPtr const & f = std::get<2>(_nameAndFunctions[_functionComboBox->currentIndex()]); for (auto const & d : range) { result.push_back(f(d)); } return result; } void MathFunctionModel:: createNameAndFunctions() { _nameAndFunctions.push_back( std::make_tuple(QString("sin()"), QString("sin(%1)"), static_cast([](double d) { return sin(d); }))); _nameAndFunctions.push_back( std::make_tuple(QString("cos()"), QString("cos(%1)"), static_cast([](double d) { return cos(d); }))); } void MathFunctionModel:: processData() { auto inputExpression = _inputExpression.lock(); if (inputExpression) { QString input = inputExpression->expression(); std::vector const & inputRange = inputExpression->range(); std::vector modifiedRange = applyFunction(inputRange); QString tt = std::get<1>(_nameAndFunctions[_functionComboBox->currentIndex()]); _expression = std::make_shared(tt.arg(input), modifiedRange); _variableLabel->setText(_expression->expression()); _variableLabel->adjustSize(); _rangeLabel->setText(convertRangeToText(modifiedRange)); _rangeLabel->adjustSize(); emit dataUpdated(0); } } void MathFunctionModel:: setInData(std::shared_ptr nodeData, PortIndex portIndex) { _inputExpression = std::static_pointer_cast(nodeData); processData(); } QWidget * MathFunctionModel:: embeddedWidget() { return _widget; }