2 Copyright 1995-2007, The AROS Development Team. All rights reserved.
3 Copyright 2001-2003, The MorphOS Development Team. All Rights Reserved.
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 <devices/timer.h>
26 #include "inputhandler.h"
27 #include "intuition_intern.h"
31 #include "intuition_customize.h"
36 #include <cybergraphx/cybergraphics.h>
40 #include <aros/debug.h>
42 extern IPTR
HookEntry();
44 /**************************************************************************************************/
46 /* this #defines are taken from workbench/libs/gadtools/menus.c!! */
48 #define TEXT_AMIGAKEY_SPACING 6
50 #define ITEXT_EXTRA_LEFT 2
51 #define ITEXT_EXTRA_RIGHT 2
52 #define ITEXT_EXTRA_TOP 1
53 #define ITEXT_EXTRA_BOTTOM 1
55 /**************************************************************************************************/
57 static void HandleMouseMove(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
);
58 static void HandleMouseClick(struct InputEvent
*ie
, struct MenuHandlerData
*mhd
,
59 struct IntuitionBase
*IntuitionBase
);
60 static void HandleCheckItem(struct Window
*win
, struct MenuItem
*item
,
61 struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
);
63 static void HighlightMenuTitle(struct Menu
*menu
, struct MenuHandlerData
*mhd
,
64 struct IntuitionBase
*IntuitionBase
);
66 static struct Menu
*FindMenu(WORD
*var
, struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
);
67 static struct MenuItem
*FindItem(WORD
*var
, struct MenuHandlerData
*mhd
);
68 static struct MenuItem
*FindSubItem(WORD
*var
, struct MenuHandlerData
*mhd
);
70 static void MakeMenuBarWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
);
71 static void KillMenuBarWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
);
72 static void RenderMenuBar(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
);
74 static void MakeMenuWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
);
75 static void KillMenuWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
);
76 static void RenderMenu(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
);
77 static void RenderMenuTitle(struct Menu
*menu
, struct MenuHandlerData
*mhd
,
78 struct IntuitionBase
*IntuitionBase
);
80 static void MakeSubMenuWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
);
81 static void KillSubMenuWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
);
82 static void RenderSubMenu(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
);
84 static void RenderItem(struct MenuItem
*item
, WORD itemtype
, struct Rectangle
*box
,
85 struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
);
87 static void RenderMenuBG(struct Window
*win
, struct MenuHandlerData
*mhd
,
88 struct IntuitionBase
*IntuitionBase
);
89 static void RenderCheckMark(struct MenuItem
*item
, WORD itemtype
, struct MenuHandlerData
*mhd
,
90 struct IntuitionBase
*IntuitionBase
);
91 static void RenderAmigaKey(struct MenuItem
*item
, WORD itemtype
, struct MenuHandlerData
*mhd
,
92 struct IntuitionBase
*IntuitionBase
);
93 static void RenderDisabledPattern(struct RastPort
*rp
, WORD x1
, WORD y1
, WORD x2
, WORD y2
,
94 struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
);
95 static void RenderFrame(struct RastPort
*rp
, WORD x1
, WORD y1
, WORD x2
, WORD y2
, WORD state
,
96 struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
);
97 static void HighlightItem(struct MenuItem
*item
, WORD itemtype
, struct MenuHandlerData
*mhd
,
98 struct IntuitionBase
*IntuitionBase
);
99 static WORD
CalcMaxCommKeyWidth(struct Window
*win
, struct MenuHandlerData
*mhd
,
100 struct IntuitionBase
*IntuitionBase
);
101 static void AddToSelection(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
);
104 /**************************************************************************************************/
105 /******************************
106 ** CreateMenuHandlerTask() **
107 ******************************/
108 struct Task
*CreateMenuHandlerTask(APTR taskparams
, struct IntuitionBase
*IntuitionBase
)
113 task
= AllocMem(sizeof (struct Task
), MEMF_PUBLIC
|MEMF_CLEAR
);
116 NEWLIST(&task
->tc_MemEntry
);
117 task
->tc_Node
.ln_Type
= NT_TASK
;
118 task
->tc_Node
.ln_Name
= MENUTASK_NAME
;
119 task
->tc_Node
.ln_Pri
= MENUTASK_PRIORITY
;
121 stack
= AllocMem(MENUTASK_STACKSIZE
, MEMF_PUBLIC
);
124 task
->tc_SPLower
=stack
;
125 task
->tc_SPUpper
=(UBYTE
*)stack
+ MENUTASK_STACKSIZE
;
128 task
->tc_SPReg
= task
->tc_SPUpper
;
131 struct TaskInitExtension taskext
;
132 struct TagItem tags
[4];
134 taskext
.Trap
= TRAP_PPCTASK
;
135 taskext
.Extension
= 0;
138 tags
[0].ti_Tag
= TASKTAG_CODETYPE
;
139 tags
[0].ti_Data
= CODETYPE_PPC
;
140 tags
[1].ti_Tag
= TASKTAG_PC
;
141 tags
[1].ti_Data
= (ULONG
)DefaultMenuHandler
;
142 tags
[2].ti_Tag
= TASKTAG_PPC_ARG1
;
143 tags
[2].ti_Data
= (ULONG
)taskparams
;
144 tags
[3].ti_Tag
= TAG_END
;
146 if(AddTask(task
, (APTR
)&taskext
, NULL
) != NULL
)
148 /* Everything went OK */
154 struct TagItem tags
[] =
156 {TASKTAG_ARG1
, (IPTR
)taskparams
},
160 #if AROS_STACK_GROWS_DOWNWARDS
161 task
->tc_SPReg
= (UBYTE
*)task
->tc_SPUpper
-SP_OFFSET
;
163 task
->tc_SPReg
=(UBYTE
*)task
->tc_SPLower
+SP_OFFSET
;
166 if(NewAddTask(task
, DefaultMenuHandler
, NULL
, tags
) != NULL
)
168 /* Everything went OK */
174 FreeMem(stack
, MENUTASK_STACKSIZE
);
176 } /* if(stack != NULL) */
177 FreeMem(task
,sizeof(struct Task
));
184 #undef DefaultMenuHandler
187 /**************************************************************************************************/
189 /***************************
190 ** DefaultMenuHandler() **
191 ***************************/
192 void DefaultMenuHandler(struct MenuTaskParams
*taskparams
)
194 struct IntuitionBase
*IntuitionBase
= taskparams
->intuitionBase
;
195 struct MenuHandlerData
*mhd
= NULL
;
197 struct MsgPort
*port
= NULL
;
198 BOOL success
= FALSE
;
200 if ((mem
= AllocMem(sizeof(struct MsgPort
) +
201 sizeof(struct MenuHandlerData
), MEMF_PUBLIC
| MEMF_CLEAR
)))
203 port
= (struct MsgPort
*)mem
;
205 port
->mp_Node
.ln_Type
= NT_MSGPORT
;
206 port
->mp_Flags
= PA_SIGNAL
;
207 port
->mp_SigBit
= AllocSignal(-1);
208 port
->mp_SigTask
= FindTask(0);
209 NEWLIST(&port
->mp_MsgList
);
211 mhd
= (struct MenuHandlerData
*)(mem
+ sizeof(struct MsgPort
));
215 } /* if ((mem = AllocMem(sizeof(struct MsgPort), MEMF_PUBLIC | MEMF_CLEAR))) */
219 taskparams
->MenuHandlerPort
= port
;
220 taskparams
->success
= TRUE
;
223 Signal(taskparams
->Caller
, SIGF_INTUITION
);
227 D(bug("DefaultMenuHandler: initialization failed. waiting for parent task to kill me.\n"));
231 D(bug("DefaultMenuHandler: initialization ok. Now waiting for messages from Intuition.\n"));
235 struct MenuMessage
*msg
;
238 while((msg
= GetMenuMessage(port
, IntuitionBase
)))
244 mhd
->scr
= mhd
->win
->WScreen
;
245 mhd
->dri
= GetScreenDrawInfo(mhd
->scr
);
246 mhd
->menu
= msg
->win
->MenuStrip
;
247 mhd
->activemenunum
= -1;
248 mhd
->activeitemnum
= -1;
249 mhd
->activesubitemnum
= -1;
250 mhd
->checkmark
= ((struct IntWindow
*)mhd
->win
)->Checkmark
;
251 mhd
->amigakey
= ((struct IntWindow
*)mhd
->win
)->AmigaKey
;
252 mhd
->submenuimage
= ((struct IntWindow
*)mhd
->win
)->SubMenuImage
;
253 mhd
->scrmousex
= mhd
->scr
->MouseX
;
254 mhd
->scrmousey
= mhd
->scr
->MouseY
;
255 mhd
->firstmenupick
= MENUNULL
;
256 mhd
->TrueColor
= GetBitMapAttr(&mhd
->scr
->BitMap
, BMA_DEPTH
) > 8 ? TRUE
: FALSE
;
258 /* close windows in the back first because
260 MakeMenuBarWin(mhd
, IntuitionBase
);
261 HandleMouseMove(mhd
, IntuitionBase
);
267 /* there might come additional messages from Intuition
268 even when we have already told it to make the menus
269 inactive, but since everything is async, this cannot
270 be avoided, so check if we are really active */
274 switch(msg
->ie
.ie_Class
)
276 case IECLASS_RAWMOUSE
:
277 if (msg
->ie
.ie_Code
== IECODE_NOBUTTON
)
279 HandleMouseMove(mhd
, IntuitionBase
);
283 HandleMouseClick(&msg
->ie
, mhd
, IntuitionBase
);
289 } /* if (mhd->active) */
292 } /* switch(msg->code) */
294 ReplyMenuMessage(msg
, IntuitionBase
);
296 } /* while((msg = (struct MenuMessage *)GetMsg(port))) */
301 /**************************************************************************************************/
303 /*******************************
304 ** InitDefaultMenuHandler() **
305 *******************************/
306 BOOL
InitDefaultMenuHandler(struct IntuitionBase
*IntuitionBase
)
308 struct MenuTaskParams params
;
312 params
.intuitionBase
= IntuitionBase
;
313 params
.Caller
= FindTask(NULL
);
314 params
.success
= FALSE
;
316 SetSignal(0, SIGF_INTUITION
);
318 if ((task
= CreateMenuHandlerTask(¶ms
, IntuitionBase
)))
320 Wait(SIGF_INTUITION
);
325 GetPrivIBase(IntuitionBase
)->MenuHandlerPort
= params
.MenuHandlerPort
;
332 } /* if ((task = CreateMenuHandlerTask(¶ms, IntuitionBase))) */
338 /**************************************************************************************************/
340 static void HandleMouseMove(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
343 struct Window
*win
= NULL
;
345 struct MenuItem
*item
;
346 WORD new_activemenunum
= mhd
->activemenunum
;
347 WORD new_activeitemnum
= mhd
->activeitemnum
;
348 WORD new_activesubitemnum
= mhd
->activesubitemnum
;
350 mhd
->scrmousex
= mhd
->scr
->MouseX
;
351 mhd
->scrmousey
= mhd
->scr
->MouseY
;
353 if ((lay
= WhichLayer(&mhd
->scr
->LayerInfo
, mhd
->scrmousex
, mhd
->scrmousey
)))
355 win
= (struct Window
*)lay
->Window
;
357 if (win
&& (win
== mhd
->submenuwin
))
359 /* Mouse over submenu box */
360 item
= FindSubItem(&new_activesubitemnum
, mhd
);
362 if (new_activesubitemnum
!= mhd
->activesubitemnum
)
364 if (mhd
->activesubitemnum
!= -1)
366 HighlightItem(mhd
->activesubitem
, ITEM_SUBITEM
, mhd
, IntuitionBase
);
369 mhd
->activesubitemnum
= new_activesubitemnum
;
370 mhd
->activesubitem
= item
;
374 HighlightItem(mhd
->activesubitem
, ITEM_SUBITEM
, mhd
, IntuitionBase
);
379 else if (win
&& (win
== mhd
->menuwin
))
381 item
= FindItem(&new_activeitemnum
, mhd
);
383 if (new_activeitemnum
!= mhd
->activeitemnum
)
385 if (mhd
->activeitemnum
!= -1)
387 HighlightItem(mhd
->activeitem
, ITEM_ITEM
, mhd
, IntuitionBase
);
388 KillSubMenuWin(mhd
, IntuitionBase
);
391 mhd
->activeitemnum
= new_activeitemnum
;
392 mhd
->activeitem
= item
;
396 HighlightItem(mhd
->activeitem
, ITEM_ITEM
, mhd
, IntuitionBase
);
400 MakeSubMenuWin(mhd
, IntuitionBase
);
404 } /* if (win && (win == mhd->menuwin)) */
405 else if (win
&& (win
== mhd
->menubarwin
))
407 /* Mouse over menu box */
409 menu
= FindMenu(&new_activemenunum
, mhd
, IntuitionBase
);
411 if (new_activemenunum
!= mhd
->activemenunum
)
414 if (mhd
->activemenunum
!= -1)
417 HighlightMenuTitle(mhd
->activemenu
, mhd
, IntuitionBase
);
418 KillMenuWin(mhd
, IntuitionBase
);
419 KillSubMenuWin(mhd
, IntuitionBase
);
422 mhd
->activemenunum
= new_activemenunum
;
423 mhd
->activemenu
= menu
;
427 HighlightMenuTitle(mhd
->activemenu
, mhd
, IntuitionBase
);
428 MakeMenuWin(mhd
, IntuitionBase
);
432 if ((mhd
->activeitemnum
!= -1) && (!mhd
->submenuwin
))
434 HighlightItem(mhd
->activeitem
, ITEM_ITEM
, mhd
, IntuitionBase
);
435 mhd
->activeitemnum
= -1;
436 mhd
->activeitem
= NULL
;
439 } /* if (win && (win == mhd->menubarwin)) */
444 } /* if ((lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey))) */
448 /* mouse outside any menu window */
450 if ((mhd
->activeitemnum
!= -1) && (!mhd
->submenuwin
))
452 HighlightItem(mhd
->activeitem
, ITEM_ITEM
, mhd
, IntuitionBase
);
453 mhd
->activeitemnum
= -1;
454 mhd
->activeitem
= NULL
;
456 else if (mhd
->activesubitemnum
!= -1)
458 HighlightItem(mhd
->activesubitem
, ITEM_SUBITEM
, mhd
, IntuitionBase
);
459 mhd
->activesubitemnum
= -1;
460 mhd
->activesubitem
= NULL
;
466 /**************************************************************************************************/
468 static void HandleMouseClick(struct InputEvent
*ie
, struct MenuHandlerData
*mhd
,
469 struct IntuitionBase
*IntuitionBase
)
478 if ((lay
= WhichLayer(&mhd
->scr
->LayerInfo
, mhd
->scrmousex
, mhd
->scrmousey
)))
480 struct Window
*win
= (struct Window
*)lay
->Window
;
481 struct MenuItem
*item
= NULL
;
483 win
= (struct Window
*)lay
->Window
;
485 if (win
&& (win
== mhd
->submenuwin
) && (mhd
->activesubitemnum
!= -1))
487 item
= mhd
->activesubitem
;
490 else if (win
&& (win
== mhd
->menuwin
) && (mhd
->activeitemnum
!= -1))
492 item
= mhd
->activeitem
;
495 if (item
) if (item
->Flags
& CHECKIT
)
497 HandleCheckItem(win
, item
, mhd
, IntuitionBase
);
500 AddToSelection(mhd
, IntuitionBase
);
502 } /* if ((lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey))) */
504 if (ie
->ie_Code
== MENUUP
)
506 KillMenuBarWin(mhd
, IntuitionBase
);
507 KillMenuWin(mhd
, IntuitionBase
);
508 KillSubMenuWin(mhd
, IntuitionBase
);
512 FreeScreenDrawInfo(mhd
->scr
, mhd
->dri
);
515 MH2Int_MakeMenusInactive(mhd
->win
, mhd
->firstmenupick
, IntuitionBase
);
522 } /* switch(ie->ie_Code) */
525 /**************************************************************************************************/
527 static void HandleCheckItem(struct Window
*win
, struct MenuItem
*item
,
528 struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
530 /* Note: If you change something here, you probably must also change
531 menus.c/CheckMenuItemWasClicked() which is used when the
532 user uses the menu key shortcuts! */
534 WORD itemtype
= ((win
== mhd
->menuwin
) ? ITEM_ITEM
: ITEM_SUBITEM
);
536 BOOL re_render
= FALSE
;
538 if (item
->Flags
& MENUTOGGLE
)
540 item
->Flags
^= CHECKED
;
545 if (!(item
->Flags
& CHECKED
))
547 item
->Flags
|= CHECKED
;
554 BOOL toggle_hi
= FALSE
;
556 if ((item
->Flags
& HIGHITEM
) &&
557 ((item
->Flags
& HIGHFLAGS
) == HIGHCOMP
)) toggle_hi
= TRUE
;
559 if (toggle_hi
) HighlightItem(item
, itemtype
, mhd
, IntuitionBase
);
560 RenderCheckMark(item
, itemtype
, mhd
, IntuitionBase
);
561 if (toggle_hi
) HighlightItem(item
, itemtype
, mhd
, IntuitionBase
);
565 if (item
->MutualExclude
)
567 struct MenuItem
*checkitem
= (itemtype
== ITEM_ITEM
) ? mhd
->activemenu
->FirstItem
:
568 mhd
->activeitem
->SubItem
;
569 BOOL toggle_hi
= FALSE
;
572 if ((item
->Flags
& HIGHITEM
) &&
573 ((item
->Flags
& HIGHFLAGS
) == HIGHBOX
)) toggle_hi
= TRUE
;
575 if (toggle_hi
) HighlightItem(item
, itemtype
, mhd
, IntuitionBase
);
577 for(i
= 0; (i
< 32) && checkitem
; i
++, checkitem
= checkitem
->NextItem
)
579 if ((item
->MutualExclude
& (1L << i
)) &&
580 ((checkitem
->Flags
& (CHECKED
| CHECKIT
)) == (CHECKIT
| CHECKED
)))
582 checkitem
->Flags
&= ~CHECKED
;
583 RenderCheckMark(checkitem
, itemtype
, mhd
, IntuitionBase
);
587 if (toggle_hi
) HighlightItem(item
, itemtype
, mhd
, IntuitionBase
);
589 } /* if (item->MutualExclude) */
592 /**************************************************************************************************/
594 static void HighlightMenuTitle(struct Menu
*menu
, struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
596 BOOL customdraw
= FALSE
;
598 if (menu
->Flags
& MENUENABLED
)
600 struct RastPort
*rp
= mhd
->menubarwin
->RPort
;
603 if (MENUS_UNDERMOUSE
)
606 struct Menu
*m
= mhd
->menu
;
610 x2
= x1
+ mhd
->menubaritemwidth
- 1;
612 for(i
= 0; m
!= menu
; m
= m
->NextMenu
) i
++;
614 y1
= mhd
->innertop
+ i
* mhd
->menubaritemheight
;
615 y2
= y1
+ mhd
->menubaritemheight
- 1;
620 x1
= menu
->LeftEdge
+ mhd
->scr
->BarHBorder
- mhd
->scr
->MenuHBorder
;
622 x2
= x1
+ menu
->Width
- 1;
623 y2
= mhd
->scr
->BarHeight
- 1;
629 SetDrMd(rp
, COMPLEMENT
);
630 RectFill(rp
, x1
, y1
, x2
, y2
);
634 menu
->Flags
^= HIGHITEM
;
635 if (MENUS_UNDERMOUSE
)
637 struct mdpDrawBackground msg
;
639 msg
.MethodID
= MDM_DRAWBACKGROUND
;
641 msg
.mdp_TrueColor
= mhd
->TrueColor
;
644 msg
.mdp_Width
= mhd
->win
->Width
- 1;
645 msg
.mdp_Height
= mhd
->win
->Height
- 1;
646 msg
.mdp_ItemLeft
= x1
;
647 msg
.mdp_ItemTop
= y1
;
648 msg
.mdp_ItemWidth
= x2
- x1
+ 1;
649 msg
.mdp_ItemHeight
= y2
- y1
+ 1;
650 msg
.mdp_Flags
= menu
->Flags
;
651 if (mhd
->win
== mhd
->submenuwin
) msg
.mdp_UserBuffer
= mhd
->SubDecorUserBuffer
;
652 else if (mhd
->win
== mhd
->menuwin
) msg
.mdp_UserBuffer
= mhd
->DecorUserBuffer
;
653 else msg
.mdp_UserBuffer
= mhd
->BarDecorUserBuffer
;
654 customdraw
= DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
657 if (!MENUS_UNDERMOUSE
) y1
++;
661 SetAPen(rp
, mhd
->dri
->dri_Pens
[(menu
->Flags
& HIGHITEM
) ? FILLPEN
: BACKGROUNDPEN
]);
662 RectFill(rp
, x1
, y1
, x2
, y2
);
664 RenderMenuTitle(menu
, mhd
, IntuitionBase
);
666 if ((menu
->Flags
& HIGHITEM
) && !customdraw
)
668 if (MENUS_UNDERMOUSE
)
670 RenderFrame(rp
, x1
, y1
, x2
, y2
, IDS_SELECTED
, mhd
, IntuitionBase
);
674 SetAPen(rp
, mhd
->dri
->dri_Pens
[SHINEPEN
]);
675 RectFill(rp
, x1
, y1
, x1
, y2
);
676 SetAPen(rp
, mhd
->dri
->dri_Pens
[SHADOWPEN
]);
677 RectFill(rp
, x2
, y1
, x2
, y2
);
684 /**************************************************************************************************/
686 static struct Menu
*FindMenu(WORD
*var
, struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
689 WORD mouse_x
, mouse_y
, i
;
691 mouse_x
= mhd
->scrmousex
- mhd
->menubarwin
->LeftEdge
;
692 mouse_y
= mhd
->scrmousey
- mhd
->menubarwin
->TopEdge
;
694 if (MENUS_UNDERMOUSE
)
698 mouse_x
-= mhd
->innerleft
;
699 mouse_y
-= mhd
->innertop
;
701 if ((mouse_x
>= 0) && (mouse_x
< mhd
->menubaritemwidth
) && (mouse_y
>= 0))
703 i
= mouse_y
/ mhd
->menubaritemheight
;
705 if ((i
>= 0) && (i
< mhd
->nummenubaritems
))
713 menu
= menu
->NextMenu
;
716 if (menu
&& (i
== 0))
725 for(menu
= mhd
->menu
, i
= 0; menu
; menu
= menu
->NextMenu
, i
++)
727 if ((mouse_x
>= menu
->LeftEdge
) &&
728 (mouse_x
< menu
->LeftEdge
+ menu
->Width
) &&
730 (mouse_y
<= mhd
->scr
->BarHeight
))
741 /**************************************************************************************************/
743 static struct MenuItem
*FindItem(WORD
*var
, struct MenuHandlerData
*mhd
)
745 struct MenuItem
*item
= NULL
;
746 WORD mouse_x
, mouse_y
, i
;
750 mouse_x
= mhd
->scrmousex
- mhd
->menuwin
->LeftEdge
+ mhd
->activemenu
->JazzX
- mhd
->innerleft
;
751 mouse_y
= mhd
->scrmousey
- mhd
->menuwin
->TopEdge
+ mhd
->activemenu
->JazzY
- mhd
->innertop
;
753 for(item
= mhd
->activemenu
->FirstItem
, i
= 0; item
; item
= item
->NextItem
, i
++)
755 if ((mouse_x
>= item
->LeftEdge
) &&
756 (mouse_x
< item
->LeftEdge
+ item
->Width
) &&
757 (mouse_y
>= item
->TopEdge
) &&
758 (mouse_y
< item
->TopEdge
+ item
->Height
))
764 } /* if (mhd->menuwin) */
766 if ((item
== NULL
) && !mhd
->submenuwin
) *var
= -1;
771 /**************************************************************************************************/
773 static struct MenuItem
*FindSubItem(WORD
*var
, struct MenuHandlerData
*mhd
)
775 struct MenuItem
*item
= NULL
;
776 WORD mouse_x
, mouse_y
, i
;
780 mouse_x
= mhd
->scrmousex
- mhd
->submenuwin
->LeftEdge
+ mhd
->submenubox
.MinX
- mhd
->menuinnerleft
;
781 mouse_y
= mhd
->scrmousey
- mhd
->submenuwin
->TopEdge
+ mhd
->submenubox
.MinY
- mhd
->menuinnertop
;
785 for(item
= mhd
->activeitem
->SubItem
, i
= 0; item
; item
= item
->NextItem
, i
++)
787 if ((mouse_x
>= item
->LeftEdge
) &&
788 (mouse_x
< item
->LeftEdge
+ item
->Width
) &&
789 (mouse_y
>= item
->TopEdge
) &&
790 (mouse_y
< item
->TopEdge
+ item
->Height
))
797 } /* if (mhd->menuwin) */
802 /**************************************************************************************************/
804 static void MakeMenuBarWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
806 struct TagItem win_tags
[] =
810 {WA_Width
, mhd
->scr
->Width
},
811 {WA_Height
, mhd
->scr
->BarHeight
+ 1 },
812 {WA_AutoAdjust
, TRUE
},
813 {WA_Borderless
, TRUE
},
814 {WA_CustomScreen
, (ULONG
)mhd
->scr
},
815 {WA_BackFill
, (IPTR
)LAYERS_NOBACKFILL
},
820 if (MENUS_UNDERMOUSE
)
822 struct RastPort
*temprp
;
825 if (!(temprp
= CloneRastPort(&mhd
->scr
->RastPort
))) return;
827 mhd
->nummenubaritems
= 0;
828 for(menu
= mhd
->menu
; menu
; menu
= menu
->NextMenu
)
830 w
= TextLength(temprp
, menu
->MenuName
, strlen(menu
->MenuName
));
831 if (w
> maxw
) maxw
= w
;
832 mhd
->nummenubaritems
++;
835 mhd
->menubaritemwidth
= maxw
+ mhd
->submenuimage
->Width
+
836 TEXT_AMIGAKEY_SPACING
+
840 if (temprp
->TxHeight
> mhd
->submenuimage
->Height
) mhd
->menubaritemheight
= temprp
->TxHeight
; else mhd
->menubaritemheight
= mhd
->submenuimage
->Height
;
842 mhd
->menubaritemheight
+= (ITEXT_EXTRA_TOP
+ ITEXT_EXTRA_BOTTOM
);
844 struct mdpGetMenuSpaces msg
;
846 msg
.MethodID
= MDM_GETMENUSPACES
;
847 msg
.mdp_TrueColor
= mhd
->TrueColor
;
848 msg
.mdp_InnerLeft
= mhd
->scr
->MenuHBorder
;
849 msg
.mdp_InnerTop
= mhd
->scr
->MenuVBorder
;
850 msg
.mdp_InnerRight
= mhd
->scr
->MenuHBorder
;
851 msg
.mdp_InnerBottom
= mhd
->scr
->MenuVBorder
;
852 msg
.mdp_ItemInnerLeft
= 0;
853 msg
.mdp_ItemInnerTop
= 0;
854 msg
.mdp_ItemInnerRight
= 0;
855 msg
.mdp_ItemInnerBottom
= 0;
856 msg
.mdp_MinWidth
= 0;
857 msg
.mdp_MinHeight
= 0;
858 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
859 mhd
->innerleft
= msg
.mdp_InnerLeft
;
860 mhd
->innerright
= msg
.mdp_InnerRight
;
861 mhd
->innertop
= msg
.mdp_InnerTop
;
862 mhd
->innerbottom
= msg
.mdp_InnerBottom
;
863 mhd
->iteminnerleft
= msg
.mdp_ItemInnerLeft
;
864 mhd
->iteminnerright
= msg
.mdp_ItemInnerRight
;
865 mhd
->iteminnertop
= msg
.mdp_ItemInnerTop
;
866 mhd
->iteminnerbottom
= msg
.mdp_ItemInnerBottom
;
867 mhd
->menubaritemwidth
+= (mhd
->iteminnerleft
+ mhd
->iteminnerright
);
868 mhd
->menubaritemheight
+= (mhd
->iteminnertop
+ mhd
->iteminnerbottom
);
870 win_tags
[2].ti_Data
= mhd
->menubaritemwidth
+ mhd
->innerleft
+ mhd
->innerright
;
871 win_tags
[3].ti_Data
= mhd
->menubaritemheight
* mhd
->nummenubaritems
+ mhd
->innertop
+ mhd
->innerbottom
;
873 if (win_tags
[2].ti_Data
< msg
.mdp_MinWidth
)
875 mhd
->menubaritemwidth
+= (msg
.mdp_MinWidth
- win_tags
[2].ti_Data
);
876 win_tags
[2].ti_Data
= msg
.mdp_MinWidth
;
879 if (win_tags
[3].ti_Data
< msg
.mdp_MinHeight
)
881 win_tags
[3].ti_Data
= msg
.mdp_MinHeight
;
884 WORD PosX
= mhd
->scr
->MouseX
- win_tags
[2].ti_Data
/ 2;
885 win_tags
[1].ti_Data
= mhd
->scr
->MouseY
;
888 if ((PosX
+ win_tags
[2].ti_Data
) > mhd
->scr
->Width
) PosX
= mhd
->scr
->Width
- win_tags
[2].ti_Data
;
889 if ((win_tags
[1].ti_Data
+ win_tags
[3].ti_Data
) > mhd
->scr
->Height
) win_tags
[1].ti_Data
= mhd
->scr
->Height
- win_tags
[3].ti_Data
;
890 if (PosX
< 0) PosX
= 0;
891 if (win_tags
[1].ti_Data
> 32000) win_tags
[1].ti_Data
= 0;
893 win_tags
[0].ti_Data
= PosX
;
895 FreeRastPort(temprp
);
899 GetAttr(MDA_UserBuffer
, ((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, &userbuffersize
);
903 mhd
->DecorUserBufferSize
= userbuffersize
;
904 mhd
->BarDecorUserBuffer
= (IPTR
) AllocMem(userbuffersize
, MEMF_ANY
| MEMF_CLEAR
);
905 if (NULL
== mhd
->BarDecorUserBuffer
) return;
909 struct mdpInitMenu msg
;
911 msg
.MethodID
= MDM_INITMENU
;
912 msg
.mdp_TrueColor
= mhd
->TrueColor
;
913 msg
.mdp_RPort
= &mhd
->scr
->RastPort
;
914 msg
.mdp_Left
= win_tags
[0].ti_Data
;
915 msg
.mdp_Top
= win_tags
[1].ti_Data
;
916 msg
.mdp_Width
= win_tags
[2].ti_Data
;
917 msg
.mdp_Height
= win_tags
[3].ti_Data
;
918 msg
.mdp_UserBuffer
= mhd
->BarDecorUserBuffer
;
919 msg
.mdp_ScreenUserBuffer
= ((struct IntScreen
*) mhd
->scr
)->DecorUserBuffer
;
921 msg
.mdp_Screen
= mhd
->scr
;
923 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
927 D(bug("MakeMenuBarWin: mhd 0x%lx\n",
930 mhd
->menubarwin
= OpenWindowTagList(0, win_tags
);
932 for(menu
= mhd
->menu
; menu
; menu
= menu
->NextMenu
)
934 menu
->Flags
&= ~HIGHITEM
;
937 RenderMenuBar(mhd
, IntuitionBase
);
940 /**************************************************************************************************/
942 static void KillMenuBarWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
946 CloseWindow(mhd
->menubarwin
);
947 mhd
->menubarwin
= NULL
;
949 if (MENUS_UNDERMOUSE
)
951 struct mdpExitMenu msg
;
953 msg
.MethodID
= MDM_EXITMENU
;
954 msg
.mdp_UserBuffer
= mhd
->BarDecorUserBuffer
;
955 msg
.mdp_TrueColor
= mhd
->TrueColor
;
956 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
958 if (mhd
->BarDecorUserBuffer
)
960 FreeMem((IPTR
) mhd
->BarDecorUserBuffer
, mhd
->DecorUserBufferSize
);
962 mhd
->BarDecorUserBuffer
= NULL
;
969 /**************************************************************************************************/
971 static void RenderMenuBar(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
975 struct Menu
*menu
= mhd
->menu
;
976 struct RastPort
*rp
= mhd
->menubarwin
->RPort
;
977 struct Layer
*oldlayerhook
;
979 SetFont(rp
, mhd
->dri
->dri_Font
);
981 if (MENUS_UNDERMOUSE
)
983 RenderMenuBG(mhd
->menubarwin
, mhd
, IntuitionBase
);
989 SetABPenDrMd(rp
, mhd
->dri
->dri_Pens
[BARBLOCKPEN
], 0, JAM1
);
993 SetABPenDrMd(rp
, mhd
->dri
->dri_Pens
[BACKGROUNDPEN
], 0, JAM1
);
996 RectFill(rp
, 0, 0, mhd
->menubarwin
->Width
- 1, mhd
->menubarwin
->Height
- 2);
998 SetAPen(rp
, mhd
->dri
->dri_Pens
[BARTRIMPEN
]);
999 RectFill(rp
, 0, mhd
->menubarwin
->Height
- 1, mhd
->menubarwin
->Width
- 1, mhd
->menubarwin
->Height
- 1);
1001 if (!MENUS_AMIGALOOK
)
1003 SetAPen(rp
, mhd
->dri
->dri_Pens
[SHINEPEN
]);
1004 RectFill(rp
, 0, 0, 0, mhd
->menubarwin
->Height
- 2);
1005 RectFill(rp
, 1, 0, mhd
->menubarwin
->Width
- 1, 0);
1006 SetAPen(rp
, mhd
->dri
->dri_Pens
[SHADOWPEN
]);
1007 RectFill(rp
, mhd
->menubarwin
->Width
- 1, 1, mhd
->menubarwin
->Width
- 1, mhd
->menubarwin
->Height
- 2);
1011 for(; menu
; menu
= menu
->NextMenu
)
1013 RenderMenuTitle(menu
, mhd
, IntuitionBase
);
1018 /**************************************************************************************************/
1020 static void RenderMenuTitle(struct Menu
*menu
, struct MenuHandlerData
*mhd
,
1021 struct IntuitionBase
*IntuitionBase
)
1023 struct RastPort
*rp
= mhd
->menubarwin
->RPort
;
1024 WORD len
= strlen(menu
->MenuName
);
1029 if (MENUS_UNDERMOUSE
)
1035 for(m
= mhd
->menu
; m
&& (m
!= menu
);m
= m
->NextMenu
)
1040 x
= mhd
->innerleft
+ ITEXT_EXTRA_LEFT
;
1041 y
= mhd
->innertop
+ ITEXT_EXTRA_TOP
+ yoff
* mhd
->menubaritemheight
;
1045 x
= mhd
->scr
->BarHBorder
+ menu
->LeftEdge
;
1046 y
= mhd
->scr
->BarVBorder
;
1049 if (MENUS_AMIGALOOK
)
1051 SetAPen(rp
, mhd
->dri
->dri_Pens
[BARDETAILPEN
]);
1055 SetAPen(rp
, mhd
->dri
->dri_Pens
[(menu
->Flags
& HIGHITEM
) ? FILLTEXTPEN
: TEXTPEN
]);
1058 Move(rp
, x
, y
+ rp
->TxBaseline
);
1059 Text(rp
, menu
->MenuName
, len
);
1061 if (MENUS_UNDERMOUSE
)
1063 if (menu
->FirstItem
)
1065 WORD state
= ((menu
->Flags
& HIGHITEM
) && ((menu
->Flags
& HIGHFLAGS
) == HIGHCOMP
)) ? IDS_SELECTED
: IDS_NORMAL
;
1066 WORD x2
= mhd
->scr
->MenuHBorder
+ mhd
->menubaritemwidth
- ITEXT_EXTRA_RIGHT
- mhd
->submenuimage
->Width
;
1068 DrawImageState(rp
, mhd
->submenuimage
, x2
, y
+ ((mhd
->menubaritemheight
- mhd
->submenuimage
->Height
) >> 1), IDS_NORMAL
, mhd
->dri
);
1072 if (!(menu
->Flags
& MENUENABLED
))
1074 WORD y2
= y
+ rp
->TxHeight
- 1;
1077 if (MENUS_UNDERMOUSE
)
1079 x2
= mhd
->scr
->MenuHBorder
+ mhd
->menubaritemwidth
- 1;
1083 x2
= x
+ TextLength(rp
, menu
->MenuName
, len
) - 1;
1086 RenderDisabledPattern(rp
, x
, y
, x2
, y2
, mhd
, IntuitionBase
);
1090 /**************************************************************************************************/
1092 static void MakeMenuWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1094 struct MenuItem
*item
;
1096 WORD width
= mhd
->activemenu
->BeatX
- mhd
->activemenu
->JazzX
+ 1;
1097 WORD height
= mhd
->activemenu
->BeatY
- mhd
->activemenu
->JazzY
+ 1;
1100 struct mdpGetMenuSpaces msg
;
1102 msg
.MethodID
= MDM_GETMENUSPACES
;
1103 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1104 msg
.mdp_InnerLeft
= 0;
1105 msg
.mdp_InnerTop
= 0;
1106 msg
.mdp_InnerRight
= 0;
1107 msg
.mdp_InnerBottom
= 0;
1108 msg
.mdp_ItemInnerLeft
= 0;
1109 msg
.mdp_ItemInnerTop
= 0;
1110 msg
.mdp_ItemInnerRight
= 0;
1111 msg
.mdp_ItemInnerBottom
= 0;
1112 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
1113 mhd
->menuinnerleft
= msg
.mdp_InnerLeft
;
1114 mhd
->menuinnerright
= msg
.mdp_InnerRight
;
1115 mhd
->menuinnertop
= msg
.mdp_InnerTop
;
1116 mhd
->menuinnerbottom
= msg
.mdp_InnerBottom
;
1118 width
+= (mhd
->menuinnerleft
+ mhd
->menuinnerright
);
1119 height
+= (mhd
->menuinnertop
+ mhd
->menuinnerbottom
);
1121 if (MENUS_UNDERMOUSE
)
1123 xpos
= mhd
->menubarwin
->LeftEdge
+ mhd
->menubarwin
->Width
- 16;
1124 ypos
= mhd
->menubarwin
->TopEdge
;
1128 xpos
= mhd
->activemenu
->LeftEdge
+ mhd
->scr
->BarHBorder
+ mhd
->activemenu
->JazzX
;
1130 if (MENUS_AMIGALOOK
)
1132 ypos
= mhd
->scr
->BarHeight
+ 1 + mhd
->activemenu
->JazzY
;
1136 ypos
= mhd
->scr
->BarHeight
+ 1;
1141 struct TagItem win_tags
[] =
1145 {WA_Width
, width
},
1146 {WA_Height
, height
},
1147 {WA_AutoAdjust
, TRUE
},
1148 {WA_Borderless
, TRUE
},
1149 {WA_CustomScreen
, (ULONG
)mhd
->scr
},
1150 {WA_BackFill
, (IPTR
)LAYERS_NOBACKFILL
},
1154 if (MENUS_UNDERMOUSE
)
1156 win_tags
[1].ti_Data
+= (mhd
->menubaritemheight
* mhd
->activemenunum
+ mhd
->scr
->MenuVBorder
) -
1158 if (xpos
+ width
> mhd
->scr
->Width
)
1160 win_tags
[0].ti_Data
= mhd
->menubarwin
->LeftEdge
- width
+ 16;
1164 if ((win_tags
[0].ti_Data
+ win_tags
[2].ti_Data
) > mhd
->scr
->Width
) win_tags
[0].ti_Data
= mhd
->scr
->Width
- win_tags
[2].ti_Data
;
1165 if ((win_tags
[1].ti_Data
+ win_tags
[3].ti_Data
) > mhd
->scr
->Height
) win_tags
[1].ti_Data
= mhd
->scr
->Height
- win_tags
[3].ti_Data
;
1166 if (((LONG
) win_tags
[0].ti_Data
) < 0) win_tags
[0].ti_Data
= 0;
1167 if (((LONG
) win_tags
[1].ti_Data
) < 0) win_tags
[1].ti_Data
= 0;
1169 if ((item
= mhd
->activemenu
->FirstItem
))
1174 item
->Flags
&= ~HIGHITEM
;
1175 item
= item
->NextItem
;
1178 IPTR userbuffersize
;
1180 GetAttr(MDA_UserBuffer
, ((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, &userbuffersize
);
1184 mhd
->DecorUserBufferSize
= userbuffersize
;
1185 mhd
->DecorUserBuffer
= (IPTR
) AllocMem(userbuffersize
, MEMF_ANY
| MEMF_CLEAR
);
1186 if (NULL
== mhd
->DecorUserBuffer
) return;
1189 struct mdpInitMenu msg
;
1191 msg
.MethodID
= MDM_INITMENU
;
1192 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1193 msg
.mdp_RPort
= &mhd
->scr
->RastPort
;
1194 msg
.mdp_Left
= win_tags
[0].ti_Data
;
1195 msg
.mdp_Top
= win_tags
[1].ti_Data
;
1196 msg
.mdp_Width
= width
;
1197 msg
.mdp_Height
= height
;
1198 msg
.mdp_UserBuffer
= mhd
->DecorUserBuffer
;
1199 msg
.mdp_ScreenUserBuffer
= ((struct IntScreen
*) mhd
->scr
)->DecorUserBuffer
;
1201 msg
.mdp_Screen
= mhd
->scr
;
1203 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
1205 mhd
->menuwin
= OpenWindowTagList(0, win_tags
);
1207 mhd
->maxcommkeywidth_menu
= CalcMaxCommKeyWidth(mhd
->menuwin
, mhd
, IntuitionBase
);
1209 RenderMenu(mhd
, IntuitionBase
);
1211 mhd
->activemenu
->Flags
|= MIDRAWN
;
1216 /**************************************************************************************************/
1218 static void KillMenuWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1222 struct MenuItem
*item
;
1224 CloseWindow(mhd
->menuwin
);
1225 mhd
->menuwin
= NULL
;
1227 TimeDelay(UNIT_VBLANK
,0,20000);
1229 for(item
= mhd
->activemenu
->FirstItem
; item
; item
= item
->NextItem
)
1231 item
->Flags
&= ~ISDRAWN
;
1233 struct mdpExitMenu msg
;
1235 msg
.MethodID
= MDM_EXITMENU
;
1236 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1237 msg
.mdp_UserBuffer
= mhd
->DecorUserBuffer
;
1238 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
1240 if (mhd
->DecorUserBuffer
)
1242 FreeMem((IPTR
) mhd
->DecorUserBuffer
, mhd
->DecorUserBufferSize
);
1244 mhd
->DecorUserBuffer
= NULL
;
1246 mhd
->activemenu
->Flags
&= ~MIDRAWN
;
1248 mhd
->activeitemnum
= -1;
1249 mhd
->activeitem
= NULL
;
1253 /**************************************************************************************************/
1255 static void RenderMenu(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1260 struct MenuItem
*item
;
1262 RenderMenuBG(mhd
->menuwin
, mhd
, IntuitionBase
);
1264 SetFont(mhd
->menuwin
->RPort
, mhd
->dri
->dri_Font
);
1266 for(item
= mhd
->activemenu
->FirstItem
; item
; item
= item
->NextItem
)
1268 RenderItem(item
, ITEM_ITEM
, (struct Rectangle
*)(&mhd
->activemenu
->JazzX
), mhd
, IntuitionBase
);
1271 } /* if (mhd->menuwin) */
1274 /**************************************************************************************************/
1276 static void MakeSubMenuWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1278 struct MenuItem
*item
= mhd
->activeitem
->SubItem
;
1280 struct TagItem win_tags
[] =
1286 {WA_AutoAdjust
, TRUE
},
1287 {WA_Borderless
, TRUE
},
1288 {WA_CustomScreen
, (ULONG
)mhd
->scr
},
1289 {WA_BackFill
, (IPTR
)LAYERS_NOBACKFILL
},
1293 GetMenuBox(mhd
->menubarwin
, item
, &mhd
->submenubox
.MinX
,
1294 &mhd
->submenubox
.MinY
,
1295 &mhd
->submenubox
.MaxX
,
1296 &mhd
->submenubox
.MaxY
);
1299 struct mdpGetMenuSpaces msg
;
1301 msg
.MethodID
= MDM_GETMENUSPACES
;
1302 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1303 msg
.mdp_InnerLeft
= 0;
1304 msg
.mdp_InnerTop
= 0;
1305 msg
.mdp_InnerRight
= 0;
1306 msg
.mdp_InnerBottom
= 0;
1308 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
1309 mhd
->menuinnerleft
= msg
.mdp_InnerLeft
;
1310 mhd
->menuinnerright
= msg
.mdp_InnerRight
;
1311 mhd
->menuinnertop
= msg
.mdp_InnerTop
;
1312 mhd
->menuinnerbottom
= msg
.mdp_InnerBottom
;
1315 win_tags
[0].ti_Data
= mhd
->menuwin
->LeftEdge
+
1316 mhd
->activeitem
->LeftEdge
- mhd
->activemenu
->JazzX
+
1317 mhd
->submenubox
.MinX
;
1319 win_tags
[1].ti_Data
= mhd
->menuwin
->TopEdge
+
1320 mhd
->activeitem
->TopEdge
- mhd
->activemenu
->JazzY
+
1321 mhd
->submenubox
.MinY
;
1323 win_tags
[2].ti_Data
= mhd
->submenubox
.MaxX
- mhd
->submenubox
.MinX
+ 1 + mhd
->menuinnerleft
+ mhd
->menuinnerright
;
1324 win_tags
[3].ti_Data
= mhd
->submenubox
.MaxY
- mhd
->submenubox
.MinY
+ 1 + mhd
->menuinnertop
+ mhd
->menuinnerbottom
;
1326 if ((win_tags
[0].ti_Data
+ win_tags
[2].ti_Data
) > mhd
->scr
->Width
) win_tags
[0].ti_Data
= mhd
->scr
->Width
- win_tags
[2].ti_Data
;
1327 if ((win_tags
[1].ti_Data
+ win_tags
[3].ti_Data
) > mhd
->scr
->Height
) win_tags
[1].ti_Data
= mhd
->scr
->Height
- win_tags
[3].ti_Data
;
1328 if (((LONG
) win_tags
[0].ti_Data
) < 0) win_tags
[0].ti_Data
= 0;
1329 if (((LONG
) win_tags
[1].ti_Data
) < 0) win_tags
[1].ti_Data
= 0;
1333 item
->Flags
&= ~HIGHITEM
;
1334 item
= item
->NextItem
;
1337 IPTR userbuffersize
;
1339 GetAttr(MDA_UserBuffer
, ((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, &userbuffersize
);
1343 mhd
->DecorUserBufferSize
= userbuffersize
;
1344 mhd
->SubDecorUserBuffer
= (IPTR
) AllocMem(userbuffersize
, MEMF_ANY
| MEMF_CLEAR
);
1345 if (NULL
== mhd
->SubDecorUserBuffer
) return;
1349 struct mdpInitMenu msg
;
1350 msg
.MethodID
= MDM_INITMENU
;
1351 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1352 msg
.mdp_RPort
= &mhd
->scr
->RastPort
;
1353 msg
.mdp_Left
= win_tags
[0].ti_Data
;
1354 msg
.mdp_Top
= win_tags
[1].ti_Data
;
1355 msg
.mdp_Width
= win_tags
[2].ti_Data
;
1356 msg
.mdp_Height
= win_tags
[3].ti_Data
;
1357 msg
.mdp_UserBuffer
= mhd
->SubDecorUserBuffer
;
1358 msg
.mdp_ScreenUserBuffer
= ((struct IntScreen
*) mhd
->scr
)->DecorUserBuffer
;
1360 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1361 msg
.mdp_Screen
= mhd
->scr
;
1363 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
1365 mhd
->submenuwin
= OpenWindowTagList(0, win_tags
);
1367 mhd
->maxcommkeywidth_submenu
= CalcMaxCommKeyWidth(mhd
->submenuwin
, mhd
, IntuitionBase
);
1369 RenderSubMenu(mhd
, IntuitionBase
);
1372 /**************************************************************************************************/
1374 static void KillSubMenuWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1376 if (mhd
->submenuwin
)
1378 CloseWindow(mhd
->submenuwin
);
1380 TimeDelay(UNIT_VBLANK
,0,20000);
1381 struct mdpExitMenu msg
;
1383 msg
.MethodID
= MDM_EXITMENU
;
1384 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1385 msg
.mdp_UserBuffer
= mhd
->SubDecorUserBuffer
;
1386 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
1388 if (mhd
->SubDecorUserBuffer
)
1390 FreeMem((IPTR
) mhd
->SubDecorUserBuffer
, mhd
->DecorUserBufferSize
);
1392 mhd
->SubDecorUserBuffer
= NULL
;
1394 mhd
->submenuwin
= NULL
;
1396 mhd
->activesubitemnum
= -1;
1397 mhd
->activesubitem
= NULL
;
1401 /**************************************************************************************************/
1403 static void RenderSubMenu(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1406 if (mhd
->submenuwin
)
1408 struct MenuItem
*item
;
1410 RenderMenuBG(mhd
->submenuwin
, mhd
, IntuitionBase
);
1412 SetFont(mhd
->submenuwin
->RPort
, mhd
->dri
->dri_Font
);
1414 for(item
= mhd
->activeitem
->SubItem
; item
; item
= item
->NextItem
)
1416 RenderItem(item
, ITEM_SUBITEM
, (struct Rectangle
*)(&mhd
->submenubox
), mhd
, IntuitionBase
);
1419 } /* if (mhd->submenuwin) */
1422 /**************************************************************************************************/
1424 static void RenderItem(struct MenuItem
*item
, WORD itemtype
, struct Rectangle
*box
,
1425 struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1428 struct Window
*win
= ((itemtype
== ITEM_ITEM
) ? mhd
->menuwin
: mhd
->submenuwin
);
1429 struct RastPort
*rp
= win
->RPort
;
1430 WORD offx
= -box
->MinX
+ mhd
->menuinnerleft
;
1431 WORD offy
= -box
->MinY
+ mhd
->menuinnertop
;
1432 BOOL enabled
= ((item
->Flags
& ITEMENABLED
) &&
1433 (mhd
->activemenu
->Flags
& MENUENABLED
) &&
1434 ((itemtype
== ITEM_ITEM
) || (mhd
->activeitem
->Flags
& ITEMENABLED
)));
1435 BOOL item_supports_disable
= FALSE
;
1442 if (item
->Flags
& ITEMTEXT
)
1444 struct IntuiText
*save
= ((struct IntuiText
*) item
->ItemFill
)->NextText
;
1449 ((struct IntuiText
*) item
->ItemFill
)->NextText
= NULL
;
1452 struct IntuiText
*it
= (struct IntuiText
*)item
->ItemFill
;
1454 if (MENUS_AMIGALOOK
)
1456 PrintIText(rp
, it
, offx
+ item
->LeftEdge
, offy
+ item
->TopEdge
);
1460 it
->FrontPen
= mhd
->dri
->dri_Pens
[(item
->Flags
& HIGHITEM
) ? FILLTEXTPEN
: TEXTPEN
];
1461 it
->DrawMode
= JAM1
;
1463 PrintIText(rp
, it
, offx
+ item
->LeftEdge
, offy
+ item
->TopEdge
);
1467 DrawImageState(rp
, mhd
->submenuimage
, offx
+ item
->Width
- mhd
->submenuimage
->Width
, offy
+ item
->TopEdge
+ ((item
->Height
- mhd
->submenuimage
->Height
) >> 1), IDS_NORMAL
, mhd
->dri
);
1468 ((struct IntuiText
*) item
->ItemFill
)->NextText
= save
;
1474 struct Image
*im
= (struct Image
*)item
->ItemFill
;
1475 LONG state
= IDS_NORMAL
;
1477 if (!enabled
&& (im
->Depth
== CUSTOMIMAGEDEPTH
))
1481 GetAttr(IA_SupportsDisable
, (Object
*)im
, &val
);
1484 item_supports_disable
= TRUE
;
1485 state
= IDS_DISABLED
;
1489 DrawImageState(rp
, im
, offx
+ item
->LeftEdge
, offy
+ item
->TopEdge
, state
, mhd
->dri
);
1492 } /* if (item->ItemFill) */
1494 RenderCheckMark(item
, itemtype
, mhd
, IntuitionBase
);
1495 RenderAmigaKey(item
, itemtype
, mhd
, IntuitionBase
);
1497 if (!enabled
&& !item_supports_disable
)
1499 RenderDisabledPattern(rp
, offx
+ item
->LeftEdge
,
1500 offy
+ item
->TopEdge
,
1501 offx
+ item
->LeftEdge
+ item
->Width
- 1,
1502 offy
+ item
->TopEdge
+ item
->Height
- 1,
1509 /**************************************************************************************************/
1511 static void RenderMenuBG(struct Window
*win
, struct MenuHandlerData
*mhd
,
1512 struct IntuitionBase
*IntuitionBase
)
1514 struct RastPort
*rp
= win
->RPort
;
1515 WORD borderx
, bordery
;
1516 BOOL customdraw
= FALSE
;
1517 struct mdpDrawBackground msg
;
1519 msg
.MethodID
= MDM_DRAWBACKGROUND
;
1520 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1524 msg
.mdp_Width
= win
->Width
- 1;
1525 msg
.mdp_Height
= win
->Height
- 1;
1526 msg
.mdp_ItemLeft
= 0;
1527 msg
.mdp_ItemTop
= 0;
1528 msg
.mdp_ItemWidth
= win
->Width
- 1;
1529 msg
.mdp_ItemHeight
= win
->Height
- 1;
1531 if (win
== mhd
->submenuwin
) msg
.mdp_UserBuffer
= mhd
->SubDecorUserBuffer
;
1532 else if (win
== mhd
->menuwin
) msg
.mdp_UserBuffer
= mhd
->DecorUserBuffer
;
1533 else msg
.mdp_UserBuffer
= mhd
->BarDecorUserBuffer
;
1534 customdraw
= DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
1536 if (customdraw
) return;
1538 if (MENUS_AMIGALOOK
)
1540 borderx
= mhd
->scr
->MenuHBorder
/ 2;
1541 bordery
= mhd
->scr
->MenuVBorder
/ 2;
1549 /* White background */
1551 if (MENUS_AMIGALOOK
)
1553 SetABPenDrMd(rp
, mhd
->dri
->dri_Pens
[BARBLOCKPEN
], 0, JAM1
);
1557 SetABPenDrMd(rp
, mhd
->dri
->dri_Pens
[BACKGROUNDPEN
], 0, JAM1
);
1560 RectFill(rp
, borderx
,
1562 win
->Width
- 1 - borderx
,
1563 win
->Height
- 1 - bordery
);
1565 /* Black border frame */
1567 if (MENUS_AMIGALOOK
)
1569 SetAPen(rp
, mhd
->dri
->dri_Pens
[BARDETAILPEN
]);
1570 RectFill(rp
, 0, 0, win
->Width
- 1, bordery
- 1);
1571 RectFill(rp
, 0, bordery
, borderx
- 1, win
->Height
- 1 - bordery
);
1572 RectFill(rp
, win
->Width
- borderx
, bordery
, win
->Width
- 1, win
->Height
- 1);
1573 RectFill(rp
, 0, win
->Height
- bordery
, win
->Width
- 1 - borderx
, win
->Height
- 1);
1577 RenderFrame(rp
, 0, 0, win
->Width
- 1, win
->Height
- 1, IDS_NORMAL
, mhd
, IntuitionBase
);
1581 /**************************************************************************************************/
1583 static void RenderCheckMark(struct MenuItem
*item
, WORD itemtype
, struct MenuHandlerData
*mhd
,
1584 struct IntuitionBase
*IntuitionBase
)
1586 struct Window
*win
= ((itemtype
== ITEM_ITEM
) ? mhd
->menuwin
: mhd
->submenuwin
);
1587 struct RastPort
*rp
= win
->RPort
;
1588 struct Rectangle
*box
= ((itemtype
== ITEM_ITEM
) ? ((struct Rectangle
*)&mhd
->activemenu
->JazzX
) : &mhd
->submenubox
);
1589 WORD offx
= -box
->MinX
+ mhd
->menuinnerleft
;
1590 WORD offy
= -box
->MinY
+ mhd
->menuinnertop
;
1591 WORD state
= ((item
->Flags
& HIGHITEM
) &&
1592 ((item
->Flags
& HIGHFLAGS
) == HIGHCOMP
)) ? IDS_SELECTED
: IDS_NORMAL
;
1594 if (item
->Flags
& CHECKIT
)
1596 WORD x1
, y1
, x2
, y2
;
1598 x1
= item
->LeftEdge
+ offx
;
1599 y1
= item
->TopEdge
+ offy
+ (item
->Height
- mhd
->checkmark
->Height
) / 2;
1600 x2
= x1
+ mhd
->checkmark
->Width
- 1;
1601 y2
= y1
+ mhd
->checkmark
->Height
- 1;
1605 if (item
->Flags
& CHECKED
)
1607 DrawImageState(rp
, mhd
->checkmark
, x1
, y1
, state
, mhd
->dri
);
1611 if (MENUS_AMIGALOOK
)
1613 SetAPen(rp
, mhd
->dri
->dri_Pens
[BARBLOCKPEN
]);
1617 SetAPen(rp
, mhd
->dri
->dri_Pens
[(state
== IDS_SELECTED
) ? FILLPEN
: BACKGROUNDPEN
]);
1619 BOOL customdraw
= FALSE
;
1621 struct mdpDrawBackground msg
;
1623 msg
.MethodID
= MDM_DRAWBACKGROUND
;
1624 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1628 msg
.mdp_Width
= win
->Width
- 1;
1629 msg
.mdp_Height
= win
->Height
- 1;
1630 msg
.mdp_ItemLeft
= x1
;
1631 msg
.mdp_ItemTop
= y1
;
1632 msg
.mdp_ItemWidth
= x2
- x1
+ 1;
1633 msg
.mdp_ItemHeight
= y2
- y1
+ 1;
1634 msg
.mdp_Flags
= item
->Flags
;
1635 if (win
== mhd
->submenuwin
) msg
.mdp_UserBuffer
= mhd
->SubDecorUserBuffer
;
1636 else if (win
== mhd
->menuwin
) msg
.mdp_UserBuffer
= mhd
->DecorUserBuffer
;
1637 else msg
.mdp_UserBuffer
= mhd
->BarDecorUserBuffer
;
1639 customdraw
= DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
1641 if (!customdraw
) RectFill(rp
, x1
, y1
, x2
, y2
);
1647 /**************************************************************************************************/
1649 static void RenderAmigaKey(struct MenuItem
*item
, WORD itemtype
, struct MenuHandlerData
*mhd
,
1650 struct IntuitionBase
*IntuitionBase
)
1652 struct Window
*win
= ((itemtype
== ITEM_ITEM
) ? mhd
->menuwin
: mhd
->submenuwin
);
1653 struct RastPort
*rp
= win
->RPort
;
1654 struct Rectangle
*box
= ((itemtype
== ITEM_ITEM
) ? ((struct Rectangle
*)&mhd
->activemenu
->JazzX
) : &mhd
->submenubox
);
1655 WORD commkeywidth
= ((itemtype
== ITEM_ITEM
) ? mhd
->maxcommkeywidth_menu
: mhd
->maxcommkeywidth_submenu
);
1656 WORD offx
= -box
->MinX
+ mhd
->menuinnerleft
;
1657 WORD offy
= -box
->MinY
+ mhd
->menuinnertop
;
1658 WORD state
= ((item
->Flags
& HIGHITEM
) &&
1659 ((item
->Flags
& HIGHFLAGS
) == HIGHCOMP
)) ? IDS_SELECTED
: IDS_NORMAL
;
1661 if (item
->Flags
& COMMSEQ
)
1663 struct TextFont
*oldfont
= rp
->Font
;
1664 struct TextFont
*newfont
= NULL
;
1666 WORD x1
, y1
, x2
, y2
;
1668 if (item
->Flags
& ITEMTEXT
)
1670 struct IntuiText
*it
= (struct IntuiText
*)item
->ItemFill
;
1674 if ((newfont
= OpenFont(it
->ITextFont
)))
1676 SetFont(rp
, newfont
);
1681 x1
= item
->LeftEdge
+ offx
+ item
->Width
- AMIGAKEY_BORDER_SPACING
-
1682 mhd
->amigakey
->Width
- AMIGAKEY_KEY_SPACING
- commkeywidth
;
1683 y1
= item
->TopEdge
+ offy
+ (item
->Height
- mhd
->amigakey
->Height
+ 1) / 2;
1684 x2
= x1
+ mhd
->amigakey
->Width
- 1;
1685 y2
= y1
+ mhd
->amigakey
->Height
- 1;
1689 DrawImageState(rp
, mhd
->amigakey
, x1
, y1
, state
, mhd
->dri
);
1691 x1
+= mhd
->amigakey
->Width
+ AMIGAKEY_KEY_SPACING
;
1693 if (MENUS_AMIGALOOK
)
1695 SetAPen(rp
, mhd
->dri
->dri_Pens
[BARDETAILPEN
]);
1699 SetAPen(rp
, mhd
->dri
->dri_Pens
[(item
->Flags
& HIGHITEM
) ? FILLTEXTPEN
: TEXTPEN
]);
1702 Move(rp
, x1
, item
->TopEdge
+ offy
+ (item
->Height
- rp
->TxHeight
) / 2 +
1704 Text(rp
, &item
->Command
, 1);
1709 SetFont(rp
, oldfont
);
1712 } /* if (item->Flags & COMMSEQ) */
1715 /**************************************************************************************************/
1717 static void RenderDisabledPattern(struct RastPort
*rp
, WORD x1
, WORD y1
, WORD x2
, WORD y2
,
1718 struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1720 static UWORD pattern
[] = {0x8888, 0x2222};
1724 if (MENUS_AMIGALOOK
)
1726 SetAPen(rp
, mhd
->dri
->dri_Pens
[BARBLOCKPEN
]);
1730 SetAPen(rp
, mhd
->dri
->dri_Pens
[BACKGROUNDPEN
]);
1733 SetAfPt(rp
, pattern
, 1);
1735 RectFill(rp
, x1
, y1
, x2
, y2
);
1737 SetAfPt(rp
, NULL
, 0);
1741 /**************************************************************************************************/
1743 static void RenderFrame(struct RastPort
*rp
, WORD x1
, WORD y1
, WORD x2
, WORD y2
, WORD state
,
1744 struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1746 SetAPen(rp
, mhd
->dri
->dri_Pens
[(state
== IDS_SELECTED
) ? SHADOWPEN
: SHINEPEN
]);
1748 RectFill(rp
, x1
, y1
, x2
, y1
);
1749 RectFill(rp
, x1
, y1
+ 1, x1
, y2
);
1751 SetAPen(rp
, mhd
->dri
->dri_Pens
[(state
== IDS_SELECTED
) ? SHINEPEN
: SHADOWPEN
]);
1752 RectFill(rp
, x2
, y1
+ 1, x2
, y2
);
1753 RectFill(rp
, x1
+ 1, y2
, x2
- 1, y2
);
1755 /**************************************************************************************************/
1757 static void HighlightItem(struct MenuItem
*item
, WORD itemtype
, struct MenuHandlerData
*mhd
,
1758 struct IntuitionBase
*IntuitionBase
)
1760 struct Window
*win
= ((itemtype
== ITEM_ITEM
) ? mhd
->menuwin
: mhd
->submenuwin
);
1761 struct RastPort
*rp
= win
->RPort
;
1762 struct Rectangle
*box
= ((itemtype
== ITEM_ITEM
) ? ((struct Rectangle
*)&mhd
->activemenu
->JazzX
) : &mhd
->submenubox
);
1764 WORD offx
= -box
->MinX
+ mhd
->menuinnerleft
;
1765 WORD offy
= -box
->MinY
+ mhd
->menuinnertop
;
1766 WORD x1
, y1
, x2
, y2
;
1767 BOOL enabled
, customdraw
;
1769 enabled
= (item
->Flags
& ITEMENABLED
) ? TRUE
: FALSE
;
1770 if (!(mhd
->activemenu
->Flags
& MENUENABLED
)) enabled
= FALSE
;
1771 if ((itemtype
== ITEM_SUBITEM
) && !(mhd
->activeitem
->Flags
& ITEMENABLED
)) enabled
= FALSE
;
1775 item
->Flags
^= HIGHITEM
;
1777 fill
= item
->ItemFill
;
1778 if ((item
->Flags
& HIGHITEM
) && (item
->SelectFill
)) fill
= item
->SelectFill
;
1780 x1
= offx
+ item
->LeftEdge
;
1781 y1
= offy
+ item
->TopEdge
;
1782 x2
= x1
+ item
->Width
- 1;
1783 y2
= y1
+ item
->Height
- 1;
1785 struct mdpDrawBackground msg
;
1787 msg
.MethodID
= MDM_DRAWBACKGROUND
;
1788 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1792 msg
.mdp_Width
= win
->Width
- 1;
1793 msg
.mdp_Height
= win
->Height
- 1;
1794 msg
.mdp_ItemLeft
= x1
;
1795 msg
.mdp_ItemTop
= y1
;
1796 msg
.mdp_ItemWidth
= x2
- x1
+ 1;
1797 msg
.mdp_ItemHeight
= y2
- y1
+ 1;
1798 msg
.mdp_Flags
= item
->Flags
;
1800 if (win
== mhd
->submenuwin
) msg
.mdp_UserBuffer
= mhd
->SubDecorUserBuffer
;
1801 else if (win
== mhd
->menuwin
) msg
.mdp_UserBuffer
= mhd
->DecorUserBuffer
;
1802 else msg
.mdp_UserBuffer
= mhd
->BarDecorUserBuffer
;
1803 customdraw
= DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
1808 if(item
->Flags
& ITEMTEXT
)
1810 struct IntuiText
*save
= ((struct IntuiText
*) fill
)->NextText
;
1815 ((struct IntuiText
*) fill
)->NextText
= NULL
;
1818 if (MENUS_AMIGALOOK
)
1820 PrintIText(rp
, (struct IntuiText
*)fill
, x1
, y1
);
1824 struct IntuiText
*it
= (struct IntuiText
*)fill
;
1826 it
->FrontPen
= mhd
->dri
->dri_Pens
[TEXTPEN
];
1827 it
->DrawMode
= JAM1
;
1829 PrintIText(rp
, it
, x1
, y1
);
1833 DrawImageState(rp
, mhd
->submenuimage
, offx
+ item
->Width
- mhd
->submenuimage
->Width
, offy
+ item
->TopEdge
+ ((item
->Height
- mhd
->submenuimage
->Height
) >> 1), IDS_NORMAL
, mhd
->dri
);
1834 ((struct IntuiText
*) fill
)->NextText
= save
;
1840 EraseImage(rp
, (struct Image
*)fill
, x1
, y1
);
1841 DrawImageState(rp
, (struct Image
*)fill
, x1
, y1
, IDS_SELECTED
, mhd
->dri
);
1843 RenderItem(item
, itemtype
, box
, mhd
, IntuitionBase
);
1847 switch(item
->Flags
& HIGHFLAGS
)
1852 if(item
->Flags
& ITEMTEXT
)
1854 struct IntuiText
*save
= ((struct IntuiText
*) fill
)->NextText
;
1859 ((struct IntuiText
*) fill
)->NextText
= NULL
;
1861 if (MENUS_AMIGALOOK
)
1863 PrintIText(rp
, (struct IntuiText
*)fill
, x1
, y1
);
1867 struct IntuiText
*it
= (struct IntuiText
*)fill
;
1869 it
->FrontPen
= mhd
->dri
->dri_Pens
[TEXTPEN
];
1870 it
->DrawMode
= JAM1
;
1872 PrintIText(rp
, it
, x1
, y1
);
1876 DrawImageState(rp
, mhd
->submenuimage
, offx
+ item
->Width
- mhd
->submenuimage
->Width
, offy
+ item
->TopEdge
+ ((item
->Height
- mhd
->submenuimage
->Height
) >> 1), IDS_NORMAL
, mhd
->dri
);
1877 ((struct IntuiText
*) fill
)->NextText
= save
;
1883 EraseImage(rp
, (struct Image
*)fill
, x1
, y1
);
1884 DrawImageState(rp
, (struct Image
*)fill
, x1
, y1
, IDS_SELECTED
, mhd
->dri
);
1889 if (MENUS_AMIGALOOK
)
1891 SetDrMd(rp
, COMPLEMENT
);
1892 RectFill(rp
, x1
, y1
, x2
, y2
);
1896 WORD state
= (item
->Flags
& HIGHITEM
) ? IDS_SELECTED
: IDS_NORMAL
;
1899 SetAPen(rp
, mhd
->dri
->dri_Pens
[(state
== IDS_SELECTED
) ? FILLPEN
: BACKGROUNDPEN
]);
1900 RectFill(rp
, x1
, y1
, x2
, y2
);
1902 RenderItem(item
, itemtype
, box
, mhd
, IntuitionBase
);
1904 if (state
== IDS_SELECTED
)
1906 RenderFrame(rp
, x1
, y1
, x2
, y2
, state
, mhd
, IntuitionBase
);
1912 SetDrMd(rp
, COMPLEMENT
);
1913 offx
= mhd
->scr
->MenuHBorder
;
1914 offy
= mhd
->scr
->MenuVBorder
;
1921 RectFill(rp
, x1
, y1
, x2
, y1
+ offy
- 1);
1922 RectFill(rp
, x2
- offx
+ 1, y1
+ offy
, x2
, y2
);
1923 RectFill(rp
, x1
, y2
- offy
+ 1, x2
- offx
, y2
);
1924 RectFill(rp
, x1
, y1
+ offy
, x1
+ offx
- 1,y2
- offy
);
1931 } /* switch(item->Flags & HIGHFLAGS) */
1933 } /* if (enabled) */
1937 /**************************************************************************************************/
1939 static WORD
CalcMaxCommKeyWidth(struct Window
*win
, struct MenuHandlerData
*mhd
,
1940 struct IntuitionBase
*IntuitionBase
)
1942 struct TextExtent te
;
1945 FontExtent(mhd
->dri
->dri_Font
, &te
);
1946 maxwidth
= te
.te_Width
;
1950 struct MenuItem
*item
;
1952 if ((win
== mhd
->menuwin
))
1954 item
= mhd
->activemenu
->FirstItem
;
1958 item
= mhd
->activeitem
->SubItem
;
1961 for(; item
; item
= item
->NextItem
)
1963 if (item
->Flags
& ITEMTEXT
)
1965 struct IntuiText
*it
= (struct IntuiText
*)item
->ItemFill
;
1969 struct TextFont
*font
;
1971 if ((font
= OpenFont(it
->ITextFont
)))
1973 FontExtent(font
, &te
);
1974 if (te
.te_Width
> maxwidth
) maxwidth
= te
.te_Width
;
1980 } /* if (item->Flags & ITEMTEXT) */
1982 } /* for(; item; item = item->NextItem); */
1989 /**************************************************************************************************/
1991 static void AddToSelection(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1993 if ((mhd
->activemenunum
!= -1) && (mhd
->activemenu
->Flags
& MENUENABLED
) &&
1994 (mhd
->activeitemnum
!= -1) && (mhd
->activeitem
->Flags
& ITEMENABLED
))
1996 struct MenuItem
*item
= NULL
;
1997 UWORD men
= FULLMENUNUM(mhd
->activemenunum
, mhd
->activeitemnum
, mhd
->activesubitemnum
);
1999 if (mhd
->activesubitemnum
!= -1)
2001 if (mhd
->activesubitem
->Flags
& ITEMENABLED
) item
= mhd
->activesubitem
;
2003 else if (!mhd
->activeitem
->SubItem
)
2005 item
= mhd
->activeitem
;
2008 if (item
&& (ItemAddress(mhd
->menu
, men
) == item
))
2010 UWORD men
= FULLMENUNUM(mhd
->activemenunum
, mhd
->activeitemnum
, mhd
->activesubitemnum
);
2012 if (mhd
->firstmenupick
== MENUNULL
)
2014 mhd
->firstmenupick
= men
;
2016 else if (men
!= mhd
->lastmenupick
)
2018 struct MenuItem
*checkitem
, *prevcheckitem
= NULL
;
2019 UWORD checkmen
= mhd
->firstmenupick
;
2021 /* Remove men from pick queue, if it was already in there
2022 and then add it at the end of the pick queue */
2024 while(checkmen
!= MENUNULL
)
2026 checkitem
= ItemAddress(mhd
->menu
, checkmen
);
2028 if (checkmen
== men
)
2030 if (prevcheckitem
== NULL
)
2032 mhd
->firstmenupick
= checkitem
->NextSelect
;
2036 prevcheckitem
->NextSelect
= checkitem
->NextSelect
;
2040 checkmen
= checkitem
->NextSelect
;
2041 prevcheckitem
= checkitem
;
2043 } /* while(checkmen != MENUNULL) */
2045 checkitem
->NextSelect
= men
;
2047 } /* else if (men != mhd->lastmenupick) */
2049 mhd
->lastmenupick
= men
;
2050 item
->NextSelect
= MENUNULL
;
2054 } /* if ((mhd->activemenunum != -1) && (mhd->activeitemnum != -1)) */