C for Yourself - part 27

Steve Mumford continues to explain the emerging WIMP C library.

In the original WIMP C example, menus were created with a particularly cumbersome brute-force function that was hardwired for the purpose. All the menu flags were converted into integers and specified as constants within the code - if I'd wanted to place a tick by a menu item, or grey one out, it would have required a great deal of tinkering in the sourcecode with the reference manuals on standby. Obviously, this isn't the sort of situation we should be aiming for, and I've attempted to rectify this in the Acorn User WIMP C library.

At present, AULib provides four functions for dealing with menu creation and display au_buildmenu, au_addtomenu, au_createmenu and au_openmenu. Two structure types, menu_data and menu_element, are also defined in the header file - these provide data containers for storing information about the menu header as well as the individual menu elements below it.

If you have access to the Programmer's Reference Manuals, you might like to take a look at the range of flags that the user must specify in order to create a menu. As well as the menu-specific options, including width, colour and entry spacing, each menu element must have a whole host of icon flags too. I spent several hours in a state of bewilderment, trying to discover why my menu options weren't being displayed. Eventually, I realised they were; I'd just neglected to set their text colour to something other than white.

Having kicked myself a couple of times, I decided that the best approach would be to build a shell round the menu creation procedure, allowing the user to specify the basic information and allowing the routines to fill in all the standard options themselves.

The first function, au_buildmenu, takes an array of characters and a pointer to a structure of type menu_data as its arguments - this sets up the appropriate menu header in the structure, using the supplied string as the title, which must be eleven characters or less in length. For instance:

menu_data globmen;
au_buildmenu("Test menu", &globmen);

Once this has been done, menu elements can be added; the memory for these is allocated automatically and they're tacked on to the end of the original structure as a linked list. The function that deals with this is au_addtomenu and it takes five arguments:

au_addtomenu("Entry 1", MENU_TICK | MENU_DOTTED, -1, 0, &globmen);
au_addtomenu("Quit", MENU_LASTITEM, -1, 0, &globmen);

The first parameter is the text of the menu entry, again eleven characters or less, followed by three integers and a pointer to a menu structure to hold the information. In order, the integers specify the menu flags to use, a pointer to a menu or window data block to display as a submenu (-1 if you don't want a sub-menu), and any extra icon flags you might require.

Various values have been set up using #define in AULib.h, and MENU_TICK and MENU_DOTTED allow you to tick an item or place a menu separator below one respectively.

In order to inform the WIMP that you've reached the end of your menu, you must tag the last element with the MENU_LASTITEM flag. Finally, if you want to grey out a menu option, you can add the MENU_SHADED flag to the icon flags parameter. Once you've built up your menu, you have to instruct AULib to compile it into a datablock that the WIMP can understand, using the au_createmenu function - this just takes a pointer to the structure that holds the menu details:


Once this has been done, you're ready to open the menu using au_openmenu - its three arguments are a pointer to the appropriate menu structure, and two integers giving the x and y coordinates of the top left-hand corner of the menu.

In order to be as useful as possible, a menu creation routine should allow the user to do several things - it should be possible to create menus dynamically, permitting them to be context sensitive (for instance, the Filer menu displays the filename of the icon the mouse was clicked over).

The user should also be able to edit a defined menu easily so that the items within can be ticked or greyed out without having to rebuild the menu from scratch. Although the current routines in the library go some way to providing this functionality, there's still space for a few improvements - for instance, the data in the menus can't be indirected at the moment, limiting th length of the text strings. We'll tackle this next time - see you then.

Source: Acorn User - 171 - August 1996
Publication: Acorn User
Contributor: Steve Mumford