Ejemplo n.º 1
0
        /// <summary>
        /// Draws the Node Canvas on the screen in the rect specified by editorState. Has to be called out of any GUI Group or area because of zooming.
        /// </summary>
        public static void DrawCanvas(NodeCanvas nodeCanvas, NodeEditorState editorState, Action repaint)
        {
            if (!editorState.drawing)
            {
                return;
            }

            curNodeCanvas  = nodeCanvas;
            curEditorState = editorState;

            if (repaint != null)
            {
                Repaint += repaint;
            }

            //		if (curEditorState.parent != null)
            //			curEditorState.canvasRect.position += curEditorState.parent.zoomPanAdjust;

            if (Event.current.type == EventType.Repaint)
            {             // Draw Background when Repainting
                GUI.BeginClip(curEditorState.canvasRect);

                float   width  = Background.width / curEditorState.zoom;
                float   height = Background.height / curEditorState.zoom;
                Vector2 offset = new Vector2((curEditorState.panOffset.x / curEditorState.zoom) % width - width,
                                             (curEditorState.panOffset.y / curEditorState.zoom) % height - height);
                int tileX = Mathf.CeilToInt((curEditorState.canvasRect.width + (width - offset.x)) / width);
                int tileY = Mathf.CeilToInt((curEditorState.canvasRect.height + (height - offset.y)) / height);

                for (int x = 0; x < tileX; x++)
                {
                    for (int y = 0; y < tileY; y++)
                    {
                        Rect texRect = new Rect(offset.x + x * width,
                                                offset.y + y * height,
                                                width, height);

                        GUI.DrawTexture(texRect, Background);
                    }
                }
                GUI.EndClip();
            }

            //		if (curEditorState.parent != null)
            //			curEditorState.canvasRect.position -= curEditorState.parent.zoomPanAdjust - curEditorState.parent.zoomPos;

            // Fetch all nested nodeEditors and set their canvasRects to be ignored by input,
            // so it can be handled later, and note it down, as it will be drawn later ontop
            List <Rect> ignoreInput = new List <Rect> ();

            for (int childCnt = 0; childCnt < curEditorState.childs.Count; childCnt++)
            {
                if (curEditorState.childs [childCnt].drawing)
                {
                    NodeEditorState nestedEditor = curEditorState.childs [childCnt];
                    ignoreInput.Add(GUIToScreenRect(nestedEditor.canvasRect));
                }
            }

            // Check the inputs
            InputEvents(ignoreInput);

            // We want to scale our nodes, but as GUI.matrix also scales our widnow's clipping group,
            // we have to scale it up first to receive a correct one as a result
            #region Scale Setup

            // End the default clipping group
            GUI.EndGroup();

            // The Rect of the new clipping group to draw our nodes in
            Rect ScaledCanvasRect = ScaleRect(curEditorState.canvasRect, curEditorState.zoomPos + curEditorState.canvasRect.position, new Vector2(curEditorState.zoom, curEditorState.zoom));
            ScaledCanvasRect.y += 23;             // Header tab height

            if (curNodeCanvas != NodeEditorWindow.MainNodeCanvas)
            {
                GUI.DrawTexture(ScaledCanvasRect, Background);
            }

            // Now continue drawing using the new clipping group
            GUI.BeginGroup(ScaledCanvasRect);
            ScaledCanvasRect.position = Vector2.zero;             // Adjust because we entered the new group

            // Because I currently found no way to actually scale to the center of the window rather than (0, 0),
            // I'm going to cheat and just pan it accordingly to let it appear as if it would scroll to the center
            // Note, due to that, other controls are still scaled to (0, 0)
            curEditorState.zoomPanAdjust = ScaledCanvasRect.center - curEditorState.canvasRect.size / 2 + curEditorState.zoomPos;

            // Take a matrix backup to restore back later on
            Matrix4x4 GUIMatrix = GUI.matrix;

            // Scale GUI.matrix. After that we have the correct clipping group again.
            GUIUtility.ScaleAroundPivot(new Vector2(1 / curEditorState.zoom, 1 / curEditorState.zoom), curEditorState.zoomPanAdjust);

            #endregion

            // Some features which require drawing (zoomed)
            if (curEditorState.navigate)
            {             // Draw a curve to the origin/active node for orientation purposes
                DrawLine(curEditorState.activeNode != null? curEditorState.activeNode.rect.center + curEditorState.zoomPanAdjust : curEditorState.panOffset,
                         ScreenToGUIPos(mousePos) + curEditorState.zoomPos * curEditorState.zoom,
                         Color.black, null, 3);
                if (Repaint != null)
                {
                    Repaint();
                }
            }
            if (curEditorState.connectOutput != null)
            {             // Draw the currently drawn connection
                DrawConnection(curEditorState.connectOutput.GetGUIKnob().center,
                               ScreenToGUIPos(mousePos) + curEditorState.zoomPos * curEditorState.zoom,
                               ConnectionTypes.GetTypeData(curEditorState.connectOutput.type).col);
                if (Repaint != null)
                {
                    Repaint();
                }
            }
            if (curEditorState.makeTransition != null)
            {             // Draw the currently made transition
                DrawLine(curEditorState.makeTransition.rect.center + curEditorState.zoomPanAdjust,
                         ScreenToGUIPos(mousePos) + curEditorState.zoomPos * curEditorState.zoom,
                         Color.grey, null, 3);
                if (Repaint != null)
                {
                    Repaint();
                }
            }

            // Draw the Node connectors; Seperated because of render order
            for (int nodeCnt = 0; nodeCnt < curNodeCanvas.nodes.Count; nodeCnt++)
            {
                curNodeCanvas.nodes [nodeCnt].DrawConnections();
            }
            for (int nodeCnt = 0; nodeCnt < curNodeCanvas.nodes.Count; nodeCnt++)
            {
                curNodeCanvas.nodes [nodeCnt].DrawKnobs();
            }
            for (int nodeCnt = 0; nodeCnt < curNodeCanvas.nodes.Count; nodeCnt++)
            {
                curNodeCanvas.nodes [nodeCnt].DrawTransitions();
            }

            // Draw the nodes
            for (int nodeCnt = 0; nodeCnt < curNodeCanvas.nodes.Count; nodeCnt++)
            {
                Node node = curNodeCanvas.nodes [nodeCnt];
                //if (node != curEditorState.activeNode)
                NodeEditor.DrawNode(node);
            }

            // Draw the active Node ontop
            //		if (editorState.activeNode != null)
            //			NodeEditor.DrawNode (curEditorState.activeNode);

            // Draw any node groups out there. Has to be drawn here, because they still need to scale according to their parents, but they mustn't be drawn inside a GUI group
            for (int editorCnt = 0; editorCnt < curEditorState.childs.Count; editorCnt++)
            {
                if (curEditorState.childs [editorCnt].drawing)
                {
                    NodeEditorState nestedEditor = curEditorState.childs [editorCnt];
                    nestedEditor.canvasRect.position += curEditorState.zoomPanAdjust;
                    //GUI.DrawTexture (nestedEditor.canvasRect, Background);
                    DrawCanvas(nestedEditor.canvas, nestedEditor, Repaint);
                    nestedEditor.canvasRect.position -= curEditorState.zoomPanAdjust;
                }
            }
            curNodeCanvas  = nodeCanvas;
            curEditorState = editorState;

            // End scaling group
            // Set default matrix and clipping group for the rest
            GUI.matrix = GUIMatrix;
            GUI.EndGroup();
            if (curNodeCanvas.parent == null)
            {
                GUI.BeginGroup(new Rect(0, 23, NodeEditorWindow.editor.position.width, NodeEditorWindow.editor.position.height));
            }
            else
            {
                Rect parentGroupRect = ScaleRect(curEditorState.parent.canvasRect, curEditorState.parent.zoomPos + curEditorState.parent.canvasRect.position, new Vector2(curEditorState.parent.zoom, curEditorState.parent.zoom));
                parentGroupRect.y += 23;                 // Header tab height
                GUI.BeginGroup(parentGroupRect);
            }
            // Check events with less priority than node GUI controls
            LateEvents(ignoreInput);
        }