Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Feedback Add maximum window size to AdvancedDropdown control

Discussion in 'Immediate Mode GUI (IMGUI)' started by Xarbrough, Aug 8, 2019.

  1. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    737
    I really like the AdvancedDropdown IMGUI control. It provides a searchable popup window with a scrollable list of entries, much like the AddComponent menu. In the past, I've implemented this type of popup in almost every project myself.

    To make the AdvancedDropdown even better, I suggest:

    Add a maximum window size property. When adding e.g. 100 items to the list, the window fills the entire screen, which is not very pleasing. I'd rather have it cover only part of the screen, since scrollbars take care of the rest. This is also in-line with the way the original AddComponent menu works. It has a maximum size and shows scroll bars early, which looks nicer and keeps the content more in one place.

    AddComponentDropdown.jpg AdvancedDropdown.jpg
     
    Last edited: May 6, 2020
  2. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    737
    Still using the AdvancedDropdown in every project and still hoping for a maximum window size property. ;) I've been trying to hack this in with reflection, but it turned out too intricate.
     
    Last edited: May 7, 2020
  3. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    440
    Challenge accepted! :D

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. namespace UnityEditor.IMGUI.Controls
    4. {
    5.     public static class AdvancedDropdownExtensions
    6.     {
    7.         public static void Show(this AdvancedDropdown dropdown, Rect buttonRect, float maxHeight)
    8.         {
    9.             dropdown.Show(buttonRect);
    10.             SetMaxHeightForOpenedPopup(buttonRect, maxHeight);
    11.         }
    12.  
    13.         private static void SetMaxHeightForOpenedPopup(Rect buttonRect, float maxHeight)
    14.         {
    15.             var window = EditorWindow.focusedWindow;
    16.  
    17.             if(window == null)
    18.             {
    19.                 Debug.LogWarning("EditorWindow.focusedWindow was null.");
    20.                 return;
    21.             }
    22.  
    23.             if(!string.Equals(window.GetType().Namespace, typeof(AdvancedDropdown).Namespace))
    24.             {
    25.                 Debug.LogWarning("EditorWindow.focusedWindow " + EditorWindow.focusedWindow.GetType().FullName + " was not in expected namespace.");
    26.                 return;
    27.             }
    28.  
    29.             var position = window.position;
    30.             if(position.height <= maxHeight)
    31.             {
    32.                 return;
    33.             }
    34.  
    35.             position.height = maxHeight;
    36.             window.minSize = position.size;
    37.             window.maxSize = position.size;
    38.             window.position = position;
    39.             window.ShowAsDropDown(GUIUtility.GUIToScreenRect(buttonRect), position.size);
    40.         }
    41.     }
    42. }
     
    Xarbrough likes this.
  4. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    737
    Thanks a lot! This works nicely and is much cleaner than I've imagined. :)

    And I feel a little dumb since I've tried to set the window size and position after opening it just yesterday, but that always placed the popup in the top left corner. :D I guess I was simply missing the call to ShowAsDropDown.
     
  5. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    440
    Glad to hear it was useful!

    Yeah, the first gotcha was that AdvancedDropdown.Show not only sets the window size internally but also minSize and maxSize, so those needed to be reset also.

    The second gotcha was that the window's y position could be affected by the content size, often pushing the window to the top of the screen during initial opening. I wanted to avoid having to calculate the correct position manually and came up with the lazy idea of just calling ShowAsDropDown again for the already open popup window - and I was happy to find out that it worked like a charm :)
     
unityunity