PeriDyno 1.0.0
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
60 QtNodeWidget::nPorts(PortType portType) const
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
76 NodeDataType QtNodeWidget::dataType(PortType portType, PortIndex portIndex) const
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::Bullet };
84 }
85 else {
86 auto& inputFields = this->getInputFields();
87 std::string str = inputFields[portIndex - mNodeInport.size()]->getClassName();
88
89 return NodeDataType{ str.c_str(), str.c_str(), PortShape::Point };
90 }
91 break;
92
93 case PortType::Out:
94 if (portIndex == 0) {
95 //TODO: return more accurate description
96 return NodeDataType{ "port", "port", PortShape::Bullet };
97 }
98 else {
99 auto& outputFields = this->getOutputFields();
100 std::string str = outputFields[portIndex - 1]->getClassName();
101
102 return NodeDataType{ str.c_str(), str.c_str(), PortShape::Point };
103 }
104
105 break;
106
107 case PortType::None:
108 break;
109 }
110
111 return NodeDataType{ "port", "port", PortShape::Point };
112 }
113
114 std::shared_ptr<QtNodeData>
115 QtNodeWidget::outData(PortIndex port)
116 {
117 return port == 0 ? std::static_pointer_cast<QtNodeData>(mNodeExport) : std::static_pointer_cast<QtNodeData>(mFieldExport[port - 1]);
118 }
119
120// std::shared_ptr<QtNodeData> QtNodeWidget::inData(PortIndex port)
121// {
122// return port < mNodeInport.size() ? std::static_pointer_cast<QtNodeData>(mNodeInport[port]) : std::static_pointer_cast<QtNodeData>(mFieldInport[port - mNodeInport.size()]);
123// }
124
125 QString QtNodeWidget::caption() const
126 {
127 return dyno::FormatBlockCaptionName(mNode->caption());
128 }
129
130 QString QtNodeWidget::name() const
131 {
132 return dyno::FormatBlockCaptionName(mNode->caption());
133 //return QString::fromStdString(mNode->getClassInfo()->getClassName());
134 }
135
137 {
138 return dyno::FormatDescription(mNode->description());
139 }
140
141 bool QtNodeWidget::portCaptionVisible(PortType portType, PortIndex portIndex) const
142 {
143 Q_UNUSED(portType); Q_UNUSED(portIndex);
144 return true;
145 }
146
147 QString QtNodeWidget::portCaption(PortType portType, PortIndex portIndex) const
148 {
149 switch (portType)
150 {
151 case PortType::In:
152 if (portIndex < mNodeInport.size()) {
153 return dyno::FormatBlockPortName(mNode->getImportNodes()[portIndex]->getPortName());
154 }
155 else {
156 auto& inputFields = this->getInputFields();
157
158 return dyno::FormatBlockPortName(inputFields[portIndex - mNodeInport.size()]->getObjectName());
159 }
160 break;
161
162 case PortType::Out:
163 if (portIndex == 0) {
164 //return dyno::FormatBlockPortName(mNode->getClassInfo()->getClassName());
165 return dyno::FormatBlockPortName("");
166 }
167 else {
168 auto& outputFields = this->getOutputFields();
169
170 return dyno::FormatBlockPortName(outputFields[portIndex - 1]->getObjectName());
171 }
172 break;
173
174 case PortType::None:
175 break;
176 }
177 }
178
179 QString QtNodeWidget::portTips(PortType portType, PortIndex portIndex) const
180 {
181 std::string tip;
182
183 auto nodeTip = [&](Node* node) -> QString {
184 return QString::fromStdString(node->getClassInfo()->getClassName());
185 };
186
187 auto fieldTip = [&](FBase* f) -> QString {
188 tip += "Class: " + f->getClassName() + "\n";
189 tip += "Template: " + f->getTemplateName() + "\n";
190
191 return QString::fromStdString(tip);
192 };
193
194 switch (portType)
195 {
196 case PortType::In:
197 if (portIndex < mNodeInport.size()) {
198 return dyno::FormatBlockPortName(mNode->getImportNodes()[portIndex]->getPortName());
199 }
200 else {
201 auto& inputFields = this->getInputFields();
202 return fieldTip(inputFields[portIndex - mNodeInport.size()]);
203 }
204 break;
205
206 case PortType::Out:
207 if (portIndex == 0) {
208 return nodeTip(mNode.get());
209 }
210 else {
211 auto& outputFields = this->getOutputFields();
212 return fieldTip(outputFields[portIndex - 1]);
213 }
214
215 break;
216
217 case PortType::None:
218 break;
219 }
220 }
221
222 void QtNodeWidget::setInData(std::shared_ptr<QtNodeData> data, PortIndex portIndex)
223 {
224 if (!mEditingEnabled)
225 return;
226
227 if (portIndex < mNodeInport.size())
228 {
229 auto node_port = std::dynamic_pointer_cast<QtExportNode>(data);
230
231 if (node_port != nullptr)
232 {
233 auto nd = node_port->getNode();
234
235 if (node_port->connectionType() == CntType::Break)
236 {
237 //mNodeInport[portIndex]->getNodePort()->removeNode(nd.get());
238 nd->disconnect(mNodeInport[portIndex]->getNodePort());
239
240 //TODO: recover the connection state, use a more elegant way in the future
241 data->setConnectionType(CntType::Link);
242 }
243 else
244 {
245 //mNodeInport[portIndex]->getNodePort()->addNode(nd.get());
246 nd->connect(mNodeInport[portIndex]->getNodePort());
247 }
248 }
249 }
250 else
251 {
252 auto fieldData = std::dynamic_pointer_cast<QtFieldData>(data);
253
254 if (fieldData != nullptr)
255 {
256 auto field = fieldData->getField();
257
258 if (fieldData->connectionType() == CntType::Break)
259 {
260 field->disconnect(mFieldInport[portIndex - mNodeInport.size()]->getField());
261 fieldData->setConnectionType(CntType::Link);
262 }
263 else
264 {
265 field->connect(mFieldInport[portIndex - mNodeInport.size()]->getField());
266 }
267 }
268 }
269
270 updateModule();
271 }
272
273
274 bool QtNodeWidget::tryInData(PortIndex portIndex, std::shared_ptr<QtNodeData> nodeData)
275 {
276 if (!mEditingEnabled)
277 return false;
278
279 if (portIndex < mNodeInport.size())
280 {
281 try
282 {
283 auto nodeExp = std::dynamic_pointer_cast<QtExportNode>(nodeData);
284
285 if (nodeExp == nullptr)
286 return false;
287
288 auto nodeInp = mNodeInport[portIndex];
289
290 return nodeInp->getNodePort()->isKindOf(nodeExp->getNode().get());;
291 }
292 catch (std::bad_cast)
293 {
294 return false;
295 }
296 }
297 else
298 {
299 try
300 {
301 auto fieldExp = std::dynamic_pointer_cast<QtFieldData>(nodeData);
302 if (fieldExp == nullptr)
303 return false;
304
305 auto fieldInp = mFieldInport[portIndex - mNodeInport.size()];
306
307 if (fieldInp->getField()->getClassName() == fieldExp->getField()->getClassName())
308 {
309 std::string className = fieldInp->getField()->getClassName();
310 if (className == dyno::InstanceBase::className())
311 {
312 dyno::InstanceBase* instIn = dynamic_cast<dyno::InstanceBase*>(fieldInp->getField());
313 dyno::InstanceBase* instOut = dynamic_cast<dyno::InstanceBase*>(fieldExp->getField());
314
315 if (instIn != nullptr && instOut != nullptr)
316 return instIn->canBeConnectedBy(instOut);
317
318 return false;
319 }
320 else
321 return fieldInp->getField()->getTemplateName() == fieldExp->getField()->getTemplateName();
322 }
323 else
324 {
325 return false;
326 }
327 }
328 catch (std::bad_cast)
329 {
330 return false;
331 }
332 }
333 }
334
335 NodeValidationState QtNodeWidget::validationState() const
336 {
338 }
339
340 QtNodeDataModel::ConnectionPolicy QtNodeWidget::portInConnectionPolicy(PortIndex portIndex) const
341 {
342 if (portIndex < mNodeInport.size())
343 {
344 auto portType = mNodeInport[portIndex]->getNodePort()->getPortType();
345
346 return portType == dyno::NodePortType::Single ? ConnectionPolicy::One : ConnectionPolicy::Many;
347 }
348 else
349 {
350 return ConnectionPolicy::One;
351 }
352 }
353
354 std::shared_ptr<Node> QtNodeWidget::getNode()
355 {
356 return mNode;
357 }
358
360 {
362 }
363
365 {
366 modelValidationState = NodeValidationState::Valid;
367 }
368
369 std::vector<FBase*>& QtNodeWidget::getOutputFields() const
370 {
371 return mNode->getOutputFields();
372 }
373
374 std::vector<FBase*>& QtNodeWidget::getInputFields() const
375 {
376 return mNode->getInputFields();
377 }
378
380 {
381 mEditingEnabled = true;
382 }
383
385 {
386 mEditingEnabled = false;
387 }
388}
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:37
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