Programming AmigaOS in C

Reaction Window

a) Creating a reaction menu

Reaction programs can be extended with a set of menus. For AmigaOS 3.x you can use the standard NewMenu structures with your Reaction window. In AmigaOS 4.x you also have PopUpMenus (which are menus opened in the app, rather than the top of the screen).

A NewMenu structure is configured as follows, from the gadtools header file:

struct NewMenu
{
   UBYTE nm_Type;               /* See below */
   /* Compiler inserts a PAD byte here */
   STRPTR nm_Label;             /* Menu's label */
   STRPTR nm_CommKey;     /* MenuItem Command Key Equiv */
   UWORD nm_Flags;             /* Menu or MenuItem flags (see note) */
   LONG nm_MutualExclude;  /* MenuItem MutualExclude word */
   APTR nm_UserData;           /* For your own use, see note */
};

A menu's type can be NM_TITLE (title of menu), NM_ITEM (an item on the menu) or NM_SUB (a sublevel menu item).
A menu label is the text or name of the menu title or item e.g. New, Open, Save, Settings etc. A label can also be set to NM_BARLABEL to create a seperator bar.
A menu Commkey is the keyboard equivalent of the menu item e.g. Amiga+O could be Open.
A menu's flags can be set to state whether they are disabled or enabled, checked, or toggled.
MutualExclude attribute on a menu, is a binary mask to exclude items from other menu items eg. 1,2,4,8,16 etc
Menu UserData is for custom user use otherwise set it to NULL or 0.

Here is an example of one menu taken from a Reaction example program. Multiple menus and submenus can be defined within the same NewMenu structure.

struct NewMenu mynewmenu[] =
{
   { NM_TITLE, "Project ", 0, 0, 0, 0},
   { NM_ITEM, "New", 0, 0, 0, 0},
   { NM_ITEM, "Open", "O", 0, 0, 0},
   { NM_ITEM, NM_BARLABEL, 0, 0, 0, 0},
   { NM_ITEM, "Save", "S", 0, 0, 0},
   { NM_ITEM, "Save as...", 0, 0, 0, 0},
   { NM_ITEM, NM_BARLABEL, 0, 0, 0, 0},
   { NM_ITEM, "About...", "?", 0, 0, 0},
   { NM_ITEM, NM_BARLABEL, 0, 0, 0, 0},
   { NM_ITEM, "Quit...", "Q", 0, 0, 0}
};

This is one menu called Project with 6 menu items, seperated by three seperator bars. Three menu items have keyboard shortcuts to them (O, S, Q).

b) Adding the menu to the program window.

In a program using the Intuition and Gadtools libraries, you would normally use the CreateMenu function to create a menu for a given window. In recent versions of Reaction you can attach a menu to a Reaction window using the WINDOW_NewMemu attribute and specify the name of the NewMenu structure. For example,

myWindow = WindowObject,
WA_ScreenTitle, "Reaction Example",
WA_Title, "Menus",
WA_DragBar, TRUE,
WA_CloseGadget, TRUE,
WA_SizeGadget, TRUE,
WA_DepthGadget, TRUE,
WA_Activate, TRUE,
WA_InnerWidth, 150,
WA_NewLookMenus, TRUE,
WINDOW_NewMenu, mynewmenu;

When the RA_OpenWindow command is run, the window is opened and the menus along with it.

c) Handling the menu selection from the user.

To determine which menu was chosen in the program, you need to check for the WMHI_MENUPICK message and then which menu item was selected. For example,

GetAttr(WINDOW_SigMask, win, &sigmask);
while (!done)
{
   siggot = Wait(sigmask | SIGBREAKF_CTRL_C);
   if (siggot & SIGBREAKF_CTRL_C) done = TRUE;
   while ((result = RA_HandleInput(win, &code)))
   {
       switch(result & WMHI_CLASSMASK)
      {
         case WMHI_MENUPICK:        /* Test to see if a menu is seelcted */
         menuStrip = window->MenuStrip;    /* Get address of which menu selected */
         selection = code;
         while ((selection != MENUNULL) && (done == FALSE))
         {
            item = ItemAddress(menuStrip, selection); /* Get the menu item from the menu */
            done = processMenus(selection, done); /* Call a subroutine to process the item */
            selection = item->NextSelect;
          }
         break;
       }
    }
}

3D Graphics