Cantabile Development Blog

Follow the development of music software Cantabile

Articles | Full Index | RSS Feed


Popup Menus

Today I finished SkinLib's support for popup menus. At first I considered using Window's menu support, and manually drawing each item with the skinned appearance. However I decided to write my own system from scratch because:

  • Window's owner-draw menus don't allow painting of the menu's frame - just the items within it - meaning I wouldn't be able to fully skin the menus.
  • I wanted a finer degree of control over the menus. In previous versions of Cantabile I've had a very difficult time with menus containing large numbers of items (eg: the plugin and program selector drop downs). Windows doesn't support scrollbars or mouse wheel within the menu.
  • I wanted the option to be able to place more complex controls within the menus.
  • I wanted to be able to hook into idle time processing of the menu message loop - this is not possible with standard Window's menus.

Turns out that what seems like a pretty simple piece of user-interface is actually quite complicated and it took me two goes to get it right. Some of the issues encountered include:

  • A menu doesn't actually take focus from the parent application so all keyboard processing needs to be done directly within the message loop and manually routed to appropriate items.
  • Mouse actions need to be co-ordinated across multiple windows when sub-menus are present, with all mouse positions manually calculated.
  • Needs to manage a stack of currently visible menus and sub-menus and update this list as user moves between menus.
  • Various delayed actions. eg: when hovering over a sub-menu, the sub-menu is automatically shown (without clicking) but only after about half second delay. Similarly if the mouse is moved from a sub menu back to the parent menu, the sub-menu isn't closed until shortly after.
  • Special handling for short-cut keys and dealing with menus that have duplicates in the one menu.
  • Other miscellaneous behaviours (eg: mouse up outside the menu closes the menu, but only if the mouse was pressed in the menu to start with).
  • Special handling to ensure the menus don't appear offscreen, and when moving back on-screen, ensure they don't obstruct the parent menu.

The final design however I'm quite happy with as it behaves exactly like a Window's, but I now have the ability to put pretty much whatever I like in a menu. I'm sure I'll be able to reap the benefits when it comes time to build the new plugin and program selectors.

Posted on April 15, 2007

Share This

Leave A Comment

All comments will be reviewed for spam before being displayed.