3 // ©1996-2002 Henrik Isaksson
17 #include <proto/intuition.h>
18 #include <proto/graphics.h>
19 #include <proto/exec.h>
20 #include <proto/utility.h>
21 #include <proto/dos.h>
22 #include <proto/commodities.h>
23 #include <proto/layers.h>
24 #include <proto/keymap.h>
25 #include <proto/cybergraphics.h>
27 #include <exec/libraries.h>
28 #include <intuition/intuition.h>
29 #include <intuition/imageclass.h>
30 #include <exec/memory.h>
31 #include <graphics/gfx.h>
32 #include <graphics/gfxmacros.h>
33 #include <exec/libraries.h>
34 #include <exec/interrupts.h>
35 #include <devices/inputevent.h>
36 #include <devices/input.h>
37 #include <devices/timer.h>
41 #include <clib/alib_protos.h>
45 #include <cybergraphx/cybergraphics.h> /* v41 uses cybergraphx/ dir */
47 #include "popupmenu.h"
54 #include "pmtopography.h"
57 #include "pminternals.h"
63 /*--- functions in V50 or higher (Release 4) ---*/
64 #pragma libcall IntuitionBase ShowWindow 342 9802
65 #pragma libcall IntuitionBase HideWindow 348 801
66 #pragma libcall IntuitionBase GetAttrsA 34e 9802
67 #pragma libcall IntuitionBase LockGUIPrefs 354 801
68 #pragma libcall IntuitionBase UnlockGUIPrefs 35a 801
69 #pragma libcall IntuitionBase SetGUIAttrsA 360 A9803
70 #pragma libcall IntuitionBase GetGUIAttrsA 366 A9803
71 #pragma tagcall IntuitionBase GetGUIAttrs 366 A9803
72 #pragma libcall IntuitionBase GetHalfPens 36c A90804
73 #pragma libcall IntuitionBase GadgetBox 372 A109805
74 #pragma libcall IntuitionBase RefreshSetGadgetAttrsA 378 BA9804
75 #pragma libcall IntuitionBase IDoSuperMethodA 37e 9A803
76 #pragma libcall IntuitionBase ISetSuperAttrsA 384 9A803
77 #pragma libcall IntuitionBase ICoerceMethodA 38a 9A803
78 #pragma libcall IntuitionBase IDoMethodA 390 9A02
79 #pragma libcall IntuitionBase OpenClass 396 0802
80 #pragma libcall IntuitionBase CloseClass 39c 801
81 #pragma libcall IntuitionBase GetClassBase 3a2 801
82 #pragma libcall IntuitionBase LockScreen 3a8 801
83 #pragma libcall IntuitionBase UnlockScreen 3ae 801
84 #pragma libcall IntuitionBase GetWindowAttrsA 3b4 9802
85 #pragma libcall IntuitionBase SetWindowAttrsA 3ba 9802
86 #pragma libcall IntuitionBase GetWindowAttr 3c0 190804
87 #pragma libcall IntuitionBase SetWindowAttr 3c6 190804
88 #pragma libcall IntuitionBase StripIntuiMessages 3cc 9802
89 #pragma libcall IntuitionBase StartScreenNotify 3d2 801
90 #pragma libcall IntuitionBase EndScreenNotify 3d8 801
91 #pragma libcall IntuitionBase GetScreenAttrsA 3de 9802
92 #pragma libcall IntuitionBase SetScreenAttrsA 3e4 9802
93 #pragma libcall IntuitionBase GetScreenAttr 3ea 190804
94 #pragma libcall IntuitionBase SetScreenAttr 3f0 190804
95 #pragma libcall IntuitionBase LockScreenList 3f6 0
96 #pragma libcall IntuitionBase UnlockScreenList 3fc 0
97 #pragma libcall IntuitionBase LockScreenGI 402 801
98 #pragma libcall IntuitionBase UnlockScreenGI 408 9802
101 #define PM_Req(c, s) if(c) EZReq("Assertion failed:\n\n" s, "OK", 0)
103 #define SelBarLeft(a) (a->p->BorderWidth+1+PM_Prefs->pmp_XSpace)
104 #define SelBarRight(a) (a->p->BorderWidth-1-PM_Prefs->pmp_XSpace)
105 #define SelBarTop(a, pm) (pm->Top+PM_Prefs->pmp_YSpace+1)
106 #define SelBarBottom(a, pm) (pm->Top-PM_Prefs->pmp_YSpace+pm->Height-1)
108 #define FirstColumn(a) (PM_Prefs->pmp_XOffset+a->p->BorderWidth+1) /* sista 1 == selbarwidth */
110 #define BarTop(a, pm) (pm->Top+pm->Height/2+1)
112 #define BarLeft(a, pm) (pm->Left)
114 #define BarRight(a, pm) (pm->Left+pm->Width)
116 #define XAPosWideSelBar(a) SelBarLeft(a)
117 #define XBPosWideSelBar(a) SelBarRight(a)
118 #define XAPosSelBar(a) SelBarLeft(a)
119 #define XBPosSelBar(a) SelBarRight(a)
120 #define YAPosSelBar(a, pm) SelBarTop(a, pm)
121 #define YBPosSelBar(a, pm) SelBarBottom(a, pm)
122 #define CheckmarkSize(a) (PM_Prefs->pmp_Intermediate+a->p->MenuFont->tf_XSize)
123 #define SubmarkSize(a) (PM_Prefs->pmp_Intermediate+a->p->MenuFont->tf_XSize)
124 #define YPosText(a, pm) (pm->Top+a->p->MenuFont->tf_Baseline+(pm->Height+1)/2-(a->p->MenuFont->tf_YSize)/2+PM_Prefs->pmp_TextDisplace)
125 //#define XPosLastCol(a) (a->Width-(1)-a->p->MenuFont->tf_XSize-PM_Prefs->pmp_Intermediate-PM_Prefs->pmp_XSpace)
126 //#define XPosLastColImg(a, img) (a->Width-a->p->BorderWidth-PMImgWidth(img)-PM_Prefs->pmp_Intermediate)
127 #define XPosLastCol(a) (pm->Left+pm->Width-a->p->MenuFont->tf_XSize-PM_Prefs->pmp_XSpace)
128 #define XPosLastColImg(a, img) (pm->Left+pm->Width-PMImgWidth(img)-PM_Prefs->pmp_XSpace)
129 #define YPosImage(a, pm, img) (pm->Top+(pm->Height+1)/2-PMImgHeight(img)/2)
130 #define YPosImage_(a, pm, img) (pm->Top+(pm->Height+1)/2-img->Height/2)
132 #define OutOfRange(x, min, max) (x>=max || x<=min)
134 #define SCREENMOUSEPOS(p) p->RootWnd->WScreen->MouseX, p->RootWnd->WScreen->MouseY
135 #define SCREENMOUSEX(p) p->RootWnd->WScreen->MouseX
136 #define SCREENMOUSEY(p) p->RootWnd->WScreen->MouseY
139 #warning "FIXME: Pens"
140 #define MENUSHINEPEN SHINEPEN
141 #define MENUSHADOWPEN SHADOWPEN
142 #define MENUTEXTPEN TEXTPEN
143 #define SELECTPEN FILLPEN
144 #define SELECTTEXTPEN FILLTEXTPEN
145 #define MENUBACKGROUNDPEN BACKGROUNDPEN
148 #define SHINE(xyz) xyz->DrawInfo->dri_Pens[MENUSHINEPEN]
149 #define SHADOW(xyz) xyz->DrawInfo->dri_Pens[MENUSHADOWPEN]
150 #define TEXT(xyz) xyz->DrawInfo->dri_Pens[MENUTEXTPEN]
151 #define FILL(xyz) xyz->DrawInfo->dri_Pens[SELECTPEN]
152 #define FTPEN(xyz) xyz->DrawInfo->dri_Pens[SELECTTEXTPEN]
153 #define BGPEN(xyz) xyz->DrawInfo->dri_Pens[MENUBACKGROUNDPEN]
154 #define HILITE(xyz) xyz->DrawInfo->dri_Pens[HIGHLIGHTTEXTPEN]
155 #define TEXTSHADOW(xyz) xyz->DrawInfo->dri_Pens[BARDETAILPEN]
156 #define TEXTOUTLINE(xyz) xyz->DrawInfo->dri_Pens[BARDETAILPEN]
158 #define BGSHADOW(xyz) xyz->DrawInfo->dri_Pens[MENUSHADOWPEN]
159 #define BGSHINE(xyz) xyz->DrawInfo->dri_Pens[MENUSHINEPEN]
160 #define HALF(xyz) xyz->DrawInfo->dri_Pens[MENUBACKGROUNDPEN]
162 #define PATCH(p, n) if(PM_Prefs->pmp_MenuTitles & p) pm->Flags|=n; else pm->Flags&=~n;
163 #define TPATCH(p, n) if(PM_Prefs->pmp_MenuItems & p) pm->Flags|=n;
165 #define PM_IDCMP (IDCMP_MOUSEBUTTONS|IDCMP_MOUSEMOVE|IDCMP_INACTIVEWINDOW|IDCMP_INTUITICKS|IDCMP_REFRESHWINDOW)
167 #define BWRP &a->Wnd->RPort
168 #define BWX (a->Wnd->Left)
169 #define BWY (a->Wnd->Top)
170 #define BWW (a->Wnd->Width)
171 #define BWH (a->Wnd->Height)
172 #define BWXX (a->Wnd->Left+a->Wnd->Width)
173 #define BWYY (a->Wnd->Top+a->Wnd->Height)
179 #define NPX_IMGPLANAR 0x0000 //
180 #define NPX_IMGCHUNKY 0x0001 //
181 #define NPX_IMGVECTOR 0x0002 //
182 #define NPX_TXTNORMAL 0x0000 // Normal (STRPTR) title
183 #define NPX_TXTLOCALE 0x0010 // Localized title
184 #define NPX_TXTBOOPSI 0x0020 // BOOPSI Object title
186 #define GET_TXTMODE(x) (x->ExtFlags&0x0030)
187 #define GET_IMGMODE(x) (x->ExtFlags&0x0003)
189 #define SET_TXTMODE(x, y) { x->ExtFlags&=~0x0030; x->ExtFlags|=y; }
190 #define SET_IMGMODE(x, y) { x->ExtFlags&=~0x0003; x->ExtFlags|=y; }
197 #define IMG_CHECKMARK (0x10L) // Checkmark \/
198 #define IMG_RIGHTARROW (0x0CL) // SysIClass Arrow |>|
199 #define IMG_MXIMAGE (0x0FL) // SysIClass MX (*)
200 #define IMG_CHECKIMAGE (0x0EL) // SysIClass Checkbox | |
201 #define IMG_AMIGAKEY (0x11L) // Amiga Key Image |A|
203 #define IMG_MMCHECK (0x7000L) // MagicMenu CheckMark
204 #define IMG_MMAMIGA (0x7001L) // MagicMenu AmigaKey
205 #define IMG_MMSUB (0x7002L) // MagicMenu Submenu arrow
206 #define IMG_MMEXCLUDE (0x7003L) // MagicMenu MX Image
208 #define IMG_BULLET_A (0x8000L) // bullet ·
209 #define IMG_BULLET_B (0x8100L) // 3d bullet ·
210 #define IMG_ARROW_A (0x8200L) // Arrow >
211 #define IMG_ARROW_B (0x8300L) // 3d arrow >
212 #define IMG_ARROW_C (0x8400L) // Arrow ->
215 struct PM_IDLst
*Next
;
221 #define IDKND_EXCLUDE 0x1
222 #define IDKND_INCLUDE 0x2
223 #define IDKND_REFLECT 0x3
224 #define IDKND_INVERSE 0x4
229 // PM_Window holds menu window information
232 struct PM_Window
*Prev
; // Previous window in the chain, for bounds checking of the entire menu
233 struct PM_Window
*NextWindow
; // Points to a submenu, while it's open
235 UWORD Width
; // Menu size differs from window size, because of shadows.
240 struct Window
*Wnd
; // The menu window
241 struct RastPort
*RPort
; // Window RastPort, NEVER use wnd->RPort
243 struct PM_WBackground
{ // Background buffer for transparency or backdrop images
247 struct PM_EffectBuffer
{ // Used for transition effects
249 struct RastPort
*RPort
; // RastPort, PM_Window::RPort will be redirected here when TE's are used
252 struct PopupMenu
*Selected
; // Currently selected item (the one in 'focus'), or NULL
253 struct PopupMenu
*PrevSel
; // Previously selected
254 struct PopupMenu
*WasSelected
; // Was selected when button was released
255 struct PopupMenu
*SubMenuToOpen
;
256 struct PopupMenu
*SubMenuParent
; // For construct hook
258 LONG AltXPos
; // Alternate X position
260 BOOL Running
; // TRUE while active, setting to FALSE will terminate this window
261 // Can be set to TRUE by submenus
263 BOOL MenuDisabled
; // Entire menu is disabled
264 ULONG IconColumn
; // Width of Icon Column(s)
265 ULONG ItemHeight
; // Height of items
266 ULONG MenuLevel
; // Wich level of submenu this is
267 BOOL FirstTime
; // Pulldown menus need to be drawn differently the first time
268 BOOL ReverseDirection
; // Open menus to the left
269 BOOL StickyFlag
; // Sticky mode: MB is down => multiselect on, close on up
271 PMTRList
*Topographic
; // Shadow management - topography
272 PMSRList
*Shadowmap
; // Shadow management - overlapping control
276 struct PM_Root
*p
; // Menu globals
280 struct MultiSlct
*next
;
281 struct PopupMenu
*pm
;
285 // Root menu structure, holds "global" variables
289 struct Window
*RootWnd
; // Window that the menu belongs to
290 struct Screen
*Scr
; // Menu screen
291 struct DrawInfo
*DrawInfo
; // Screen's drawinfo
292 struct PopupMenu
*PM
; // The menu
293 struct PM_Window
*RootMenu
; // First window in the menu
295 ULONG Subtimer
; // Timer for submenu
296 APTR ReturnCode
; // Return code
297 ULONG ReturnID
; // Return ID
299 LONG BorderWidth
; // Line width of menu borders
300 LONG BorderHeight
; // Line Height of menu borders
303 BOOL PullDown
; // This menu is a pulldown menu
307 UWORD ShadowWidth
; // Width of shadows
308 UWORD ShadowHeight
; // Height of shadows
309 UWORD ShadowAddX
; // Width increase for each layer
310 UWORD ShadowAddY
; // Height increase for each layer
317 struct timerequest
*treq
;
318 struct MsgPort
*tport
;
321 // Current Timer - Used to figure out when to refresh menus (update hook for dynamic menus)
330 struct MultiSlct
*MultiSel
;
338 struct Hook
*MenuHandler
; // Handles multiselect
339 struct Hook
*LocaleHook
; // Translates numbers to strings
342 // Button that opened the menu
354 UWORD MenuWidth
; // Only used for the first menu
359 // Menu font - All font operations must use this font!
362 struct TextFont
*MenuFont
;
372 BOOL DoneMulti
; // MultiSelect has been used => turns SingleSelect off
374 struct PM_InputHandler
*pmh
;
376 struct Image
*MenuImages
[PMIMG_LAST
];
379 extern struct PM_Root
*p
;
384 #define IST_INACTIVE 2
386 #define PMACT_DESELECT 2
387 #define PMACT_SELECT 3
396 void PM_DrawShadow(struct PM_Window
*w
, int x
, int y
, int xb
, int yb
);
397 struct PM_Root
*PM_AllocPMRoot(struct Window
*w
);
399 void PM_FreeSubWindow(struct PM_Window
*parent
, struct PM_Window
*a
);
400 struct PM_Window
*PM_SetupSubWindow(struct PM_Window
*parent
, struct PM_Root
*p
, struct PopupMenu
*pm
);
401 APTR
PM_DoPopup(struct PM_Window
*a
);
402 void PM_CloseWindow(struct PM_Window
*);
403 void StripIntuiMessages(struct MsgPort
*, struct Window
*);
404 BOOL
PM_OpenWindow(struct PM_Window
*pw
, int left
, int top
, int width
, int height
, struct Screen
*scr
);
405 void PM_ResizeWindow(struct PM_Window
*bw
, int l
, int t
, int w
, int h
);
406 BOOL
PM_InsideWindows(int px
, int py
, struct PM_Window
*wnd
);
407 UWORD
PM_ItemHeight(struct PM_Window
*a
, struct PopupMenu
*pm
);
408 UWORD
PM_ItemWidth(struct PM_Window
*a
, struct PopupMenu
*pm
);
409 void PM_LayoutMenu(struct PM_Window
*a
);
410 void PM_RenderMenu(struct PM_Window
*a
, BOOL MenuDisable
, BOOL
);
413 void EZDeleteTimer(struct timerequest
*);
414 struct timerequest
*EZCreateTimer(LONG Unit
);
420 void PM_FreeTitle(struct PopupMenu
*p
);
426 LONG
EZReq(STRPTR Text
, STRPTR ButtonText
, ULONG Arg
, ...);
432 void PM_LayoutMenu(struct PM_Window
*a
);
433 void PM_LayoutGroup(struct PM_Window
*a
, struct PopupMenu
*pm
);
434 void PM_CalcItemSize(struct PM_Window
*a
, struct PopupMenu
*pm
);
435 UWORD
PM_ItemWidth(struct PM_Window
*a
, struct PopupMenu
*pm
);
436 UWORD
PM_ItemHeight(struct PM_Window
*a
, struct PopupMenu
*pm
);
444 void CloseLibs(void);
452 extern BOOL CyberGfx
;
459 APTR __saveds ASM
PM_OpenPopupMenuA(register __a1
struct Window
*prevwnd
GNUCREG(a1
),
460 register __a2
struct TagItem
*tags
GNUCREG(a2
));
461 // register __a6 struct PopupMenuBase *l GNUCREG(a6));
463 void __saveds ASM
PM_FreePopupMenu(register __a1
struct PopupMenu
*p
GNUCREG(a1
));
465 struct PopupMenu
* __saveds ASM
PM_MakeItemA(register __a1
struct TagItem
*tags
GNUCREG(a1
));
467 struct PopupMenu
* __saveds ASM
PM_MakeMenuA(register __a1
struct TagItem
*tags
GNUCREG(a1
));
469 struct PM_IDLst
* __saveds ASM
PM_MakeIDListA(register __a1
struct TagItem
*tags
GNUCREG(a1
));
471 LONG __saveds ASM
PM_GetItemAttrsA(register __a2
struct PopupMenu
*p
GNUCREG(a2
),
472 register __a1
struct TagItem
*tags
GNUCREG(a1
));
474 LONG __saveds ASM
PM_SetItemAttrsA(register __a2
struct PopupMenu
*p
GNUCREG(a2
),
475 register __a1
struct TagItem
*tags
GNUCREG(a1
));
477 void __saveds ASM
PM_AlterState(register __a1
struct PopupMenu
*base
GNUCREG(a1
),
478 register __a2
struct PM_IDLst
*ids
GNUCREG(a2
),
479 register __d1 UWORD action
GNUCREG(d1
));
481 struct PM_IDLst
* __saveds ASM
PM_ExLstA(register __a1 ULONG
*id
GNUCREG(a1
));
483 APTR __asm __saveds
LIBPM_FilterIMsgA(register __a0
struct Window
*w
GNUCREG(a0
),
484 register __a1
struct PopupMenu
*pm
GNUCREG(a1
),
485 register __a2
struct IntuiMessage
*im
GNUCREG(a2
),
486 register __a3
struct TagItem
*tags
GNUCREG(a3
));
488 struct PopupMenu
* __saveds ASM
PM_FindItem(register __a1
struct PopupMenu
*pm
GNUCREG(a1
),
489 register __d1 ULONG ID
GNUCREG(d1
));
491 BOOL __saveds ASM
PM_ItemChecked(register __a1
struct PopupMenu
*pm
GNUCREG(a1
),
492 register __d1 ULONG id
GNUCREG(d1
));