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