Vuo  2.0.0
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);
68  void removeCable(VuoRendererCable *rc);
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 portsPassSanityCheckToTypeconvert(VuoRendererPort *fromPort, VuoRendererPort *toPort, VuoType *candidateFromType=NULL, VuoType *candidateToType=NULL);
298 
299  void fireTriggerPortEvent(VuoPort *port);
300  QList<QAction *> promoteSingletonsFromSubmenus(QList<QAction *> actionList);
301  static bool nodeSetMenuActionLessThan(QAction *action1, QAction *action2);
302  static bool itemHigherOnCanvas(QGraphicsItem *item1, QGraphicsItem *item2);
303  static double calculateNodeSimilarity(VuoNodeClass *node1, VuoNodeClass *node2);
304 
305  // Popovers
306  void enableInactivePopoverForPort(VuoRendererPort *rp);
307  void disablePopoverForPortThreadSafe(string portID);
308  void disablePortPopovers(VuoRendererNode *node=NULL);
309  void moveDetachedPortPopoversBy(int dx, int dy);
310  void moveErrorPopoversBy(int dx, int dy);
311  VuoErrorMark *errorMark;
312  set<VuoErrorPopover *> errorPopovers;
313  bool errorMarkingUpdatesEnabled;
314 
315 private slots:
316  void moveNodesBy(set<VuoRendererNode *> nodes, qreal dx, qreal dy, bool movedByDragging);
317  void moveCommentsBy(set<VuoRendererComment *> comments, qreal dx, qreal dy, bool movedByDragging);
318  void resizeCommentBy(VuoRendererComment *comment, qreal dx, qreal dy);
319  void editSelectedComments();
320  void insertNode();
321  void insertComment();
322  void insertSubcomposition();
323  void deleteConnectedCables();
324  void hideConnectedCables();
325  void unhideConnectedCables();
326  void fireTriggerPortEvent();
327  void setPortConstant();
328  void setTriggerThrottling(int eventThrottling);
329  void specializeGenericPortType();
330  void unspecializePortType();
331  void addInputPort();
332  void removeInputPort();
333  void swapNode();
334  void setDisableDragStickiness(bool disable);
335  void updatePortAnimation(qreal value);
336  void endPortAnimation(void);
337  void expandChangeNodeMenu();
338 
339  // Popovers
340  void updatePopoversForActiveWindowChange(QWidget *old, QWidget *now);
341  void updatePopoversForApplicationStateChange(bool active);
342  void enablePopoverForNode(VuoRendererNode *rn);
343  void repositionPopover();
344 
345 private:
346  static const qreal nodeMoveRate;
347  static const qreal nodeMoveRateMultiplier;
348  static const qreal showEventsModeUpdateInterval;
349  static const int initialChangeNodeSuggestionCount;
350  VuoMainWindow *window;
351  VuoCompiler *compiler;
352  VuoModuleManager *moduleManager;
353  VuoInputEditorManager *inputEditorManager;
354  VuoProtocol *activeProtocol;
355  VuoRunner *runner;
356  VuoCompilerComposition *runningComposition;
357  VuoCompilerDriver *runningCompositionActiveDriver;
358  dispatch_queue_t runCompositionQueue;
359  dispatch_queue_t activePortPopoversQueue;
360  bool stopRequested;
361  string linkedCompositionPath;
362  VuoRunningCompositionLibraries *runningCompositionLibraries;
363  QAction *contextMenuDeleteSelected;
364  QAction *contextMenuHideSelectedCables;
365  QAction *contextMenuRenameSelected;
366  QAction *contextMenuRefactorSelected;
367  QAction *contextMenuPublishPort;
368  QAction *contextMenuDeleteCables;
369  QAction *contextMenuHideCables;
370  QAction *contextMenuUnhideCables;
371  QAction *contextMenuFireEvent;
372  QAction *contextMenuAddInputPort;
373  QAction *contextMenuRemoveInputPort;
374  QAction *contextMenuSetPortConstant;
375  QAction *contextMenuEditSelectedComments;
376  QMenu *contextMenuChangeNode;
377  QList<QAction *> contextMenuThrottlingActions;
378  QList<QAction *> contextMenuTintActions;
379  bool duplicateOnNextMouseMove;
380  bool duplicationDragInProgress;
381  bool duplicationCancelled;
382  QPointF cursorPosBeforeDuplicationDragMove;
383  VuoCable *cableInProgress;
384  bool cableInProgressWasNew;
385  bool cableInProgressShouldBeWireless;
386  VuoRendererPort *portWithDragInitiated;
387  VuoRendererCable *cableWithYankInitiated;
388  bool menuSelectionInProgress;
389  QGraphicsItem *previousNearbyItem;
390  map<string, VuoNode *> nodeWithGraphvizIdentifier;
391  map<string, VuoPort *> portWithStaticIdentifier;
392  map<VuoPort *, string> staticIdentifierForPort;
393  bool dragStickinessDisabled;
394  bool ignoreApplicationStateChangeEvents;
395  bool showEventsMode;
396  QTimer *refreshComponentAlphaLevelTimer;
397  set<QGraphicsItemAnimation *> preparedAnimations;
398  map<QTimeLine *, QGraphicsItemAnimation *> animationForTimeline;
399  string triggerPortToRefire;
400 
401  // Popovers
402  bool popoverEventsEnabled;
403  map<string, VuoPortPopover *> activePortPopovers;
404  set<string> portsWithPopoversClosedAtLastEvent;
405 
406  bool isPortCurrentlyRevertible(VuoRendererPort *port);
407  void addActionToMenuAndMapper(QMenu *menu, QSignalMapper *mapper, QString name, int index);
408  void mousePressEventNonLeftButton(QGraphicsSceneMouseEvent *event);
409  void correctForCancelledDuplication(QGraphicsSceneMouseEvent *event);
410  void initiateCableDrag(VuoRendererPort *currentPort, VuoRendererCable *cableYankedDirectly, QGraphicsSceneMouseEvent *event);
411  void concludeCableDrag(QGraphicsSceneMouseEvent *event);
412  void concludePublishedCableDrag(QGraphicsSceneMouseEvent *event);
413  void updateHoverHighlighting(QPointF scenePos, bool disablePortHoverHighlighting=false);
414  void highlightEligibleEndpointsForCable(VuoCable *cable);
415  void highlightInternalPortsConnectableToPort(VuoRendererPort *port, VuoRendererCable *cable);
416  void updateEligibilityHighlightingForPort(VuoRendererPort *portToHighlight, VuoRendererPort *fixedPort, bool eventOnlyConnection);
417  void updateEligibilityHighlightingForNode(VuoRendererNode *node);
418  bool selectBridgingSolutionFromOptions(vector<string> suitableTypecasts, map<string, VuoRendererPort *> portToSpecializeForTypecast, map<string, string> specializedTypeNameForTypecast, string &selectedTypecast);
419  vector<string> findBridgingSolutions(VuoRendererPort *fromPort, VuoRendererPort *toPort, bool toPortIsDragDestination, map<string, VuoRendererPort *> &portToSpecializeForTypecast, map<string, string> &specializedTypeNameForTypecast);
420  bool promptForBridgingSelectionFromOptions(vector<string> suitableTypecasts, map<string, VuoRendererPort *> portToSpecializeForTypecast, map<string, string> specializedTypeNameForTypecast, string &selectedTypecast);
421  QString getDisplayTextForSpecializationOption(VuoRendererPort *portToSpecialize, string specializedTypeName);
422  bool hasFeedbackErrors(void);
423  void buildComposition(string compositionSnapshot, const set<string> &dependenciesUninstalled = set<string>());
424  bool isRunningThreadUnsafe(void);
425  string getIdentifierForRunningPort(VuoPort *port);
426  void moveItemsBy(set<VuoRendererNode *> nodes, set<VuoRendererComment *> comments, qreal dx, qreal dy, bool movedByDragging);
427  void setPopoversHideOnDeactivate(bool shouldHide);
428 
429  QGraphicsItemAnimation * setUpAnimationForPort(QGraphicsItemAnimation *animation, VuoRendererPort *port);
430  void animatePort(VuoRendererPort *port);
431  QGraphicsItemAnimation * getAvailableAnimationForPort(VuoRendererPort *port);
432 
433  friend class TestVuoEditor;
434 };