Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

EditorWindow, draggable GUI.Window and dragging to pan [SOLVED]

Discussion in 'Immediate Mode GUI (IMGUI)' started by rev087, Jan 16, 2015.

  1. rev087

    rev087

    Joined:
    Oct 3, 2013
    Posts:
    11
    User unimechanic posted a couple years ago a snippet of C# code to create a simple Node Editor, which he later updated to add a simple pan functionality. The thread is here: http://forum.unity3d.com/threads/simple-node-editor.189230/

    I've been trying to figure out a way to drag the EditorWindow background instead of using buttons to pan. This little snippet seemed to do the trick:

    Code (CSharp):
    1.         if (Event.current.button == 1 && Event.current.type == EventType.MouseDrag) {
    2.             panX += Event.current.delta.x;
    3.             panY += Event.current.delta.y;
    4.         }
    ...except when we attempt to drag the GUI.Windows that we use as the nodes, both the window and the whole group will drag.

    I've been trying to figure out a way to detect if the GUI.Window is being dragged, or if the mouse is within the rect of the windows, but after a lot of browsing in the documentation I can't figure out how to achieve either.

    The whole script for testing:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. public class NodeEditor : EditorWindow {
    5.  
    6.     Rect window1;
    7.     Rect window2;
    8.     float panX = 0;
    9.     float panY = 0;
    10.    
    11.     [MenuItem("Window/Node Editor")]
    12.     static void ShowEditor() {
    13.         NodeEditor editor = EditorWindow.GetWindow<NodeEditor>();
    14.         editor.Show();
    15.     }
    16.    
    17.     public void Awake() {
    18.         window1 = new Rect(10, 10, 100, 100);
    19.         window2 = new Rect(210, 210, 100, 100);
    20.     }
    21.    
    22.     void OnGUI() {
    23.         bool didPan = false;
    24.         if (Event.current.type == EventType.MouseDrag) {
    25.             panX += Event.current.delta.x;
    26.             panY += Event.current.delta.y;
    27.             didPan = true;
    28.         }
    29.        
    30.         GUI.BeginGroup(new Rect(panX, panY, 100000, 100000));
    31.        
    32.         DrawNodeCurve(window1, window2); // Here the curve is drawn under the windows
    33.        
    34.         BeginWindows();
    35.         window1 = GUI.Window(2, window1, DrawNodeWindow, "Node A");   // Updates the Rect's when these are dragged
    36.         window2 = GUI.Window(3, window2, DrawNodeWindow, "Node B");
    37.         EndWindows();
    38.        
    39.         GUI.EndGroup();
    40.        
    41.         if (didPan) Repaint();
    42.     }
    43.    
    44.     void DrawNodeWindow(int id) {
    45.         GUI.DragWindow();
    46.     }
    47.    
    48.     void DrawNodeCurve(Rect start, Rect end) {
    49.         Vector3 startPos = new Vector3(start.x + start.width, start.y + start.height / 2, 0);
    50.         Vector3 endPos = new Vector3(end.x, end.y + end.height / 2, 0);
    51.         Vector3 startTan = startPos + Vector3.right * 50;
    52.         Vector3 endTan = endPos + Vector3.left * 50;
    53.         Handles.DrawBezier(startPos, endPos, startTan, endTan, Color.white, null, 4);
    54.     }
    55. }
     
  2. rev087

    rev087

    Joined:
    Oct 3, 2013
    Posts:
    11
    Derp! I figured it out! I'm very new to Unity, so I didn't realize that GUI.Window returns the window Rect - the current one, accounting for the windows being dragged.

    With that, I simply need to check each window rect for Rect.Contain(Event.Current.mousePosition). If neither window rect contains the mouse position, that means the user is dragging the background.
     
    MaykeBr likes this.
  3. Colite

    Colite

    Joined:
    Jun 23, 2015
    Posts:
    1
    I know this is more than a year old and it's probably way irrelevant to you by now but you can simply move the panning code below GUI.EndGroup ().

    I don't quite understand why it works, maybe something to do with the windows already being serialized before the panning code, I will try to look into it. Anyways, this should simplify the code and I hope this helps.

    P.S. no need for the didPan bool check simply replace it with repaint.
     
    ununion likes this.
  4. ununion

    ununion

    Joined:
    Dec 2, 2018
    Posts:
    202
    yes you are right! simple way to solve it