Tabs to spaces, more consistent formatting.
[AROS.git] / workbench / libs / muimaster / menu.c
blob5b319b5d810109f0cbec5f9c2daac7c2b1a7d57c
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 if ((lay =
217 WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex,
218 mhd->scrmousey)))
220 win = (struct Window *)lay->Window;
222 if (win && (win == mhd->submenuwin))
224 /* Mouse over submenu box */
225 item = FindSubItem(&new_activesubitemnum, mhd);
227 if (new_activesubitemnum != mhd->activesubitemnum)
229 if (mhd->activesubitemnum != -1)
231 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd);
234 mhd->activesubitemnum = new_activesubitemnum;
235 mhd->activesubitem = item;
237 if (item)
239 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd);
244 else if (win && (win == mhd->menuwin))
246 item = FindItem(&new_activeitemnum, mhd);
248 if (new_activeitemnum != mhd->activeitemnum)
250 if (mhd->activeitemnum != -1)
252 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd);
253 KillSubMenuWin(mhd);
256 mhd->activeitemnum = new_activeitemnum;
257 mhd->activeitem = item;
259 if (item)
261 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd);
263 if (item->SubItem)
265 MakeSubMenuWin(mhd);
270 else if (win && (win == mhd->menubarwin))
272 /* Mouse over menu box */
274 menu = FindMenu(&new_activemenunum, mhd);
276 if (new_activemenunum != mhd->activemenunum)
278 if (mhd->activemenunum != -1)
280 HighlightMenuTitle(mhd->activemenu, mhd);
281 KillMenuWin(mhd);
282 KillSubMenuWin(mhd);
285 mhd->activemenunum = new_activemenunum;
286 mhd->activemenu = menu;
288 if (menu)
290 HighlightMenuTitle(mhd->activemenu, mhd);
291 MakeMenuWin(mhd);
295 if ((mhd->activeitemnum != -1) && (!mhd->submenuwin))
297 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd);
298 mhd->activeitemnum = -1;
299 mhd->activeitem = NULL;
302 else
304 win = NULL;
308 if (!win)
310 /* mouse outside any menu window */
312 if ((mhd->activeitemnum != -1) && (!mhd->submenuwin))
314 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd);
315 mhd->activeitemnum = -1;
316 mhd->activeitem = NULL;
318 else if (mhd->activesubitemnum != -1)
320 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd);
321 mhd->activesubitemnum = -1;
322 mhd->activesubitem = NULL;
329 static void HandleMouseClick(struct MenuHandlerData *mhd, int menuup)
331 struct Layer *lay;
333 if ((lay =
334 WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex,
335 mhd->scrmousey)))
337 struct Window *win = (struct Window *)lay->Window;
338 struct MenuItem *item = NULL;
339 WORD itemnum = 0;
341 win = (struct Window *)lay->Window;
343 if (win && (win == mhd->submenuwin)
344 && (mhd->activesubitemnum != -1))
346 item = mhd->activesubitem;
348 else if (win && (win == mhd->menuwin) && (mhd->activeitemnum != -1))
350 item = mhd->activeitem;
353 if (item)
354 if (item->Flags & CHECKIT)
356 HandleCheckItem(win, item, itemnum, mhd);
359 AddToSelection(mhd);
364 static void HandleCheckItem(struct Window *win, struct MenuItem *item,
365 WORD itemnum, struct MenuHandlerData *mhd)
367 /* Note: If you change something here, you probably must also change
368 menus.c/CheckMenuItemWasClicked() which is used when the
369 user uses the menu key shortcuts! */
371 WORD itemtype = ((win == mhd->menuwin) ? ITEM_ITEM : ITEM_SUBITEM);
373 BOOL re_render = FALSE;
375 if (item->Flags & MENUTOGGLE)
377 item->Flags ^= CHECKED;
378 re_render = TRUE;
380 else
382 if (!(item->Flags & CHECKED))
384 item->Flags |= CHECKED;
385 re_render = TRUE;
389 if (re_render)
391 BOOL toggle_hi = FALSE;
393 if ((item->Flags & HIGHITEM) &&
394 ((item->Flags & HIGHFLAGS) == HIGHCOMP))
395 toggle_hi = TRUE;
397 if (toggle_hi)
398 HighlightItem(item, itemtype, mhd);
399 RenderCheckMark(item, itemtype, mhd);
400 if (toggle_hi)
401 HighlightItem(item, itemtype, mhd);
405 if (item->MutualExclude)
407 struct MenuItem *checkitem =
408 (itemtype ==
409 ITEM_ITEM) ? mhd->activemenu->FirstItem : mhd->activeitem->
410 SubItem;
411 BOOL toggle_hi = FALSE;
412 WORD i;
414 if ((item->Flags & HIGHITEM) &&
415 ((item->Flags & HIGHFLAGS) == HIGHBOX))
416 toggle_hi = TRUE;
418 if (toggle_hi)
419 HighlightItem(item, itemtype, mhd);
421 for (i = 0; (i < 32) && checkitem;
422 i++, checkitem = checkitem->NextItem)
424 if ((i != itemnum) && (item->MutualExclude & (1L << i)) &&
425 ((checkitem->Flags & (CHECKED | CHECKIT)) ==
426 (CHECKIT | CHECKED)))
428 checkitem->Flags &= ~CHECKED;
429 RenderCheckMark(checkitem, itemtype, mhd);
433 if (toggle_hi)
434 HighlightItem(item, itemtype, mhd);
439 static void HighlightMenuTitle(struct Menu *menu,
440 struct MenuHandlerData *mhd)
442 if (menu->Flags & MENUENABLED)
444 struct RastPort *rp = mhd->menubarwin->RPort;
446 #if MENUS_UNDERMOUSE
447 struct Menu *m = mhd->menu;
448 WORD x1 = mhd->scr->MenuHBorder;
449 WORD x2 = x1 + mhd->menubaritemwidth - 1;
450 WORD y1, y2, i;
452 for (i = 0; m != menu; m = m->NextMenu)
453 i++;
455 y1 = mhd->scr->MenuVBorder + i * mhd->menubaritemheight;
456 y2 = y1 + mhd->menubaritemheight - 1;
458 #else
459 WORD x1 =
460 menu->LeftEdge + mhd->scr->BarHBorder - mhd->scr->MenuHBorder;
461 WORD y1 = 0;
462 WORD x2 = x1 + menu->Width - 1;
463 WORD y2 = mhd->scr->BarHeight - 1;
464 #endif
466 #if MENUS_AMIGALOOK
467 SetDrMd(rp, COMPLEMENT);
468 RectFill(rp, x1, y1, x2, y2);
469 #else
470 menu->Flags ^= HIGHITEM;
472 #if !MENUS_UNDERMOUSE
473 y1++;
474 #endif
476 SetDrMd(rp, JAM1);
477 SetAPen(rp,
478 mhd->dri->dri_Pens[(menu->
479 Flags & HIGHITEM) ? FILLPEN : BACKGROUNDPEN]);
480 RectFill(rp, x1, y1, x2, y2);
482 RenderMenuTitle(menu, mhd);
484 if (menu->Flags & HIGHITEM)
486 #if MENUS_UNDERMOUSE
487 RenderFrame(rp, x1, y1, x2, y2, IDS_SELECTED, mhd);
488 #else
489 SetAPen(rp, mhd->dri->dri_Pens[SHINEPEN]);
490 RectFill(rp, x1, y1, x1, y2);
491 SetAPen(rp, mhd->dri->dri_Pens[SHADOWPEN]);
492 RectFill(rp, x2, y1, x2, y2);
493 #endif
497 #endif /* MENUS_AMIGALOOK */
502 static struct Menu *FindMenu(WORD *var, struct MenuHandlerData *mhd)
504 struct Menu *menu;
505 WORD mouse_x, mouse_y, i;
507 mouse_x = mhd->scrmousex - mhd->menubarwin->LeftEdge;
508 mouse_y = mhd->scrmousey - mhd->menubarwin->TopEdge;
510 #if MENUS_UNDERMOUSE
511 menu = NULL;
513 mouse_x -= mhd->scr->MenuHBorder;
514 mouse_y -= mhd->scr->MenuVBorder;
516 if ((mouse_x >= 0) && (mouse_x < mhd->menubaritemwidth)
517 && (mouse_y >= 0))
519 i = mouse_y / mhd->menubaritemheight;
521 if ((i >= 0) && (i < mhd->nummenubaritems))
523 WORD i2 = i;
525 menu = mhd->menu;
526 while (i && menu)
528 i--;
529 menu = menu->NextMenu;
532 if (menu && (i == 0))
534 *var = i2;
538 #else
539 for (menu = mhd->menu, i = 0; menu; menu = menu->NextMenu, i++)
541 if ((mouse_x >= menu->LeftEdge) &&
542 (mouse_x < menu->LeftEdge + menu->Width) &&
543 (mouse_y >= 0) && (mouse_y <= mhd->scr->BarHeight))
545 *var = i;
546 break;
549 #endif
551 return menu;
555 static struct MenuItem *FindItem(WORD *var, struct MenuHandlerData *mhd)
557 struct MenuItem *item = NULL;
558 WORD mouse_x, mouse_y, i;
560 if (mhd->menuwin)
562 mouse_x =
563 mhd->scrmousex - mhd->menuwin->LeftEdge +
564 mhd->activemenu->JazzX;
565 mouse_y =
566 mhd->scrmousey - mhd->menuwin->TopEdge + mhd->activemenu->JazzY;
568 for (item = mhd->activemenu->FirstItem, i = 0; item;
569 item = item->NextItem, i++)
571 if ((mouse_x >= item->LeftEdge) &&
572 (mouse_x < item->LeftEdge + item->Width) &&
573 (mouse_y >= item->TopEdge) &&
574 (mouse_y < item->TopEdge + item->Height))
576 *var = i;
577 break;
582 if ((item == NULL) && !mhd->submenuwin)
583 *var = -1;
585 return item;
589 static struct MenuItem *FindSubItem(WORD *var, struct MenuHandlerData *mhd)
591 struct MenuItem *item = NULL;
592 WORD mouse_x, mouse_y, i;
594 if (mhd->submenuwin)
596 mouse_x =
597 mhd->scrmousex - mhd->submenuwin->LeftEdge +
598 mhd->submenubox.MinX;
599 mouse_y =
600 mhd->scrmousey - mhd->submenuwin->TopEdge +
601 mhd->submenubox.MinY;
603 *var = -1;
605 for (item = mhd->activeitem->SubItem, i = 0; item;
606 item = item->NextItem, i++)
608 if ((mouse_x >= item->LeftEdge) &&
609 (mouse_x < item->LeftEdge + item->Width) &&
610 (mouse_y >= item->TopEdge) &&
611 (mouse_y < item->TopEdge + item->Height))
613 *var = i;
614 break;
620 return item;
624 static void MakeMenuBarWin(struct MenuHandlerData *mhd)
626 struct TagItem win_tags[9];
627 struct Menu *menu;
629 #if MENUS_UNDERMOUSE
630 WORD w, maxw = 0;
631 #endif
633 win_tags[0].ti_Tag = WA_Left;
634 win_tags[0].ti_Data = 0;
635 win_tags[1].ti_Tag = WA_Top;
636 win_tags[1].ti_Data = 0;
637 win_tags[2].ti_Tag = WA_Width;
638 win_tags[2].ti_Data = mhd->scr->Width;
639 win_tags[3].ti_Tag = WA_Height;
640 win_tags[3].ti_Data = mhd->scr->BarHeight + 1;
641 win_tags[4].ti_Tag = WA_AutoAdjust;
642 win_tags[4].ti_Data = TRUE;
643 win_tags[5].ti_Tag = WA_Borderless;
644 win_tags[5].ti_Data = TRUE;
645 win_tags[6].ti_Tag = WA_CustomScreen;
646 win_tags[6].ti_Data = (IPTR) mhd->scr;
647 win_tags[7].ti_Tag = WA_BackFill;
648 win_tags[7].ti_Tag = (IPTR) LAYERS_NOBACKFILL;
649 win_tags[8].ti_Tag = TAG_DONE;
651 #if MENUS_UNDERMOUSE
653 mhd->nummenubaritems = 0;
654 for (menu = mhd->menu; menu; menu = menu->NextMenu)
656 w = TextLength(&mhd->scr->RastPort, menu->MenuName,
657 strlen(menu->MenuName));
658 if (w > maxw)
659 maxw = w;
660 mhd->nummenubaritems++;
663 mhd->menubaritemwidth =
664 maxw + TextLength(&mhd->scr->RastPort, subitemindicator,
665 1) + TEXT_AMIGAKEY_SPACING + ITEXT_EXTRA_LEFT + ITEXT_EXTRA_RIGHT;
667 mhd->menubaritemheight =
668 mhd->scr->RastPort.TxHeight + ITEXT_EXTRA_TOP + ITEXT_EXTRA_BOTTOM;
670 win_tags[2].ti_Data = mhd->menubaritemwidth + mhd->scr->MenuHBorder * 2;
671 win_tags[3].ti_Data =
672 mhd->menubaritemheight * mhd->nummenubaritems +
673 mhd->scr->MenuVBorder * 2;
674 win_tags[0].ti_Data = mhd->scr->MouseX - win_tags[2].ti_Data / 2;
675 win_tags[1].ti_Data = mhd->scr->MouseY;
677 #endif
679 mhd->menubarwin = OpenWindowTagList(0, win_tags);
681 for (menu = mhd->menu; menu; menu = menu->NextMenu)
683 menu->Flags &= ~HIGHITEM;
686 RenderMenuBar(mhd);
690 static void KillMenuBarWin(struct MenuHandlerData *mhd)
692 if (mhd->menubarwin)
694 CloseWindow(mhd->menubarwin);
695 mhd->menubarwin = NULL;
700 static void RenderMenuBar(struct MenuHandlerData *mhd)
702 if (mhd->menubarwin)
704 struct Menu *menu = mhd->menu;
705 struct RastPort *rp = mhd->menubarwin->RPort;
707 SetFont(rp, mhd->dri->dri_Font);
709 #if MENUS_UNDERMOUSE
711 RenderMenuBG(mhd->menubarwin, mhd);
713 #else
715 #if MENUS_AMIGALOOK
716 SetABPenDrMd(rp, mhd->dri->dri_Pens[BARBLOCKPEN], 0, JAM1);
717 #else
718 SetABPenDrMd(rp, mhd->dri->dri_Pens[BACKGROUNDPEN], 0, JAM1);
719 #endif
720 RectFill(rp, 0, 0, mhd->menubarwin->Width - 1,
721 mhd->menubarwin->Height - 2);
722 SetAPen(rp, mhd->dri->dri_Pens[BARTRIMPEN]);
723 RectFill(rp, 0, mhd->menubarwin->Height - 1,
724 mhd->menubarwin->Width - 1, mhd->menubarwin->Height - 1);
726 #if !MENUS_AMIGALOOK
727 SetAPen(rp, mhd->dri->dri_Pens[SHINEPEN]);
728 RectFill(rp, 0, 0, 0, mhd->menubarwin->Height - 2);
729 RectFill(rp, 1, 0, mhd->menubarwin->Width - 1, 0);
730 SetAPen(rp, mhd->dri->dri_Pens[SHADOWPEN]);
731 RectFill(rp, mhd->menubarwin->Width - 1, 1,
732 mhd->menubarwin->Width - 1, mhd->menubarwin->Height - 2);
734 #endif
736 #endif
738 for (; menu; menu = menu->NextMenu)
740 RenderMenuTitle(menu, mhd);
746 static void RenderMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd)
748 struct RastPort *rp = mhd->menubarwin->RPort;
749 WORD len = strlen(menu->MenuName);
751 #if MENUS_UNDERMOUSE
752 struct Menu *m;
753 WORD x, y, yoff;
755 yoff = 0;
756 for (m = mhd->menu; m && (m != menu); m = m->NextMenu)
758 yoff++;
761 x = mhd->scr->MenuHBorder + ITEXT_EXTRA_LEFT;
762 y = mhd->scr->MenuVBorder + ITEXT_EXTRA_TOP +
763 yoff * mhd->menubaritemheight;
764 #else
765 WORD x = mhd->scr->BarHBorder + menu->LeftEdge;
766 WORD y = mhd->scr->BarVBorder;
767 #endif
769 #if MENUS_AMIGALOOK
770 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
771 #else
772 SetAPen(rp,
773 mhd->dri->dri_Pens[(menu->
774 Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN]);
775 #endif
777 Move(rp, x, y + rp->TxBaseline);
778 Text(rp, menu->MenuName, len);
780 #if MENUS_UNDERMOUSE
781 if (menu->FirstItem)
783 WORD silen = TextLength(rp, subitemindicator, 1);
784 WORD x2 =
785 mhd->scr->MenuHBorder + mhd->menubaritemwidth -
786 ITEXT_EXTRA_RIGHT - silen;
788 Move(rp, x2, y + rp->TxBaseline);
789 Text(rp, subitemindicator, 1);
791 #endif
793 if (!(menu->Flags & MENUENABLED))
795 #if MENUS_UNDERMOUSE
796 WORD x2 = mhd->scr->MenuHBorder + mhd->menubaritemwidth - 1;
797 #else
798 WORD x2 = x + TextLength(rp, menu->MenuName, len) - 1;
799 #endif
800 WORD y2 = y + rp->TxHeight - 1;
802 RenderDisabledPattern(rp, x, y, x2, y2, mhd);
807 static void MakeMenuWin(struct MenuHandlerData *mhd)
809 struct MenuItem *item;
811 WORD width = mhd->activemenu->BeatX - mhd->activemenu->JazzX + 1;
812 WORD height = mhd->activemenu->BeatY - mhd->activemenu->JazzY + 1;
813 #if MENUS_UNDERMOUSE
814 WORD xpos = mhd->menubarwin->LeftEdge + mhd->menubarwin->Width - 16;
815 WORD ypos = mhd->menubarwin->TopEdge;
816 #else
817 WORD xpos =
818 mhd->activemenu->LeftEdge + mhd->scr->BarHBorder +
819 mhd->activemenu->JazzX;
821 #if MENUS_AMIGALOOK
822 WORD ypos = mhd->scr->BarHeight + 1 + mhd->activemenu->JazzY;
823 #else
824 WORD ypos = mhd->scr->BarHeight + 1;
825 #endif
827 #endif
829 struct TagItem win_tags[9];
831 win_tags[0].ti_Tag = WA_Left;
832 win_tags[0].ti_Data = xpos;
833 win_tags[1].ti_Tag = WA_Top;
834 win_tags[1].ti_Data = ypos;
835 win_tags[2].ti_Tag = WA_Width;
836 win_tags[2].ti_Data = width;
837 win_tags[3].ti_Tag = WA_Height;
838 win_tags[3].ti_Data = height;
839 win_tags[4].ti_Tag = WA_AutoAdjust;
840 win_tags[4].ti_Data = TRUE;
841 win_tags[5].ti_Tag = WA_Borderless;
842 win_tags[5].ti_Data = TRUE;
843 win_tags[6].ti_Tag = WA_CustomScreen;
844 win_tags[6].ti_Data = (IPTR) mhd->scr;
845 win_tags[7].ti_Tag = WA_BackFill;
846 win_tags[7].ti_Tag = (IPTR) LAYERS_NOBACKFILL;
847 win_tags[8].ti_Tag = TAG_DONE;
850 #if MENUS_UNDERMOUSE
851 win_tags[1].ti_Data +=
852 (mhd->menubaritemheight * mhd->activemenunum +
853 mhd->scr->MenuVBorder) - height / 2;
854 if (xpos + width > mhd->scr->Width)
856 win_tags[0].ti_Data = mhd->menubarwin->LeftEdge - width + 16;
858 #endif
860 if ((item = mhd->activemenu->FirstItem))
862 while (item)
864 item->Flags &= ~HIGHITEM;
865 item = item->NextItem;
867 mhd->menuwin = OpenWindowTagList(0, win_tags);
869 mhd->maxcommkeywidth_menu = CalcMaxCommKeyWidth(mhd->menuwin, mhd);
871 RenderMenu(mhd);
873 mhd->activemenu->Flags |= MIDRAWN;
878 static void KillMenuWin(struct MenuHandlerData *mhd)
880 if (mhd->menuwin)
882 struct MenuItem *item;
884 CloseWindow(mhd->menuwin);
885 mhd->menuwin = NULL;
887 for (item = mhd->activemenu->FirstItem; item; item = item->NextItem)
889 item->Flags &= ~ISDRAWN;
892 mhd->activemenu->Flags &= ~MIDRAWN;
894 mhd->activeitemnum = -1;
895 mhd->activeitem = NULL;
900 static void RenderMenu(struct MenuHandlerData *mhd)
903 if (mhd->menuwin)
905 struct MenuItem *item;
907 RenderMenuBG(mhd->menuwin, mhd);
909 SetFont(mhd->menuwin->RPort, mhd->dri->dri_Font);
911 for (item = mhd->activemenu->FirstItem; item; item = item->NextItem)
913 RenderItem(item, ITEM_ITEM,
914 (struct Rectangle *)(&mhd->activemenu->JazzX), mhd);
920 static void MakeSubMenuWin(struct MenuHandlerData *mhd)
922 struct MenuItem *item = mhd->activeitem->SubItem;
923 struct TagItem win_tags[9];
925 win_tags[0].ti_Tag = WA_Left;
926 win_tags[0].ti_Data = 0;
927 win_tags[1].ti_Tag = WA_Top;
928 win_tags[1].ti_Data = 0;
929 win_tags[2].ti_Tag = WA_Width;
930 win_tags[2].ti_Data = 0;
931 win_tags[3].ti_Tag = WA_Height;
932 win_tags[3].ti_Data = 0;
933 win_tags[4].ti_Tag = WA_AutoAdjust;
934 win_tags[4].ti_Data = TRUE;
935 win_tags[5].ti_Tag = WA_Borderless;
936 win_tags[5].ti_Data = TRUE;
937 win_tags[6].ti_Tag = WA_CustomScreen;
938 win_tags[6].ti_Data = (IPTR) mhd->scr;
939 win_tags[7].ti_Tag = WA_BackFill;
940 win_tags[7].ti_Tag = (IPTR) LAYERS_NOBACKFILL;
941 win_tags[8].ti_Tag = TAG_DONE;
943 GetMenuBox(mhd->menubarwin, item, &mhd->submenubox.MinX,
944 &mhd->submenubox.MinY,
945 &mhd->submenubox.MaxX, &mhd->submenubox.MaxY);
947 win_tags[0].ti_Data = mhd->menuwin->LeftEdge +
948 mhd->activeitem->LeftEdge - mhd->activemenu->JazzX +
949 mhd->submenubox.MinX;
951 win_tags[1].ti_Data = mhd->menuwin->TopEdge +
952 mhd->activeitem->TopEdge - mhd->activemenu->JazzY +
953 mhd->submenubox.MinY;
955 win_tags[2].ti_Data = mhd->submenubox.MaxX - mhd->submenubox.MinX + 1;
956 win_tags[3].ti_Data = mhd->submenubox.MaxY - mhd->submenubox.MinY + 1;
958 while (item)
960 item->Flags &= ~HIGHITEM;
961 item = item->NextItem;
964 mhd->submenuwin = OpenWindowTagList(0, win_tags);
966 mhd->maxcommkeywidth_submenu =
967 CalcMaxCommKeyWidth(mhd->submenuwin, mhd);
969 RenderSubMenu(mhd);
973 static void KillSubMenuWin(struct MenuHandlerData *mhd)
975 if (mhd->submenuwin)
977 CloseWindow(mhd->submenuwin);
978 mhd->submenuwin = NULL;
980 mhd->activesubitemnum = -1;
981 mhd->activesubitem = NULL;
986 static void RenderSubMenu(struct MenuHandlerData *mhd)
989 if (mhd->submenuwin)
991 struct MenuItem *item;
993 RenderMenuBG(mhd->submenuwin, mhd);
995 SetFont(mhd->submenuwin->RPort, mhd->dri->dri_Font);
997 for (item = mhd->activeitem->SubItem; item; item = item->NextItem)
999 RenderItem(item, ITEM_SUBITEM,
1000 (struct Rectangle *)(&mhd->submenubox), mhd);
1006 static void RenderItem(struct MenuItem *item, WORD itemtype,
1007 struct Rectangle *box, struct MenuHandlerData *mhd)
1009 struct Window *win =
1010 ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1011 struct RastPort *rp = win->RPort;
1012 WORD offx = -box->MinX;
1013 WORD offy = -box->MinY;
1014 BOOL enabled = ((item->Flags & ITEMENABLED) &&
1015 (mhd->activemenu->Flags & MENUENABLED) &&
1016 ((itemtype == ITEM_ITEM)
1017 || (mhd->activeitem->Flags & ITEMENABLED)));
1018 BOOL item_supports_disable = FALSE;
1020 SetDrMd(rp, JAM1);
1022 if (item->ItemFill)
1024 if (item->Flags & ITEMTEXT)
1026 #if MENUS_AMIGALOOK
1027 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1029 PrintIText(rp, it, offx + item->LeftEdge, offy + item->TopEdge);
1030 #else
1031 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1033 it->FrontPen =
1034 mhd->dri->dri_Pens[(item->
1035 Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN];
1036 it->DrawMode = JAM1;
1038 PrintIText(rp, it, offx + item->LeftEdge, offy + item->TopEdge);
1039 #endif
1041 else
1043 struct Image *im = (struct Image *)item->ItemFill;
1044 LONG state = IDS_NORMAL;
1046 if (!enabled && (im->Depth == CUSTOMIMAGEDEPTH))
1048 IPTR val = 0;
1050 GetAttr(IA_SupportsDisable, (Object *) im, &val);
1051 if (val)
1053 item_supports_disable = TRUE;
1054 state = IDS_DISABLED;
1058 DrawImageState(rp, im, offx + item->LeftEdge,
1059 offy + item->TopEdge, state, mhd->dri);
1062 } /* if (item->ItemFill) */
1064 RenderCheckMark(item, itemtype, mhd);
1065 RenderAmigaKey(item, itemtype, mhd);
1067 if (!enabled && !item_supports_disable)
1069 RenderDisabledPattern(rp, offx + item->LeftEdge,
1070 offy + item->TopEdge,
1071 offx + item->LeftEdge + item->Width - 1,
1072 offy + item->TopEdge + item->Height - 1, mhd);
1078 static void RenderMenuBG(struct Window *win, struct MenuHandlerData *mhd)
1080 struct RastPort *rp = win->RPort;
1082 #if MENUS_AMIGALOOK
1083 WORD borderx = mhd->scr->MenuHBorder / 2;
1084 WORD bordery = mhd->scr->MenuVBorder / 2;
1085 #else
1086 WORD borderx = 1;
1087 WORD bordery = 1;
1088 #endif
1090 /* White background */
1092 #if MENUS_AMIGALOOK
1093 SetABPenDrMd(rp, mhd->dri->dri_Pens[BARBLOCKPEN], 0, JAM1);
1094 #else
1095 SetABPenDrMd(rp, mhd->dri->dri_Pens[BACKGROUNDPEN], 0, JAM1);
1096 #endif
1097 RectFill(rp, borderx,
1098 bordery, win->Width - 1 - borderx, win->Height - 1 - bordery);
1100 /* Black border frame */
1102 #if MENUS_AMIGALOOK
1103 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
1104 RectFill(rp, 0, 0, win->Width - 1, bordery - 1);
1105 RectFill(rp, 0, bordery, borderx - 1, win->Height - 1 - bordery);
1106 RectFill(rp, win->Width - borderx, bordery, win->Width - 1,
1107 win->Height - 1);
1108 RectFill(rp, 0, win->Height - bordery, win->Width - 1 - borderx,
1109 win->Height - 1);
1110 #else
1111 RenderFrame(rp, 0, 0, win->Width - 1, win->Height - 1, IDS_NORMAL, mhd);
1112 #endif
1116 static void RenderCheckMark(struct MenuItem *item, WORD itemtype,
1117 struct MenuHandlerData *mhd)
1119 struct Window *win =
1120 ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1121 struct RastPort *rp = win->RPort;
1122 struct Rectangle *box =
1123 ((itemtype ==
1124 ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->
1125 JazzX) : &mhd->submenubox);
1126 WORD offx = -box->MinX;
1127 WORD offy = -box->MinY;
1128 WORD state = ((item->Flags & HIGHITEM) &&
1129 ((item->Flags & HIGHFLAGS) ==
1130 HIGHCOMP)) ? IDS_SELECTED : IDS_NORMAL;
1132 if (item->Flags & CHECKIT)
1134 WORD x1, y1, x2, y2;
1136 x1 = item->LeftEdge + offx;
1137 y1 = item->TopEdge + offy + (item->Height -
1138 mhd->checkmark->Height) / 2;
1139 x2 = x1 + mhd->checkmark->Width - 1;
1140 y2 = y1 + mhd->checkmark->Height - 1;
1142 SetDrMd(rp, JAM1);
1144 if (item->Flags & CHECKED)
1146 DrawImageState(rp, mhd->checkmark, x1, y1, state, mhd->dri);
1148 else
1150 #if MENUS_AMIGALOOK
1151 SetAPen(rp, mhd->dri->dri_Pens[BARBLOCKPEN]);
1152 #else
1153 SetAPen(rp,
1154 mhd->dri->dri_Pens[(state ==
1155 IDS_SELECTED) ? FILLPEN : BACKGROUNDPEN]);
1156 #endif
1157 RectFill(rp, x1, y1, x2, y2);
1164 static void RenderAmigaKey(struct MenuItem *item, WORD itemtype,
1165 struct MenuHandlerData *mhd)
1167 struct Window *win =
1168 ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1169 struct RastPort *rp = win->RPort;
1170 struct Rectangle *box =
1171 ((itemtype ==
1172 ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->
1173 JazzX) : &mhd->submenubox);
1174 WORD commkeywidth =
1175 ((itemtype ==
1176 ITEM_ITEM) ? mhd->maxcommkeywidth_menu : mhd->
1177 maxcommkeywidth_submenu);
1178 WORD offx = -box->MinX;
1179 WORD offy = -box->MinY;
1180 WORD state = ((item->Flags & HIGHITEM) &&
1181 ((item->Flags & HIGHFLAGS) ==
1182 HIGHCOMP)) ? IDS_SELECTED : IDS_NORMAL;
1184 if (item->Flags & COMMSEQ)
1186 struct TextFont *oldfont = rp->Font;
1187 struct TextFont *newfont = NULL;
1189 WORD x1, y1;
1191 if (item->Flags & ITEMTEXT)
1193 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1195 if (it->ITextFont)
1197 if ((newfont = OpenFont(it->ITextFont)))
1199 SetFont(rp, newfont);
1204 x1 = item->LeftEdge + offx + item->Width - AMIGAKEY_BORDER_SPACING -
1205 mhd->amigakey->Width - AMIGAKEY_KEY_SPACING - commkeywidth;
1206 y1 = item->TopEdge + offy + (item->Height - mhd->amigakey->Height +
1207 1) / 2;
1209 SetDrMd(rp, JAM1);
1211 DrawImageState(rp, mhd->amigakey, x1, y1, state, mhd->dri);
1213 x1 += mhd->amigakey->Width + AMIGAKEY_KEY_SPACING;
1215 #if MENUS_AMIGALOOK
1216 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
1217 #else
1218 SetAPen(rp,
1219 mhd->dri->dri_Pens[(item->
1220 Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN]);
1221 #endif
1222 Move(rp, x1,
1223 item->TopEdge + offy + (item->Height - rp->TxHeight) / 2 +
1224 rp->TxBaseline);
1225 Text(rp, &item->Command, 1);
1227 if (newfont)
1229 CloseFont(newfont);
1230 SetFont(rp, oldfont);
1236 static void RenderDisabledPattern(struct RastPort *rp, WORD x1, WORD y1,
1237 WORD x2, WORD y2, struct MenuHandlerData *mhd)
1239 static UWORD pattern[] = { 0x8888, 0x2222 };
1241 SetDrMd(rp, JAM1);
1242 #if MENUS_AMIGALOOK
1243 SetAPen(rp, mhd->dri->dri_Pens[BARBLOCKPEN]);
1244 #else
1245 SetAPen(rp, mhd->dri->dri_Pens[BACKGROUNDPEN]);
1246 #endif
1248 SetAfPt(rp, pattern, 1);
1250 RectFill(rp, x1, y1, x2, y2);
1252 SetAfPt(rp, NULL, 0);
1256 #if 0
1257 static void RenderFrame(struct RastPort *rp, WORD x1, WORD y1, WORD x2,
1258 WORD y2, WORD state, struct MenuHandlerData *mhd)
1260 SetAPen(rp,
1261 mhd->dri->dri_Pens[(state == IDS_SELECTED) ? SHADOWPEN : SHINEPEN]);
1263 RectFill(rp, x1, y1, x2, y1);
1264 RectFill(rp, x1, y1 + 1, x1, y2);
1266 SetAPen(rp,
1267 mhd->dri->dri_Pens[(state == IDS_SELECTED) ? SHINEPEN : SHADOWPEN]);
1268 RectFill(rp, x2, y1 + 1, x2, y2);
1269 RectFill(rp, x1 + 1, y2, x2 - 1, y2);
1271 #endif
1274 static void HighlightItem(struct MenuItem *item, WORD itemtype,
1275 struct MenuHandlerData *mhd)
1277 struct Window *win =
1278 ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1279 struct RastPort *rp = win->RPort;
1280 struct Rectangle *box =
1281 ((itemtype ==
1282 ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->
1283 JazzX) : &mhd->submenubox);
1284 APTR fill;
1285 WORD offx = -box->MinX;
1286 WORD offy = -box->MinY;
1287 WORD x1, y1, x2, y2;
1288 BOOL enabled;
1290 enabled = (item->Flags & ITEMENABLED) ? TRUE : FALSE;
1291 if (!(mhd->activemenu->Flags & MENUENABLED))
1292 enabled = FALSE;
1293 if ((itemtype == ITEM_SUBITEM)
1294 && !(mhd->activeitem->Flags & ITEMENABLED))
1295 enabled = FALSE;
1297 if (enabled)
1299 item->Flags ^= HIGHITEM;
1301 fill = item->ItemFill;
1302 if ((item->Flags & HIGHITEM) && (item->SelectFill))
1303 fill = item->SelectFill;
1305 x1 = offx + item->LeftEdge;
1306 y1 = offy + item->TopEdge;
1307 x2 = x1 + item->Width - 1;
1308 y2 = y1 + item->Height - 1;
1310 switch (item->Flags & HIGHFLAGS)
1312 case HIGHIMAGE:
1313 SetDrMd(rp, JAM1);
1315 if (item->Flags & ITEMTEXT)
1317 #if MENUS_AMIGALOOK
1318 PrintIText(rp, (struct IntuiText *)fill, x1, y1);
1319 #else
1320 struct IntuiText *it = (struct IntuiText *)fill;
1322 it->FrontPen = mhd->dri->dri_Pens[TEXTPEN];
1323 it->DrawMode = JAM1;
1325 PrintIText(rp, it, x1, y1);
1326 #endif
1328 else
1330 EraseImage(rp, (struct Image *)fill, x1, y1);
1331 DrawImageState(rp, (struct Image *)fill, x1, y1,
1332 IDS_SELECTED, mhd->dri);
1334 break;
1336 case HIGHCOMP:
1337 #if MENUS_AMIGALOOK
1338 SetDrMd(rp, COMPLEMENT);
1339 RectFill(rp, x1, y1, x2, y2);
1340 #else
1342 WORD state =
1343 (item->Flags & HIGHITEM) ? IDS_SELECTED : IDS_NORMAL;
1345 SetDrMd(rp, JAM1);
1346 SetAPen(rp,
1347 mhd->dri->dri_Pens[(state ==
1348 IDS_SELECTED) ? FILLPEN : BACKGROUNDPEN]);
1349 RectFill(rp, x1, y1, x2, y2);
1351 RenderItem(item, itemtype, box, mhd);
1353 if (state == IDS_SELECTED)
1355 RenderFrame(rp, x1, y1, x2, y2, state, mhd);
1358 #endif
1359 break;
1361 case HIGHBOX:
1362 SetDrMd(rp, COMPLEMENT);
1363 offx = mhd->scr->MenuHBorder;
1364 offy = mhd->scr->MenuVBorder;
1366 x1 -= offx;
1367 x2 += offx;
1368 y1 -= offy;
1369 y2 += offy;
1371 RectFill(rp, x1, y1, x2, y1 + offy - 1);
1372 RectFill(rp, x2 - offx + 1, y1 + offy, x2, y2);
1373 RectFill(rp, x1, y2 - offy + 1, x2 - offx, y2);
1374 RectFill(rp, x1, y1 + offy, x1 + offx - 1, y2 - offy);
1375 break;
1377 case HIGHNONE:
1378 /* Do nothing */
1379 break;
1386 static WORD CalcMaxCommKeyWidth(struct Window *win,
1387 struct MenuHandlerData *mhd)
1389 WORD maxwidth = mhd->dri->dri_Font->tf_XSize;
1391 if (win)
1393 struct MenuItem *item;
1395 if ((win == mhd->menuwin))
1397 item = mhd->activemenu->FirstItem;
1399 else
1401 item = mhd->activeitem->SubItem;
1404 for (; item; item = item->NextItem)
1406 if (item->Flags & ITEMTEXT)
1408 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1410 if (it->ITextFont)
1412 struct TextFont *font;
1414 if ((font = OpenFont(it->ITextFont)))
1416 if (font->tf_XSize > maxwidth)
1417 maxwidth = font->tf_XSize;
1419 CloseFont(font);
1426 return maxwidth;
1430 static void AddToSelection(struct MenuHandlerData *mhd)
1432 if ((mhd->activemenunum != -1) && (mhd->activemenu->Flags & MENUENABLED)
1433 && (mhd->activeitemnum != -1)
1434 && (mhd->activeitem->Flags & ITEMENABLED))
1436 struct MenuItem *item = NULL;
1437 UWORD men =
1438 FULLMENUNUM(mhd->activemenunum, mhd->activeitemnum,
1439 mhd->activesubitemnum);
1441 if (mhd->activesubitemnum != -1)
1443 if (mhd->activesubitem->Flags & ITEMENABLED)
1444 item = mhd->activesubitem;
1446 else if (!mhd->activeitem->SubItem)
1448 item = mhd->activeitem;
1451 if (item && (ItemAddress(mhd->menu, men) == item))
1453 UWORD men =
1454 FULLMENUNUM(mhd->activemenunum, mhd->activeitemnum,
1455 mhd->activesubitemnum);
1457 if (mhd->firstmenupick == MENUNULL)
1459 mhd->firstmenupick = men;
1461 else if (men != mhd->lastmenupick)
1463 struct MenuItem *checkitem, *prevcheckitem = NULL;
1464 UWORD checkmen = mhd->firstmenupick;
1466 /* Remove men from pick queue, if it was already in there
1467 and then add it at the end of the pick queue */
1469 while (checkmen != MENUNULL)
1471 checkitem = ItemAddress(mhd->menu, checkmen);
1473 if (checkmen == men)
1475 if (prevcheckitem == NULL)
1477 mhd->firstmenupick = checkitem->NextSelect;
1479 else
1481 prevcheckitem->NextSelect =
1482 checkitem->NextSelect;
1486 checkmen = checkitem->NextSelect;
1487 prevcheckitem = checkitem;
1490 checkitem->NextSelect = men;
1493 mhd->lastmenupick = men;
1494 item->NextSelect = MENUNULL;
1500 /** END AROS **/
1502 struct ZMenu
1504 struct MenuHandlerData mhd;
1507 struct ZMenu *zune_open_menu(struct Window *wnd, struct NewMenu *newmenu)
1509 struct TagItem tags[] = {
1510 {GTMN_NewLookMenus, TRUE},
1511 {TAG_DONE}
1514 struct ZMenu *zmenu;
1515 struct Menu *menu;
1516 APTR visinfo;
1517 zmenu = (struct ZMenu *)AllocVec(sizeof(struct ZMenu), MEMF_CLEAR);
1518 if (!zmenu)
1519 return NULL;
1521 visinfo = GetVisualInfoA(wnd->WScreen, NULL);
1522 if (!visinfo)
1524 FreeVec(zmenu);
1525 return NULL;
1528 if (!(menu = CreateMenusA(newmenu, NULL)))
1530 FreeVec(zmenu);
1531 return NULL;
1534 LayoutMenusA(menu, visinfo, tags);
1535 FreeVisualInfo(visinfo);
1537 Characterize(menu);
1538 CalculateDims(wnd, menu);
1540 zmenu->mhd.win = wnd;
1541 zmenu->mhd.scr = zmenu->mhd.win->WScreen;
1542 zmenu->mhd.dri = GetScreenDrawInfo(zmenu->mhd.scr);
1543 zmenu->mhd.menu = menu;
1544 zmenu->mhd.activemenunum = -1;
1545 zmenu->mhd.activeitemnum = -1;
1546 zmenu->mhd.activesubitemnum = -1;
1547 zmenu->mhd.checkmark = zmenu->mhd.dri->dri_CheckMark;
1548 zmenu->mhd.amigakey = zmenu->mhd.dri->dri_AmigaKey;
1549 zmenu->mhd.scrmousex = zmenu->mhd.scr->MouseX;
1550 zmenu->mhd.scrmousey = zmenu->mhd.scr->MouseY;
1551 zmenu->mhd.firstmenupick = MENUNULL;
1553 MakeMenuBarWin(&zmenu->mhd);
1554 HandleMouseMove(&zmenu->mhd);
1555 return zmenu;
1558 void zune_mouse_update(struct ZMenu *zmenu, int left_down)
1560 if (!zmenu)
1561 return;
1563 if (!left_down)
1564 HandleMouseMove(&zmenu->mhd);
1565 else
1566 HandleMouseClick(&zmenu->mhd, 0);
1569 struct MenuItem *zune_leave_menu(struct ZMenu *zmenu)
1571 HandleMouseClick(&zmenu->mhd, 1);
1573 return ItemAddress(zmenu->mhd.menu, zmenu->mhd.firstmenupick);
1576 /* returns the address of the selected menuitem entry */
1577 void zune_close_menu(struct ZMenu *zmenu)
1579 if (!zmenu)
1580 return;
1582 KillMenuBarWin(&zmenu->mhd);
1583 KillMenuWin(&zmenu->mhd);
1584 KillSubMenuWin(&zmenu->mhd);
1586 FreeMenus(zmenu->mhd.menu);
1587 zmenu->mhd.menu = 0;
1589 if (zmenu->mhd.dri)
1591 FreeScreenDrawInfo(zmenu->mhd.scr, zmenu->mhd.dri);
1592 zmenu->mhd.dri = 0;
1595 // MH2Int_MakeMenusInactive(mhd->win, mhd->firstmenupick);
1596 zmenu->mhd.active = FALSE;
1598 FreeVec(zmenu);
1601 struct Menu *zune_get_menu_pointer(struct ZMenu *menu)
1603 return menu->mhd.menu;