Vuo  2.1.0
VuoRendererInputListDrawer.cc
Go to the documentation of this file.
1 
11 #include "VuoRendererPort.hh"
12 #include "VuoRendererSignaler.hh"
13 
18  : VuoRendererInputDrawer(baseNode, signaler)
19 {
20  dragInProgress = false;
21 
22  this->dragHandleIsHovered = false;
23  mousePositionAtLastPortCountAdjustment = QPointF(NAN,NAN);
24 
25  updateCachedBoundingRect();
26 }
27 
33 void VuoRendererInputListDrawer::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
34 {
35  VuoNode *hostNode = getUnderlyingHostNode();
36  if (hostNode && hostNode->hasRenderer() && hostNode->getRenderer()->isSelected() && !isSelected())
37  this->setSelected(true);
38 
39  drawBoundingRect(painter);
40 
41  VuoRendererColors::SelectionType selectionType = (isSelected()? VuoRendererColors::directSelection : VuoRendererColors::noSelection);
42  qint64 timeOfLastActivity = (getRenderActivity()? timeLastExecutionEnded : VuoRendererItem::notTrackingActivity);
43  VuoRendererColors *drawerColors = new VuoRendererColors(getBase()->getTintColor(),
44  selectionType,
45  false,
46  _eligibilityHighlight,
47  timeOfLastActivity);
48 
49  VuoRendererColors *dragHandleColors = new VuoRendererColors(getBase()->getTintColor(),
50  selectionType,
51  dragHandleIsHovered,
52  _eligibilityHighlight,
53  timeOfLastActivity);
54 
55  // Drawer frame
56  QPainterPath drawerFrame = getDrawerPath(true);
57  painter->fillPath(drawerFrame, drawerColors->nodeFill());
58 
59  // Drag handle
60  if (dragHandleIsHovered)
61  {
62  painter->setClipPath(drawerFrame);
63  painter->fillRect(getDragHandleRect(), dragHandleColors->nodeFill());
64  painter->setClipping(false);
65  }
66  painter->fillPath(getMakeListDragHandlePath(), dragHandleColors->nodeFrame());
67 
68  // Child input ports
69  layoutPorts();
70 
71  delete drawerColors;
72  delete dragHandleColors;
73 }
74 
78 QPainterPath VuoRendererInputListDrawer::getMakeListNodePath() const
79 {
80  QPainterPath p;
81  p.addPath(getDrawerPath(true));
82  return p;
83 }
84 
88 QPainterPath VuoRendererInputListDrawer::getMakeListDragHandlePath() const
89 {
90  QPainterPath p;
91  QRectF r = getDragHandleRect();
92  QRectF r2(floor(r.center().x()) - 3, r.top()+2, 7, 1);
93  p.addRoundedRect(r2, 1,1);
94  return p;
95 }
96 
101 {
102  return cachedBoundingRect;
103 }
104 
105 void VuoRendererInputListDrawer::updateCachedBoundingRect()
106 {
107  cachedBoundingRect = getMakeListNodePath().boundingRect();
108  cachedBoundingRect = cachedBoundingRect.united(getExtendedDragHandleRect());
109 
110  // Antialiasing bleed
111  cachedBoundingRect.adjust(-1,-1,1,1);
112 
113  cachedBoundingRect = cachedBoundingRect.toAlignedRect();
114 }
115 
120 {
122  updateCachedBoundingRect();
123 }
124 
130 {
131  QPainterPath p;
132  p.addPath(getDrawerPath(true));
133  p.addRect(getExtendedDragHandleRect());
134  p.setFillRule(Qt::WindingFill);
135 
136  return p;
137 }
138 
142 QRectF VuoRendererInputListDrawer::getDragHandleRect() const
143 {
144  const qreal handleVerticalOffset = 6;
145  const qreal handleHeight = 6;
146  qreal drawerBottomExtensionWidth = getMaxDrawerLabelWidth();
147 
148  return QRectF(VuoRendererPort::portRadius - 1,
149  drawerBottomExtensionHeight + handleVerticalOffset,
150  qRound(drawerBottomExtensionWidth) - VuoRendererPort::portRadius + 1,
151  handleHeight);
152 }
153 
158 {
159  return getDragHandleRect().adjusted(-3,-5,3,5);
160 }
161 
166 {
167  bool cursorAboveDragHandle = (getExtendedDragHandleRect().translated(this->scenePos()).contains(scenePos));
168  prepareGeometryChange();
169  dragHandleIsHovered = cursorAboveDragHandle;
170 }
171 
176 {
177  bool cursorAboveDragHandle = (getExtendedDragHandleRect().translated(this->scenePos()).contains(scenePos));
178  prepareGeometryChange();
179  dragHandleIsHovered = cursorAboveDragHandle;
180 }
181 
186 {
187  prepareGeometryChange();
188  dragHandleIsHovered = false;
189 }
190 
194 void VuoRendererInputListDrawer::mousePressEvent(QGraphicsSceneMouseEvent *event)
195 {
196  bool leftButtonPressed = (event->button() == Qt::LeftButton);
197  bool pressedOnDragHandle = (getExtendedDragHandleRect().contains(event->pos()));
198  if (leftButtonPressed && pressedOnDragHandle)
199  {
200  setDragInProgress(true);
201  mousePositionAtLastPortCountAdjustment = event->pos();
202  }
203 
204  else
205  QGraphicsItem::mousePressEvent(event);
206 }
207 
211 void VuoRendererInputListDrawer::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
212 {
213  bool leftMouseButtonPressed = (event->buttons() & Qt::LeftButton);
214 
215  if (leftMouseButtonPressed && dragInProgress)
216  {
217  if (isnan(mousePositionAtLastPortCountAdjustment.y()))
218  mousePositionAtLastPortCountAdjustment = event->pos();
219 
220  QPointF delta = event->pos() - mousePositionAtLastPortCountAdjustment;
221  double steps = delta.y() / VuoRendererPort::portSpacing;
222 
223  // If the user has dragged the drag handle down, add 1 or more input ports.
224  if (steps >= 1.)
225  triggerPortCountAdjustment(round(steps), event);
226 
227  // If the user has dragged the drag handle up, remove 1 or more input ports.
228  else if (steps <= -1. && drawerPorts.size() >= 1)
229  triggerPortCountAdjustment(fmax(-(int)drawerPorts.size(), round(steps)), event);
230  }
231 
232  else
233  QGraphicsItem::mouseMoveEvent(event);
234 }
235 
239 void VuoRendererInputListDrawer::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
240 {
241  if (event->button() == Qt::LeftButton)
242  {
243  if (scene() && (scene()->mouseGrabberItem() == this))
244  ungrabMouse();
245 
246  setDragInProgress(false);
247 
249  }
250 
251  else
252  QGraphicsItem::mouseReleaseEvent(event);
253 }
254 
259 {
260  updateGeometry();
261  this->dragInProgress = inProgress;
262 
263  if (signaler)
265 
266  mousePositionAtLastPortCountAdjustment = QPointF(NAN,NAN);
267 }
268 
273 void VuoRendererInputListDrawer::triggerPortCountAdjustment(int portCountDelta, QGraphicsSceneMouseEvent *event)
274 {
275  mousePositionAtLastPortCountAdjustment = event->pos();
276  dragHandleIsHovered = false;
277 
278  if (signaler)
279  signaler->signalInputPortCountAdjustmentRequested(this, portCountDelta, true);
280 }
281 
286 {
287  return getDrawerPath(true).boundingRect();
288 }