GCWindowMenu [download]

Turn any view into a pop-up

You wouldn't think this would be hard, and it's not really. However, some of the solutions I've seen "out there" are bizarre and over-complicated. Thus I made this one the way I feel it ought to be done.

How it works: You create an instance of GCWindowMenu, then you add the main content view to it (a slider control, or whatever you like - in fact the creation of the window and supplying the view is one class method call), then you call one class method to handle the rest - positioning it, popping it up on screen, tracking it and then finally fading it away quickly but gracefully at the end.

GCWindowMenu endeavours to emulate the standard menu behaviour - if you click once quickly to bring it up, it will stay on screen and you can click and drag in it. If you click and hold, it will stay up as long as the mouse is down.

Standard view mouse event handling methods are called while the menu is being tracked, so by and large you can easily design a view to work in any situation - in a window or in a menu. For standard control views, there are a few additional minor kinks, since those views implement their own tracking loops. At present their design means that depending on how you position the menu, you may not be able to use the click-hold-release method with some kinds of controls. GCWindowMenu tries to do the right thing, and has some flags you can set to change the behaviour.

GCWindowMenu only implements the menu, not the widget that triggers it. However, the example code in the download shows one simple way to handle this - as you'll see it's just a very small effort.

This code was originally developed for use in Gradient Panel (http://gradientpanel.com) which is itself a spin-off of DrawKit's user interface widget toolbox. However it is totally general purpose and relies on no other parts of DrawKit or Gradient Panel. Another example of GCWindowMenu's use can be found in the Gradient Panel demo, where it is used to pop-up the colour wheel picker when you right-click a gradient stop.