muimaster.library: revert r50831
[AROS.git] / workbench / libs / muimaster / menu.c
blob5fbb7294e84a265e6d8643cc92b3e5f8fff16bce
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"
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)
51 *xmin = left - win->WScreen->MenuHBorder;
52 if (ymin)
53 *ymin = top - win->WScreen->MenuVBorder;
54 if (xmax)
55 *xmax = right + win->WScreen->MenuHBorder;
56 if (ymax)
57 *ymax = bottom + win->WScreen->MenuVBorder;
61 void CalculateDims(struct Window *win, struct Menu *menu)
63 struct MenuItem *item;
65 while (menu != NULL)
67 item = menu->FirstItem;
69 GetMenuBox(win, item, &menu->JazzX, &menu->JazzY, &menu->BeatX,
70 &menu->BeatY);
72 menu = menu->NextMenu;
76 /* Mark items that has subitems. This is necessary for the input handler
77 code. It's not possible to check item->SubItem within it as we save
78 the layer coordinates there. */
79 void Characterize(struct Menu *menu)
81 while (menu != NULL)
83 struct MenuItem *item;
85 item = menu->FirstItem;
87 while (item != NULL)
89 // if(item->SubItem != NULL)
90 // item->Flags |= HASSUBITEM;
92 item = item->NextItem;
95 menu = menu->NextMenu;
99 #define MENUS_UNDERMOUSE 1
100 #define MENUS_AMIGALOOK 1
102 /** BEGIN AROS **/
104 #define ITEM_ITEM 1
105 #define ITEM_SUBITEM 2
107 #define AMIGAKEY_KEY_SPACING 4 /* GadTools assumes this, too */
108 #define AMIGAKEY_BORDER_SPACING 2
110 struct MenuHandlerData
112 struct Window *win;
113 struct Screen *scr;
114 struct DrawInfo *dri;
115 struct Window *menubarwin;
116 struct Window *menuwin;
117 struct Window *submenuwin;
118 struct Menu *menu;
119 struct Menu *activemenu;
120 struct MenuItem *activeitem;
121 struct MenuItem *activesubitem;
122 struct Rectangle submenubox;
123 struct Image *checkmark;
124 struct Image *amigakey;
125 WORD menubarwidth;
126 WORD menubarheight;
127 WORD menubaritemwidth;
128 WORD menubaritemheight;
129 WORD nummenubaritems;
130 WORD activemenunum;
131 WORD activeitemnum;
132 WORD activesubitemnum;
133 WORD maxcommkeywidth_menu;
134 WORD maxcommkeywidth_submenu;
135 WORD scrmousex;
136 WORD scrmousey;
137 UWORD firstmenupick;
138 UWORD lastmenupick;
139 BOOL active;
142 /* this #defines are taken from workbench/libs/gadtools/menus.c!! */
144 #define TEXT_AMIGAKEY_SPACING 6
146 #define ITEXT_EXTRA_LEFT 2
147 #define ITEXT_EXTRA_RIGHT 2
148 #define ITEXT_EXTRA_TOP 1
149 #define ITEXT_EXTRA_BOTTOM 1
151 static const char subitemindicator[] = "»";
154 static void HandleMouseMove(struct MenuHandlerData *mhd);
155 static void HandleMouseClick(struct MenuHandlerData *mhd, int menuup);
156 static void HandleCheckItem(struct Window *win, struct MenuItem *item,
157 WORD itemnum, struct MenuHandlerData *mhd);
159 static void HighlightMenuTitle(struct Menu *menu,
160 struct MenuHandlerData *mhd);
162 static struct Menu *FindMenu(WORD *var, struct MenuHandlerData *mhd);
163 static struct MenuItem *FindItem(WORD *var, struct MenuHandlerData *mhd);
164 static struct MenuItem *FindSubItem(WORD *var,
165 struct MenuHandlerData *mhd);
167 static void MakeMenuBarWin(struct MenuHandlerData *mhd);
168 static void KillMenuBarWin(struct MenuHandlerData *mhd);
169 static void RenderMenuBar(struct MenuHandlerData *mhd);
171 static void MakeMenuWin(struct MenuHandlerData *mhd);
172 static void KillMenuWin(struct MenuHandlerData *mhd);
173 static void RenderMenu(struct MenuHandlerData *mhd);
174 static void RenderMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd);
176 static void MakeSubMenuWin(struct MenuHandlerData *mhd);
177 static void KillSubMenuWin(struct MenuHandlerData *mhd);
178 static void RenderSubMenu(struct MenuHandlerData *mhd);
180 static void RenderItem(struct MenuItem *item, WORD itemtype,
181 struct Rectangle *box, struct MenuHandlerData *mhd);
183 static void RenderMenuBG(struct Window *win, struct MenuHandlerData *mhd);
184 static void RenderCheckMark(struct MenuItem *item, WORD itemtype,
185 struct MenuHandlerData *mhd);
186 static void RenderAmigaKey(struct MenuItem *item, WORD itemtype,
187 struct MenuHandlerData *mhd);
188 static void RenderDisabledPattern(struct RastPort *rp, WORD x1, WORD y1,
189 WORD x2, WORD y2, struct MenuHandlerData *mhd);
190 #if 0
191 static void RenderFrame(struct RastPort *rp, WORD x1, WORD y1, WORD x2,
192 WORD y2, WORD state, struct MenuHandlerData *mhd);
193 #endif
194 static void HighlightItem(struct MenuItem *item, WORD itemtype,
195 struct MenuHandlerData *mhd);
196 static WORD CalcMaxCommKeyWidth(struct Window *win,
197 struct MenuHandlerData *mhd);
198 static void AddToSelection(struct MenuHandlerData *mhd);
202 static void HandleMouseMove(struct MenuHandlerData *mhd)
204 struct Layer *lay;
205 struct Window *win = NULL;
206 struct Menu *menu;
207 struct MenuItem *item;
209 WORD new_activemenunum = mhd->activemenunum;
210 WORD new_activeitemnum = mhd->activeitemnum;
211 WORD new_activesubitemnum = mhd->activesubitemnum;
213 mhd->scrmousex = mhd->scr->MouseX;
214 mhd->scrmousey = mhd->scr->MouseY;
216 LockLayerInfo(&mhd->scr->LayerInfo);
217 lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey);
218 UnlockLayerInfo(&mhd->scr->LayerInfo);
220 if (lay)
222 win = (struct Window *)lay->Window;
224 if (win && (win == mhd->submenuwin))
226 /* Mouse over submenu box */
227 item = FindSubItem(&new_activesubitemnum, mhd);
229 if (new_activesubitemnum != mhd->activesubitemnum)
231 if (mhd->activesubitemnum != -1)
233 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd);
236 mhd->activesubitemnum = new_activesubitemnum;
237 mhd->activesubitem = item;
239 if (item)
241 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd);
246 else if (win && (win == mhd->menuwin))
248 item = FindItem(&new_activeitemnum, mhd);
250 if (new_activeitemnum != mhd->activeitemnum)
252 if (mhd->activeitemnum != -1)
254 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd);
255 KillSubMenuWin(mhd);
258 mhd->activeitemnum = new_activeitemnum;
259 mhd->activeitem = item;
261 if (item)
263 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd);
265 if (item->SubItem)
267 MakeSubMenuWin(mhd);
272 else if (win && (win == mhd->menubarwin))
274 /* Mouse over menu box */
276 menu = FindMenu(&new_activemenunum, mhd);
278 if (new_activemenunum != mhd->activemenunum)
280 if (mhd->activemenunum != -1)
282 HighlightMenuTitle(mhd->activemenu, mhd);
283 KillMenuWin(mhd);
284 KillSubMenuWin(mhd);
287 mhd->activemenunum = new_activemenunum;
288 mhd->activemenu = menu;
290 if (menu)
292 HighlightMenuTitle(mhd->activemenu, mhd);
293 MakeMenuWin(mhd);
297 if ((mhd->activeitemnum != -1) && (!mhd->submenuwin))
299 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd);
300 mhd->activeitemnum = -1;
301 mhd->activeitem = NULL;
304 else
306 win = NULL;
310 if (!win)
312 /* mouse outside any menu window */
314 if ((mhd->activeitemnum != -1) && (!mhd->submenuwin))
316 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd);
317 mhd->activeitemnum = -1;
318 mhd->activeitem = NULL;
320 else if (mhd->activesubitemnum != -1)
322 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd);
323 mhd->activesubitemnum = -1;
324 mhd->activesubitem = NULL;
331 static void HandleMouseClick(struct MenuHandlerData *mhd, int menuup)
333 struct Layer *lay;
335 LockLayerInfo(&mhd->scr->LayerInfo);
336 lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey);
337 UnlockLayerInfo(&mhd->scr->LayerInfo);
339 if (lay)
341 struct Window *win = (struct Window *)lay->Window;
342 struct MenuItem *item = NULL;
343 WORD itemnum = 0;
345 win = (struct Window *)lay->Window;
347 if (win && (win == mhd->submenuwin)
348 && (mhd->activesubitemnum != -1))
350 item = mhd->activesubitem;
352 else if (win && (win == mhd->menuwin) && (mhd->activeitemnum != -1))
354 item = mhd->activeitem;
357 if (item)
358 if (item->Flags & CHECKIT)
360 HandleCheckItem(win, item, itemnum, mhd);
363 AddToSelection(mhd);
368 static void HandleCheckItem(struct Window *win, struct MenuItem *item,
369 WORD itemnum, struct MenuHandlerData *mhd)
371 /* Note: If you change something here, you probably must also change
372 menus.c/CheckMenuItemWasClicked() which is used when the
373 user uses the menu key shortcuts! */
375 WORD itemtype = ((win == mhd->menuwin) ? ITEM_ITEM : ITEM_SUBITEM);
377 BOOL re_render = FALSE;
379 if (item->Flags & MENUTOGGLE)
381 item->Flags ^= CHECKED;
382 re_render = TRUE;
384 else
386 if (!(item->Flags & CHECKED))
388 item->Flags |= CHECKED;
389 re_render = TRUE;
393 if (re_render)
395 BOOL toggle_hi = FALSE;
397 if ((item->Flags & HIGHITEM) &&
398 ((item->Flags & HIGHFLAGS) == HIGHCOMP))
399 toggle_hi = TRUE;
401 if (toggle_hi)
402 HighlightItem(item, itemtype, mhd);
403 RenderCheckMark(item, itemtype, mhd);
404 if (toggle_hi)
405 HighlightItem(item, itemtype, mhd);
409 if (item->MutualExclude)
411 struct MenuItem *checkitem =
412 (itemtype ==
413 ITEM_ITEM) ? mhd->activemenu->FirstItem : mhd->activeitem->
414 SubItem;
415 BOOL toggle_hi = FALSE;
416 WORD i;
418 if ((item->Flags & HIGHITEM) &&
419 ((item->Flags & HIGHFLAGS) == HIGHBOX))
420 toggle_hi = TRUE;
422 if (toggle_hi)
423 HighlightItem(item, itemtype, mhd);
425 for (i = 0; (i < 32) && checkitem;
426 i++, checkitem = checkitem->NextItem)
428 if ((i != itemnum) && (item->MutualExclude & (1L << i)) &&
429 ((checkitem->Flags & (CHECKED | CHECKIT)) ==
430 (CHECKIT | CHECKED)))
432 checkitem->Flags &= ~CHECKED;
433 RenderCheckMark(checkitem, itemtype, mhd);
437 if (toggle_hi)
438 HighlightItem(item, itemtype, mhd);
443 static void HighlightMenuTitle(struct Menu *menu,
444 struct MenuHandlerData *mhd)
446 if (menu->Flags & MENUENABLED)
448 struct RastPort *rp = mhd->menubarwin->RPort;
450 #if MENUS_UNDERMOUSE
451 struct Menu *m = mhd->menu;
452 WORD x1 = mhd->scr->MenuHBorder;
453 WORD x2 = x1 + mhd->menubaritemwidth - 1;
454 WORD y1, y2, i;
456 for (i = 0; m != menu; m = m->NextMenu)
457 i++;
459 y1 = mhd->scr->MenuVBorder + i * mhd->menubaritemheight;
460 y2 = y1 + mhd->menubaritemheight - 1;
462 #else
463 WORD x1 =
464 menu->LeftEdge + mhd->scr->BarHBorder - mhd->scr->MenuHBorder;
465 WORD y1 = 0;
466 WORD x2 = x1 + menu->Width - 1;
467 WORD y2 = mhd->scr->BarHeight - 1;
468 #endif
470 #if MENUS_AMIGALOOK
471 SetDrMd(rp, COMPLEMENT);
472 RectFill(rp, x1, y1, x2, y2);
473 #else
474 menu->Flags ^= HIGHITEM;
476 #if !MENUS_UNDERMOUSE
477 y1++;
478 #endif
480 SetDrMd(rp, JAM1);
481 SetAPen(rp,
482 mhd->dri->dri_Pens[(menu->
483 Flags & HIGHITEM) ? FILLPEN : BACKGROUNDPEN]);
484 RectFill(rp, x1, y1, x2, y2);
486 RenderMenuTitle(menu, mhd);
488 if (menu->Flags & HIGHITEM)
490 #if MENUS_UNDERMOUSE
491 RenderFrame(rp, x1, y1, x2, y2, IDS_SELECTED, mhd);
492 #else
493 SetAPen(rp, mhd->dri->dri_Pens[SHINEPEN]);
494 RectFill(rp, x1, y1, x1, y2);
495 SetAPen(rp, mhd->dri->dri_Pens[SHADOWPEN]);
496 RectFill(rp, x2, y1, x2, y2);
497 #endif
501 #endif /* MENUS_AMIGALOOK */
506 static struct Menu *FindMenu(WORD *var, struct MenuHandlerData *mhd)
508 struct Menu *menu;
509 WORD mouse_x, mouse_y, i;
511 mouse_x = mhd->scrmousex - mhd->menubarwin->LeftEdge;
512 mouse_y = mhd->scrmousey - mhd->menubarwin->TopEdge;
514 #if MENUS_UNDERMOUSE
515 menu = NULL;
517 mouse_x -= mhd->scr->MenuHBorder;
518 mouse_y -= mhd->scr->MenuVBorder;
520 if ((mouse_x >= 0) && (mouse_x < mhd->menubaritemwidth)
521 && (mouse_y >= 0))
523 i = mouse_y / mhd->menubaritemheight;
525 if ((i >= 0) && (i < mhd->nummenubaritems))
527 WORD i2 = i;
529 menu = mhd->menu;
530 while (i && menu)
532 i--;
533 menu = menu->NextMenu;
536 if (menu && (i == 0))
538 *var = i2;
542 #else
543 for (menu = mhd->menu, i = 0; menu; menu = menu->NextMenu, i++)
545 if ((mouse_x >= menu->LeftEdge) &&
546 (mouse_x < menu->LeftEdge + menu->Width) &&
547 (mouse_y >= 0) && (mouse_y <= mhd->scr->BarHeight))
549 *var = i;
550 break;
553 #endif
555 return menu;
559 static struct MenuItem *FindItem(WORD *var, struct MenuHandlerData *mhd)
561 struct MenuItem *item = NULL;
562 WORD mouse_x, mouse_y, i;
564 if (mhd->menuwin)
566 mouse_x =
567 mhd->scrmousex - mhd->menuwin->LeftEdge +
568 mhd->activemenu->JazzX;
569 mouse_y =
570 mhd->scrmousey - mhd->menuwin->TopEdge + mhd->activemenu->JazzY;
572 for (item = mhd->activemenu->FirstItem, i = 0; item;
573 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;
586 if ((item == NULL) && !mhd->submenuwin)
587 *var = -1;
589 return item;
593 static struct MenuItem *FindSubItem(WORD *var, struct MenuHandlerData *mhd)
595 struct MenuItem *item = NULL;
596 WORD mouse_x, mouse_y, i;
598 if (mhd->submenuwin)
600 mouse_x =
601 mhd->scrmousex - mhd->submenuwin->LeftEdge +
602 mhd->submenubox.MinX;
603 mouse_y =
604 mhd->scrmousey - mhd->submenuwin->TopEdge +
605 mhd->submenubox.MinY;
607 *var = -1;
609 for (item = mhd->activeitem->SubItem, i = 0; item;
610 item = item->NextItem, i++)
612 if ((mouse_x >= item->LeftEdge) &&
613 (mouse_x < item->LeftEdge + item->Width) &&
614 (mouse_y >= item->TopEdge) &&
615 (mouse_y < item->TopEdge + item->Height))
617 *var = i;
618 break;
624 return item;
628 static void MakeMenuBarWin(struct MenuHandlerData *mhd)
630 struct TagItem win_tags[9];
631 struct Menu *menu;
633 #if MENUS_UNDERMOUSE
634 WORD w, maxw = 0;
635 #endif
637 win_tags[0].ti_Tag = WA_Left;
638 win_tags[0].ti_Data = 0;
639 win_tags[1].ti_Tag = WA_Top;
640 win_tags[1].ti_Data = 0;
641 win_tags[2].ti_Tag = WA_Width;
642 win_tags[2].ti_Data = mhd->scr->Width;
643 win_tags[3].ti_Tag = WA_Height;
644 win_tags[3].ti_Data = mhd->scr->BarHeight + 1;
645 win_tags[4].ti_Tag = WA_AutoAdjust;
646 win_tags[4].ti_Data = TRUE;
647 win_tags[5].ti_Tag = WA_Borderless;
648 win_tags[5].ti_Data = TRUE;
649 win_tags[6].ti_Tag = WA_CustomScreen;
650 win_tags[6].ti_Data = (IPTR) mhd->scr;
651 win_tags[7].ti_Tag = WA_BackFill;
652 win_tags[7].ti_Tag = (IPTR) LAYERS_NOBACKFILL;
653 win_tags[8].ti_Tag = TAG_DONE;
655 #if MENUS_UNDERMOUSE
657 mhd->nummenubaritems = 0;
658 for (menu = mhd->menu; menu; menu = menu->NextMenu)
660 w = TextLength(&mhd->scr->RastPort, menu->MenuName,
661 strlen(menu->MenuName));
662 if (w > maxw)
663 maxw = w;
664 mhd->nummenubaritems++;
667 mhd->menubaritemwidth =
668 maxw + TextLength(&mhd->scr->RastPort, subitemindicator,
669 1) + TEXT_AMIGAKEY_SPACING + ITEXT_EXTRA_LEFT + ITEXT_EXTRA_RIGHT;
671 mhd->menubaritemheight =
672 mhd->scr->RastPort.TxHeight + ITEXT_EXTRA_TOP + ITEXT_EXTRA_BOTTOM;
674 win_tags[2].ti_Data = mhd->menubaritemwidth + mhd->scr->MenuHBorder * 2;
675 win_tags[3].ti_Data =
676 mhd->menubaritemheight * mhd->nummenubaritems +
677 mhd->scr->MenuVBorder * 2;
678 win_tags[0].ti_Data = mhd->scr->MouseX - win_tags[2].ti_Data / 2;
679 win_tags[1].ti_Data = mhd->scr->MouseY;
681 #endif
683 mhd->menubarwin = OpenWindowTagList(0, win_tags);
685 for (menu = mhd->menu; menu; menu = menu->NextMenu)
687 menu->Flags &= ~HIGHITEM;
690 RenderMenuBar(mhd);
694 static void KillMenuBarWin(struct MenuHandlerData *mhd)
696 if (mhd->menubarwin)
698 CloseWindow(mhd->menubarwin);
699 mhd->menubarwin = NULL;
704 static void RenderMenuBar(struct MenuHandlerData *mhd)
706 if (mhd->menubarwin)
708 struct Menu *menu = mhd->menu;
709 struct RastPort *rp = mhd->menubarwin->RPort;
711 SetFont(rp, mhd->dri->dri_Font);
713 #if MENUS_UNDERMOUSE
715 RenderMenuBG(mhd->menubarwin, mhd);
717 #else
719 #if MENUS_AMIGALOOK
720 SetABPenDrMd(rp, mhd->dri->dri_Pens[BARBLOCKPEN], 0, JAM1);
721 #else
722 SetABPenDrMd(rp, mhd->dri->dri_Pens[BACKGROUNDPEN], 0, JAM1);
723 #endif
724 RectFill(rp, 0, 0, mhd->menubarwin->Width - 1,
725 mhd->menubarwin->Height - 2);
726 SetAPen(rp, mhd->dri->dri_Pens[BARTRIMPEN]);
727 RectFill(rp, 0, mhd->menubarwin->Height - 1,
728 mhd->menubarwin->Width - 1, mhd->menubarwin->Height - 1);
730 #if !MENUS_AMIGALOOK
731 SetAPen(rp, mhd->dri->dri_Pens[SHINEPEN]);
732 RectFill(rp, 0, 0, 0, mhd->menubarwin->Height - 2);
733 RectFill(rp, 1, 0, mhd->menubarwin->Width - 1, 0);
734 SetAPen(rp, mhd->dri->dri_Pens[SHADOWPEN]);
735 RectFill(rp, mhd->menubarwin->Width - 1, 1,
736 mhd->menubarwin->Width - 1, mhd->menubarwin->Height - 2);
738 #endif
740 #endif
742 for (; menu; menu = menu->NextMenu)
744 RenderMenuTitle(menu, mhd);
750 static void RenderMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd)
752 struct RastPort *rp = mhd->menubarwin->RPort;
753 WORD len = strlen(menu->MenuName);
755 #if MENUS_UNDERMOUSE
756 struct Menu *m;
757 WORD x, y, yoff;
759 yoff = 0;
760 for (m = mhd->menu; m && (m != menu); m = m->NextMenu)
762 yoff++;
765 x = mhd->scr->MenuHBorder + ITEXT_EXTRA_LEFT;
766 y = mhd->scr->MenuVBorder + ITEXT_EXTRA_TOP +
767 yoff * mhd->menubaritemheight;
768 #else
769 WORD x = mhd->scr->BarHBorder + menu->LeftEdge;
770 WORD y = mhd->scr->BarVBorder;
771 #endif
773 #if MENUS_AMIGALOOK
774 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
775 #else
776 SetAPen(rp,
777 mhd->dri->dri_Pens[(menu->
778 Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN]);
779 #endif
781 Move(rp, x, y + rp->TxBaseline);
782 Text(rp, menu->MenuName, len);
784 #if MENUS_UNDERMOUSE
785 if (menu->FirstItem)
787 WORD silen = TextLength(rp, subitemindicator, 1);
788 WORD x2 =
789 mhd->scr->MenuHBorder + mhd->menubaritemwidth -
790 ITEXT_EXTRA_RIGHT - silen;
792 Move(rp, x2, y + rp->TxBaseline);
793 Text(rp, subitemindicator, 1);
795 #endif
797 if (!(menu->Flags & MENUENABLED))
799 #if MENUS_UNDERMOUSE
800 WORD x2 = mhd->scr->MenuHBorder + mhd->menubaritemwidth - 1;
801 #else
802 WORD x2 = x + TextLength(rp, menu->MenuName, len) - 1;
803 #endif
804 WORD y2 = y + rp->TxHeight - 1;
806 RenderDisabledPattern(rp, x, y, x2, y2, mhd);
811 static void MakeMenuWin(struct MenuHandlerData *mhd)
813 struct MenuItem *item;
815 WORD width = mhd->activemenu->BeatX - mhd->activemenu->JazzX + 1;
816 WORD height = mhd->activemenu->BeatY - mhd->activemenu->JazzY + 1;
817 #if MENUS_UNDERMOUSE
818 WORD xpos = mhd->menubarwin->LeftEdge + mhd->menubarwin->Width - 16;
819 WORD ypos = mhd->menubarwin->TopEdge;
820 #else
821 WORD xpos =
822 mhd->activemenu->LeftEdge + mhd->scr->BarHBorder +
823 mhd->activemenu->JazzX;
825 #if MENUS_AMIGALOOK
826 WORD ypos = mhd->scr->BarHeight + 1 + mhd->activemenu->JazzY;
827 #else
828 WORD ypos = mhd->scr->BarHeight + 1;
829 #endif
831 #endif
833 struct TagItem win_tags[9];
835 win_tags[0].ti_Tag = WA_Left;
836 win_tags[0].ti_Data = xpos;
837 win_tags[1].ti_Tag = WA_Top;
838 win_tags[1].ti_Data = ypos;
839 win_tags[2].ti_Tag = WA_Width;
840 win_tags[2].ti_Data = width;
841 win_tags[3].ti_Tag = WA_Height;
842 win_tags[3].ti_Data = height;
843 win_tags[4].ti_Tag = WA_AutoAdjust;
844 win_tags[4].ti_Data = TRUE;
845 win_tags[5].ti_Tag = WA_Borderless;
846 win_tags[5].ti_Data = TRUE;
847 win_tags[6].ti_Tag = WA_CustomScreen;
848 win_tags[6].ti_Data = (IPTR) mhd->scr;
849 win_tags[7].ti_Tag = WA_BackFill;
850 win_tags[7].ti_Tag = (IPTR) LAYERS_NOBACKFILL;
851 win_tags[8].ti_Tag = TAG_DONE;
854 #if MENUS_UNDERMOUSE
855 win_tags[1].ti_Data +=
856 (mhd->menubaritemheight * mhd->activemenunum +
857 mhd->scr->MenuVBorder) - height / 2;
858 if (xpos + width > mhd->scr->Width)
860 win_tags[0].ti_Data = mhd->menubarwin->LeftEdge - width + 16;
862 #endif
864 if ((item = mhd->activemenu->FirstItem))
866 while (item)
868 item->Flags &= ~HIGHITEM;
869 item = item->NextItem;
871 mhd->menuwin = OpenWindowTagList(0, win_tags);
873 mhd->maxcommkeywidth_menu = CalcMaxCommKeyWidth(mhd->menuwin, mhd);
875 RenderMenu(mhd);
877 mhd->activemenu->Flags |= MIDRAWN;
882 static void KillMenuWin(struct MenuHandlerData *mhd)
884 if (mhd->menuwin)
886 struct MenuItem *item;
888 CloseWindow(mhd->menuwin);
889 mhd->menuwin = NULL;
891 for (item = mhd->activemenu->FirstItem; item; item = item->NextItem)
893 item->Flags &= ~ISDRAWN;
896 mhd->activemenu->Flags &= ~MIDRAWN;
898 mhd->activeitemnum = -1;
899 mhd->activeitem = NULL;
904 static void RenderMenu(struct MenuHandlerData *mhd)
907 if (mhd->menuwin)
909 struct MenuItem *item;
911 RenderMenuBG(mhd->menuwin, mhd);
913 SetFont(mhd->menuwin->RPort, mhd->dri->dri_Font);
915 for (item = mhd->activemenu->FirstItem; item; item = item->NextItem)
917 RenderItem(item, ITEM_ITEM,
918 (struct Rectangle *)(&mhd->activemenu->JazzX), mhd);
924 static void MakeSubMenuWin(struct MenuHandlerData *mhd)
926 struct MenuItem *item = mhd->activeitem->SubItem;
927 struct TagItem win_tags[9];
929 win_tags[0].ti_Tag = WA_Left;
930 win_tags[0].ti_Data = 0;
931 win_tags[1].ti_Tag = WA_Top;
932 win_tags[1].ti_Data = 0;
933 win_tags[2].ti_Tag = WA_Width;
934 win_tags[2].ti_Data = 0;
935 win_tags[3].ti_Tag = WA_Height;
936 win_tags[3].ti_Data = 0;
937 win_tags[4].ti_Tag = WA_AutoAdjust;
938 win_tags[4].ti_Data = TRUE;
939 win_tags[5].ti_Tag = WA_Borderless;
940 win_tags[5].ti_Data = TRUE;
941 win_tags[6].ti_Tag = WA_CustomScreen;
942 win_tags[6].ti_Data = (IPTR) mhd->scr;
943 win_tags[7].ti_Tag = WA_BackFill;
944 win_tags[7].ti_Tag = (IPTR) LAYERS_NOBACKFILL;
945 win_tags[8].ti_Tag = TAG_DONE;
947 GetMenuBox(mhd->menubarwin, item, &mhd->submenubox.MinX,
948 &mhd->submenubox.MinY,
949 &mhd->submenubox.MaxX, &mhd->submenubox.MaxY);
951 win_tags[0].ti_Data = mhd->menuwin->LeftEdge +
952 mhd->activeitem->LeftEdge - mhd->activemenu->JazzX +
953 mhd->submenubox.MinX;
955 win_tags[1].ti_Data = mhd->menuwin->TopEdge +
956 mhd->activeitem->TopEdge - mhd->activemenu->JazzY +
957 mhd->submenubox.MinY;
959 win_tags[2].ti_Data = mhd->submenubox.MaxX - mhd->submenubox.MinX + 1;
960 win_tags[3].ti_Data = mhd->submenubox.MaxY - mhd->submenubox.MinY + 1;
962 while (item)
964 item->Flags &= ~HIGHITEM;
965 item = item->NextItem;
968 mhd->submenuwin = OpenWindowTagList(0, win_tags);
970 mhd->maxcommkeywidth_submenu =
971 CalcMaxCommKeyWidth(mhd->submenuwin, mhd);
973 RenderSubMenu(mhd);
977 static void KillSubMenuWin(struct MenuHandlerData *mhd)
979 if (mhd->submenuwin)
981 CloseWindow(mhd->submenuwin);
982 mhd->submenuwin = NULL;
984 mhd->activesubitemnum = -1;
985 mhd->activesubitem = NULL;
990 static void RenderSubMenu(struct MenuHandlerData *mhd)
993 if (mhd->submenuwin)
995 struct MenuItem *item;
997 RenderMenuBG(mhd->submenuwin, mhd);
999 SetFont(mhd->submenuwin->RPort, mhd->dri->dri_Font);
1001 for (item = mhd->activeitem->SubItem; item; item = item->NextItem)
1003 RenderItem(item, ITEM_SUBITEM,
1004 (struct Rectangle *)(&mhd->submenubox), mhd);
1010 static void RenderItem(struct MenuItem *item, WORD itemtype,
1011 struct Rectangle *box, struct MenuHandlerData *mhd)
1013 struct Window *win =
1014 ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1015 struct RastPort *rp = win->RPort;
1016 WORD offx = -box->MinX;
1017 WORD offy = -box->MinY;
1018 BOOL enabled = ((item->Flags & ITEMENABLED) &&
1019 (mhd->activemenu->Flags & MENUENABLED) &&
1020 ((itemtype == ITEM_ITEM)
1021 || (mhd->activeitem->Flags & ITEMENABLED)));
1022 BOOL item_supports_disable = FALSE;
1024 SetDrMd(rp, JAM1);
1026 if (item->ItemFill)
1028 if (item->Flags & ITEMTEXT)
1030 #if MENUS_AMIGALOOK
1031 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1033 PrintIText(rp, it, offx + item->LeftEdge, offy + item->TopEdge);
1034 #else
1035 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1037 it->FrontPen =
1038 mhd->dri->dri_Pens[(item->
1039 Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN];
1040 it->DrawMode = JAM1;
1042 PrintIText(rp, it, offx + item->LeftEdge, offy + item->TopEdge);
1043 #endif
1045 else
1047 struct Image *im = (struct Image *)item->ItemFill;
1048 LONG state = IDS_NORMAL;
1050 if (!enabled && (im->Depth == CUSTOMIMAGEDEPTH))
1052 IPTR val = 0;
1054 GetAttr(IA_SupportsDisable, (Object *) im, &val);
1055 if (val)
1057 item_supports_disable = TRUE;
1058 state = IDS_DISABLED;
1062 DrawImageState(rp, im, offx + item->LeftEdge,
1063 offy + item->TopEdge, state, mhd->dri);
1066 } /* if (item->ItemFill) */
1068 RenderCheckMark(item, itemtype, mhd);
1069 RenderAmigaKey(item, itemtype, mhd);
1071 if (!enabled && !item_supports_disable)
1073 RenderDisabledPattern(rp, offx + item->LeftEdge,
1074 offy + item->TopEdge,
1075 offx + item->LeftEdge + item->Width - 1,
1076 offy + item->TopEdge + item->Height - 1, mhd);
1082 static void RenderMenuBG(struct Window *win, struct MenuHandlerData *mhd)
1084 struct RastPort *rp = win->RPort;
1086 #if MENUS_AMIGALOOK
1087 WORD borderx = mhd->scr->MenuHBorder / 2;
1088 WORD bordery = mhd->scr->MenuVBorder / 2;
1089 #else
1090 WORD borderx = 1;
1091 WORD bordery = 1;
1092 #endif
1094 /* White background */
1096 #if MENUS_AMIGALOOK
1097 SetABPenDrMd(rp, mhd->dri->dri_Pens[BARBLOCKPEN], 0, JAM1);
1098 #else
1099 SetABPenDrMd(rp, mhd->dri->dri_Pens[BACKGROUNDPEN], 0, JAM1);
1100 #endif
1101 RectFill(rp, borderx,
1102 bordery, win->Width - 1 - borderx, win->Height - 1 - bordery);
1104 /* Black border frame */
1106 #if MENUS_AMIGALOOK
1107 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
1108 RectFill(rp, 0, 0, win->Width - 1, bordery - 1);
1109 RectFill(rp, 0, bordery, borderx - 1, win->Height - 1 - bordery);
1110 RectFill(rp, win->Width - borderx, bordery, win->Width - 1,
1111 win->Height - 1);
1112 RectFill(rp, 0, win->Height - bordery, win->Width - 1 - borderx,
1113 win->Height - 1);
1114 #else
1115 RenderFrame(rp, 0, 0, win->Width - 1, win->Height - 1, IDS_NORMAL, mhd);
1116 #endif
1120 static void RenderCheckMark(struct MenuItem *item, WORD itemtype,
1121 struct MenuHandlerData *mhd)
1123 struct Window *win =
1124 ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1125 struct RastPort *rp = win->RPort;
1126 struct Rectangle *box =
1127 ((itemtype ==
1128 ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->
1129 JazzX) : &mhd->submenubox);
1130 WORD offx = -box->MinX;
1131 WORD offy = -box->MinY;
1132 WORD state = ((item->Flags & HIGHITEM) &&
1133 ((item->Flags & HIGHFLAGS) ==
1134 HIGHCOMP)) ? IDS_SELECTED : IDS_NORMAL;
1136 if (item->Flags & CHECKIT)
1138 WORD x1, y1, x2, y2;
1140 x1 = item->LeftEdge + offx;
1141 y1 = item->TopEdge + offy + (item->Height -
1142 mhd->checkmark->Height) / 2;
1143 x2 = x1 + mhd->checkmark->Width - 1;
1144 y2 = y1 + mhd->checkmark->Height - 1;
1146 SetDrMd(rp, JAM1);
1148 if (item->Flags & CHECKED)
1150 DrawImageState(rp, mhd->checkmark, x1, y1, state, mhd->dri);
1152 else
1154 #if MENUS_AMIGALOOK
1155 SetAPen(rp, mhd->dri->dri_Pens[BARBLOCKPEN]);
1156 #else
1157 SetAPen(rp,
1158 mhd->dri->dri_Pens[(state ==
1159 IDS_SELECTED) ? FILLPEN : BACKGROUNDPEN]);
1160 #endif
1161 RectFill(rp, x1, y1, x2, y2);
1168 static void RenderAmigaKey(struct MenuItem *item, WORD itemtype,
1169 struct MenuHandlerData *mhd)
1171 struct Window *win =
1172 ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1173 struct RastPort *rp = win->RPort;
1174 struct Rectangle *box =
1175 ((itemtype ==
1176 ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->
1177 JazzX) : &mhd->submenubox);
1178 WORD commkeywidth =
1179 ((itemtype ==
1180 ITEM_ITEM) ? mhd->maxcommkeywidth_menu : mhd->
1181 maxcommkeywidth_submenu);
1182 WORD offx = -box->MinX;
1183 WORD offy = -box->MinY;
1184 WORD state = ((item->Flags & HIGHITEM) &&
1185 ((item->Flags & HIGHFLAGS) ==
1186 HIGHCOMP)) ? IDS_SELECTED : IDS_NORMAL;
1188 if (item->Flags & COMMSEQ)
1190 struct TextFont *oldfont = rp->Font;
1191 struct TextFont *newfont = NULL;
1193 WORD x1, y1;
1195 if (item->Flags & ITEMTEXT)
1197 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1199 if (it->ITextFont)
1201 if ((newfont = OpenFont(it->ITextFont)))
1203 SetFont(rp, newfont);
1208 x1 = item->LeftEdge + offx + item->Width - AMIGAKEY_BORDER_SPACING -
1209 mhd->amigakey->Width - AMIGAKEY_KEY_SPACING - commkeywidth;
1210 y1 = item->TopEdge + offy + (item->Height - mhd->amigakey->Height +
1211 1) / 2;
1213 SetDrMd(rp, JAM1);
1215 DrawImageState(rp, mhd->amigakey, x1, y1, state, mhd->dri);
1217 x1 += mhd->amigakey->Width + AMIGAKEY_KEY_SPACING;
1219 #if MENUS_AMIGALOOK
1220 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
1221 #else
1222 SetAPen(rp,
1223 mhd->dri->dri_Pens[(item->
1224 Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN]);
1225 #endif
1226 Move(rp, x1,
1227 item->TopEdge + offy + (item->Height - rp->TxHeight) / 2 +
1228 rp->TxBaseline);
1229 Text(rp, &item->Command, 1);
1231 if (newfont)
1233 CloseFont(newfont);
1234 SetFont(rp, oldfont);
1240 static void RenderDisabledPattern(struct RastPort *rp, WORD x1, WORD y1,
1241 WORD x2, WORD y2, struct MenuHandlerData *mhd)
1243 static UWORD pattern[] = { 0x8888, 0x2222 };
1245 SetDrMd(rp, JAM1);
1246 #if MENUS_AMIGALOOK
1247 SetAPen(rp, mhd->dri->dri_Pens[BARBLOCKPEN]);
1248 #else
1249 SetAPen(rp, mhd->dri->dri_Pens[BACKGROUNDPEN]);
1250 #endif
1252 SetAfPt(rp, pattern, 1);
1254 RectFill(rp, x1, y1, x2, y2);
1256 SetAfPt(rp, NULL, 0);
1260 #if 0
1261 static void RenderFrame(struct RastPort *rp, WORD x1, WORD y1, WORD x2,
1262 WORD y2, WORD state, struct MenuHandlerData *mhd)
1264 SetAPen(rp,
1265 mhd->dri->dri_Pens[(state == IDS_SELECTED) ? SHADOWPEN : SHINEPEN]);
1267 RectFill(rp, x1, y1, x2, y1);
1268 RectFill(rp, x1, y1 + 1, x1, y2);
1270 SetAPen(rp,
1271 mhd->dri->dri_Pens[(state == IDS_SELECTED) ? SHINEPEN : SHADOWPEN]);
1272 RectFill(rp, x2, y1 + 1, x2, y2);
1273 RectFill(rp, x1 + 1, y2, x2 - 1, y2);
1275 #endif
1278 static void HighlightItem(struct MenuItem *item, WORD itemtype,
1279 struct MenuHandlerData *mhd)
1281 struct Window *win =
1282 ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1283 struct RastPort *rp = win->RPort;
1284 struct Rectangle *box =
1285 ((itemtype ==
1286 ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->
1287 JazzX) : &mhd->submenubox);
1288 APTR fill;
1289 WORD offx = -box->MinX;
1290 WORD offy = -box->MinY;
1291 WORD x1, y1, x2, y2;
1292 BOOL enabled;
1294 enabled = (item->Flags & ITEMENABLED) ? TRUE : FALSE;
1295 if (!(mhd->activemenu->Flags & MENUENABLED))
1296 enabled = FALSE;
1297 if ((itemtype == ITEM_SUBITEM)
1298 && !(mhd->activeitem->Flags & ITEMENABLED))
1299 enabled = FALSE;
1301 if (enabled)
1303 item->Flags ^= HIGHITEM;
1305 fill = item->ItemFill;
1306 if ((item->Flags & HIGHITEM) && (item->SelectFill))
1307 fill = item->SelectFill;
1309 x1 = offx + item->LeftEdge;
1310 y1 = offy + item->TopEdge;
1311 x2 = x1 + item->Width - 1;
1312 y2 = y1 + item->Height - 1;
1314 switch (item->Flags & HIGHFLAGS)
1316 case HIGHIMAGE:
1317 SetDrMd(rp, JAM1);
1319 if (item->Flags & ITEMTEXT)
1321 #if MENUS_AMIGALOOK
1322 PrintIText(rp, (struct IntuiText *)fill, x1, y1);
1323 #else
1324 struct IntuiText *it = (struct IntuiText *)fill;
1326 it->FrontPen = mhd->dri->dri_Pens[TEXTPEN];
1327 it->DrawMode = JAM1;
1329 PrintIText(rp, it, x1, y1);
1330 #endif
1332 else
1334 EraseImage(rp, (struct Image *)fill, x1, y1);
1335 DrawImageState(rp, (struct Image *)fill, x1, y1,
1336 IDS_SELECTED, mhd->dri);
1338 break;
1340 case HIGHCOMP:
1341 #if MENUS_AMIGALOOK
1342 SetDrMd(rp, COMPLEMENT);
1343 RectFill(rp, x1, y1, x2, y2);
1344 #else
1346 WORD state =
1347 (item->Flags & HIGHITEM) ? IDS_SELECTED : IDS_NORMAL;
1349 SetDrMd(rp, JAM1);
1350 SetAPen(rp,
1351 mhd->dri->dri_Pens[(state ==
1352 IDS_SELECTED) ? FILLPEN : BACKGROUNDPEN]);
1353 RectFill(rp, x1, y1, x2, y2);
1355 RenderItem(item, itemtype, box, mhd);
1357 if (state == IDS_SELECTED)
1359 RenderFrame(rp, x1, y1, x2, y2, state, mhd);
1362 #endif
1363 break;
1365 case HIGHBOX:
1366 SetDrMd(rp, COMPLEMENT);
1367 offx = mhd->scr->MenuHBorder;
1368 offy = mhd->scr->MenuVBorder;
1370 x1 -= offx;
1371 x2 += offx;
1372 y1 -= offy;
1373 y2 += offy;
1375 RectFill(rp, x1, y1, x2, y1 + offy - 1);
1376 RectFill(rp, x2 - offx + 1, y1 + offy, x2, y2);
1377 RectFill(rp, x1, y2 - offy + 1, x2 - offx, y2);
1378 RectFill(rp, x1, y1 + offy, x1 + offx - 1, y2 - offy);
1379 break;
1381 case HIGHNONE:
1382 /* Do nothing */
1383 break;
1390 static WORD CalcMaxCommKeyWidth(struct Window *win,
1391 struct MenuHandlerData *mhd)
1393 WORD maxwidth = mhd->dri->dri_Font->tf_XSize;
1395 if (win)
1397 struct MenuItem *item;
1399 if ((win == mhd->menuwin))
1401 item = mhd->activemenu->FirstItem;
1403 else
1405 item = mhd->activeitem->SubItem;
1408 for (; item; item = item->NextItem)
1410 if (item->Flags & ITEMTEXT)
1412 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1414 if (it->ITextFont)
1416 struct TextFont *font;
1418 if ((font = OpenFont(it->ITextFont)))
1420 if (font->tf_XSize > maxwidth)
1421 maxwidth = font->tf_XSize;
1423 CloseFont(font);
1430 return maxwidth;
1434 static void AddToSelection(struct MenuHandlerData *mhd)
1436 if ((mhd->activemenunum != -1) && (mhd->activemenu->Flags & MENUENABLED)
1437 && (mhd->activeitemnum != -1)
1438 && (mhd->activeitem->Flags & ITEMENABLED))
1440 struct MenuItem *item = NULL;
1441 UWORD men =
1442 FULLMENUNUM(mhd->activemenunum, mhd->activeitemnum,
1443 mhd->activesubitemnum);
1445 if (mhd->activesubitemnum != -1)
1447 if (mhd->activesubitem->Flags & ITEMENABLED)
1448 item = mhd->activesubitem;
1450 else if (!mhd->activeitem->SubItem)
1452 item = mhd->activeitem;
1455 if (item && (ItemAddress(mhd->menu, men) == item))
1457 UWORD men =
1458 FULLMENUNUM(mhd->activemenunum, mhd->activeitemnum,
1459 mhd->activesubitemnum);
1461 if (mhd->firstmenupick == MENUNULL)
1463 mhd->firstmenupick = men;
1465 else if (men != mhd->lastmenupick)
1467 struct MenuItem *checkitem, *prevcheckitem = NULL;
1468 UWORD checkmen = mhd->firstmenupick;
1470 /* Remove men from pick queue, if it was already in there
1471 and then add it at the end of the pick queue */
1473 while (checkmen != MENUNULL)
1475 checkitem = ItemAddress(mhd->menu, checkmen);
1477 if (checkmen == men)
1479 if (prevcheckitem == NULL)
1481 mhd->firstmenupick = checkitem->NextSelect;
1483 else
1485 prevcheckitem->NextSelect =
1486 checkitem->NextSelect;
1490 checkmen = checkitem->NextSelect;
1491 prevcheckitem = checkitem;
1494 checkitem->NextSelect = men;
1497 mhd->lastmenupick = men;
1498 item->NextSelect = MENUNULL;
1504 /** END AROS **/
1506 struct ZMenu
1508 struct MenuHandlerData mhd;
1511 struct ZMenu *zune_open_menu(struct Window *wnd, struct NewMenu *newmenu)
1513 struct TagItem tags[] = {
1514 {GTMN_NewLookMenus, TRUE},
1515 {TAG_DONE}
1518 struct ZMenu *zmenu;
1519 struct Menu *menu;
1520 APTR visinfo;
1521 zmenu = (struct ZMenu *)AllocVec(sizeof(struct ZMenu), MEMF_CLEAR);
1522 if (!zmenu)
1523 return NULL;
1525 visinfo = GetVisualInfoA(wnd->WScreen, NULL);
1526 if (!visinfo)
1528 FreeVec(zmenu);
1529 return NULL;
1532 if (!(menu = CreateMenusA(newmenu, NULL)))
1534 FreeVec(zmenu);
1535 return NULL;
1538 LayoutMenusA(menu, visinfo, tags);
1539 FreeVisualInfo(visinfo);
1541 Characterize(menu);
1542 CalculateDims(wnd, menu);
1544 zmenu->mhd.win = wnd;
1545 zmenu->mhd.scr = zmenu->mhd.win->WScreen;
1546 zmenu->mhd.dri = GetScreenDrawInfo(zmenu->mhd.scr);
1547 zmenu->mhd.menu = menu;
1548 zmenu->mhd.activemenunum = -1;
1549 zmenu->mhd.activeitemnum = -1;
1550 zmenu->mhd.activesubitemnum = -1;
1551 zmenu->mhd.checkmark = zmenu->mhd.dri->dri_CheckMark;
1552 zmenu->mhd.amigakey = zmenu->mhd.dri->dri_AmigaKey;
1553 zmenu->mhd.scrmousex = zmenu->mhd.scr->MouseX;
1554 zmenu->mhd.scrmousey = zmenu->mhd.scr->MouseY;
1555 zmenu->mhd.firstmenupick = MENUNULL;
1557 MakeMenuBarWin(&zmenu->mhd);
1558 HandleMouseMove(&zmenu->mhd);
1559 return zmenu;
1562 void zune_mouse_update(struct ZMenu *zmenu, int left_down)
1564 if (!zmenu)
1565 return;
1567 if (!left_down)
1568 HandleMouseMove(&zmenu->mhd);
1569 else
1570 HandleMouseClick(&zmenu->mhd, 0);
1573 struct MenuItem *zune_leave_menu(struct ZMenu *zmenu)
1575 HandleMouseClick(&zmenu->mhd, 1);
1577 return ItemAddress(zmenu->mhd.menu, zmenu->mhd.firstmenupick);
1580 /* returns the address of the selected menuitem entry */
1581 void zune_close_menu(struct ZMenu *zmenu)
1583 if (!zmenu)
1584 return;
1586 KillMenuBarWin(&zmenu->mhd);
1587 KillMenuWin(&zmenu->mhd);
1588 KillSubMenuWin(&zmenu->mhd);
1590 FreeMenus(zmenu->mhd.menu);
1591 zmenu->mhd.menu = 0;
1593 if (zmenu->mhd.dri)
1595 FreeScreenDrawInfo(zmenu->mhd.scr, zmenu->mhd.dri);
1596 zmenu->mhd.dri = 0;
1599 // MH2Int_MakeMenusInactive(mhd->win, mhd->firstmenupick);
1600 zmenu->mhd.active = FALSE;
1602 FreeVec(zmenu);
1605 struct Menu *zune_get_menu_pointer(struct ZMenu *menu)
1607 return menu->mhd.menu;