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
)) y1
++;
640 SetAPen(rp
, mhd
->dri
->dri_Pens
[(menu
->Flags
& HIGHITEM
) ? FILLPEN
: BACKGROUNDPEN
]);
641 RectFill(rp
, x1
, y1
, x2
, y2
);
642 RenderMenuTitle(menu
, mhd
, IntuitionBase
);
644 if ((menu
->Flags
& HIGHITEM
))
646 if (MENUS_UNDERMOUSE(IntuitionBase
))
648 RenderFrame(rp
, x1
, y1
, x2
, y2
, IDS_SELECTED
, mhd
, IntuitionBase
);
652 SetAPen(rp
, mhd
->dri
->dri_Pens
[SHINEPEN
]);
653 RectFill(rp
, x1
, y1
, x1
, y2
);
654 SetAPen(rp
, mhd
->dri
->dri_Pens
[SHADOWPEN
]);
655 RectFill(rp
, x2
, y1
, x2
, y2
);
662 /**************************************************************************************************/
664 static struct Menu
*FindMenu(WORD
*var
, struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
666 struct Menu
*menu
= NULL
;
667 WORD mouse_x
, mouse_y
, i
;
671 mouse_x
= mhd
->scrmousex
- mhd
->menubarwin
->LeftEdge
;
672 mouse_y
= mhd
->scrmousey
- mhd
->menubarwin
->TopEdge
;
674 if (MENUS_UNDERMOUSE(IntuitionBase
))
678 mouse_x
-= mhd
->innerleft
;
679 mouse_y
-= mhd
->innertop
;
681 if ((mouse_x
>= 0) && (mouse_x
< mhd
->menubaritemwidth
) && (mouse_y
>= 0))
683 i
= mouse_y
/ mhd
->menubaritemheight
;
685 if ((i
>= 0) && (i
< mhd
->nummenubaritems
))
693 menu
= menu
->NextMenu
;
696 if (menu
&& (i
== 0))
705 for(menu
= mhd
->menu
, i
= 0; menu
; menu
= menu
->NextMenu
, i
++)
707 if ((mouse_x
>= menu
->LeftEdge
) &&
708 (mouse_x
< menu
->LeftEdge
+ menu
->Width
) &&
710 (mouse_y
<= mhd
->scr
->BarHeight
))
721 /**************************************************************************************************/
723 static struct MenuItem
*FindItem(WORD
*var
, struct MenuHandlerData
*mhd
)
725 struct MenuItem
*item
= NULL
;
726 WORD mouse_x
, mouse_y
, i
;
730 mouse_x
= mhd
->scrmousex
- mhd
->menuwin
->LeftEdge
731 + mhd
->activemenu
->JazzX
- mhd
->innerleft
- mhd
->menuinnerleft
;
732 mouse_y
= mhd
->scrmousey
- mhd
->menuwin
->TopEdge
733 + mhd
->activemenu
->JazzY
- mhd
->innertop
- mhd
->menuinnertop
;
735 for(item
= mhd
->activemenu
->FirstItem
, i
= 0; item
; item
= item
->NextItem
, i
++)
737 if ((mouse_x
>= item
->LeftEdge
) &&
738 (mouse_x
< item
->LeftEdge
+ item
->Width
) &&
739 (mouse_y
>= item
->TopEdge
) &&
740 (mouse_y
< item
->TopEdge
+ item
->Height
))
746 } /* if (mhd->menuwin) */
748 if ((item
== NULL
) && !mhd
->submenuwin
) *var
= -1;
753 /**************************************************************************************************/
755 static struct MenuItem
*FindSubItem(WORD
*var
, struct MenuHandlerData
*mhd
)
757 struct MenuItem
*item
= NULL
;
758 WORD mouse_x
, mouse_y
, i
;
762 mouse_x
= mhd
->scrmousex
- mhd
->submenuwin
->LeftEdge
+ mhd
->submenubox
.MinX
- mhd
->menuinnerleft
;
763 mouse_y
= mhd
->scrmousey
- mhd
->submenuwin
->TopEdge
+ mhd
->submenubox
.MinY
- mhd
->menuinnertop
;
767 for(item
= mhd
->activeitem
->SubItem
, i
= 0; item
; item
= item
->NextItem
, i
++)
769 if ((mouse_x
>= item
->LeftEdge
) &&
770 (mouse_x
< item
->LeftEdge
+ item
->Width
) &&
771 (mouse_y
>= item
->TopEdge
) &&
772 (mouse_y
< item
->TopEdge
+ item
->Height
))
779 } /* if (mhd->menuwin) */
784 /**************************************************************************************************/
786 static void MakeMenuBarWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
788 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
789 struct TagItem win_tags
[] =
793 {WA_Width
, mhd
->scr
->Width
},
794 {WA_Height
, mhd
->scr
->BarHeight
+ 1},
795 {WA_AutoAdjust
, TRUE
},
796 {WA_Borderless
, TRUE
},
797 {WA_CustomScreen
, (IPTR
)mhd
->scr
},
798 {WA_BackFill
, (IPTR
)LAYERS_NOBACKFILL
},
803 mhd
->menubarwin
= NULL
;
804 /* No entry to draw ? */
805 if(mhd
->menu
== NULL
) return;
807 if (MENUS_UNDERMOUSE(IntuitionBase
))
809 struct RastPort
*temprp
;
812 if (!(temprp
= CloneRastPort(&mhd
->scr
->RastPort
))) return;
814 mhd
->nummenubaritems
= 0;
815 for(menu
= mhd
->menu
; menu
; menu
= menu
->NextMenu
)
817 w
= TextLength(temprp
, menu
->MenuName
, strlen(menu
->MenuName
));
818 if (w
> maxw
) maxw
= w
;
819 mhd
->nummenubaritems
++;
822 mhd
->menubaritemwidth
= maxw
+ mhd
->submenuimage
->Width
+
823 TEXT_AMIGAKEY_SPACING
+
827 if (temprp
->TxHeight
> mhd
->submenuimage
->Height
)
829 mhd
->menubaritemheight
= temprp
->TxHeight
;
833 mhd
->menubaritemheight
= mhd
->submenuimage
->Height
;
836 mhd
->menubaritemheight
+= (ITEXT_EXTRA_TOP
+ ITEXT_EXTRA_BOTTOM
);
838 struct mdpGetMenuSpaces msg
;
840 msg
.MethodID
= MDM_GETMENUSPACES
;
841 msg
.mdp_TrueColor
= mhd
->TrueColor
;
842 msg
.mdp_InnerLeft
= mhd
->scr
->MenuHBorder
;
843 msg
.mdp_InnerTop
= mhd
->scr
->MenuVBorder
;
844 msg
.mdp_InnerRight
= mhd
->scr
->MenuHBorder
;
845 msg
.mdp_InnerBottom
= mhd
->scr
->MenuVBorder
;
846 msg
.mdp_ItemInnerLeft
= 0;
847 msg
.mdp_ItemInnerTop
= 0;
848 msg
.mdp_ItemInnerRight
= 0;
849 msg
.mdp_ItemInnerBottom
= 0;
850 msg
.mdp_MinWidth
= 0;
851 msg
.mdp_MinHeight
= 0;
852 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
853 mhd
->innerleft
= msg
.mdp_InnerLeft
;
854 mhd
->innerright
= msg
.mdp_InnerRight
;
855 mhd
->innertop
= msg
.mdp_InnerTop
;
856 mhd
->innerbottom
= msg
.mdp_InnerBottom
;
857 mhd
->iteminnerleft
= msg
.mdp_ItemInnerLeft
;
858 mhd
->iteminnerright
= msg
.mdp_ItemInnerRight
;
859 mhd
->iteminnertop
= msg
.mdp_ItemInnerTop
;
860 mhd
->iteminnerbottom
= msg
.mdp_ItemInnerBottom
;
861 mhd
->menubaritemwidth
+= (mhd
->iteminnerleft
+ mhd
->iteminnerright
);
862 mhd
->menubaritemheight
+= (mhd
->iteminnertop
+ mhd
->iteminnerbottom
);
864 win_tags
[2].ti_Data
= mhd
->menubaritemwidth
+ mhd
->innerleft
+ mhd
->innerright
;
865 win_tags
[3].ti_Data
= mhd
->menubaritemheight
* mhd
->nummenubaritems
+ mhd
->innertop
+ mhd
->innerbottom
;
867 if (win_tags
[2].ti_Data
< msg
.mdp_MinWidth
)
869 mhd
->menubaritemwidth
+= (msg
.mdp_MinWidth
- win_tags
[2].ti_Data
);
870 win_tags
[2].ti_Data
= msg
.mdp_MinWidth
;
873 if (win_tags
[3].ti_Data
< msg
.mdp_MinHeight
)
875 win_tags
[3].ti_Data
= msg
.mdp_MinHeight
;
878 WORD PosX
= mhd
->scr
->MouseX
- win_tags
[2].ti_Data
/ 2;
879 win_tags
[1].ti_Data
= mhd
->scr
->MouseY
;
881 if ((PosX
+ win_tags
[2].ti_Data
) > mhd
->scr
->Width
) PosX
= mhd
->scr
->Width
- win_tags
[2].ti_Data
;
882 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
;
883 if (PosX
< 0) PosX
= 0;
884 if (win_tags
[1].ti_Data
> 32000) win_tags
[1].ti_Data
= 0;
886 win_tags
[0].ti_Data
= PosX
;
888 FreeRastPort(temprp
);
893 struct mdpInitMenu msg
;
895 GetAttr(MDA_UserBuffer
, ((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, &userbuffersize
);
899 mhd
->DecorUserBufferSize
= userbuffersize
;
900 mhd
->BarDecorUserBuffer
= (IPTR
) AllocMem(userbuffersize
, MEMF_ANY
| MEMF_CLEAR
);
901 if (0 == mhd
->BarDecorUserBuffer
) return;
904 msg
.MethodID
= MDM_INITMENU
;
905 msg
.mdp_TrueColor
= mhd
->TrueColor
;
906 msg
.mdp_RPort
= &mhd
->scr
->RastPort
;
907 msg
.mdp_Left
= win_tags
[0].ti_Data
;
908 msg
.mdp_Top
= win_tags
[1].ti_Data
;
909 msg
.mdp_Width
= win_tags
[2].ti_Data
;
910 msg
.mdp_Height
= win_tags
[3].ti_Data
;
911 msg
.mdp_UserBuffer
= mhd
->BarDecorUserBuffer
;
912 msg
.mdp_ScreenUserBuffer
= ((struct IntScreen
*) mhd
->scr
)->DecorUserBuffer
;
913 msg
.mdp_MenuDecorFlags
= (MENUS_UNDERMOUSE(IntuitionBase
)) ? MDP_MDF_MENUS_UNDERMOUSE
: 0;
914 msg
.mdp_MenuDecorFlags
|= MDP_MDF_MENU
;
916 msg
.mdp_Screen
= mhd
->scr
;
918 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
922 D(bug("MakeMenuBarWin: mhd 0x%lx\n", mhd
));
924 mhd
->menubarwin
= OpenWindowTagList(0, win_tags
);
926 for(menu
= mhd
->menu
; menu
; menu
= menu
->NextMenu
)
928 menu
->Flags
&= ~HIGHITEM
;
931 RenderMenuBar(mhd
, IntuitionBase
);
934 /**************************************************************************************************/
936 static void KillMenuBarWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
940 struct mdpExitMenu msg
;
942 CloseWindow(mhd
->menubarwin
);
943 mhd
->menubarwin
= NULL
;
945 msg
.MethodID
= MDM_EXITMENU
;
946 msg
.mdp_UserBuffer
= mhd
->BarDecorUserBuffer
;
947 msg
.mdp_TrueColor
= mhd
->TrueColor
;
948 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
950 if (mhd
->BarDecorUserBuffer
)
952 FreeMem((void *)mhd
->BarDecorUserBuffer
, mhd
->DecorUserBufferSize
);
954 mhd
->BarDecorUserBuffer
= 0;
959 /**************************************************************************************************/
961 static void RenderMenuBar(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
963 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
966 struct Menu
*menu
= mhd
->menu
;
967 struct Window
*win
= mhd
->menubarwin
;
968 struct RastPort
*rp
= win
->RPort
;
970 SetFont(rp
, mhd
->dri
->dri_Font
);
972 /* Bar renders using different pens in Amiga mode than rest of menu */
973 if (MENUS_UNDERMOUSE(IntuitionBase
))
975 RenderMenuBG(win
, mhd
, IntuitionBase
);
979 if (!CustomDrawBackground(rp
, win
, 0, 0, win
->Width
- 1, win
->Height
- 1, 0, mhd
, IntuitionBase
))
981 if (MENUS_AMIGALOOK(IntuitionBase
))
983 SetABPenDrMd(rp
, mhd
->dri
->dri_Pens
[BARBLOCKPEN
], 0, JAM1
);
987 SetABPenDrMd(rp
, mhd
->dri
->dri_Pens
[BACKGROUNDPEN
], 0, JAM1
);
990 RectFill(rp
, 0, 0, win
->Width
- 1, win
->Height
- 2);
992 SetAPen(rp
, mhd
->dri
->dri_Pens
[BARTRIMPEN
]);
993 RectFill(rp
, 0, win
->Height
- 1, win
->Width
- 1, win
->Height
- 1);
995 if (!MENUS_AMIGALOOK(IntuitionBase
))
997 SetAPen(rp
, mhd
->dri
->dri_Pens
[SHINEPEN
]);
998 RectFill(rp
, 0, 0, 0, win
->Height
- 2);
999 RectFill(rp
, 1, 0, win
->Width
- 1, 0);
1000 SetAPen(rp
, mhd
->dri
->dri_Pens
[SHADOWPEN
]);
1001 RectFill(rp
, win
->Width
- 1, 1, win
->Width
- 1, win
->Height
- 2);
1006 for(; menu
; menu
= menu
->NextMenu
)
1008 RenderMenuTitle(menu
, mhd
, IntuitionBase
);
1013 /**************************************************************************************************/
1015 static void RenderMenuTitle(struct Menu
*menu
, struct MenuHandlerData
*mhd
,
1016 struct IntuitionBase
*IntuitionBase
)
1018 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1019 struct RastPort
*rp
;
1020 WORD len
= strlen(menu
->MenuName
);
1025 rp
= mhd
->menubarwin
->RPort
;
1028 if (MENUS_UNDERMOUSE(IntuitionBase
))
1034 for(m
= mhd
->menu
; m
&& (m
!= menu
);m
= m
->NextMenu
)
1039 x
= mhd
->innerleft
+ ITEXT_EXTRA_LEFT
;
1040 y
= mhd
->innertop
+ ITEXT_EXTRA_TOP
+ yoff
* mhd
->menubaritemheight
;
1044 x
= mhd
->scr
->BarHBorder
+ menu
->LeftEdge
;
1045 y
= mhd
->scr
->BarVBorder
+ ((mhd
->scr
->BarHeight
- rp
->Font
->tf_YSize
) / 2);
1048 if (MENUS_AMIGALOOK(IntuitionBase
))
1050 SetAPen(rp
, mhd
->dri
->dri_Pens
[BARDETAILPEN
]);
1054 SetAPen(rp
, mhd
->dri
->dri_Pens
[(menu
->Flags
& HIGHITEM
) ? FILLTEXTPEN
: TEXTPEN
]);
1057 Move(rp
, x
, y
+ rp
->TxBaseline
);
1058 Text(rp
, menu
->MenuName
, len
);
1060 if (MENUS_UNDERMOUSE(IntuitionBase
))
1062 if (menu
->FirstItem
)
1064 WORD x2
= mhd
->scr
->MenuHBorder
+ mhd
->menubaritemwidth
- ITEXT_EXTRA_RIGHT
- mhd
->submenuimage
->Width
;
1066 DrawImageState(rp
, mhd
->submenuimage
, x2
, y
+ ((mhd
->menubaritemheight
- mhd
->submenuimage
->Height
) >> 1), IDS_NORMAL
, mhd
->dri
);
1070 if (!(menu
->Flags
& MENUENABLED
))
1072 WORD y2
= y
+ rp
->TxHeight
- 1;
1075 if (MENUS_UNDERMOUSE(IntuitionBase
))
1077 x2
= mhd
->scr
->MenuHBorder
+ mhd
->menubaritemwidth
- 1;
1081 x2
= x
+ TextLength(rp
, menu
->MenuName
, len
) - 1;
1084 RenderDisabledPattern(rp
, x
, y
, x2
, y2
, mhd
, IntuitionBase
);
1089 /**************************************************************************************************/
1091 static void MakeMenuWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1093 struct MenuItem
*item
;
1095 WORD width
= mhd
->activemenu
->BeatX
- mhd
->activemenu
->JazzX
+ 1;
1096 WORD height
= mhd
->activemenu
->BeatY
- mhd
->activemenu
->JazzY
+ 1;
1099 struct mdpGetMenuSpaces msg
;
1101 msg
.MethodID
= MDM_GETMENUSPACES
;
1102 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1103 msg
.mdp_InnerLeft
= 0;
1104 msg
.mdp_InnerTop
= 0;
1105 msg
.mdp_InnerRight
= 0;
1106 msg
.mdp_InnerBottom
= 0;
1107 msg
.mdp_ItemInnerLeft
= 0;
1108 msg
.mdp_ItemInnerTop
= 0;
1109 msg
.mdp_ItemInnerRight
= 0;
1110 msg
.mdp_ItemInnerBottom
= 0;
1111 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
1112 mhd
->menuinnerleft
= msg
.mdp_InnerLeft
;
1113 mhd
->menuinnerright
= msg
.mdp_InnerRight
;
1114 mhd
->menuinnertop
= msg
.mdp_InnerTop
;
1115 mhd
->menuinnerbottom
= msg
.mdp_InnerBottom
;
1117 width
+= (mhd
->menuinnerleft
+ mhd
->menuinnerright
);
1118 height
+= (mhd
->menuinnertop
+ mhd
->menuinnerbottom
);
1120 if (MENUS_UNDERMOUSE(IntuitionBase
))
1122 xpos
= mhd
->menubarwin
->LeftEdge
+ mhd
->menubarwin
->Width
- 16;
1123 ypos
= mhd
->menubarwin
->TopEdge
;
1127 xpos
= mhd
->activemenu
->LeftEdge
+ mhd
->scr
->BarHBorder
+ mhd
->activemenu
->JazzX
;
1129 if (MENUS_AMIGALOOK(IntuitionBase
))
1131 ypos
= mhd
->scr
->BarHeight
+ 1 + mhd
->activemenu
->JazzY
;
1135 ypos
= mhd
->scr
->BarHeight
+ 1;
1140 struct TagItem win_tags
[] =
1144 {WA_Width
, width
},
1145 {WA_Height
, height
},
1146 {WA_AutoAdjust
, TRUE
},
1147 {WA_Borderless
, TRUE
},
1148 {WA_CustomScreen
, (IPTR
)mhd
->scr
},
1149 {WA_BackFill
, (IPTR
)LAYERS_NOBACKFILL
},
1153 if (MENUS_UNDERMOUSE(IntuitionBase
))
1155 win_tags
[1].ti_Data
+= (mhd
->menubaritemheight
* mhd
->activemenunum
+ mhd
->scr
->MenuVBorder
) -
1157 if (xpos
+ width
> mhd
->scr
->Width
)
1159 win_tags
[0].ti_Data
= mhd
->menubarwin
->LeftEdge
- width
+ 16;
1163 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
;
1164 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
;
1165 if (((LONG
) win_tags
[0].ti_Data
) < 0) win_tags
[0].ti_Data
= 0;
1166 if (((LONG
) win_tags
[1].ti_Data
) < 0) win_tags
[1].ti_Data
= 0;
1168 if ((item
= mhd
->activemenu
->FirstItem
))
1173 item
->Flags
&= ~HIGHITEM
;
1174 item
= item
->NextItem
;
1177 IPTR userbuffersize
;
1179 GetAttr(MDA_UserBuffer
, ((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, &userbuffersize
);
1183 mhd
->DecorUserBufferSize
= userbuffersize
;
1184 mhd
->DecorUserBuffer
= (IPTR
) AllocMem(userbuffersize
, MEMF_ANY
| MEMF_CLEAR
);
1185 if (0 == mhd
->DecorUserBuffer
) return;
1188 struct mdpInitMenu msg
;
1190 msg
.MethodID
= MDM_INITMENU
;
1191 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1192 msg
.mdp_RPort
= &mhd
->scr
->RastPort
;
1193 msg
.mdp_Left
= win_tags
[0].ti_Data
;
1194 msg
.mdp_Top
= win_tags
[1].ti_Data
;
1195 msg
.mdp_Width
= width
;
1196 msg
.mdp_Height
= height
;
1197 msg
.mdp_UserBuffer
= mhd
->DecorUserBuffer
;
1198 msg
.mdp_ScreenUserBuffer
= ((struct IntScreen
*) mhd
->scr
)->DecorUserBuffer
;
1199 msg
.mdp_Screen
= mhd
->scr
;
1200 msg
.mdp_MenuDecorFlags
= (MENUS_UNDERMOUSE(IntuitionBase
)) ? MDP_MDF_MENUS_UNDERMOUSE
: 0;
1201 msg
.mdp_MenuDecorFlags
|= MDP_MDF_ITEM
;
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((void *)mhd
->DecorUserBuffer
, mhd
->DecorUserBufferSize
);
1244 mhd
->DecorUserBuffer
= 0;
1246 mhd
->activemenu
->Flags
&= ~MIDRAWN
;
1248 mhd
->activeitemnum
= -1;
1249 mhd
->activeitem
= NULL
;
1253 /**************************************************************************************************/
1255 static void RenderMenu(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1257 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1261 struct MenuItem
*item
;
1263 RenderMenuBG(mhd
->menuwin
, mhd
, IntuitionBase
);
1265 SetFont(mhd
->menuwin
->RPort
, mhd
->dri
->dri_Font
);
1267 for(item
= mhd
->activemenu
->FirstItem
; item
; item
= item
->NextItem
)
1269 RenderItem(item
, ITEM_ITEM
, (struct Rectangle
*)(&mhd
->activemenu
->JazzX
), mhd
, IntuitionBase
);
1272 } /* if (mhd->menuwin) */
1275 /**************************************************************************************************/
1277 static void MakeSubMenuWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1279 struct MenuItem
*item
= mhd
->activeitem
->SubItem
;
1281 struct TagItem win_tags
[] =
1287 {WA_AutoAdjust
, TRUE
},
1288 {WA_Borderless
, TRUE
},
1289 {WA_CustomScreen
, (IPTR
)mhd
->scr
},
1290 {WA_BackFill
, (IPTR
)LAYERS_NOBACKFILL
},
1296 GetMenuBox(mhd
->menubarwin
, item
, &mhd
->submenubox
.MinX
,
1297 &mhd
->submenubox
.MinY
,
1298 &mhd
->submenubox
.MaxX
,
1299 &mhd
->submenubox
.MaxY
);
1302 struct mdpGetMenuSpaces msg
;
1304 msg
.MethodID
= MDM_GETMENUSPACES
;
1305 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1306 msg
.mdp_InnerLeft
= 0;
1307 msg
.mdp_InnerTop
= 0;
1308 msg
.mdp_InnerRight
= 0;
1309 msg
.mdp_InnerBottom
= 0;
1311 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
1312 mhd
->menuinnerleft
= msg
.mdp_InnerLeft
;
1313 mhd
->menuinnerright
= msg
.mdp_InnerRight
;
1314 mhd
->menuinnertop
= msg
.mdp_InnerTop
;
1315 mhd
->menuinnerbottom
= msg
.mdp_InnerBottom
;
1318 win_tags
[0].ti_Data
= mhd
->menuwin
->LeftEdge
+
1319 mhd
->activeitem
->LeftEdge
- mhd
->activemenu
->JazzX
+
1320 mhd
->submenubox
.MinX
;
1322 win_tags
[1].ti_Data
= mhd
->menuwin
->TopEdge
+
1323 mhd
->activeitem
->TopEdge
- mhd
->activemenu
->JazzY
+
1324 mhd
->submenubox
.MinY
;
1326 win_tags
[2].ti_Data
= mhd
->submenubox
.MaxX
- mhd
->submenubox
.MinX
+ 1 + mhd
->menuinnerleft
+ mhd
->menuinnerright
;
1327 win_tags
[3].ti_Data
= mhd
->submenubox
.MaxY
- mhd
->submenubox
.MinY
+ 1 + mhd
->menuinnertop
+ mhd
->menuinnerbottom
;
1329 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
;
1330 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
;
1331 if (((LONG
) win_tags
[0].ti_Data
) < 0) win_tags
[0].ti_Data
= 0;
1332 if (((LONG
) win_tags
[1].ti_Data
) < 0) win_tags
[1].ti_Data
= 0;
1336 item
->Flags
&= ~HIGHITEM
;
1337 item
= item
->NextItem
;
1340 IPTR userbuffersize
;
1342 GetAttr(MDA_UserBuffer
, ((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, &userbuffersize
);
1346 mhd
->DecorUserBufferSize
= userbuffersize
;
1347 mhd
->SubDecorUserBuffer
= (IPTR
) AllocMem(userbuffersize
, MEMF_ANY
| MEMF_CLEAR
);
1348 if (0 == mhd
->SubDecorUserBuffer
) return;
1352 struct mdpInitMenu msg
;
1353 msg
.MethodID
= MDM_INITMENU
;
1354 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1355 msg
.mdp_RPort
= &mhd
->scr
->RastPort
;
1356 msg
.mdp_Left
= win_tags
[0].ti_Data
;
1357 msg
.mdp_Top
= win_tags
[1].ti_Data
;
1358 msg
.mdp_Width
= win_tags
[2].ti_Data
;
1359 msg
.mdp_Height
= win_tags
[3].ti_Data
;
1360 msg
.mdp_UserBuffer
= mhd
->SubDecorUserBuffer
;
1361 msg
.mdp_ScreenUserBuffer
= ((struct IntScreen
*) mhd
->scr
)->DecorUserBuffer
;
1362 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1363 msg
.mdp_Screen
= mhd
->scr
;
1364 msg
.mdp_MenuDecorFlags
= (MENUS_UNDERMOUSE(IntuitionBase
)) ? MDP_MDF_MENUS_UNDERMOUSE
: 0;
1365 msg
.mdp_MenuDecorFlags
|= MDP_MDF_SUBITEM
;
1367 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
1369 mhd
->submenuwin
= OpenWindowTagList(0, win_tags
);
1371 mhd
->maxcommkeywidth_submenu
= CalcMaxCommKeyWidth(mhd
->submenuwin
, mhd
, IntuitionBase
);
1373 RenderSubMenu(mhd
, IntuitionBase
);
1377 /**************************************************************************************************/
1379 static void KillSubMenuWin(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1381 if (mhd
->submenuwin
)
1383 CloseWindow(mhd
->submenuwin
);
1385 TimeDelay(UNIT_VBLANK
,0,20000);
1386 struct mdpExitMenu msg
;
1388 msg
.MethodID
= MDM_EXITMENU
;
1389 msg
.mdp_TrueColor
= mhd
->TrueColor
;
1390 msg
.mdp_UserBuffer
= mhd
->SubDecorUserBuffer
;
1391 DoMethodA(((struct IntScreen
*)(mhd
->scr
))->MenuDecorObj
, (Msg
)&msg
);
1393 if (mhd
->SubDecorUserBuffer
)
1395 FreeMem((void *)mhd
->SubDecorUserBuffer
, mhd
->DecorUserBufferSize
);
1397 mhd
->SubDecorUserBuffer
= 0;
1399 mhd
->submenuwin
= NULL
;
1401 mhd
->activesubitemnum
= -1;
1402 mhd
->activesubitem
= NULL
;
1406 /**************************************************************************************************/
1408 static void RenderSubMenu(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1410 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1412 if (mhd
->submenuwin
)
1414 struct MenuItem
*item
;
1416 RenderMenuBG(mhd
->submenuwin
, mhd
, IntuitionBase
);
1418 SetFont(mhd
->submenuwin
->RPort
, mhd
->dri
->dri_Font
);
1420 for(item
= mhd
->activeitem
->SubItem
; item
; item
= item
->NextItem
)
1422 RenderItem(item
, ITEM_SUBITEM
, (struct Rectangle
*)(&mhd
->submenubox
), mhd
, IntuitionBase
);
1425 } /* if (mhd->submenuwin) */
1428 /**************************************************************************************************/
1430 static void RenderItem(struct MenuItem
*item
, WORD itemtype
, struct Rectangle
*box
,
1431 struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1433 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1434 struct Window
*win
= ((itemtype
== ITEM_ITEM
) ? mhd
->menuwin
: mhd
->submenuwin
);
1435 struct RastPort
*rp
= win
->RPort
;
1436 WORD offx
= -box
->MinX
+ mhd
->menuinnerleft
;
1437 WORD offy
= -box
->MinY
+ mhd
->menuinnertop
;
1438 BOOL enabled
= ((item
->Flags
& ITEMENABLED
) &&
1439 (mhd
->activemenu
->Flags
& MENUENABLED
) &&
1440 ((itemtype
== ITEM_ITEM
) || (mhd
->activeitem
->Flags
& ITEMENABLED
)));
1441 BOOL item_supports_disable
= FALSE
;
1448 if (item
->Flags
& ITEMTEXT
)
1450 struct IntuiText
*save
= ((struct IntuiText
*) item
->ItemFill
)->NextText
;
1455 ((struct IntuiText
*) item
->ItemFill
)->NextText
= NULL
;
1458 struct IntuiText
*it
= (struct IntuiText
*)item
->ItemFill
;
1460 if (MENUS_AMIGALOOK(IntuitionBase
))
1462 PrintIText(rp
, it
, offx
+ item
->LeftEdge
, offy
+ item
->TopEdge
);
1466 it
->FrontPen
= mhd
->dri
->dri_Pens
[(item
->Flags
& HIGHITEM
) ? FILLTEXTPEN
: TEXTPEN
];
1467 it
->DrawMode
= JAM1
;
1469 PrintIText(rp
, it
, offx
+ item
->LeftEdge
, offy
+ item
->TopEdge
);
1473 DrawImageState(rp
, mhd
->submenuimage
, offx
+ item
->Width
- mhd
->submenuimage
->Width
, offy
+ item
->TopEdge
+ ((item
->Height
- mhd
->submenuimage
->Height
) >> 1), IDS_NORMAL
, mhd
->dri
);
1474 ((struct IntuiText
*) item
->ItemFill
)->NextText
= save
;
1480 struct Image
*im
= (struct Image
*)item
->ItemFill
;
1481 LONG state
= IDS_NORMAL
;
1483 if (!enabled
&& (im
->Depth
== CUSTOMIMAGEDEPTH
))
1487 GetAttr(IA_SupportsDisable
, (Object
*)im
, &val
);
1490 item_supports_disable
= TRUE
;
1491 state
= IDS_DISABLED
;
1495 DrawImageState(rp
, im
, offx
+ item
->LeftEdge
, offy
+ item
->TopEdge
, state
, mhd
->dri
);
1498 } /* if (item->ItemFill) */
1500 RenderCheckMark(item
, itemtype
, mhd
, IntuitionBase
);
1501 RenderAmigaKey(item
, itemtype
, mhd
, IntuitionBase
);
1503 if (!enabled
&& !item_supports_disable
)
1505 RenderDisabledPattern(rp
, offx
+ item
->LeftEdge
,
1506 offy
+ item
->TopEdge
,
1507 offx
+ item
->LeftEdge
+ item
->Width
- 1,
1508 offy
+ item
->TopEdge
+ item
->Height
- 1,
1515 /**************************************************************************************************/
1517 static void RenderMenuBG(struct Window
*win
, struct MenuHandlerData
*mhd
,
1518 struct IntuitionBase
*IntuitionBase
)
1521 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1522 struct RastPort
*rp
= win
->RPort
;
1523 WORD borderx
, bordery
;
1525 if (CustomDrawBackground(rp
, win
, 0, 0, win
->Width
- 1, win
->Height
- 1, 0, mhd
, IntuitionBase
)) return;
1527 if (MENUS_AMIGALOOK(IntuitionBase
))
1529 borderx
= mhd
->scr
->MenuHBorder
/ 2;
1530 bordery
= mhd
->scr
->MenuVBorder
/ 2;
1538 /* White background */
1540 if (MENUS_AMIGALOOK(IntuitionBase
))
1542 SetABPenDrMd(rp
, mhd
->dri
->dri_Pens
[BARBLOCKPEN
], 0, JAM1
);
1546 SetABPenDrMd(rp
, mhd
->dri
->dri_Pens
[BACKGROUNDPEN
], 0, JAM1
);
1549 RectFill(rp
, borderx
,
1551 win
->Width
- 1 - borderx
,
1552 win
->Height
- 1 - bordery
);
1554 /* Black border frame */
1556 if (MENUS_AMIGALOOK(IntuitionBase
))
1558 SetAPen(rp
, mhd
->dri
->dri_Pens
[BARDETAILPEN
]);
1559 RectFill(rp
, 0, 0, win
->Width
- 1, bordery
- 1);
1560 RectFill(rp
, 0, bordery
, borderx
- 1, win
->Height
- 1 - bordery
);
1561 RectFill(rp
, win
->Width
- borderx
, bordery
, win
->Width
- 1, win
->Height
- 1);
1562 RectFill(rp
, 0, win
->Height
- bordery
, win
->Width
- 1 - borderx
, win
->Height
- 1);
1566 RenderFrame(rp
, 0, 0, win
->Width
- 1, win
->Height
- 1, IDS_NORMAL
, mhd
, IntuitionBase
);
1570 /**************************************************************************************************/
1572 static void RenderCheckMark(struct MenuItem
*item
, WORD itemtype
, struct MenuHandlerData
*mhd
,
1573 struct IntuitionBase
*IntuitionBase
)
1575 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1576 struct Window
*win
= ((itemtype
== ITEM_ITEM
) ? mhd
->menuwin
: mhd
->submenuwin
);
1577 struct RastPort
*rp
= win
->RPort
;
1578 struct Rectangle
*box
= ((itemtype
== ITEM_ITEM
) ? ((struct Rectangle
*)&mhd
->activemenu
->JazzX
) : &mhd
->submenubox
);
1579 WORD offx
= -box
->MinX
+ mhd
->menuinnerleft
;
1580 WORD offy
= -box
->MinY
+ mhd
->menuinnertop
;
1581 WORD state
= ((item
->Flags
& HIGHITEM
) &&
1582 ((item
->Flags
& HIGHFLAGS
) == HIGHCOMP
)) ? IDS_SELECTED
: IDS_NORMAL
;
1584 if (item
->Flags
& CHECKIT
)
1586 WORD x1
, y1
, x2
, y2
;
1588 x1
= item
->LeftEdge
+ offx
;
1589 y1
= item
->TopEdge
+ offy
+ (item
->Height
- mhd
->checkmark
->Height
) / 2;
1590 x2
= x1
+ mhd
->checkmark
->Width
- 1;
1591 y2
= y1
+ mhd
->checkmark
->Height
- 1;
1595 if (item
->Flags
& CHECKED
)
1597 DrawImageState(rp
, mhd
->checkmark
, x1
, y1
, state
, mhd
->dri
);
1601 if (MENUS_AMIGALOOK(IntuitionBase
))
1603 SetAPen(rp
, mhd
->dri
->dri_Pens
[BARBLOCKPEN
]);
1607 SetAPen(rp
, mhd
->dri
->dri_Pens
[(state
== IDS_SELECTED
) ? FILLPEN
: BACKGROUNDPEN
]);
1610 if (!CustomDrawBackground(rp
, win
, x1
, y1
, x2
- x1
+ 1, y2
- y1
+ 1, item
->Flags
, mhd
, IntuitionBase
)) RectFill(rp
, x1
, y1
, x2
, y2
);
1616 /**************************************************************************************************/
1618 static void RenderAmigaKey(struct MenuItem
*item
, WORD itemtype
, struct MenuHandlerData
*mhd
,
1619 struct IntuitionBase
*IntuitionBase
)
1621 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1622 struct Window
*win
= ((itemtype
== ITEM_ITEM
) ? mhd
->menuwin
: mhd
->submenuwin
);
1623 struct RastPort
*rp
= win
->RPort
;
1624 struct Rectangle
*box
= ((itemtype
== ITEM_ITEM
) ? ((struct Rectangle
*)&mhd
->activemenu
->JazzX
) : &mhd
->submenubox
);
1625 WORD commkeywidth
= ((itemtype
== ITEM_ITEM
) ? mhd
->maxcommkeywidth_menu
: mhd
->maxcommkeywidth_submenu
);
1626 WORD offx
= -box
->MinX
+ mhd
->menuinnerleft
;
1627 WORD offy
= -box
->MinY
+ mhd
->menuinnertop
;
1628 WORD state
= ((item
->Flags
& HIGHITEM
) &&
1629 ((item
->Flags
& HIGHFLAGS
) == HIGHCOMP
)) ? IDS_SELECTED
: IDS_NORMAL
;
1631 if (item
->Flags
& COMMSEQ
)
1633 struct TextFont
*oldfont
= rp
->Font
;
1634 struct TextFont
*newfont
= NULL
;
1638 if (item
->Flags
& ITEMTEXT
)
1640 struct IntuiText
*it
= (struct IntuiText
*)item
->ItemFill
;
1644 if ((newfont
= OpenFont(it
->ITextFont
)))
1646 SetFont(rp
, newfont
);
1651 x1
= item
->LeftEdge
+ offx
+ item
->Width
- AMIGAKEY_BORDER_SPACING
-
1652 mhd
->amigakey
->Width
- AMIGAKEY_KEY_SPACING
- commkeywidth
;
1653 y1
= item
->TopEdge
+ offy
+ (item
->Height
- mhd
->amigakey
->Height
+ 1) / 2;
1657 DrawImageState(rp
, mhd
->amigakey
, x1
, y1
, state
, mhd
->dri
);
1659 x1
+= mhd
->amigakey
->Width
+ AMIGAKEY_KEY_SPACING
;
1661 if (MENUS_AMIGALOOK(IntuitionBase
))
1663 SetAPen(rp
, mhd
->dri
->dri_Pens
[BARDETAILPEN
]);
1667 SetAPen(rp
, mhd
->dri
->dri_Pens
[(item
->Flags
& HIGHITEM
) ? FILLTEXTPEN
: TEXTPEN
]);
1670 Move(rp
, x1
, item
->TopEdge
+ offy
+ (item
->Height
- rp
->TxHeight
) / 2 +
1672 Text(rp
, &item
->Command
, 1);
1677 SetFont(rp
, oldfont
);
1680 } /* if (item->Flags & COMMSEQ) */
1683 /**************************************************************************************************/
1685 static void RenderDisabledPattern(struct RastPort
*rp
, WORD x1
, WORD y1
, WORD x2
, WORD y2
,
1686 struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1688 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1689 static CONST UWORD pattern
[] = {0x8888, 0x2222};
1693 if (MENUS_AMIGALOOK(IntuitionBase
))
1695 SetAPen(rp
, mhd
->dri
->dri_Pens
[BARBLOCKPEN
]);
1699 SetAPen(rp
, mhd
->dri
->dri_Pens
[BACKGROUNDPEN
]);
1702 SetAfPt(rp
, pattern
, 1);
1704 RectFill(rp
, x1
, y1
, x2
, y2
);
1706 SetAfPt(rp
, NULL
, 0);
1710 /**************************************************************************************************/
1712 static void RenderFrame(struct RastPort
*rp
, WORD x1
, WORD y1
, WORD x2
, WORD y2
, WORD state
,
1713 struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1715 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1717 SetAPen(rp
, mhd
->dri
->dri_Pens
[(state
== IDS_SELECTED
) ? SHADOWPEN
: SHINEPEN
]);
1719 RectFill(rp
, x1
, y1
, x2
, y1
);
1720 RectFill(rp
, x1
, y1
+ 1, x1
, y2
);
1722 SetAPen(rp
, mhd
->dri
->dri_Pens
[(state
== IDS_SELECTED
) ? SHINEPEN
: SHADOWPEN
]);
1723 RectFill(rp
, x2
, y1
+ 1, x2
, y2
);
1724 RectFill(rp
, x1
+ 1, y2
, x2
- 1, y2
);
1726 /**************************************************************************************************/
1728 static void HighlightItem(struct MenuItem
*item
, WORD itemtype
, struct MenuHandlerData
*mhd
,
1729 struct IntuitionBase
*IntuitionBase
)
1731 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1732 struct Window
*win
= ((itemtype
== ITEM_ITEM
) ? mhd
->menuwin
: mhd
->submenuwin
);
1733 struct RastPort
*rp
= win
->RPort
;
1734 struct Rectangle
*box
= ((itemtype
== ITEM_ITEM
) ? ((struct Rectangle
*)&mhd
->activemenu
->JazzX
) : &mhd
->submenubox
);
1736 WORD offx
= -box
->MinX
+ mhd
->menuinnerleft
;
1737 WORD offy
= -box
->MinY
+ mhd
->menuinnertop
;
1738 WORD x1
, y1
, x2
, y2
;
1741 enabled
= (item
->Flags
& ITEMENABLED
) ? TRUE
: FALSE
;
1742 if (!(mhd
->activemenu
->Flags
& MENUENABLED
)) enabled
= FALSE
;
1743 if ((itemtype
== ITEM_SUBITEM
) && !(mhd
->activeitem
->Flags
& ITEMENABLED
)) enabled
= FALSE
;
1747 item
->Flags
^= HIGHITEM
;
1749 fill
= item
->ItemFill
;
1750 if ((item
->Flags
& HIGHITEM
) && (item
->SelectFill
)) fill
= item
->SelectFill
;
1752 x1
= offx
+ item
->LeftEdge
;
1753 y1
= offy
+ item
->TopEdge
;
1754 x2
= x1
+ item
->Width
- 1;
1755 y2
= y1
+ item
->Height
- 1;
1757 if (CustomDrawBackground(rp
, win
, x1
, y1
, x2
- x1
+ 1, y2
- y1
+ 1, item
->Flags
, mhd
, IntuitionBase
)) {
1760 if(item
->Flags
& ITEMTEXT
)
1762 struct IntuiText
*save
= ((struct IntuiText
*) fill
)->NextText
;
1767 ((struct IntuiText
*) fill
)->NextText
= NULL
;
1770 if (MENUS_AMIGALOOK(IntuitionBase
))
1772 PrintIText(rp
, (struct IntuiText
*)fill
, x1
, y1
);
1776 struct IntuiText
*it
= (struct IntuiText
*)fill
;
1778 it
->FrontPen
= mhd
->dri
->dri_Pens
[TEXTPEN
];
1779 it
->DrawMode
= JAM1
;
1781 PrintIText(rp
, it
, x1
, y1
);
1785 DrawImageState(rp
, mhd
->submenuimage
, offx
+ item
->Width
- mhd
->submenuimage
->Width
, offy
+ item
->TopEdge
+ ((item
->Height
- mhd
->submenuimage
->Height
) >> 1), IDS_NORMAL
, mhd
->dri
);
1786 ((struct IntuiText
*) fill
)->NextText
= save
;
1792 EraseImage(rp
, (struct Image
*)fill
, x1
, y1
);
1793 DrawImageState(rp
, (struct Image
*)fill
, x1
, y1
, IDS_SELECTED
, mhd
->dri
);
1795 RenderItem(item
, itemtype
, box
, mhd
, IntuitionBase
);
1799 switch(item
->Flags
& HIGHFLAGS
)
1804 if(item
->Flags
& ITEMTEXT
)
1806 struct IntuiText
*save
= ((struct IntuiText
*) fill
)->NextText
;
1811 ((struct IntuiText
*) fill
)->NextText
= NULL
;
1813 if (MENUS_AMIGALOOK(IntuitionBase
))
1815 PrintIText(rp
, (struct IntuiText
*)fill
, x1
, y1
);
1819 struct IntuiText
*it
= (struct IntuiText
*)fill
;
1821 it
->FrontPen
= mhd
->dri
->dri_Pens
[TEXTPEN
];
1822 it
->DrawMode
= JAM1
;
1824 PrintIText(rp
, it
, x1
, y1
);
1828 DrawImageState(rp
, mhd
->submenuimage
, offx
+ item
->Width
- mhd
->submenuimage
->Width
, offy
+ item
->TopEdge
+ ((item
->Height
- mhd
->submenuimage
->Height
) >> 1), IDS_NORMAL
, mhd
->dri
);
1829 ((struct IntuiText
*) fill
)->NextText
= save
;
1835 EraseImage(rp
, (struct Image
*)fill
, x1
, y1
);
1836 DrawImageState(rp
, (struct Image
*)fill
, x1
, y1
, IDS_SELECTED
, mhd
->dri
);
1841 if (MENUS_AMIGALOOK(IntuitionBase
))
1843 SetDrMd(rp
, COMPLEMENT
);
1844 RectFill(rp
, x1
, y1
, x2
, y2
);
1848 WORD state
= (item
->Flags
& HIGHITEM
) ? IDS_SELECTED
: IDS_NORMAL
;
1851 SetAPen(rp
, mhd
->dri
->dri_Pens
[(state
== IDS_SELECTED
) ? FILLPEN
: BACKGROUNDPEN
]);
1852 RectFill(rp
, x1
, y1
, x2
, y2
);
1854 RenderItem(item
, itemtype
, box
, mhd
, IntuitionBase
);
1856 if (state
== IDS_SELECTED
)
1858 RenderFrame(rp
, x1
, y1
, x2
, y2
, state
, mhd
, IntuitionBase
);
1864 SetDrMd(rp
, COMPLEMENT
);
1865 offx
= mhd
->scr
->MenuHBorder
;
1866 offy
= mhd
->scr
->MenuVBorder
;
1873 RectFill(rp
, x1
, y1
, x2
, y1
+ offy
- 1);
1874 RectFill(rp
, x2
- offx
+ 1, y1
+ offy
, x2
, y2
);
1875 RectFill(rp
, x1
, y2
- offy
+ 1, x2
- offx
, y2
);
1876 RectFill(rp
, x1
, y1
+ offy
, x1
+ offx
- 1,y2
- offy
);
1883 } /* switch(item->Flags & HIGHFLAGS) */
1885 } /* if (enabled) */
1889 /**************************************************************************************************/
1891 static WORD
CalcMaxCommKeyWidth(struct Window
*win
, struct MenuHandlerData
*mhd
,
1892 struct IntuitionBase
*IntuitionBase
)
1894 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1895 struct TextExtent te
;
1898 FontExtent(mhd
->dri
->dri_Font
, &te
);
1899 maxwidth
= te
.te_Width
;
1903 struct MenuItem
*item
;
1905 if ((win
== mhd
->menuwin
))
1907 item
= mhd
->activemenu
->FirstItem
;
1911 item
= mhd
->activeitem
->SubItem
;
1914 for(; item
; item
= item
->NextItem
)
1916 if (item
->Flags
& ITEMTEXT
)
1918 struct IntuiText
*it
= (struct IntuiText
*)item
->ItemFill
;
1922 struct TextFont
*font
;
1924 if ((font
= OpenFont(it
->ITextFont
)))
1926 FontExtent(font
, &te
);
1927 if (te
.te_Width
> maxwidth
) maxwidth
= te
.te_Width
;
1933 } /* if (item->Flags & ITEMTEXT) */
1935 } /* for(; item; item = item->NextItem); */
1942 /**************************************************************************************************/
1944 static void AddToSelection(struct MenuHandlerData
*mhd
, struct IntuitionBase
*IntuitionBase
)
1946 if ((mhd
->activemenunum
!= -1) && (mhd
->activemenu
->Flags
& MENUENABLED
) &&
1947 (mhd
->activeitemnum
!= -1) && (mhd
->activeitem
->Flags
& ITEMENABLED
))
1949 struct MenuItem
*item
= NULL
;
1950 UWORD men
= FULLMENUNUM(mhd
->activemenunum
, mhd
->activeitemnum
, mhd
->activesubitemnum
);
1952 if (mhd
->activesubitemnum
!= -1)
1954 if (mhd
->activesubitem
->Flags
& ITEMENABLED
) item
= mhd
->activesubitem
;
1956 else if (!mhd
->activeitem
->SubItem
)
1958 item
= mhd
->activeitem
;
1961 if (item
&& (ItemAddress(mhd
->menu
, men
) == item
))
1963 UWORD men
= FULLMENUNUM(mhd
->activemenunum
, mhd
->activeitemnum
, mhd
->activesubitemnum
);
1965 if (mhd
->firstmenupick
== MENUNULL
)
1967 mhd
->firstmenupick
= men
;
1969 else if (men
!= mhd
->lastmenupick
)
1971 struct MenuItem
*checkitem
, *prevcheckitem
= NULL
;
1972 UWORD checkmen
= mhd
->firstmenupick
;
1974 /* Remove men from pick queue, if it was already in there
1975 and then add it at the end of the pick queue */
1977 while(checkmen
!= MENUNULL
)
1979 checkitem
= ItemAddress(mhd
->menu
, checkmen
);
1981 if (checkmen
== men
)
1983 if (prevcheckitem
== NULL
)
1985 mhd
->firstmenupick
= checkitem
->NextSelect
;
1989 prevcheckitem
->NextSelect
= checkitem
->NextSelect
;
1993 checkmen
= checkitem
->NextSelect
;
1994 prevcheckitem
= checkitem
;
1996 } /* while(checkmen != MENUNULL) */
1998 checkitem
->NextSelect
= men
;
2000 } /* else if (men != mhd->lastmenupick) */
2002 mhd
->lastmenupick
= men
;
2003 item
->NextSelect
= MENUNULL
;
2007 } /* if ((mhd->activemenunum != -1) && (mhd->activeitemnum != -1)) */