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