From 69149b3e4580c342dc0866e841a76fd19218073c Mon Sep 17 00:00:00 2001 From: Daguerreo Date: Mon, 26 Apr 2021 18:02:44 +0200 Subject: [PATCH] Added FibonacciModel in calculator example showing dynamic output ports --- examples/calculator/FibonacciModel.cpp | 150 +++++++++++++++++++++++++ examples/calculator/FibonacciModel.hpp | 78 +++++++++++++ examples/calculator/main.cpp | 7 +- 3 files changed, 233 insertions(+), 2 deletions(-) create mode 100644 examples/calculator/FibonacciModel.cpp create mode 100644 examples/calculator/FibonacciModel.hpp diff --git a/examples/calculator/FibonacciModel.cpp b/examples/calculator/FibonacciModel.cpp new file mode 100644 index 00000000..f9e93b6e --- /dev/null +++ b/examples/calculator/FibonacciModel.cpp @@ -0,0 +1,150 @@ +#include "FibonacciModel.hpp" + +#include + +int fibo(int n) +{ + if(n<=1) return 1; + + int fibo = 0; + int fibo1 = 1; + int fibo2 = 1; + int i = 1; + + while (i +FibonacciModel:: + outData(QtNodes::PortIndex port) +{ + return std::make_shared(fibo(port)); +} + +void +FibonacciModel:: + setInData(std::shared_ptr, QtNodes::PortIndex) +{ +} + +QString +FibonacciModel:: + caption() const +{ + return QStringLiteral("Fibonacci"); +} + +bool +FibonacciModel:: + portCaptionVisible(QtNodes::PortType, QtNodes::PortIndex) const +{ + return true; +} + +QString +FibonacciModel:: + portCaption(QtNodes::PortType, QtNodes::PortIndex portIndex) const +{ + return QString("Fibo %1").arg(portIndex); +} + +QString +FibonacciModel:: + name() const +{ + return QStringLiteral("Fibonacci"); +} + +QtNodes::NodeValidationState +FibonacciModel:: + validationState() const +{ + return _modelValidationState; +} + +QString +FibonacciModel:: + validationMessage() const +{ + return _modelValidationError; +} + +void FibonacciModel::restore(const QJsonObject& obj) +{ + int out = obj["dynamic_outputs"].toInt(); + if(out > 1){ + _indexCounter = out; + } +} + +void FibonacciModel::outputConnectionCreated(const QtNodes::Connection& c) +{ + auto outIndex = static_cast(c.getPortIndex(QtNodes::PortType::Out)); + + // Create a new port only if the last port is connected and the connection is completed + if (outIndex == _indexCounter-1 && c.complete()){ + ++_indexCounter; + Q_EMIT portAdded(PortType::Out, _indexCounter-1); + } +} + +void FibonacciModel::outputConnectionDeleted(const QtNodes::Connection& c) +{ + auto outIndex = static_cast(c.getPortIndex(QtNodes::PortType::Out)); + + // outIndex >= 0 ---> dynamic remove only for ports exceding 0 + // !c.complete() ---> port is removed only if connection is removed e and mouse released + // outIndex != _indexCounter-1 --> if you start a connection from the last port but do not connect it + // the connection is destroyed as incomplete, but the port must not be removed because that + // port is already the last one + + if ((outIndex >= 0) && (!c.complete()) && (outIndex != _indexCounter-1)){ + Q_EMIT portRemoved(PortType::Out, outIndex); + --_indexCounter; + + // Recalculate ports + for(int i = outIndex; i<_indexCounter; ++i){ + Q_EMIT dataUpdated(i); + } + } +} diff --git a/examples/calculator/FibonacciModel.hpp b/examples/calculator/FibonacciModel.hpp new file mode 100644 index 00000000..7d0ee7c0 --- /dev/null +++ b/examples/calculator/FibonacciModel.hpp @@ -0,0 +1,78 @@ +#pragma once + +#include +#include + +#include "DecimalData.hpp" + +using QtNodes::PortType; +using QtNodes::PortIndex; +using QtNodes::NodeData; +using QtNodes::NodeDataType; +using QtNodes::NodeDataModel; +using QtNodes::NodeValidationState; + +class FibonacciModel : public NodeDataModel +{ + Q_OBJECT + +public: + FibonacciModel(); + + unsigned int + nPorts(PortType portType) const override; + + bool + hasDynamicPorts(PortType portType) const override; + + NodeDataType + dataType(PortType portType, PortIndex portIndex) const override; + + std::shared_ptr + outData(PortIndex port) override; + + void + setInData(std::shared_ptr data, PortIndex portIndex) override; + +public: + + QString + caption() const override; + + bool + portCaptionVisible(PortType portType, PortIndex portIndex) const override; + + QString + portCaption(PortType portType, PortIndex portIndex) const override; + + QString + name() const override; + +public: + + QWidget * + embeddedWidget() override { return nullptr; } + + NodeValidationState + validationState() const override; + + QString + validationMessage() const override; + +private: + + void + restore(const QJsonObject& obj) override; + + void + outputConnectionCreated(const QtNodes::Connection& c) override; + + void + outputConnectionDeleted(const QtNodes::Connection& c) override; + +private: + int _indexCounter; + + NodeValidationState _modelValidationState = NodeValidationState::Warning; + QString _modelValidationError = QString("Missing or incorrect inputs"); +}; diff --git a/examples/calculator/main.cpp b/examples/calculator/main.cpp index ae425205..b604b9f1 100644 --- a/examples/calculator/main.cpp +++ b/examples/calculator/main.cpp @@ -20,6 +20,7 @@ #include "AccumulatorModel.hpp" #include "MinModel.hpp" #include "MaxModel.hpp" +#include "FibonacciModel.hpp" #include "Converters.hpp" using QtNodes::DataModelRegistry; @@ -49,9 +50,11 @@ registerDataModels() ret->registerModel("Operators"); - ret->registerModel("Operators"); + ret->registerModel("Special"); - ret->registerModel("Operators"); + ret->registerModel("Special"); + + ret->registerModel("Special"); ret->registerTypeConverter(std::make_pair(DecimalData().type(), IntegerData().type()),