Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / libs / muimaster / menu.c
blob184372ae47e1a54908b0df19128ee07f5121f881
1 /*
2 Copyright © 2002, The AROS Development Team.
3 All rights reserved.
5 $Id$
6 */
8 #include <string.h>
10 #include <graphics/gfxmacros.h>
11 #include <intuition/imageclass.h>
12 #include <clib/alib_protos.h>
13 #include <proto/exec.h>
14 #include <proto/intuition.h>
15 #include <proto/gadtools.h>
16 #include <proto/graphics.h>
17 #include <proto/layers.h>
19 #include "muimaster_intern.h"
21 extern struct Library *MUIMasterBase;
23 /**************************************************************************
24 The following stuff is taken from AROS's intuition. Maybe if this go to
25 the public somewhere we don't need this in the AROS version
26 **************************************************************************/
28 #define min(a,b) (((a) < (b)) ? (a) : (b))
29 #define max(a,b) (((a) > (b)) ? (a) : (b))
31 void GetMenuBox(struct Window *win, struct MenuItem *item,
32 WORD *xmin, WORD *ymin, WORD *xmax, WORD *ymax)
35 WORD left, right, top, bottom;
37 left = top = 0x7fff;
38 right = bottom = -0x7fff;
40 while(item != NULL)
42 left = min(left, item->LeftEdge);
43 top = min(top, item->TopEdge);
44 right = max(right, item->LeftEdge + item->Width - 1);
45 bottom = max(bottom, item->TopEdge + item->Height - 1);
47 item = item->NextItem;
50 if (xmin) *xmin = left - win->WScreen->MenuHBorder;
51 if (ymin) *ymin = top - win->WScreen->MenuVBorder;
52 if (xmax) *xmax = right + win->WScreen->MenuHBorder;
53 if (ymax) *ymax = bottom + win->WScreen->MenuVBorder;
57 void CalculateDims(struct Window *win, struct Menu *menu)
59 struct MenuItem *item;
61 while(menu != NULL)
63 item = menu->FirstItem;
65 GetMenuBox(win, item, &menu->JazzX, &menu->JazzY, &menu->BeatX, &menu->BeatY);
67 menu = menu->NextMenu;
71 /* Mark items that has subitems. This is necessary for the input handler
72 code. It's not possible to check item->SubItem within it as we save
73 the layer coordinates there. */
74 void Characterize(struct Menu *menu)
76 while(menu != NULL)
78 struct MenuItem *item;
80 item = menu->FirstItem;
82 while(item != NULL)
84 // if(item->SubItem != NULL)
85 // item->Flags |= HASSUBITEM;
87 item = item->NextItem;
90 menu = menu->NextMenu;
94 #define MENUS_UNDERMOUSE 1
95 #define MENUS_AMIGALOOK 1
97 /** BEGIN AROS **/
99 #define ITEM_ITEM 1
100 #define ITEM_SUBITEM 2
102 #define AMIGAKEY_KEY_SPACING 4 /* GadTools assumes this, too */
103 #define AMIGAKEY_BORDER_SPACING 2
105 struct MenuHandlerData
107 struct Window *win;
108 struct Screen *scr;
109 struct DrawInfo *dri;
110 struct Window *menubarwin;
111 struct Window *menuwin;
112 struct Window *submenuwin;
113 struct Menu *menu;
114 struct Menu *activemenu;
115 struct MenuItem *activeitem;
116 struct MenuItem *activesubitem;
117 struct Rectangle submenubox;
118 struct Image *checkmark;
119 struct Image *amigakey;
120 WORD menubarwidth;
121 WORD menubarheight;
122 WORD menubaritemwidth;
123 WORD menubaritemheight;
124 WORD nummenubaritems;
125 WORD activemenunum;
126 WORD activeitemnum;
127 WORD activesubitemnum;
128 WORD maxcommkeywidth_menu;
129 WORD maxcommkeywidth_submenu;
130 WORD scrmousex;
131 WORD scrmousey;
132 UWORD firstmenupick;
133 UWORD lastmenupick;
134 BOOL active;
137 /* this #defines are taken from workbench/libs/gadtools/menus.c!! */
139 #define TEXT_AMIGAKEY_SPACING 6
141 #define ITEXT_EXTRA_LEFT 2
142 #define ITEXT_EXTRA_RIGHT 2
143 #define ITEXT_EXTRA_TOP 1
144 #define ITEXT_EXTRA_BOTTOM 1
146 static const char subitemindicator[] = "»";
148 /**************************************************************************************************/
150 static void HandleMouseMove(struct MenuHandlerData *mhd);
151 static void HandleMouseClick(struct MenuHandlerData *mhd, int menuup);
152 static void HandleCheckItem(struct Window *win, struct MenuItem *item, WORD itemnum,
153 struct MenuHandlerData *mhd);
155 static void HighlightMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd);
157 static struct Menu *FindMenu(WORD *var, struct MenuHandlerData *mhd);
158 static struct MenuItem *FindItem(WORD *var, struct MenuHandlerData *mhd);
159 static struct MenuItem *FindSubItem(WORD *var, struct MenuHandlerData *mhd);
161 static void MakeMenuBarWin(struct MenuHandlerData *mhd);
162 static void KillMenuBarWin(struct MenuHandlerData *mhd);
163 static void RenderMenuBar(struct MenuHandlerData *mhd);
165 static void MakeMenuWin(struct MenuHandlerData *mhd);
166 static void KillMenuWin(struct MenuHandlerData *mhd);
167 static void RenderMenu(struct MenuHandlerData *mhd);
168 static void RenderMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd);
170 static void MakeSubMenuWin(struct MenuHandlerData *mhd);
171 static void KillSubMenuWin(struct MenuHandlerData *mhd);
172 static void RenderSubMenu(struct MenuHandlerData *mhd);
174 static void RenderItem(struct MenuItem *item, WORD itemtype, struct Rectangle *box,
175 struct MenuHandlerData *mhd);
177 static void RenderMenuBG(struct Window *win, struct MenuHandlerData *mhd);
178 static void RenderCheckMark(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd);
179 static void RenderAmigaKey(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd);
180 static void RenderDisabledPattern(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2,
181 struct MenuHandlerData *mhd);
182 #if 0
183 static void RenderFrame(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2, WORD state,
184 struct MenuHandlerData *mhd);
185 #endif
186 static void HighlightItem(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd);
187 static WORD CalcMaxCommKeyWidth(struct Window *win, struct MenuHandlerData *mhd);
188 static void AddToSelection(struct MenuHandlerData *mhd);
191 /**************************************************************************************************/
193 static void HandleMouseMove(struct MenuHandlerData *mhd)
195 struct Layer *lay;
196 struct Window *win = NULL;
197 struct Menu *menu;
198 struct MenuItem *item;
200 WORD new_activemenunum = mhd->activemenunum;
201 WORD new_activeitemnum = mhd->activeitemnum;
202 WORD new_activesubitemnum = mhd->activesubitemnum;
204 mhd->scrmousex = mhd->scr->MouseX;
205 mhd->scrmousey = mhd->scr->MouseY;
207 if ((lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey)))
209 win = (struct Window *)lay->Window;
211 if (win && (win == mhd->submenuwin))
213 /* Mouse over submenu box */
214 item = FindSubItem(&new_activesubitemnum, mhd);
216 if (new_activesubitemnum != mhd->activesubitemnum)
218 if (mhd->activesubitemnum != -1)
220 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd);
223 mhd->activesubitemnum = new_activesubitemnum;
224 mhd->activesubitem = item;
226 if (item)
228 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd);
233 else if (win && (win == mhd->menuwin))
235 item = FindItem(&new_activeitemnum, mhd);
237 if (new_activeitemnum != mhd->activeitemnum)
239 if (mhd->activeitemnum != -1)
241 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd);
242 KillSubMenuWin(mhd);
245 mhd->activeitemnum = new_activeitemnum;
246 mhd->activeitem = item;
248 if (item)
250 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd);
252 if (item->SubItem)
254 MakeSubMenuWin(mhd);
258 } /* if (win && (win == mhd->menuwin)) */
259 else if (win && (win == mhd->menubarwin))
261 /* Mouse over menu box */
263 menu = FindMenu(&new_activemenunum, mhd);
265 if (new_activemenunum != mhd->activemenunum)
267 if (mhd->activemenunum != -1)
269 HighlightMenuTitle(mhd->activemenu, mhd);
270 KillMenuWin(mhd);
271 KillSubMenuWin(mhd);
274 mhd->activemenunum = new_activemenunum;
275 mhd->activemenu = menu;
277 if (menu)
279 HighlightMenuTitle(mhd->activemenu, mhd);
280 MakeMenuWin(mhd);
284 if ((mhd->activeitemnum != -1) && (!mhd->submenuwin))
286 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd);
287 mhd->activeitemnum = -1;
288 mhd->activeitem = NULL;
291 } /* if (win && (win == mhd->menubarwin)) */
292 else
294 win = NULL;
296 } /* if ((lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey))) */
298 if (!win)
300 /* mouse outside any menu window */
302 if ((mhd->activeitemnum != -1) && (!mhd->submenuwin))
304 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd);
305 mhd->activeitemnum = -1;
306 mhd->activeitem = NULL;
308 else if (mhd->activesubitemnum != -1)
310 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd);
311 mhd->activesubitemnum = -1;
312 mhd->activesubitem = NULL;
318 /**************************************************************************************************/
320 static void HandleMouseClick(struct MenuHandlerData *mhd, int menuup)
322 struct Layer *lay;
324 if ((lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey)))
326 struct Window *win = (struct Window *)lay->Window;
327 struct MenuItem *item = NULL;
328 WORD itemnum;
330 win = (struct Window *)lay->Window;
332 if (win && (win == mhd->submenuwin) && (mhd->activesubitemnum != -1))
334 item = mhd->activesubitem;
336 else if (win && (win == mhd->menuwin) && (mhd->activeitemnum != -1))
338 item = mhd->activeitem;
341 if (item) if (item->Flags & CHECKIT)
343 HandleCheckItem(win, item, itemnum, mhd);
346 AddToSelection(mhd);
347 } /* if ((lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey))) */
350 /**************************************************************************************************/
352 static void HandleCheckItem(struct Window *win, struct MenuItem *item, WORD itemnum,
353 struct MenuHandlerData *mhd)
355 /* Note: If you change something here, you probably must also change
356 menus.c/CheckMenuItemWasClicked() which is used when the
357 user uses the menu key shortcuts! */
359 WORD itemtype = ((win == mhd->menuwin) ? ITEM_ITEM : ITEM_SUBITEM);
361 BOOL re_render = FALSE;
363 if (item->Flags & MENUTOGGLE)
365 item->Flags ^= CHECKED;
366 re_render = TRUE;
368 else
370 if (!(item->Flags & CHECKED))
372 item->Flags |= CHECKED;
373 re_render = TRUE;
377 if (re_render)
379 BOOL toggle_hi = FALSE;
381 if ((item->Flags & HIGHITEM) &&
382 ((item->Flags & HIGHFLAGS) == HIGHCOMP)) toggle_hi = TRUE;
384 if (toggle_hi) HighlightItem(item, itemtype, mhd);
385 RenderCheckMark(item, itemtype, mhd);
386 if (toggle_hi) HighlightItem(item, itemtype, mhd);
390 if (item->MutualExclude)
392 struct MenuItem *checkitem = (itemtype == ITEM_ITEM) ? mhd->activemenu->FirstItem :
393 mhd->activeitem->SubItem;
394 BOOL toggle_hi = FALSE;
395 WORD i;
397 if ((item->Flags & HIGHITEM) &&
398 ((item->Flags & HIGHFLAGS) == HIGHBOX)) toggle_hi = TRUE;
400 if (toggle_hi) HighlightItem(item, itemtype, mhd);
402 for(i = 0; (i < 32) && checkitem; i++, checkitem = checkitem->NextItem)
404 if ((i != itemnum) && (item->MutualExclude & (1L << i)) &&
405 ((checkitem->Flags & (CHECKED | CHECKIT)) == (CHECKIT | CHECKED)))
407 checkitem->Flags &= ~CHECKED;
408 RenderCheckMark(checkitem, itemtype, mhd);
412 if (toggle_hi) HighlightItem(item, itemtype, mhd);
414 } /* if (item->MutualExclude) */
417 /**************************************************************************************************/
419 static void HighlightMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd)
421 if (menu->Flags & MENUENABLED)
423 struct RastPort *rp = mhd->menubarwin->RPort;
425 #if MENUS_UNDERMOUSE
426 struct Menu *m = mhd->menu;
427 WORD x1 = mhd->scr->MenuHBorder;
428 WORD x2 = x1 + mhd->menubaritemwidth - 1;
429 WORD y1, y2, i;
431 for(i = 0; m != menu; m = m->NextMenu) i++;
433 y1 = mhd->scr->MenuVBorder + i * mhd->menubaritemheight;
434 y2 = y1 + mhd->menubaritemheight - 1;
436 #else
437 WORD x1 = menu->LeftEdge + mhd->scr->BarHBorder - mhd->scr->MenuHBorder;
438 WORD y1 = 0;
439 WORD x2 = x1 + menu->Width - 1;
440 WORD y2 = mhd->scr->BarHeight - 1;
441 #endif
443 #if MENUS_AMIGALOOK
444 SetDrMd(rp, COMPLEMENT);
445 RectFill(rp, x1, y1, x2, y2);
446 #else
447 menu->Flags ^= HIGHITEM;
449 #if !MENUS_UNDERMOUSE
450 y1++;
451 #endif
453 SetDrMd(rp, JAM1);
454 SetAPen(rp, mhd->dri->dri_Pens[(menu->Flags & HIGHITEM) ? FILLPEN : BACKGROUNDPEN]);
455 RectFill(rp, x1, y1, x2, y2);
457 RenderMenuTitle(menu, mhd);
459 if (menu->Flags & HIGHITEM)
461 #if MENUS_UNDERMOUSE
462 RenderFrame(rp, x1, y1, x2, y2, IDS_SELECTED, mhd);
463 #else
464 SetAPen(rp, mhd->dri->dri_Pens[SHINEPEN]);
465 RectFill(rp, x1, y1, x1, y2);
466 SetAPen(rp, mhd->dri->dri_Pens[SHADOWPEN]);
467 RectFill(rp, x2, y1, x2, y2);
468 #endif
472 #endif/* MENUS_AMIGALOOK */
476 /**************************************************************************************************/
478 static struct Menu *FindMenu(WORD *var, struct MenuHandlerData *mhd)
480 struct Menu *menu;
481 WORD mouse_x, mouse_y, i;
483 mouse_x = mhd->scrmousex - mhd->menubarwin->LeftEdge;
484 mouse_y = mhd->scrmousey - mhd->menubarwin->TopEdge;
486 #if MENUS_UNDERMOUSE
487 menu = NULL;
489 mouse_x -= mhd->scr->MenuHBorder;
490 mouse_y -= mhd->scr->MenuVBorder;
492 if ((mouse_x >= 0) && (mouse_x < mhd->menubaritemwidth) && (mouse_y >= 0))
494 i = mouse_y / mhd->menubaritemheight;
496 if ((i >= 0) && (i < mhd->nummenubaritems))
498 WORD i2 = i;
500 menu = mhd->menu;
501 while(i && menu)
503 i--; menu = menu->NextMenu;
506 if (menu && (i == 0))
508 *var = i2;
512 #else
513 for(menu = mhd->menu, i = 0; menu; menu = menu->NextMenu, i++)
515 if ((mouse_x >= menu->LeftEdge) &&
516 (mouse_x < menu->LeftEdge + menu->Width) &&
517 (mouse_y >= 0) &&
518 (mouse_y <= mhd->scr->BarHeight))
520 *var = i;
521 break;
524 #endif
526 return menu;
529 /**************************************************************************************************/
531 static struct MenuItem *FindItem(WORD *var, struct MenuHandlerData *mhd)
533 struct MenuItem *item = NULL;
534 WORD mouse_x, mouse_y, i;
536 if (mhd->menuwin)
538 mouse_x = mhd->scrmousex - mhd->menuwin->LeftEdge + mhd->activemenu->JazzX;
539 mouse_y = mhd->scrmousey - mhd->menuwin->TopEdge + mhd->activemenu->JazzY;
541 for(item = mhd->activemenu->FirstItem, i = 0; item; item = item->NextItem, i++)
543 if ((mouse_x >= item->LeftEdge) &&
544 (mouse_x < item->LeftEdge + item->Width) &&
545 (mouse_y >= item->TopEdge) &&
546 (mouse_y < item->TopEdge + item->Height))
548 *var = i;
549 break;
552 } /* if (mhd->menuwin) */
554 if ((item == NULL) && !mhd->submenuwin) *var = -1;
556 return item;
559 /**************************************************************************************************/
561 static struct MenuItem *FindSubItem(WORD *var, struct MenuHandlerData *mhd)
563 struct MenuItem *item = NULL;
564 WORD mouse_x, mouse_y, i;
566 if (mhd->submenuwin)
568 mouse_x = mhd->scrmousex - mhd->submenuwin->LeftEdge + mhd->submenubox.MinX;
569 mouse_y = mhd->scrmousey - mhd->submenuwin->TopEdge + mhd->submenubox.MinY;
571 *var = -1;
573 for(item = mhd->activeitem->SubItem, i = 0; item; item = item->NextItem, i++)
575 if ((mouse_x >= item->LeftEdge) &&
576 (mouse_x < item->LeftEdge + item->Width) &&
577 (mouse_y >= item->TopEdge) &&
578 (mouse_y < item->TopEdge + item->Height))
580 *var = i;
581 break;
585 } /* if (mhd->menuwin) */
587 return item;
590 /**************************************************************************************************/
592 static void MakeMenuBarWin(struct MenuHandlerData *mhd)
594 struct TagItem win_tags[9];
595 struct Menu *menu;
597 #if MENUS_UNDERMOUSE
598 struct RastPort *temprp;
599 WORD w, maxw = 0;
600 #endif
602 win_tags[0].ti_Tag = WA_Left;
603 win_tags[0].ti_Data = 0;
604 win_tags[1].ti_Tag = WA_Top;
605 win_tags[1].ti_Data = 0;
606 win_tags[2].ti_Tag = WA_Width;
607 win_tags[2].ti_Data = mhd->scr->Width;
608 win_tags[3].ti_Tag = WA_Height;
609 win_tags[3].ti_Data = mhd->scr->BarHeight + 1;
610 win_tags[4].ti_Tag = WA_AutoAdjust;
611 win_tags[4].ti_Data = TRUE;
612 win_tags[5].ti_Tag = WA_Borderless;
613 win_tags[5].ti_Data = TRUE;
614 win_tags[6].ti_Tag = WA_CustomScreen;
615 win_tags[6].ti_Data = (ULONG)mhd->scr;
616 win_tags[7].ti_Tag = WA_BackFill;
617 win_tags[7].ti_Tag = (IPTR)LAYERS_NOBACKFILL;
618 win_tags[8].ti_Tag = TAG_DONE;
620 #if MENUS_UNDERMOUSE
622 if (!(temprp = CloneRastPort(&mhd->scr->RastPort))) return;
624 mhd->nummenubaritems = 0;
625 for(menu = mhd->menu; menu; menu = menu->NextMenu)
627 w = TextLength(temprp, menu->MenuName, strlen(menu->MenuName));
628 if (w > maxw) maxw = w;
629 mhd->nummenubaritems++;
632 mhd->menubaritemwidth = maxw + TextLength(temprp, subitemindicator, 1) +
633 TEXT_AMIGAKEY_SPACING +
634 ITEXT_EXTRA_LEFT +
635 ITEXT_EXTRA_RIGHT;
637 mhd->menubaritemheight = temprp->TxHeight + ITEXT_EXTRA_TOP + ITEXT_EXTRA_BOTTOM;
639 win_tags[2].ti_Data = mhd->menubaritemwidth + mhd->scr->MenuHBorder * 2;
640 win_tags[3].ti_Data = mhd->menubaritemheight * mhd->nummenubaritems + mhd->scr->MenuVBorder * 2;
641 win_tags[0].ti_Data = mhd->scr->MouseX - win_tags[2].ti_Data / 2;
642 win_tags[1].ti_Data = mhd->scr->MouseY;
644 FreeRastPort(temprp);
646 #endif
648 mhd->menubarwin = OpenWindowTagList(0, win_tags);
650 for(menu = mhd->menu; menu; menu = menu->NextMenu)
652 menu->Flags &= ~HIGHITEM;
655 RenderMenuBar(mhd);
658 /**************************************************************************************************/
660 static void KillMenuBarWin(struct MenuHandlerData *mhd)
662 if (mhd->menubarwin)
664 CloseWindow(mhd->menubarwin);
665 mhd->menubarwin = NULL;
669 /**************************************************************************************************/
671 static void RenderMenuBar(struct MenuHandlerData *mhd)
673 if (mhd->menubarwin)
675 struct Menu *menu = mhd->menu;
676 struct RastPort *rp = mhd->menubarwin->RPort;
678 SetFont(rp, mhd->dri->dri_Font);
680 #if MENUS_UNDERMOUSE
682 RenderMenuBG(mhd->menubarwin, mhd);
684 #else
686 #if MENUS_AMIGALOOK
687 SetABPenDrMd(rp, mhd->dri->dri_Pens[BARBLOCKPEN], 0, JAM1);
688 #else
689 SetABPenDrMd(rp, mhd->dri->dri_Pens[BACKGROUNDPEN], 0, JAM1);
690 #endif
691 RectFill(rp, 0, 0, mhd->menubarwin->Width - 1, mhd->menubarwin->Height - 2);
692 SetAPen(rp, mhd->dri->dri_Pens[BARTRIMPEN]);
693 RectFill(rp, 0, mhd->menubarwin->Height - 1, mhd->menubarwin->Width - 1, mhd->menubarwin->Height - 1);
695 #if !MENUS_AMIGALOOK
696 SetAPen(rp, mhd->dri->dri_Pens[SHINEPEN]);
697 RectFill(rp, 0, 0, 0, mhd->menubarwin->Height - 2);
698 RectFill(rp, 1, 0, mhd->menubarwin->Width - 1, 0);
699 SetAPen(rp, mhd->dri->dri_Pens[SHADOWPEN]);
700 RectFill(rp, mhd->menubarwin->Width - 1, 1, mhd->menubarwin->Width - 1, mhd->menubarwin->Height - 2);
702 #endif
704 #endif
706 for(; menu; menu = menu->NextMenu)
708 RenderMenuTitle(menu, mhd);
713 /**************************************************************************************************/
715 static void RenderMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd)
717 struct RastPort *rp = mhd->menubarwin->RPort;
718 WORD len = strlen(menu->MenuName);
720 #if MENUS_UNDERMOUSE
721 struct Menu *m;
722 WORD x, y, yoff;
724 yoff = 0;
725 for(m = mhd->menu; m && (m != menu);m = m ->NextMenu)
727 yoff++;
730 x = mhd->scr->MenuHBorder + ITEXT_EXTRA_LEFT;
731 y = mhd->scr->MenuVBorder + ITEXT_EXTRA_TOP + yoff * mhd->menubaritemheight;
732 #else
733 WORD x = mhd->scr->BarHBorder + menu->LeftEdge;
734 WORD y = mhd->scr->BarVBorder;
735 #endif
737 #if MENUS_AMIGALOOK
738 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
739 #else
740 SetAPen(rp, mhd->dri->dri_Pens[(menu->Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN]);
741 #endif
743 Move(rp, x, y + rp->TxBaseline);
744 Text(rp, menu->MenuName, len);
746 #if MENUS_UNDERMOUSE
747 if (menu->FirstItem)
749 WORD silen = TextLength(rp, subitemindicator, 1);
750 WORD x2 = mhd->scr->MenuHBorder + mhd->menubaritemwidth - ITEXT_EXTRA_RIGHT - silen;
752 Move(rp, x2, y + rp->TxBaseline);
753 Text(rp, subitemindicator, 1);
755 #endif
757 if (!(menu->Flags & MENUENABLED))
759 #if MENUS_UNDERMOUSE
760 WORD x2 = mhd->scr->MenuHBorder + mhd->menubaritemwidth - 1;
761 #else
762 WORD x2 = x + TextLength(rp, menu->MenuName, len) - 1;
763 #endif
764 WORD y2 = y + rp->TxHeight - 1;
766 RenderDisabledPattern(rp, x, y, x2, y2, mhd);
770 /**************************************************************************************************/
772 static void MakeMenuWin(struct MenuHandlerData *mhd)
774 struct MenuItem *item;
776 WORD width = mhd->activemenu->BeatX - mhd->activemenu->JazzX + 1;
777 WORD height = mhd->activemenu->BeatY - mhd->activemenu->JazzY + 1;
778 #if MENUS_UNDERMOUSE
779 WORD xpos = mhd->menubarwin->LeftEdge + mhd->menubarwin->Width - 16;
780 WORD ypos = mhd->menubarwin->TopEdge;
781 #else
782 WORD xpos = mhd->activemenu->LeftEdge + mhd->scr->BarHBorder + mhd->activemenu->JazzX;
784 #if MENUS_AMIGALOOK
785 WORD ypos = mhd->scr->BarHeight + 1 + mhd->activemenu->JazzY;
786 #else
787 WORD ypos = mhd->scr->BarHeight + 1;
788 #endif
790 #endif
792 struct TagItem win_tags[9];
794 win_tags[0].ti_Tag = WA_Left;
795 win_tags[0].ti_Data = xpos;
796 win_tags[1].ti_Tag = WA_Top;
797 win_tags[1].ti_Data = ypos;
798 win_tags[2].ti_Tag = WA_Width;
799 win_tags[2].ti_Data = width;
800 win_tags[3].ti_Tag = WA_Height;
801 win_tags[3].ti_Data = height;
802 win_tags[4].ti_Tag = WA_AutoAdjust;
803 win_tags[4].ti_Data = TRUE;
804 win_tags[5].ti_Tag = WA_Borderless;
805 win_tags[5].ti_Data = TRUE;
806 win_tags[6].ti_Tag = WA_CustomScreen;
807 win_tags[6].ti_Data = (ULONG)mhd->scr;
808 win_tags[7].ti_Tag = WA_BackFill;
809 win_tags[7].ti_Tag = (IPTR)LAYERS_NOBACKFILL;
810 win_tags[8].ti_Tag = TAG_DONE;
813 #if MENUS_UNDERMOUSE
814 win_tags[1].ti_Data += (mhd->menubaritemheight * mhd->activemenunum + mhd->scr->MenuVBorder) -
815 height / 2;
816 if (xpos + width > mhd->scr->Width)
818 win_tags[0].ti_Data = mhd->menubarwin->LeftEdge - width + 16;
820 #endif
822 if ((item = mhd->activemenu->FirstItem))
824 while(item)
826 item->Flags &= ~HIGHITEM;
827 item = item->NextItem;
829 mhd->menuwin = OpenWindowTagList(0, win_tags);
831 mhd->maxcommkeywidth_menu = CalcMaxCommKeyWidth(mhd->menuwin, mhd);
833 RenderMenu(mhd);
835 mhd->activemenu->Flags |= MIDRAWN;
839 /**************************************************************************************************/
841 static void KillMenuWin(struct MenuHandlerData *mhd)
843 if (mhd->menuwin)
845 struct MenuItem *item;
847 CloseWindow(mhd->menuwin);
848 mhd->menuwin = NULL;
850 for(item = mhd->activemenu->FirstItem; item; item = item->NextItem)
852 item->Flags &= ~ISDRAWN;
855 mhd->activemenu->Flags &= ~MIDRAWN;
857 mhd->activeitemnum = -1;
858 mhd->activeitem = NULL;
862 /**************************************************************************************************/
864 static void RenderMenu(struct MenuHandlerData *mhd)
867 if (mhd->menuwin)
869 struct MenuItem *item;
871 RenderMenuBG(mhd->menuwin, mhd);
873 SetFont(mhd->menuwin->RPort, mhd->dri->dri_Font);
875 for(item = mhd->activemenu->FirstItem; item; item = item->NextItem)
877 RenderItem(item, ITEM_ITEM, (struct Rectangle *)(&mhd->activemenu->JazzX), mhd);
880 } /* if (mhd->menuwin) */
883 /**************************************************************************************************/
885 static void MakeSubMenuWin(struct MenuHandlerData *mhd)
887 struct MenuItem *item = mhd->activeitem->SubItem;
888 struct TagItem win_tags[9];
890 win_tags[0].ti_Tag = WA_Left;
891 win_tags[0].ti_Data = 0;
892 win_tags[1].ti_Tag = WA_Top;
893 win_tags[1].ti_Data = 0;
894 win_tags[2].ti_Tag = WA_Width;
895 win_tags[2].ti_Data = 0;
896 win_tags[3].ti_Tag = WA_Height;
897 win_tags[3].ti_Data = 0;
898 win_tags[4].ti_Tag = WA_AutoAdjust;
899 win_tags[4].ti_Data = TRUE;
900 win_tags[5].ti_Tag = WA_Borderless;
901 win_tags[5].ti_Data = TRUE;
902 win_tags[6].ti_Tag = WA_CustomScreen;
903 win_tags[6].ti_Data = (ULONG)mhd->scr;
904 win_tags[7].ti_Tag = WA_BackFill;
905 win_tags[7].ti_Tag = (IPTR)LAYERS_NOBACKFILL;
906 win_tags[8].ti_Tag = TAG_DONE;
908 GetMenuBox(mhd->menubarwin, item, &mhd->submenubox.MinX,
909 &mhd->submenubox.MinY,
910 &mhd->submenubox.MaxX,
911 &mhd->submenubox.MaxY);
913 win_tags[0].ti_Data = mhd->menuwin->LeftEdge +
914 mhd->activeitem->LeftEdge - mhd->activemenu->JazzX +
915 mhd->submenubox.MinX;
917 win_tags[1].ti_Data = mhd->menuwin->TopEdge +
918 mhd->activeitem->TopEdge - mhd->activemenu->JazzY +
919 mhd->submenubox.MinY;
921 win_tags[2].ti_Data = mhd->submenubox.MaxX - mhd->submenubox.MinX + 1;
922 win_tags[3].ti_Data = mhd->submenubox.MaxY - mhd->submenubox.MinY + 1;
924 while(item)
926 item->Flags &= ~HIGHITEM;
927 item = item->NextItem;
930 mhd->submenuwin = OpenWindowTagList(0, win_tags);
932 mhd->maxcommkeywidth_submenu = CalcMaxCommKeyWidth(mhd->submenuwin, mhd);
934 RenderSubMenu(mhd);
937 /**************************************************************************************************/
939 static void KillSubMenuWin(struct MenuHandlerData *mhd)
941 if (mhd->submenuwin)
943 CloseWindow(mhd->submenuwin);
944 mhd->submenuwin = NULL;
946 mhd->activesubitemnum = -1;
947 mhd->activesubitem = NULL;
951 /**************************************************************************************************/
953 static void RenderSubMenu(struct MenuHandlerData *mhd)
956 if (mhd->submenuwin)
958 struct MenuItem *item;
960 RenderMenuBG(mhd->submenuwin, mhd);
962 SetFont(mhd->submenuwin->RPort, mhd->dri->dri_Font);
964 for(item = mhd->activeitem->SubItem; item; item = item->NextItem)
966 RenderItem(item, ITEM_SUBITEM, (struct Rectangle *)(&mhd->submenubox), mhd);
969 } /* if (mhd->submenuwin) */
972 /**************************************************************************************************/
974 static void RenderItem(struct MenuItem *item, WORD itemtype, struct Rectangle *box,
975 struct MenuHandlerData *mhd)
977 struct Window *win = ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
978 struct RastPort *rp = win->RPort;
979 WORD offx = -box->MinX;
980 WORD offy = -box->MinY;
981 BOOL enabled = ((item->Flags & ITEMENABLED) &&
982 (mhd->activemenu->Flags & MENUENABLED) &&
983 ((itemtype == ITEM_ITEM) || (mhd->activeitem->Flags & ITEMENABLED)));
984 BOOL item_supports_disable = FALSE;
986 SetDrMd(rp, JAM1);
988 if (item->ItemFill)
990 if (item->Flags & ITEMTEXT)
992 #if MENUS_AMIGALOOK
993 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
995 PrintIText(rp, it, offx + item->LeftEdge, offy + item->TopEdge);
996 #else
997 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
999 it->FrontPen = mhd->dri->dri_Pens[(item->Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN];
1000 it->DrawMode = JAM1;
1002 PrintIText(rp, it, offx + item->LeftEdge, offy + item->TopEdge);
1003 #endif
1005 else
1007 struct Image *im = (struct Image *)item->ItemFill;
1008 LONG state = IDS_NORMAL;
1010 if (!enabled && (im->Depth == CUSTOMIMAGEDEPTH))
1012 IPTR val = 0;
1014 GetAttr(IA_SupportsDisable, (Object *)im, &val);
1015 if (val)
1017 item_supports_disable = TRUE;
1018 state = IDS_DISABLED;
1022 DrawImageState(rp, im, offx + item->LeftEdge, offy + item->TopEdge, state, mhd->dri);
1025 } /* if (item->ItemFill) */
1027 RenderCheckMark(item, itemtype, mhd);
1028 RenderAmigaKey(item, itemtype, mhd);
1030 if (!enabled && !item_supports_disable)
1032 RenderDisabledPattern(rp, offx + item->LeftEdge,
1033 offy + item->TopEdge,
1034 offx + item->LeftEdge + item->Width - 1,
1035 offy + item->TopEdge + item->Height - 1,
1036 mhd);
1041 /**************************************************************************************************/
1043 static void RenderMenuBG(struct Window *win, struct MenuHandlerData *mhd)
1045 struct RastPort *rp = win->RPort;
1047 #if MENUS_AMIGALOOK
1048 WORD borderx = mhd->scr->MenuHBorder / 2;
1049 WORD bordery = mhd->scr->MenuVBorder / 2;
1050 #else
1051 WORD borderx = 1;
1052 WORD bordery = 1;
1053 #endif
1055 /* White background */
1057 #if MENUS_AMIGALOOK
1058 SetABPenDrMd(rp, mhd->dri->dri_Pens[BARBLOCKPEN], 0, JAM1);
1059 #else
1060 SetABPenDrMd(rp, mhd->dri->dri_Pens[BACKGROUNDPEN], 0, JAM1);
1061 #endif
1062 RectFill(rp, borderx,
1063 bordery,
1064 win->Width - 1 - borderx,
1065 win->Height - 1 - bordery);
1067 /* Black border frame */
1069 #if MENUS_AMIGALOOK
1070 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
1071 RectFill(rp, 0, 0, win->Width - 1, bordery - 1);
1072 RectFill(rp, 0, bordery, borderx - 1, win->Height - 1 - bordery);
1073 RectFill(rp, win->Width - borderx, bordery, win->Width - 1, win->Height - 1);
1074 RectFill(rp, 0, win->Height - bordery, win->Width - 1 - borderx, win->Height - 1);
1075 #else
1076 RenderFrame(rp, 0, 0, win->Width - 1, win->Height - 1, IDS_NORMAL, mhd);
1077 #endif
1080 /**************************************************************************************************/
1082 static void RenderCheckMark(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd)
1084 struct Window *win = ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1085 struct RastPort *rp = win->RPort;
1086 struct Rectangle *box = ((itemtype == ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->JazzX) : &mhd->submenubox);
1087 WORD offx = -box->MinX;
1088 WORD offy = -box->MinY;
1089 WORD state = ((item->Flags & HIGHITEM) &&
1090 ((item->Flags & HIGHFLAGS) == HIGHCOMP)) ? IDS_SELECTED : IDS_NORMAL;
1092 if (item->Flags & CHECKIT)
1094 WORD x1, y1, x2, y2;
1096 x1 = item->LeftEdge + offx;
1097 y1 = item->TopEdge + offy + (item->Height - mhd->checkmark->Height) / 2;
1098 x2 = x1 + mhd->checkmark->Width - 1;
1099 y2 = y1 + mhd->checkmark->Height - 1;
1101 SetDrMd(rp, JAM1);
1103 if (item->Flags & CHECKED)
1105 DrawImageState(rp, mhd->checkmark, x1, y1, state, mhd->dri);
1106 } else {
1107 #if MENUS_AMIGALOOK
1108 SetAPen(rp, mhd->dri->dri_Pens[BARBLOCKPEN]);
1109 #else
1110 SetAPen(rp, mhd->dri->dri_Pens[(state == IDS_SELECTED) ? FILLPEN : BACKGROUNDPEN]);
1111 #endif
1112 RectFill(rp, x1, y1, x2, y2);
1118 /**************************************************************************************************/
1120 static void RenderAmigaKey(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd)
1122 struct Window *win = ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1123 struct RastPort *rp = win->RPort;
1124 struct Rectangle *box = ((itemtype == ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->JazzX) : &mhd->submenubox);
1125 WORD commkeywidth = ((itemtype == ITEM_ITEM) ? mhd->maxcommkeywidth_menu : mhd->maxcommkeywidth_submenu);
1126 WORD offx = -box->MinX;
1127 WORD offy = -box->MinY;
1128 WORD state = ((item->Flags & HIGHITEM) &&
1129 ((item->Flags & HIGHFLAGS) == HIGHCOMP)) ? IDS_SELECTED : IDS_NORMAL;
1131 if (item->Flags & COMMSEQ)
1133 struct TextFont *oldfont = rp->Font;
1134 struct TextFont *newfont = NULL;
1136 WORD x1, y1, x2, y2;
1138 if (item->Flags & ITEMTEXT)
1140 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1142 if (it->ITextFont)
1144 if ((newfont = OpenFont(it->ITextFont)))
1146 SetFont(rp, newfont);
1151 x1 = item->LeftEdge + offx + item->Width - AMIGAKEY_BORDER_SPACING -
1152 mhd->amigakey->Width - AMIGAKEY_KEY_SPACING - commkeywidth;
1153 y1 = item->TopEdge + offy + (item->Height - mhd->amigakey->Height + 1) / 2;
1154 x2 = x1 + mhd->amigakey->Width - 1;
1155 y2 = y1 + mhd->amigakey->Height - 1;
1157 SetDrMd(rp, JAM1);
1159 DrawImageState(rp, mhd->amigakey, x1, y1, state, mhd->dri);
1161 x1 += mhd->amigakey->Width + AMIGAKEY_KEY_SPACING;
1163 #if MENUS_AMIGALOOK
1164 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
1165 #else
1166 SetAPen(rp, mhd->dri->dri_Pens[(item->Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN]);
1167 #endif
1168 Move(rp, x1, item->TopEdge + offy + (item->Height - rp->TxHeight) / 2 +
1169 rp->TxBaseline);
1170 Text(rp, &item->Command, 1);
1172 if (newfont)
1174 CloseFont(newfont);
1175 SetFont(rp, oldfont);
1178 } /* if (item->Flags & COMMSEQ) */
1181 /**************************************************************************************************/
1183 static void RenderDisabledPattern(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2,
1184 struct MenuHandlerData *mhd)
1186 static UWORD pattern [] = {0x8888, 0x2222};
1188 SetDrMd(rp, JAM1);
1189 #if MENUS_AMIGALOOK
1190 SetAPen(rp, mhd->dri->dri_Pens[BARBLOCKPEN]);
1191 #else
1192 SetAPen(rp, mhd->dri->dri_Pens[BACKGROUNDPEN]);
1193 #endif
1195 SetAfPt(rp, pattern, 1);
1197 RectFill(rp, x1, y1, x2, y2);
1199 SetAfPt(rp, NULL, 0);
1202 /**************************************************************************************************/
1203 #if 0
1204 static void RenderFrame(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2, WORD state,
1205 struct MenuHandlerData *mhd)
1207 SetAPen(rp, mhd->dri->dri_Pens[(state == IDS_SELECTED) ? SHADOWPEN : SHINEPEN]);
1209 RectFill(rp, x1, y1, x2, y1);
1210 RectFill(rp, x1, y1 + 1, x1, y2);
1212 SetAPen(rp, mhd->dri->dri_Pens[(state == IDS_SELECTED) ? SHINEPEN : SHADOWPEN]);
1213 RectFill(rp, x2, y1 + 1, x2, y2);
1214 RectFill(rp, x1 + 1, y2, x2 - 1, y2);
1216 #endif
1217 /**************************************************************************************************/
1219 static void HighlightItem(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd)
1221 struct Window *win = ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1222 struct RastPort *rp = win->RPort;
1223 struct Rectangle *box = ((itemtype == ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->JazzX) : &mhd->submenubox);
1224 APTR fill;
1225 WORD offx = -box->MinX;
1226 WORD offy = -box->MinY;
1227 WORD x1, y1, x2, y2;
1228 BOOL enabled;
1230 enabled = (item->Flags & ITEMENABLED) ? TRUE : FALSE;
1231 if (!(mhd->activemenu->Flags & MENUENABLED)) enabled = FALSE;
1232 if ((itemtype == ITEM_SUBITEM) && !(mhd->activeitem->Flags & ITEMENABLED)) enabled = FALSE;
1234 if (enabled)
1236 item->Flags ^= HIGHITEM;
1238 fill = item->ItemFill;
1239 if ((item->Flags & HIGHITEM) && (item->SelectFill)) fill = item->SelectFill;
1241 x1 = offx + item->LeftEdge;
1242 y1 = offy + item->TopEdge;
1243 x2 = x1 + item->Width - 1;
1244 y2 = y1 + item->Height - 1;
1246 switch(item->Flags & HIGHFLAGS)
1248 case HIGHIMAGE:
1249 SetDrMd(rp, JAM1);
1251 if(item->Flags & ITEMTEXT)
1253 #if MENUS_AMIGALOOK
1254 PrintIText(rp, (struct IntuiText *)fill, x1, y1);
1255 #else
1256 struct IntuiText *it = (struct IntuiText *)fill;
1258 it->FrontPen = mhd->dri->dri_Pens[TEXTPEN];
1259 it->DrawMode = JAM1;
1261 PrintIText(rp, it, x1, y1);
1262 #endif
1263 } else {
1264 EraseImage(rp, (struct Image *)fill, x1, y1);
1265 DrawImageState(rp, (struct Image *)fill, x1, y1, IDS_SELECTED, mhd->dri);
1267 break;
1269 case HIGHCOMP:
1270 #if MENUS_AMIGALOOK
1271 SetDrMd(rp, COMPLEMENT);
1272 RectFill(rp, x1, y1, x2, y2);
1273 #else
1275 WORD state = (item->Flags & HIGHITEM) ? IDS_SELECTED : IDS_NORMAL;
1277 SetDrMd(rp, JAM1);
1278 SetAPen(rp, mhd->dri->dri_Pens[(state == IDS_SELECTED) ? FILLPEN : BACKGROUNDPEN]);
1279 RectFill(rp, x1, y1, x2, y2);
1281 RenderItem(item, itemtype, box, mhd);
1283 if (state == IDS_SELECTED)
1285 RenderFrame(rp, x1, y1, x2, y2, state, mhd);
1288 #endif
1289 break;
1291 case HIGHBOX:
1292 SetDrMd(rp, COMPLEMENT);
1293 offx = mhd->scr->MenuHBorder;
1294 offy = mhd->scr->MenuVBorder;
1296 x1 -= offx; x2 += offx;
1297 y1 -= offy; y2 += offy;
1299 RectFill(rp, x1, y1, x2, y1 + offy - 1);
1300 RectFill(rp, x2 - offx + 1, y1 + offy, x2, y2);
1301 RectFill(rp, x1, y2 - offy + 1, x2 - offx, y2);
1302 RectFill(rp, x1, y1 + offy, x1 + offx - 1,y2 - offy);
1303 break;
1305 case HIGHNONE:
1306 /* Do nothing */
1307 break;
1309 } /* switch(item->Flags & HIGHFLAGS) */
1311 } /* if (enabled) */
1317 /**************************************************************************************************/
1319 static WORD CalcMaxCommKeyWidth(struct Window *win, struct MenuHandlerData *mhd)
1321 WORD maxwidth = mhd->dri->dri_Font->tf_XSize;
1323 if (win)
1325 struct MenuItem *item;
1327 if ((win == mhd->menuwin))
1329 item = mhd->activemenu->FirstItem;
1331 else
1333 item = mhd->activeitem->SubItem;
1336 for(; item; item = item->NextItem)
1338 if (item->Flags & ITEMTEXT)
1340 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1342 if (it->ITextFont)
1344 struct TextFont *font;
1346 if ((font = OpenFont(it->ITextFont)))
1348 if (font->tf_XSize > maxwidth) maxwidth = font->tf_XSize;
1350 CloseFont(font);
1354 } /* if (item->Flags & ITEMTEXT) */
1356 } /* for(; item; item = item->NextItem); */
1358 } /* if (win) */
1360 return maxwidth;
1363 /**************************************************************************************************/
1365 static void AddToSelection(struct MenuHandlerData *mhd)
1367 if ((mhd->activemenunum != -1) && (mhd->activemenu->Flags & MENUENABLED) &&
1368 (mhd->activeitemnum != -1) && (mhd->activeitem->Flags & ITEMENABLED))
1370 struct MenuItem *item = NULL;
1371 UWORD men = FULLMENUNUM(mhd->activemenunum, mhd->activeitemnum, mhd->activesubitemnum);
1373 if (mhd->activesubitemnum != -1)
1375 if (mhd->activesubitem->Flags & ITEMENABLED) item = mhd->activesubitem;
1377 else if (!mhd->activeitem->SubItem)
1379 item = mhd->activeitem;
1382 if (item && (ItemAddress(mhd->menu, men) == item))
1384 UWORD men = FULLMENUNUM(mhd->activemenunum, mhd->activeitemnum, mhd->activesubitemnum);
1386 if (mhd->firstmenupick == MENUNULL)
1388 mhd->firstmenupick = men;
1390 else if (men != mhd->lastmenupick)
1392 struct MenuItem *checkitem, *prevcheckitem = NULL;
1393 UWORD checkmen = mhd->firstmenupick;
1395 /* Remove men from pick queue, if it was already in there
1396 and then add it at the end of the pick queue */
1398 while(checkmen != MENUNULL)
1400 checkitem = ItemAddress(mhd->menu, checkmen);
1402 if (checkmen == men)
1404 if (prevcheckitem == NULL)
1406 mhd->firstmenupick = checkitem->NextSelect;
1408 else
1410 prevcheckitem->NextSelect = checkitem->NextSelect;
1414 checkmen = checkitem->NextSelect;
1415 prevcheckitem = checkitem;
1417 } /* while(checkmen != MENUNULL) */
1419 checkitem->NextSelect = men;
1421 } /* else if (men != mhd->lastmenupick) */
1423 mhd->lastmenupick = men;
1424 item->NextSelect = MENUNULL;
1426 } /* if (item) */
1428 } /* if ((mhd->activemenunum != -1) && (mhd->activeitemnum != -1)) */
1431 /**************************************************************************************************/
1433 /** END AROS **/
1435 struct ZMenu
1437 struct MenuHandlerData mhd;
1440 struct ZMenu *zune_open_menu(struct Window *wnd, struct NewMenu *newmenu)
1442 struct TagItem tags[] =
1444 {GTMN_NewLookMenus ,TRUE},
1445 {TAG_DONE }
1448 struct ZMenu *zmenu;
1449 struct Menu *menu;
1450 APTR visinfo;
1451 zmenu = (struct ZMenu*)AllocVec(sizeof(struct ZMenu),MEMF_CLEAR);
1452 if (!zmenu) return NULL;
1454 visinfo = GetVisualInfoA(wnd->WScreen,NULL);
1455 if (!visinfo)
1457 FreeVec(zmenu);
1458 return NULL;
1461 if (!(menu = CreateMenusA(newmenu,NULL)))
1463 FreeVec(zmenu);
1464 return NULL;
1467 LayoutMenusA(menu, visinfo, tags);
1468 FreeVisualInfo(visinfo);
1470 Characterize(menu);
1471 CalculateDims(wnd, menu);
1473 zmenu->mhd.win = wnd;
1474 zmenu->mhd.scr = zmenu->mhd.win->WScreen;
1475 zmenu->mhd.dri = GetScreenDrawInfo(zmenu->mhd.scr);
1476 zmenu->mhd.menu = menu;
1477 zmenu->mhd.activemenunum = -1;
1478 zmenu->mhd.activeitemnum = -1;
1479 zmenu->mhd.activesubitemnum = -1;
1480 zmenu->mhd.checkmark = zmenu->mhd.dri->dri_CheckMark;
1481 zmenu->mhd.amigakey = zmenu->mhd.dri->dri_AmigaKey;
1482 zmenu->mhd.scrmousex = zmenu->mhd.scr->MouseX;
1483 zmenu->mhd.scrmousey = zmenu->mhd.scr->MouseY;
1484 zmenu->mhd.firstmenupick = MENUNULL;
1486 MakeMenuBarWin(&zmenu->mhd);
1487 HandleMouseMove(&zmenu->mhd);
1488 return zmenu;
1491 void zune_mouse_update(struct ZMenu *zmenu, int left_down)
1493 if (!zmenu) return;
1495 if (!left_down) HandleMouseMove(&zmenu->mhd);
1496 else HandleMouseClick(&zmenu->mhd, 0);
1499 struct MenuItem *zune_leave_menu(struct ZMenu *zmenu)
1501 HandleMouseClick(&zmenu->mhd, 1);
1503 return ItemAddress(zmenu->mhd.menu, zmenu->mhd.firstmenupick);
1506 /* returns the address of the selected menuitem entry */
1507 void zune_close_menu(struct ZMenu *zmenu)
1509 if (!zmenu) return;
1511 KillMenuBarWin(&zmenu->mhd);
1512 KillMenuWin(&zmenu->mhd);
1513 KillSubMenuWin(&zmenu->mhd);
1515 FreeMenus(zmenu->mhd.menu);
1516 zmenu->mhd.menu = 0;
1518 if (zmenu->mhd.dri)
1520 FreeScreenDrawInfo(zmenu->mhd.scr, zmenu->mhd.dri);
1521 zmenu->mhd.dri = 0;
1524 // MH2Int_MakeMenusInactive(mhd->win, mhd->firstmenupick);
1525 zmenu->mhd.active = FALSE;
1527 FreeVec(zmenu);
1530 struct Menu *zune_get_menu_pointer(struct ZMenu *menu)
1532 return menu->mhd.menu;