2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: GadTools menu creation functions
9 /**************************************************************************************************/
14 #include <proto/exec.h>
15 #include <exec/types.h>
16 #include <exec/libraries.h>
17 #include <exec/memory.h>
18 #include <proto/intuition.h>
19 #include <proto/utility.h>
20 #include <intuition/intuition.h>
21 #include <intuition/classusr.h>
22 #include <intuition/imageclass.h>
23 #include <intuition/screens.h>
24 #include <intuition/icclass.h>
25 #include <proto/utility.h>
26 #include <utility/tagitem.h>
27 #include <libraries/gadtools.h>
31 #include <aros/debug.h>
33 #include "gadtools_intern.h"
35 /**************************************************************************************************/
37 #define CHECKMARK_TEXT_SPACING 2
38 #define MENU_COLUMN_SPACING 8 /* when items must be arranged in 2 or more columns to fit on screen */
39 #define AMIGAKEY_KEY_SPACING 4 /* we guess that Intuition uses the same value */
40 #define TEXT_AMIGAKEY_SPACING 20
42 #define ITEXT_EXTRA_LEFT 2
43 #define ITEXT_EXTRA_RIGHT 2
44 #define ITEXT_EXTRA_TOP 1
45 #define ITEXT_EXTRA_BOTTOM 1
47 #define IMAGE_EXTRA_LEFT 1
48 #define IMAGE_EXTRA_RIGHT 1
49 #define IMAGE_EXTRA_TOP 1
50 #define IMAGE_EXTRA_BOTTOM 1
52 /**************************************************************************************************/
54 BOOL
is_menubarlabelclass_image(struct Image
*im
, struct GadToolsBase_intern
*GadToolsBase
)
56 BOOL is_barlabel
= FALSE
;
58 DEBUG_FREEMENUS(bug("is_menubarlabelclass_image: im %p\n", im
));
62 DEBUG_FREEMENUS(bug("is_menubarlabelclass_image: depth %ld\n", im
->Depth
));
63 if (im
->Depth
== CUSTOMIMAGEDEPTH
)
67 DEBUG_FREEMENUS(bug("is_menubarlabelclass_image: boopsi\n"));
71 DEBUG_FREEMENUS(bug("is_menubarlabelclass_image: cl %p\n",cl
));
75 DEBUG_FREEMENUS(bug("is_menubarlabelclass_image: ID %p\n",cl
->cl_ID
));
78 if (strcmp(cl
->cl_ID
, MENUBARLABELCLASS
) == 0)
80 DEBUG_FREEMENUS(bug("is_menubarlabelclass_image: barlabel\n"));
91 /**************************************************************************************************/
93 void appendmenu(struct Menu
* firstmenu
,
94 struct Menu
* lastmenu
)
96 while (NULL
!= firstmenu
->NextMenu
)
97 firstmenu
= firstmenu
->NextMenu
;
99 firstmenu
->NextMenu
= lastmenu
;
102 /**************************************************************************************************/
104 void appenditem(struct Menu
* curmenu
,
105 struct MenuItem
* item
)
107 struct MenuItem
* mi
= curmenu
->FirstItem
;
110 curmenu
->FirstItem
= item
;
113 while (NULL
!= mi
->NextItem
)
120 /**************************************************************************************************/
122 void appendsubitem(struct MenuItem
* curitem
,
123 struct MenuItem
* cursubitem
)
125 struct MenuItem
*mi
= curitem
->SubItem
;
128 curitem
->SubItem
= cursubitem
;
131 while (NULL
!= mi
->NextItem
)
134 mi
->NextItem
= cursubitem
;
138 /**************************************************************************************************/
141 struct Menu
* makemenutitle(struct NewMenu
* newmenu
,
142 UBYTE
**MyMenuMemPtr
,
143 struct TagItem
* taglist
)
145 struct Menu
* menu
= NULL
;
148 p
=(ULONG
*) *MyMenuMemPtr
;
149 memset(p
,0,sizeof(ULONG
)+sizeof(struct Menu
)+sizeof(APTR
));
150 *MyMenuMemPtr
+= sizeof(ULONG
)+sizeof(struct Menu
)+sizeof(APTR
);
153 menu
= (struct Menu
*)(p
+ 1);
154 menu
->Flags
= (newmenu
->nm_Flags
& NM_MENUDISABLED
) ^ MENUENABLED
;
155 menu
->MenuName
= newmenu
->nm_Label
;
156 GTMENU_USERDATA(menu
) = newmenu
->nm_UserData
;
161 ULONG
getmenutitlesize(struct NewMenu
* newmenu
,
162 struct TagItem
* taglist
)
164 return(sizeof(ULONG
)+sizeof(struct Menu
)+sizeof(APTR
));
168 struct Menu
* makemenutitle(struct NewMenu
* newmenu
,
169 struct TagItem
* taglist
)
171 struct Menu
* menu
= NULL
;
174 p
= (ULONG
*)AllocMem(sizeof(ULONG
)+sizeof(struct Menu
)+sizeof(APTR
), MEMF_CLEAR
);
179 menu
= (struct Menu
*)(p
+ 1);
180 menu
->Flags
= (newmenu
->nm_Flags
& NM_MENUDISABLED
) ^ MENUENABLED
;
181 menu
->MenuName
= newmenu
->nm_Label
;
182 GTMENU_USERDATA(menu
) = newmenu
->nm_UserData
;
189 /**************************************************************************************************/
191 struct MenuItem
* makemenuitem(struct NewMenu
* newmenu
,
192 UBYTE
**MyMenuMemPtr
,
193 struct Image
***MyBarTablePtr
,
195 struct TagItem
* taglist
,
196 struct GadToolsBase_intern
* GadToolsBase
)
198 struct MenuItem
* menuitem
= NULL
;
202 /* Note: 2 IntuiTexts must be alloced, because CreateMenusA can depend on it
203 if a subitem mark (">>") must be added */
205 if (newmenu
->nm_Label
== NM_BARLABEL
) is_image
= TRUE
;
207 allocsize
= sizeof(ULONG
) + sizeof(struct MenuItem
) + sizeof(APTR
);
208 if (!is_image
) allocsize
+= sizeof(struct IntuiText
) * 2; /* for text + (commandstring OR ">>") */
210 p
=(ULONG
*) *MyMenuMemPtr
;
211 memset(p
,0,allocsize
);
212 *MyMenuMemPtr
+= allocsize
;
215 menuitem
= (struct MenuItem
*)(p
+ 1);
217 DEBUG_ALLOCMENUS(bug("makemenuitem: MenuItem %p\n",menuitem
));
218 menuitem
->Flags
= (newmenu
->nm_Flags
& (NM_ITEMDISABLED
| CHECKIT
| MENUTOGGLE
| CHECKED
)) ^
221 menuitem
->Flags
|= HIGHCOMP
;
223 if (newmenu
->nm_CommKey
)
225 if (!(newmenu
->nm_Flags
& NM_COMMANDSTRING
))
227 menuitem
->Flags
|= COMMSEQ
;
228 menuitem
->Command
= newmenu
->nm_CommKey
[0];
232 menuitem
->MutualExclude
= newmenu
->nm_MutualExclude
;
233 GTMENUITEM_USERDATA(menuitem
) = newmenu
->nm_UserData
;
235 if (FALSE
== is_image
)
240 struct IntuiText
* it
= (struct IntuiText
*)(((UBYTE
*)menuitem
) +
241 sizeof(struct MenuItem
) +
244 DEBUG_ALLOCMENUS(bug("makemenuitem: Text MenuItem\n"));
245 menuitem
->ItemFill
= (APTR
)it
;
247 it
->FrontPen
= GetTagData(GTMN_FrontPen
, 0, taglist
);
250 it
->IText
= newmenu
->nm_Label
;
251 DEBUG_ALLOCMENUS(bug("makemenuitem: FillName <%s>\n",it
->IText
));
253 menuitem
->Flags
|= ITEMTEXT
;
255 if (newmenu
->nm_CommKey
&& (newmenu
->nm_Flags
& NM_COMMANDSTRING
))
257 struct IntuiText
*it2
= it
+ 1;
260 it2
->IText
= newmenu
->nm_CommKey
;
264 } /* if (FALSE == is_image) */
267 DEBUG_ALLOCMENUS(bug("makemenuitem: Image MenuItem\n"));
268 menuitem
->Flags
&= ~ITEMTEXT
;
270 if (newmenu
->nm_Label
!= NM_BARLABEL
)
275 menuitem
->ItemFill
= (APTR
)newmenu
->nm_Label
;
276 DEBUG_ALLOCMENUS(bug("makemenuitem: FillImage 0x%lx\n",menuitem
->ItemFill
));
284 struct TagItem barlabel_tags
[] =
286 {IA_Left
, ITEXT_EXTRA_LEFT
},
293 menuitem
->Flags
&= ~ITEMENABLED
;
295 menuitem
->ItemFill
= NewObjectA(NULL
, MENUBARLABELCLASS
, barlabel_tags
);
297 DEBUG_ALLOCMENUS(bug("makemenuitem: BarImage 0x%lx\n",menuitem
->ItemFill
));
299 if (!menuitem
->ItemFill
)
301 DEBUG_ALLOCMENUS(bug("makemenuitem: barimage failed\n"));
304 DEBUG_ALLOCMENUS(bug("makemenuitem: BarTablePtr 0x%lx\n",*MyBarTablePtr
));
306 * Here we put the new Image to the array the BarTablePtr points to
307 * and then inc the BarTablePtr to the next empty Array slot
309 **MyBarTablePtr
= menuitem
->ItemFill
;
311 * Attention..the () is *required*
321 ULONG
getmenuitemsize(struct NewMenu
* newmenu
,
323 struct TagItem
* taglist
,
324 struct GadToolsBase_intern
* GadToolsBase
)
328 if (newmenu
->nm_Label
== NM_BARLABEL
) is_image
= TRUE
;
330 allocsize
= sizeof(ULONG
) + sizeof(struct MenuItem
) + sizeof(APTR
);
331 if (!is_image
) allocsize
+= sizeof(struct IntuiText
) * 2; /* for text + (commandstring OR ">>") */
333 DEBUG_ALLOCMENUS(bug("getmenuitemsize: allocsize %ld\n",allocsize
));
338 struct MenuItem
* makemenuitem(struct NewMenu
* newmenu
,
340 struct TagItem
* taglist
,
341 struct GadToolsBase_intern
* GadToolsBase
)
343 struct MenuItem
* menuitem
= NULL
;
347 /* Note: 2 IntuiTexts must be alloced, because CreateMenusA can depend on it
348 if a subitem mark (">>") must be added */
350 if (newmenu
->nm_Label
== NM_BARLABEL
) is_image
= TRUE
;
352 allocsize
= sizeof(ULONG
) + sizeof(struct MenuItem
) + sizeof(APTR
);
353 if (!is_image
) allocsize
+= sizeof(struct IntuiText
) * 2; /* for text + (commandstring OR ">>") */
355 p
= (ULONG
*)AllocMem(allocsize
, MEMF_CLEAR
);
360 menuitem
= (struct MenuItem
*)(p
+ 1);
362 DEBUG_ALLOCMENUS(bug("makemenuitem: MenuItem %p\n",menuitem
));
363 menuitem
->Flags
= (newmenu
->nm_Flags
& (NM_ITEMDISABLED
| CHECKIT
| MENUTOGGLE
| CHECKED
)) ^
366 menuitem
->Flags
|= HIGHCOMP
;
368 if (newmenu
->nm_CommKey
)
370 if (!(newmenu
->nm_Flags
& NM_COMMANDSTRING
))
372 menuitem
->Flags
|= COMMSEQ
;
373 menuitem
->Command
= newmenu
->nm_CommKey
[0];
377 menuitem
->MutualExclude
= newmenu
->nm_MutualExclude
;
378 GTMENUITEM_USERDATA(menuitem
) = newmenu
->nm_UserData
;
380 if (FALSE
== is_image
)
385 struct IntuiText
* it
= (struct IntuiText
*)(((UBYTE
*)menuitem
) +
386 sizeof(struct MenuItem
) +
389 DEBUG_ALLOCMENUS(bug("makemenuitem: Text MenuItem\n"));
390 menuitem
->ItemFill
= (APTR
)it
;
392 it
->FrontPen
= GetTagData(GTMN_FrontPen
, 0, taglist
);
395 it
->IText
= newmenu
->nm_Label
;
396 DEBUG_ALLOCMENUS(bug("makemenuitem: FillName <%s>\n",it
->IText
));
398 menuitem
->Flags
|= ITEMTEXT
;
400 if (newmenu
->nm_CommKey
&& (newmenu
->nm_Flags
& NM_COMMANDSTRING
))
402 struct IntuiText
*it2
= it
+ 1;
405 it2
->IText
= newmenu
->nm_CommKey
;
409 } /* if (FALSE == is_image) */
412 DEBUG_ALLOCMENUS(bug("makemenuitem: Image MenuItem\n"));
413 menuitem
->Flags
&= ~ITEMTEXT
;
415 if (newmenu
->nm_Label
!= NM_BARLABEL
)
420 menuitem
->ItemFill
= (APTR
)newmenu
->nm_Label
;
421 DEBUG_ALLOCMENUS(bug("makemenuitem: FillImage 0x%lx\n",menuitem
->ItemFill
));
429 struct TagItem barlabel_tags
[] =
431 {IA_Left
, ITEXT_EXTRA_LEFT
},
438 menuitem
->Flags
&= ~ITEMENABLED
;
440 menuitem
->ItemFill
= NewObjectA(NULL
, MENUBARLABELCLASS
, barlabel_tags
);
442 DEBUG_ALLOCMENUS(bug("makemenuitem: BarImage 0x%lx\n",menuitem
->ItemFill
));
444 if (!menuitem
->ItemFill
)
446 DEBUG_ALLOCMENUS(bug("makemenuitem: barimage failed\n"));
454 } /* if (NULL != menuitem) */
460 /**************************************************************************************************/
463 static void freeitem(struct MenuItem
*item
, struct GadToolsBase_intern
* GadToolsBase
)
465 ULONG
* p
= (ULONG
*)item
- 1;
467 DEBUG_FREEMENUS(bug("FreeItem: item %p\n", item
));
469 DEBUG_FREEMENUS(bug("FreeItem: NextItem %p\n", item
->NextItem
));
470 DEBUG_FREEMENUS(bug("FreeItem: Left %ld Top %ld Width %ld Height %ld\n", item
->LeftEdge
,item
->TopEdge
,item
->Width
,item
->Height
));
471 DEBUG_FREEMENUS(bug("FreeItem: Flags 0x%lx ItemFill 0x%lx SelectFill 0x%lx\n", item
->Flags
,item
->ItemFill
,item
->SelectFill
));
472 DEBUG_FREEMENUS(bug("FreeItem: Command %lc SubItem 0x%lx NextSelect 0x%lx\n", item
->Command
,item
->SubItem
,item
->NextSelect
));
474 if (!(item
->Flags
& ITEMTEXT
))
476 struct Image
*im
= (struct Image
*)item
->ItemFill
;
478 DEBUG_FREEMENUS(bug("FreeItem: free image\n"));
479 if (is_menubarlabelclass_image(im
, GadToolsBase
))
481 DEBUG_FREEMENUS(bug("FreeItem: menubarimage %p\n",im
));
487 struct IntuiText
*MyText
=(struct IntuiText
*) item
->ItemFill
;
488 struct IntuiText
*MyText2
=(struct IntuiText
*) item
->SelectFill
;
491 DEBUG_FREEMENUS(bug("FreeItem: FillName <%s>\n",MyText
->IText
));
495 DEBUG_FREEMENUS(bug("FreeItem: SelectName <%s>\n",MyText2
->IText
));
499 DEBUG_FREEMENUS(bug("FreeItem: freeitem %p size %ld\n", p
,*p
));
502 DEBUG_FREEMENUS(bug("FreeItem: done\n"));
505 /**************************************************************************************************/
507 void freeitems(struct MenuItem
* mi
, struct GadToolsBase_intern
* GadToolsBase
)
509 DEBUG_FREEMENUS(bug("FreeItems: MenuItem %p\n",mi
));
512 struct MenuItem
* _mi
= mi
->NextItem
, *si
= mi
->SubItem
;
514 DEBUG_FREEMENUS(bug("FreeItems: CurrentItem %p NextItem %p\n",mi
,_mi
));
516 DEBUG_FREEMENUS(bug("FreeItems: free SubItems\n"));
519 struct MenuItem
* _si
= si
->NextItem
;
521 DEBUG_FREEMENUS(bug("FreeItems: Current SubItem %p Next SubItem %p\n",si
,_si
));
523 freeitem(si
, GadToolsBase
);
527 DEBUG_FREEMENUS(bug("FreeItems: free MenuItem %p\n",mi
));
529 freeitem(mi
, GadToolsBase
);
533 DEBUG_FREEMENUS(bug("FreeItems: done\n"));
536 /**************************************************************************************************/
538 static WORD
MyIntuiTextLength(struct VisualInfo
*vi
, struct IntuiText
*it
,
539 struct GadToolsBase_intern
* GadToolsBase
)
545 struct IntuiText
*it_next
= it
->NextText
;
548 width
= IntuiTextLength(it
);
549 it
->NextText
= it_next
;
554 width
= TextLength(&vi
->vi_screen
->RastPort
, it
->IText
, strlen(it
->IText
));
560 /**************************************************************************************************/
562 static ULONG
EqualizeItems(struct MenuItem
*firstitem
, struct MenuItem
*lastitem
,
563 struct Image
*amikeyimage
, struct VisualInfo
*vi
,
564 struct GadToolsBase_intern
* GadToolsBase
)
566 struct MenuItem
*item
;
567 struct TextExtent te
;
568 WORD minx
= 0, maxwidth
= 0, maxrightstuffwidth
= 0;
570 if (!firstitem
) return 0;
572 /* Calc. the max. width of item text/image (+ checkmark image)
573 Calc. the min. item->LeftEdge */
575 for(item
= firstitem
; item
&& (item
!= lastitem
); item
= item
->NextItem
)
577 if (item
->LeftEdge
< minx
) minx
= item
->LeftEdge
;
578 if (item
->Width
> maxwidth
) maxwidth
= item
->Width
;
581 /* Calc. the max. width of AmigaKey/CommandString/">>" */
583 FontExtent(vi
->vi_dri
->dri_Font
, &te
);
585 for(item
= firstitem
; item
&& (item
!= lastitem
); item
= item
->NextItem
)
589 if (item
->Flags
& COMMSEQ
)
593 if (item
->Flags
& ITEMTEXT
)
595 struct TextFont
*font
;
596 struct IntuiText
*it
= (struct IntuiText
*)item
->ItemFill
;
600 if ((font
= OpenFont(it
->ITextFont
)))
604 FontExtent(font
, &e
);
612 width
+= amikeyimage
->Width
+
613 AMIGAKEY_KEY_SPACING
;
616 else if (item
->Flags
& ITEMTEXT
)
618 struct IntuiText
*it
= (struct IntuiText
*)item
->ItemFill
;
619 struct IntuiText
*it2
;
621 if ((it2
= it
->NextText
))
623 it2
->FrontPen
= it
->FrontPen
;
624 it2
->BackPen
= it
->BackPen
;
625 it2
->DrawMode
= it
->DrawMode
;
626 it2
->TopEdge
= it
->TopEdge
;
628 /* save width also in it->LeftEdge. Will be used below to
631 width
= it2
->LeftEdge
= MyIntuiTextLength(vi
, it2
, GadToolsBase
);
635 if (width
> maxrightstuffwidth
) maxrightstuffwidth
= width
;
637 } /* for(item = firstitem; item; item = item->NextItem) */
639 /* Calc. x coordinate of command strings and ">>"'s and submenu pos. */
641 if (maxrightstuffwidth
)
643 maxwidth
+= maxrightstuffwidth
+ TEXT_AMIGAKEY_SPACING
;
645 for(item
= firstitem
; item
&& (item
!= lastitem
); item
= item
->NextItem
)
647 struct MenuItem
*subitem
;
649 if (item
->Flags
& ITEMTEXT
)
651 struct IntuiText
*it
= (struct IntuiText
*)item
->ItemFill
;
653 if ((it
= it
->NextText
))
655 /* it->LeftEdge contains the pixel width. see above */
657 it
->LeftEdge
= minx
+ maxwidth
- it
->LeftEdge
- ITEXT_EXTRA_RIGHT
;
661 for(subitem
= item
->SubItem
; subitem
; subitem
= subitem
->NextItem
)
663 subitem
->LeftEdge
+= (maxwidth
- maxrightstuffwidth
);
667 } /* if (maxrightstuffwidth) */
669 /* Make all items have the same width and set also the width and the
670 drawinfo of barlabel images */
672 for(item
= firstitem
; item
&& (item
!= lastitem
); item
= item
->NextItem
)
674 item
->Width
= maxwidth
;
676 if(!(item
->Flags
& ITEMTEXT
))
678 struct Image
*im
= (struct Image
*)item
->ItemFill
;
680 if (is_menubarlabelclass_image(im
, GadToolsBase
))
682 struct TagItem image_tags
[] =
684 {IA_Width
, maxwidth
- ITEXT_EXTRA_LEFT
- ITEXT_EXTRA_RIGHT
},
685 {SYSIA_DrawInfo
, (IPTR
)vi
->vi_dri
},
689 SetAttrsA(im
, image_tags
);
695 return (ULONG
)maxwidth
;
698 /**************************************************************************************************/
700 BOOL
layoutmenuitems(struct MenuItem
* firstitem
,
701 struct VisualInfo
* vi
,
702 struct TagItem
* taglist
,
703 struct GadToolsBase_intern
* GadToolsBase
)
706 struct MenuItem
* menuitem
= firstitem
;
707 struct MenuItem
* equalizeitem
= firstitem
;
708 struct Image
* amikeyimage
, * chkimage
;
709 struct TextExtent te
;
714 amikeyimage
= (struct Image
*)GetTagData(GTMN_AmigaKey
, 0, taglist
);
715 if (!amikeyimage
) amikeyimage
= vi
->vi_dri
->dri_AmigaKey
;
717 chkimage
= (struct Image
*)GetTagData(GTMN_Checkmark
, 0, taglist
);
718 if (!chkimage
) chkimage
= vi
->vi_dri
->dri_CheckMark
;
720 FontExtent(vi
->vi_dri
->dri_Font
, &te
);
722 while (NULL
!= menuitem
)
727 menuitem
->LeftEdge
= curX
;
728 menuitem
->TopEdge
= curY
;
730 if (0 != (menuitem
->Flags
& CHECKIT
))
733 ** A checkmark will appear on the left.
736 addleft
+= chkimage
->Width
+ CHECKMARK_TEXT_SPACING
;
737 addwidth
+= chkimage
->Width
+ CHECKMARK_TEXT_SPACING
;
740 if (0 != (menuitem
->Flags
& ITEMTEXT
))
745 struct IntuiText
* it
= (struct IntuiText
*)menuitem
->ItemFill
;
751 if (NULL
!= (ti
= FindTagItem(GTMN_FrontPen
, taglist
)))
753 it
->FrontPen
= ti
->ti_Data
;
757 it
->FrontPen
= vi
->vi_dri
->dri_Pens
[BARDETAILPEN
];
760 it
->ITextFont
= (struct TextAttr
*)GetTagData(GTMN_TextAttr
,
764 it
->LeftEdge
= ITEXT_EXTRA_LEFT
+ addleft
;
765 it
->TopEdge
= ITEXT_EXTRA_TOP
;
767 menuitem
->Width
= MyIntuiTextLength(vi
, it
, GadToolsBase
) +
768 addwidth
+ ITEXT_EXTRA_LEFT
+ ITEXT_EXTRA_RIGHT
;
771 ** Calculate the height menu item.
773 if (NULL
== it
->ITextFont
)
776 ** No font is provided, so I will work with the screen font.
778 menuitem
->Height
= vi
->vi_dri
->dri_Font
->tf_YSize
+ ITEXT_EXTRA_TOP
+ ITEXT_EXTRA_BOTTOM
;
782 struct TextFont
* font
;
784 if (NULL
!= (font
= OpenFont(it
->ITextFont
)))
786 menuitem
->Height
= font
->tf_YSize
+ ITEXT_EXTRA_TOP
+ ITEXT_EXTRA_BOTTOM
;
793 } /* if (0 != (menuitem->Flags & ITEMTEXT)) */
799 struct Image
* im
= (struct Image
*)menuitem
->ItemFill
;
801 if (NULL
== im
) return FALSE
;
803 if (is_menubarlabelclass_image(im
, GadToolsBase
))
805 menuitem
->Width
= 10;
806 menuitem
->Height
= 7;
812 menuitem
->Width
= im
->Width
+ addwidth
+ IMAGE_EXTRA_LEFT
+ IMAGE_EXTRA_RIGHT
;
813 menuitem
->Height
= im
->Height
+ IMAGE_EXTRA_TOP
+ IMAGE_EXTRA_BOTTOM
;
814 im
->LeftEdge
= IMAGE_EXTRA_LEFT
+ addleft
;
815 im
->TopEdge
= IMAGE_EXTRA_TOP
;
818 } /* if (0 != (menuitem->Flags & ITEMTEXT)) else ... */
820 curY
+= menuitem
->Height
;
823 ** In case this menu becomes too high it will have more columns.
826 if (curY
> vi
->vi_screen
->Height
)
830 width
= EqualizeItems(equalizeitem
, menuitem
, amikeyimage
, vi
, GadToolsBase
);
831 equalizeitem
= menuitem
;
834 curX
+= width
+ MENU_COLUMN_SPACING
;
835 menuitem
->LeftEdge
= curX
;
836 menuitem
->TopEdge
= curY
;
838 curY
+= menuitem
->Height
;
844 ** Process the next menu item
846 menuitem
= menuitem
->NextItem
;
848 } /* while (NULL != menuitem) */
850 EqualizeItems(equalizeitem
, NULL
, amikeyimage
, vi
, GadToolsBase
);
852 menu
= (struct Menu
*)GetTagData(GTMN_Menu
, 0, taglist
);
853 if (menu
&& (menu
->FirstItem
== firstitem
))
855 /* Make sure the menu box is at least as large as the menu title,
856 otherwise it looks ugly */
858 WORD menuwidth
, minx
, maxx
, titlewidth
, prevy
= -1, col
= 1;
863 for(menuitem
= firstitem
; menuitem
; menuitem
= menuitem
->NextItem
)
865 if (menuitem
->LeftEdge
< minx
) minx
= menuitem
->LeftEdge
;
866 if (menuitem
->LeftEdge
+ menuitem
->Width
- 1 > maxx
) maxx
= menuitem
->LeftEdge
+ menuitem
->Width
- 1;
869 menuwidth
= maxx
- minx
+ 1;
870 titlewidth
= TextLength(&vi
->vi_screen
->RastPort
, menu
->MenuName
, strlen(menu
->MenuName
));
872 if (titlewidth
> menuwidth
)
874 WORD extrawidth
= (titlewidth
- menuwidth
+ numcolumns
/ 2) / numcolumns
;
876 for(menuitem
= firstitem
; menuitem
; menuitem
= menuitem
->NextItem
)
878 struct MenuItem
*subitem
;
880 if (menuitem
->TopEdge
< prevy
) col
++;
881 prevy
= menuitem
->TopEdge
;
883 menuitem
->LeftEdge
+= (col
- 1) * extrawidth
;
884 menuitem
->Width
+= extrawidth
;
886 if (menuitem
->Flags
& ITEMTEXT
)
888 struct IntuiText
*it
= (struct IntuiText
*)menuitem
->ItemFill
;
890 if ((it
= it
->NextText
))
892 it
->LeftEdge
+= extrawidth
;
897 struct Image
*im
= (struct Image
*)menuitem
->ItemFill
;
899 if (is_menubarlabelclass_image(im
, GadToolsBase
))
901 im
->Width
+= extrawidth
;
905 if ((subitem
= menuitem
->SubItem
))
909 subitem
->LeftEdge
+= extrawidth
;
910 subitem
= subitem
->NextItem
;
914 } /* for(menuitem = firstitem; menuitem; menuitem = menuitem->NextItem) */
916 } /* if (titlewidth > menuwidth) */
918 } /* if (menu && (menu->FirstItem == firstitem)) */
924 /**************************************************************************************************/
926 BOOL
layoutsubitems(struct MenuItem
* motheritem
,
927 struct VisualInfo
* vi
,
928 struct TagItem
* taglist
,
929 struct GadToolsBase_intern
* GadToolsBase
)
931 struct MenuItem
* menuitem
= motheritem
->SubItem
;
933 layoutmenuitems(menuitem
, vi
, taglist
, GadToolsBase
);
938 /**************************************************************************************************/