Vuo 2.4.4
Loading...
Searching...
No Matches
VuoRendererCable.cc
Go to the documentation of this file.
1
10#include "VuoRendererCable.hh"
11#include "VuoRendererFonts.hh"
13#include "VuoCable.hh"
14#include "VuoCompilerCable.hh"
15#include "VuoNodeClass.hh"
16
17
19const qreal VuoRendererCable::cableWidth = 5; // VuoRendererFonts::thickPenWidth / 4.;
20
22const qreal VuoRendererCable::cableYankRadius = 20; // VuoRendererFonts::thickPenWidth;
23
28 : VuoBaseDetail<VuoCable>("VuoRendererCable", baseCable)
29{
30 getBase()->setRenderer(this);
31
32 portConstantsChangedSinceLastCachedOutline = true;
33
34 setZValue(cableZValue);
35
36 VuoNode *fromNode = getBase()->getFromNode();
37 VuoRendererNode *fromRN = ((fromNode && fromNode->hasRenderer())? fromNode->getRenderer() : NULL);
38
39 if (fromRN)
41
42 VuoNode *toNode = getBase()->getToNode();
43 VuoRendererNode * toRN = ((toNode && toNode->hasRenderer())? toNode->getRenderer() : NULL);
44
45 if (toRN)
47
48 floatingEndpointLoc = QPointF();
49 floatingEndpointPreviousToPort = NULL;
50 previouslyAlwaysEventOnly = false;
51 floatingEndpointAboveEventPort = false;
52 isHovered = false;
53 _eligibilityHighlight = VuoRendererColors::noHighlight;
54
55 this->setAcceptHoverEvents(true);
56 this->setFlags(QGraphicsItem::ItemIsSelectable);
58}
59
64{
65 if (paintingDisabled())
66 return QRectF();
67
68 QPainterPath cablePath = getCablePath();
69 QRectF r = cablePath.boundingRect();
70
71 if (r.isNull())
72 return r;
73
74 // Include thick width of cable.
75 r.adjust(-cableWidth/2., -cableWidth/2., cableWidth/2., cableWidth/2.);
76
77 // Antialiasing bleed
78 r.adjust(-1,-1,1,1);
79
80 return r.toAlignedRect();
81}
82
87QPainterPath VuoRendererCable::shape() const
88{
89 if (paintingDisabled())
90 return QPainterPath();
91
92 QPainterPath p;
93 p.addPath(getCablePath());
94
95 QPainterPathStroker s;
96 s.setWidth(cableWidth);
97
98 return s.createStroke(p);
99}
100
104QPointF VuoRendererCable::getStartPoint(void) const
105{
106 VuoNode *fromNode = getBase()->getFromNode();
107 VuoPort *fromPort = getBase()->getFromPort();
108
109 if (fromPort && fromPort->hasRenderer())
110 {
111 VuoRendererPublishedPort *sidebarPort = dynamic_cast<VuoRendererPublishedPort *>(fromPort->getRenderer());
112 if (sidebarPort)
113 {
114 QList<QGraphicsView *> views = scene()->views();
115 return (views.empty()? QPointF(0,0) : views[0]->mapToScene(sidebarPort->getCompositionViewportPos()));
116 }
117
118 else if (fromNode && fromNode->hasRenderer())
119 return fromNode->getRenderer()->pos() + fromPort->getRenderer()->pos() + QPointF(0, -.35);
120 }
121
122 return floatingEndpointLoc;
123}
124
128QPointF VuoRendererCable::getEndPoint(void) const
129{
130 VuoCable *cable = getBase();
131 VuoNode *toNode = cable->getToNode();
132 VuoPort *toPort = cable->getToPort();
133
134 if (toNode && toPort && toPort->hasRenderer())
135 {
136 VuoRendererPublishedPort *sidebarPort = dynamic_cast<VuoRendererPublishedPort *>(toPort->getRenderer());
137 if (sidebarPort)
138 {
139 QList<QGraphicsView *> views = scene()->views();
140 return (views.empty()? QPointF(0,0) : views[0]->mapToScene(sidebarPort->getCompositionViewportPos()));
141 }
142
143 else if (toNode->hasRenderer())
144 {
145 VuoRendererNode *rn = toNode->getRenderer();
146 VuoRendererNode *toNodeProxy = rn->getProxyNode();
147 if (toNodeProxy)
148 return toNodeProxy->pos() + toPort->getRenderer()->pos() + QPointF(0, -.35);
149 else
150 return rn->pos() + toPort->getRenderer()->pos() + QPointF(0, -.35);
151 }
152 }
153
154 return floatingEndpointLoc;
155}
156
160QPainterPath VuoRendererCable::getCablePath(void) const
161{
162 if (paintingDisabled())
163 return QPainterPath();
164
165 return getCablePathForEndpoints(getStartPoint(), getEndPoint());
166}
167
174void VuoRendererCable::arclineTo(QPainterPath &cablePath, QPointF to, float radius, float fromCableStandoff) const
175{
176 QPointF from = cablePath.currentPosition();
177 float direction = from.y() < to.y() ? 1 : -1;
178
179 QRectF fromRect(from - QPointF(radius, -radius*2*direction), from + QPointF(radius, 0));
180
181 if (to.x() >= from.x() + radius*2)
182 {
183 // Cable is going left-to-right.
184 // Draw an arc at the cable's start and end.
185
186 // Cable start:
187 float stopAngle = -atan2(to.y() - from.y(), to.x() - from.x()) * 180/M_PI;
188 cablePath.arcTo(fromRect, -90, -stopAngle*direction);
189
190 // Cable end:
191 QRectF toRect(to - QPointF(radius, radius*2*direction), to + QPointF(radius, 0));
192 cablePath.arcTo(toRect, -90 + stopAngle*direction, -stopAngle*direction);
193 }
194 else
195 {
196 // Cable is going right-to-left.
197 // At the cable's start and end, draw an arc, then draw a line to escape the node height, then draw another arc.
198
199 // Cable start:
200 cablePath.arcTo(fromRect, -90, 90);
201
202 float fromNodeEscape = 0;
203 {
204 VuoNode *fromNode = getBase()->getFromNode();
205 VuoPort *fromPort = getBase()->getFromPort();
206 if (fromNode && fromNode->hasRenderer()
207 && fromPort && fromPort->hasRenderer())
208 {
209 VuoRendererNode *rn = fromNode->getRenderer();
210 if (rn->getProxyNode())
211 rn = rn->getProxyNode();
212
213 QRectF nodeRect = rn->sceneBoundingRect();
214 QRectF portRect = fromPort->getRenderer()->sceneBoundingRect();
215 if (from.y() < to.y())
216 // Cable is going downward, so escape the part of the node below the `from` port.
217 fromNodeEscape = nodeRect.bottom() - portRect.bottom();
218 else
219 // Cable is going upward.
220 fromNodeEscape = portRect.top() - nodeRect.top();
221 }
222
223 fromNodeEscape += fromCableStandoff;
224 }
225
226 float toNodeEscape = 0;
227 VuoNode *toNode = getBase()->getToNode();
228 {
229 VuoPort *toPort = getBase()->getToPort();
230 if (toNode && toNode->hasRenderer()
231 && toPort && toPort->hasRenderer())
232 {
233 VuoRendererNode *rn = toNode->getRenderer();
234 if (rn->getProxyNode())
235 rn = rn->getProxyNode();
236
237 QRectF nodeRect = rn->sceneBoundingRect();
238 QRectF portRect = toPort->getRenderer()->sceneBoundingRect();
239 if (from.y() < to.y())
240 // Cable is going downward, so escape the part of the node above the `to` port.
241 toNodeEscape = portRect.top() - nodeRect.top();
242 else
243 // Cable is going upward.
244 toNodeEscape = nodeRect.bottom() - portRect.bottom();
245 }
246 }
247
248 // When a cable connects 2 nodes that are 1 grid spacing apart,
249 // make the horizontal section of the cable exactly horizontal.
250 fromNodeEscape += direction>0 ? 4.85 : 3.15;
251 if (toNode && toNode->getNodeClass()->isDrawerNodeClass())
252 toNodeEscape += direction>0 ? 8 : -1.75;
253 else
254 toNodeEscape += direction>0 ? 4.15 : 4.85;
255
256 // If the ports are so close that the escapement would look loopy, forget it.
257 if (fromNodeEscape + toNodeEscape + radius*3 >= fabs(from.y() - to.y()))
258 fromNodeEscape = toNodeEscape = 0;
259
260 QPointF fromEscaped = cablePath.currentPosition() + QPointF(0, fromNodeEscape*direction);
261 QPointF toEscaped = to - QPointF(radius, (radius + toNodeEscape)*direction);
262
263 QRectF fromEscapedRect(fromEscaped - QPointF(radius*2, radius*direction),
264 fromEscaped + QPointF(0, radius*direction));
265
266 float stopAngle = atan2(fromEscaped.x() - toEscaped.x(), fromEscaped.y() - toEscaped.y()) * 180/M_PI;
267 if (to.y() > from.y())
268 stopAngle = 180-stopAngle;
269
270 cablePath.arcTo(fromEscapedRect, 0, -stopAngle);
271
272
273 // Cable end:
274 QRectF toEscapedRect(toEscaped - QPointF(0, radius*direction), toEscaped + QPointF(radius*2, radius*direction));
275 cablePath.arcTo(toEscapedRect, 180 - stopAngle, stopAngle);
276
277 QRectF toRect(to-QPointF(radius, radius*2*direction), to + QPointF(radius, 0));
278 cablePath.arcTo(toRect, 180, 90);
279 }
280}
281
288QPainterPath VuoRendererCable::getCablePathForEndpoints(QPointF from, QPointF to) const
289{
290 QPainterPath cablePath(from);
291
292 // The `from` node's other output ports (besides the port it's connected to)
293 // may have cables, so escape them to avoid overlapping.
294 float fromStandoff = 0; // Total standoff
295 float fromCableStandoff = 0; // Standoff due to routed cables (excluding hidden cables)
296 VuoNode *fromNode = getBase()->getFromNode();
297 VuoPort *fromPort = getBase()->getFromPort();
298 if (fromNode && fromPort)
299 {
300 vector<VuoPort *> outputs = (from.y() < to.y())
301 ? fromNode->getOutputPortsAfterPort(fromPort)
302 : fromNode->getOutputPortsBeforePort(fromPort);
303 for (vector<VuoPort *>::iterator i = outputs.begin(); i != outputs.end(); ++i)
304 {
305 vector<VuoCable *> cables = (*i)->getConnectedCables();
306 if ((*i)->hasRenderer() && !cables.empty())
307 {
308 bool hasOnlyWireless = true;
309 for (vector<VuoCable *>::iterator cable = cables.begin(); cable != cables.end(); ++cable)
310 if ((*cable)->hasRenderer())
311 {
312 VuoRendererCable *cableR = (*cable)->getRenderer();
313 if (!cableR->getEffectivelyWireless())
314 {
315 hasOnlyWireless = false;
316 break;
317 }
318 }
319
320 if (hasOnlyWireless)
321 // We only need to escape the wireless antenna once (we don't need to escape every port's antenna).
322 fromStandoff = fmax(fromStandoff, VuoRendererPort::portSpacing);
323 else
324 {
325 fromStandoff += VuoRendererPort::portSpacing;
326 fromCableStandoff += VuoRendererPort::portSpacing;
327 }
328 }
329 }
330 }
331 fromStandoff += VuoRendererPort::portSpacing / 2.;
332
333 // The `to` node's other input ports (besides the port it's connected to)
334 // may have constant flags, so escape them.
335 float toStandoff = 0;
336 VuoNode *toNode = getBase()->getToNode();
337 VuoPort *toPort = getBase()->getToPort();
338 if (toNode && toPort)
339 {
340 vector<VuoPort *> inputs = (from.y() < to.y())
341 ? toNode->getInputPortsBeforePort(toPort)
342 : toNode->getInputPortsAfterPort(toPort);
343 for (vector<VuoPort *>::iterator i = inputs.begin(); i != inputs.end(); ++i)
344 if ((*i)->hasRenderer() && (*i)->getRenderer()->isConstant())
345 {
346 float constantFlagWidth = (*i)->getRenderer()->getPortConstantTextRect().width();
347 toStandoff = fmax(toStandoff, constantFlagWidth);
348 }
349 }
350
351 // Move the cable attachment point to the left of the port constant.
352 if (!effectivelyCarriesData() && toPort)
353 toStandoff = fmax(toStandoff, toPort->getRenderer()->getPortConstantTextRect().width());
354
355 toStandoff += VuoRendererPort::portSpacing / 2.;
356
357 QPointF fromWithStandoff(from.x() + fromStandoff, from.y());
358 QPointF toWithStandoff( to.x() - toStandoff, to.y());
359
360 float length = (from - to).manhattanLength();
361 if (length < fromStandoff + toStandoff + VuoRendererPort::portSpacing * 3)
362 {
363 // Cable is very short; just draw a single line.
364 }
365 else
366 {
367 cablePath.lineTo(fromWithStandoff);
368 arclineTo(cablePath, toWithStandoff, VuoRendererPort::portSpacing / 2., fromCableStandoff);
369 }
370
371 cablePath.lineTo(to);
372
373 return cablePath;
374}
375
381{
382 VuoPort *fromPort = getBase()->getFromPort();
383 if (fromPort && fromPort->hasRenderer())
384 return fromPort->getRenderer()->getPortTint();
385
386 return VuoNode::TintNone;
387}
388
393bool VuoRendererCable::isConnectedToSelectedNode(void)
394{
395 VuoNode *fromNode = getBase()->getFromNode();
396 VuoNode *toNode = getBase()->getToNode();
397
398 bool fromNodeIsSelected = (fromNode && fromNode->hasRenderer() && fromNode->getRenderer()->isSelected());
399 bool toNodeIsSelected = (toNode && toNode->hasRenderer() && toNode->getRenderer()->isSelected());
400 bool toNodeViaTypeconverterIsSelected = toNode && toNode->hasRenderer() && toNode->getRenderer()->getProxyNode() && toNode->getRenderer()->getProxyNode()->isEffectivelySelected();
401 bool toNodeViaAttachmentIsSelected = toNode && toNode->hasRenderer() &&
402 dynamic_cast<VuoRendererInputAttachment *>(toNode->getRenderer()) &&
403 dynamic_cast<VuoRendererInputAttachment *>(toNode->getRenderer())->getRenderedHostNode() &&
404 dynamic_cast<VuoRendererInputAttachment *>(toNode->getRenderer())->getRenderedHostNode()->getRenderer()->isSelected();
405
406 return (fromNodeIsSelected || toNodeIsSelected || toNodeViaTypeconverterIsSelected || toNodeViaAttachmentIsSelected);
407}
408
412void VuoRendererCable::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
413{
414 if (paintingDisabled())
415 return;
416
417 bool hoverHighlightingEnabled = isHovered;
418 drawBoundingRect(painter);
419
420 VuoNode::TintColor tintColor = getTintColor();
421 VuoRendererColors::SelectionType selectionType = (isSelected()? VuoRendererColors::directSelection :
422 (isConnectedToSelectedNode()? VuoRendererColors::indirectSelection :
423 VuoRendererColors::noSelection));
424
425 qint64 timeOfLastActivity = (getRenderActivity()? timeLastEventPropagated : VuoRendererItem::notTrackingActivity);
426 VuoRendererColors colors(tintColor,
427 selectionType,
428 (selectionType != VuoRendererColors::noSelection? false : hoverHighlightingEnabled),
429 _eligibilityHighlight,
430 timeOfLastActivity
431 );
432
433 VuoRendererColors yankZoneColors(tintColor,
434 selectionType,
435 true,
437 timeOfLastActivity);
438
439 QPointF startPoint = getStartPoint();
440 QPointF endPoint = getEndPoint();
441 bool renderAsIfCableCarriesData = effectivelyCarriesData() && !floatingEndpointAboveEventPort;
442
443 // Etch the highlight out of the main cable.
444 QPainterPath outline = getOutline(startPoint, endPoint, renderAsIfCableCarriesData);
445 if (outline.isEmpty())
446 return;
447
448 // Fill the cable.
449 painter->fillPath(outline, QBrush(colors.cableMain()));
450
451 // Highlight the yank zone when hovering.
452 if (hoverHighlightingEnabled)
453 {
454 bool toPortSupportsYanking = getBase()->getToPort() &&
456
457 QPainterPath yankZone;
458 getYankZonePath(startPoint, endPoint, renderAsIfCableCarriesData, toPortSupportsYanking, yankZone);
459
460 painter->setClipPath(yankZone);
461 painter->fillPath(outline, QBrush(yankZoneColors.cableMain()));
462
463 painter->setClipping(false);
464 }
465}
466
472QPainterPath VuoRendererCable::getOutline(QPointF startPoint,
473 QPointF endPoint,
474 bool cableCarriesData)
475{
476 if ((qMakePair(startPoint, endPoint) != this->cachedEndpointsForOutlines)
477 || (cableCarriesData != this->cachedCarriesDataValueForOutlines)
478 || portConstantsChangedSinceLastCachedOutline)
479 {
480 qreal cableWidth;
481 getCableSpecs(cableCarriesData, cableWidth);
482
483 QPainterPath cablePath = getCablePathForEndpoints(startPoint, endPoint);
484
485 QPainterPathStroker mainStroker;
486 mainStroker.setWidth(cableWidth);
487 mainStroker.setCapStyle(Qt::RoundCap);
488 QPainterPath mainOutline = mainStroker.createStroke(cablePath);
489
490 this->cachedEndpointsForOutlines = qMakePair(startPoint, endPoint);
491 this->cachedCarriesDataValueForOutlines = cableCarriesData;
492 this->cachedOutline = mainOutline;
493 this->portConstantsChangedSinceLastCachedOutline = false;
494 }
495
496 return this->cachedOutline;
497}
498
505void VuoRendererCable::getYankZonePath(QPointF startPoint,
506 QPointF endPoint,
507 bool cableCarriesData,
508 bool toPortSupportsYanking,
509 QPainterPath &yankZone
510 )
511{
512 if ((qMakePair(startPoint, endPoint) != this->cachedEndpointsForYankZone) ||
513 (toPortSupportsYanking != this->cachedToPortSupportsYankingValueForYankZone) ||
514 (cableCarriesData != this->cachedCarriesDataValueForYankZone))
515 {
516 // Calculate the yank zone.
517 QPainterPath yankZone;
518 if (getBase()->getToPort() && toPortSupportsYanking)
520
521 this->cachedEndpointsForYankZone = qMakePair(startPoint, endPoint);
522 this->cachedCarriesDataValueForYankZone = cableCarriesData;
523 this->cachedToPortSupportsYankingValueForYankZone = toPortSupportsYanking;
524 this->cachedYankZonePath = yankZone;
525 }
526
527 yankZone = this->cachedYankZonePath;
528}
529
533void VuoRendererCable::getCableSpecs(bool cableCarriesData, qreal &cableWidth)
534{
535 const qreal dataCableToEventCableWidthRatio = 4;
536
537 cableWidth = (cableCarriesData? VuoRendererCable::cableWidth :
538 VuoRendererCable::cableWidth/dataCableToEventCableWidthRatio);
539}
540
545{
546 VuoCable *cable = getBase();
547 VuoNode *fromNode = cable->getFromNode();
548
549 // If the cable is an outgoing cable from a collapsed typecast, disable painting.
550 if (fromNode && fromNode->hasRenderer() && fromNode->getRenderer()->getProxyNode())
551 return true;
552
553 // If the cable is an outgoing cable from an input port attachment, disable painting.
554 if (fromNode && fromNode->hasRenderer() && dynamic_cast<VuoRendererInputAttachment *>(fromNode->getRenderer()))
555 return true;
556
557 // If the cable is a published cable and published port sidebars are not currently displayed, disable painting.
558 if (isPublishedInputCableWithoutVisiblePublishedPort() || isPublishedOutputCableWithoutVisiblePublishedPort())
559 return true;
560
561 // If the cable is an internal wireless cable, disable painting unless the composition is currently
562 // in show-hidden-cables mode.
563 if (cable->getCompiler()->getHidden() && !getRenderHiddenCables())
564 return true;
565
566 return false;
567}
568
573bool VuoRendererCable::isPublishedInputCableWithoutVisiblePublishedPort() const
574{
575 VuoPort *fromPort = getBase()->getFromPort();
576
577 // If the cable is connected to a published input port withn the published input sidebar,
578 // but the sidebar is not currently displayed, disable painting.
579 if (fromPort)
580 {
581 VuoRendererPublishedPort *publishedPort = dynamic_cast<VuoRendererPublishedPort *>(fromPort->getRenderer());
582
583 if (publishedPort)
584 {
585 bool proxyPublishedInputSidebarPortHidden = (! publishedPort->isVisible());
586 if (proxyPublishedInputSidebarPortHidden)
587 return true;
588 }
589 }
590
591 return false;
592}
593
598bool VuoRendererCable::isPublishedOutputCableWithoutVisiblePublishedPort() const
599{
600 VuoPort *toPort = getBase()->getToPort();
601
602 // If the cable is connected to a published output port within the published output sidebar,
603 // but the sidebar is not currently displayed, disable painting.
604 if (toPort)
605 {
606 VuoRendererPublishedPort *publishedPort = dynamic_cast<VuoRendererPublishedPort *>(toPort->getRenderer());
607
608 if (publishedPort)
609 {
610 bool proxyPublishedOutputSidebarPortHidden = (! publishedPort->isVisible());
611 if (proxyPublishedOutputSidebarPortHidden)
612 return true;
613 }
614 }
615
616 return false;
617}
618
623{
624 if (isPublishedInputCableWithoutVisiblePublishedPort() || isPublishedOutputCableWithoutVisiblePublishedPort())
625 return true;
626
627 return getBase()->getCompiler()->getHidden();
628}
629
635{
636 VuoRendererPort *fromPort = ((getBase()->getFromPort() && getBase()->getFromPort()->hasRenderer())?
637 getBase()->getFromPort()->getRenderer() : NULL);
638 VuoRendererPort *toPort = ((getBase()->getToPort() && getBase()->getToPort()->hasRenderer())?
639 getBase()->getToPort()->getRenderer() : NULL);
640
642
643 if (fromPort)
644 fromPort->updateGeometry();
645
646 if (toPort)
647 toPort->updateGeometry();
648
649 QGraphicsItem::CacheMode normalCacheMode = cacheMode();
650 setCacheModeForCableAndConnectedPorts(QGraphicsItem::NoCache);
651
652 getBase()->getCompiler()->setHidden(wireless);
653
655}
656
661{
662 this->setCacheMode(mode);
663
664 VuoRendererPort *fromPort = ((getBase()->getFromPort() && getBase()->getFromPort()->hasRenderer())?
665 getBase()->getFromPort()->getRenderer() : NULL);
666 VuoRendererPort *toPort = ((getBase()->getToPort() && getBase()->getToPort()->hasRenderer())?
667 getBase()->getToPort()->getRenderer() : NULL);
668
669 if (fromPort)
670 fromPort->setCacheMode(mode);
671
672 if (toPort)
673 toPort->setCacheMode(mode);
674}
675
681{
682 portConstantsChangedSinceLastCachedOutline = true;
683}
684
690{
691 return floatingEndpointLoc;
692}
693
698void VuoRendererCable::setFrom(VuoNode *fromNode, VuoPort *fromPort)
699{
700 VuoPort *origFromPort = getBase()->getFromPort();
701
702 QGraphicsItem::CacheMode normalCacheMode = cacheMode();
703
704 // Prepare affected ports and cable for geometry changes
706
707 if (origFromPort && origFromPort->hasRenderer())
708 {
709 origFromPort->getRenderer()->setCacheModeForPortAndChildren(QGraphicsItem::NoCache);
710 origFromPort->getRenderer()->updateGeometry();
711 }
712
713 if (fromPort && fromPort->hasRenderer())
714 {
715 fromPort->getRenderer()->setCacheModeForPortAndChildren(QGraphicsItem::NoCache);
716 fromPort->getRenderer()->updateGeometry();
717 }
718
719 getBase()->setFrom(fromNode, fromPort);
720
721 if (origFromPort && origFromPort->hasRenderer())
722 origFromPort->getRenderer()->setCacheModeForPortAndChildren(normalCacheMode);
723
724 if (fromPort && fromPort->hasRenderer())
725 fromPort->getRenderer()->setCacheModeForPortAndChildren(normalCacheMode);
726}
727
733{
734 VuoPort *origToPort = getBase()->getToPort();
735
736 QGraphicsItem::CacheMode normalCacheMode = cacheMode();
737
738 // Prepare affected ports and cable for geometry changes
740
741 if (origToPort && origToPort->hasRenderer())
742 {
743 origToPort->getRenderer()->setCacheModeForPortAndChildren(QGraphicsItem::NoCache);
744 origToPort->getRenderer()->updateGeometry();
745 }
746
747 if (toPort && toPort->hasRenderer())
748 {
749 toPort->getRenderer()->setCacheModeForPortAndChildren(QGraphicsItem::NoCache);
750 toPort->getRenderer()->updateGeometry();
751 }
752
753 getBase()->setTo(toNode, toPort);
754
755 // Re-lay out any drawers connected to the original and updated "To" nodes.
756 if (origToPort && origToPort->hasRenderer())
757 {
758 origToPort->getRenderer()->updateGeometry();
759
760 if (origToPort->getRenderer()->getRenderedParentNode())
762
763 origToPort->getRenderer()->setCacheModeForPortAndChildren(normalCacheMode);
764 }
765
766 if (toPort && toPort->hasRenderer())
767 {
768 toPort->getRenderer()->updateGeometry();
769
770 if (toPort->getRenderer()->getRenderedParentNode())
772
773 toPort->getRenderer()->setCacheModeForPortAndChildren(normalCacheMode);
774 }
775}
776
781{
782 floatingEndpointLoc = loc;
783}
784
790{
791 floatingEndpointAboveEventPort = aboveEventPort;
792}
793
798{
799 return floatingEndpointAboveEventPort;
800}
801
806{
807 if (scene())
808 {
809 this->prepareGeometryChange();
810
811 VuoPort *rcFromPort = this->getBase()->getFromPort();
812 VuoPort *rcToPort = this->getBase()->getToPort();
813
814 if (rcFromPort && rcFromPort->hasRenderer())
815 {
816 rcFromPort->getRenderer()->updateGeometry();
817 }
818
819 if (rcToPort && rcToPort->hasRenderer())
820 {
821 rcToPort->getRenderer()->updateGeometry();
822 }
823
824 scene()->removeItem(this);
825 }
826}
827
835
843
851
857{
858 qreal yankDistance = QLineF(scenePos, getEndPoint()).length();
859 return (yankDistance <= cableYankRadius);
860}
861
867{
868 return floatingEndpointPreviousToPort;
869}
870
876{
877 this->floatingEndpointPreviousToPort = port;
878}
879
885{
886 return this->previouslyAlwaysEventOnly;
887}
888
894{
895 this->previouslyAlwaysEventOnly = eventOnly;
896}
897
902{
903 QGraphicsItem::CacheMode normalCacheMode = cacheMode();
904 setCacheMode(QGraphicsItem::NoCache);
905
906 prepareGeometryChange();
907
908 this->isHovered = hovered;
909
910 setCacheMode(normalCacheMode);
911}
912
917{
918 _eligibilityHighlight = eligibility;
919}
920
925{
926 this->prepareGeometryChange();
927}
928
937
942{
943 return (getBase()->hasCompiler() ?
944 getBase()->getCompiler()->carriesData() :
945 false);
946}