Click here to Skip to main content
Click here to Skip to main content

Radial Context Menu

, 21 Jul 2005
Rate this:
Please Sign up or sign in to vote.
Mouse gesture with a graphical user interface.

Radial Context Menu

Radial Context Menu With Tips

Radial context menu ...

... with tips

Mouse gesture with a graphical user interface.

Introduction

Some time ago, as I was looking for some kind of mouse gesture add-on for my web browser, I came across this web site. There, one can get an add-on for the browsers Firefox and Mozilla, which implements mouse gestures with a graphical front end. I was slightly confused by this fact - 'Mouse gesture with GUI?', I thought. What could this look like? I took a look at the screenshots and was immediately enthused. The add-on merged the advantages of context menus with that of mouse gestures in a clever way: fast execution of commands as with mouse gestures were combined with an easy to understand context menu. In this way one learns the often used gestures very fast while one still has access to the gestures one doesn't recall at any time. Especially less experienced users will profit from this concept. For instance, my wife and my kids won't browse the web without this extension anymore . So if you're using Firefox or Mozilla, go and get your copy of this real great extension!

I planned to implement this ingenious concept for the use with some of my projects for a long time, but had too less free time. Until now...

How it works

As soon as the user presses the right mouse button, a round menu pops up, displaying up to eight icons. The user now may move the mouse in one of eight directions. As soon as (s)he releases the right mouse button, the function below the mouse cursor will be executed. Since mouse gestures don't work precisely on pixels, the radial menu will follow the mouse cursor on demand. The cursor also doesn't need to be exactly over the icon to select a function. To find out which function to use, the menu checks all points on a thought line from the current cursor position to the center of the radial menu. If the line intersects an icon's area, then it is assumed that the user meant this icon. In this way fast acting professionals will get the right result, too. For users who are new to your program and/or can't recall every mouse gesture (or even don't know what the icon stands for), the menu pops up some kind of tool tips after a short delay time. That way even inexperienced users or users who don't like mouse gestures will quickly get along with this concept.

To build up more complex menus (with more than 8 items), one can build up submenus. That way one can implement gestures such as 'right, then up', too.

Using the code

The radial context menu is implemented to watch for the right mouse button. To activate such a menu, you will need to install a handler for the WM_RBUTTONDOWN window message. The radial context menu object can either be instantiated in this handler method, in the constructor of your CWnd-derived class, or in the OnCreate() handler method.

The size of the icons, the colors and fonts to use should be set up before one sets up the menu items themselves. By default the radial menu will use the system colors and fonts as well as an icon size of 16x16 pixels.

// methods for configuration

// Set background color.
CRadialContextMenu &    SetBkColor(COLORREF clr = ::GetSysColor(COLOR_BTNFACE));

// Set icon size.
CRadialContextMenu &    SetIconSize(CSize size = CSize(16, 16));
CRadialContextMenu &    SetIconSize(int cx, int cy);

// Set font for tips
CRadialContextMenu &    SetTipFont(CFont * pFont);

// Set colors for the tips
CRadialContextMenu &    SetTipColors(COLORREF color1, COLORREF color2, 
                           COLORREF textcolor = ::GetSysColor(COLOR_BTNTEXT));

Having set up the outwardness, one might go on to set up the menu items.

// methods for setting menu items

// Many projects support CFrameWnd or derived window classes that
// own at least one toolbar. To simplify the setup of the radial
// context menu, you might add these toolbars to the menu. You
// don't need to specify an icon then.
CRadialContextMenu &    AddToolBar(CToolBar * pBar);


// Note on CRadialContextMenu::EIconPosition:
// The enumeration describes all possible positions for icons. It starts
// with ICON_TOP und goes clockwise to ICON_TOPRIGHT,
// ICON_RIGHT, ICON_BOTTOMRIGHT and so on.

// Tip texts are always optional. Normally the menu tries to locate
// the tips by browsing the string resources for a string with the
// same ID as given as an argument.

// Use this overload only if you have provided at least one toolbar
// that contains the icons.
CRadialContextMenu &    SetMenuItem(UINT uID, EIconPosition pos, 
                               const CString & tip = "");

// Use this to provide an icon by yourself.
CRadialContextMenu &    SetMenuItem(UINT uID, HICON hIcon, 
                               EIconPosition pos, const CString & tip = "");

// Use this to set a submenu.
CRadialContextMenu &    SetMenuItem(CRadialContextMenu * pSubmenu, 
                               HICON hIcon, EIconPosition pos, 
                               const CString & tip = "");

// You might enable/disable items by either
// the command id or the position in the menu
CRadialContextMenu &    EnableMenuItem(UINT uID, bool bEnable = true);
CRadialContextMenu &    EnableMenuItem(EIconPosition pos, bool bEnable = true);

Now one might call this method.

bool TrackRadialMenu(CWnd * pReceiver);

to pop up the radial context menu. The method won't return unless the user releases the right mouse button or presses the ESC key. The return value indicates whether the user selected a valid item. If it returns true, then a WM_COMMAND message was sent to the window given as the argument.

Thus an exemplary implementation of a WM_RBUTTONDOWN handler might look like this:

void CMyOwnWindow::OnRButtonDown(UINT nFlags, CPoint point)
{
    // In this small example we use standard colors and
    // standard icon size and font.
    CRadialContextMenu()
        .AddToolBar(&m_wndToolbar)
        .SetMenuItem(ID_FILE_NEW, CRadialContextMenu::ICON_TOP)
        .SetMenuItem(ID_FILE_OPEN, CRadialContextMenu::ICON_RIGHT)
        .SetMenuItem(ID_FILE_SAVE, CRadialContextMenu::ICON_BOTTOM)
        .SetMenuItem(ID_FILE_PRINT, CRadialContextMenu::ICON_LEFT)
        .EnableMenuItem(ID_FILE_SAVE, GetDocument()->IsModified())
        .TrackRadialMenu(this);
}

History

  • July, 20 2005 - first implementation.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Joerg Koenig

Germany Germany
No Biography provided

Comments and Discussions

 
Generalcool PinmemberBartosz Wojcik28-Feb-08 6:29 
GeneralPie Menus Pinmemberbmz5-Aug-05 21:40 
GeneralC# Pinmemberdr4cul421-Jul-05 22:27 
GeneralRe: C# PinmemberYves Tkaczyk22-Jul-05 5:06 
GeneralFirst impressions PinmemberNeville Franks21-Jul-05 1:17 
GeneralRe: First impressions PinstaffNishant Sivakumar21-Jul-05 2:47 
GeneralRe: First impressions PinmemberKochise21-Jul-05 3:27 
GeneralRe: First impressions PinmemberJoerg Koenig21-Jul-05 3:30 
GeneralRe: First impressions PinmemberSchniddel21-Jul-05 10:56 
GeneralRe: First impressions PinmemberDieter Hammer21-Jul-05 21:03 
GeneralRe: First impressions PinmemberAndromeda Shun26-Jul-05 22:33 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141220.1 | Last Updated 21 Jul 2005
Article Copyright 2005 by Joerg Koenig
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid