PeriDyno 1.2.1
Loading...
Searching...
No Matches
WtConnection.cpp
Go to the documentation of this file.
1#include "WtConnection.h"
2
3#include <cmath>
4#include <utility>
5#include <cassert>
6
7#include "WtNode.h"
8#include "WtFlowScene.h"
9
11#include "WtNodeDataModel.h"
13
14#include "WtNodeStyle.h"
15
17 : _in(0, 0)
18 , _out(0, 0)
19 , _lineWidth(3.0)
20 , _hovered(false)
21{}
22
23Wt::WPointF const& WtConnectionGeometry::getEndPoint(PortType portType) const
24{
25 assert(portType != PortType::None);
26 return (portType == PortType::Out ? _out : _in);
27}
28
29void WtConnectionGeometry::setEndPoint(PortType portType, Wt::WPointF const& point)
30{
31 switch (portType)
32 {
33 case PortType::In:
34 _in = point;
35 break;
36 case PortType::Out:
37 _out = point;
38 break;
39
40 default:
41 break;
42 }
43}
44
45void WtConnectionGeometry::moveEndPoint(PortType portType, Wt::WPointF const& offset)
46{
47 switch (portType)
48 {
49 case PortType::In:
50 _in += offset;
51 break;
52 case PortType::Out:
53 _out += offset;
54 break;
55
56 default:
57 break;
58 }
59}
60
62{
63 auto points = pointsC1C2();
64
65 Wt::WRectF basicRect = Wt::WRectF(_out, _in).normalized();
66
67 Wt::WRectF c1c2Rect = Wt::WRectF(points.first, points.second).normalized();
68
69 auto const& connectionStyle = WtStyleCollection::connectionStyle();
70
71 float const diam = connectionStyle.pointDiameter();
72
73 Wt::WRectF commonRect = basicRect.united(c1c2Rect);
74
75 Wt::WPointF const cornerOffset(diam, diam);
76
77 Wt::WPointF topLeft(commonRect.topLeft().x() - cornerOffset.x(), commonRect.topLeft().y() - cornerOffset.y());
78
79 Wt::WPointF bottomRight(commonRect.bottomLeft().x() + 2 * cornerOffset.x(), commonRect.bottomLeft().y() + 2 * cornerOffset.y());
80
81 return Wt::WRectF(topLeft, bottomRight);
82}
83
84std::pair<Wt::WPointF, Wt::WPointF> WtConnectionGeometry::pointsC1C2() const
85{
86 const double defaultOffset = 200;
87
88 double xDistance = _in.x() - _out.x();
89
90 double horizontalOffset = std::min(defaultOffset, std::abs(xDistance));
91
92 double verticalOffset = 0;
93
94 double ratioX = 0.5;
95
96 if (xDistance <= 0)
97 {
98 double yDistance = _in.y() - _out.y();
99
100 double vector = yDistance < 0 ? -1.0 : 1.0;
101
102 verticalOffset = std::min(defaultOffset, std::abs(yDistance)) * vector;
103
104 ratioX = 1.0;
105 }
106
107 horizontalOffset *= ratioX;
108
109 Wt::WPointF c1(_out.x() + horizontalOffset, _out.y() + verticalOffset);
110 Wt::WPointF c2(_in.x() - horizontalOffset, _in.y() - verticalOffset);
111
112 return std::make_pair(c1, c2);
113}
114
115// WtConnectionState
120
122{
123 if (node)
124 {
125 _lastHoveredNode = node;
126 }
127 else
128 {
130 }
131}
132
137
139{
141 _lastHoveredNode->resetReactionToConnection();
142
143 _lastHoveredNode = nullptr;
144}
145
147 PortType portType,
148 WtNode& node,
149 PortIndex portIndex)
150 : _uid(Wt::newGuid())
154{
155 setNodeToPort(node, portType, portIndex);
156 setRequiredPort(oppositePort(portType));
157}
158
160 WtNode& nodeIn,
161 PortIndex portIndexIn,
162 WtNode& nodeOut,
163 PortIndex portIndexOut,
164 TypeConverter converter)
165 : _uid(Wt::Guid())
166 , _outNode(&nodeOut)
167 , _inNode(&nodeIn)
168 , _outPortIndex(portIndexOut)
169 , _inPortIndex(portIndexIn)
171{
172 setNodeToPort(nodeIn, PortType::In, portIndexIn);
173 setNodeToPort(nodeOut, PortType::Out, portIndexOut);
174}
175
177 WtNode& nodeIn,
178 PortIndex portIndexIn,
179 WtNode& nodeOut,
180 PortIndex portIndexOut)
181 : _uid(Wt::Guid())
182 , _outNode(&nodeOut)
183 , _inNode(&nodeIn)
184 , _outPortIndex(portIndexOut)
185 , _inPortIndex(portIndexIn)
187{
188 setNodeToPort(nodeIn, PortType::In, portIndexIn);
189 setNodeToPort(nodeOut, PortType::Out, portIndexOut);
190}
191
193{
194 if (complete())
195 {
196 //signal
197 //connectionMadeIncomplete(*this);
198 }
199 //propagateDisconnectedData();
200
201 if (_inNode)
202 {
203 // No Update
204 //_inNode->nodeGraphicsObject().update();
205 }
206
207 if (_outNode)
208 {
209 // No Update
210 //_outNode->nodeGraphicsObject.update();
211 }
212}
213
214//QJsonObject
215//QtConnection::
216//save() const
217//{
218// QJsonObject connectionJson;
219//
220// if (_inNode && _outNode)
221// {
222// connectionJson["in_id"] = _inNode->id().toString();
223// connectionJson["in_index"] = _inPortIndex;
224//
225// connectionJson["out_id"] = _outNode->id().toString();
226// connectionJson["out_index"] = _outPortIndex;
227//
228// if (_converter)
229// {
230// auto getTypeJson = [this](PortType type)
231// {
232// QJsonObject typeJson;
233// NodeDataType nodeType = this->dataType(type);
234// typeJson["id"] = nodeType.id;
235// typeJson["name"] = nodeType.name;
236//
237// return typeJson;
238// };
239//
240// QJsonObject converterTypeJson;
241//
242// converterTypeJson["in"] = getTypeJson(PortType::In);
243// converterTypeJson["out"] = getTypeJson(PortType::Out);
244//
245// connectionJson["converter"] = converterTypeJson;
246// }
247// }
248//
249// return connectionJson;
250//}
251
253{
254 return _uid;
255}
256
258{
259 return _inNode != nullptr && _outNode != nullptr;
260}
261
263{
264 _connectionState.setRequiredPort(dragging);
265
266 switch (dragging)
267 {
268 case PortType::Out:
269 _outNode = nullptr;
271 break;
272
273 case PortType::In:
274 _inNode = nullptr;
276 break;
277
278 default:
279 break;
280 }
281}
282
284{
285 return _connectionState.requiredPort();
286}
287
288void WtConnection::setGraphicsObject(std::unique_ptr<WtConnectionGraphicsObject>&& graphics)
289{
290 _connectionGraphicsObject = std::move(graphics);
291
292 // This function is only called when the ConnectionGraphicsObject
293 // is newly created. At this moment both end coordinates are (0, 0)
294 // in QtConnection G.O. coordinates. The position of the whole
295 // QtConnection G. O. in scene coordinate system is also (0, 0).
296 // By moving the whole object to the QtNode Port position
297 // we position both connection ends correctly.
298
300 {
301 PortType attachedPort = oppositePort(requiredPort());
302
303 PortIndex attachedPortIndex = getPortIndex(attachedPort);
304
305 auto node = getNode(attachedPort);
306
307 Wt::WTransform nodeSceneTransform = node->nodeGraphicsObject().sceneTransform();
308
309 Wt::WPointF pos = node->nodeGeometry().portScenePosition(attachedPortIndex,
310 attachedPort,
311 nodeSceneTransform);
312
313 _connectionGraphicsObject->setPos(pos);
314 }
316}
317
319{
320 PortIndex result = INVALID_PORT;
321
322 switch (portType)
323 {
324 case PortType::In:
325 result = _inPortIndex;
326 break;
327
328 case PortType::Out:
329 result = _outPortIndex;
330
331 break;
332
333 default:
334 break;
335 }
336
337 return result;
338}
339
341 WtNode& node,
342 PortType portType,
343 PortIndex portIndex)
344{
345 bool wasIncomplete = !complete();
346
347 auto& nodeWeak = getNode(portType);
348
349 nodeWeak = &node;
350
351 if (portType == PortType::Out)
352 _outPortIndex = portIndex;
353 else
354 _inPortIndex = portIndex;
355
356 _connectionState.setNoRequiredPort();
357
358 //signal
359 //updated(*this);
360
361 if (complete() && wasIncomplete) {
362 //signal
363 //connectionCompleted(*this);
364 }
365}
366
368{
369 if (_inNode)
370 _inNode->nodeState().eraseConnection(PortType::In, _inPortIndex, id());
371
372 if (_outNode)
373 _outNode->nodeState().eraseConnection(PortType::Out, _outPortIndex, id());
374}
375
380
385
390
395
400
402{
403 switch (portType)
404 {
405 case PortType::In:
406 return _inNode;
407 break;
408
409 case PortType::Out:
410 return _outNode;
411 break;
412
413 default:
414 // not possible
415 break;
416 }
417 return nullptr;
418}
419
421{
422 switch (portType)
423 {
424 case PortType::In:
425 return _inNode;
426 break;
427
428 case PortType::Out:
429 return _outNode;
430 break;
431
432 default:
433 // not possible
434 break;
435 }
436 //sQ_UNREACHABLE();
437}
438
440{
441 if (complete())
442 {
443 //signal
444 //connectionMadeIncomplete(*this);
445 }
446
447 getNode(portType) = nullptr;
448
449 if (portType == PortType::In)
451 else
453}
454
456{
457 if (_inNode && _outNode)
458 {
459 auto const& model = (portType == PortType::In) ?
460 _inNode->nodeDataModel() :
461 _outNode->nodeDataModel();
462 PortIndex index = (portType == PortType::In) ?
465
466 return model->dataType(portType, index);
467 }
468 else
469 {
470 WtNode* validNode;
471 PortIndex index = INVALID_PORT;
472
473 if ((validNode = _inNode))
474 {
475 index = _inPortIndex;
476 portType = PortType::In;
477 }
478 else if ((validNode = _outNode))
479 {
480 index = _outPortIndex;
481 portType = PortType::Out;
482 }
483
484 if (validNode)
485 {
486 auto const& model = validNode->nodeDataModel();
487
488 return model->dataType(portType, index);
489 }
490 }
491 //Q_UNREACHABLE();
492}
493
495{
496 _converter = std::move(converter);
497}
498
499void WtConnection::propagateData(std::shared_ptr<WtNodeData> nodeData) const
500{
501 if (_inNode)
502 {
503 if (_converter)
504 {
505 nodeData = _converter(nodeData);
506 }
507
508 _inNode->propagateData(nodeData, _inPortIndex);
509 }
510}
511
513{
514 std::shared_ptr<WtNodeData> emptyData;
515
516 propagateData(emptyData);
517}
518
520{
521 std::shared_ptr<WtNodeData> deletedData = nullptr;
522 if (_outNode)
523 {
524 deletedData = _outNode->nodeDataModel()->outData(_outPortIndex);
525 if (_inNode && deletedData) {
526 deletedData->setConnectionType(CntType::Break);
527 }
528 }
529
530 propagateData(deletedData);
531}
assert(queueCount >=1)
std::function< SharedNodeData(SharedNodeData)> TypeConverter
int PortIndex
static const int INVALID_PORT
PortType oppositePort(PortType port)
PortType
Wt::WRectF boundingRect() const
void moveEndPoint(PortType portType, Wt::WPointF const &offset)
void setEndPoint(PortType portType, Wt::WPointF const &point)
Wt::WPointF const & getEndPoint(PortType portType) const
std::pair< Wt::WPointF, Wt::WPointF > pointsC1C2() const
Graphic Object for connection. Adds itself to scene.
WtConnectionState _connectionState
WtNode * _outNode
void propagateData(std::shared_ptr< WtNodeData > nodeData) const
WtNode * getNode(PortType portType) const
WtConnectionGeometry _connectionGeometry
NodeDataType dataType(PortType portType) const
WtConnectionGraphicsObject & getConnectionGraphicsObject() const
void setTypeConverter(TypeConverter converter)
void clearNode(PortType portType)
void propagateDisconnectedData() const
PortIndex _outPortIndex
PortType requiredPort() const
void setRequiredPort(PortType portType)
bool complete() const
PortIndex getPortIndex(PortType portType) const
WtConnection(PortType portType, WtNode &node, PortIndex portIndex)
PortIndex _inPortIndex
Wt::Guid id() const
WtNode * _inNode
void propagateEmptyData() const
Wt::Guid _uid
WtConnectionState const & connectionState() const
WtConnectionGeometry & connectionGeometry()
std::unique_ptr< WtConnectionGraphicsObject > _connectionGraphicsObject
void setGraphicsObject(std::unique_ptr< WtConnectionGraphicsObject > &&graphics)
void setNodeToPort(WtNode &node, PortType portType, PortIndex portIndex)
void removeFromNodes() const
TypeConverter _converter
WtNode * _lastHoveredNode
void setLastHoveredNode(WtNode *node)
void interactWithNode(WtNode *node)
virtual NodeDataType dataType(PortType portType, PortIndex portIndex) const =0
WtNodeDataModel * nodeDataModel() const
Definition WtNode.cpp:727
static WtConnectionStyle const & connectionStyle()
Definition guid.cpp:5