Last modified on 14 May 2012, at 23:21

Aros/Developer/Docs/Libraries/GadTools

Navbar for the Aros wikibook
Aros User Docs
Aros User Docs
Aros User FAQs
Aros User Applications
Aros User DOS Shell
Aros/User/AmigaLegacy
Aros Dev Docs
Aros Developer Docs
Porting Software from AmigaOS/SDL
For Zune Beginners
Zune .MUI Classes
For SDL Beginners
Aros Developer BuildSystem
Specific platforms
68k Support
PPC Power Architecture Support
Arm Raspberry Pi Support
Android support
Linux and FreeBSD Support
Windows Mingw and MacOSX Support
Aros x86 Installing
Aros x86 Audio/Video Support
Aros x86 Network Support
Aros x86 Complete System HCL
Aros Storage Support IDE SATA etc
Aros Poseidon USB Support
x86-64 Support
misc
Aros Public License


IntroductionEdit

  • V34 - OS1.3x Gadtools did not exist
  • V36 - OS2.0x First Introduction
  • V37 - OS2.04 NewLook rendering scheme
  • V39 - OS3.0x NewLook menus added - GT_GetGadgetAttrs() added -
  • V40 - OS3.1x Fixes


Until AmigaOS™ 2.0, there was no unified look and feel design standard — application developers had to write their own objects (buttons, requesters and menus), with Intuition providing minimal support. With AmigaOS™ 2.0 came gadtools.library, which provided standard widget sets, and the Interface Style Guide, which explained how applications could be laid out for consistency to the user.



you should refer to the GadTools Library chapter and Amiga list.

Gadtools is a deprecated interface. Try just using BOOPSI gadgets (much easier to use, too) or MUI Zune instead. BOOPSI is the underpinning for MUI, bgui and Reaction.

GadgetsEdit

Gadget Type Description or Example Usage
Button Familiar action gadgets, such as "OK" or "Cancel".
String For text entry.
Integer For numeric entry.
Checkboxes For on/off items.
Mutually exclusive Radio buttons, select one choice among several.
Cycle Multiple-choice, pick one of a small number of choices.
Sliders To indicate a level within a range.
Scrollers To indicate a position in a list or area.
Listviews Scrolling lists of text.
Palette Color selection.
Text-display Read-only text.
Numeric-display Read-only numbers.



UnderscoreEdit

