Custom EditorWindow GenericMenu Position

Is it possible to assign the position at which a GenericMenu appears manually?

I’ve created a custom editor window with a zoomable panel. When the zoom is at 1 (normal zoom level), any generic menus I’m creating appear underneath the mouse position as I would expect. But when I open these menus at any other zoom level, they’re offset slightly. This is understandable because of how I’m creating the zoom effect and I could correct it if I could manually set the position at which the GenericMenu appears, but I can’t find any way to do that.

Thanks in advance.
Matt

It would be easier to answer your question when we would see your actual code. Anyways:

ShowAsContext() simply calls DropDown with this Rect:

DropDown(new Rect(Event.current.mousePosition.x, Event.current.mousePosition.y, 0f, 0f));

DropDown on the other hand uses the internal method EditorUtility.DisplayCustomMenuWithSeparators to actually display the menu.

“DisplayCustomMenuWithSeparators” uses GUIUtility.GUIToScreenPoint to convert the GUI position into a screen position

Vector2 vector = GUIUtility.GUIToScreenPoint(new Vector2(position.x, position.y));
position.x = vector.x;
position.y = vector.y;

Depending on how you actually “zoom” it’s possible that your zoom factor is not taken into account. So you would need to correct the GUI position manually. GUI.matrix manipulations are critical as they apply to the whole rendering context / window and not just the client area.

[irony] I also had much fun with this issue. [/irony] I was about to extend the GenericMenu class to override the positioning logic. Unfortunately this is not how Unity works. Next I wanted to create my own BetterGenericMenu class [irony] since I enjoy rewriting existing components and have enough spare time [/irony]. But with the hint of @Bunny83 (thanks by the way) I found a hack to get it running.

// cache the original matrix
Matrix4x4 m4 = GUI.matrix;
// scale it by your zoom
GUI.matrix = GUI.matrix * Matrix4x4.Scale(new Vector3( 1 / Zoom, 1 / Zoom, 1 / Zoom));

GenericMenu m = new GenericMenu();
m.AddDisabledItem(new GUIContent("Fun with the");
m.AddDisabledItem(new GUIContent("Unity API");
m.ShowAsContext();

// restore matrix
GUI.matrix = m4;

Sorry for the sarcasm but this issue just drove me crazy. :slight_smile:

I’ve opposite problem. GUI was scaled or not scaled. When not scaled as it should menu was on correct position but when scaled was out of position. So I saved scaled matrix then set GUI to not scaled and then back saved scaling.

            // cache the original matrix(we assume this is scaled)
            Matrix4x4 m4 = GUI.matrix;
            //reset to non-scaled
            GUI.matrix = Matrix4x4.identity;


            genericMenu.ShowAsContext();

            GUI.matrix = m4;

I ended up using the DropDown method and passing in a custom Rect that was scaled in the same way that I’m scaling the Editor window Rect.

Thanks for the responses.

Matt