muimaster.library: a selection of top level Menu is also expected to trigger MUIM_Con...
[AROS.git] / workbench / libs / muimaster / menu.c
blob8c0941ab3f92caeac919106227f229bfffb2886c
1 /*
2 Copyright © 2002-2011, 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"
20 #include "menu.h"
22 extern struct Library *MUIMasterBase;
24 /**************************************************************************
25 The following stuff is taken from AROS's intuition. Maybe if this go to
26 the public somewhere we don't need this in the AROS version
27 **************************************************************************/
29 #define min(a,b) (((a) < (b)) ? (a) : (b))
30 #define max(a,b) (((a) > (b)) ? (a) : (b))
32 void GetMenuBox(struct Window *win, struct MenuItem *item,
33 WORD *xmin, WORD *ymin, WORD *xmax, WORD *ymax)
36 WORD left, right, top, bottom;
38 left = top = 0x7fff;
39 right = bottom = -0x7fff;
41 while (item != NULL)
43 left = min(left, item->LeftEdge);
44 top = min(top, item->TopEdge);
45 right = max(right, item->LeftEdge + item->Width - 1);
46 bottom = max(bottom, item->TopEdge + item->Height - 1);
48 item = item->NextItem;
51 if (xmin)
52 *xmin = left - win->WScreen->MenuHBorder;
53 if (ymin)
54 *ymin = top - win->WScreen->MenuVBorder;
55 if (xmax)
56 *xmax = right + win->WScreen->MenuHBorder;
57 if (ymax)
58 *ymax = bottom + win->WScreen->MenuVBorder;
62 void CalculateDims(struct Window *win, struct Menu *menu)
64 struct MenuItem *item;
66 while (menu != NULL)
68 item = menu->FirstItem;
70 GetMenuBox(win, item, &menu->JazzX, &menu->JazzY, &menu->BeatX,
71 &menu->BeatY);
73 menu = menu->NextMenu;
77 /* Mark items that has subitems. This is necessary for the input handler
78 code. It's not possible to check item->SubItem within it as we save
79 the layer coordinates there. */
80 void Characterize(struct Menu *menu)
82 while (menu != NULL)
84 struct MenuItem *item;
86 item = menu->FirstItem;
88 while (item != NULL)
90 // if(item->SubItem != NULL)
91 // item->Flags |= HASSUBITEM;
93 item = item->NextItem;
96 menu = menu->NextMenu;
100 #define MENUS_UNDERMOUSE 1
101 #define MENUS_AMIGALOOK 1
103 /** BEGIN AROS **/
105 #define ITEM_ITEM 1
106 #define ITEM_SUBITEM 2
108 #define AMIGAKEY_KEY_SPACING 4 /* GadTools assumes this, too */
109 #define AMIGAKEY_BORDER_SPACING 2
111 struct MenuHandlerData
113 struct Window *win;
114 struct Screen *scr;
115 struct DrawInfo *dri;
116 struct Window *menubarwin;
117 struct Window *menuwin;
118 struct Window *submenuwin;
119 struct Menu *menu;
120 struct Menu *activemenu;
121 struct MenuItem *activeitem;
122 struct MenuItem *activesubitem;
123 struct Rectangle submenubox;
124 struct Image *checkmark;
125 struct Image *amigakey;
126 WORD menubarwidth;
127 WORD menubarheight;
128 WORD menubaritemwidth;
129 WORD menubaritemheight;
130 WORD nummenubaritems;
131 WORD activemenunum;
132 WORD activeitemnum;
133 WORD activesubitemnum;
134 WORD maxcommkeywidth_menu;
135 WORD maxcommkeywidth_submenu;
136 WORD scrmousex;
137 WORD scrmousey;
138 UWORD firstmenupick;
139 UWORD lastmenupick;
140 BOOL active;
143 /* this #defines are taken from workbench/libs/gadtools/menus.c!! */
145 #define TEXT_AMIGAKEY_SPACING 6
147 #define ITEXT_EXTRA_LEFT 2
148 #define ITEXT_EXTRA_RIGHT 2
149 #define ITEXT_EXTRA_TOP 1
150 #define ITEXT_EXTRA_BOTTOM 1
152 static const char subitemindicator[] = "»";
155 static void HandleMouseMove(struct MenuHandlerData *mhd);
156 static void HandleMouseClick(struct MenuHandlerData *mhd, int menuup);
157 static void HandleCheckItem(struct Window *win, struct MenuItem *item,
158 WORD itemnum, struct MenuHandlerData *mhd);
160 static void HighlightMenuTitle(struct Menu *menu,
161 struct MenuHandlerData *mhd);
163 static struct Menu *FindMenu(WORD *var, struct MenuHandlerData *mhd);
164 static struct MenuItem *FindItem(WORD *var, struct MenuHandlerData *mhd);
165 static struct MenuItem *FindSubItem(WORD *var,
166 struct MenuHandlerData *mhd);
168 static void MakeMenuBarWin(struct MenuHandlerData *mhd);
169 static void KillMenuBarWin(struct MenuHandlerData *mhd);
170 static void RenderMenuBar(struct MenuHandlerData *mhd);
172 static void MakeMenuWin(struct MenuHandlerData *mhd);
173 static void KillMenuWin(struct MenuHandlerData *mhd);
174 static void RenderMenu(struct MenuHandlerData *mhd);
175 static void RenderMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd);
177 static void MakeSubMenuWin(struct MenuHandlerData *mhd);
178 static void KillSubMenuWin(struct MenuHandlerData *mhd);
179 static void RenderSubMenu(struct MenuHandlerData *mhd);
181 static void RenderItem(struct MenuItem *item, WORD itemtype,
182 struct Rectangle *box, struct MenuHandlerData *mhd);
184 static void RenderMenuBG(struct Window *win, struct MenuHandlerData *mhd);
185 static void RenderCheckMark(struct MenuItem *item, WORD itemtype,
186 struct MenuHandlerData *mhd);
187 static void RenderAmigaKey(struct MenuItem *item, WORD itemtype,
188 struct MenuHandlerData *mhd);
189 static void RenderDisabledPattern(struct RastPort *rp, WORD x1, WORD y1,
190 WORD x2, WORD y2, struct MenuHandlerData *mhd);
191 #if 0
192 static void RenderFrame(struct RastPort *rp, WORD x1, WORD y1, WORD x2,
193 WORD y2, WORD state, struct MenuHandlerData *mhd);
194 #endif
195 static void HighlightItem(struct MenuItem *item, WORD itemtype,
196 struct MenuHandlerData *mhd);
197 static WORD CalcMaxCommKeyWidth(struct Window *win,
198 struct MenuHandlerData *mhd);
199 static void AddToSelection(struct MenuHandlerData *mhd);
203 static void HandleMouseMove(struct MenuHandlerData *mhd)
205 struct Layer *lay;
206 struct Window *win = NULL;
207 struct Menu *menu;
208 struct MenuItem *item;
210 WORD new_activemenunum = mhd->activemenunum;
211 WORD new_activeitemnum = mhd->activeitemnum;
212 WORD new_activesubitemnum = mhd->activesubitemnum;
214 mhd->scrmousex = mhd->scr->MouseX;
215 mhd->scrmousey = mhd->scr->MouseY;
217 LockLayerInfo(&mhd->scr->LayerInfo);
218 lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey);
219 UnlockLayerInfo(&mhd->scr->LayerInfo);
221 if (lay)
223 win = (struct Window *)lay->Window;
225 if (win && (win == mhd->submenuwin))
227 /* Mouse over submenu box */
228 item = FindSubItem(&new_activesubitemnum, mhd);
230 if (new_activesubitemnum != mhd->activesubitemnum)
232 if (mhd->activesubitemnum != -1)
234 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd);
237 mhd->activesubitemnum = new_activesubitemnum;
238 mhd->activesubitem = item;
240 if (item)
242 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd);
247 else if (win && (win == mhd->menuwin))
249 item = FindItem(&new_activeitemnum, mhd);
251 if (new_activeitemnum != mhd->activeitemnum)
253 if (mhd->activeitemnum != -1)
255 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd);
256 KillSubMenuWin(mhd);
259 mhd->activeitemnum = new_activeitemnum;
260 mhd->activeitem = item;
262 if (item)
264 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd);
266 if (item->SubItem)
268 MakeSubMenuWin(mhd);
273 else if (win && (win == mhd->menubarwin))
275 /* Mouse over menu box */
277 menu = FindMenu(&new_activemenunum, mhd);
279 if (new_activemenunum != mhd->activemenunum)
281 if (mhd->activemenunum != -1)
283 HighlightMenuTitle(mhd->activemenu, mhd);
284 KillMenuWin(mhd);
285 KillSubMenuWin(mhd);
288 mhd->activemenunum = new_activemenunum;
289 mhd->activemenu = menu;
291 if (menu)
293 HighlightMenuTitle(mhd->activemenu, mhd);
294 MakeMenuWin(mhd);
298 if ((mhd->activeitemnum != -1) && (!mhd->submenuwin))
300 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd);
301 mhd->activeitemnum = -1;
302 mhd->activeitem = NULL;
305 else
307 win = NULL;
311 if (!win)
313 /* mouse outside any menu window */
315 if ((mhd->activeitemnum != -1) && (!mhd->submenuwin))
317 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd);
318 mhd->activeitemnum = -1;
319 mhd->activeitem = NULL;
321 else if (mhd->activesubitemnum != -1)
323 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd);
324 mhd->activesubitemnum = -1;
325 mhd->activesubitem = NULL;
332 static void HandleMouseClick(struct MenuHandlerData *mhd, int menuup)
334 struct Layer *lay;
336 LockLayerInfo(&mhd->scr->LayerInfo);
337 lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey);
338 UnlockLayerInfo(&mhd->scr->LayerInfo);
340 if (lay)
342 struct Window *win = (struct Window *)lay->Window;
343 struct MenuItem *item = NULL;
344 WORD itemnum = 0;
346 win = (struct Window *)lay->Window;
348 if (win && (win == mhd->submenuwin)
349 && (mhd->activesubitemnum != -1))
351 item = mhd->activesubitem;
353 else if (win && (win == mhd->menuwin) && (mhd->activeitemnum != -1))
355 item = mhd->activeitem;
358 if (item)
359 if (item->Flags & CHECKIT)
361 HandleCheckItem(win, item, itemnum, mhd);
364 AddToSelection(mhd);
369 static void HandleCheckItem(struct Window *win, struct MenuItem *item,
370 WORD itemnum, struct MenuHandlerData *mhd)
372 /* Note: If you change something here, you probably must also change
373 menus.c/CheckMenuItemWasClicked() which is used when the
374 user uses the menu key shortcuts! */
376 WORD itemtype = ((win == mhd->menuwin) ? ITEM_ITEM : ITEM_SUBITEM);
378 BOOL re_render = FALSE;
380 if (item->Flags & MENUTOGGLE)
382 item->Flags ^= CHECKED;
383 re_render = TRUE;
385 else
387 if (!(item->Flags & CHECKED))
389 item->Flags |= CHECKED;
390 re_render = TRUE;
394 if (re_render)
396 BOOL toggle_hi = FALSE;
398 if ((item->Flags & HIGHITEM) &&
399 ((item->Flags & HIGHFLAGS) == HIGHCOMP))
400 toggle_hi = TRUE;
402 if (toggle_hi)
403 HighlightItem(item, itemtype, mhd);
404 RenderCheckMark(item, itemtype, mhd);
405 if (toggle_hi)
406 HighlightItem(item, itemtype, mhd);
410 if (item->MutualExclude)
412 struct MenuItem *checkitem =
413 (itemtype ==
414 ITEM_ITEM) ? mhd->activemenu->FirstItem : mhd->activeitem->
415 SubItem;
416 BOOL toggle_hi = FALSE;
417 WORD i;
419 if ((item->Flags & HIGHITEM) &&
420 ((item->Flags & HIGHFLAGS) == HIGHBOX))
421 toggle_hi = TRUE;
423 if (toggle_hi)
424 HighlightItem(item, itemtype, mhd);
426 for (i = 0; (i < 32) && checkitem;
427 i++, checkitem = checkitem->NextItem)
429 if ((i != itemnum) && (item->MutualExclude & (1L << i)) &&
430 ((checkitem->Flags & (CHECKED | CHECKIT)) ==
431 (CHECKIT | CHECKED)))
433 checkitem->Flags &= ~CHECKED;
434 RenderCheckMark(checkitem, itemtype, mhd);
438 if (toggle_hi)
439 HighlightItem(item, itemtype, mhd);
444 static void HighlightMenuTitle(struct Menu *menu,
445 struct MenuHandlerData *mhd)
447 if (menu->Flags & MENUENABLED)
449 struct RastPort *rp = mhd->menubarwin->RPort;
451 #if MENUS_UNDERMOUSE
452 struct Menu *m = mhd->menu;
453 WORD x1 = mhd->scr->MenuHBorder;
454 WORD x2 = x1 + mhd->menubaritemwidth - 1;
455 WORD y1, y2, i;
457 for (i = 0; m != menu; m = m->NextMenu)
458 i++;
460 y1 = mhd->scr->MenuVBorder + i * mhd->menubaritemheight;
461 y2 = y1 + mhd->menubaritemheight - 1;
463 #else
464 WORD x1 =
465 menu->LeftEdge + mhd->scr->BarHBorder - mhd->scr->MenuHBorder;
466 WORD y1 = 0;
467 WORD x2 = x1 + menu->Width - 1;
468 WORD y2 = mhd->scr->BarHeight - 1;
469 #endif
471 #if MENUS_AMIGALOOK
472 SetDrMd(rp, COMPLEMENT);
473 RectFill(rp, x1, y1, x2, y2);
474 #else
475 menu->Flags ^= HIGHITEM;
477 #if !MENUS_UNDERMOUSE
478 y1++;
479 #endif
481 SetDrMd(rp, JAM1);
482 SetAPen(rp,
483 mhd->dri->dri_Pens[(menu->
484 Flags & HIGHITEM) ? FILLPEN : BACKGROUNDPEN]);
485 RectFill(rp, x1, y1, x2, y2);
487 RenderMenuTitle(menu, mhd);
489 if (menu->Flags & HIGHITEM)
491 #if MENUS_UNDERMOUSE
492 RenderFrame(rp, x1, y1, x2, y2, IDS_SELECTED, mhd);
493 #else
494 SetAPen(rp, mhd->dri->dri_Pens[SHINEPEN]);
495 RectFill(rp, x1, y1, x1, y2);
496 SetAPen(rp, mhd->dri->dri_Pens[SHADOWPEN]);
497 RectFill(rp, x2, y1, x2, y2);
498 #endif
502 #endif /* MENUS_AMIGALOOK */
507 static struct Menu *FindMenu(WORD *var, struct MenuHandlerData *mhd)
509 struct Menu *menu;
510 WORD mouse_x, mouse_y, i;
512 mouse_x = mhd->scrmousex - mhd->menubarwin->LeftEdge;
513 mouse_y = mhd->scrmousey - mhd->menubarwin->TopEdge;
515 #if MENUS_UNDERMOUSE
516 menu = NULL;
518 mouse_x -= mhd->scr->MenuHBorder;
519 mouse_y -= mhd->scr->MenuVBorder;
521 if ((mouse_x >= 0) && (mouse_x < mhd->menubaritemwidth)
522 && (mouse_y >= 0))
524 i = mouse_y / mhd->menubaritemheight;
526 if ((i >= 0) && (i < mhd->nummenubaritems))
528 WORD i2 = i;
530 menu = mhd->menu;
531 while (i && menu)
533 i--;
534 menu = menu->NextMenu;
537 if (menu && (i == 0))
539 *var = i2;
543 #else
544 for (menu = mhd->menu, i = 0; menu; menu = menu->NextMenu, i++)
546 if ((mouse_x >= menu->LeftEdge) &&
547 (mouse_x < menu->LeftEdge + menu->Width) &&
548 (mouse_y >= 0) && (mouse_y <= mhd->scr->BarHeight))
550 *var = i;
551 break;
554 #endif
556 return menu;
560 static struct MenuItem *FindItem(WORD *var, struct MenuHandlerData *mhd)
562 struct MenuItem *item = NULL;
563 WORD mouse_x, mouse_y, i;
565 if (mhd->menuwin)
567 mouse_x =
568 mhd->scrmousex - mhd->menuwin->LeftEdge +
569 mhd->activemenu->JazzX;
570 mouse_y =
571 mhd->scrmousey - mhd->menuwin->TopEdge + mhd->activemenu->JazzY;
573 for (item = mhd->activemenu->FirstItem, i = 0; item;
574 item = item->NextItem, i++)
576 if ((mouse_x >= item->LeftEdge) &&
577 (mouse_x < item->LeftEdge + item->Width) &&
578 (mouse_y >= item->TopEdge) &&
579 (mouse_y < item->TopEdge + item->Height))
581 *var = i;
582 break;
587 if ((item == NULL) && !mhd->submenuwin)
588 *var = -1;
590 return item;
594 static struct MenuItem *FindSubItem(WORD *var, struct MenuHandlerData *mhd)
596 struct MenuItem *item = NULL;
597 WORD mouse_x, mouse_y, i;
599 if (mhd->submenuwin)
601 mouse_x =
602 mhd->scrmousex - mhd->submenuwin->LeftEdge +
603 mhd->submenubox.MinX;
604 mouse_y =
605 mhd->scrmousey - mhd->submenuwin->TopEdge +
606 mhd->submenubox.MinY;
608 *var = -1;
610 for (item = mhd->activeitem->SubItem, i = 0; item;
611 item = item->NextItem, i++)
613 if ((mouse_x >= item->LeftEdge) &&
614 (mouse_x < item->LeftEdge + item->Width) &&
615 (mouse_y >= item->TopEdge) &&
616 (mouse_y < item->TopEdge + item->Height))
618 *var = i;
619 break;
625 return item;
629 static void MakeMenuBarWin(struct MenuHandlerData *mhd)
631 struct TagItem win_tags[9];
632 struct Menu *menu;
634 #if MENUS_UNDERMOUSE
635 WORD w, maxw = 0;
636 #endif
638 win_tags[0].ti_Tag = WA_Left;
639 win_tags[0].ti_Data = 0;
640 win_tags[1].ti_Tag = WA_Top;
641 win_tags[1].ti_Data = 0;
642 win_tags[2].ti_Tag = WA_Width;
643 win_tags[2].ti_Data = mhd->scr->Width;
644 win_tags[3].ti_Tag = WA_Height;
645 win_tags[3].ti_Data = mhd->scr->BarHeight + 1;
646 win_tags[4].ti_Tag = WA_AutoAdjust;
647 win_tags[4].ti_Data = TRUE;
648 win_tags[5].ti_Tag = WA_Borderless;
649 win_tags[5].ti_Data = TRUE;
650 win_tags[6].ti_Tag = WA_CustomScreen;
651 win_tags[6].ti_Data = (IPTR) mhd->scr;
652 win_tags[7].ti_Tag = WA_BackFill;
653 win_tags[7].ti_Tag = (IPTR) LAYERS_NOBACKFILL;
654 win_tags[8].ti_Tag = TAG_DONE;
656 #if MENUS_UNDERMOUSE
658 mhd->nummenubaritems = 0;
659 for (menu = mhd->menu; menu; menu = menu->NextMenu)
661 w = TextLength(&mhd->scr->RastPort, menu->MenuName,
662 strlen(menu->MenuName));
663 if (w > maxw)
664 maxw = w;
665 mhd->nummenubaritems++;
668 mhd->menubaritemwidth =
669 maxw + TextLength(&mhd->scr->RastPort, subitemindicator,
670 1) + TEXT_AMIGAKEY_SPACING + ITEXT_EXTRA_LEFT + ITEXT_EXTRA_RIGHT;
672 mhd->menubaritemheight =
673 mhd->scr->RastPort.TxHeight + ITEXT_EXTRA_TOP + ITEXT_EXTRA_BOTTOM;
675 win_tags[2].ti_Data = mhd->menubaritemwidth + mhd->scr->MenuHBorder * 2;
676 win_tags[3].ti_Data =
677 mhd->menubaritemheight * mhd->nummenubaritems +
678 mhd->scr->MenuVBorder * 2;
679 win_tags[0].ti_Data = mhd->scr->MouseX - win_tags[2].ti_Data / 2;
680 win_tags[1].ti_Data = mhd->scr->MouseY;
682 #endif
684 mhd->menubarwin = OpenWindowTagList(0, win_tags);
686 for (menu = mhd->menu; menu; menu = menu->NextMenu)
688 menu->Flags &= ~HIGHITEM;
691 RenderMenuBar(mhd);
695 static void KillMenuBarWin(struct MenuHandlerData *mhd)
697 if (mhd->menubarwin)
699 CloseWindow(mhd->menubarwin);
700 mhd->menubarwin = NULL;
705 static void RenderMenuBar(struct MenuHandlerData *mhd)
707 if (mhd->menubarwin)
709 struct Menu *menu = mhd->menu;
710 struct RastPort *rp = mhd->menubarwin->RPort;
712 SetFont(rp, mhd->dri->dri_Font);
714 #if MENUS_UNDERMOUSE
716 RenderMenuBG(mhd->menubarwin, mhd);
718 #else
720 #if MENUS_AMIGALOOK
721 SetABPenDrMd(rp, mhd->dri->dri_Pens[BARBLOCKPEN], 0, JAM1);
722 #else
723 SetABPenDrMd(rp, mhd->dri->dri_Pens[BACKGROUNDPEN], 0, JAM1);
724 #endif
725 RectFill(rp, 0, 0, mhd->menubarwin->Width - 1,
726 mhd->menubarwin->Height - 2);
727 SetAPen(rp, mhd->dri->dri_Pens[BARTRIMPEN]);
728 RectFill(rp, 0, mhd->menubarwin->Height - 1,
729 mhd->menubarwin->Width - 1, mhd->menubarwin->Height - 1);
731 #if !MENUS_AMIGALOOK
732 SetAPen(rp, mhd->dri->dri_Pens[SHINEPEN]);
733 RectFill(rp, 0, 0, 0, mhd->menubarwin->Height - 2);
734 RectFill(rp, 1, 0, mhd->menubarwin->Width - 1, 0);
735 SetAPen(rp, mhd->dri->dri_Pens[SHADOWPEN]);
736 RectFill(rp, mhd->menubarwin->Width - 1, 1,
737 mhd->menubarwin->Width - 1, mhd->menubarwin->Height - 2);
739 #endif
741 #endif
743 for (; menu; menu = menu->NextMenu)
745 RenderMenuTitle(menu, mhd);
751 static void RenderMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd)
753 struct RastPort *rp = mhd->menubarwin->RPort;
754 WORD len = strlen(menu->MenuName);
756 #if MENUS_UNDERMOUSE
757 struct Menu *m;
758 WORD x, y, yoff;
760 yoff = 0;
761 for (m = mhd->menu; m && (m != menu); m = m->NextMenu)
763 yoff++;
766 x = mhd->scr->MenuHBorder + ITEXT_EXTRA_LEFT;
767 y = mhd->scr->MenuVBorder + ITEXT_EXTRA_TOP +
768 yoff * mhd->menubaritemheight;
769 #else
770 WORD x = mhd->scr->BarHBorder + menu->LeftEdge;
771 WORD y = mhd->scr->BarVBorder;
772 #endif
774 #if MENUS_AMIGALOOK
775 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
776 #else
777 SetAPen(rp,
778 mhd->dri->dri_Pens[(menu->
779 Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN]);
780 #endif
782 Move(rp, x, y + rp->TxBaseline);
783 Text(rp, menu->MenuName, len);
785 #if MENUS_UNDERMOUSE
786 if (menu->FirstItem)
788 WORD silen = TextLength(rp, subitemindicator, 1);
789 WORD x2 =
790 mhd->scr->MenuHBorder + mhd->menubaritemwidth -
791 ITEXT_EXTRA_RIGHT - silen;
793 Move(rp, x2, y + rp->TxBaseline);
794 Text(rp, subitemindicator, 1);
796 #endif
798 if (!(menu->Flags & MENUENABLED))
800 #if MENUS_UNDERMOUSE
801 WORD x2 = mhd->scr->MenuHBorder + mhd->menubaritemwidth - 1;
802 #else
803 WORD x2 = x + TextLength(rp, menu->MenuName, len) - 1;
804 #endif
805 WORD y2 = y + rp->TxHeight - 1;
807 RenderDisabledPattern(rp, x, y, x2, y2, mhd);
812 static void MakeMenuWin(struct MenuHandlerData *mhd)
814 struct MenuItem *item;
816 WORD width = mhd->activemenu->BeatX - mhd->activemenu->JazzX + 1;
817 WORD height = mhd->activemenu->BeatY - mhd->activemenu->JazzY + 1;
818 #if MENUS_UNDERMOUSE
819 WORD xpos = mhd->menubarwin->LeftEdge + mhd->menubarwin->Width - 16;
820 WORD ypos = mhd->menubarwin->TopEdge;
821 #else
822 WORD xpos =
823 mhd->activemenu->LeftEdge + mhd->scr->BarHBorder +
824 mhd->activemenu->JazzX;
826 #if MENUS_AMIGALOOK
827 WORD ypos = mhd->scr->BarHeight + 1 + mhd->activemenu->JazzY;
828 #else
829 WORD ypos = mhd->scr->BarHeight + 1;
830 #endif
832 #endif
834 struct TagItem win_tags[9];
836 win_tags[0].ti_Tag = WA_Left;
837 win_tags[0].ti_Data = xpos;
838 win_tags[1].ti_Tag = WA_Top;
839 win_tags[1].ti_Data = ypos;
840 win_tags[2].ti_Tag = WA_Width;
841 win_tags[2].ti_Data = width;
842 win_tags[3].ti_Tag = WA_Height;
843 win_tags[3].ti_Data = height;
844 win_tags[4].ti_Tag = WA_AutoAdjust;
845 win_tags[4].ti_Data = TRUE;
846 win_tags[5].ti_Tag = WA_Borderless;
847 win_tags[5].ti_Data = TRUE;
848 win_tags[6].ti_Tag = WA_CustomScreen;
849 win_tags[6].ti_Data = (IPTR) mhd->scr;
850 win_tags[7].ti_Tag = WA_BackFill;
851 win_tags[7].ti_Tag = (IPTR) LAYERS_NOBACKFILL;
852 win_tags[8].ti_Tag = TAG_DONE;
855 #if MENUS_UNDERMOUSE
856 win_tags[1].ti_Data +=
857 (mhd->menubaritemheight * mhd->activemenunum +
858 mhd->scr->MenuVBorder) - height / 2;
859 if (xpos + width > mhd->scr->Width)
861 win_tags[0].ti_Data = mhd->menubarwin->LeftEdge - width + 16;
863 #endif
865 if ((item = mhd->activemenu->FirstItem))
867 while (item)
869 item->Flags &= ~HIGHITEM;
870 item = item->NextItem;
872 mhd->menuwin = OpenWindowTagList(0, win_tags);
874 mhd->maxcommkeywidth_menu = CalcMaxCommKeyWidth(mhd->menuwin, mhd);
876 RenderMenu(mhd);
878 mhd->activemenu->Flags |= MIDRAWN;
883 static void KillMenuWin(struct MenuHandlerData *mhd)
885 if (mhd->menuwin)
887 struct MenuItem *item;
889 CloseWindow(mhd->menuwin);
890 mhd->menuwin = NULL;
892 for (item = mhd->activemenu->FirstItem; item; item = item->NextItem)
894 item->Flags &= ~ISDRAWN;
897 mhd->activemenu->Flags &= ~MIDRAWN;
899 mhd->activeitemnum = -1;
900 mhd->activeitem = NULL;
905 static void RenderMenu(struct MenuHandlerData *mhd)
908 if (mhd->menuwin)
910 struct MenuItem *item;
912 RenderMenuBG(mhd->menuwin, mhd);
914 SetFont(mhd->menuwin->RPort, mhd->dri->dri_Font);
916 for (item = mhd->activemenu->FirstItem; item; item = item->NextItem)
918 RenderItem(item, ITEM_ITEM,
919 (struct Rectangle *)(&mhd->activemenu->JazzX), mhd);
925 static void MakeSubMenuWin(struct MenuHandlerData *mhd)
927 struct MenuItem *item = mhd->activeitem->SubItem;
928 struct TagItem win_tags[9];
930 win_tags[0].ti_Tag = WA_Left;
931 win_tags[0].ti_Data = 0;
932 win_tags[1].ti_Tag = WA_Top;
933 win_tags[1].ti_Data = 0;
934 win_tags[2].ti_Tag = WA_Width;
935 win_tags[2].ti_Data = 0;
936 win_tags[3].ti_Tag = WA_Height;
937 win_tags[3].ti_Data = 0;
938 win_tags[4].ti_Tag = WA_AutoAdjust;
939 win_tags[4].ti_Data = TRUE;
940 win_tags[5].ti_Tag = WA_Borderless;
941 win_tags[5].ti_Data = TRUE;
942 win_tags[6].ti_Tag = WA_CustomScreen;
943 win_tags[6].ti_Data = (IPTR) mhd->scr;
944 win_tags[7].ti_Tag = WA_BackFill;
945 win_tags[7].ti_Tag = (IPTR) LAYERS_NOBACKFILL;
946 win_tags[8].ti_Tag = TAG_DONE;
948 GetMenuBox(mhd->menubarwin, item, &mhd->submenubox.MinX,
949 &mhd->submenubox.MinY,
950 &mhd->submenubox.MaxX, &mhd->submenubox.MaxY);
952 win_tags[0].ti_Data = mhd->menuwin->LeftEdge +
953 mhd->activeitem->LeftEdge - mhd->activemenu->JazzX +
954 mhd->submenubox.MinX;
956 win_tags[1].ti_Data = mhd->menuwin->TopEdge +
957 mhd->activeitem->TopEdge - mhd->activemenu->JazzY +
958 mhd->submenubox.MinY;
960 win_tags[2].ti_Data = mhd->submenubox.MaxX - mhd->submenubox.MinX + 1;
961 win_tags[3].ti_Data = mhd->submenubox.MaxY - mhd->submenubox.MinY + 1;
963 while (item)
965 item->Flags &= ~HIGHITEM;
966 item = item->NextItem;
969 mhd->submenuwin = OpenWindowTagList(0, win_tags);
971 mhd->maxcommkeywidth_submenu =
972 CalcMaxCommKeyWidth(mhd->submenuwin, mhd);
974 RenderSubMenu(mhd);
978 static void KillSubMenuWin(struct MenuHandlerData *mhd)
980 if (mhd->submenuwin)
982 CloseWindow(mhd->submenuwin);
983 mhd->submenuwin = NULL;
985 mhd->activesubitemnum = -1;
986 mhd->activesubitem = NULL;
991 static void RenderSubMenu(struct MenuHandlerData *mhd)
994 if (mhd->submenuwin)
996 struct MenuItem *item;
998 RenderMenuBG(mhd->submenuwin, mhd);
1000 SetFont(mhd->submenuwin->RPort, mhd->dri->dri_Font);
1002 for (item = mhd->activeitem->SubItem; item; item = item->NextItem)
1004 RenderItem(item, ITEM_SUBITEM,
1005 (struct Rectangle *)(&mhd->submenubox), mhd);
1011 static void RenderItem(struct MenuItem *item, WORD itemtype,
1012 struct Rectangle *box, struct MenuHandlerData *mhd)
1014 struct Window *win =
1015 ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1016 struct RastPort *rp = win->RPort;
1017 WORD offx = -box->MinX;
1018 WORD offy = -box->MinY;
1019 BOOL enabled = ((item->Flags & ITEMENABLED) &&
1020 (mhd->activemenu->Flags & MENUENABLED) &&
1021 ((itemtype == ITEM_ITEM)
1022 || (mhd->activeitem->Flags & ITEMENABLED)));
1023 BOOL item_supports_disable = FALSE;
1025 SetDrMd(rp, JAM1);
1027 if (item->ItemFill)
1029 if (item->Flags & ITEMTEXT)
1031 #if MENUS_AMIGALOOK
1032 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1034 PrintIText(rp, it, offx + item->LeftEdge, offy + item->TopEdge);
1035 #else
1036 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1038 it->FrontPen =
1039 mhd->dri->dri_Pens[(item->
1040 Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN];
1041 it->DrawMode = JAM1;
1043 PrintIText(rp, it, offx + item->LeftEdge, offy + item->TopEdge);
1044 #endif
1046 else
1048 struct Image *im = (struct Image *)item->ItemFill;
1049 LONG state = IDS_NORMAL;
1051 if (!enabled && (im->Depth == CUSTOMIMAGEDEPTH))
1053 IPTR val = 0;
1055 GetAttr(IA_SupportsDisable, (Object *) im, &val);
1056 if (val)
1058 item_supports_disable = TRUE;
1059 state = IDS_DISABLED;
1063 DrawImageState(rp, im, offx + item->LeftEdge,
1064 offy + item->TopEdge, state, mhd->dri);
1067 } /* if (item->ItemFill) */
1069 RenderCheckMark(item, itemtype, mhd);
1070 RenderAmigaKey(item, itemtype, mhd);
1072 if (!enabled && !item_supports_disable)
1074 RenderDisabledPattern(rp, offx + item->LeftEdge,
1075 offy + item->TopEdge,
1076 offx + item->LeftEdge + item->Width - 1,
1077 offy + item->TopEdge + item->Height - 1, mhd);
1083 static void RenderMenuBG(struct Window *win, struct MenuHandlerData *mhd)
1085 struct RastPort *rp = win->RPort;
1087 #if MENUS_AMIGALOOK
1088 WORD borderx = mhd->scr->MenuHBorder / 2;
1089 WORD bordery = mhd->scr->MenuVBorder / 2;
1090 #else
1091 WORD borderx = 1;
1092 WORD bordery = 1;
1093 #endif
1095 /* White background */
1097 #if MENUS_AMIGALOOK
1098 SetABPenDrMd(rp, mhd->dri->dri_Pens[BARBLOCKPEN], 0, JAM1);
1099 #else
1100 SetABPenDrMd(rp, mhd->dri->dri_Pens[BACKGROUNDPEN], 0, JAM1);
1101 #endif
1102 RectFill(rp, borderx,
1103 bordery, win->Width - 1 - borderx, win->Height - 1 - bordery);
1105 /* Black border frame */
1107 #if MENUS_AMIGALOOK
1108 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
1109 RectFill(rp, 0, 0, win->Width - 1, bordery - 1);
1110 RectFill(rp, 0, bordery, borderx - 1, win->Height - 1 - bordery);
1111 RectFill(rp, win->Width - borderx, bordery, win->Width - 1,
1112 win->Height - 1);
1113 RectFill(rp, 0, win->Height - bordery, win->Width - 1 - borderx,
1114 win->Height - 1);
1115 #else
1116 RenderFrame(rp, 0, 0, win->Width - 1, win->Height - 1, IDS_NORMAL, mhd);
1117 #endif
1121 static void RenderCheckMark(struct MenuItem *item, WORD itemtype,
1122 struct MenuHandlerData *mhd)
1124 struct Window *win =
1125 ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1126 struct RastPort *rp = win->RPort;
1127 struct Rectangle *box =
1128 ((itemtype ==
1129 ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->
1130 JazzX) : &mhd->submenubox);
1131 WORD offx = -box->MinX;
1132 WORD offy = -box->MinY;
1133 WORD state = ((item->Flags & HIGHITEM) &&
1134 ((item->Flags & HIGHFLAGS) ==
1135 HIGHCOMP)) ? IDS_SELECTED : IDS_NORMAL;
1137 if (item->Flags & CHECKIT)
1139 WORD x1, y1, x2, y2;
1141 x1 = item->LeftEdge + offx;
1142 y1 = item->TopEdge + offy + (item->Height -
1143 mhd->checkmark->Height) / 2;
1144 x2 = x1 + mhd->checkmark->Width - 1;
1145 y2 = y1 + mhd->checkmark->Height - 1;
1147 SetDrMd(rp, JAM1);
1149 if (item->Flags & CHECKED)
1151 DrawImageState(rp, mhd->checkmark, x1, y1, state, mhd->dri);
1153 else
1155 #if MENUS_AMIGALOOK
1156 SetAPen(rp, mhd->dri->dri_Pens[BARBLOCKPEN]);
1157 #else
1158 SetAPen(rp,
1159 mhd->dri->dri_Pens[(state ==
1160 IDS_SELECTED) ? FILLPEN : BACKGROUNDPEN]);
1161 #endif
1162 RectFill(rp, x1, y1, x2, y2);
1169 static void RenderAmigaKey(struct MenuItem *item, WORD itemtype,
1170 struct MenuHandlerData *mhd)
1172 struct Window *win =
1173 ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1174 struct RastPort *rp = win->RPort;
1175 struct Rectangle *box =
1176 ((itemtype ==
1177 ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->
1178 JazzX) : &mhd->submenubox);
1179 WORD commkeywidth =
1180 ((itemtype ==
1181 ITEM_ITEM) ? mhd->maxcommkeywidth_menu : mhd->
1182 maxcommkeywidth_submenu);
1183 WORD offx = -box->MinX;
1184 WORD offy = -box->MinY;
1185 WORD state = ((item->Flags & HIGHITEM) &&
1186 ((item->Flags & HIGHFLAGS) ==
1187 HIGHCOMP)) ? IDS_SELECTED : IDS_NORMAL;
1189 if (item->Flags & COMMSEQ)
1191 struct TextFont *oldfont = rp->Font;
1192 struct TextFont *newfont = NULL;
1194 WORD x1, y1;
1196 if (item->Flags & ITEMTEXT)
1198 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1200 if (it->ITextFont)
1202 if ((newfont = OpenFont(it->ITextFont)))
1204 SetFont(rp, newfont);
1209 x1 = item->LeftEdge + offx + item->Width - AMIGAKEY_BORDER_SPACING -
1210 mhd->amigakey->Width - AMIGAKEY_KEY_SPACING - commkeywidth;
1211 y1 = item->TopEdge + offy + (item->Height - mhd->amigakey->Height +
1212 1) / 2;
1214 SetDrMd(rp, JAM1);
1216 DrawImageState(rp, mhd->amigakey, x1, y1, state, mhd->dri);
1218 x1 += mhd->amigakey->Width + AMIGAKEY_KEY_SPACING;
1220 #if MENUS_AMIGALOOK
1221 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
1222 #else
1223 SetAPen(rp,
1224 mhd->dri->dri_Pens[(item->
1225 Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN]);
1226 #endif
1227 Move(rp, x1,
1228 item->TopEdge + offy + (item->Height - rp->TxHeight) / 2 +
1229 rp->TxBaseline);
1230 Text(rp, &item->Command, 1);
1232 if (newfont)
1234 CloseFont(newfont);
1235 SetFont(rp, oldfont);
1241 static void RenderDisabledPattern(struct RastPort *rp, WORD x1, WORD y1,
1242 WORD x2, WORD y2, struct MenuHandlerData *mhd)
1244 static UWORD pattern[] = { 0x8888, 0x2222 };
1246 SetDrMd(rp, JAM1);
1247 #if MENUS_AMIGALOOK
1248 SetAPen(rp, mhd->dri->dri_Pens[BARBLOCKPEN]);
1249 #else
1250 SetAPen(rp, mhd->dri->dri_Pens[BACKGROUNDPEN]);
1251 #endif
1253 SetAfPt(rp, pattern, 1);
1255 RectFill(rp, x1, y1, x2, y2);
1257 SetAfPt(rp, NULL, 0);
1261 #if 0
1262 static void RenderFrame(struct RastPort *rp, WORD x1, WORD y1, WORD x2,
1263 WORD y2, WORD state, struct MenuHandlerData *mhd)
1265 SetAPen(rp,
1266 mhd->dri->dri_Pens[(state == IDS_SELECTED) ? SHADOWPEN : SHINEPEN]);
1268 RectFill(rp, x1, y1, x2, y1);
1269 RectFill(rp, x1, y1 + 1, x1, y2);
1271 SetAPen(rp,
1272 mhd->dri->dri_Pens[(state == IDS_SELECTED) ? SHINEPEN : SHADOWPEN]);
1273 RectFill(rp, x2, y1 + 1, x2, y2);
1274 RectFill(rp, x1 + 1, y2, x2 - 1, y2);
1276 #endif
1279 static void HighlightItem(struct MenuItem *item, WORD itemtype,
1280 struct MenuHandlerData *mhd)
1282 struct Window *win =
1283 ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1284 struct RastPort *rp = win->RPort;
1285 struct Rectangle *box =
1286 ((itemtype ==
1287 ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->
1288 JazzX) : &mhd->submenubox);
1289 APTR fill;
1290 WORD offx = -box->MinX;
1291 WORD offy = -box->MinY;
1292 WORD x1, y1, x2, y2;
1293 BOOL enabled;
1295 enabled = (item->Flags & ITEMENABLED) ? TRUE : FALSE;
1296 if (!(mhd->activemenu->Flags & MENUENABLED))
1297 enabled = FALSE;
1298 if ((itemtype == ITEM_SUBITEM)
1299 && !(mhd->activeitem->Flags & ITEMENABLED))
1300 enabled = FALSE;
1302 if (enabled)
1304 item->Flags ^= HIGHITEM;
1306 fill = item->ItemFill;
1307 if ((item->Flags & HIGHITEM) && (item->SelectFill))
1308 fill = item->SelectFill;
1310 x1 = offx + item->LeftEdge;
1311 y1 = offy + item->TopEdge;
1312 x2 = x1 + item->Width - 1;
1313 y2 = y1 + item->Height - 1;
1315 switch (item->Flags & HIGHFLAGS)
1317 case HIGHIMAGE:
1318 SetDrMd(rp, JAM1);
1320 if (item->Flags & ITEMTEXT)
1322 #if MENUS_AMIGALOOK
1323 PrintIText(rp, (struct IntuiText *)fill, x1, y1);
1324 #else
1325 struct IntuiText *it = (struct IntuiText *)fill;
1327 it->FrontPen = mhd->dri->dri_Pens[TEXTPEN];
1328 it->DrawMode = JAM1;
1330 PrintIText(rp, it, x1, y1);
1331 #endif
1333 else
1335 EraseImage(rp, (struct Image *)fill, x1, y1);
1336 DrawImageState(rp, (struct Image *)fill, x1, y1,
1337 IDS_SELECTED, mhd->dri);
1339 break;
1341 case HIGHCOMP:
1342 #if MENUS_AMIGALOOK
1343 SetDrMd(rp, COMPLEMENT);
1344 RectFill(rp, x1, y1, x2, y2);
1345 #else
1347 WORD state =
1348 (item->Flags & HIGHITEM) ? IDS_SELECTED : IDS_NORMAL;
1350 SetDrMd(rp, JAM1);
1351 SetAPen(rp,
1352 mhd->dri->dri_Pens[(state ==
1353 IDS_SELECTED) ? FILLPEN : BACKGROUNDPEN]);
1354 RectFill(rp, x1, y1, x2, y2);
1356 RenderItem(item, itemtype, box, mhd);
1358 if (state == IDS_SELECTED)
1360 RenderFrame(rp, x1, y1, x2, y2, state, mhd);
1363 #endif
1364 break;
1366 case HIGHBOX:
1367 SetDrMd(rp, COMPLEMENT);
1368 offx = mhd->scr->MenuHBorder;
1369 offy = mhd->scr->MenuVBorder;
1371 x1 -= offx;
1372 x2 += offx;
1373 y1 -= offy;
1374 y2 += offy;
1376 RectFill(rp, x1, y1, x2, y1 + offy - 1);
1377 RectFill(rp, x2 - offx + 1, y1 + offy, x2, y2);
1378 RectFill(rp, x1, y2 - offy + 1, x2 - offx, y2);
1379 RectFill(rp, x1, y1 + offy, x1 + offx - 1, y2 - offy);
1380 break;
1382 case HIGHNONE:
1383 /* Do nothing */
1384 break;
1391 static WORD CalcMaxCommKeyWidth(struct Window *win,
1392 struct MenuHandlerData *mhd)
1394 WORD maxwidth = mhd->dri->dri_Font->tf_XSize;
1396 if (win)
1398 struct MenuItem *item;
1400 if ((win == mhd->menuwin))
1402 item = mhd->activemenu->FirstItem;
1404 else
1406 item = mhd->activeitem->SubItem;
1409 for (; item; item = item->NextItem)
1411 if (item->Flags & ITEMTEXT)
1413 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1415 if (it->ITextFont)
1417 struct TextFont *font;
1419 if ((font = OpenFont(it->ITextFont)))
1421 if (font->tf_XSize > maxwidth)
1422 maxwidth = font->tf_XSize;
1424 CloseFont(font);
1431 return maxwidth;
1435 static void AddToSelection(struct MenuHandlerData *mhd)
1437 if ((mhd->activemenunum != -1) && (mhd->activemenu->Flags & MENUENABLED)
1438 && (mhd->activeitemnum != -1)
1439 && (mhd->activeitem->Flags & ITEMENABLED))
1441 struct MenuItem *item = NULL;
1442 UWORD men =
1443 FULLMENUNUM(mhd->activemenunum, mhd->activeitemnum,
1444 mhd->activesubitemnum);
1446 if (mhd->activesubitemnum != -1)
1448 if (mhd->activesubitem->Flags & ITEMENABLED)
1449 item = mhd->activesubitem;
1451 else if (!mhd->activeitem->SubItem)
1453 item = mhd->activeitem;
1456 if (item && (ItemAddress(mhd->menu, men) == item))
1458 UWORD men =
1459 FULLMENUNUM(mhd->activemenunum, mhd->activeitemnum,
1460 mhd->activesubitemnum);
1462 if (mhd->firstmenupick == MENUNULL)
1464 mhd->firstmenupick = men;
1466 else if (men != mhd->lastmenupick)
1468 struct MenuItem *checkitem, *prevcheckitem = NULL;
1469 UWORD checkmen = mhd->firstmenupick;
1471 /* Remove men from pick queue, if it was already in there
1472 and then add it at the end of the pick queue */
1474 while (checkmen != MENUNULL)
1476 checkitem = ItemAddress(mhd->menu, checkmen);
1478 if (checkmen == men)
1480 if (prevcheckitem == NULL)
1482 mhd->firstmenupick = checkitem->NextSelect;
1484 else
1486 prevcheckitem->NextSelect =
1487 checkitem->NextSelect;
1491 checkmen = checkitem->NextSelect;
1492 prevcheckitem = checkitem;
1495 checkitem->NextSelect = men;
1498 mhd->lastmenupick = men;
1499 item->NextSelect = MENUNULL;
1505 /** END AROS **/
1507 struct ZMenu
1509 struct MenuHandlerData mhd;
1512 struct ZMenu *zune_open_menu(struct Window *wnd, struct NewMenu *newmenu)
1514 struct TagItem tags[] = {
1515 {GTMN_NewLookMenus, TRUE},
1516 {TAG_DONE}
1519 struct ZMenu *zmenu;
1520 struct Menu *menu;
1521 APTR visinfo;
1522 zmenu = (struct ZMenu *)AllocVec(sizeof(struct ZMenu), MEMF_CLEAR);
1523 if (!zmenu)
1524 return NULL;
1526 visinfo = GetVisualInfoA(wnd->WScreen, NULL);
1527 if (!visinfo)
1529 FreeVec(zmenu);
1530 return NULL;
1533 if (!(menu = CreateMenusA(newmenu, NULL)))
1535 FreeVec(zmenu);
1536 return NULL;
1539 LayoutMenusA(menu, visinfo, tags);
1540 FreeVisualInfo(visinfo);
1542 Characterize(menu);
1543 CalculateDims(wnd, menu);
1545 zmenu->mhd.win = wnd;
1546 zmenu->mhd.scr = zmenu->mhd.win->WScreen;
1547 zmenu->mhd.dri = GetScreenDrawInfo(zmenu->mhd.scr);
1548 zmenu->mhd.menu = menu;
1549 zmenu->mhd.activemenunum = -1;
1550 zmenu->mhd.activeitemnum = -1;
1551 zmenu->mhd.activesubitemnum = -1;
1552 zmenu->mhd.checkmark = zmenu->mhd.dri->dri_CheckMark;
1553 zmenu->mhd.amigakey = zmenu->mhd.dri->dri_AmigaKey;
1554 zmenu->mhd.scrmousex = zmenu->mhd.scr->MouseX;
1555 zmenu->mhd.scrmousey = zmenu->mhd.scr->MouseY;
1556 zmenu->mhd.firstmenupick = MENUNULL;
1558 MakeMenuBarWin(&zmenu->mhd);
1559 HandleMouseMove(&zmenu->mhd);
1560 return zmenu;
1563 void zune_mouse_update(struct ZMenu *zmenu, int left_down)
1565 if (!zmenu)
1566 return;
1568 if (!left_down)
1569 HandleMouseMove(&zmenu->mhd);
1570 else
1571 HandleMouseClick(&zmenu->mhd, 0);
1574 void zune_leave_menu(struct ZMenu *zmenu, struct zlm *res)
1576 HandleMouseClick(&zmenu->mhd, 1);
1578 res->item = ItemAddress(zmenu->mhd.menu, zmenu->mhd.firstmenupick);
1580 if (!res->item)
1582 struct Layer *lay;
1583 struct MenuHandlerData *mhd = &zmenu->mhd;
1585 LockLayerInfo(&mhd->scr->LayerInfo);
1586 lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey);
1587 UnlockLayerInfo(&mhd->scr->LayerInfo);
1589 if (lay)
1591 struct Window *win = (struct Window *)lay->Window;
1593 if (win && (win == mhd->menubarwin)
1594 && (mhd->activemenunum != -1))
1596 res->menu = mhd->activemenu;
1602 /* returns the address of the selected menuitem entry */
1603 void zune_close_menu(struct ZMenu *zmenu)
1605 if (!zmenu)
1606 return;
1608 KillMenuBarWin(&zmenu->mhd);
1609 KillMenuWin(&zmenu->mhd);
1610 KillSubMenuWin(&zmenu->mhd);
1612 FreeMenus(zmenu->mhd.menu);
1613 zmenu->mhd.menu = 0;
1615 if (zmenu->mhd.dri)
1617 FreeScreenDrawInfo(zmenu->mhd.scr, zmenu->mhd.dri);
1618 zmenu->mhd.dri = 0;
1621 // MH2Int_MakeMenusInactive(mhd->win, mhd->firstmenupick);
1622 zmenu->mhd.active = FALSE;
1624 FreeVec(zmenu);
1627 struct Menu *zune_get_menu_pointer(struct ZMenu *menu)
1629 return menu->mhd.menu;