2 Copyright © 1995-2012, 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
);
103 /**************************************************************************************************/
105 /***************************
106 ** DefaultMenuHandler() **
107 ***************************/
108 void DefaultMenuHandler(struct MenuTaskParams
*taskparams
)
110 struct IntuitionBase
*IntuitionBase
= taskparams
->intuitionBase
;
111 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
112 struct MenuHandlerData
*mhd
= NULL
;
114 struct MsgPort
*port
= NULL
;
115 BOOL success
= FALSE
;
117 if ((mem
= AllocMem(sizeof(struct MsgPort
) +
118 sizeof(struct MenuHandlerData
), MEMF_PUBLIC
| MEMF_CLEAR
)))
120 port
= (struct MsgPort
*)mem
;
122 port
->mp_Node
.ln_Type
= NT_MSGPORT
;
123 port
->mp_Flags
= PA_SIGNAL
;
124 port
->mp_SigBit
= AllocSignal(-1);
125 port
->mp_SigTask
= FindTask(0);
126 NEWLIST(&port
->mp_MsgList
);
128 mhd
= (struct MenuHandlerData
*)(mem
+ sizeof(struct MsgPort
));
132 } /* if ((mem = AllocMem(sizeof(struct MsgPort), MEMF_PUBLIC | MEMF_CLEAR))) */
136 taskparams
->MenuHandlerPort
= port
;
137 taskparams
->success
= TRUE
;
140 Signal(taskparams
->Caller
, SIGF_INTUITION
);
144 D(bug("DefaultMenuHandler: initialization failed. waiting for parent task to kill me.\n"));
148 D(bug("DefaultMenuHandler: initialization ok. Now waiting for messages from Intuition.\n"));
152 struct MenuMessage
*msg
;
155 while((msg
= GetMenuMessage(port
, IntuitionBase
)))
161 mhd
->scr
= mhd
->win
->WScreen
;
162 mhd
->dri
= GetScreenDrawInfo(mhd
->scr
);
163 mhd
->menu
= msg
->win
->MenuStrip
;
164 mhd
->activemenunum
= -1;
165 mhd
->activeitemnum
= -1;
166 mhd
->activesubitemnum
= -1;
167 mhd
->checkmark
= ((struct IntWindow
*)mhd
->win
)->Checkmark
;
168 mhd
->amigakey
= ((struct IntWindow
*)mhd
->win
)->AmigaKey
;
169 mhd
->submenuimage
= ((struct IntWindow
*)mhd
->win
)->SubMenuImage
;
170 mhd
->scrmousex
= mhd
->scr
->MouseX
;
171 mhd
->scrmousey
= mhd
->scr
->MouseY
;
172 mhd
->firstmenupick
= MENUNULL
;
173 mhd
->keepmenuup
= TRUE
;
174 mhd
->TrueColor
= GetBitMapAttr(mhd
->scr
->RastPort
.BitMap
, BMA_DEPTH
) > 8 ? TRUE
: FALSE
;
176 /* close windows in the back first because
178 MakeMenuBarWin(mhd
, IntuitionBase
);
179 HandleMouseMove(mhd
, IntuitionBase
);
184 /* there might come additional messages from Intuition
185 even when we have already told it to make the menus
186 inactive, but since everything is async, this cannot
187 be avoided, so check if we are really active */
191 switch(msg
->ie
.ie_Class
)
193 case IECLASS_RAWMOUSE
:
194 if (msg
->ie
.ie_Code
== IECODE_NOBUTTON
)
196 HandleMouseMove(mhd
, IntuitionBase
);
200 HandleMouseClick(&msg
->ie
, mhd
, IntuitionBase
);
205 } /* if (mhd->active) */
208 } /* switch(msg->code) */
210 ReplyMenuMessage(msg
, IntuitionBase
);
212 } /* while((msg = (struct MenuMessage *)GetMsg(port))) */
217 /**************************************************************************************************/
219 /*******************************
220 ** InitDefaultMenuHandler() **
221 *******************************/
222 BOOL
InitDefaultMenuHandler(struct IntuitionBase
*IntuitionBase
)
224 struct MenuTaskParams params
;
228 params
.intuitionBase
= IntuitionBase
;
229 params
.Caller
= FindTask(NULL
);
230 params
.success
= FALSE
;
232 SetSignal(0, SIGF_INTUITION
);
234 task
= NewCreateTask(TASKTAG_NAME
, "Intuition menu handler",
235 TASKTAG_PC
, DefaultMenuHandler
,
236 TASKTAG_ARG1
, ¶ms
,
241 Wait(SIGF_INTUITION
);
246 GetPrivIBase(IntuitionBase
)->MenuHandlerPort
= params
.MenuHandlerPort
;
253 } /* if ((task = CreateMenuHandlerTask(¶ms, IntuitionBase))) */
259 /**************************************************************************************************/
261 static void HandleMouseMove(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
263 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
265 struct Window
*win
= NULL
;
267 struct MenuItem
*item
;
268 WORD new_activemenunum
= mhd
->activemenunum
;
269 WORD new_activeitemnum
= mhd
->activeitemnum
;
270 WORD new_activesubitemnum
= mhd
->activesubitemnum
;
272 mhd
->scrmousex
= mhd
->scr
->MouseX
;
273 mhd
->scrmousey
= mhd
->scr
->MouseY
;
275 LockLayerInfo(&mhd
->scr
->LayerInfo
);
276 lay
= WhichLayer(&mhd
->scr
->LayerInfo
, mhd
->scrmousex
, mhd
->scrmousey
);
277 UnlockLayerInfo(&mhd
->scr
->LayerInfo
);
281 win
= (struct Window
*)lay
->Window
;
283 if (win
&& (win
== mhd
->submenuwin
))
285 /* Mouse over submenu box */
286 item
= FindSubItem(&new_activesubitemnum
, mhd
);
288 if (new_activesubitemnum
!= mhd
->activesubitemnum
)
290 if (mhd
->activesubitemnum
!= -1)
292 HighlightItem(mhd
->activesubitem
, ITEM_SUBITEM
, mhd
, IntuitionBase
);
295 mhd
->activesubitemnum
= new_activesubitemnum
;
296 mhd
->activesubitem
= item
;
300 HighlightItem(mhd
->activesubitem
, ITEM_SUBITEM
, mhd
, IntuitionBase
);
305 else if (win
&& (win
== mhd
->menuwin
))
307 item
= FindItem(&new_activeitemnum
, mhd
);
309 if (new_activeitemnum
!= mhd
->activeitemnum
)
311 if (mhd
->activeitemnum
!= -1)
313 HighlightItem(mhd
->activeitem
, ITEM_ITEM
, mhd
, IntuitionBase
);
314 KillSubMenuWin(mhd
, IntuitionBase
);
317 mhd
->activeitemnum
= new_activeitemnum
;
318 mhd
->activeitem
= item
;
322 HighlightItem(mhd
->activeitem
, ITEM_ITEM
, mhd
, IntuitionBase
);
326 MakeSubMenuWin(mhd
, IntuitionBase
);
330 } /* if (win && (win == mhd->menuwin)) */
331 else if (win
&& (win
== mhd
->menubarwin
))
333 /* Mouse over menu box */
335 menu
= FindMenu(&new_activemenunum
, mhd
, IntuitionBase
);
337 if (new_activemenunum
!= mhd
->activemenunum
)
340 if (mhd
->activemenunum
!= -1)
342 HighlightMenuTitle(mhd
->activemenu
, mhd
, IntuitionBase
);
343 KillMenuWin(mhd
, IntuitionBase
);
344 KillSubMenuWin(mhd
, IntuitionBase
);
347 mhd
->activemenunum
= new_activemenunum
;
348 mhd
->activemenu
= menu
;
352 HighlightMenuTitle(mhd
->activemenu
, mhd
, IntuitionBase
);
353 MakeMenuWin(mhd
, IntuitionBase
);
357 if ((mhd
->activeitemnum
!= -1) && (!mhd
->submenuwin
))
359 HighlightItem(mhd
->activeitem
, ITEM_ITEM
, mhd
, IntuitionBase
);
360 mhd
->activeitemnum
= -1;
361 mhd
->activeitem
= NULL
;
364 } /* if (win && (win == mhd->menubarwin)) */
369 } /* if ((lay = WhichLayer(&mhd->scr->LayerInfo, mhd->scrmousex, mhd->scrmousey))) */
373 /* mouse outside any menu window */
375 if ((mhd
->activeitemnum
!= -1) && (!mhd
->submenuwin
))
377 HighlightItem(mhd
->activeitem
, ITEM_ITEM
, mhd
, IntuitionBase
);
378 mhd
->activeitemnum
= -1;
379 mhd
->activeitem
= NULL
;
381 else if (mhd
->activesubitemnum
!= -1)
383 HighlightItem(mhd
->activesubitem
, ITEM_SUBITEM
, mhd
, IntuitionBase
);
384 mhd
->activesubitemnum
= -1;
385 mhd
->activesubitem
= NULL
;
391 /**************************************************************************************************/
393 static void HandleSelection(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
395 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
398 LockLayerInfo(&mhd
->scr
->LayerInfo
);
399 lay
= WhichLayer(&mhd
->scr
->LayerInfo
, mhd
->scrmousex
, mhd
->scrmousey
);
400 UnlockLayerInfo(&mhd
->scr
->LayerInfo
);
404 struct Window
*win
= (struct Window
*)lay
->Window
;
405 struct MenuItem
*item
= NULL
;
407 if (win
&& (win
== mhd
->submenuwin
) && (mhd
->activesubitemnum
!= -1))
408 item
= mhd
->activesubitem
;
409 else if (win
&& (win
== mhd
->menuwin
) && (mhd
->activeitemnum
!= -1))
410 item
= mhd
->activeitem
;
413 if (item
->Flags
& CHECKIT
)
414 HandleCheckItem(win
, item
, mhd
, IntuitionBase
);
417 AddToSelection(mhd
, IntuitionBase
);
421 /**************************************************************************************************/
423 static void HandleMouseClick(struct InputEvent
*ie
, struct MenuHandlerData
*mhd
,
424 struct IntuitionBase
*IntuitionBase
)
427 ULONG sticky
= GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_Flags
& ICF_STICKYMENUS
; /* ic_Flags is ULONG */
432 sticky
= sticky
&& (DoubleClick(
433 GetPrivIBase(IntuitionBase
)->LastMenuDownSecs
,
434 GetPrivIBase(IntuitionBase
)->LastMenuDownMicro
,
435 ie
->ie_TimeStamp
.tv_secs
, ie
->ie_TimeStamp
.tv_micro
)
443 HandleSelection(mhd
, IntuitionBase
);
445 if (ie
->ie_Code
== MENUUP
)
454 HandleSelection(mhd
, IntuitionBase
);
463 mhd
->keepmenuup
= FALSE
;
465 HandleSelection(mhd
, IntuitionBase
);
468 GetPrivIBase(IntuitionBase
)->LastMenuDownSecs
=
469 ie
->ie_TimeStamp
.tv_secs
;
470 GetPrivIBase(IntuitionBase
)->LastMenuDownMicro
=
471 ie
->ie_TimeStamp
.tv_micro
;
474 } /* switch(ie->ie_Code) */
478 KillMenuBarWin(mhd
, IntuitionBase
);
479 KillMenuWin(mhd
, IntuitionBase
);
480 KillSubMenuWin(mhd
, IntuitionBase
);
484 FreeScreenDrawInfo(mhd
->scr
, mhd
->dri
);
487 MH2Int_MakeMenusInactive(mhd
->win
, mhd
->firstmenupick
, IntuitionBase
);
492 /**************************************************************************************************/
494 static void HandleCheckItem(struct Window
*win
, struct MenuItem
*item
,
495 struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
497 /* Note: If you change something here, you probably must also change
498 menus.c/CheckMenuItemWasClicked() which is used when the
499 user uses the menu key shortcuts! */
501 WORD itemtype
= ((win
== mhd
->menuwin
) ? ITEM_ITEM
: ITEM_SUBITEM
);
503 BOOL re_render
= FALSE
;
505 if (item
->Flags
& MENUTOGGLE
)
507 item
->Flags
^= CHECKED
;
512 if (!(item
->Flags
& CHECKED
))
514 item
->Flags
|= CHECKED
;
521 BOOL toggle_hi
= FALSE
;
523 if ((item
->Flags
& HIGHITEM
) &&
524 ((item
->Flags
& HIGHFLAGS
) == HIGHCOMP
)) toggle_hi
= TRUE
;
526 if (toggle_hi
) HighlightItem(item
, itemtype
, mhd
, IntuitionBase
);
527 RenderCheckMark(item
, itemtype
, mhd
, IntuitionBase
);
528 if (toggle_hi
) HighlightItem(item
, itemtype
, mhd
, IntuitionBase
);
532 if (item
->MutualExclude
)
534 struct MenuItem
*checkitem
= (itemtype
== ITEM_ITEM
) ? mhd
->activemenu
->FirstItem
:
535 mhd
->activeitem
->SubItem
;
536 BOOL toggle_hi
= FALSE
;
539 if ((item
->Flags
& HIGHITEM
) &&
540 ((item
->Flags
& HIGHFLAGS
) == HIGHBOX
)) toggle_hi
= TRUE
;
542 if (toggle_hi
) HighlightItem(item
, itemtype
, mhd
, IntuitionBase
);
544 for(i
= 0; (i
< 32) && checkitem
; i
++, checkitem
= checkitem
->NextItem
)
546 if ((item
->MutualExclude
& (1L << i
)) &&
547 ((checkitem
->Flags
& (CHECKED
| CHECKIT
)) == (CHECKIT
| CHECKED
)))
549 checkitem
->Flags
&= ~CHECKED
;
550 RenderCheckMark(checkitem
, itemtype
, mhd
, IntuitionBase
);
554 if (toggle_hi
) HighlightItem(item
, itemtype
, mhd
, IntuitionBase
);
556 } /* if (item->MutualExclude) */
559 /**************************************************************************************************/
561 static inline BOOL
CustomDrawBackground(struct RastPort
*rp
, struct Window
*win
,
562 LONG itemleft
, LONG itemtop
, LONG itemwidth
, LONG itemheight
, UWORD flags
,
563 struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
565 struct mdpDrawBackground msg
;
567 msg
.MethodID
= MDM_DRAWBACKGROUND
;
569 msg
.mdp_TrueColor
= mhd
->TrueColor
;
572 msg
.mdp_Width
= win
->Width
- 1;
573 msg
.mdp_Height
= win
->Height
- 1;
574 msg
.mdp_ItemLeft
= itemleft
;
575 msg
.mdp_ItemTop
= itemtop
;
576 msg
.mdp_ItemWidth
= itemwidth
;
577 msg
.mdp_ItemHeight
= itemheight
;
578 msg
.mdp_Flags
= flags
;
580 msg
.mdp_MenuDecorFlags
= (MENUS_UNDERMOUSE(IntuitionBase
)) ? MDP_MDF_MENUS_UNDERMOUSE
: 0;
581 if (win
== mhd
->submenuwin
) { msg
.mdp_UserBuffer
= mhd
->SubDecorUserBuffer
; msg
.mdp_MenuDecorFlags
|= MDP_MDF_SUBITEM
; }
582 else if (win
== mhd
->menuwin
) { msg
.mdp_UserBuffer
= mhd
->DecorUserBuffer
; msg
.mdp_MenuDecorFlags
|= MDP_MDF_ITEM
; }
583 else { msg
.mdp_UserBuffer
= mhd
->BarDecorUserBuffer
; msg
.mdp_MenuDecorFlags
|= MDP_MDF_MENU
; }
585 return DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
588 /**************************************************************************************************/
590 static void HighlightMenuTitle(struct Menu
*menu
, struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
592 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
594 if ((menu
->Flags
& MENUENABLED
) && mhd
->menubarwin
)
596 struct RastPort
*rp
= mhd
->menubarwin
->RPort
;
599 if (MENUS_UNDERMOUSE(IntuitionBase
))
602 struct Menu
*m
= mhd
->menu
;
606 x2
= x1
+ mhd
->menubaritemwidth
- 1;
608 for(i
= 0; m
!= menu
; m
= m
->NextMenu
) i
++;
610 y1
= mhd
->innertop
+ i
* mhd
->menubaritemheight
;
611 y2
= y1
+ mhd
->menubaritemheight
- 1;
616 x1
= menu
->LeftEdge
+ mhd
->scr
->BarHBorder
- mhd
->scr
->MenuHBorder
;
619 x2
= x1
+ menu
->Width
- 1;
620 y2
= mhd
->scr
->BarHeight
- 1;
623 menu
->Flags
^= HIGHITEM
;
624 if (CustomDrawBackground(rp
, mhd
->win
, x1
, y1
, x2
- x1
+ 1, y2
- y1
+ 1, menu
->Flags
, mhd
, IntuitionBase
))
626 RenderMenuTitle(menu
, mhd
, IntuitionBase
);
630 if (MENUS_AMIGALOOK(IntuitionBase
))
632 SetDrMd(rp
, COMPLEMENT
);
633 RectFill(rp
, x1
, y1
, x2
, y2
);
637 if (!MENUS_UNDERMOUSE(IntuitionBase
))
641 SetAPen(rp
, mhd
->dri
->dri_Pens
[(menu
->Flags
& HIGHITEM
) ? FILLPEN
: BACKGROUNDPEN
]);
642 RectFill(rp
, x1
, y1
, x2
, y2
);
643 RenderMenuTitle(menu
, mhd
, IntuitionBase
);
645 if ((menu
->Flags
& HIGHITEM
))
647 if (MENUS_UNDERMOUSE(IntuitionBase
))
649 RenderFrame(rp
, x1
, y1
, x2
, y2
, IDS_SELECTED
, mhd
, IntuitionBase
);
653 SetAPen(rp
, mhd
->dri
->dri_Pens
[SHINEPEN
]);
654 RectFill(rp
, x1
, y1
, x1
, y2
);
655 SetAPen(rp
, mhd
->dri
->dri_Pens
[SHADOWPEN
]);
656 RectFill(rp
, x2
, y1
, x2
, y2
);
663 /**************************************************************************************************/
665 static struct Menu
*FindMenu(WORD
*var
, struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
667 struct Menu
*menu
= NULL
;
668 WORD mouse_x
, mouse_y
, i
;
672 mouse_x
= mhd
->scrmousex
- mhd
->menubarwin
->LeftEdge
;
673 mouse_y
= mhd
->scrmousey
- mhd
->menubarwin
->TopEdge
;
675 if (MENUS_UNDERMOUSE(IntuitionBase
))
679 mouse_x
-= mhd
->innerleft
;
680 mouse_y
-= mhd
->innertop
;
682 if ((mouse_x
>= 0) && (mouse_x
< mhd
->menubaritemwidth
) && (mouse_y
>= 0))
684 i
= mouse_y
/ mhd
->menubaritemheight
;
686 if ((i
>= 0) && (i
< mhd
->nummenubaritems
))
694 menu
= menu
->NextMenu
;
697 if (menu
&& (i
== 0))
706 for(menu
= mhd
->menu
, i
= 0; menu
; menu
= menu
->NextMenu
, i
++)
708 if ((mouse_x
>= menu
->LeftEdge
) &&
709 (mouse_x
< menu
->LeftEdge
+ menu
->Width
) &&
711 (mouse_y
<= mhd
->scr
->BarHeight
))
722 /**************************************************************************************************/
724 static struct MenuItem
*FindItem(WORD
*var
, struct MenuHandlerData
*mhd
)
726 struct MenuItem
*item
= NULL
;
727 WORD mouse_x
, mouse_y
, i
;
731 mouse_x
= mhd
->scrmousex
- mhd
->menuwin
->LeftEdge
732 + mhd
->activemenu
->JazzX
- mhd
->innerleft
- mhd
->menuinnerleft
;
733 mouse_y
= mhd
->scrmousey
- mhd
->menuwin
->TopEdge
734 + mhd
->activemenu
->JazzY
- mhd
->innertop
- mhd
->menuinnertop
;
736 for(item
= mhd
->activemenu
->FirstItem
, i
= 0; item
; item
= item
->NextItem
, i
++)
738 if ((mouse_x
>= item
->LeftEdge
) &&
739 (mouse_x
< item
->LeftEdge
+ item
->Width
) &&
740 (mouse_y
>= item
->TopEdge
) &&
741 (mouse_y
< item
->TopEdge
+ item
->Height
))
747 } /* if (mhd->menuwin) */
749 if ((item
== NULL
) && !mhd
->submenuwin
) *var
= -1;
754 /**************************************************************************************************/
756 static struct MenuItem
*FindSubItem(WORD
*var
, struct MenuHandlerData
*mhd
)
758 struct MenuItem
*item
= NULL
;
759 WORD mouse_x
, mouse_y
, i
;
763 mouse_x
= mhd
->scrmousex
- mhd
->submenuwin
->LeftEdge
+ mhd
->submenubox
.MinX
- mhd
->menuinnerleft
;
764 mouse_y
= mhd
->scrmousey
- mhd
->submenuwin
->TopEdge
+ mhd
->submenubox
.MinY
- mhd
->menuinnertop
;
768 for(item
= mhd
->activeitem
->SubItem
, i
= 0; item
; item
= item
->NextItem
, i
++)
770 if ((mouse_x
>= item
->LeftEdge
) &&
771 (mouse_x
< item
->LeftEdge
+ item
->Width
) &&
772 (mouse_y
>= item
->TopEdge
) &&
773 (mouse_y
< item
->TopEdge
+ item
->Height
))
780 } /* if (mhd->menuwin) */
785 /**************************************************************************************************/
787 static void MakeMenuBarWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
789 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
790 struct TagItem win_tags
[] =
794 {WA_Width
, mhd
->scr
->Width
},
795 {WA_Height
, mhd
->scr
->BarHeight
+ 1},
796 {WA_AutoAdjust
, TRUE
},
797 {WA_Borderless
, TRUE
},
798 {WA_CustomScreen
, (IPTR
)mhd
->scr
},
799 {WA_BackFill
, (IPTR
)LAYERS_NOBACKFILL
},
804 mhd
->menubarwin
= NULL
;
805 /* No entry to draw ? */
806 if(mhd
->menu
== NULL
) return;
808 if (MENUS_UNDERMOUSE(IntuitionBase
))
810 struct RastPort
*temprp
;
813 if (!(temprp
= CloneRastPort(&mhd
->scr
->RastPort
))) return;
815 mhd
->nummenubaritems
= 0;
816 for(menu
= mhd
->menu
; menu
; menu
= menu
->NextMenu
)
818 w
= TextLength(temprp
, menu
->MenuName
, strlen(menu
->MenuName
));
819 if (w
> maxw
) maxw
= w
;
820 mhd
->nummenubaritems
++;
823 mhd
->menubaritemwidth
= maxw
+ mhd
->submenuimage
->Width
+
824 TEXT_AMIGAKEY_SPACING
+
828 if (temprp
->TxHeight
> mhd
->submenuimage
->Height
)
830 mhd
->menubaritemheight
= temprp
->TxHeight
;
834 mhd
->menubaritemheight
= mhd
->submenuimage
->Height
;
837 mhd
->menubaritemheight
+= (ITEXT_EXTRA_TOP
+ ITEXT_EXTRA_BOTTOM
);
839 struct mdpGetMenuSpaces msg
;
841 msg
.MethodID
= MDM_GETMENUSPACES
;
842 msg
.mdp_TrueColor
= mhd
->TrueColor
;
843 msg
.mdp_InnerLeft
= mhd
->scr
->MenuHBorder
;
844 msg
.mdp_InnerTop
= mhd
->scr
->MenuVBorder
;
845 msg
.mdp_InnerRight
= mhd
->scr
->MenuHBorder
;
846 msg
.mdp_InnerBottom
= mhd
->scr
->MenuVBorder
;
847 msg
.mdp_ItemInnerLeft
= 0;
848 msg
.mdp_ItemInnerTop
= 0;
849 msg
.mdp_ItemInnerRight
= 0;
850 msg
.mdp_ItemInnerBottom
= 0;
851 msg
.mdp_MinWidth
= 0;
852 msg
.mdp_MinHeight
= 0;
853 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
854 mhd
->innerleft
= msg
.mdp_InnerLeft
;
855 mhd
->innerright
= msg
.mdp_InnerRight
;
856 mhd
->innertop
= msg
.mdp_InnerTop
;
857 mhd
->innerbottom
= msg
.mdp_InnerBottom
;
858 mhd
->iteminnerleft
= msg
.mdp_ItemInnerLeft
;
859 mhd
->iteminnerright
= msg
.mdp_ItemInnerRight
;
860 mhd
->iteminnertop
= msg
.mdp_ItemInnerTop
;
861 mhd
->iteminnerbottom
= msg
.mdp_ItemInnerBottom
;
862 mhd
->menubaritemwidth
+= (mhd
->iteminnerleft
+ mhd
->iteminnerright
);
863 mhd
->menubaritemheight
+= (mhd
->iteminnertop
+ mhd
->iteminnerbottom
);
865 win_tags
[2].ti_Data
= mhd
->menubaritemwidth
+ mhd
->innerleft
+ mhd
->innerright
;
866 win_tags
[3].ti_Data
= mhd
->menubaritemheight
* mhd
->nummenubaritems
+ mhd
->innertop
+ mhd
->innerbottom
;
868 if (win_tags
[2].ti_Data
< msg
.mdp_MinWidth
)
870 mhd
->menubaritemwidth
+= (msg
.mdp_MinWidth
- win_tags
[2].ti_Data
);
871 win_tags
[2].ti_Data
= msg
.mdp_MinWidth
;
874 if (win_tags
[3].ti_Data
< msg
.mdp_MinHeight
)
876 win_tags
[3].ti_Data
= msg
.mdp_MinHeight
;
879 WORD PosX
= mhd
->scr
->MouseX
- win_tags
[2].ti_Data
/ 2;
880 win_tags
[1].ti_Data
= mhd
->scr
->MouseY
;
882 if ((PosX
+ win_tags
[2].ti_Data
) > mhd
->scr
->Width
) PosX
= mhd
->scr
->Width
- win_tags
[2].ti_Data
;
883 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
;
884 if (PosX
< 0) PosX
= 0;
885 if (win_tags
[1].ti_Data
> 32000) win_tags
[1].ti_Data
= 0;
887 win_tags
[0].ti_Data
= PosX
;
889 FreeRastPort(temprp
);
894 struct mdpInitMenu msg
;
896 GetAttr(MDA_UserBuffer
, ((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, &userbuffersize
);
900 mhd
->DecorUserBufferSize
= userbuffersize
;
901 mhd
->BarDecorUserBuffer
= (IPTR
) AllocMem(userbuffersize
, MEMF_ANY
| MEMF_CLEAR
);
902 if (0 == mhd
->BarDecorUserBuffer
) return;
905 msg
.MethodID
= MDM_INITMENU
;
906 msg
.mdp_TrueColor
= mhd
->TrueColor
;
907 msg
.mdp_RPort
= &mhd
->scr
->RastPort
;
908 msg
.mdp_Left
= win_tags
[0].ti_Data
;
909 msg
.mdp_Top
= win_tags
[1].ti_Data
;
910 msg
.mdp_Width
= win_tags
[2].ti_Data
;
911 msg
.mdp_Height
= win_tags
[3].ti_Data
;
912 msg
.mdp_UserBuffer
= mhd
->BarDecorUserBuffer
;
913 msg
.mdp_ScreenUserBuffer
= ((struct IntScreen
*) mhd
->scr
)->DecorUserBuffer
;
914 msg
.mdp_MenuDecorFlags
= (MENUS_UNDERMOUSE(IntuitionBase
)) ? MDP_MDF_MENUS_UNDERMOUSE
: 0;
915 msg
.mdp_MenuDecorFlags
|= MDP_MDF_MENU
;
917 msg
.mdp_Screen
= mhd
->scr
;
919 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
923 D(bug("MakeMenuBarWin: mhd 0x%lx\n", mhd
));
925 mhd
->menubarwin
= OpenWindowTagList(0, win_tags
);
927 for(menu
= mhd
->menu
; menu
; menu
= menu
->NextMenu
)
929 menu
->Flags
&= ~HIGHITEM
;
932 RenderMenuBar(mhd
, IntuitionBase
);
935 /**************************************************************************************************/
937 static void KillMenuBarWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
941 struct mdpExitMenu msg
;
943 CloseWindow(mhd
->menubarwin
);
944 mhd
->menubarwin
= NULL
;
946 msg
.MethodID
= MDM_EXITMENU
;
947 msg
.mdp_UserBuffer
= mhd
->BarDecorUserBuffer
;
948 msg
.mdp_TrueColor
= mhd
->TrueColor
;
949 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
951 if (mhd
->BarDecorUserBuffer
)
953 FreeMem((void *)mhd
->BarDecorUserBuffer
, mhd
->DecorUserBufferSize
);
955 mhd
->BarDecorUserBuffer
= 0;
960 /**************************************************************************************************/
962 static void RenderMenuBar(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
964 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
967 struct Menu
*menu
= mhd
->menu
;
968 struct Window
*win
= mhd
->menubarwin
;
969 struct RastPort
*rp
= win
->RPort
;
971 SetFont(rp
, mhd
->dri
->dri_Font
);
973 /* Bar renders using different pens in Amiga mode than rest of menu */
974 if (MENUS_UNDERMOUSE(IntuitionBase
))
976 RenderMenuBG(win
, mhd
, IntuitionBase
);
980 if (!CustomDrawBackground(rp
, win
, 0, 0, win
->Width
- 1, win
->Height
- 1, 0, mhd
, IntuitionBase
))
982 if (MENUS_AMIGALOOK(IntuitionBase
))
984 SetABPenDrMd(rp
, mhd
->dri
->dri_Pens
[BARBLOCKPEN
], 0, JAM1
);
988 SetABPenDrMd(rp
, mhd
->dri
->dri_Pens
[BACKGROUNDPEN
], 0, JAM1
);
991 RectFill(rp
, 0, 0, win
->Width
- 1, win
->Height
- 2);
993 SetAPen(rp
, mhd
->dri
->dri_Pens
[BARTRIMPEN
]);
994 RectFill(rp
, 0, win
->Height
- 1, win
->Width
- 1, win
->Height
- 1);
996 if (!MENUS_AMIGALOOK(IntuitionBase
))
998 SetAPen(rp
, mhd
->dri
->dri_Pens
[SHINEPEN
]);
999 RectFill(rp
, 0, 0, 0, win
->Height
- 2);
1000 RectFill(rp
, 1, 0, win
->Width
- 1, 0);
1001 SetAPen(rp
, mhd
->dri
->dri_Pens
[SHADOWPEN
]);
1002 RectFill(rp
, win
->Width
- 1, 1, win
->Width
- 1, win
->Height
- 2);
1007 for(; menu
; menu
= menu
->NextMenu
)
1009 RenderMenuTitle(menu
, mhd
, IntuitionBase
);
1014 /**************************************************************************************************/
1016 static void RenderMenuTitle(struct Menu
*menu
, struct MenuHandlerData
*mhd
,
1017 struct IntuitionBase
*IntuitionBase
)
1019 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1020 struct RastPort
*rp
;
1025 len
= strlen(menu
->MenuName
);
1028 bug("Intuition: MenuEntry with missing string @ 0x%p\n", menu
);
1033 rp
= mhd
->menubarwin
->RPort
;
1036 if (MENUS_UNDERMOUSE(IntuitionBase
))
1042 for(m
= mhd
->menu
; m
&& (m
!= menu
);m
= m
->NextMenu
)
1047 x
= mhd
->innerleft
+ ITEXT_EXTRA_LEFT
;
1048 y
= mhd
->innertop
+ ITEXT_EXTRA_TOP
+ yoff
* mhd
->menubaritemheight
;
1052 x
= mhd
->scr
->BarHBorder
+ menu
->LeftEdge
;
1053 y
= mhd
->scr
->BarVBorder
+ ((mhd
->scr
->BarHeight
- rp
->Font
->tf_YSize
) / 2);
1058 if (MENUS_AMIGALOOK(IntuitionBase
))
1060 SetAPen(rp
, mhd
->dri
->dri_Pens
[BARDETAILPEN
]);
1064 SetAPen(rp
, mhd
->dri
->dri_Pens
[(menu
->Flags
& HIGHITEM
) ? FILLTEXTPEN
: TEXTPEN
]);
1067 Move(rp
, x
, y
+ rp
->TxBaseline
);
1068 Text(rp
, menu
->MenuName
, len
);
1071 if (MENUS_UNDERMOUSE(IntuitionBase
))
1073 if (menu
->FirstItem
)
1075 WORD x2
= mhd
->scr
->MenuHBorder
+ mhd
->menubaritemwidth
- ITEXT_EXTRA_RIGHT
- mhd
->submenuimage
->Width
;
1077 DrawImageState(rp
, mhd
->submenuimage
, x2
, y
+ ((mhd
->menubaritemheight
- mhd
->submenuimage
->Height
) >> 1), IDS_NORMAL
, mhd
->dri
);
1081 if (!(menu
->Flags
& MENUENABLED
))
1083 WORD y2
= y
+ rp
->TxHeight
- 1;
1086 if (MENUS_UNDERMOUSE(IntuitionBase
))
1088 x2
= mhd
->scr
->MenuHBorder
+ mhd
->menubaritemwidth
- 1;
1090 else if (menu
->MenuName
)
1092 x2
= x
+ TextLength(rp
, menu
->MenuName
, len
) - 1;
1094 x2
= x
+ TextLength(rp
, " ", 1) - 1;
1097 RenderDisabledPattern(rp
, x
, y
, x2
, y2
, mhd
, IntuitionBase
);
1102 /**************************************************************************************************/
1104 static void MakeMenuWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1106 struct MenuItem
*item
;
1108 WORD width
= mhd
->activemenu
->BeatX
- mhd
->activemenu
->JazzX
+ 1;
1109 WORD height
= mhd
->activemenu
->BeatY
- mhd
->activemenu
->JazzY
+ 1;
1112 struct mdpGetMenuSpaces msg
;
1114 msg
.MethodID
= MDM_GETMENUSPACES
;
1115 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1116 msg
.mdp_InnerLeft
= 0;
1117 msg
.mdp_InnerTop
= 0;
1118 msg
.mdp_InnerRight
= 0;
1119 msg
.mdp_InnerBottom
= 0;
1120 msg
.mdp_ItemInnerLeft
= 0;
1121 msg
.mdp_ItemInnerTop
= 0;
1122 msg
.mdp_ItemInnerRight
= 0;
1123 msg
.mdp_ItemInnerBottom
= 0;
1124 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
1125 mhd
->menuinnerleft
= msg
.mdp_InnerLeft
;
1126 mhd
->menuinnerright
= msg
.mdp_InnerRight
;
1127 mhd
->menuinnertop
= msg
.mdp_InnerTop
;
1128 mhd
->menuinnerbottom
= msg
.mdp_InnerBottom
;
1130 width
+= (mhd
->menuinnerleft
+ mhd
->menuinnerright
);
1131 height
+= (mhd
->menuinnertop
+ mhd
->menuinnerbottom
);
1133 if (MENUS_UNDERMOUSE(IntuitionBase
))
1135 xpos
= mhd
->menubarwin
->LeftEdge
+ mhd
->menubarwin
->Width
- 16;
1136 ypos
= mhd
->menubarwin
->TopEdge
;
1140 xpos
= mhd
->activemenu
->LeftEdge
+ mhd
->scr
->BarHBorder
+ mhd
->activemenu
->JazzX
;
1142 if (MENUS_AMIGALOOK(IntuitionBase
))
1144 ypos
= mhd
->scr
->BarHeight
+ 1 + mhd
->activemenu
->JazzY
;
1148 ypos
= mhd
->scr
->BarHeight
+ 1;
1153 struct TagItem win_tags
[] =
1157 {WA_Width
, width
},
1158 {WA_Height
, height
},
1159 {WA_AutoAdjust
, TRUE
},
1160 {WA_Borderless
, TRUE
},
1161 {WA_CustomScreen
, (IPTR
)mhd
->scr
},
1162 {WA_BackFill
, (IPTR
)LAYERS_NOBACKFILL
},
1166 if (MENUS_UNDERMOUSE(IntuitionBase
))
1168 win_tags
[1].ti_Data
+= (mhd
->menubaritemheight
* mhd
->activemenunum
+ mhd
->scr
->MenuVBorder
) -
1170 if (xpos
+ width
> mhd
->scr
->Width
)
1172 win_tags
[0].ti_Data
= mhd
->menubarwin
->LeftEdge
- width
+ 16;
1176 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
;
1177 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
;
1178 if (((LONG
) win_tags
[0].ti_Data
) < 0) win_tags
[0].ti_Data
= 0;
1179 if (((LONG
) win_tags
[1].ti_Data
) < 0) win_tags
[1].ti_Data
= 0;
1181 if ((item
= mhd
->activemenu
->FirstItem
))
1186 item
->Flags
&= ~HIGHITEM
;
1187 item
= item
->NextItem
;
1190 IPTR userbuffersize
;
1192 GetAttr(MDA_UserBuffer
, ((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, &userbuffersize
);
1196 mhd
->DecorUserBufferSize
= userbuffersize
;
1197 mhd
->DecorUserBuffer
= (IPTR
) AllocMem(userbuffersize
, MEMF_ANY
| MEMF_CLEAR
);
1198 if (0 == mhd
->DecorUserBuffer
) return;
1201 struct mdpInitMenu msg
;
1203 msg
.MethodID
= MDM_INITMENU
;
1204 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1205 msg
.mdp_RPort
= &mhd
->scr
->RastPort
;
1206 msg
.mdp_Left
= win_tags
[0].ti_Data
;
1207 msg
.mdp_Top
= win_tags
[1].ti_Data
;
1208 msg
.mdp_Width
= width
;
1209 msg
.mdp_Height
= height
;
1210 msg
.mdp_UserBuffer
= mhd
->DecorUserBuffer
;
1211 msg
.mdp_ScreenUserBuffer
= ((struct IntScreen
*) mhd
->scr
)->DecorUserBuffer
;
1212 msg
.mdp_Screen
= mhd
->scr
;
1213 msg
.mdp_MenuDecorFlags
= (MENUS_UNDERMOUSE(IntuitionBase
)) ? MDP_MDF_MENUS_UNDERMOUSE
: 0;
1214 msg
.mdp_MenuDecorFlags
|= MDP_MDF_ITEM
;
1216 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
1218 mhd
->menuwin
= OpenWindowTagList(0, win_tags
);
1220 mhd
->maxcommkeywidth_menu
= CalcMaxCommKeyWidth(mhd
->menuwin
, mhd
, IntuitionBase
);
1222 RenderMenu(mhd
, IntuitionBase
);
1224 mhd
->activemenu
->Flags
|= MIDRAWN
;
1229 /**************************************************************************************************/
1231 static void KillMenuWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1235 struct MenuItem
*item
;
1237 CloseWindow(mhd
->menuwin
);
1238 mhd
->menuwin
= NULL
;
1240 TimeDelay(UNIT_VBLANK
,0,20000);
1242 for(item
= mhd
->activemenu
->FirstItem
; item
; item
= item
->NextItem
)
1244 item
->Flags
&= ~ISDRAWN
;
1246 struct mdpExitMenu msg
;
1248 msg
.MethodID
= MDM_EXITMENU
;
1249 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1250 msg
.mdp_UserBuffer
= mhd
->DecorUserBuffer
;
1251 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
1253 if (mhd
->DecorUserBuffer
)
1255 FreeMem((void *)mhd
->DecorUserBuffer
, mhd
->DecorUserBufferSize
);
1257 mhd
->DecorUserBuffer
= 0;
1259 mhd
->activemenu
->Flags
&= ~MIDRAWN
;
1261 mhd
->activeitemnum
= -1;
1262 mhd
->activeitem
= NULL
;
1266 /**************************************************************************************************/
1268 static void RenderMenu(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1270 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1274 struct MenuItem
*item
;
1276 RenderMenuBG(mhd
->menuwin
, mhd
, IntuitionBase
);
1278 SetFont(mhd
->menuwin
->RPort
, mhd
->dri
->dri_Font
);
1280 for(item
= mhd
->activemenu
->FirstItem
; item
; item
= item
->NextItem
)
1282 RenderItem(item
, ITEM_ITEM
, (struct Rectangle
*)(&mhd
->activemenu
->JazzX
), mhd
, IntuitionBase
);
1285 } /* if (mhd->menuwin) */
1288 /**************************************************************************************************/
1290 static void MakeSubMenuWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1292 struct MenuItem
*item
= mhd
->activeitem
->SubItem
;
1294 struct TagItem win_tags
[] =
1300 {WA_AutoAdjust
, TRUE
},
1301 {WA_Borderless
, TRUE
},
1302 {WA_CustomScreen
, (IPTR
)mhd
->scr
},
1303 {WA_BackFill
, (IPTR
)LAYERS_NOBACKFILL
},
1309 GetMenuBox(mhd
->menubarwin
, item
, &mhd
->submenubox
.MinX
,
1310 &mhd
->submenubox
.MinY
,
1311 &mhd
->submenubox
.MaxX
,
1312 &mhd
->submenubox
.MaxY
);
1315 struct mdpGetMenuSpaces msg
;
1317 msg
.MethodID
= MDM_GETMENUSPACES
;
1318 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1319 msg
.mdp_InnerLeft
= 0;
1320 msg
.mdp_InnerTop
= 0;
1321 msg
.mdp_InnerRight
= 0;
1322 msg
.mdp_InnerBottom
= 0;
1324 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
1325 mhd
->menuinnerleft
= msg
.mdp_InnerLeft
;
1326 mhd
->menuinnerright
= msg
.mdp_InnerRight
;
1327 mhd
->menuinnertop
= msg
.mdp_InnerTop
;
1328 mhd
->menuinnerbottom
= msg
.mdp_InnerBottom
;
1331 win_tags
[0].ti_Data
= mhd
->menuwin
->LeftEdge
+
1332 mhd
->activeitem
->LeftEdge
- mhd
->activemenu
->JazzX
+
1333 mhd
->submenubox
.MinX
;
1335 win_tags
[1].ti_Data
= mhd
->menuwin
->TopEdge
+
1336 mhd
->activeitem
->TopEdge
- mhd
->activemenu
->JazzY
+
1337 mhd
->submenubox
.MinY
;
1339 win_tags
[2].ti_Data
= mhd
->submenubox
.MaxX
- mhd
->submenubox
.MinX
+ 1 + mhd
->menuinnerleft
+ mhd
->menuinnerright
;
1340 win_tags
[3].ti_Data
= mhd
->submenubox
.MaxY
- mhd
->submenubox
.MinY
+ 1 + mhd
->menuinnertop
+ mhd
->menuinnerbottom
;
1342 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
;
1343 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
;
1344 if (((LONG
) win_tags
[0].ti_Data
) < 0) win_tags
[0].ti_Data
= 0;
1345 if (((LONG
) win_tags
[1].ti_Data
) < 0) win_tags
[1].ti_Data
= 0;
1349 item
->Flags
&= ~HIGHITEM
;
1350 item
= item
->NextItem
;
1353 IPTR userbuffersize
;
1355 GetAttr(MDA_UserBuffer
, ((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, &userbuffersize
);
1359 mhd
->DecorUserBufferSize
= userbuffersize
;
1360 mhd
->SubDecorUserBuffer
= (IPTR
) AllocMem(userbuffersize
, MEMF_ANY
| MEMF_CLEAR
);
1361 if (0 == mhd
->SubDecorUserBuffer
) return;
1365 struct mdpInitMenu msg
;
1366 msg
.MethodID
= MDM_INITMENU
;
1367 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1368 msg
.mdp_RPort
= &mhd
->scr
->RastPort
;
1369 msg
.mdp_Left
= win_tags
[0].ti_Data
;
1370 msg
.mdp_Top
= win_tags
[1].ti_Data
;
1371 msg
.mdp_Width
= win_tags
[2].ti_Data
;
1372 msg
.mdp_Height
= win_tags
[3].ti_Data
;
1373 msg
.mdp_UserBuffer
= mhd
->SubDecorUserBuffer
;
1374 msg
.mdp_ScreenUserBuffer
= ((struct IntScreen
*) mhd
->scr
)->DecorUserBuffer
;
1375 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1376 msg
.mdp_Screen
= mhd
->scr
;
1377 msg
.mdp_MenuDecorFlags
= (MENUS_UNDERMOUSE(IntuitionBase
)) ? MDP_MDF_MENUS_UNDERMOUSE
: 0;
1378 msg
.mdp_MenuDecorFlags
|= MDP_MDF_SUBITEM
;
1380 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
1382 mhd
->submenuwin
= OpenWindowTagList(0, win_tags
);
1384 mhd
->maxcommkeywidth_submenu
= CalcMaxCommKeyWidth(mhd
->submenuwin
, mhd
, IntuitionBase
);
1386 RenderSubMenu(mhd
, IntuitionBase
);
1390 /**************************************************************************************************/
1392 static void KillSubMenuWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1394 if (mhd
->submenuwin
)
1396 CloseWindow(mhd
->submenuwin
);
1398 TimeDelay(UNIT_VBLANK
,0,20000);
1399 struct mdpExitMenu msg
;
1401 msg
.MethodID
= MDM_EXITMENU
;
1402 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1403 msg
.mdp_UserBuffer
= mhd
->SubDecorUserBuffer
;
1404 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
1406 if (mhd
->SubDecorUserBuffer
)
1408 FreeMem((void *)mhd
->SubDecorUserBuffer
, mhd
->DecorUserBufferSize
);
1410 mhd
->SubDecorUserBuffer
= 0;
1412 mhd
->submenuwin
= NULL
;
1414 mhd
->activesubitemnum
= -1;
1415 mhd
->activesubitem
= NULL
;
1419 /**************************************************************************************************/
1421 static void RenderSubMenu(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1423 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1425 if (mhd
->submenuwin
)
1427 struct MenuItem
*item
;
1429 RenderMenuBG(mhd
->submenuwin
, mhd
, IntuitionBase
);
1431 SetFont(mhd
->submenuwin
->RPort
, mhd
->dri
->dri_Font
);
1433 for(item
= mhd
->activeitem
->SubItem
; item
; item
= item
->NextItem
)
1435 RenderItem(item
, ITEM_SUBITEM
, (struct Rectangle
*)(&mhd
->submenubox
), mhd
, IntuitionBase
);
1438 } /* if (mhd->submenuwin) */
1441 /**************************************************************************************************/
1443 static void RenderItem(struct MenuItem
*item
, WORD itemtype
, struct Rectangle
*box
,
1444 struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1446 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1447 struct Window
*win
= ((itemtype
== ITEM_ITEM
) ? mhd
->menuwin
: mhd
->submenuwin
);
1448 struct RastPort
*rp
= win
->RPort
;
1449 WORD offx
= -box
->MinX
+ mhd
->menuinnerleft
;
1450 WORD offy
= -box
->MinY
+ mhd
->menuinnertop
;
1451 BOOL enabled
= ((item
->Flags
& ITEMENABLED
) &&
1452 (mhd
->activemenu
->Flags
& MENUENABLED
) &&
1453 ((itemtype
== ITEM_ITEM
) || (mhd
->activeitem
->Flags
& ITEMENABLED
)));
1454 BOOL item_supports_disable
= FALSE
;
1461 if (item
->Flags
& ITEMTEXT
)
1463 struct IntuiText
*save
= ((struct IntuiText
*) item
->ItemFill
)->NextText
;
1468 ((struct IntuiText
*) item
->ItemFill
)->NextText
= NULL
;
1471 struct IntuiText
*it
= (struct IntuiText
*)item
->ItemFill
;
1473 if (MENUS_AMIGALOOK(IntuitionBase
))
1475 PrintIText(rp
, it
, offx
+ item
->LeftEdge
, offy
+ item
->TopEdge
);
1479 it
->FrontPen
= mhd
->dri
->dri_Pens
[(item
->Flags
& HIGHITEM
) ? FILLTEXTPEN
: TEXTPEN
];
1480 it
->DrawMode
= JAM1
;
1482 PrintIText(rp
, it
, offx
+ item
->LeftEdge
, offy
+ item
->TopEdge
);
1486 DrawImageState(rp
, mhd
->submenuimage
, offx
+ item
->Width
- mhd
->submenuimage
->Width
, offy
+ item
->TopEdge
+ ((item
->Height
- mhd
->submenuimage
->Height
) >> 1), IDS_NORMAL
, mhd
->dri
);
1487 ((struct IntuiText
*) item
->ItemFill
)->NextText
= save
;
1493 struct Image
*im
= (struct Image
*)item
->ItemFill
;
1494 LONG state
= IDS_NORMAL
;
1496 if (!enabled
&& (im
->Depth
== CUSTOMIMAGEDEPTH
))
1500 GetAttr(IA_SupportsDisable
, (Object
*)im
, &val
);
1503 item_supports_disable
= TRUE
;
1504 state
= IDS_DISABLED
;
1508 DrawImageState(rp
, im
, offx
+ item
->LeftEdge
, offy
+ item
->TopEdge
, state
, mhd
->dri
);
1511 } /* if (item->ItemFill) */
1513 RenderCheckMark(item
, itemtype
, mhd
, IntuitionBase
);
1514 RenderAmigaKey(item
, itemtype
, mhd
, IntuitionBase
);
1516 if (!enabled
&& !item_supports_disable
)
1518 RenderDisabledPattern(rp
, offx
+ item
->LeftEdge
,
1519 offy
+ item
->TopEdge
,
1520 offx
+ item
->LeftEdge
+ item
->Width
- 1,
1521 offy
+ item
->TopEdge
+ item
->Height
- 1,
1528 /**************************************************************************************************/
1530 static void RenderMenuBG(struct Window
*win
, struct MenuHandlerData
*mhd
,
1531 struct IntuitionBase
*IntuitionBase
)
1534 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1535 struct RastPort
*rp
= win
->RPort
;
1536 WORD borderx
, bordery
;
1538 if (CustomDrawBackground(rp
, win
, 0, 0, win
->Width
- 1, win
->Height
- 1, 0, mhd
, IntuitionBase
)) return;
1540 if (MENUS_AMIGALOOK(IntuitionBase
))
1542 borderx
= mhd
->scr
->MenuHBorder
/ 2;
1543 bordery
= mhd
->scr
->MenuVBorder
/ 2;
1551 /* White background */
1553 if (MENUS_AMIGALOOK(IntuitionBase
))
1555 SetABPenDrMd(rp
, mhd
->dri
->dri_Pens
[BARBLOCKPEN
], 0, JAM1
);
1559 SetABPenDrMd(rp
, mhd
->dri
->dri_Pens
[BACKGROUNDPEN
], 0, JAM1
);
1562 RectFill(rp
, borderx
,
1564 win
->Width
- 1 - borderx
,
1565 win
->Height
- 1 - bordery
);
1567 /* Black border frame */
1569 if (MENUS_AMIGALOOK(IntuitionBase
))
1571 SetAPen(rp
, mhd
->dri
->dri_Pens
[BARDETAILPEN
]);
1572 RectFill(rp
, 0, 0, win
->Width
- 1, bordery
- 1);
1573 RectFill(rp
, 0, bordery
, borderx
- 1, win
->Height
- 1 - bordery
);
1574 RectFill(rp
, win
->Width
- borderx
, bordery
, win
->Width
- 1, win
->Height
- 1);
1575 RectFill(rp
, 0, win
->Height
- bordery
, win
->Width
- 1 - borderx
, win
->Height
- 1);
1579 RenderFrame(rp
, 0, 0, win
->Width
- 1, win
->Height
- 1, IDS_NORMAL
, mhd
, IntuitionBase
);
1583 /**************************************************************************************************/
1585 static void RenderCheckMark(struct MenuItem
*item
, WORD itemtype
, struct MenuHandlerData
*mhd
,
1586 struct IntuitionBase
*IntuitionBase
)
1588 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1589 struct Window
*win
= ((itemtype
== ITEM_ITEM
) ? mhd
->menuwin
: mhd
->submenuwin
);
1590 struct RastPort
*rp
= win
->RPort
;
1591 struct Rectangle
*box
= ((itemtype
== ITEM_ITEM
) ? ((struct Rectangle
*)&mhd
->activemenu
->JazzX
) : &mhd
->submenubox
);
1592 WORD offx
= -box
->MinX
+ mhd
->menuinnerleft
;
1593 WORD offy
= -box
->MinY
+ mhd
->menuinnertop
;
1594 WORD state
= ((item
->Flags
& HIGHITEM
) &&
1595 ((item
->Flags
& HIGHFLAGS
) == HIGHCOMP
)) ? IDS_SELECTED
: IDS_NORMAL
;
1597 if (item
->Flags
& CHECKIT
)
1599 WORD x1
, y1
, x2
, y2
;
1601 x1
= item
->LeftEdge
+ offx
;
1602 y1
= item
->TopEdge
+ offy
+ (item
->Height
- mhd
->checkmark
->Height
) / 2;
1603 x2
= x1
+ mhd
->checkmark
->Width
- 1;
1604 y2
= y1
+ mhd
->checkmark
->Height
- 1;
1608 if (item
->Flags
& CHECKED
)
1610 DrawImageState(rp
, mhd
->checkmark
, x1
, y1
, state
, mhd
->dri
);
1614 if (MENUS_AMIGALOOK(IntuitionBase
))
1616 SetAPen(rp
, mhd
->dri
->dri_Pens
[BARBLOCKPEN
]);
1620 SetAPen(rp
, mhd
->dri
->dri_Pens
[(state
== IDS_SELECTED
) ? FILLPEN
: BACKGROUNDPEN
]);
1623 if (!CustomDrawBackground(rp
, win
, x1
, y1
, x2
- x1
+ 1, y2
- y1
+ 1, item
->Flags
, mhd
, IntuitionBase
)) RectFill(rp
, x1
, y1
, x2
, y2
);
1629 /**************************************************************************************************/
1631 static void RenderAmigaKey(struct MenuItem
*item
, WORD itemtype
, struct MenuHandlerData
*mhd
,
1632 struct IntuitionBase
*IntuitionBase
)
1634 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1635 struct Window
*win
= ((itemtype
== ITEM_ITEM
) ? mhd
->menuwin
: mhd
->submenuwin
);
1636 struct RastPort
*rp
= win
->RPort
;
1637 struct Rectangle
*box
= ((itemtype
== ITEM_ITEM
) ? ((struct Rectangle
*)&mhd
->activemenu
->JazzX
) : &mhd
->submenubox
);
1638 WORD commkeywidth
= ((itemtype
== ITEM_ITEM
) ? mhd
->maxcommkeywidth_menu
: mhd
->maxcommkeywidth_submenu
);
1639 WORD offx
= -box
->MinX
+ mhd
->menuinnerleft
;
1640 WORD offy
= -box
->MinY
+ mhd
->menuinnertop
;
1641 WORD state
= ((item
->Flags
& HIGHITEM
) &&
1642 ((item
->Flags
& HIGHFLAGS
) == HIGHCOMP
)) ? IDS_SELECTED
: IDS_NORMAL
;
1644 if (item
->Flags
& COMMSEQ
)
1646 struct TextFont
*oldfont
= rp
->Font
;
1647 struct TextFont
*newfont
= NULL
;
1651 if (item
->Flags
& ITEMTEXT
)
1653 struct IntuiText
*it
= (struct IntuiText
*)item
->ItemFill
;
1657 if ((newfont
= OpenFont(it
->ITextFont
)))
1659 SetFont(rp
, newfont
);
1664 x1
= item
->LeftEdge
+ offx
+ item
->Width
- AMIGAKEY_BORDER_SPACING
-
1665 mhd
->amigakey
->Width
- AMIGAKEY_KEY_SPACING
- commkeywidth
;
1666 y1
= item
->TopEdge
+ offy
+ (item
->Height
- mhd
->amigakey
->Height
+ 1) / 2;
1670 DrawImageState(rp
, mhd
->amigakey
, x1
, y1
, state
, mhd
->dri
);
1672 x1
+= mhd
->amigakey
->Width
+ AMIGAKEY_KEY_SPACING
;
1674 if (MENUS_AMIGALOOK(IntuitionBase
))
1676 SetAPen(rp
, mhd
->dri
->dri_Pens
[BARDETAILPEN
]);
1680 SetAPen(rp
, mhd
->dri
->dri_Pens
[(item
->Flags
& HIGHITEM
) ? FILLTEXTPEN
: TEXTPEN
]);
1683 Move(rp
, x1
, item
->TopEdge
+ offy
+ (item
->Height
- rp
->TxHeight
) / 2 +
1685 Text(rp
, &item
->Command
, 1);
1690 SetFont(rp
, oldfont
);
1693 } /* if (item->Flags & COMMSEQ) */
1696 /**************************************************************************************************/
1698 static void RenderDisabledPattern(struct RastPort
*rp
, WORD x1
, WORD y1
, WORD x2
, WORD y2
,
1699 struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1701 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1702 static CONST UWORD pattern
[] = {0x8888, 0x2222};
1706 if (MENUS_AMIGALOOK(IntuitionBase
))
1708 SetAPen(rp
, mhd
->dri
->dri_Pens
[BARBLOCKPEN
]);
1712 SetAPen(rp
, mhd
->dri
->dri_Pens
[BACKGROUNDPEN
]);
1715 SetAfPt(rp
, pattern
, 1);
1717 RectFill(rp
, x1
, y1
, x2
, y2
);
1719 SetAfPt(rp
, NULL
, 0);
1723 /**************************************************************************************************/
1725 static void RenderFrame(struct RastPort
*rp
, WORD x1
, WORD y1
, WORD x2
, WORD y2
, WORD state
,
1726 struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1728 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1730 SetAPen(rp
, mhd
->dri
->dri_Pens
[(state
== IDS_SELECTED
) ? SHADOWPEN
: SHINEPEN
]);
1732 RectFill(rp
, x1
, y1
, x2
, y1
);
1733 RectFill(rp
, x1
, y1
+ 1, x1
, y2
);
1735 SetAPen(rp
, mhd
->dri
->dri_Pens
[(state
== IDS_SELECTED
) ? SHINEPEN
: SHADOWPEN
]);
1736 RectFill(rp
, x2
, y1
+ 1, x2
, y2
);
1737 RectFill(rp
, x1
+ 1, y2
, x2
- 1, y2
);
1739 /**************************************************************************************************/
1741 static void HighlightItem(struct MenuItem
*item
, WORD itemtype
, struct MenuHandlerData
*mhd
,
1742 struct IntuitionBase
*IntuitionBase
)
1744 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1745 struct Window
*win
= ((itemtype
== ITEM_ITEM
) ? mhd
->menuwin
: mhd
->submenuwin
);
1746 struct RastPort
*rp
= win
->RPort
;
1747 struct Rectangle
*box
= ((itemtype
== ITEM_ITEM
) ? ((struct Rectangle
*)&mhd
->activemenu
->JazzX
) : &mhd
->submenubox
);
1749 WORD offx
= -box
->MinX
+ mhd
->menuinnerleft
;
1750 WORD offy
= -box
->MinY
+ mhd
->menuinnertop
;
1751 WORD x1
, y1
, x2
, y2
;
1754 enabled
= (item
->Flags
& ITEMENABLED
) ? TRUE
: FALSE
;
1755 if (!(mhd
->activemenu
->Flags
& MENUENABLED
)) enabled
= FALSE
;
1756 if ((itemtype
== ITEM_SUBITEM
) && !(mhd
->activeitem
->Flags
& ITEMENABLED
)) enabled
= FALSE
;
1760 item
->Flags
^= HIGHITEM
;
1762 fill
= item
->ItemFill
;
1763 if ((item
->Flags
& HIGHITEM
) && (item
->SelectFill
)) fill
= item
->SelectFill
;
1765 x1
= offx
+ item
->LeftEdge
;
1766 y1
= offy
+ item
->TopEdge
;
1767 x2
= x1
+ item
->Width
- 1;
1768 y2
= y1
+ item
->Height
- 1;
1770 if (CustomDrawBackground(rp
, win
, x1
, y1
, x2
- x1
+ 1, y2
- y1
+ 1, item
->Flags
, mhd
, IntuitionBase
)) {
1773 if(item
->Flags
& ITEMTEXT
)
1775 struct IntuiText
*save
= ((struct IntuiText
*) fill
)->NextText
;
1780 ((struct IntuiText
*) fill
)->NextText
= NULL
;
1783 if (MENUS_AMIGALOOK(IntuitionBase
))
1785 PrintIText(rp
, (struct IntuiText
*)fill
, x1
, y1
);
1789 struct IntuiText
*it
= (struct IntuiText
*)fill
;
1791 it
->FrontPen
= mhd
->dri
->dri_Pens
[TEXTPEN
];
1792 it
->DrawMode
= JAM1
;
1794 PrintIText(rp
, it
, x1
, y1
);
1798 DrawImageState(rp
, mhd
->submenuimage
, offx
+ item
->Width
- mhd
->submenuimage
->Width
, offy
+ item
->TopEdge
+ ((item
->Height
- mhd
->submenuimage
->Height
) >> 1), IDS_NORMAL
, mhd
->dri
);
1799 ((struct IntuiText
*) fill
)->NextText
= save
;
1805 EraseImage(rp
, (struct Image
*)fill
, x1
, y1
);
1806 DrawImageState(rp
, (struct Image
*)fill
, x1
, y1
, IDS_SELECTED
, mhd
->dri
);
1808 RenderItem(item
, itemtype
, box
, mhd
, IntuitionBase
);
1812 switch(item
->Flags
& HIGHFLAGS
)
1817 if(item
->Flags
& ITEMTEXT
)
1819 struct IntuiText
*save
= ((struct IntuiText
*) fill
)->NextText
;
1824 ((struct IntuiText
*) fill
)->NextText
= NULL
;
1826 if (MENUS_AMIGALOOK(IntuitionBase
))
1828 PrintIText(rp
, (struct IntuiText
*)fill
, x1
, y1
);
1832 struct IntuiText
*it
= (struct IntuiText
*)fill
;
1834 it
->FrontPen
= mhd
->dri
->dri_Pens
[TEXTPEN
];
1835 it
->DrawMode
= JAM1
;
1837 PrintIText(rp
, it
, x1
, y1
);
1841 DrawImageState(rp
, mhd
->submenuimage
, offx
+ item
->Width
- mhd
->submenuimage
->Width
, offy
+ item
->TopEdge
+ ((item
->Height
- mhd
->submenuimage
->Height
) >> 1), IDS_NORMAL
, mhd
->dri
);
1842 ((struct IntuiText
*) fill
)->NextText
= save
;
1848 EraseImage(rp
, (struct Image
*)fill
, x1
, y1
);
1849 DrawImageState(rp
, (struct Image
*)fill
, x1
, y1
, IDS_SELECTED
, mhd
->dri
);
1854 if (MENUS_AMIGALOOK(IntuitionBase
))
1856 SetDrMd(rp
, COMPLEMENT
);
1857 RectFill(rp
, x1
, y1
, x2
, y2
);
1861 WORD state
= (item
->Flags
& HIGHITEM
) ? IDS_SELECTED
: IDS_NORMAL
;
1864 SetAPen(rp
, mhd
->dri
->dri_Pens
[(state
== IDS_SELECTED
) ? FILLPEN
: BACKGROUNDPEN
]);
1865 RectFill(rp
, x1
, y1
, x2
, y2
);
1867 RenderItem(item
, itemtype
, box
, mhd
, IntuitionBase
);
1869 if (state
== IDS_SELECTED
)
1871 RenderFrame(rp
, x1
, y1
, x2
, y2
, state
, mhd
, IntuitionBase
);
1877 SetDrMd(rp
, COMPLEMENT
);
1878 offx
= mhd
->scr
->MenuHBorder
;
1879 offy
= mhd
->scr
->MenuVBorder
;
1886 RectFill(rp
, x1
, y1
, x2
, y1
+ offy
- 1);
1887 RectFill(rp
, x2
- offx
+ 1, y1
+ offy
, x2
, y2
);
1888 RectFill(rp
, x1
, y2
- offy
+ 1, x2
- offx
, y2
);
1889 RectFill(rp
, x1
, y1
+ offy
, x1
+ offx
- 1,y2
- offy
);
1896 } /* switch(item->Flags & HIGHFLAGS) */
1898 } /* if (enabled) */
1902 /**************************************************************************************************/
1904 static WORD
CalcMaxCommKeyWidth(struct Window
*win
, struct MenuHandlerData
*mhd
,
1905 struct IntuitionBase
*IntuitionBase
)
1907 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1908 struct TextExtent te
;
1911 FontExtent(mhd
->dri
->dri_Font
, &te
);
1912 maxwidth
= te
.te_Width
;
1916 struct MenuItem
*item
;
1918 if ((win
== mhd
->menuwin
))
1920 item
= mhd
->activemenu
->FirstItem
;
1924 item
= mhd
->activeitem
->SubItem
;
1927 for(; item
; item
= item
->NextItem
)
1929 if (item
->Flags
& ITEMTEXT
)
1931 struct IntuiText
*it
= (struct IntuiText
*)item
->ItemFill
;
1935 struct TextFont
*font
;
1937 if ((font
= OpenFont(it
->ITextFont
)))
1939 FontExtent(font
, &te
);
1940 if (te
.te_Width
> maxwidth
) maxwidth
= te
.te_Width
;
1946 } /* if (item->Flags & ITEMTEXT) */
1948 } /* for(; item; item = item->NextItem); */
1955 /**************************************************************************************************/
1957 static void AddToSelection(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1959 if ((mhd
->activemenunum
!= -1) && (mhd
->activemenu
->Flags
& MENUENABLED
) &&
1960 (mhd
->activeitemnum
!= -1) && (mhd
->activeitem
->Flags
& ITEMENABLED
))
1962 struct MenuItem
*item
= NULL
;
1963 UWORD men
= FULLMENUNUM(mhd
->activemenunum
, mhd
->activeitemnum
, mhd
->activesubitemnum
);
1965 if (mhd
->activesubitemnum
!= -1)
1967 if (mhd
->activesubitem
->Flags
& ITEMENABLED
) item
= mhd
->activesubitem
;
1969 else if (!mhd
->activeitem
->SubItem
)
1971 item
= mhd
->activeitem
;
1974 if (item
&& (ItemAddress(mhd
->menu
, men
) == item
))
1976 UWORD men
= FULLMENUNUM(mhd
->activemenunum
, mhd
->activeitemnum
, mhd
->activesubitemnum
);
1978 if (mhd
->firstmenupick
== MENUNULL
)
1980 mhd
->firstmenupick
= men
;
1982 else if (men
!= mhd
->lastmenupick
)
1984 struct MenuItem
*checkitem
, *prevcheckitem
= NULL
;
1985 UWORD checkmen
= mhd
->firstmenupick
;
1987 /* Remove men from pick queue, if it was already in there
1988 and then add it at the end of the pick queue */
1990 while(checkmen
!= MENUNULL
)
1992 checkitem
= ItemAddress(mhd
->menu
, checkmen
);
1994 if (checkmen
== men
)
1996 if (prevcheckitem
== NULL
)
1998 mhd
->firstmenupick
= checkitem
->NextSelect
;
2002 prevcheckitem
->NextSelect
= checkitem
->NextSelect
;
2006 checkmen
= checkitem
->NextSelect
;
2007 prevcheckitem
= checkitem
;
2009 } /* while(checkmen != MENUNULL) */
2011 checkitem
->NextSelect
= men
;
2013 } /* else if (men != mhd->lastmenupick) */
2015 mhd
->lastmenupick
= men
;
2016 item
->NextSelect
= MENUNULL
;
2020 } /* if ((mhd->activemenunum != -1) && (mhd->activeitemnum != -1)) */