Search Unity

How to display a popup window when called via Shortcut attribute hotkey?

Discussion in 'Editor Workflows' started by Xarbrough, Jul 27, 2019.

  1. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    What is the intended way of showing a context popup window that is invoked via keypress with the new ShortcutManager/ShortcutAttribute system?

    For example, this code:

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEditor.ShortcutManagement;
    3. using UnityEngine;
    4.  
    5. public class Test
    6. {
    7.     [Shortcut("Test", KeyCode.G)]
    8.     public static void ShowMyCustomPopup()
    9.     {
    10.         // This GenericMenu shows, but it's not under the mouse,
    11.         // becaues we're not calling it from OnGUI.
    12.         var menu = new GenericMenu();
    13.         menu.AddItem(new GUIContent("Test"), false, null);
    14.         menu.ShowAsContext();
    15.  
    16.         // This shows as well, but the mouse position is incorrect,
    17.         // since not called from OnGUI.
    18.         // Additionally, an unhandled ExitGUIException is thrown
    19.         // when closing the popup.
    20.         var rect = new Rect(Event.current.mousePosition, Vector2.zero);
    21.         PopupWindow.Show(rect, new CustomContent());
    22.     }
    23.  
    24.     private class CustomContent : PopupWindowContent
    25.     {
    26.         public override void OnGUI(Rect rect)
    27.         {
    28.             EditorGUI.LabelField(rect, "Test");
    29.         }
    30.     }
    31. }
    I'd like to show a popup when a certain key is pressed, but the functions are invoked by Unity not during the OnGUI call, so common GUI functions such as GenericMenu.ShowAsContext or PopupWindow do not work. Is there a way of telling the shortcut system that I want my callback to be invoked in the GUI loop or do I have to queue my own commands and execute them during the next GUI call? If so, how do I get a globally available GUI call? In this specific case I would want my menu to be available in the SceneView and the Hierarchy Window, so I would need to subscribe to multiple GUI loops in this case.

    I've experimented with using my own GUI callback like this, but it's not exactly what I want:

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEditor.ShortcutManagement;
    3. using UnityEngine;
    4.  
    5. public class Test
    6. {
    7.     [Shortcut("Test", typeof(SceneView), KeyCode.G)]
    8.     public static void ShowMyCustomPopup(ShortcutArguments args)
    9.     {
    10.         SceneView.beforeSceneGui += OnSceneGUI;
    11.     }
    12.  
    13.     private static void OnSceneGUI(SceneView obj)
    14.     {
    15.         SceneView.beforeSceneGui -= OnSceneGUI;
    16.  
    17.         var rect = new Rect(Event.current.mousePosition, Vector2.zero);
    18.         PopupWindow.Show(rect, new CustomContent());
    19.     }
    20.  
    21.     private class CustomContent : PopupWindowContent
    22.     {
    23.         public override void OnGUI(Rect rect)
    24.         {
    25.             EditorGUI.LabelField(rect, "Test");
    26.         }
    27.     }
    28. }
    When the mouse is over the SceneView I can invoke the shortcut callback and then wait for the next SceneView.beforeSceneGui callback to show the menu. This works nicely, but I also want the shortcut to work in other windows or even globally. However, I don't have access to the type of the HierarchWindow, so I can't use it as a custom shortcut context and not all windows have gui callbacks, which I can access.
     
    Last edited: Jul 27, 2019
    Peter77 likes this.
  2. ADZ_

    ADZ_

    Joined:
    Jun 14, 2019
    Posts:
    7
    I know I'm very late to this, but in case anyone else is having issues with ExitGUIException, if you subscribe to EditorApplication.update and then immediately unsubscribe upon execution, like the example above, that seems to completely avoid the GUI loop.