The underscore character, `_' is the recommended marker-symbol. So, for example, to mark the letter "F" as the keyboard equivalent for a button labelled "Select Font...", create the gadget text:

ng.ng_GadgetText = "Select _Font...";



CreateEdit

http://thomas-rapp.homepage.t-online.de/examples/gadtools.c


ModifyEdit

To change the flags and the pot and body variables after the gadget is displayed, the program can call Intuition's NewModifyProp().

void NewModifyProp( struct Gadget *gadget, struct Window *window, struct Requester *requester, 
                    unsigned long flags, unsigned long horizPot, unsigned long vertPot,
                       unsigned long horizBody, unsigned long vertBody, long numGad );

The gadget's internal state will be recalculated and the imagery will be redisplayed to show the new state. When numGads (in the prototype above) is set to all ones, NewModifyProp() will only update those parts of the imagery that have changed, which is much faster than removing the gadget, changing values, adding the gadget back and refreshing its imagery.

Each kind of GadTools gadget requires one or more of these IDCMP classes: IDCMP_GADGETUP, IDCMP_GADGETDOWN, IDCMP_MOUSEMOVE, IDCMP_MOUSEBUTTONS and IDCMP_INTUITICKS.

programs that use Gadgets always require notification about window refresh events. Even if the application performs no rendering of its own, it may not use the WFLG_NOCAREREFRESH window flag and must always set IDCMP_REFRESHWINDOW.

The attributes of a gadget are set up when the gadget is created. Some of these attributes can be changed later by using the GT_SetGadgetAttrs() function:

   void GT_SetGadgetAttrs (struct Gadget *gad, struct Window *win,
                           struct Requester *req, Tag tag1, ... )
   void GT_SetGadgetAttrsA(struct Gadget *gad, struct Window *win,
                           struct Requester *req, struct TagItem *taglist)



MenusEdit

http://thomas-rapp.homepage.t-online.de/examples/gtmenu.c

To set up GadTools menus

GetVisualInfo() and FreeVisualInfo()    CreateContext() 



ListEdit

http://thomas-rapp.homepage.t-online.de/examples/lv.c

When CreateGadget() is called multiple times (for each gadget), each new gadget is automatically linked to the previous gadget's NextGadget field, thus creating a gadget list. Second, if one of the gadget creations fails (usually due to low memory, but other causes are possible), then for the next call to CreateGadget(), next_gad will be NULL and CreateGadget() will fail immediately. This means that the program can perform several successive calls to CreateGadget() and only have to check for failure at the end.

can not use GadTools scroller gadgets in window borders


StringEdit

Most regular Intuition string gadgets which default to FALSE


ScrollEdit

http://thomas-rapp.homepage.t-online.de/examples/scroll.c http://thomas-rapp.homepage.t-online.de/examples/iconify.c

Get the imagery for the gadgets from BOOPSI by allocating an object containing the appropriate imagery (imageclass) and then using this to draw the graphic into the button.



ReferenceEdit

Some code relies on AOS implementation of gadtools library which uses fake (non-boopsi) gadgets where especially the more complex ones (listview) have most gadget (input) handling done in the GT_GetImsg/GT_FitlerImsg() funcs. In AROS gadtools library uses real boopsi gadgets and therefore behaves differently.


struct Gadget *CreateGadgetA(ULONG kind, struct Gadget *previous, struct NewGadget *ng, struct TagItem *taglist) 
void FreeGadgets(struct Gadget *glist)
void GT_SetGadgetAttrsA(struct Gadget *gad, struct Window *win, struct Requester *req, struct TagItem *tagList) 
struct Menu *CreateMenusA(struct NewMenu *newmenu, struct TagItem *tagList) 
void FreeMenus(struct Menu *menu) 
BOOL LayoutMenuItemsA(struct MenuItem *menuitem, APTR vi, struct TagItem *tagList) 
BOOL LayoutMenusA(struct Menu *menu, APTR vi, struct TagItem *tagList) 
struct IntuiMessage *GT_GetIMsg(struct MsgPort *intuiport) 
void GT_ReplyIMsg(struct IntuiMessage *imsg) 
void GT_RefreshWindow(struct Window *win, struct Requester *req) 
void GT_BeginRefresh(struct Window *win) 
void GT_EndRefresh(struct Window *win, BOOL complete) 
struct IntuiMessage *GT_FilterIMsg(struct IntuiMessage *imsg)
struct IntuiMessage *GT_PostFilterIMsg(struct IntuiMessage *modimsg) 
struct Gadget *CreateContext(struct Gadget **glistpointer) 
void DrawBevelBoxA(struct RastPort *rport, WORD left, WORD top, WORD width, WORD height, struct TagItem *taglist) 
APTR GetVisualInfoA(struct Screen *screen, struct TagItem *tagList) 
void FreeVisualInfo(APTR vi) 

LONG GT_GetGadgetAttrsA(struct Gadget *gad, struct Window *win, struct Requester *req, struct TagItem *taglist) 



The first few items in each option can be altered after being created.

GA_Immediate and GA_RelVerify are tags, GACT_IMMEDIATE and GACT_RELVERIFY are flags used for the Activation field of struct Gadget.


CreateGadgetA Taglists

GT_Underscore - Indicates the symbol that precedes the character in the gadget label to be underscored. This can be to indicate keyboard equivalents for gadgets (note that GadTools does not process the keys - just displays the underscore).


BUTTON_OPTION (action buttons):

GA_Disabled (BOOL) - Set to TRUE to disable gadget, FALSE otherwise (default FALSE). 

GA_Immediate (BOOL) - Hear IDCMP_GADGETDOWN events from button gadget (default FALSE). 


CHECKBOX_OPTION (on/off items):

GA_Disabled (BOOL) - Set to TRUE to disable gadget, FALSE otherwise (default FALSE).
GTCB_Checked (BOOL) - Initial state of checkbox (default FALSE) 

GTCB_Scaled (BOOL) - If true, then checkbox imagery will be scaled to fit the gadget's width & height.  Otherwise, a fixed size of CHECKBOXWIDTH by CHECKBOXHEIGHT will be used. (default FALSE)


CYCLEOPTION (multiple state selections):

GA_Disabled (BOOL) - Set to TRUE to disable gadget, FALSE otherwise (default FALSE). 
GTCY_Labels (STRPTR *) - Pointer to NULL-terminated array of strings that are the choices offered by the cycle gadget. This tag is required. 
GTCY_Active (UWORD) - The ordinal number (counting from zero) of the initially active choice of a cycle gadget (default zero).


INTEGER_OPTION (numeric entry):

GA_Disabled (BOOL) - Set to TRUE to disable gadget, FALSE otherwise (default FALSE). 
GTIN_Number (LONG) - The initial contents of the integer gadget (default 0). 

GA_Immediate (BOOL) - Hear IDCMP_GADGETDOWN events from integer gadget (default FALSE). 
GA_TabCycle (BOOL) - Set to TRUE so that pressing  or will activate the next or previous such gadget. (default TRUE).
GTIN_MaxChars (UWORD) - The maximum number of digits that the integer gadget is to hold (defaults to 10). 
GTIN_EditHook (struct Hook *) - Hook to use as a custom integer gadget edit hook (StringExtend->EditHook) for this gadget. GadTools will allocate the StringExtend->WorkBuffer for you. (default NULL). 
STRINGA_ExitHelp (BOOL) - Set to TRUE to have the help-key cause an exit from the integer gadget.  You will then receive an IDCMP_GADGETUP event with Code = 0x5F (rawkey for help). (default FALSE) 
STRINGA_Justification - Controls the justification of the contents of an integer gadget.  Choose one of STRINGLEFT, STRINGRIGHT, or STRINGCENTER (defaults to STRINGLEFT). 
STRINGA_ReplaceMode (BOOL) - If TRUE, this integer gadget is in replace-mode (default FALSE (insert-mode)). 


LISTVIEW_OPTION (scrolling list):

GA_Disabled (BOOL) - Set to TRUE to disable gadget, FALSE otherwise (default FALSE). 
GTLV_Top (WORD) - Top item visible in the listview.  This value will be made reasonable if out-of-range (default 0). 
GTLV_Labels (struct List *) - List of nodes whose ln_Name fields are to be displayed in the listview. 
GTLV_Selected (UWORD) - Ordinal number of currently selected item, or 0 to have no current selection (default 0).

GTLV_MakeVisible (WORD) - Number of an item that should be forced within the visible area of the listview by doing minimal scrolling. This tag overrides GTLV_Top. 
GTLV_ReadOnly (BOOL) - If TRUE, then listview is read-only (default FALSE). 
GTLV_ScrollWidth (UWORD) - Width of scroll bar for listview. Must be greater than zero (default 16). 
GTLV_ShowSelected (struct Gadget *) - NULL to have the currently selected item displayed beneath the listview under V37 or with a highlight bar in V39. If not NULL, this is a pointer to an already-created GadTools STRING_KIND gadget to have an editable display of the currently selected item. If the tag is not present, the currently selected item will not be displayed. 
LAYOUTA_Spacing (UWORD) - Extra space to place between lines of listview (default 0). 
GTLV_ItemHeight (UWORD) - The exact height of an item. This is normally useful for listviews that use the GTLV_CallBack             rendering hook (defaults to ng->ng_TextAttr->ta_YSize). 
GTLV_CallBack (struct Hook *) - Callback hook for various listview operations. Only callback supported is for custom rendering of individual items in the listview. The call back hook is called with:
                A0 - struct Hook *
                A1 - struct LVDrawMsg *
                A2 - struct Node *
The callback hook *must* check the lvdm_MethodID field of the message and only do processing if it equals LV_DRAW. If any other value is passed, the callback hook must return LVCB_UNKNOWN 
GTLV_MaxPen (UWORD) - The maximum pen number used by rendering in a custom rendering callback hook. This is used to optimize the rendering and scrolling of the listview display (default being the maximum pen number used by all of TEXTPEN, BACKGROUNDPEN, FILLPEN, TEXTFILLPEN, and BLOCKPEN. 


MX_OPTION (mutually exclusive, radio buttons):

GA_Disabled (BOOL) - Set to TRUE to disable gadget, FALSE otherwise (default FALSE).
GTMX_Active (UWORD) - The ordinal number (counting from zero) of the initially active choice of an mx gadget (default 0). 

GTMX_Labels (STRPTR *) - Pointer to a NULL-terminated array of strings which are to be the labels beside each choice in a set of mutually exclusive gadgets. This tag is required 
GTMX_Spacing (UWORD) - The amount of space between each choice of a set of mutually exclusive gadgets.  This amount is added  to the font height to produce the vertical shift between choices (default 1). 
GTMX_Scaled (BOOL) - If true, then mx gadget imagery will be scaled to fit the gadget's width & height.  Otherwise, a fixed size of MXWIDTH by MXHEIGHT will be used. When setting this tag to TRUE, should typically set the height of the gadget to be (ng.ng_TextAttr->ta_YSize + 1). (default FALSE.) 
GTMX_TitlePlace - One of PLACETEXT_LEFT, PLACETEXT_RIGHT, PLACETEXT_ABOVE, or PLACETEXT_BELOW, indicating where the title of the gadget is to be displayed. Without this tag, the NewGadget.ng_GadgetText field is ignored for MX_OPTION gadgets. 

LAYOUTA_Spacing - FOR COMPATIBILITY ONLY.  Use GTMX_Spacing instead. The number of extra pixels to insert between each choice of a mutually exclusive gadget.  This is added to the present gadget image height (9) to produce the true spacing between choices. (default FontHeight-8, which is zero for 8-point font users). 


NUMBER_OPTION (read-only numeric):

GTNM_Number (LONG) - A signed long integer to be displayed as a read-only number (default 0). 

GTNM_Border (BOOL) - If TRUE, this flag asks for a recessed border to be placed around the gadget. 
GTNM_FrontPen (UBYTE) - The pen to use when rendering the number (default DrawInfo->dri_Pens[TEXTPEN]). 
GTNM_BackPen (UBYTE) - The pen to use when rendering the background of the number (defaults to leaving the background untouched). 
GTNM_Justification (UBYTE) - Determines how the number is rendered within the gadget box. GTJ_LEFT will make the rendering be flush with the left side of the gadget, GTJ_RIGHT will make it flush with the right side, and GTJ_CENTER will center the number within the gadget box. (default GTJ_LEFT). 
GTNM_Format (STRPTR) - C-Style formatting string to apply on the number before display. Be sure to use the 'l' (long) modifier. This string is processed using exec.library/RawDoFmt(), so refer to that function for details. (default "%ld") 
GTNM_MaxNumberLen (ULONG) - Maximum number of bytes that can be generated by applying the GTNM_Format formatting string to the number (excluding the NULL terminator). (default 10). 
GTNM_Clipped (BOOL) - Determine whether text should be clipped to the gadget dimensions (defaults to FALSE for gadgets without borders, TRUE for gadgets with borders). 


PALETTE_OPTION (color selection):

GA_Disabled (BOOL) - Set to TRUE to disable gadget, FALSE otherwise (default FALSE). 
GTPA_Color (UBYTE) - Initially selected color of the palette. This number is a pen number, and not the ordinal color number within the palette gadget itself. (default 1). 
GTPA_ColorOffset (UBYTE) - First color to use in palette (default 0).
GTPA_ColorTable (UBYTE *) - Pointer to a table of pen numbers indicating  which colors should be used and edited by the palette gadget. This array must contain as many entries as there are colors displayed in the palette gadget. The array provided with this tag must remain valid for the life of the gadget or until a new table is provided. (default NULL, which causes a 1-to-1 mapping of pen numbers). 

GTPA_Depth (UWORD) - Number of bitplanes in the palette (default 1). 
GTPA_IndicatorWidth (UWORD) - The desired width of the current-color indicator, if you want one to the left of the palette. 
GTPA_IndicatorHeight (UWORD) - The desired height of the current-color indicator, if you want one above the palette. 
GTPA_NumColors (UWORD) - Number of colors to display in the palette gadget. This override GTPA_Depth and allows numbers which are not powers of 2. (default 2) 


SCROLLER_OPTION (for scrolling through areas or lists):

GA_Disabled (BOOL) - Set to TRUE to disable gadget, FALSE otherwise (default FALSE). 
GTSC_Top (WORD) - Top visible in area scroller represents (default 0). 
GTSC_Total (WORD) - Total in area scroller represents (default 0). 
GTSC_Visible (WORD) - Number visible in scroller (default 2). 

GA_RelVerify (BOOL) - Hear every IDCMP_GADGETUP event from scroller (default FALSE). 
GA_Immediate (BOOL) - Hear every IDCMP_GADGETDOWN event from scroller (default FALSE). 
GTSC_Arrows (UWORD) - Asks for arrows to be attached to the scroller. The value supplied will be taken as the width of each arrow button for a horizontal scroller, or the height of each button for a vertical scroller (the other dimension will match the whole scroller). 

PGA_Freedom - Whether scroller is horizontal or vertical. Choose LORIENT_VERT or LORIENT_HORIZ (default LORIENT_HORIZ).


SLIDER_OPTION (to indicate level or intensity):

GA_Disabled (BOOL) - Set to TRUE to disable gadget, FALSE otherwise (default FALSE). 
GTSL_Min (WORD) - Minimum level for slider (default 0).  
GTSL_Max (WORD) - Maximum level for slider (default 15). 
GTSL_Level (WORD) - Current level of slider (default 0). 

GA_RelVerify (BOOL) - If you want to hear each slider IDCMP_GADGETUP event (default FALSE). 
GA_Immediate (BOOL) - If you want to hear each slider IDCMP_GADGETDOWN event (default FALSE). 
GTSL_MaxLevelLen (UWORD) - Maximum length in characters of level string when rendered beside slider (default 2). 
GTSL_LevelFormat (STRPTR) - C-Style formatting string for slider level.  Be sure to use the 'l' (long)  modifier.  This string is processed using exec.library/RawDoFmt(), so refer to that function for details. (default "%ld"). 
GTSL_LevelPlace - One of PLACETEXT_LEFT, PLACETEXT_RIGHT, PLACETEXT_ABOVE, or PLACETEXT_BELOW, indicating where the level indicator is to go relative to slider (default to PLACETEXT_LEFT). 
GTSL_DispFunc ( LONG (*function)(struct Gadget *, WORD) ) - To calculate level to be displayed.  A number-of-colors slider might want to set the slider up to think depth, and have a (1 << n) function here. No Default  Your function must take a pointer to gadget as the first parameter, the level (a WORD) as the second, and return the result as a LONG. 
GTSL_MaxPixelLen (ULONG) - Indicates the maximum pixel size used up by the level display for any value of the slider. This is mostly useful when dealing with proportional fonts. (default FontWidth*MaxLevelLen). 
GTSL_Justification (UBYTE) - Determines how the level display is to be justified within its alotted space. Choose one of GTJ_LEFT, GTJ_RIGHT, or GTJ_CENTER (default GTJ_LEFT). 

PGA_Freedom - Set to LORIENT_VERT or LORIENT_HORIZ to have a vertical or horizontal slider (defaults to LORIENT_HORIZ). 


STRING_OPTION (text-entry):

GA_Disabled (BOOL) - Set to TRUE to disable gadget, FALSE otherwise (default FALSE). 
GTST_String (STRPTR) - The initial contents of the string gadget, or NULL (default) if string is to start empty. 
GA_Immediate (BOOL) - Hear IDCMP_GADGETDOWN events from string gadget (default FALSE). 
GA_TabCycle (BOOL) - Set to TRUE so that pressing  or will activate the next or previous such gadget. (defaults to TRUE, unlike regular Intuition string gadgets which default FALSE).
GTST_MaxChars (UWORD) - The maximum number of characters that the string gadget is to hold. 
GTST_EditHook (struct Hook *) - Hook to use as a custom string gadget edit hook (StringExtend->EditHook) for this gadget. GadTools will allocate the StringExtend->WorkBuffer for you. (default NULL).
STRINGA_ExitHelp (BOOL) - Set to TRUE to have the help-key cause an exit from the string gadget.  You will then receive an IDCMP_GADGETUP event with Code = 0x5F (rawkey for help).
STRINGA_Justification - Controls the justification of the contents of a string gadget.  Choose one of STRINGLEFT, STRINGRIGHT, or STRINGCENTER (default STRINGLEFT). 
STRINGA_ReplaceMode (BOOL) - If TRUE, this string gadget is in replace-mode (defaults to FALSE (insert-mode)). 


TEXT_OPTION (read-only text):

GTTX_Text - Pointer to a NULL terminated string to be displayed, as a read-only text-display gadget, or NULL. (default NULL) 

GTTX_CopyText (BOOL) -  This flag instructs the text-display gadget to copy the supplied text string, instead of using only pointer to the string.  This only works for the initial value of GTTX_Text set at CreateGadget() time.  If you subsequently change GTTX_Text, the new text will be referenced by pointer, not copied.  Do not use this tag with a NULL GTTX_Text. 
GTTX_Border (BOOL) - If TRUE, this flag asks for a recessed border to be placed around the gadget. 
GTTX_FrontPen (UBYTE) - The pen to use when rendering the text (default DrawInfo->dri_Pens[TEXTPEN]). 
GTTX_BackPen (UBYTE) - The pen to use when rendering the background of the text (defaults to leaving the background untouched).
GTTX_Justification (UBYTE) - Determines how the text is rendered within the gadget box. GTJ_LEFT will make the rendering be flush with the left side of the gadget, GTJ_RIGHT will make it flush with the right side, and GTJ_CENTER will center the text within the gadget box. (default GTJ_LEFT).
GTTX_Clipped (BOOL) - Determine whether text should be clipped to the gadget dimensions (defaults to FALSE for gadgets without borders, TRUE for gadgets with borders). 


LayoutGadgetTags

GTMN_Menu (struct Menu *) - Pointer to the Menu structure whose FirstItem is the MenuItem supplied. If the menu items are such that they need to be columnized or shifted, the Menu structure is needed to perform the complete calculation. For the following tags, please see the description under LayoutMenusA().  Their behavior is identical when used in LayoutMenuItemsA(). 
            GTMN_TextAttr
            GTMN_NewLookMenus
            GTMN_Checkmark
            GTMN_AmigaKey
            GTMN_FrontPen



Trying to manually open gadtools in the console code (for menus). I need it to be opened manually, because it *will* fail for the boot shell (see below), so I need to handle the case where it's not available. It seems to me that auto-opening non-resident libraries during boot is a really bad idea... Will lots of stuff break if that's turned off? Alternatively, is there a method to prevent auto-opening on a case by case basis? IIRC you just need to declare the base pointer manually. This will prevent from getting it (and associated library opening code) from libautoinit. With programs it works. I think it works with residents. The autoinit code is linked in by the libbase variable. E.g. the autoinit code defined the global libbase variable of a library. If you define 'struct Library *GadToolsBase' somewhere in your code as a global variable the autoinit code won't be linked in. Please, only use it when really needed and put proper comments why it is needed. The specific case here is avoiding duplicating a bunch of menu-layout code from gadtools in the console code to add menus to the console windows without requiring gadtools to be linked into the kernel. It means the boot shell won't get the menu, but I think that's a fair enough trade off vs. making things really messy.

And it's only called in when global library bases are used at all, which shouldn't be the case with romable code, should it? That's something I didn't think about. Do I mess up stuff if I declare a global GadToolsBase, or are bss properly handled? If it messes things up, are there alternative ways of preventing the auto-opening? (committed a basic menu structure for the console handler that uses a global GadToolsBase).

It's non-optimal, actually, since on m68k the only 'know to always exist' memory for the .bss is in Chip RAM, which is both precious and dog slow (due to contention with video and audio operations). For this usage it's probably fine, but if you can find a way to allocate it in a structure that the console handler passes around (con_base?) and dereference it from there, it's probably a better way to do. AllocMem() memory allocates from the highest priority first. See rom/devs/filesys/AmberRAM/handler.h's 'struct Handler', and the macros that immediately follow it for an example of how to do this. The console handler does already put lots of stuff in it's handler data structure, so if there is a way I can suppress auto-opening without a global variable, it's trivial enough to put it in there.

Is there a good reference somewhere on all the things I need to take care of during a NEWWINDOWSIZE event? You probably know this already, but NEWWINDOWSIZE doesn't block until ReplyMsg() like SIZEVERIFY.


Endian issues

There may be method structs in the code which uses WORD for some of the (coord) fields and then when calling the method it does something like gDoClassMethod(... , (x << 16) | (y & 0xffff), ...). This relies on big endianess and therefore fails on x86.




/* Menus for LiteBench */
 
#ifdef WB_1.3
/* 
 * Workbench 1.3 style menus (obsolete)
 * 
 * Workbench		
 *   Open	
 *   Close
 *   Duplicate
 *   Rename
 *   Info
 *   Discard
 * 
 * Disk
 *   Empty Disk
 *   Initialize
 *
 *  Special
 *    Clean up
 *    Last error
 *    Redraw
 *    Snapshot
 *    Version
*/
struct NewMenu mynewmenu[] =
    {
        { NM_TITLE, "Workbench",          0, 0, 0, 0, },
        {  NM_ITEM,   "Open"              0  0, 0, 0, },
        {  NM_ITEM,   "Close",    	  0, 0, 0, 0, },
        {  NM_ITEM,   "Duplicate",        0, 0, 0, 0, },
        {  NM_ITEM,   "Rename",           0, 0, 0, 0, },
        {  NM_ITEM,   "Info",             0, 0, 0, 0, },
        {  NM_ITEM,   "Discard",          0, 0, 0, 0, },
 
        { NM_TITLE, "Disk",               0, 0, 0, 0, },
        {   NM_ITEM,  "Empty Disk",       0, 0, 0, 0, },
        {   NM_ITEM,  "Initialize",       0, 0, 0, 0, },
 
        { NM_TITLE, "Special",            0, 0, 0, 0, },
        {   NM_ITEM, "Clean Up",          0, 0, 0, 0, },
        {   NM_ITEM, "Last Error"         0, 0, 0, 0, },
        {   NM_ITEM, "Redraw",            0, 0, 0, 0, },
        {   NM_ITEM, "Snapshot",          0, 0, 0, 0, },
        {   NM_ITEM, "Version",           0, 0, 0, 0, },
 
        {   NM_END, NULL,              0, 0, 0, 0, },
    };
 
#endif /* WB_1.3 */
 
#ifdef LITEBENCH
/* simplified menus for a minimal workbench program */
struct NewMenu mynewmenu[] =
    {
        { NM_TITLE, "Icon",          0, 0, 0, 0, },
        {   NM_ITEM, "Open",             "O", 0, 0, 0, },
        {   NM_ITEM, "Copy",             "C", 0, 0, 0, },
        {   NM_ITEM, "Rename...",        "R", 0, 0, 0, },
        {   NM_ITEM, "Information...",   "I", 0, 0, 0, },
        {   NM_ITEM, "Snapshot",         "S", 0, 0, 0, },
        {   NM_ITEM, "Unsnapshot",       "U", 0, 0, 0, },
        {   NM_ITEM, "Leave out",        "L", 0, 0, 0, },
        {   NM_ITEM, "Put away",         "P", 0, 0, 0, },
        {   NM_ITEM, NM_BARLABEL,          0, 0, 0, 0, },
        {   NM_ITEM, "Delete...",          0, 0, 0, 0, },
        {   NM_ITEM, "Format...",          0, 0, 0, 0, },
        {   NM_ITEM, "Empty trash",        0, 0, 0, 0, },   
 
        { NM_TITLE, "Window",             0, 0, 0, 0, },
        {   NM_ITEM,  "New drawer",        "N", 0, 0, 0, },
        {   NM_ITEM,  "Open parent",       "K", 0, 0, 0, },
        {   NM_ITEM,  "Close",               0, 0, 0, 0, },
        {   NM_ITEM,  "Update",              0, 0, 0, 0, }, 
        {   NM_ITEM,  "Select contents",   "A", 0, 0, 0, },
 
        {   NM_ITEM, "Clean up by",        0, 0, 0, 0, },
        {     NM_SUB,   "Column",        ".", 0, 0, 0, },
        {     NM_SUB,   NM_BARLABEL,       0, 0, 0, 0, },
        {     NM_SUB,   "Name",            0, (CHECKIT), 0, 0, },
        {     NM_SUB,   "Date",            0, (CHECKIT), 0, 0, },
        {     NM_SUB,   "Size",            0, (CHECKIT), 0, 0, },
        {     NM_SUB,   "Type",            0, (CHECKIT), 0, 0, },
 
        {   NM_ITEM, "Resize to fit",      0, 0, 0, 0, },
 
        {   NM_ITEM, "Snapshot",           0, 0, 0, 0, },
        {     NM_SUB,  "Window",            0, 0, 0, 0, },
        {     NM_SUB,  "All",               0, 0, 0, 0, },
 
        {   NM_ITEM, "Show",                0, 0, 0, 0, },
        {     NM_SUB, "Only icons",       "-", 0, 0, 0, },
        {     NM_SUB, "All files",        "+", 0, 0, 0, },
 
        {   NM_ITEM, "View by",             0, 0, 0, 0, },
        {     NM_SUB,   "Icon",           "1", 0, 0, 0, },
        {     NM_SUB, NM_BARLABEL,         0 , 0, 0, 0, },
        {     NM_SUB, "Name",             "2", 0, 0, 0, },
        {     NM_SUB, "Date",             "3", 0, 0, 0, },
        {     NM_SUB, "Size",             "4", 0, 0, 0, },
        {     NM_SUB, "Type",             "5", 0, 0, 0, },
 
		{ NM_TITLE, "Special"			0, 0, 0, 0, },
		{   NM_ITEM, "New Shell..."		"W",0,0,0, },
		{   NM_ITEM, "Icon Editor..."   "Y",0,0,0, },
 		{   NM_ITEM, NM_BARLABEL,		  0, 0, 0, 0, },
        {   NM_ITEM, "Quit Litebench", "Q", 0, 0, 0, },  
 
        {   NM_END, NULL,              0, 0, 0, 0, },
    };
 
#endif /* LITEBENCH */
 
#ifdef WB_3.x
/*  Workbench 3.x compatible menu strips, same keyboard shortcuts, etc.
 * *
 *  Workbench
 *  x Backdrop [a]B	 
 *  Enter Command [a]E	 
 *  Redraw all		 
 *  Update all		 
 *  Last Message	
 *  About...		
 *  Quit [a]Q	
 *
 * Window
 *  New drawer [a]N
 *  Open parent [a]K
 *  Close
 *  Update
 *  Select Contents [a]A
 *  Clear selection [a]Z
 *  Clean up by >>
 *                 Column [a]. {period}
 *                 -------------------
 *                 Name
 *                 Date
 *                 Size
 *                 Type
 *  Resize to fit
 *  Snapshot    >>
 *                 Window
 *                 All
 *  Show        >>
 *                 Only icons [a] - {minus}
 *                 All files  [a] + {plus}
 *  View by     >>
 *                 Icon       [a] 1 {one}
 *                 ------------------
 *                 Name       [a] 2 {two}
 *                 Date       [a] 3 {three}
 *                 Size       [a] 4 {four}
 *                 Type       [a] 5 {five}
 *
 * Icons
 *  Open [a]O
 *  Copy [a]C
 *  Rename... [a]R
 *  Information... a[I]
 *  Snapshot [a]S
 *  Unsnapshot [a]U
 *  Leave out [a]L
 *  Put away a[P]
 *  -------------------
 *  Delete....
 *  Format....
 *  Empty Trash
 *
 * Tools
 *   ResetWB
 *
 */
struct NewMenu mynewmenu[] =
    {
        { NM_TITLE, "Workbench",          0, 0, 0, 0, },
        {  NM_ITEM,   "Backdrop",         "B", (CHECKIT|CHECKED), 0, 0, },
        {  NM_ITEM,   "Enter command",    "E", 0, 0, 0, },
        {  NM_ITEM,   "Redraw all",         0, 0, 0, 0, },
        {  NM_ITEM,   "Update all",         0, 0, 0, 0, },
        {  NM_ITEM,   "Last message",       0, 0, 0, 0, },
        {  NM_ITEM,   "About...",           0, 0, 0, 0, },
        {  NM_ITEM,   "Quit",             "Q", 0, 0, 0, },
 
        { NM_TITLE, "Window",             0, 0, 0, 0, },
        {   NM_ITEM,  "New drawer",        "N", 0, 0, 0, },
        {   NM_ITEM,  "Open parent",       "K", 0, 0, 0, },
        {   NM_ITEM,  "Close",               0, 0, 0, 0, },
        {   NM_ITEM,  "Update",              0, 0, 0, 0, }, 
        {   NM_ITEM,  "Select contents",   "A", 0, 0, 0, },
 
        {   NM_ITEM, "Clean up by",        0, 0, 0, 0, },
        {     NM_SUB,   "Column",        ".", 0, 0, 0, },
        {     NM_SUB,   NM_BARLABEL,       0, 0, 0, 0, },
        {     NM_SUB,   "Name",            0, (CHECKIT), 0, 0, },
        {     NM_SUB,   "Date",            0, (CHECKIT), 0, 0, },
        {     NM_SUB,   "Size",            0, (CHECKIT), 0, 0, },
        {     NM_SUB,   "Type",            0, (CHECKIT), 0, 0, },
 
        {   NM_ITEM, "Resize to fit",      0, 0, 0, 0, },
 
        {   NM_ITEM, "Snapshot",           0, 0, 0, 0, },
        {     NM_SUB,  "Window",            0, 0, 0, 0, },
        {     NM_SUB,  "All",               0, 0, 0, 0, },
 
        {   NM_ITEM, "Show",                0, 0, 0, 0, },
        {     NM_SUB, "Only icons",       "-", 0, 0, 0, },
        {     NM_SUB, "All files",        "+", 0, 0, 0, },
 
        {   NM_ITEM, "View by",             0, 0, 0, 0, },
        {     NM_SUB,   "Icon",           "1", 0, 0, 0, },
        {     NM_SUB, NM_BARLABEL,         0 , 0, 0, 0, },
        {     NM_SUB, "Name",             "2", 0, 0, 0, },
        {     NM_SUB, "Date",             "3", 0, 0, 0, },
        {     NM_SUB, "Size",             "4", 0, 0, 0, },
        {     NM_SUB, "Type",             "5", 0, 0, 0, },
 
        {   NM_ITEM, NM_BARLABEL,           0, 0, 0, 0, },
        {   NM_ITEM, "Find...",           "F", 0, 0, 0, },
 
        { NM_TITLE, "Icons",               0, 0, 0, 0, },
        {   NM_ITEM, "Open",             "O", 0, 0, 0, },
        {   NM_ITEM, "Copy",             "C", 0, 0, 0, },
        {   NM_ITEM, "Rename...",        "R", 0, 0, 0, },
        {   NM_ITEM, "Information...",   "I", 0, 0, 0, },
        {   NM_ITEM, "Snapshot",         "S", 0, 0, 0, },
        {   NM_ITEM, "Unsnapshot",       "U", 0, 0, 0, },
        {   NM_ITEM, "Leave out",        "L", 0, 0, 0, },
        {   NM_ITEM, "Put away",         "P", 0, 0, 0, },
        {   NM_ITEM, NM_BARLABEL,          0, 0, 0, 0, },
        {   NM_ITEM, "Delete...",          0, 0, 0, 0, },
        {   NM_ITEM, "Format...",          0, 0, 0, 0, },
        {   NM_ITEM, "Empty trash",        0, 0, 0, 0, },
 
        { NM_TITLE, "Tools",           0, 0, 0, 0, },
        {   NM_ITEM, "ResetWB",        0, 0, 0, 0, },
 
        {   NM_END, NULL,              0, 0, 0, 0, },
    };
#endif /* WB_3.x */
 
#ifdef AROSbench /* enhanced WB_3.x style for AROS */
struct NewMenu mynewmenu[] =
    {
	{ NM_TITLE, "AROSbench",	    0, 0, 0, 0, },
        {  NM_ITEM,   "Backdrop",      "B", (CHECKIT|CHECKED), 0, 0, },
        {  NM_ITEM,   "Enter command",    "E", 0, 0, 0, },
	{  NM_ITEM,   "New Shell",        "W", 0, 0, 0, },
        {  NM_ITEM,   "Redraw all",         0, 0, 0, 0, },
        {  NM_ITEM,   "Update all",         0, 0, 0, 0, },
        {  NM_ITEM,   "Last message",       0, 0, 0, 0, },
        {  NM_ITEM,   "About AROSbench..."  0, 0, 0, 0, },
	{  NM_ITEM,   "Quit AROSbench",	  "Q", 0, 0, 0, },
	{  NM_ITEM,   NM_BARLABEL,          0, 0, 0, 0, },
	{  NM_ITEM,   "Shutdown AROS...",   0, 0, 0, 0, },
 
        { NM_TITLE, "Window",             0, 0, 0, 0, },
        {   NM_ITEM,  "New drawer",     "N", 0, 0, 0, },
        {   NM_ITEM,  "Open parent",    "K", 0, 0, 0, },
        {   NM_ITEM,  "Close",            0, 0, 0, 0, },
        {   NM_ITEM,  "Update",           0, 0, 0, 0, }, 
        {   NM_ITEM,  "Select contents","A", 0, 0, 0, },
 
        {   NM_ITEM, "Clean up by",        0, 0, 0, 0, },
        {     NM_SUB,   "Column",        ".", 0, 0, 0, },
        {     NM_SUB,   NM_BARLABEL,       0, 0, 0, 0, },
        {     NM_SUB,   "Name",            0, (CHECKIT), 0, 0, },
        {     NM_SUB,   "Date",            0, (CHECKIT), 0, 0, },
        {     NM_SUB,   "Size",            0, (CHECKIT), 0, 0, },
        {     NM_SUB,   "Type",            0, (CHECKIT), 0, 0, },
 
        {   NM_ITEM, "Resize to fit",      0, 0, 0, 0, },
 
        {   NM_ITEM, "Snapshot",           0, 0, 0, 0, },
        {     NM_SUB,  "Window",           0, 0, 0, 0, },
        {     NM_SUB,  "All",              0, 0, 0, 0, },
 
        {   NM_ITEM, "Show",                0, 0, 0, 0, },
        {     NM_SUB, "Only icons",       "-", 0, 0, 0, },
        {     NM_SUB, "All files",        "+", 0, 0, 0, },
 
        {   NM_ITEM, "View by",             0, 0, 0, 0, },
        {     NM_SUB, "Icon",             "1", 0, 0, 0, },
        {     NM_SUB, NM_BARLABEL,         0 , 0, 0, 0, },
        {     NM_SUB, "Name",             "2", 0, 0, 0, },
        {     NM_SUB, "Date",             "3", 0, 0, 0, },
        {     NM_SUB, "Size",             "4", 0, 0, 0, },
        {     NM_SUB, "Type",             "5", 0, 0, 0, },
 
        {   NM_ITEM, NM_BARLABEL,           0, 0, 0, 0, },
        {   NM_ITEM, "Find...",           "F", 0, 0, 0, },
 
        { NM_TITLE, "Icons",               0, 0, 0, 0, },
        {   NM_ITEM, "Open",             "O", 0, 0, 0, },
        {   NM_ITEM, "Copy",             "C", 0, 0, 0, },
        {   NM_ITEM, "Rename...",        "R", 0, 0, 0, },
        {   NM_ITEM, "Information...",   "I", 0, 0, 0, },
        {   NM_ITEM, "Snapshot",         "S", 0, 0, 0, },
        {   NM_ITEM, "Unsnapshot",       "U", 0, 0, 0, },
        {   NM_ITEM, "Leave out",        "L", 0, 0, 0, },
        {   NM_ITEM, "Put away",         "P", 0, 0, 0, },
        {   NM_ITEM, NM_BARLABEL,          0, 0, 0, 0, },
        {   NM_ITEM, "Delete...",          0, 0, 0, 0, },
        {   NM_ITEM, "Format...",          0, 0, 0, 0, },
        {   NM_ITEM, "Empty trash",        0, 0, 0, 0, },
 
	{ NM_TITLE, "QuickAccess",	   0, 0, 0, 0, },
	{   NM_ITEM,  "WBstartup files",   0, 0, 0, 0, },
	{   NM_ITEM,  "System preferences",  0, 0, 0, 0, },
	{   NM_ITEM,  "System scripts",    0, 0, 0, 0, },
	{   NM_ITEM,  "System tools",      0, 0, 0, 0, },
	{   NM_ITEM,  "System utilities" , 0, 0, 0, 0, },
	{   NM_ITEM,  "System fonts", 	   0, 0, 0, 0, },
	{   NM_ITEM,  "System deficons",   0, 0, 0, 0, },
	{   NM_ITEM,  "System temporary files",   0, 0, 0, 0, },
	{   NM_ITEM,  "Trashcan", 	   0, 0, 0, 0, },
 
 
        { NM_TITLE, "Tools",           0, 0, 0, 0, },
        {   NM_END, NULL,              0, 0, 0, 0, },
    };
 
 
#endif /* AROSbench */



/* gadtoolsmenu.c*/
 
#define INTUI_V36_NAMES_ONLY
 
#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <libraries/gadtools.h>
 
#include <proto/exec.h>
#include <proto/gadtools.h>
#include <proto/intuition.h>
 
#include <stdio.h>
 
struct Library *GadToolsBase;
struct IntuitionBase *IntuitionBase;
 
struct NewMenu mynewmenu[] =
    {
        { NM_TITLE, "Project",    0 , 0, 0, 0,},
        {  NM_ITEM, "Open...",   "O", 0, 0, 0,},
        {  NM_ITEM, "Save",      "S", 0, 0, 0,},
        {  NM_ITEM, NM_BARLABEL,  0 , 0, 0, 0,},
        {  NM_ITEM, "Print",      0 , 0, 0, 0,},
        {   NM_SUB, "Draft",      0 , 0, 0, 0,},
        {   NM_SUB, "NLQ",        0 , 0, 0, 0,},
        {  NM_ITEM, NM_BARLABEL,  0 , 0, 0, 0,},
        {  NM_ITEM, "Quit...",   "Q", 0, 0, 0,},
 
        { NM_TITLE, "Edit",       0 , 0, 0, 0,},
        {  NM_ITEM, "Cut",       "X", 0, 0, 0,},
        {  NM_ITEM, "Copy",      "C", 0, 0, 0,},
        {  NM_ITEM, "Paste",     "V", 0, 0, 0,},
        {  NM_ITEM, NM_BARLABEL,  0 , 0, 0, 0,},
        {  NM_ITEM, "Undo",      "Z", 0, 0, 0,},
 
        {   NM_END, NULL,         0 , 0, 0, 0,},
    };
 
 
/* Watch the menus and wait for the user to select the close gadget or quit from the menus. */
VOID handle_window_events(struct Window *win, struct Menu *menuStrip)
{
struct IntuiMessage *msg;
SHORT done;
UWORD menuNumber;
UWORD menuNum;
UWORD itemNum;
UWORD subNum;
struct MenuItem *item;
 
done = FALSE;
while (FALSE == done)
    {
    /* we only have one signal bit, so we do not have to check which
    ** bit broke the Wait().
    */
    Wait(1L << win->UserPort->mp_SigBit);
 
    while ( (FALSE == done) &&
            (NULL != (msg = (struct IntuiMessage *)GetMsg(win->UserPort))))
        {
        switch (msg->Class)
            {
            case IDCMP_CLOSEWINDOW:
                done = TRUE;
                break;
            case IDCMP_MENUPICK:
                menuNumber = msg->Code;
                while ((menuNumber != MENUNULL) && (!done))
                    {
                    item = ItemAddress(menuStrip, menuNumber);
 
                    /* process the item here! */
                    menuNum = MENUNUM(menuNumber);
                    itemNum = ITEMNUM(menuNumber);
                    subNum  = SUBNUM(menuNumber);
 
                    /* stop if quit is selected. */
                    if ((menuNum == 0) && (itemNum == 5))
                        done = TRUE;
 
                    menuNumber = item->NextSelect;
                    }
                break;
            }
        ReplyMsg((struct Message *)msg);
        }
    }
}
 
 
/*
** Open all of the required libraries and set-up the menus.
*/
VOID main(int argc, char *argv[])
{
struct Window *win;
APTR *my_VisualInfo;
struct Menu *menuStrip;
 
/* Open the Intuition Library */
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37);
if (IntuitionBase != NULL)
    {
    /* Open the gadtools Library */
    GadToolsBase = OpenLibrary("gadtools.library", 37);
    if (GadToolsBase != NULL)
        {
        if (NULL != (win = OpenWindowTags(NULL,
                            WA_Width,  400,       WA_Activate,    TRUE,
                            WA_Height, 100,       WA_CloseGadget, TRUE,
                            WA_Title,  "Menu Test Window",
                            WA_IDCMP,  IDCMP_CLOSEWINDOW | IDCMP_MENUPICK,
                            TAG_END)))
            {
            if (NULL != (my_VisualInfo = GetVisualInfo(win->WScreen, TAG_END)))
                {
                if (NULL != (menuStrip = CreateMenus(mynewmenu, TAG_END)))
                    {
                    if (LayoutMenus(menuStrip, my_VisualInfo, TAG_END))
                        {
                        if (SetMenuStrip(win, menuStrip))
                            {
                            handle_window_events(win,menuStrip);
 
                            ClearMenuStrip(win);
                            }
                        FreeMenus(menuStrip);
                        }
                    }
                FreeVisualInfo(my_VisualInfo);
                }
            CloseWindow(win);
            }
        CloseLibrary((struct Library *)GadToolsBase);
        }
    CloseLibrary((struct Library *)IntuitionBase);
    }
}