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.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

GraphView mouse event handling for Edges.

Discussion in 'UI Toolkit' started by tmhbrts, Jan 6, 2020.

  1. tmhbrts

    tmhbrts

    Joined:
    Dec 24, 2013
    Posts:
    13
    Hi,

    Hopefully it's OK to ask questions regarding the still experimental GraphView class. Since most classes in the GraphView namespace are based on VisualElement, this seemed the right place for questions.

    I am trying to execute methods upon MouseUpEvents in the GraphView.

    My GraphView instance is called diagramView.

    In the OnEnable method of diagramView's window, I use the following code to capture and handle MouseUpEvents:
    Code (CSharp):
    1.    diagramView.RegisterCallback<MouseUpEvent>(
    2.        e => UpdateGameObjectSelection()
    3.    );
    Each Node and Edge in the graph represents a GameObject in the scene. I made a custom class for the Nodes called DiagramNode, which contains a public field for its related GameObject:
    Code (CSharp):
    1.     public class DiagramNode : Node
    2.     {
    3.         public GameObject GameObject;
    4.     }
    Then, in the UpdateGameObjectSelection method, I alter GameObjects in UnityEditor.Selection.objects to match the selection of graph elements. I want a selected Node to result in its related GameObject to be selected in the scene. A selected Edge should result in the related GameObjects on both sides of the Edge to be selected in the scene:

    Code (CSharp):
    1.  
    2.     private void UpdateGameObjectSelection()
    3.     {
    4.         var selectedElements = diagramView.selection;
    5.         List<GameObject> gameObjectsToSelect = new List<GameObject>();
    6.         selectedElements.ForEach((selectedElement) =>
    7.         {
    8.             Edge selectedEdge = selectedElement as Edge;
    9.             if(selectedEdge != null)
    10.             {
    11.                 DiagramNode outputNode = selectedEdge.output.node as DiagramNode;
    12.                 DiagramNode inputNode = selectedEdge.input.node as DiagramNode;
    13.                 gameObjectsToSelect.Add(outputNode.GameObject);
    14.                 gameObjectsToSelect.Add(inputNode.GameObject);
    15.             }
    16.             DiagramNode selectedNode = selectedElement as DiagramNode;
    17.             if(selectedNode != null)
    18.             {
    19.                 gameObjectsToSelect.Add(selectedNode.GameObject);
    20.             }
    21.         });
    22.         Selection.objects = gameObjectsToSelect.ToArray();
    23.     }
    This works fine when I select a Node in the graph view: the related GameObject(s) is/are selected in the hierarchy and scene view.
    However, when I select an Edge, it does not work. When I drag select or ctrl/cmd click an Edge, it does work... Something weird seems to be going on with the event handling here. Any help and suggestions would be greatly appreciated.
     
    Last edited: Jan 6, 2020
  2. tmhbrts

    tmhbrts

    Joined:
    Dec 24, 2013
    Posts:
    13
    Having done some more attempts, I found that when I seperately RegisterCallBack for each newly created Edge, (from GraphViewChange.edgesToCreate), I am able to handle mouse events on Edges. When I do the same for a Node instance, it does not work. In that case I have to add the event registration to the parent GraphView instance, and check for changes in GraphView.selection (as shown in the code example of my original post)
    This is a bit odd, but at least I have a workaround.

    Regards,
    Tim
     
    Last edited: Jan 6, 2020
  3. jonathanma_unity

    jonathanma_unity

    Unity Technologies

    Joined:
    Jan 7, 2019
    Posts:
    229
    Hi tmhbrts,

    This is a guess on my part but when this kind of issues happen it's often because another event handler is processing the event.
    By looking at the EdgeManipulator here : https://github.com/Unity-Technologi...ewEditor/Manipulators/EdgeManipulator.cs#L147

    You can see that it stop the event propagation which may explain why diagramView doesn't receive it.
    One thing you can try is to register your callback handler on the TrickleDown phase.

    Code (CSharp):
    1. diagramView.RegisterCallback<MouseUpEvent>(
    2.        e => UpdateGameObjectSelection()
    3. , TrickleDown.TrickleDown);
    You can get more information about this here : https://docs.unity3d.com/2019.1/Documentation/Manual/UIE-Events-Handling.html
     
    VelievIlya and gooby429 like this.