Vuo  2.0.1
VuoEditorComposition.hh
Go to the documentation of this file.
1 
10 #pragma once
11 
14 #include "VuoRunner.hh"
15 #ifdef VUO_PRO
16 #include "VuoMovieExporter.hh"
17 #endif
18 
19 #include <dispatch/dispatch.h>
20 
22 class VuoCompilerPort;
23 class VuoEditorWindow;
24 class VuoErrorMark;
25 class VuoErrorPopover;
27 class VuoMainWindow;
28 class VuoModuleManager;
29 class VuoPortPopover;
30 class VuoProtocol;
31 
36 {
37  Q_OBJECT
38 
39 public:
44  {
45  targetTypePort,
46  targetTypeNodeHeader,
47  targetTypeAny
48  };
49 
50  static const qreal componentCollisionRange;
51 
52  explicit VuoEditorComposition(VuoMainWindow *window, VuoComposition *baseComposition);
54  void setCompiler(VuoCompiler *compiler);
55  void setModuleManager(VuoModuleManager *moduleManager);
57  void setColor(bool isDark);
58  void setInputEditorManager(VuoInputEditorManager *inputEditorManager);
60  VuoRendererNode * createNode(QString nodeClassName, string title="", double x=0, double y=0);
61  VuoNode * createBaseNode(VuoCompilerNodeClass *nodeClass, VuoNode *modelNode, string title="", double x=0, double y=0);
62  VuoNode * createNodeWithMissingImplementation(VuoNodeClass *modelNodeClass, VuoNode *modelNode, string title="", double x=0, double y=0);
64  void addNode(VuoNode *node, bool nodeShouldBeRendered=true, bool nodeShouldBeGivenUniqueIdentifier=true);
65  void removeNode(VuoRendererNode *rn, bool resetState=true);
66  void replaceNode(VuoRendererNode *oldNode, VuoNode *newNode);
67  void addCable(VuoCable *cable, bool emitHiddenCableNotification=true);
68  void removeCable(VuoRendererCable *rc, bool emitHiddenCableNotification=true);
70  void createAndConnectDictionaryAttachmentsForNode(VuoNode *node, set<VuoRendererNode *> &createdRendererNodes, set<VuoRendererCable *> &createdRendererCables);
71  QList<QGraphicsItem *> createAndConnectInputAttachments(VuoRendererNode *node, bool createButDoNotAdd=false);
72  void modifyComponents(void (^modify)(void));
74  QAction * getContextMenuDeleteSelectedAction(void);
75  QMenu * getContextMenuTints(QMenu *parent = 0);
76  void populateChangeNodeMenu(QMenu *menu, VuoRendererNode *node, int matchLimit=0);
77  set<VuoRendererCable *> getCablesInternalToSubcomposition(QList<QGraphicsItem *> subcompositionComponents);
81  VuoRendererNode * findNearbyNodeHeader(QPointF scenePos);
82  QGraphicsItem * findNearbyComponent(QPointF scenePos, targetComponentType componentType=VuoEditorComposition::targetTypeAny, bool limitPortCollisionRange=true);
85  QRectF internalItemsBoundingRect() const;
86  QRectF internalSelectedItemsBoundingRect() const;
88  set<VuoRendererNode *> getSelectedNodes();
89  set<VuoRendererComment *> getSelectedComments();
90  set<VuoRendererCable *> getSelectedCables(bool includePublishedCables);
91  void cancelCableDrag(void);
92  void revertCableDrag(void);
96  void setIgnoreApplicationStateChangeEvents(bool ignore);
98  string getIdentifierForStaticPort(VuoPort *staticPort, VuoNode *parentNode=NULL);
99  VuoPort * getPortWithStaticIdentifier(string portID);
100  void updateInternalPortConstant(string portID, string newValue, bool updateInRunningComposition);
101  void updatePublishedPortConstant(string portName, string newValue, bool updateInRunningComposition);
102  void updatePortConstant(VuoCompilerPort *port, string newValue, bool updateInRunningComposition=true);
103  void updateGenericPortTypes(void);
104  void createReplacementsToUnspecializePort(VuoPort *port, map<VuoNode *, string> &nodesToReplace, set<VuoCable *> &cablesToDelete);
105  void run(string compositionSnapshot);
106  void stop(void);
107  bool isRunning(void);
108  void updateRunningComposition(string oldCompositionSnapshot, string newCompositionSnapshot, VuoCompilerCompositionDiff *diffInfo = nullptr, set<string> dependenciesUninstalled = set<string>());
109  void updateCompositionsThatContainThisSubcomposition(string newCompositionSnapshot);
110  void syncInternalPortConstantInRunningComposition(string runningPortID);
111  void syncPublishedPortConstantInRunningComposition(string portName);
113  void updateInternalPortConstantInSubcompositionInstances(string subcompositionPath, string portIdentifier, string constant);
116  VuoRendererPublishedPort * publishInternalPort(VuoPort *port, bool forceEventOnlyPublication, string name="", VuoType *type=NULL, bool attemptMerge=false, bool *mergePerformed=NULL);
117  VuoCable * createPublishedCable(VuoPort *externalPort, VuoPort *internalPort, bool forceEventOnlyPublication);
118  void addActiveProtocol(VuoProtocol *protocol, bool useUndoStack);
119  bool removeActiveProtocol(VuoProtocol *protocol, VuoProtocol *replacementProtocol);
121  map<string, string> publishPorts(set<string> portsToPublish);
125  bool validateProtocol(VuoEditorWindow *window, bool isExportingMovie);
126  void addPublishedPort(VuoPublishedPort *publishedPort, bool isPublishedInput, bool shouldUpdateUi=true);
127  int removePublishedPort(VuoPublishedPort *publishedPort, bool isPublishedInput, bool shouldUpdateUi=true);
128  void setPublishedPortName(VuoRendererPublishedPort *publishedPort, string name);
129  void leftMousePressEventAtNearbyItem(QGraphicsItem *nearbyItem, QGraphicsSceneMouseEvent *event);
130  static VuoNode * getUnderlyingParentNodeForPort(VuoPort *runningPort, VuoEditorComposition *composition);
131  QGraphicsItem * findNearbyPort(QPointF scenePos, bool limitPortCollisionRange=true);
132  VuoRendererColors::HighlightType getEligibilityHighlightingForPort(VuoRendererPort *portToHighlight, VuoRendererPort *fixedPort, bool eventOnlyConnection);
133  vector<string> findBridgingSolutions(VuoRendererPort *fromPort, VuoRendererPort *toPort, bool toPortIsDragDestination);
134  bool selectBridgingSolution(VuoRendererPort *fromPort, VuoRendererPort *toPort, bool toPortIsDragDestination, VuoRendererPort **portToSpecialize, string &specializedTypeName, string &typecastToInsert);
135  QList<QAction *> getCompatibleTypesForMenu(VuoRendererPort *genericPort, set<string> compatibleTypesInIsolation, set<string> compatibleTypesInContext, bool limitToNodeSet, string nodeSetName="", QMenu *menu=NULL);
136  void addTypeActionsToMenu(QList<QAction *> actionList, QMenu *menu);
137  vector<string> getAllSpecializedTypeOptions(bool lists);
138  void deleteSelectedNodes(string commandDescription="");
139  void clear();
140 
141  // Popovers
142  VuoPortPopover * getActivePopoverForPort(string portID);
144  void updatePortPopovers(VuoRendererNode *node=NULL);
145  void updateDataInPortPopoverFromRunningTopLevelComposition(VuoEditorComposition *popoverComposition, string popoverCompositionIdentifier, string portID);
146  void updateDataInPortPopover(string portID);
147  void movePopoversBy(int dx, int dy);
148  void disableNondetachedPortPopovers(VuoRendererNode *node=NULL, bool recordWhichPopoversClosed=false);
150  void disableErrorPopovers();
151  void disablePopovers();
152  void emitCompositionOnTop(bool top);
154 
155  void receivedTelemetryInputPortUpdated(string compositionIdentifier, string portIdentifier, bool receivedEvent, bool receivedData, string dataSummary);
156  void receivedTelemetryOutputPortUpdated(string compositionIdentifier, string portIdentifier, bool sentEvent, bool sentData, string dataSummary);
157  void receivedTelemetryEventDropped(string compositionIdentifier, string portIdentifier);
158  void receivedTelemetryNodeExecutionStarted(string compositionIdentifier, string nodeIdentifier);
159  void receivedTelemetryNodeExecutionFinished(string compositionIdentifier, string nodeIdentifier);
160  void lostContactWithComposition(void);
161 
162  bool getShowEventsMode();
163  void setShowEventsMode(bool showEventsMode);
166  void setTriggerPortToRefire(VuoPort *port);
168  void refireTriggerPortEvent();
169 
170  string takeSnapshot(void);
171  string generateCompositionHeader();
172 
173  static string getDefaultNameForPath(const string &compositionPath);
174  QString getFormattedName();
175  static QString formatCompositionFileNameForDisplay(QString unformattedCompositionFileName);
176  static QString formatNodeSetNameForDisplay(QString nodeSetName);
177  QString formatTypeNameForDisplay(VuoType *type);
179 
180  void beginDisplayingActivity(bool includePorts=true);
181  void stopDisplayingActivity();
182 
183 #ifdef VUO_PRO
184 #include "pro/VuoEditorComposition_Pro.hh"
185 #endif
186 
187 public slots:
188  void updateFeedbackErrors(VuoRendererPort *targetPort=NULL);
189  void renameSelectedNodes();
191  void deleteSelectedCompositionComponents(string commandDescription);
193  void tintSelectedItems(int tintColor);
195  void selectAllComments();
197  void moveSelectedItemsBy(qreal dx, qreal dy);
200 
201  // Popovers
202  void setPopoverEventsEnabled(bool enable);
203  void disablePopoverForPort(string);
204 
205 signals:
206  void leftMouseButtonReleased(void);
208  void itemsMoved(set<VuoRendererNode *> nodes, set<VuoRendererComment *> comments, qreal dx, qreal dy, bool movedByDragging);
209  void commentResized(VuoRendererComment *comment, qreal dx, qreal dy);
211  void componentsAdded(QList<QGraphicsItem *> addedComponents, VuoEditorComposition *target);
212  void componentsRemoved(QList<QGraphicsItem *> removedComponents, string commandDescription="Remove");
213  void cablesHidden(set<VuoRendererCable *> cables);
215  void cablesUnhidden(set<VuoRendererCable *> cables);
216  void changeInHiddenCables();
217  void portPublicationRequested(VuoPort *port, bool forceEventOnlyPublication);
218  void portPublicationRequested(VuoPort *internalPort, VuoPublishedPort *externalPort, bool forceEventOnlyPublication, VuoPort *portToSpecialize, string specializedTypeName, string typecastToInsert, bool useUndoStackMacro);
219  void portUnpublicationRequested(VuoPort *port);
220  void publishedPortNameEditorRequested(VuoRendererPublishedPort *port, bool useUndoStack);
221  void publishedPortModified();
222  void protocolPortChangesRequested(map<VuoPublishedPort *, string> publishedPortsToRename, set<VuoPublishedPort *> publishedPortsToRemove, vector<VuoPublishedPort *> publishedPortsToAdd, bool beginUndoStackMacro, bool endUndoStackMacro);
223  void activeProtocolChanged();
224  void triggerThrottlingUpdated(VuoPort *port, enum VuoPortClass::EventThrottling eventThrottling);
225  void inputPortCountAdjustmentRequested(VuoRendererNode *node, int inputPortCountDelta, bool requestedByDragging);
228  void nodeSwapRequested(VuoRendererNode *node, string newNodeClassName);
229  void specializePort(VuoRendererPort *port, string specializedTypeName);
230  void respecializePort(VuoRendererPort *port, string specializedTypeName);
231  void unspecializePort(VuoRendererPort *port);
232  void highlightPublishedSidebarDropLocationsRequested(VuoRendererPort *port, bool eventOnlyConnection);
234  void connectionCompletedByDragging(VuoRendererCable *cableInProgress, VuoRendererPort *targetPort, pair<VuoRendererCable *, VuoRendererCable *> cableArgs, VuoRendererNode *typecastNodeToDelete, pair<string, string> typeArgs, pair<VuoRendererPort *, VuoRendererPort *> portArgs);
237  void portConstantChangeRequested(VuoRendererPort *port, string value);
240  void subcompositionInsertionRequested(QPointF scenePos);
241  void commentInsertionRequested(QPointF scenePos);
243  void compositionStoppedItself();
244  void buildStarted();
245  void buildFinished(QString error);
246  void stopFinished();
247  void nodePopoverRequestedForClass(VuoNodeClass *nodeClass);
248  void popoverDetached();
249  void compositionOnTop(bool);
250  void applicationActive(bool);
251  void refirePortChanged();
252  void cableDragInitiated();
253  void cableDragEnded();
254  void undoStackMacroBeginRequested(QString commandName);
256  void refactorRequested();
257 
258 protected:
259  void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
260  void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
261  void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
262  void dropEvent(QGraphicsSceneDragDropEvent *event);
263 
264  void mouseDoubleClickEvent (QGraphicsSceneMouseEvent *event);
265  void mousePressEvent(QGraphicsSceneMouseEvent *event);
266  void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
267  void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
268  void keyPressEvent(QKeyEvent *event);
269  void keyReleaseEvent(QKeyEvent *event);
270  void contextMenuEvent(QGraphicsSceneContextMenuEvent* event);
271 
272 private:
273  void registerNodeID(VuoNode *node);
274  void setPortConstantToValue(VuoRendererPort *port, string value);
275  void setCustomConstantsForNewNode(VuoRendererNode *newNode);
276  void openSelectedEditableNodes();
277  string getNonProtocolVariantForPortName(string portName);
278  set<string> getRespecializationOptionsForPortInNetwork(VuoRendererPort *port);
279  bool canConnectDirectlyWithRespecializationNondestructively(VuoRendererPort *fromPort,
280  VuoRendererPort *toPort,
281  bool eventOnlyConnection,
282  bool forwardConnection);
283  bool canConnectDirectlyWithRespecializationNondestructively(VuoRendererPort *fromPort,
284  VuoRendererPort *toPort,
285  bool eventOnlyConnection,
286  bool forwardConnection,
287  VuoRendererPort **portToRespecialize,
288  string &respecializedTypeName);
289  bool canConnectDirectlyWithRespecialization(VuoRendererPort *fromPort,
290  VuoRendererPort *toPort,
291  bool eventOnlyConnection,
292  bool forwardConnection,
293  VuoRendererPort **portToRespecialize,
294  string &respecializedTypeName);
295  bool canSwapWithoutBreakingCables(VuoRendererNode *origNode, VuoNodeClass *newNodeClass);
296  bool portCanBeUnspecializedNondestructively(VuoPort *port);
297  bool portsPassSanityCheckToBridge(VuoRendererPort *fromPort, VuoRendererPort *toPort);
298  bool portsPassSanityCheckToTypeconvert(VuoRendererPort *fromPort, VuoRendererPort *toPort, VuoType *candidateFromType=NULL, VuoType *candidateToType=NULL);
299 
300  void fireTriggerPortEvent(VuoPort *port);
301  QList<QAction *> promoteSingletonsFromSubmenus(QList<QAction *> actionList);
302  static bool nodeSetMenuActionLessThan(QAction *action1, QAction *action2);
303  static bool itemHigherOnCanvas(QGraphicsItem *item1, QGraphicsItem *item2);
304  static double calculateNodeSimilarity(VuoNodeClass *node1, VuoNodeClass *node2);
305 
306  // Popovers
307  void enableInactivePopoverForPort(VuoRendererPort *rp);
308  void disablePopoverForPortThreadSafe(string portID);
309  void disablePortPopovers(VuoRendererNode *node=NULL);
310  void moveDetachedPortPopoversBy(int dx, int dy);
311  void moveErrorPopoversBy(int dx, int dy);
312  VuoErrorMark *errorMark;
313  set<VuoErrorPopover *> errorPopovers;
314  bool errorMarkingUpdatesEnabled;
315 
316 private slots:
317  void moveNodesBy(set<VuoRendererNode *> nodes, qreal dx, qreal dy, bool movedByDragging);
318  void moveCommentsBy(set<VuoRendererComment *> comments, qreal dx, qreal dy, bool movedByDragging);
319  void resizeCommentBy(VuoRendererComment *comment, qreal dx, qreal dy);
320  void editSelectedComments();
321  void insertNode();
322  void insertComment();
323  void insertSubcomposition();
324  void deleteConnectedCables();
325  void hideConnectedCables();
326  void unhideConnectedCables();
327  void fireTriggerPortEvent();
328  void setPortConstant();
329  void setTriggerThrottling(int eventThrottling);
330  void specializeGenericPortType();
331  void unspecializePortType();
332  void addInputPort();
333  void removeInputPort();
334  void swapNode();
335  void setDisableDragStickiness(bool disable);
336  void updatePortAnimation(qreal value);
337  void endPortAnimation(void);
338  void expandChangeNodeMenu();
339 
340  // Popovers
341  void updatePopoversForActiveWindowChange(QWidget *old, QWidget *now);
342  void updatePopoversForApplicationStateChange(bool active);
343  void enablePopoverForNode(VuoRendererNode *rn);
344  void repositionPopover();
345 
346 private:
347  static const qreal nodeMoveRate;
348  static const qreal nodeMoveRateMultiplier;
349  static const qreal showEventsModeUpdateInterval;
350  static const int initialChangeNodeSuggestionCount;
351  VuoMainWindow *window;
352  VuoCompiler *compiler;
353  VuoModuleManager *moduleManager;
354  VuoInputEditorManager *inputEditorManager;
355  VuoProtocol *activeProtocol;
356  VuoRunner *runner;
357  VuoCompilerComposition *runningComposition;
358  VuoCompilerDriver *runningCompositionActiveDriver;
359  dispatch_queue_t runCompositionQueue;
360  dispatch_queue_t activePortPopoversQueue;
361  bool stopRequested;
362  string linkedCompositionPath;
363  VuoRunningCompositionLibraries *runningCompositionLibraries;
364  QAction *contextMenuDeleteSelected;
365  QAction *contextMenuHideSelectedCables;
366  QAction *contextMenuRenameSelected;
367  QAction *contextMenuRefactorSelected;
368  QAction *contextMenuPublishPort;
369  QAction *contextMenuDeleteCables;
370  QAction *contextMenuHideCables;
371  QAction *contextMenuUnhideCables;
372  QAction *contextMenuFireEvent;
373  QAction *contextMenuAddInputPort;
374  QAction *contextMenuRemoveInputPort;
375  QAction *contextMenuSetPortConstant;
376  QAction *contextMenuEditSelectedComments;
377  QMenu *contextMenuChangeNode;
378  QList<QAction *> contextMenuThrottlingActions;
379  QList<QAction *> contextMenuTintActions;
380  bool duplicateOnNextMouseMove;
381  bool duplicationDragInProgress;
382  bool duplicationCancelled;
383  QPointF cursorPosBeforeDuplicationDragMove;
384  VuoCable *cableInProgress;
385  bool cableInProgressWasNew;
386  bool cableInProgressShouldBeWireless;
387  VuoRendererPort *portWithDragInitiated;
388  VuoRendererCable *cableWithYankInitiated;
389  bool menuSelectionInProgress;
390  QGraphicsItem *previousNearbyItem;
391  map<string, VuoNode *> nodeWithGraphvizIdentifier;
392  map<string, VuoPort *> portWithStaticIdentifier;
393  map<VuoPort *, string> staticIdentifierForPort;
394  bool dragStickinessDisabled;
395  bool ignoreApplicationStateChangeEvents;
396  bool showEventsMode;
397  QTimer *refreshComponentAlphaLevelTimer;
398  set<QGraphicsItemAnimation *> preparedAnimations;
399  map<QTimeLine *, QGraphicsItemAnimation *> animationForTimeline;
400  string triggerPortToRefire;
401 
402  // Popovers
403  bool popoverEventsEnabled;
404  map<string, VuoPortPopover *> activePortPopovers;
405  set<string> portsWithPopoversClosedAtLastEvent;
406 
407  bool isPortCurrentlyRevertible(VuoRendererPort *port);
408  void addActionToMenuAndMapper(QMenu *menu, QSignalMapper *mapper, QString name, int index);
409  void mousePressEventNonLeftButton(QGraphicsSceneMouseEvent *event);
410  void correctForCancelledDuplication(QGraphicsSceneMouseEvent *event);
411  void initiateCableDrag(VuoRendererPort *currentPort, VuoRendererCable *cableYankedDirectly, QGraphicsSceneMouseEvent *event);
412  void concludeCableDrag(QGraphicsSceneMouseEvent *event);
413  void concludePublishedCableDrag(QGraphicsSceneMouseEvent *event);
414  void updateHoverHighlighting(QPointF scenePos, bool disablePortHoverHighlighting=false);
415  void highlightEligibleEndpointsForCable(VuoCable *cable);
416  void highlightInternalPortsConnectableToPort(VuoRendererPort *port, VuoRendererCable *cable);
417  void updateEligibilityHighlightingForPort(VuoRendererPort *portToHighlight, VuoRendererPort *fixedPort, bool eventOnlyConnection);
418  void updateEligibilityHighlightingForNode(VuoRendererNode *node);
419  bool selectBridgingSolutionFromOptions(vector<string> suitableTypecasts, map<string, VuoRendererPort *> portToSpecializeForTypecast, map<string, string> specializedTypeNameForTypecast, string &selectedTypecast);
420  vector<string> findBridgingSolutions(VuoRendererPort *fromPort, VuoRendererPort *toPort, bool toPortIsDragDestination, map<string, VuoRendererPort *> &portToSpecializeForTypecast, map<string, string> &specializedTypeNameForTypecast);
421  bool promptForBridgingSelectionFromOptions(vector<string> suitableTypecasts, map<string, VuoRendererPort *> portToSpecializeForTypecast, map<string, string> specializedTypeNameForTypecast, string &selectedTypecast);
422  QString getDisplayTextForSpecializationOption(VuoRendererPort *portToSpecialize, string specializedTypeName);
423  bool hasFeedbackErrors(void);
424  void buildComposition(string compositionSnapshot, const set<string> &dependenciesUninstalled = set<string>());
425  bool isRunningThreadUnsafe(void);
426  string getIdentifierForRunningPort(VuoPort *port);
427  void moveItemsBy(set<VuoRendererNode *> nodes, set<VuoRendererComment *> comments, qreal dx, qreal dy, bool movedByDragging);
428  void setPopoversHideOnDeactivate(bool shouldHide);
429 
430  QGraphicsItemAnimation * setUpAnimationForPort(QGraphicsItemAnimation *animation, VuoRendererPort *port);
431  void animatePort(VuoRendererPort *port);
432  QGraphicsItemAnimation * getAvailableAnimationForPort(VuoRendererPort *port);
433 
434  friend class TestVuoEditor;
435 };