Vuo  2.1.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;
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  void modifyComponents(void (^modify)(void));
76  QAction * getContextMenuDeleteSelectedAction(void);
77  QMenu * getContextMenuTints(QMenu *parent = 0);
78  void populateChangeNodeMenu(QMenu *menu, VuoRendererNode *node, int matchLimit=0);
79  set<VuoRendererCable *> getCablesInternalToSubcomposition(QList<QGraphicsItem *> subcompositionComponents);
83  VuoRendererNode * findNearbyNodeHeader(QPointF scenePos);
84  QGraphicsItem * findNearbyComponent(QPointF scenePos, targetComponentType componentType=VuoEditorComposition::targetTypeAny, bool limitPortCollisionRange=true);
87  QRectF internalItemsBoundingRect() const;
88  QRectF internalSelectedItemsBoundingRect() const;
90  set<VuoRendererNode *> getSelectedNodes();
91  set<VuoRendererComment *> getSelectedComments();
92  set<VuoRendererCable *> getSelectedCables(bool includePublishedCables);
93  void cancelCableDrag(void);
94  void revertCableDrag(void);
98  void setIgnoreApplicationStateChangeEvents(bool ignore);
100  static string getIdentifierForStaticPort(VuoPort *staticPort, VuoNode *parentNode=NULL);
101  VuoPort * getPortWithStaticIdentifier(string portID);
102  void updateInternalPortConstant(string portID, string newValue, bool updateInRunningComposition);
103  void updatePublishedPortConstant(string portName, string newValue, bool updateInRunningComposition);
104  void updatePortConstant(VuoCompilerPort *port, string newValue, bool updateInRunningComposition=true);
105  void updateGenericPortTypes(void);
106  void createReplacementsToUnspecializePort(VuoPort *port, bool shouldOutputNodesToReplace, map<VuoNode *, string> &nodesToReplace, set<VuoCable *> &cablesToDelete);
107  void run(string compositionSnapshot);
108  void stop(void);
109  bool isRunning(void);
110  void updateRunningComposition(string oldCompositionSnapshot, string newCompositionSnapshot, VuoCompilerCompositionDiff *diffInfo = nullptr, set<string> dependenciesUninstalled = set<string>());
111  void updateCompositionsThatContainThisSubcomposition(string newCompositionSnapshot);
112  void syncInternalPortConstantInRunningComposition(string runningPortID);
113  void syncPublishedPortConstantInRunningComposition(string portName);
115  void updateInternalPortConstantInSubcompositionInstances(string subcompositionPath, string portIdentifier, string constant);
117  VuoRendererPublishedPort * publishInternalPort(VuoPort *port, bool forceEventOnlyPublication, string name="", VuoType *type=NULL, bool attemptMerge=false, bool *mergePerformed=NULL);
118  VuoCable * createPublishedCable(VuoPort *externalPort, VuoPort *internalPort, bool forceEventOnlyPublication);
119  void addActiveProtocol(VuoProtocol *protocol, bool useUndoStack);
120  bool removeActiveProtocol(VuoProtocol *protocol, VuoProtocol *replacementProtocol);
122  map<string, string> publishPorts(set<string> portsToPublish);
126  bool validateProtocol(VuoEditorWindow *window, bool isExportingMovie);
127  void addPublishedPort(VuoPublishedPort *publishedPort, bool isPublishedInput, bool shouldUpdateUi=true);
128  int removePublishedPort(VuoPublishedPort *publishedPort, bool isPublishedInput, bool shouldUpdateUi=true);
129  void setPublishedPortName(VuoRendererPublishedPort *publishedPort, string name);
130  void leftMousePressEventAtNearbyItem(QGraphicsItem *nearbyItem, QGraphicsSceneMouseEvent *event);
131  static VuoNode * getUnderlyingParentNodeForPort(VuoPort *runningPort, VuoEditorComposition *composition);
132  QGraphicsItem * findNearbyPort(QPointF scenePos, bool limitPortCollisionRange=true);
133  VuoRendererColors::HighlightType getEligibilityHighlightingForPort(VuoRendererPort *portToHighlight, VuoRendererPort *fixedPort, bool eventOnlyConnection, map<string, VuoCompilerType *> &types);
134  vector<string> findBridgingSolutions(VuoRendererPort *fromPort, VuoRendererPort *toPort, bool toPortIsDragDestination, map<string, VuoCompilerType *> &types);
135  bool selectBridgingSolution(VuoRendererPort *fromPort, VuoRendererPort *toPort, bool toPortIsDragDestination, VuoRendererPort **portToSpecialize, string &specializedTypeName, string &typecastToInsert);
136  QList<QAction *> getCompatibleTypesForMenu(VuoRendererPort *genericPort, set<string> compatibleTypesInIsolation, set<string> compatibleTypesInContext, bool limitToNodeSet, string nodeSetName="", QMenu *menu=NULL);
137  void addTypeActionsToMenu(QList<QAction *> actionList, QMenu *menu);
138  vector<string> getAllSpecializedTypeOptions(bool lists);
139  void deleteSelectedNodes(string commandDescription="");
140  void clear();
141 
142  // Popovers
143  VuoPortPopover * getActivePopoverForPort(string portID);
145  void updatePortPopovers(VuoRendererNode *node=NULL);
146  void updateDataInPortPopoverFromRunningTopLevelComposition(VuoEditorComposition *popoverComposition, string popoverCompositionIdentifier, string portID);
147  void updateDataInPortPopover(string portID);
148  void movePopoversBy(int dx, int dy);
149  void disableNondetachedPortPopovers(VuoRendererNode *node=NULL, bool recordWhichPopoversClosed=false);
151  void disableErrorPopovers();
152  void disablePopovers();
153  void emitCompositionOnTop(bool top);
155 
156  void receivedTelemetryInputPortUpdated(string compositionIdentifier, string portIdentifier, bool receivedEvent, bool receivedData, string dataSummary);
157  void receivedTelemetryOutputPortUpdated(string compositionIdentifier, string portIdentifier, bool sentEvent, bool sentData, string dataSummary);
158  void receivedTelemetryEventDropped(string compositionIdentifier, string portIdentifier);
159  void receivedTelemetryNodeExecutionStarted(string compositionIdentifier, string nodeIdentifier);
160  void receivedTelemetryNodeExecutionFinished(string compositionIdentifier, string nodeIdentifier);
161  void lostContactWithComposition(void);
162 
163  bool getShowEventsMode();
164  void setShowEventsMode(bool showEventsMode);
167  void setTriggerPortToRefire(VuoPort *port);
169  void refireTriggerPortEvent();
170 
171  string takeSnapshot(void);
172  string generateCompositionHeader();
173 
174  static string getDefaultNameForPath(const string &compositionPath);
175  QString getFormattedName();
176  static QString formatCompositionFileNameForDisplay(QString unformattedCompositionFileName);
177  static QString formatNodeSetNameForDisplay(QString nodeSetName);
178  QString formatTypeNameForDisplay(VuoType *type);
180 
181  void beginDisplayingActivity(bool includePorts=true);
182  void stopDisplayingActivity();
183 
184 #ifdef VUO_PRO
185 #include "pro/VuoEditorComposition_Pro.hh"
186 #endif
187 
188 public slots:
189  void updateFeedbackErrors(VuoRendererPort *targetPort=NULL);
190  void renameSelectedNodes();
192  void deleteSelectedCompositionComponents(string commandDescription);
194  void tintSelectedItems(int tintColor);
196  void selectAllComments();
198  void moveSelectedItemsBy(qreal dx, qreal dy);
201 
202  // Popovers
203  void setPopoverEventsEnabled(bool enable);
204  void disablePopoverForPort(string);
205 
206 signals:
209  void itemsMoved(set<VuoRendererNode *> nodes, set<VuoRendererComment *> comments, qreal dx, qreal dy, bool movedByDragging);
210  void commentResized(VuoRendererComment *comment, qreal dx, qreal dy);
212  void componentsAdded(QList<QGraphicsItem *> addedComponents, VuoEditorComposition *target);
213  void componentsRemoved(QList<QGraphicsItem *> removedComponents, string commandDescription="Remove");
214  void cablesHidden(set<VuoRendererCable *> cables);
216  void cablesUnhidden(set<VuoRendererCable *> cables);
218  void portPublicationRequested(VuoPort *port, bool forceEventOnlyPublication);
219  void portPublicationRequested(VuoPort *internalPort, VuoPublishedPort *externalPort, bool forceEventOnlyPublication, VuoPort *portToSpecialize, string specializedTypeName, string typecastToInsert, bool useUndoStackMacro);
223  void protocolPortChangesRequested(map<VuoPublishedPort *, string> publishedPortsToRename, set<VuoPublishedPort *> publishedPortsToRemove, vector<VuoPublishedPort *> publishedPortsToAdd, bool beginUndoStackMacro, bool endUndoStackMacro);
226  void inputPortCountAdjustmentRequested(VuoRendererNode *node, int inputPortCountDelta, bool requestedByDragging);
229  void nodeSwapRequested(VuoRendererNode *node, string newNodeClassName);
230  void specializePort(VuoRendererPort *port, string specializedTypeName);
231  void respecializePort(VuoRendererPort *port, string specializedTypeName);
233  void highlightPublishedSidebarDropLocationsRequested(VuoRendererPort *port, bool eventOnlyConnection);
235  void connectionCompletedByDragging(VuoRendererCable *cableInProgress, VuoRendererPort *targetPort, pair<VuoRendererCable *, VuoRendererCable *> cableArgs, VuoRendererNode *typecastNodeToDelete, pair<string, string> typeArgs, pair<VuoRendererPort *, VuoRendererPort *> portArgs);
238  void portConstantChangeRequested(VuoRendererPort *port, string value);
241  void subcompositionInsertionRequested(QPointF scenePos);
242  void commentInsertionRequested(QPointF scenePos);
245  void buildStarted();
246  void buildFinished(QString error);
247  void stopFinished();
250  void compositionOnTop(bool);
251  void applicationActive(bool);
255  void undoStackMacroBeginRequested(QString commandName);
258 
259 protected:
260  void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
261  void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
262  void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
263  void dropEvent(QGraphicsSceneDragDropEvent *event);
264 
265  void mouseDoubleClickEvent (QGraphicsSceneMouseEvent *event);
266  void mousePressEvent(QGraphicsSceneMouseEvent *event);
267  void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
268  void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
269  void keyPressEvent(QKeyEvent *event);
270  void keyReleaseEvent(QKeyEvent *event);
271  void contextMenuEvent(QGraphicsSceneContextMenuEvent* event);
272 
273 private:
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  std::shared_ptr<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  VuoNodeAndPortIdentifierCache *identifierCache;
392  bool dragStickinessDisabled;
393  bool ignoreApplicationStateChangeEvents;
394  bool showEventsMode;
395  QTimer *refreshComponentAlphaLevelTimer;
396  set<QGraphicsItemAnimation *> preparedAnimations;
397  map<QTimeLine *, QGraphicsItemAnimation *> animationForTimeline;
398  string triggerPortToRefire;
399 
400  // Popovers
401  bool popoverEventsEnabled;
402  map<string, VuoPortPopover *> activePortPopovers;
403  set<string> portsWithPopoversClosedAtLastEvent;
404 
405  bool isPortCurrentlyRevertible(VuoRendererPort *port);
406  void addActionToMenuAndMapper(QMenu *menu, QSignalMapper *mapper, QString name, int index);
407  void mousePressEventNonLeftButton(QGraphicsSceneMouseEvent *event);
408  void correctForCancelledDuplication(QGraphicsSceneMouseEvent *event);
409  void initiateCableDrag(VuoRendererPort *currentPort, VuoRendererCable *cableYankedDirectly, QGraphicsSceneMouseEvent *event);
410  void concludeCableDrag(QGraphicsSceneMouseEvent *event);
411  void concludePublishedCableDrag(QGraphicsSceneMouseEvent *event);
412  void updateHoverHighlighting(QPointF scenePos, bool disablePortHoverHighlighting=false);
413  void highlightEligibleEndpointsForCable(VuoCable *cable);
414  void highlightInternalPortsConnectableToPort(VuoRendererPort *port, VuoRendererCable *cable);
415  void updateEligibilityHighlightingForPort(VuoRendererPort *portToHighlight, VuoRendererPort *fixedPort, bool eventOnlyConnection, map<string, VuoCompilerType *> &types);
416  void updateEligibilityHighlightingForNode(VuoRendererNode *node);
417  bool selectBridgingSolutionFromOptions(vector<string> suitableTypecasts, map<string, VuoRendererPort *> portToSpecializeForTypecast, map<string, string> specializedTypeNameForTypecast, string &selectedTypecast);
418  vector<string> findBridgingSolutions(VuoRendererPort *fromPort, VuoRendererPort *toPort, bool toPortIsDragDestination, map<string, VuoRendererPort *> &portToSpecializeForTypecast, map<string, string> &specializedTypeNameForTypecast, map<string, VuoCompilerType *> &types);
419  bool promptForBridgingSelectionFromOptions(vector<string> suitableTypecasts, map<string, VuoRendererPort *> portToSpecializeForTypecast, map<string, string> specializedTypeNameForTypecast, string &selectedTypecast);
420  QString getDisplayTextForSpecializationOption(VuoRendererPort *portToSpecialize, string specializedTypeName);
421  bool hasFeedbackErrors(void);
422  void buildComposition(string compositionSnapshot, const set<string> &dependenciesUninstalled = set<string>());
423  bool isRunningThreadUnsafe(void);
424  string getIdentifierForRunningPort(VuoPort *port);
425  void moveItemsBy(set<VuoRendererNode *> nodes, set<VuoRendererComment *> comments, qreal dx, qreal dy, bool movedByDragging);
426  void setPopoversHideOnDeactivate(bool shouldHide);
427 
428  QGraphicsItemAnimation * setUpAnimationForPort(QGraphicsItemAnimation *animation, VuoRendererPort *port);
429  void animatePort(VuoRendererPort *port);
430  QGraphicsItemAnimation * getAvailableAnimationForPort(VuoRendererPort *port);
431 
432  friend class TestVuoEditor;
433 };