Skip to content

Commit e9fb8f9

Browse files
committed
Implement headless calculator example
1 parent 298f60a commit e9fb8f9

9 files changed

+221
-19
lines changed

examples/calculator/CMakeLists.txt

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
1-
file(GLOB_RECURSE CPPS ./*.cpp )
1+
set(CALC_SOURCE_FILES
2+
main.cpp
3+
MathOperationDataModel.cpp
4+
NumberDisplayDataModel.cpp
5+
NumberSourceDataModel.cpp)
26

3-
add_executable(calculator ${CPPS})
7+
add_executable(calculator ${CALC_SOURCE_FILES})
48

59
target_link_libraries(calculator QtNodes)
10+
11+
12+
13+
set(HEADLESS_CALC_SOURCE_FILES
14+
headless_main.cpp
15+
MathOperationDataModel.cpp
16+
NumberDisplayDataModel.cpp
17+
NumberSourceDataModel.cpp)
18+
19+
add_executable(headless_calculator ${HEADLESS_CALC_SOURCE_FILES})
20+
21+
target_link_libraries(headless_calculator QtNodes)

examples/calculator/NumberDisplayDataModel.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#include "NumberDisplayDataModel.hpp"
22

3-
#include "DecimalData.hpp"
4-
53
#include <QtWidgets/QLabel>
64

75
NumberDisplayDataModel::
@@ -55,11 +53,14 @@ void
5553
NumberDisplayDataModel::
5654
setInData(std::shared_ptr<NodeData> data, PortIndex portIndex)
5755
{
58-
auto numberData = std::dynamic_pointer_cast<DecimalData>(data);
56+
_numberData = std::dynamic_pointer_cast<DecimalData>(data);
57+
58+
if (!_label)
59+
return;
5960

60-
if (numberData)
61+
if (_numberData)
6162
{
62-
_label->setText(numberData->numberAsText());
63+
_label->setText(_numberData->numberAsText());
6364
}
6465
else
6566
{
@@ -82,3 +83,14 @@ embeddedWidget()
8283

8384
return _label;
8485
}
86+
87+
88+
double
89+
NumberDisplayDataModel::
90+
number() const
91+
{
92+
if (_numberData)
93+
return _numberData->number();
94+
95+
return 0.0;
96+
}

examples/calculator/NumberDisplayDataModel.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
#include <iostream>
88

9+
#include "DecimalData.hpp"
10+
11+
912
using QtNodes::PortType;
1013
using QtNodes::PortIndex;
1114
using QtNodes::NodeData;
@@ -58,5 +61,11 @@ class NumberDisplayDataModel : public NodeDelegateModel
5861
QWidget *
5962
embeddedWidget() override;
6063

64+
double number() const;
65+
66+
67+
private:
68+
std::shared_ptr<DecimalData> _numberData;
69+
6170
QLabel* _label;
6271
};

examples/calculator/NumberSourceDataModel.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
NumberSourceDataModel::
1111
NumberSourceDataModel()
1212
: _lineEdit{nullptr}
13+
, _number(std::make_shared<DecimalData>(0.0))
1314
{
1415
}
1516

@@ -20,8 +21,7 @@ save() const
2021
{
2122
QJsonObject modelJson = NodeDelegateModel::save();
2223

23-
if (_number)
24-
modelJson["number"] = QString::number(_number->number());
24+
modelJson["number"] = QString::number(_number->number());
2525

2626
return modelJson;
2727
}
@@ -42,7 +42,9 @@ load(QJsonObject const& p)
4242
if (ok)
4343
{
4444
_number = std::make_shared<DecimalData>(d);
45-
_lineEdit->setText(strNum);
45+
46+
if (_lineEdit)
47+
_lineEdit->setText(strNum);
4648
}
4749
}
4850
}
@@ -73,13 +75,11 @@ nPorts(PortType portType) const
7375

7476
void
7577
NumberSourceDataModel::
76-
onTextEdited(QString const& string)
78+
onTextEdited(QString const& str)
7779
{
78-
Q_UNUSED(string);
79-
8080
bool ok = false;
8181

82-
double number = _lineEdit->text().toDouble(&ok);
82+
double number = str.toDouble(&ok);
8383

8484
if (ok)
8585
{
@@ -124,8 +124,21 @@ embeddedWidget()
124124
connect(_lineEdit, &QLineEdit::textChanged,
125125
this, &NumberSourceDataModel::onTextEdited);
126126

127-
_lineEdit->setText("0.0");
127+
_lineEdit->setText(QString::number(_number->number()));
128128
}
129129

130130
return _lineEdit;
131131
}
132+
133+
134+
void
135+
NumberSourceDataModel::
136+
setNumber(double n)
137+
{
138+
_number = std::make_shared<DecimalData>(n);
139+
140+
Q_EMIT dataUpdated(0);
141+
142+
if(_lineEdit)
143+
_lineEdit->setText(QString::number(_number->number()));
144+
}

examples/calculator/NumberSourceDataModel.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ class NumberSourceDataModel : public NodeDelegateModel
6868
QWidget *
6969
embeddedWidget() override;
7070

71+
public:
72+
void setNumber(double number);
73+
7174
private Q_SLOTS:
7275

7376
void

examples/calculator/headless_main.cpp

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
#include "AdditionModel.hpp"
2+
#include "DivisionModel.hpp"
3+
#include "MultiplicationModel.hpp"
4+
#include "NumberDisplayDataModel.hpp"
5+
#include "NumberSourceDataModel.hpp"
6+
#include "SubtractionModel.hpp"
7+
8+
#include <QtNodes/DataFlowGraphModel>
9+
#include <QtNodes/NodeDelegateModelRegistry>
10+
11+
12+
using QtNodes::NodeId;
13+
using QtNodes::DataFlowGraphModel;
14+
using QtNodes::NodeDelegateModelRegistry;
15+
16+
17+
static std::shared_ptr<NodeDelegateModelRegistry>
18+
registerDataModels()
19+
{
20+
auto ret = std::make_shared<NodeDelegateModelRegistry>();
21+
ret->registerModel<NumberSourceDataModel>("Sources");
22+
23+
ret->registerModel<NumberDisplayDataModel>("Displays");
24+
25+
ret->registerModel<AdditionModel>("Operators");
26+
27+
ret->registerModel<SubtractionModel>("Operators");
28+
29+
ret->registerModel<MultiplicationModel>("Operators");
30+
31+
ret->registerModel<DivisionModel>("Operators");
32+
33+
return ret;
34+
}
35+
36+
37+
/**
38+
* This scene JSON was saved by the normal `calculator` example.
39+
* It has one source number node connected to both inputs of an addition node,
40+
* the result is rendered in a displayer node.
41+
*
42+
* ____________
43+
* / O[ ]
44+
* _____________ / [ addition ] ______________
45+
* [ source node ]O [ node ]O- - - -O[ display node ]
46+
* ------------- \ [ ] --------------
47+
* \ O[____________]
48+
*/
49+
static QString addingNumbersScene(
50+
R"(
51+
{
52+
"nodes": [
53+
{
54+
"id": 0,
55+
"internal-data": {
56+
"model-name": "NumberSource",
57+
"number": "3"
58+
},
59+
"position": {
60+
"x": -338,
61+
"y": -160
62+
}
63+
},
64+
{
65+
"id": 1,
66+
"internal-data": {
67+
"model-name": "Addition"
68+
},
69+
"position": {
70+
"x": -31,
71+
"y": -264
72+
}
73+
},
74+
{
75+
"id": 2,
76+
"internal-data": {
77+
"model-name": "Result"
78+
},
79+
"position": {
80+
"x": 201,
81+
"y": -129
82+
}
83+
}
84+
],
85+
"connections": [
86+
{
87+
"inPortIndex": 0,
88+
"intNodeId": 2,
89+
"outNodeId": 1,
90+
"outPortIndex": 0
91+
},
92+
{
93+
"inPortIndex": 1,
94+
"intNodeId": 1,
95+
"outNodeId": 0,
96+
"outPortIndex": 0
97+
},
98+
{
99+
"inPortIndex": 0,
100+
"intNodeId": 1,
101+
"outNodeId": 0,
102+
"outPortIndex": 0
103+
}
104+
]
105+
}
106+
)");
107+
108+
109+
int
110+
main(int argc, char* argv[])
111+
{
112+
std::shared_ptr<NodeDelegateModelRegistry> registry = registerDataModels();
113+
114+
// Here we create a graph model without attaching to any view or scene.
115+
DataFlowGraphModel dataFlowGraphModel(registry);
116+
117+
// Alternatively you can create the graph by yourself with the functions
118+
// `DataFlowGraphModel::addNode` and `DataFlowGraphModel::addConnection` and
119+
// use the obtained `NodeId` to fetch the `NodeDelegateModel`s
120+
QJsonDocument sceneJson = QJsonDocument::fromJson(addingNumbersScene.toUtf8());
121+
122+
dataFlowGraphModel.load(sceneJson);
123+
124+
qInfo() << "Data Flow graph was created from a json-serialized graph";
125+
126+
NodeId const nodeSource = 0;
127+
NodeId const nodeResult = 2;
128+
129+
130+
qInfo() << "========================================";
131+
qInfo() << "Entering the number " << 33.3 << "to the input node";
132+
dataFlowGraphModel.delegateModel<NumberSourceDataModel>(nodeSource)->setNumber(33.3);
133+
134+
qInfo() << "Result of the addiion operation: "
135+
<< dataFlowGraphModel.delegateModel<NumberDisplayDataModel>(nodeResult)->number();
136+
137+
qInfo() << "========================================";
138+
qInfo() << "Entering the number " << -5. << "to the input node";
139+
dataFlowGraphModel.delegateModel<NumberSourceDataModel>(nodeSource)->setNumber(-5);
140+
141+
qInfo() << "Result of the addiion operation: "
142+
<< dataFlowGraphModel.delegateModel<NumberDisplayDataModel>(nodeResult)->number();
143+
return 0;
144+
}
145+

examples/calculator/main.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,9 @@ main(int argc, char* argv[])
8383
QWidget mainWidget;
8484

8585
auto menuBar = new QMenuBar();
86-
auto saveAction = menuBar->addAction("Save..");
87-
auto loadAction = menuBar->addAction("Load..");
86+
QMenu* menu = menuBar->addMenu("File");
87+
auto saveAction = menu->addAction("Save Scene");
88+
auto loadAction = menu->addAction("Load Scene");
8889

8990
QVBoxLayout* l = new QVBoxLayout(&mainWidget);
9091

examples/simple_graph_model/SimpleGraphModel.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,11 +322,13 @@ SimpleGraphModel::
322322
setPortData(NodeId nodeId,
323323
PortType portType,
324324
PortIndex portIndex,
325-
PortRole role) const
325+
QVariant const& value,
326+
PortRole role)
326327
{
327328
Q_UNUSED(nodeId);
328329
Q_UNUSED(portType);
329330
Q_UNUSED(portIndex);
331+
Q_UNUSED(value);
330332
Q_UNUSED(role);
331333

332334
return false;

examples/simple_graph_model/SimpleGraphModel.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ class SimpleGraphModel : public QtNodes::AbstractGraphModel
8787
setPortData(NodeId nodeId,
8888
PortType portType,
8989
PortIndex portIndex,
90-
PortRole role) const override;
90+
QVariant const& value,
91+
PortRole role = PortRole::Data) override;
9192

9293
bool
9394
deleteConnection(ConnectionId const connectionId) override;

0 commit comments

Comments
 (0)