Instead of "eax" and "edx" in asm constraints use "a" and "d"
[tangerine.git] / rom / intuition / menutask_aros.c
blob9a8b4fef920202ec350e36ad6c015dea35976fd3
1 /*
2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
4 $Id$
5 */
7 #include <proto/exec.h>
8 #include <proto/intuition.h>
9 #include <proto/alib.h>
10 #include <proto/layers.h>
11 #include <proto/graphics.h>
12 #include <proto/keymap.h>
13 #include <proto/cybergraphics.h>
14 #include <exec/memory.h>
15 #include <exec/alerts.h>
16 #include <exec/interrupts.h>
17 #include <exec/ports.h>
18 #include <intuition/intuition.h>
19 #include <intuition/intuitionbase.h>
20 #include <intuition/imageclass.h>
21 #include <graphics/gfxmacros.h>
22 #include <graphics/rpattr.h>
23 #include <devices/inputevent.h>
24 #include <devices/input.h>
25 #include "inputhandler.h"
26 #include "intuition_intern.h"
27 #include <string.h>
29 #ifdef SKINS
30 #include "intuition_customize.h"
31 #endif
33 #include "menus.h"
34 #include "menutask.h"
35 #include <cybergraphx/cybergraphics.h>
37 #undef DEBUG
38 #define DEBUG 0
39 #include <aros/debug.h>
41 extern ULONG HookEntry();
43 /**************************************************************************************************/
45 /* this #defines are taken from workbench/libs/gadtools/menus.c!! */
47 #define TEXT_AMIGAKEY_SPACING 6
49 #define ITEXT_EXTRA_LEFT 2
50 #define ITEXT_EXTRA_RIGHT 2
51 #define ITEXT_EXTRA_TOP 1
52 #define ITEXT_EXTRA_BOTTOM 1
54 static const char *subitemindicator = "»";
56 /**************************************************************************************************/
58 static void HandleMouseMove(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
59 static void HandleMouseClick(struct InputEvent *ie, struct MenuHandlerData *mhd,
60 struct IntuitionBase *IntuitionBase);
61 static void HandleCheckItem(struct Window *win, struct MenuItem *item,
62 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
64 static void HighlightMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd,
65 struct IntuitionBase *IntuitionBase);
67 static struct Menu *FindMenu(WORD *var, struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
68 static struct MenuItem *FindItem(WORD *var, struct MenuHandlerData *mhd);
69 static struct MenuItem *FindSubItem(WORD *var, struct MenuHandlerData *mhd);
71 static void MakeMenuBarWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
72 static void KillMenuBarWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
73 static void RenderMenuBar(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
75 static void MakeMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
76 static void KillMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
77 static void RenderMenu(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
78 static void RenderMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd,
79 struct IntuitionBase *IntuitionBase);
81 static void MakeSubMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
82 static void KillSubMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
83 static void RenderSubMenu(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
85 static void RenderItem(struct MenuItem *item, WORD itemtype, struct Rectangle *box,
86 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
88 static void RenderMenuBG(struct Window *win, struct MenuHandlerData *mhd,
89 struct IntuitionBase *IntuitionBase);
90 static void RenderCheckMark(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd,
91 struct IntuitionBase *IntuitionBase);
92 static void RenderAmigaKey(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd,
93 struct IntuitionBase *IntuitionBase);
94 static void RenderDisabledPattern(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2,
95 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
96 static void RenderFrame(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2, WORD state,
97 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
98 static void HighlightItem(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd,
99 struct IntuitionBase *IntuitionBase);
100 static WORD CalcMaxCommKeyWidth(struct Window *win, struct MenuHandlerData *mhd,
101 struct IntuitionBase *IntuitionBase);
102 static void AddToSelection(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase);
105 /**************************************************************************************************/
106 /******************************
107 ** CreateMenuHandlerTask() **
108 ******************************/
109 struct Task *CreateMenuHandlerTask(APTR taskparams, struct IntuitionBase *IntuitionBase)
111 struct Task *task;
112 APTR stack;
114 task = AllocMem(sizeof (struct Task), MEMF_PUBLIC|MEMF_CLEAR);
115 if (task)
117 NEWLIST(&task->tc_MemEntry);
118 task->tc_Node.ln_Type = NT_TASK;
119 task->tc_Node.ln_Name = MENUTASK_NAME;
120 task->tc_Node.ln_Pri = MENUTASK_PRIORITY;
122 stack = AllocMem(MENUTASK_STACKSIZE, MEMF_PUBLIC);
123 if(stack != NULL)
125 task->tc_SPLower=stack;
126 task->tc_SPUpper=(UBYTE *)stack + MENUTASK_STACKSIZE;
128 #ifdef __MORPHOS__
129 task->tc_SPReg = task->tc_SPUpper;
132 struct TaskInitExtension taskext;
133 struct TagItem tags[4];
135 taskext.Trap = TRAP_PPCTASK;
136 taskext.Extension = 0;
137 taskext.Tags = tags;
139 tags[0].ti_Tag = TASKTAG_CODETYPE;
140 tags[0].ti_Data = CODETYPE_PPC;
141 tags[1].ti_Tag = TASKTAG_PC;
142 tags[1].ti_Data = (ULONG)DefaultMenuHandler;
143 tags[2].ti_Tag = TASKTAG_PPC_ARG1;
144 tags[2].ti_Data = (ULONG)taskparams;
145 tags[3].ti_Tag = TAG_END;
147 if(AddTask(task, (APTR)&taskext, NULL) != NULL)
149 /* Everything went OK */
150 return (task);
153 #else
155 struct TagItem tags[] =
157 {TASKTAG_ARG1, (IPTR)taskparams },
158 {TAG_DONE }
161 #if AROS_STACK_GROWS_DOWNWARDS
162 task->tc_SPReg = (UBYTE *)task->tc_SPUpper-SP_OFFSET;
163 #else
164 task->tc_SPReg=(UBYTE *)task->tc_SPLower+SP_OFFSET;
165 #endif
167 if(NewAddTask(task, DefaultMenuHandler, NULL, tags) != NULL)
169 /* Everything went OK */
170 return (task);
174 #endif
175 FreeMem(stack, MENUTASK_STACKSIZE);
177 } /* if(stack != NULL) */
178 FreeMem(task,sizeof(struct Task));
180 } /* if (task) */
181 return (NULL);
185 #undef DefaultMenuHandler
188 /**************************************************************************************************/
190 /***************************
191 ** DefaultMenuHandler() **
192 ***************************/
193 void DefaultMenuHandler(struct MenuTaskParams *taskparams)
195 struct IntuitionBase *IntuitionBase = taskparams->intuitionBase;
196 struct MenuHandlerData *mhd = NULL;
197 UBYTE *mem;
198 struct MsgPort *port = NULL;
199 BOOL success = FALSE;
201 if ((mem = AllocMem(sizeof(struct MsgPort) +
202 sizeof(struct MenuHandlerData), MEMF_PUBLIC | MEMF_CLEAR)))
204 port = (struct MsgPort *)mem;
206 port->mp_Node.ln_Type = NT_MSGPORT;
207 port->mp_Flags = PA_SIGNAL;
208 port->mp_SigBit = AllocSignal(-1);
209 port->mp_SigTask = FindTask(0);
210 NEWLIST(&port->mp_MsgList);
212 mhd = (struct MenuHandlerData *)(mem + sizeof(struct MsgPort));
214 success = TRUE;
216 } /* if ((mem = AllocMem(sizeof(struct MsgPort), MEMF_PUBLIC | MEMF_CLEAR))) */
218 if (success)
220 taskparams->MenuHandlerPort = port;
221 taskparams->success = TRUE;
224 Signal(taskparams->Caller, SIGF_INTUITION);
226 if (!success)
228 D(bug("DefaultMenuHandler: initialization failed. waiting for parent task to kill me.\n"));
229 Wait(0);
232 D(bug("DefaultMenuHandler: initialization ok. Now waiting for messages from Intuition.\n"));
234 for(;;)
236 struct MenuMessage *msg;
238 WaitPort(port);
239 while((msg = GetMenuMessage(port, IntuitionBase)))
241 switch(msg->code)
243 case MMCODE_START:
244 mhd->win = msg->win;
245 mhd->scr = mhd->win->WScreen;
246 mhd->dri = GetScreenDrawInfo(mhd->scr);
247 mhd->menu = msg->win->MenuStrip;
248 mhd->activemenunum = -1;
249 mhd->activeitemnum = -1;
250 mhd->activesubitemnum = -1;
251 mhd->checkmark = ((struct IntWindow *)mhd->win)->Checkmark;
252 mhd->amigakey = ((struct IntWindow *)mhd->win)->AmigaKey;
253 mhd->scrmousex = mhd->scr->MouseX;
254 mhd->scrmousey = mhd->scr->MouseY;
255 mhd->firstmenupick = MENUNULL;
257 /* close windows in the back first because
258 this is faster */
259 MakeMenuBarWin(mhd, IntuitionBase);
260 HandleMouseMove(mhd, IntuitionBase);
262 mhd->active = TRUE;
263 break;
265 case MMCODE_EVENT:
266 /* there might come additional messages from Intuition
267 even when we have already told it to make the menus
268 inactive, but since everything is async, this cannot
269 be avoided, so check if we are really active */
271 if (mhd->active)
273 switch(msg->ie.ie_Class)
275 case IECLASS_RAWMOUSE:
276 if (msg->ie.ie_Code == IECODE_NOBUTTON)
278 HandleMouseMove(mhd, IntuitionBase);
280 else
282 HandleMouseClick(&msg->ie, mhd, IntuitionBase);
284 break;
288 } /* if (mhd->active) */
289 break;
291 } /* switch(msg->code) */
293 ReplyMenuMessage(msg, IntuitionBase);
295 } /* while((msg = (struct MenuMessage *)GetMsg(port))) */
297 } /* for(;;) */
300 /**************************************************************************************************/
302 /*******************************
303 ** InitDefaultMenuHandler() **
304 *******************************/
305 BOOL InitDefaultMenuHandler(struct IntuitionBase *IntuitionBase)
307 struct MenuTaskParams params;
308 struct Task *task;
309 BOOL result = FALSE;
311 params.intuitionBase = IntuitionBase;
312 params.Caller = FindTask(NULL);
313 params.success = FALSE;
315 SetSignal(0, SIGF_INTUITION);
317 if ((task = CreateMenuHandlerTask(&params, IntuitionBase)))
319 Wait(SIGF_INTUITION);
321 if (params.success)
323 result = TRUE;
324 GetPrivIBase(IntuitionBase)->MenuHandlerPort = params.MenuHandlerPort;
326 else
328 RemTask(task);
331 } /* if ((task = CreateMenuHandlerTask(&params, IntuitionBase))) */
333 return result;
337 /**************************************************************************************************/
339 static void HandleMouseMove(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
341 struct Layer *lay;
342 struct Window *win = NULL;
343 struct Menu *menu;
344 struct MenuItem *item;
345 WORD new_activemenunum = mhd->activemenunum;
346 WORD new_activeitemnum = mhd->activeitemnum;
347 WORD new_activesubitemnum = mhd->activesubitemnum;
349 mhd->scrmousex = mhd->scr->MouseX;
350 mhd->scrmousey = mhd->scr->MouseY;
352 if ((lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey)))
354 win = (struct Window *)lay->Window;
356 if (win && (win == mhd->submenuwin))
358 /* Mouse over submenu box */
359 item = FindSubItem(&new_activesubitemnum, mhd);
361 if (new_activesubitemnum != mhd->activesubitemnum)
363 if (mhd->activesubitemnum != -1)
365 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd, IntuitionBase);
368 mhd->activesubitemnum = new_activesubitemnum;
369 mhd->activesubitem = item;
371 if (item)
373 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd, IntuitionBase);
378 else if (win && (win == mhd->menuwin))
380 item = FindItem(&new_activeitemnum, mhd);
382 if (new_activeitemnum != mhd->activeitemnum)
384 if (mhd->activeitemnum != -1)
386 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd, IntuitionBase);
387 KillSubMenuWin(mhd, IntuitionBase);
390 mhd->activeitemnum = new_activeitemnum;
391 mhd->activeitem = item;
393 if (item)
395 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd, IntuitionBase);
397 if (item->SubItem)
399 MakeSubMenuWin(mhd, IntuitionBase);
403 } /* if (win && (win == mhd->menuwin)) */
404 else if (win && (win == mhd->menubarwin))
406 /* Mouse over menu box */
408 menu = FindMenu(&new_activemenunum, mhd, IntuitionBase);
410 if (new_activemenunum != mhd->activemenunum)
412 if (mhd->activemenunum != -1)
414 HighlightMenuTitle(mhd->activemenu, mhd, IntuitionBase);
415 KillMenuWin(mhd, IntuitionBase);
416 KillSubMenuWin(mhd, IntuitionBase);
419 mhd->activemenunum = new_activemenunum;
420 mhd->activemenu = menu;
422 if (menu)
424 HighlightMenuTitle(mhd->activemenu, mhd, IntuitionBase);
425 MakeMenuWin(mhd, IntuitionBase);
429 if ((mhd->activeitemnum != -1) && (!mhd->submenuwin))
431 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd, IntuitionBase);
432 mhd->activeitemnum = -1;
433 mhd->activeitem = NULL;
436 } /* if (win && (win == mhd->menubarwin)) */
437 else
439 win = NULL;
441 } /* if ((lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey))) */
443 if (!win)
445 /* mouse outside any menu window */
447 if ((mhd->activeitemnum != -1) && (!mhd->submenuwin))
449 HighlightItem(mhd->activeitem, ITEM_ITEM, mhd, IntuitionBase);
450 mhd->activeitemnum = -1;
451 mhd->activeitem = NULL;
453 else if (mhd->activesubitemnum != -1)
455 HighlightItem(mhd->activesubitem, ITEM_SUBITEM, mhd, IntuitionBase);
456 mhd->activesubitemnum = -1;
457 mhd->activesubitem = NULL;
463 /**************************************************************************************************/
465 static void HandleMouseClick(struct InputEvent *ie, struct MenuHandlerData *mhd,
466 struct IntuitionBase *IntuitionBase)
468 switch(ie->ie_Code)
470 case MENUUP:
471 case SELECTDOWN:
473 struct Layer *lay;
475 if ((lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey)))
477 struct Window *win = (struct Window *)lay->Window;
478 struct MenuItem *item = NULL;
480 win = (struct Window *)lay->Window;
482 if (win && (win == mhd->submenuwin) && (mhd->activesubitemnum != -1))
484 item = mhd->activesubitem;
487 else if (win && (win == mhd->menuwin) && (mhd->activeitemnum != -1))
489 item = mhd->activeitem;
492 if (item) if (item->Flags & CHECKIT)
494 HandleCheckItem(win, item, mhd, IntuitionBase);
497 AddToSelection(mhd, IntuitionBase);
499 } /* if ((lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey))) */
501 if (ie->ie_Code == MENUUP)
503 KillMenuBarWin(mhd, IntuitionBase);
504 KillMenuWin(mhd, IntuitionBase);
505 KillSubMenuWin(mhd, IntuitionBase);
507 if (mhd->dri)
509 FreeScreenDrawInfo(mhd->scr, mhd->dri);
510 mhd->dri = 0;
512 MH2Int_MakeMenusInactive(mhd->win, mhd->firstmenupick, IntuitionBase);
513 mhd->active = FALSE;
516 break;
519 } /* switch(ie->ie_Code) */
522 /**************************************************************************************************/
524 static void HandleCheckItem(struct Window *win, struct MenuItem *item,
525 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
527 /* Note: If you change something here, you probably must also change
528 menus.c/CheckMenuItemWasClicked() which is used when the
529 user uses the menu key shortcuts! */
531 WORD itemtype = ((win == mhd->menuwin) ? ITEM_ITEM : ITEM_SUBITEM);
533 BOOL re_render = FALSE;
535 if (item->Flags & MENUTOGGLE)
537 item->Flags ^= CHECKED;
538 re_render = TRUE;
540 else
542 if (!(item->Flags & CHECKED))
544 item->Flags |= CHECKED;
545 re_render = TRUE;
549 if (re_render)
551 BOOL toggle_hi = FALSE;
553 if ((item->Flags & HIGHITEM) &&
554 ((item->Flags & HIGHFLAGS) == HIGHCOMP)) toggle_hi = TRUE;
556 if (toggle_hi) HighlightItem(item, itemtype, mhd, IntuitionBase);
557 RenderCheckMark(item, itemtype, mhd, IntuitionBase);
558 if (toggle_hi) HighlightItem(item, itemtype, mhd, IntuitionBase);
562 if (item->MutualExclude)
564 struct MenuItem *checkitem = (itemtype == ITEM_ITEM) ? mhd->activemenu->FirstItem :
565 mhd->activeitem->SubItem;
566 BOOL toggle_hi = FALSE;
567 WORD i;
569 if ((item->Flags & HIGHITEM) &&
570 ((item->Flags & HIGHFLAGS) == HIGHBOX)) toggle_hi = TRUE;
572 if (toggle_hi) HighlightItem(item, itemtype, mhd, IntuitionBase);
574 for(i = 0; (i < 32) && checkitem; i++, checkitem = checkitem->NextItem)
576 if ((item->MutualExclude & (1L << i)) &&
577 ((checkitem->Flags & (CHECKED | CHECKIT)) == (CHECKIT | CHECKED)))
579 checkitem->Flags &= ~CHECKED;
580 RenderCheckMark(checkitem, itemtype, mhd, IntuitionBase);
584 if (toggle_hi) HighlightItem(item, itemtype, mhd, IntuitionBase);
586 } /* if (item->MutualExclude) */
589 /**************************************************************************************************/
591 static void HighlightMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
593 if (menu->Flags & MENUENABLED)
595 struct RastPort *rp = mhd->menubarwin->RPort;
596 WORD x1, x2, y1, y2;
598 if (MENUS_UNDERMOUSE)
600 WORD i;
601 struct Menu *m = mhd->menu;
603 x1 = mhd->scr->MenuHBorder;
604 x2 = x1 + mhd->menubaritemwidth - 1;
606 for(i = 0; m != menu; m = m->NextMenu) i++;
608 y1 = mhd->scr->MenuVBorder + i * mhd->menubaritemheight;
609 y2 = y1 + mhd->menubaritemheight - 1;
611 else
613 x1 = menu->LeftEdge + mhd->scr->BarHBorder - mhd->scr->MenuHBorder;
614 y1 = 0;
615 x2 = x1 + menu->Width - 1;
616 y2 = mhd->scr->BarHeight - 1;
619 if (MENUS_AMIGALOOK)
621 SetDrMd(rp, COMPLEMENT);
622 RectFill(rp, x1, y1, x2, y2);
624 else
626 menu->Flags ^= HIGHITEM;
628 if (!MENUS_UNDERMOUSE) y1++;
630 SetDrMd(rp, JAM1);
631 SetAPen(rp, mhd->dri->dri_Pens[(menu->Flags & HIGHITEM) ? FILLPEN : BACKGROUNDPEN]);
632 RectFill(rp, x1, y1, x2, y2);
634 RenderMenuTitle(menu, mhd, IntuitionBase);
636 if (menu->Flags & HIGHITEM)
638 if (MENUS_UNDERMOUSE)
640 RenderFrame(rp, x1, y1, x2, y2, IDS_SELECTED, mhd, IntuitionBase);
642 else
644 SetAPen(rp, mhd->dri->dri_Pens[SHINEPEN]);
645 RectFill(rp, x1, y1, x1, y2);
646 SetAPen(rp, mhd->dri->dri_Pens[SHADOWPEN]);
647 RectFill(rp, x2, y1, x2, y2);
654 /**************************************************************************************************/
656 static struct Menu *FindMenu(WORD *var, struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
658 struct Menu *menu;
659 WORD mouse_x, mouse_y, i;
661 mouse_x = mhd->scrmousex - mhd->menubarwin->LeftEdge;
662 mouse_y = mhd->scrmousey - mhd->menubarwin->TopEdge;
664 if (MENUS_UNDERMOUSE)
666 menu = NULL;
668 mouse_x -= mhd->scr->MenuHBorder;
669 mouse_y -= mhd->scr->MenuVBorder;
671 if ((mouse_x >= 0) && (mouse_x < mhd->menubaritemwidth) && (mouse_y >= 0))
673 i = mouse_y / mhd->menubaritemheight;
675 if ((i >= 0) && (i < mhd->nummenubaritems))
677 WORD i2 = i;
679 menu = mhd->menu;
680 while(i && menu)
682 i--;
683 menu = menu->NextMenu;
686 if (menu && (i == 0))
688 *var = i2;
693 else
695 for(menu = mhd->menu, i = 0; menu; menu = menu->NextMenu, i++)
697 if ((mouse_x >= menu->LeftEdge) &&
698 (mouse_x < menu->LeftEdge + menu->Width) &&
699 (mouse_y >= 0) &&
700 (mouse_y <= mhd->scr->BarHeight))
702 *var = i;
703 break;
708 return menu;
711 /**************************************************************************************************/
713 static struct MenuItem *FindItem(WORD *var, struct MenuHandlerData *mhd)
715 struct MenuItem *item = NULL;
716 WORD mouse_x, mouse_y, i;
718 if (mhd->menuwin)
720 mouse_x = mhd->scrmousex - mhd->menuwin->LeftEdge + mhd->activemenu->JazzX;
721 mouse_y = mhd->scrmousey - mhd->menuwin->TopEdge + mhd->activemenu->JazzY;
723 for(item = mhd->activemenu->FirstItem, i = 0; item; item = item->NextItem, i++)
725 if ((mouse_x >= item->LeftEdge) &&
726 (mouse_x < item->LeftEdge + item->Width) &&
727 (mouse_y >= item->TopEdge) &&
728 (mouse_y < item->TopEdge + item->Height))
730 *var = i;
731 break;
734 } /* if (mhd->menuwin) */
736 if ((item == NULL) && !mhd->submenuwin) *var = -1;
738 return item;
741 /**************************************************************************************************/
743 static struct MenuItem *FindSubItem(WORD *var, struct MenuHandlerData *mhd)
745 struct MenuItem *item = NULL;
746 WORD mouse_x, mouse_y, i;
748 if (mhd->submenuwin)
750 mouse_x = mhd->scrmousex - mhd->submenuwin->LeftEdge + mhd->submenubox.MinX;
751 mouse_y = mhd->scrmousey - mhd->submenuwin->TopEdge + mhd->submenubox.MinY;
753 *var = -1;
755 for(item = mhd->activeitem->SubItem, i = 0; item; item = item->NextItem, i++)
757 if ((mouse_x >= item->LeftEdge) &&
758 (mouse_x < item->LeftEdge + item->Width) &&
759 (mouse_y >= item->TopEdge) &&
760 (mouse_y < item->TopEdge + item->Height))
762 *var = i;
763 break;
767 } /* if (mhd->menuwin) */
769 return item;
772 /**************************************************************************************************/
774 static void MakeMenuBarWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
776 struct TagItem win_tags[] =
778 {WA_Left , 0 },
779 {WA_Top , 0 },
780 {WA_Width , mhd->scr->Width },
781 {WA_Height , mhd->scr->BarHeight + 1 },
782 {WA_AutoAdjust , TRUE },
783 {WA_Borderless , TRUE },
784 {WA_CustomScreen, (ULONG)mhd->scr },
785 {WA_BackFill , (IPTR)LAYERS_NOBACKFILL },
786 {TAG_DONE }
788 struct Menu *menu;
790 if (MENUS_UNDERMOUSE)
792 struct RastPort *temprp;
793 WORD w, maxw = 0;
795 if (!(temprp = CloneRastPort(&mhd->scr->RastPort))) return;
797 mhd->nummenubaritems = 0;
798 for(menu = mhd->menu; menu; menu = menu->NextMenu)
800 w = TextLength(temprp, menu->MenuName, strlen(menu->MenuName));
801 if (w > maxw) maxw = w;
802 mhd->nummenubaritems++;
805 mhd->menubaritemwidth = maxw + TextLength(temprp, (char *)subitemindicator, 1) +
806 TEXT_AMIGAKEY_SPACING +
807 ITEXT_EXTRA_LEFT +
808 ITEXT_EXTRA_RIGHT;
810 mhd->menubaritemheight = temprp->TxHeight + ITEXT_EXTRA_TOP + ITEXT_EXTRA_BOTTOM;
812 win_tags[2].ti_Data = mhd->menubaritemwidth + mhd->scr->MenuHBorder * 2;
813 win_tags[3].ti_Data = mhd->menubaritemheight * mhd->nummenubaritems + mhd->scr->MenuVBorder * 2;
814 win_tags[0].ti_Data = mhd->scr->MouseX - win_tags[2].ti_Data / 2;
815 win_tags[1].ti_Data = mhd->scr->MouseY;
817 FreeRastPort(temprp);
820 D(bug("MakeMenuBarWin: mhd 0x%lx\n",
821 mhd));
823 mhd->menubarwin = OpenWindowTagList(0, win_tags);
825 for(menu = mhd->menu; menu; menu = menu->NextMenu)
827 menu->Flags &= ~HIGHITEM;
830 RenderMenuBar(mhd, IntuitionBase);
833 /**************************************************************************************************/
835 static void KillMenuBarWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
837 if (mhd->menubarwin)
839 CloseWindow(mhd->menubarwin);
840 mhd->menubarwin = NULL;
845 /**************************************************************************************************/
847 static void RenderMenuBar(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
849 if (mhd->menubarwin)
851 struct Menu *menu = mhd->menu;
852 struct RastPort *rp = mhd->menubarwin->RPort;
853 struct Layer *oldlayerhook;
855 SetFont(rp, mhd->dri->dri_Font);
857 if (MENUS_UNDERMOUSE)
859 RenderMenuBG(mhd->menubarwin, mhd, IntuitionBase);
861 else
863 if (MENUS_AMIGALOOK)
865 SetABPenDrMd(rp, mhd->dri->dri_Pens[BARBLOCKPEN], 0, JAM1);
867 else
869 SetABPenDrMd(rp, mhd->dri->dri_Pens[BACKGROUNDPEN], 0, JAM1);
872 RectFill(rp, 0, 0, mhd->menubarwin->Width - 1, mhd->menubarwin->Height - 2);
874 SetAPen(rp, mhd->dri->dri_Pens[BARTRIMPEN]);
875 RectFill(rp, 0, mhd->menubarwin->Height - 1, mhd->menubarwin->Width - 1, mhd->menubarwin->Height - 1);
877 if (!MENUS_AMIGALOOK)
879 SetAPen(rp, mhd->dri->dri_Pens[SHINEPEN]);
880 RectFill(rp, 0, 0, 0, mhd->menubarwin->Height - 2);
881 RectFill(rp, 1, 0, mhd->menubarwin->Width - 1, 0);
882 SetAPen(rp, mhd->dri->dri_Pens[SHADOWPEN]);
883 RectFill(rp, mhd->menubarwin->Width - 1, 1, mhd->menubarwin->Width - 1, mhd->menubarwin->Height - 2);
887 for(; menu; menu = menu->NextMenu)
889 RenderMenuTitle(menu, mhd, IntuitionBase);
894 /**************************************************************************************************/
896 static void RenderMenuTitle(struct Menu *menu, struct MenuHandlerData *mhd,
897 struct IntuitionBase *IntuitionBase)
899 struct RastPort *rp = mhd->menubarwin->RPort;
900 WORD len = strlen(menu->MenuName);
901 WORD x, y;
903 if (MENUS_UNDERMOUSE)
905 struct Menu *m;
906 WORD yoff;
908 yoff = 0;
909 for(m = mhd->menu; m && (m != menu);m = m ->NextMenu)
911 yoff++;
914 x = mhd->scr->MenuHBorder + ITEXT_EXTRA_LEFT;
915 y = mhd->scr->MenuVBorder + ITEXT_EXTRA_TOP + yoff * mhd->menubaritemheight;
917 else
919 x = mhd->scr->BarHBorder + menu->LeftEdge;
920 y = mhd->scr->BarVBorder;
923 if (MENUS_AMIGALOOK)
925 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
927 else
929 SetAPen(rp, mhd->dri->dri_Pens[(menu->Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN]);
932 Move(rp, x, y + rp->TxBaseline);
933 Text(rp, menu->MenuName, len);
935 if (MENUS_UNDERMOUSE)
937 if (menu->FirstItem)
939 WORD silen = TextLength(rp, (char *)subitemindicator, 1);
940 WORD x2 = mhd->scr->MenuHBorder + mhd->menubaritemwidth - ITEXT_EXTRA_RIGHT - silen;
942 Move(rp, x2, y + rp->TxBaseline);
943 Text(rp, (char *)subitemindicator, 1);
947 if (!(menu->Flags & MENUENABLED))
949 WORD y2 = y + rp->TxHeight - 1;
950 WORD x2;
952 if (MENUS_UNDERMOUSE)
954 x2 = mhd->scr->MenuHBorder + mhd->menubaritemwidth - 1;
956 else
958 x2 = x + TextLength(rp, menu->MenuName, len) - 1;
961 RenderDisabledPattern(rp, x, y, x2, y2, mhd, IntuitionBase);
965 /**************************************************************************************************/
967 static void MakeMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
969 struct MenuItem *item;
971 WORD width = mhd->activemenu->BeatX - mhd->activemenu->JazzX + 1;
972 WORD height = mhd->activemenu->BeatY - mhd->activemenu->JazzY + 1;
973 WORD xpos,ypos;
975 if (MENUS_UNDERMOUSE)
977 xpos = mhd->menubarwin->LeftEdge + mhd->menubarwin->Width - 16;
978 ypos = mhd->menubarwin->TopEdge;
980 else
982 xpos = mhd->activemenu->LeftEdge + mhd->scr->BarHBorder + mhd->activemenu->JazzX;
984 if (MENUS_AMIGALOOK)
986 ypos = mhd->scr->BarHeight + 1 + mhd->activemenu->JazzY;
988 else
990 ypos = mhd->scr->BarHeight + 1;
995 struct TagItem win_tags[] =
997 {WA_Left , xpos },
998 {WA_Top , ypos },
999 {WA_Width , width },
1000 {WA_Height , height },
1001 {WA_AutoAdjust , TRUE },
1002 {WA_Borderless , TRUE },
1003 {WA_CustomScreen, (ULONG)mhd->scr },
1004 {WA_BackFill , (IPTR)LAYERS_NOBACKFILL },
1005 {TAG_DONE }
1008 if (MENUS_UNDERMOUSE)
1010 win_tags[1].ti_Data += (mhd->menubaritemheight * mhd->activemenunum + mhd->scr->MenuVBorder) -
1011 height / 2;
1012 if (xpos + width > mhd->scr->Width)
1014 win_tags[0].ti_Data = mhd->menubarwin->LeftEdge - width + 16;
1018 if ((item = mhd->activemenu->FirstItem))
1021 while(item)
1023 item->Flags &= ~HIGHITEM;
1024 item = item->NextItem;
1026 mhd->menuwin = OpenWindowTagList(0, win_tags);
1028 mhd->maxcommkeywidth_menu = CalcMaxCommKeyWidth(mhd->menuwin, mhd, IntuitionBase);
1030 RenderMenu(mhd, IntuitionBase);
1032 mhd->activemenu->Flags |= MIDRAWN;
1037 /**************************************************************************************************/
1039 static void KillMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1041 if (mhd->menuwin)
1043 struct MenuItem *item;
1045 CloseWindow(mhd->menuwin);
1046 mhd->menuwin = NULL;
1048 for(item = mhd->activemenu->FirstItem; item; item = item->NextItem)
1050 item->Flags &= ~ISDRAWN;
1053 mhd->activemenu->Flags &= ~MIDRAWN;
1055 mhd->activeitemnum = -1;
1056 mhd->activeitem = NULL;
1060 /**************************************************************************************************/
1062 static void RenderMenu(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1065 if (mhd->menuwin)
1067 struct MenuItem *item;
1069 RenderMenuBG(mhd->menuwin, mhd, IntuitionBase);
1071 SetFont(mhd->menuwin->RPort, mhd->dri->dri_Font);
1073 for(item = mhd->activemenu->FirstItem; item; item = item->NextItem)
1075 RenderItem(item, ITEM_ITEM, (struct Rectangle *)(&mhd->activemenu->JazzX), mhd, IntuitionBase);
1078 } /* if (mhd->menuwin) */
1081 /**************************************************************************************************/
1083 static void MakeSubMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1085 struct MenuItem *item = mhd->activeitem->SubItem;
1087 struct TagItem win_tags[] =
1089 {WA_Left , 0 },
1090 {WA_Top , 0 },
1091 {WA_Width , 0 },
1092 {WA_Height , 0 },
1093 {WA_AutoAdjust , TRUE },
1094 {WA_Borderless , TRUE },
1095 {WA_CustomScreen, (ULONG)mhd->scr },
1096 {WA_BackFill , (IPTR)LAYERS_NOBACKFILL },
1097 {TAG_DONE }
1100 GetMenuBox(mhd->menubarwin, item, &mhd->submenubox.MinX,
1101 &mhd->submenubox.MinY,
1102 &mhd->submenubox.MaxX,
1103 &mhd->submenubox.MaxY);
1105 win_tags[0].ti_Data = mhd->menuwin->LeftEdge +
1106 mhd->activeitem->LeftEdge - mhd->activemenu->JazzX +
1107 mhd->submenubox.MinX;
1109 win_tags[1].ti_Data = mhd->menuwin->TopEdge +
1110 mhd->activeitem->TopEdge - mhd->activemenu->JazzY +
1111 mhd->submenubox.MinY;
1113 win_tags[2].ti_Data = mhd->submenubox.MaxX - mhd->submenubox.MinX + 1;
1114 win_tags[3].ti_Data = mhd->submenubox.MaxY - mhd->submenubox.MinY + 1;
1116 while(item)
1118 item->Flags &= ~HIGHITEM;
1119 item = item->NextItem;
1122 mhd->submenuwin = OpenWindowTagList(0, win_tags);
1124 mhd->maxcommkeywidth_submenu = CalcMaxCommKeyWidth(mhd->submenuwin, mhd, IntuitionBase);
1126 RenderSubMenu(mhd, IntuitionBase);
1129 /**************************************************************************************************/
1131 static void KillSubMenuWin(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1133 if (mhd->submenuwin)
1135 CloseWindow(mhd->submenuwin);
1136 mhd->submenuwin = NULL;
1138 mhd->activesubitemnum = -1;
1139 mhd->activesubitem = NULL;
1143 /**************************************************************************************************/
1145 static void RenderSubMenu(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1148 if (mhd->submenuwin)
1150 struct MenuItem *item;
1152 RenderMenuBG(mhd->submenuwin, mhd, IntuitionBase);
1154 SetFont(mhd->submenuwin->RPort, mhd->dri->dri_Font);
1156 for(item = mhd->activeitem->SubItem; item; item = item->NextItem)
1158 RenderItem(item, ITEM_SUBITEM, (struct Rectangle *)(&mhd->submenubox), mhd, IntuitionBase);
1161 } /* if (mhd->submenuwin) */
1164 /**************************************************************************************************/
1166 static void RenderItem(struct MenuItem *item, WORD itemtype, struct Rectangle *box,
1167 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1169 struct Window *win = ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1170 struct RastPort *rp = win->RPort;
1171 WORD offx = -box->MinX;
1172 WORD offy = -box->MinY;
1173 BOOL enabled = ((item->Flags & ITEMENABLED) &&
1174 (mhd->activemenu->Flags & MENUENABLED) &&
1175 ((itemtype == ITEM_ITEM) || (mhd->activeitem->Flags & ITEMENABLED)));
1176 BOOL item_supports_disable = FALSE;
1178 SetDrMd(rp, JAM1);
1180 if (item->ItemFill)
1182 if (item->Flags & ITEMTEXT)
1184 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1186 if (MENUS_AMIGALOOK)
1188 PrintIText(rp, it, offx + item->LeftEdge, offy + item->TopEdge);
1190 else
1192 it->FrontPen = mhd->dri->dri_Pens[(item->Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN];
1193 it->DrawMode = JAM1;
1195 PrintIText(rp, it, offx + item->LeftEdge, offy + item->TopEdge);
1198 else
1200 struct Image *im = (struct Image *)item->ItemFill;
1201 LONG state = IDS_NORMAL;
1203 if (!enabled && (im->Depth == CUSTOMIMAGEDEPTH))
1205 IPTR val = 0;
1207 GetAttr(IA_SupportsDisable, (Object *)im, &val);
1208 if (val)
1210 item_supports_disable = TRUE;
1211 state = IDS_DISABLED;
1215 DrawImageState(rp, im, offx + item->LeftEdge, offy + item->TopEdge, state, mhd->dri);
1218 } /* if (item->ItemFill) */
1220 RenderCheckMark(item, itemtype, mhd, IntuitionBase);
1221 RenderAmigaKey(item, itemtype, mhd, IntuitionBase);
1223 if (!enabled && !item_supports_disable)
1225 RenderDisabledPattern(rp, offx + item->LeftEdge,
1226 offy + item->TopEdge,
1227 offx + item->LeftEdge + item->Width - 1,
1228 offy + item->TopEdge + item->Height - 1,
1229 mhd,
1230 IntuitionBase);
1235 /**************************************************************************************************/
1237 static void RenderMenuBG(struct Window *win, struct MenuHandlerData *mhd,
1238 struct IntuitionBase *IntuitionBase)
1240 struct RastPort *rp = win->RPort;
1241 WORD borderx, bordery;
1243 if (MENUS_AMIGALOOK)
1245 borderx = mhd->scr->MenuHBorder / 2;
1246 bordery = mhd->scr->MenuVBorder / 2;
1248 else
1250 borderx = 1;
1251 bordery = 1;
1254 /* White background */
1256 if (MENUS_AMIGALOOK)
1258 SetABPenDrMd(rp, mhd->dri->dri_Pens[BARBLOCKPEN], 0, JAM1);
1260 else
1262 SetABPenDrMd(rp, mhd->dri->dri_Pens[BACKGROUNDPEN], 0, JAM1);
1265 RectFill(rp, borderx,
1266 bordery,
1267 win->Width - 1 - borderx,
1268 win->Height - 1 - bordery);
1270 /* Black border frame */
1272 if (MENUS_AMIGALOOK)
1274 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
1275 RectFill(rp, 0, 0, win->Width - 1, bordery - 1);
1276 RectFill(rp, 0, bordery, borderx - 1, win->Height - 1 - bordery);
1277 RectFill(rp, win->Width - borderx, bordery, win->Width - 1, win->Height - 1);
1278 RectFill(rp, 0, win->Height - bordery, win->Width - 1 - borderx, win->Height - 1);
1280 else
1282 RenderFrame(rp, 0, 0, win->Width - 1, win->Height - 1, IDS_NORMAL, mhd, IntuitionBase);
1286 /**************************************************************************************************/
1288 static void RenderCheckMark(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd,
1289 struct IntuitionBase *IntuitionBase)
1291 struct Window *win = ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1292 struct RastPort *rp = win->RPort;
1293 struct Rectangle *box = ((itemtype == ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->JazzX) : &mhd->submenubox);
1294 WORD offx = -box->MinX;
1295 WORD offy = -box->MinY;
1296 WORD state = ((item->Flags & HIGHITEM) &&
1297 ((item->Flags & HIGHFLAGS) == HIGHCOMP)) ? IDS_SELECTED : IDS_NORMAL;
1299 if (item->Flags & CHECKIT)
1301 WORD x1, y1, x2, y2;
1303 x1 = item->LeftEdge + offx;
1304 y1 = item->TopEdge + offy + (item->Height - mhd->checkmark->Height) / 2;
1305 x2 = x1 + mhd->checkmark->Width - 1;
1306 y2 = y1 + mhd->checkmark->Height - 1;
1308 SetDrMd(rp, JAM1);
1310 if (item->Flags & CHECKED)
1312 DrawImageState(rp, mhd->checkmark, x1, y1, state, mhd->dri);
1314 else
1316 if (MENUS_AMIGALOOK)
1318 SetAPen(rp, mhd->dri->dri_Pens[BARBLOCKPEN]);
1320 else
1322 SetAPen(rp, mhd->dri->dri_Pens[(state == IDS_SELECTED) ? FILLPEN : BACKGROUNDPEN]);
1325 RectFill(rp, x1, y1, x2, y2);
1331 /**************************************************************************************************/
1333 static void RenderAmigaKey(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd,
1334 struct IntuitionBase *IntuitionBase)
1336 struct Window *win = ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1337 struct RastPort *rp = win->RPort;
1338 struct Rectangle *box = ((itemtype == ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->JazzX) : &mhd->submenubox);
1339 WORD commkeywidth = ((itemtype == ITEM_ITEM) ? mhd->maxcommkeywidth_menu : mhd->maxcommkeywidth_submenu);
1340 WORD offx = -box->MinX;
1341 WORD offy = -box->MinY;
1342 WORD state = ((item->Flags & HIGHITEM) &&
1343 ((item->Flags & HIGHFLAGS) == HIGHCOMP)) ? IDS_SELECTED : IDS_NORMAL;
1345 if (item->Flags & COMMSEQ)
1347 struct TextFont *oldfont = rp->Font;
1348 struct TextFont *newfont = NULL;
1350 WORD x1, y1, x2, y2;
1352 if (item->Flags & ITEMTEXT)
1354 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1356 if (it->ITextFont)
1358 if ((newfont = OpenFont(it->ITextFont)))
1360 SetFont(rp, newfont);
1365 x1 = item->LeftEdge + offx + item->Width - AMIGAKEY_BORDER_SPACING -
1366 mhd->amigakey->Width - AMIGAKEY_KEY_SPACING - commkeywidth;
1367 y1 = item->TopEdge + offy + (item->Height - mhd->amigakey->Height + 1) / 2;
1368 x2 = x1 + mhd->amigakey->Width - 1;
1369 y2 = y1 + mhd->amigakey->Height - 1;
1371 SetDrMd(rp, JAM1);
1373 DrawImageState(rp, mhd->amigakey, x1, y1, state, mhd->dri);
1375 x1 += mhd->amigakey->Width + AMIGAKEY_KEY_SPACING;
1377 if (MENUS_AMIGALOOK)
1379 SetAPen(rp, mhd->dri->dri_Pens[BARDETAILPEN]);
1381 else
1383 SetAPen(rp, mhd->dri->dri_Pens[(item->Flags & HIGHITEM) ? FILLTEXTPEN : TEXTPEN]);
1386 Move(rp, x1, item->TopEdge + offy + (item->Height - rp->TxHeight) / 2 +
1387 rp->TxBaseline);
1388 Text(rp, &item->Command, 1);
1390 if (newfont)
1392 CloseFont(newfont);
1393 SetFont(rp, oldfont);
1396 } /* if (item->Flags & COMMSEQ) */
1399 /**************************************************************************************************/
1401 static void RenderDisabledPattern(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2,
1402 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1404 static UWORD pattern [] = {0x8888, 0x2222};
1406 SetDrMd(rp, JAM1);
1408 if (MENUS_AMIGALOOK)
1410 SetAPen(rp, mhd->dri->dri_Pens[BARBLOCKPEN]);
1412 else
1414 SetAPen(rp, mhd->dri->dri_Pens[BACKGROUNDPEN]);
1417 SetAfPt(rp, pattern, 1);
1419 RectFill(rp, x1, y1, x2, y2);
1421 SetAfPt(rp, NULL, 0);
1425 /**************************************************************************************************/
1427 static void RenderFrame(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2, WORD state,
1428 struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1430 SetAPen(rp, mhd->dri->dri_Pens[(state == IDS_SELECTED) ? SHADOWPEN : SHINEPEN]);
1432 RectFill(rp, x1, y1, x2, y1);
1433 RectFill(rp, x1, y1 + 1, x1, y2);
1435 SetAPen(rp, mhd->dri->dri_Pens[(state == IDS_SELECTED) ? SHINEPEN : SHADOWPEN]);
1436 RectFill(rp, x2, y1 + 1, x2, y2);
1437 RectFill(rp, x1 + 1, y2, x2 - 1, y2);
1439 /**************************************************************************************************/
1441 static void HighlightItem(struct MenuItem *item, WORD itemtype, struct MenuHandlerData *mhd,
1442 struct IntuitionBase *IntuitionBase)
1444 struct Window *win = ((itemtype == ITEM_ITEM) ? mhd->menuwin : mhd->submenuwin);
1445 struct RastPort *rp = win->RPort;
1446 struct Rectangle *box = ((itemtype == ITEM_ITEM) ? ((struct Rectangle *)&mhd->activemenu->JazzX) : &mhd->submenubox);
1447 APTR fill;
1448 WORD offx = -box->MinX;
1449 WORD offy = -box->MinY;
1450 WORD x1, y1, x2, y2;
1451 BOOL enabled;
1453 enabled = (item->Flags & ITEMENABLED) ? TRUE : FALSE;
1454 if (!(mhd->activemenu->Flags & MENUENABLED)) enabled = FALSE;
1455 if ((itemtype == ITEM_SUBITEM) && !(mhd->activeitem->Flags & ITEMENABLED)) enabled = FALSE;
1457 if (enabled)
1459 item->Flags ^= HIGHITEM;
1461 fill = item->ItemFill;
1462 if ((item->Flags & HIGHITEM) && (item->SelectFill)) fill = item->SelectFill;
1464 x1 = offx + item->LeftEdge;
1465 y1 = offy + item->TopEdge;
1466 x2 = x1 + item->Width - 1;
1467 y2 = y1 + item->Height - 1;
1469 switch(item->Flags & HIGHFLAGS)
1471 case HIGHIMAGE:
1472 SetDrMd(rp, JAM1);
1474 if(item->Flags & ITEMTEXT)
1476 if (MENUS_AMIGALOOK)
1478 PrintIText(rp, (struct IntuiText *)fill, x1, y1);
1480 else
1482 struct IntuiText *it = (struct IntuiText *)fill;
1484 it->FrontPen = mhd->dri->dri_Pens[TEXTPEN];
1485 it->DrawMode = JAM1;
1487 PrintIText(rp, it, x1, y1);
1490 else
1492 EraseImage(rp, (struct Image *)fill, x1, y1);
1493 DrawImageState(rp, (struct Image *)fill, x1, y1, IDS_SELECTED, mhd->dri);
1495 break;
1497 case HIGHCOMP:
1498 if (MENUS_AMIGALOOK)
1500 SetDrMd(rp, COMPLEMENT);
1501 RectFill(rp, x1, y1, x2, y2);
1503 else
1505 WORD state = (item->Flags & HIGHITEM) ? IDS_SELECTED : IDS_NORMAL;
1507 SetDrMd(rp, JAM1);
1508 SetAPen(rp, mhd->dri->dri_Pens[(state == IDS_SELECTED) ? FILLPEN : BACKGROUNDPEN]);
1509 RectFill(rp, x1, y1, x2, y2);
1511 RenderItem(item, itemtype, box, mhd, IntuitionBase);
1513 if (state == IDS_SELECTED)
1515 RenderFrame(rp, x1, y1, x2, y2, state, mhd, IntuitionBase);
1518 break;
1520 case HIGHBOX:
1521 SetDrMd(rp, COMPLEMENT);
1522 offx = mhd->scr->MenuHBorder;
1523 offy = mhd->scr->MenuVBorder;
1525 x1 -= offx;
1526 x2 += offx;
1527 y1 -= offy;
1528 y2 += offy;
1530 RectFill(rp, x1, y1, x2, y1 + offy - 1);
1531 RectFill(rp, x2 - offx + 1, y1 + offy, x2, y2);
1532 RectFill(rp, x1, y2 - offy + 1, x2 - offx, y2);
1533 RectFill(rp, x1, y1 + offy, x1 + offx - 1,y2 - offy);
1534 break;
1536 case HIGHNONE:
1537 /* Do nothing */
1538 break;
1540 } /* switch(item->Flags & HIGHFLAGS) */
1542 } /* if (enabled) */
1546 /**************************************************************************************************/
1548 static WORD CalcMaxCommKeyWidth(struct Window *win, struct MenuHandlerData *mhd,
1549 struct IntuitionBase *IntuitionBase)
1551 struct TextExtent te;
1552 WORD maxwidth;
1554 FontExtent(mhd->dri->dri_Font, &te);
1555 maxwidth = te.te_Width;
1557 if (win)
1559 struct MenuItem *item;
1561 if ((win == mhd->menuwin))
1563 item = mhd->activemenu->FirstItem;
1565 else
1567 item = mhd->activeitem->SubItem;
1570 for(; item; item = item->NextItem)
1572 if (item->Flags & ITEMTEXT)
1574 struct IntuiText *it = (struct IntuiText *)item->ItemFill;
1576 if (it->ITextFont)
1578 struct TextFont *font;
1580 if ((font = OpenFont(it->ITextFont)))
1582 FontExtent(font, &te);
1583 if (te.te_Width > maxwidth) maxwidth = te.te_Width;
1585 CloseFont(font);
1589 } /* if (item->Flags & ITEMTEXT) */
1591 } /* for(; item; item = item->NextItem); */
1593 } /* if (win) */
1595 return maxwidth;
1598 /**************************************************************************************************/
1600 static void AddToSelection(struct MenuHandlerData *mhd, struct IntuitionBase *IntuitionBase)
1602 if ((mhd->activemenunum != -1) && (mhd->activemenu->Flags & MENUENABLED) &&
1603 (mhd->activeitemnum != -1) && (mhd->activeitem->Flags & ITEMENABLED))
1605 struct MenuItem *item = NULL;
1606 UWORD men = FULLMENUNUM(mhd->activemenunum, mhd->activeitemnum, mhd->activesubitemnum);
1608 if (mhd->activesubitemnum != -1)
1610 if (mhd->activesubitem->Flags & ITEMENABLED) item = mhd->activesubitem;
1612 else if (!mhd->activeitem->SubItem)
1614 item = mhd->activeitem;
1617 if (item && (ItemAddress(mhd->menu, men) == item))
1619 UWORD men = FULLMENUNUM(mhd->activemenunum, mhd->activeitemnum, mhd->activesubitemnum);
1621 if (mhd->firstmenupick == MENUNULL)
1623 mhd->firstmenupick = men;
1625 else if (men != mhd->lastmenupick)
1627 struct MenuItem *checkitem, *prevcheckitem = NULL;
1628 UWORD checkmen = mhd->firstmenupick;
1630 /* Remove men from pick queue, if it was already in there
1631 and then add it at the end of the pick queue */
1633 while(checkmen != MENUNULL)
1635 checkitem = ItemAddress(mhd->menu, checkmen);
1637 if (checkmen == men)
1639 if (prevcheckitem == NULL)
1641 mhd->firstmenupick = checkitem->NextSelect;
1643 else
1645 prevcheckitem->NextSelect = checkitem->NextSelect;
1649 checkmen = checkitem->NextSelect;
1650 prevcheckitem = checkitem;
1652 } /* while(checkmen != MENUNULL) */
1654 checkitem->NextSelect = men;
1656 } /* else if (men != mhd->lastmenupick) */
1658 mhd->lastmenupick = men;
1659 item->NextSelect = MENUNULL;
1661 } /* if (item) */
1663 } /* if ((mhd->activemenunum != -1) && (mhd->activeitemnum != -1)) */