// =========================================================================== // Copyright 2018 Autodesk, Inc. All rights reserved. // // Use of this software is subject to the terms of the Autodesk license // agreement provided at the time of installation or download, or which // otherwise accompanies this software in either electronic or hard copy form. // =========================================================================== // // Creation Date: 08/2010 // // Description: // // This file contains the procedures which create and manipulate a // Node Editor window. // // Saving and restoring layout Can be disabled with optionVar nodeEdDontSaveLayoutWithWindows // // stores scripts to restore the saved panel state // format is [panelName1, panelRestoreScript1, panelName2, panelRestoreScript2,...] // // stores panel names which require save/restore of state // format is [panelName1, panelName2,..] // global string $gNodeEditorWindowPanels[]; global int $gNodeEditorWindowPanelsDeleteScriptJobs[]; //! take action when a panel is added if it has been flagged global proc nodeEdWindowAddCallback(string $whichPanel) { if(`scriptedPanel -q -to $whichPanel`) { // If the panel still has an associated scriptJob for deletion // at this point, kill it, because it is from a previous version // of the panel that will act on this panel (i.e. delete it), which // we don't want. The scriptJob for this panel will always be created // after this point. global string $gNodeEditorWindowPanels[]; global int $gNodeEditorWindowPanelsDeleteScriptJobs[]; int $index = stringArrayFind($whichPanel, 0, $gNodeEditorWindowPanels); if($index != -1) { if(`scriptJob -exists $gNodeEditorWindowPanelsDeleteScriptJobs[$index]`) { scriptJob -kill $gNodeEditorWindowPanelsDeleteScriptJobs[$index]; } stringArrayRemoveAtIndex($index, $gNodeEditorWindowPanels); intArrayRemoveAtIndex($index, $gNodeEditorWindowPanelsDeleteScriptJobs); } } } //! take action when a panel is removed if it has been flagged global proc nodeEdWindowRemoveCallback(string $whichPanel) { global string $gNodeEditorWindowPanels[]; global int $gNodeEditorWindowPanelsDeleteScriptJobs[]; // If this is the primary Node Editor, reset the visible // state of the Create Node pane back to the default (i.e. // not visible) // string $ned = ( $whichPanel + "NodeEditorEd" ); global int $gNodeEditorCreateNodePaneShown; if(`nodeEditor -q -primary $ned`) { $gNodeEditorCreateNodePaneShown = false; } // if this is torn-off panel we don't know about, make sure the panel // gets managed anyway. if (!stringArrayContains($whichPanel, $gNodeEditorWindowPanels)) { if (`scriptedPanel -exists $whichPanel` && `scriptedPanel -q -to $whichPanel` && $whichPanel != "nodeEditorPanel1") { int $max = `size $gNodeEditorWindowPanels`; $gNodeEditorWindowPanels[$max] = $whichPanel; // create a scriptJob which will run when the window is deleted // string $panelControl = `panel -q -control $whichPanel`; string $windowName = match("^[^|]*",$panelControl); $gNodeEditorWindowPanelsDeleteScriptJobs[$max] = `scriptJob -runOnce true -uiDeleted $windowName ("nodeEditorWindowClosed \""+$whichPanel+"\"")`; } } } proc string createPrimaryNodeEditorWindow() // // Description: // This procedure creates the primary Node Editor, which is always 'nodeEditorPanel1' // by tearing it off, if needed, and then making sure its visible. It also makes // visible any child editors which are the tabs that were torn off. // // Return: // Name of the new nodeEditor. // { // Tear off (if needed) the default node editor panel (Panel1) and then make // sure all the other node editor panels are visible. string $primaryNEPanel = "nodeEditorPanel1"; if (`scriptedPanel -q -exists $primaryNEPanel`) { // First tear-off the primary Node Editor. scriptedPanel -e -tor $primaryNEPanel; // Then make sure all the Node Editors (primary and torn-off) are also visible. string $nodeEdPanels[] = `getPanel -scriptType "nodeEditorPanel"`; string $nodeEdPanel; for ($nodeEdPanel in $nodeEdPanels) { showWindow ($nodeEdPanel + "Window"); } // We don't allow the Node Editor to be duplicated. if (`workspaceControl -exists ($primaryNEPanel + "Window")`) workspaceControl -e -dup false ($primaryNEPanel + "Window"); // Set the focus to the primary one. evalDeferred ("setFocus \"" + editorNameFromPanel($primaryNEPanel) + "\""); return editorNameFromPanel($primaryNEPanel); } else { // Should never happen, but if for some reason we don't have the // 'nodeEditorPanel1', we'll create a new node editor window which // should then take-over the role of primary and be panel 1. return createNodeEditorWindow(); } } proc string createNodeEditorWindow() // // Description: // This procedure creates a new window with a node editor and menu bar. // // Return: // Name of the new nodeEditor. // { // create a new nodeEditor panel // string $panelLabel = localizedPanelLabel("Node Editor"); string $whichPanel = `scriptedPanel -label $panelLabel -type nodeEditorPanel -unParent`; // tear if off to create a new window scriptedPanel -e -tor $whichPanel; // register this panel as needing save/restore of state // global string $gNodeEditorWindowPanels[]; global int $gNodeEditorWindowPanelsDeleteScriptJobs[]; int $index = stringArrayFind($whichPanel, 0, $gNodeEditorWindowPanels); if($index == -1) { $index = `size $gNodeEditorWindowPanels`; $gNodeEditorWindowPanels[$index] = $whichPanel; } else { scriptJob -kill $gNodeEditorWindowPanelsDeleteScriptJobs[$index]; } // create a scriptJob which will run when the window is deleted // string $panelControl = `panel -q -control $whichPanel`; string $windowName = match("^[^|]*",$panelControl); $gNodeEditorWindowPanelsDeleteScriptJobs[$index] = `scriptJob -runOnce true -uiDeleted $windowName ("nodeEditorWindowClosed \""+$whichPanel+"\"")`; // We don't allow the Node Editor to be duplicated. if (`workspaceControl -exists ($whichPanel + "Window")`) workspaceControl -e -dup false ($whichPanel + "Window"); evalDeferred ("setFocus \"" + editorNameFromPanel($whichPanel) + "\""); return editorNameFromPanel($whichPanel); } global proc string nodeEditorWindow() { // Create by tearing off (if needed) and make visible the primary node editor // (and any torn-off child editors) which is 'nodeEditorPanel1'. return createPrimaryNodeEditorWindow(); } global proc nodeEditorWindowClosed(string $whichPanel) // // Description: // Clean up the window resources { // Check if it is the default nodeEditor panel. // Don't delete the default hyper graph panel. // if ($whichPanel != "nodeEditorPanel1") { // remove the panel entry global string $gNodeEditorWindowPanels[]; global int $gNodeEditorWindowPanelsDeleteScriptJobs[]; int $index = stringArrayFind($whichPanel, 0, $gNodeEditorWindowPanels); if($index != -1) { stringArrayRemoveAtIndex($index, $gNodeEditorWindowPanels); intArrayRemoveAtIndex($index, $gNodeEditorWindowPanelsDeleteScriptJobs); } if (`scriptedPanel -exists $whichPanel`) { // delete the panel itself deleteUI -panel $whichPanel; } } } proc string windowFromEditor(string $editor) { string $window = $editor; if (endsWith($editor, "NodeEditorEd")) { $window = startString($editor, size($editor) - size("NodeEditorEd")); $window += "Window"; } return $window; } global proc string createTearOffNodeEditorFrom(string $fromNE, int $xPos, int $yPos) { // First get the size of the window we are tearing off from. If we are // tearing off from a panel node editor we won't have a window. So in that // case we'll just position the new node editor and use the default size. string $fromNEWindow = windowFromEditor($fromNE); int $we[] = {0, 0}; if (`window -query -exists $fromNEWindow`) $we = `window -query -widthHeight $fromNEWindow`; // When running Maya on a scaled DPI setting, the width and height of the window // are the actual values for it's width/height. However when we create a new // window and set it's size we want to pass the unscaled values since the window // command will auto-scale them for us. if (`exists mayaDpiSetting`) { float $rsv = `mayaDpiSetting -q -realScaleValue`; $we[0] = $we[0] / $rsv; $we[1] = $we[1] / $rsv; } return createTearOffNodeEditor($xPos, $yPos, $we[0], $we[1]); } global proc string createTearOffNodeEditor(int $xPos, int $yPos, int $width, int $height) // // Description: // This procedure creates a new node editor window for a tab that is being torn // off from the primary node editor. The new editor is created at the input // position and set to the input size. // // Return: // Name of the new nodeEditor. // { // Then create the new Node Editor Editor. string $newNEEditor = createNodeEditorWindow(); // Move and resize this new window to match the input. // Note: the flag is 'topLeftCorner' so the x/y are reversed. // Note: Because we want to position/size this node editor window directly // we need to delete any window pref which might exist for a window // with this name. string $newNEWindow = windowFromEditor($newNEEditor); if (`windowPref -ex $newNEWindow`) windowPref -remove $newNEWindow; if ( ($width != 0) && ($height != 0) ) window -e -topLeftCorner $yPos $xPos -widthHeight $width $height $newNEWindow; else window -e -topLeftCorner $yPos $xPos $newNEWindow; return $newNEEditor; } global proc closeNodeEditorEd(string $editor) { if (`nodeEditor -ex $editor`) { string $wnd = windowFromEditor($editor); if (`window -ex $wnd`) { // delete this window later evalDeferred(("catchQuiet (`deleteUI -window " + $wnd + "`)")); } } } global proc closeAllNodeEditors() { string $nodeEdPanels[] = `getPanel -scriptType "nodeEditorPanel"`; string $nodeEdPanel; for ($nodeEdPanel in $nodeEdPanels) { deleteUI -panel $nodeEdPanel; } }