PeriDyno 1.2.1
Loading...
Searching...
No Matches
QtNodeWidget.cpp
Go to the documentation of this file.
1#include "QtNodeWidget.h"
2
3#include "nodes/QConnection"
4#include "nodes/QNode"
5
6#include "Node.h"
7#include "NodePort.h"
8
9#include "Format.h"
10
11#include "FInstance.h"
12#include "Field.h"
13
14namespace Qt
15{
16 QtNodeWidget::QtNodeWidget(std::shared_ptr<Node> base)
17 {
18 mNode = base;
19
20 if (mNode != nullptr)
21 {
22 //initialize in node ports
23 auto inputs = mNode->getImportNodes();
24 auto input_num = inputs.size();
25
26 mNodeInport.resize(input_num);
27 for (int i = 0; i < inputs.size(); i++)
28 {
29 mNodeInport[i] = std::make_shared<QtImportNode>(inputs[i]);
30 }
31
32 //initialize out node ports
33 mNodeExport = std::make_shared<QtExportNode>(base);
34
35 int output_fnum = getOutputFields().size();
36 mFieldExport.resize(output_fnum);
37 auto fOutputs = getOutputFields();
38 for (int i = 0; i < fOutputs.size(); i++)
39 {
40 mFieldExport[i] = std::make_shared<QtFieldData>(fOutputs[i]);
41 }
42
43 //initialize in ports
44 int input_fnum = getInputFields().size();
45 mFieldInport.resize(input_fnum);
46 auto fInputs = getInputFields();
47 for (int i = 0; i < fInputs.size(); i++)
48 {
49 mFieldInport[i] = std::make_shared<QtFieldData>(fInputs[i]);
50 }
51 }
52
53 }
54
58
59 unsigned int
61 {
62 unsigned int result;
63
64 if (portType == PortType::In)
65 {
66 result = (unsigned int)mNode->getImportNodes().size() + mFieldInport.size();
67 }
68 else
69 {
70 result = 1 + mFieldExport.size();
71 }
72
73 return result;
74 }
75
77 {
78 switch (portType)
79 {
80 case PortType::In:
81 if (portIndex < mNodeInport.size()) {
82 //TODO: return more accurate description
83 return NodeDataType{ "port", "port", PortShape::Diamond };
84 }
85 else {
86 auto& inputFields = this->getInputFields();
87 std::string str = inputFields[portIndex - mNodeInport.size()]->getClassName();
88
89 if (str == "FInstance" || str == "FInstances")
90 {
91 std::string insName = dyno::InstanceBase::className();
92 return NodeDataType{ insName.c_str(), insName.c_str(), PortShape::Point };
93 }
94 else
95 return NodeDataType{ str.c_str(), str.c_str(), PortShape::Point };
96
97 }
98 break;
99
100 case PortType::Out:
101 if (portIndex == 0) {
102 //TODO: return more accurate description
103 return NodeDataType{ "port", "port", PortShape::Diamond };
104 }
105 else {
106 auto& outputFields = this->getOutputFields();
107 std::string str = outputFields[portIndex - 1]->getClassName();
108
109 if (str == "FInstance" || str == "FInstances")
110 {
111 std::string insName = dyno::InstanceBase::className();
112 return NodeDataType{ insName.c_str(), insName.c_str(), PortShape::Point };
113 }
114 else
115 return NodeDataType{ str.c_str(), str.c_str(), PortShape::Point };
116 }
117
118 break;
119
120 case PortType::None:
121 break;
122 }
123
124 return NodeDataType{ "port", "port", PortShape::Point };
125 }
126
127 std::shared_ptr<QtNodeData>
129 {
130 return port == 0 ? std::static_pointer_cast<QtNodeData>(mNodeExport) : std::static_pointer_cast<QtNodeData>(mFieldExport[port - 1]);
131 }
132
133// std::shared_ptr<QtNodeData> QtNodeWidget::inData(PortIndex port)
134// {
135// return port < mNodeInport.size() ? std::static_pointer_cast<QtNodeData>(mNodeInport[port]) : std::static_pointer_cast<QtNodeData>(mFieldInport[port - mNodeInport.size()]);
136// }
137
138 QString QtNodeWidget::caption() const
139 {
140 return dyno::FormatBlockCaptionName(mNode->caption());
141 }
142
143 QString QtNodeWidget::name() const
144 {
145 return dyno::FormatBlockCaptionName(mNode->caption());
146 //return QString::fromStdString(mNode->getClassInfo()->getClassName());
147 }
148
150 {
151 return dyno::FormatDescription(mNode->description());
152 }
153
155 {
156 Q_UNUSED(portType); Q_UNUSED(portIndex);
157 return true;
158 }
159
160 QString QtNodeWidget::portCaption(PortType portType, PortIndex portIndex) const
161 {
162 switch (portType)
163 {
164 case PortType::In:
165 if (portIndex < mNodeInport.size()) {
166 return dyno::FormatBlockPortName(mNode->getImportNodes()[portIndex]->getPortName());
167 }
168 else {
169 auto& inputFields = this->getInputFields();
170
171 return dyno::FormatBlockPortName(inputFields[portIndex - mNodeInport.size()]->getObjectName());
172 }
173 break;
174
175 case PortType::Out:
176 if (portIndex == 0) {
177 //return dyno::FormatBlockPortName(mNode->getClassInfo()->getClassName());
178 return dyno::FormatBlockPortName("");
179 }
180 else {
181 auto& outputFields = this->getOutputFields();
182
183 return dyno::FormatBlockPortName(outputFields[portIndex - 1]->getObjectName());
184 }
185 break;
186
187 case PortType::None:
188 break;
189 }
190
191 return QString("");
192 }
193
194 QString QtNodeWidget::portTips(PortType portType, PortIndex portIndex) const
195 {
196 std::string tip;
197
198 auto nodeTip = [&](Node* node) -> QString {
199 return QString::fromStdString(node->getClassInfo()->getClassName());
200 };
201
202 auto fieldTip = [&](FBase* f) -> QString {
203 tip += "Class: " + f->getClassName() + "\n";
204 tip += "Template: " + f->getTemplateName() + "\n";
205
206 return QString::fromStdString(tip);
207 };
208
209 switch (portType)
210 {
211 case PortType::In:
212 if (portIndex < mNodeInport.size()) {
213 return dyno::FormatBlockPortName(mNode->getImportNodes()[portIndex]->getPortName());
214 }
215 else {
216 auto& inputFields = this->getInputFields();
217 return fieldTip(inputFields[portIndex - mNodeInport.size()]);
218 }
219 break;
220
221 case PortType::Out:
222 if (portIndex == 0) {
223 return nodeTip(mNode.get());
224 }
225 else {
226 auto& outputFields = this->getOutputFields();
227 return fieldTip(outputFields[portIndex - 1]);
228 }
229
230 break;
231
232 case PortType::None:
233 break;
234 }
235 }
236
237 void QtNodeWidget::setInData(std::shared_ptr<QtNodeData> data, PortIndex portIndex)
238 {
239 if (!mEditingEnabled)
240 return;
241
242 if (portIndex < mNodeInport.size())
243 {
244 auto node_port = std::dynamic_pointer_cast<QtExportNode>(data);
245
246 if (node_port != nullptr)
247 {
248 auto nd = node_port->getNode();
249
250 if (node_port->connectionType() == CntType::Break)
251 {
252 //mNodeInport[portIndex]->getNodePort()->removeNode(nd.get());
253 nd->disconnect(mNodeInport[portIndex]->getNodePort());
254
255 //TODO: recover the connection state, use a more elegant way in the future
256 data->setConnectionType(CntType::Link);
257 }
258 else
259 {
260 //mNodeInport[portIndex]->getNodePort()->addNode(nd.get());
261 nd->connect(mNodeInport[portIndex]->getNodePort());
262 }
263 }
264 }
265 else
266 {
267 auto fieldData = std::dynamic_pointer_cast<QtFieldData>(data);
268
269 if (fieldData != nullptr)
270 {
271 auto field = fieldData->getField();
272
273 if (fieldData->connectionType() == CntType::Break)
274 {
275 field->disconnect(mFieldInport[portIndex - mNodeInport.size()]->getField());
276 fieldData->setConnectionType(CntType::Link);
277 }
278 else
279 {
280 field->connect(mFieldInport[portIndex - mNodeInport.size()]->getField());
281 }
282 }
283 }
284
285 updateModule();
286 }
287
288
289 bool QtNodeWidget::tryInData(PortIndex portIndex, std::shared_ptr<QtNodeData> nodeData)
290 {
291 if (!mEditingEnabled)
292 return false;
293
294 if (portIndex < mNodeInport.size())
295 {
296 try
297 {
298 auto nodeExp = std::dynamic_pointer_cast<QtExportNode>(nodeData);
299
300 if (nodeExp == nullptr)
301 return false;
302
303 auto nodeInp = mNodeInport[portIndex];
304
305 return nodeInp->getNodePort()->isKindOf(nodeExp->getNode().get());;
306 }
307 catch (std::bad_cast)
308 {
309 return false;
310 }
311 }
312 else
313 {
314 try
315 {
316 auto fieldExp = std::dynamic_pointer_cast<QtFieldData>(nodeData);
317 if (fieldExp == nullptr)
318 return false;
319
320 auto fieldInp = mFieldInport[portIndex - mNodeInport.size()];
321
322 auto fIn = fieldInp->getField();
323 auto fExp = fieldExp->getField();
324
325 dyno::InstanceBase* instIn = dynamic_cast<dyno::InstanceBase*>(fIn);
326 dyno::InstanceBase* instOut = dynamic_cast<dyno::InstanceBase*>(fExp);
327
328 if (instIn != nullptr && instOut != nullptr)
329 return instIn->canBeConnectedBy(instOut);
330 else if (instIn == nullptr && instOut == nullptr)
331 {
332 return fIn->getClassName() == fExp->getClassName() && fIn->getTemplateName() == fExp->getTemplateName();
333 }
334 else
335 return false;
336
337 }
338 catch (std::bad_cast)
339 {
340 return false;
341 }
342 }
343 }
344
349
350 QtNodeDataModel::ConnectionPolicy QtNodeWidget::portInConnectionPolicy(PortIndex portIndex) const
351 {
352 if (portIndex < mNodeInport.size())
353 {
354 auto portType = mNodeInport[portIndex]->getNodePort()->getPortType();
355
356 return portType == dyno::NodePortType::Single ? ConnectionPolicy::One : ConnectionPolicy::Many;
357 }
358 else
359 {
360 auto fieldInp = mFieldInport[portIndex - mNodeInport.size()];
361
362 return fieldInp->getField()->inputPolicy() == FBase::One ? ConnectionPolicy::One : ConnectionPolicy::Many;
363 }
364 }
365
366 std::shared_ptr<Node> QtNodeWidget::getNode()
367 {
368 return mNode;
369 }
370
372 {
374 }
375
380
381 std::vector<FBase*>& QtNodeWidget::getOutputFields() const
382 {
383 return mNode->getOutputFields();
384 }
385
386 std::vector<FBase*>& QtNodeWidget::getInputFields() const
387 {
388 return mNode->getInputFields();
389 }
390
392 {
393 mEditingEnabled = true;
394 }
395
397 {
398 mEditingEnabled = false;
399 }
400}
int PortIndex
PortType
NodeValidationState
@ One
Definition FBase.h:56
QString portCaption(PortType portType, PortIndex portIndex) const override
NodeValidationState validationState() const override
QtNodeWidget(std::shared_ptr< Node > base=nullptr)
std::vector< FBase * > & getInputFields() const
ExportNodePtr mNodeExport
bool tryInData(PortIndex portIndex, std::shared_ptr< QtNodeData > nodeData) override
To test whether nodaData can be set as the input data for portIndex.
QtNodeDataModel::ConnectionPolicy portInConnectionPolicy(PortIndex portIndex) const override
QString name() const override
InFieldPtr mFieldInport
QString modelValidationError
NodeValidationState modelValidationState
QString validationMessage() const override
unsigned int nPorts(PortType portType) const override
QString portTips(PortType portType, PortIndex portIndex) const override
NodeDataType dataType(PortType portType, PortIndex portIndex) const override
OutFieldPtr mFieldExport
std::shared_ptr< QtNodeData > outData(PortIndex port) override
void disableEditing()
When disabled, the scenegraph can not be affected by the corresponding GUI.
void setInData(std::shared_ptr< QtNodeData > data, PortIndex portIndex) override
bool portCaptionVisible(PortType portType, PortIndex portIndex) const override
virtual void updateModule()
virtual ~QtNodeWidget()
std::vector< FBase * > & getOutputFields() const
ImportNodePtr mNodeInport
QString nodeTips() const override
void enableEditing()
When enabled, the scenegraph can be updated as long as the corresponding GUI is updated.
std::shared_ptr< Node > mNode
QString caption() const override
std::shared_ptr< Node > getNode()
virtual bool canBeConnectedBy(InstanceBase *ins)=0
static const std::string className()
Definition FInstance.h:40
QString FormatBlockCaptionName(std::string name)
Definition Format.cpp:64
QString FormatDescription(std::string name)
Definition Format.cpp:93
QString FormatBlockPortName(std::string name)
Definition Format.cpp:35
@ Single
Definition NodePort.h:28