Add maximum window size to AdvancedDropdown control

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.

Still using the AdvancedDropdown in every project and still hoping for a maximum window size property. :wink: I’ve been trying to hack this in with reflection, but it turned out too intricate.

Challenge accepted! :smile:

using UnityEngine;

namespace UnityEditor.IMGUI.Controls
{
    public static class AdvancedDropdownExtensions
    {
        public static void Show(this AdvancedDropdown dropdown, Rect buttonRect, float maxHeight)
        {
            dropdown.Show(buttonRect);
            SetMaxHeightForOpenedPopup(buttonRect, maxHeight);
        }

        private static void SetMaxHeightForOpenedPopup(Rect buttonRect, float maxHeight)
        {
            var window = EditorWindow.focusedWindow;

            if(window == null)
            {
                Debug.LogWarning("EditorWindow.focusedWindow was null.");
                return;
            }

            if(!string.Equals(window.GetType().Namespace, typeof(AdvancedDropdown).Namespace))
            {
                Debug.LogWarning("EditorWindow.focusedWindow " + EditorWindow.focusedWindow.GetType().FullName + " was not in expected namespace.");
                return;
            }

            var position = window.position;
            if(position.height <= maxHeight)
            {
                return;
            }

            position.height = maxHeight;
            window.minSize = position.size;
            window.maxSize = position.size;
            window.position = position;
            window.ShowAsDropDown(GUIUtility.GUIToScreenRect(buttonRect), position.size);
        }
    }
}
5 Likes

Thanks a lot! This works nicely and is much cleaner than I’ve imagined. :slight_smile:

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. :smile: I guess I was simply missing the call to ShowAsDropDown.

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 :slight_smile:

Great work, but it would be better if Unity provided us the means of changing maxSize property.
We don’t have direct control over AdvancedDropdownWindow, whereas Unity has control over the window for AddComponent dropdown, they override CalculateWindowSize and set maxSize for it.
Basically at least making AdvancedDropdown.maximumSize protected (it’s internal now) would already be good. For some reason only minimumSize is protected. =D

1 Like

I will never understand Unity’s reasonings. Why make AdvancedDropdown.minimumSize protected but AdvancedDropdown.maximumSize internal?