2 Copyright 2011-2012, The AROS Development Team.
7 #include <aros/debug.h>
9 #include <clib/alib_protos.h>
11 #include <intuition/intuition.h>
12 #include <intuition/extensions.h>
13 #include <intuition/imageclass.h>
14 #include <proto/intuition.h>
15 #include <proto/graphics.h>
16 #include <proto/utility.h>
17 #include <proto/exec.h>
19 #include "menudecorclass.h"
20 #include "screendecorclass.h"
21 #include "drawfuncs.h"
25 #define SETIMAGE_MEN(id) md->img_##id=sd->di->img_##id
29 struct DecorConfig
* dc
;
31 /* Pointers to images used for sys images */
32 struct NewImage
*img_amigakey
;
33 struct NewImage
*img_menucheck
;
34 struct NewImage
*img_submenu
;
37 static IPTR
menudecor_getdefsizes(Class
*cl
, Object
*obj
, struct mdpGetDefSizeSysImage
*msg
)
39 struct menudecor_data
*data
= INST_DATA(cl
, obj
);
41 struct NewImage
*n
= NULL
;
44 switch(msg
->mdp_Which
)
47 n
= data
->img_amigakey
;
52 n
= data
->img_menucheck
;
57 n
= data
->img_submenu
;
65 if (!isset
) return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
67 *msg
->mdp_Width
= n
->w
;
68 *msg
->mdp_Height
= n
->h
;
72 static IPTR
menudecor_getmenuspaces(Class
*cl
, Object
*obj
, struct mdpGetMenuSpaces
*msg
)
74 struct menudecor_data
*data
= INST_DATA(cl
, obj
);
76 msg
->mdp_InnerLeft
= data
->dc
->MenuInnerLeft
;
77 msg
->mdp_InnerTop
= data
->dc
->MenuInnerTop
;
78 msg
->mdp_InnerRight
= data
->dc
->MenuInnerRight
;
79 msg
->mdp_InnerBottom
= data
->dc
->MenuInnerBottom
;
80 msg
->mdp_ItemInnerLeft
= 1;
81 msg
->mdp_ItemInnerTop
= 2;
82 msg
->mdp_ItemInnerRight
= 2;
83 msg
->mdp_ItemInnerBottom
= 1;
84 if ((data
->dc
->MenuTileLeft
+ data
->dc
->MenuTileRight
) > (data
->dc
->MenuInnerLeft
+ data
->dc
->MenuInnerRight
))
85 msg
->mdp_MinWidth
= data
->dc
->MenuTileLeft
+ data
->dc
->MenuTileRight
;
87 msg
->mdp_MinWidth
= data
->dc
->MenuInnerLeft
+ data
->dc
->MenuInnerRight
;
89 if ((data
->dc
->MenuTileTop
+ data
->dc
->MenuTileBottom
) > (data
->dc
->MenuInnerTop
+ data
->dc
->MenuInnerBottom
))
90 msg
->mdp_MinHeight
= data
->dc
->MenuTileTop
+ data
->dc
->MenuTileBottom
;
92 msg
->mdp_MinHeight
= data
->dc
->MenuInnerTop
+ data
->dc
->MenuInnerBottom
;
97 static IPTR
menudecor_draw_sysimage(Class
*cl
, Object
*obj
, struct mdpDrawSysImage
*msg
)
99 struct ScreenData
*md
= (struct ScreenData
*) msg
->mdp_UserBuffer
;
100 struct RastPort
*rp
= msg
->mdp_RPort
;
101 struct NewImage
*ni
= NULL
;
102 LONG left
= msg
->mdp_X
;
103 LONG top
= msg
->mdp_Y
;
108 switch(msg
->mdp_Which
)
111 if (md
&& md
->img_amigakey
->ok
)
113 ni
= md
->img_amigakey
;
119 if (md
&& md
->img_menucheck
->ok
)
121 ni
= md
->img_menucheck
;
127 if (md
&& md
->img_submenu
->ok
)
129 ni
= md
->img_submenu
;
135 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
138 if (!isset
|| (ni
== NULL
)) return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
140 DrawStatefulGadgetImageToRP(rp
, ni
, IDS_NORMAL
, left
+ addx
, top
+ addy
);
145 /**************************************************************************************************/
147 static IPTR
menudecor_renderbackground(Class
*cl
, Object
*obj
, struct mdpDrawBackground
*msg
)
149 struct menudecor_data
*data
= INST_DATA(cl
, obj
);
150 struct RastPort
*rp
= msg
->mdp_RPort
;
152 struct MenuData
*md
= (struct MenuData
*) msg
->mdp_UserBuffer
;
153 UWORD flags
= msg
->mdp_Flags
;
155 if ((flags
& HIGHITEM
) && md
->ni
)
157 ni
= NewImageContainer(msg
->mdp_ItemWidth
, msg
->mdp_ItemHeight
);
160 DrawPartToImage(md
->ni
, ni
, msg
->mdp_ItemLeft
, msg
->mdp_ItemTop
, msg
->mdp_ItemWidth
, msg
->mdp_ItemHeight
, 0, 0);
161 SetImageTint(ni
, 255 - (data
->dc
->MenuHighlightTint
>> 24), data
->dc
->MenuHighlightTint
& 0xffffff);
162 PutImageToRP(rp
, ni
, msg
->mdp_ItemLeft
, msg
->mdp_ItemTop
);
167 if (md
->ni
) DrawPartImageToRP(rp
, md
->ni
, msg
->mdp_ItemLeft
, msg
->mdp_ItemTop
, msg
->mdp_ItemLeft
, msg
->mdp_ItemTop
, msg
->mdp_ItemWidth
, msg
->mdp_ItemHeight
);
173 static IPTR
menudecor_initmenu(Class
*cl
, Object
*obj
, struct mdpInitMenu
*msg
)
175 struct menudecor_data
*data
= INST_DATA(cl
, obj
);
176 struct RastPort
*rp
= msg
->mdp_RPort
;
177 struct MenuData
*md
= (struct MenuData
*) msg
->mdp_UserBuffer
;
178 struct ScreenData
*sd
= (struct ScreenData
*) msg
->mdp_ScreenUserBuffer
;
181 SETIMAGE_MEN(amigakey
);
182 SETIMAGE_MEN(menucheck
);
183 SETIMAGE_MEN(submenu
);
185 if (data
->dc
->MenuIsTiled
)
187 md
->img_menu_ti
= AllocVec(sizeof(struct TileInfo
), MEMF_ANY
| MEMF_CLEAR
);
188 md
->img_menu_ti
->TileLeft
= data
->dc
->MenuTileLeft
;
189 md
->img_menu_ti
->TileRight
= data
->dc
->MenuTileRight
;
190 md
->img_menu_ti
->TileBottom
= data
->dc
->MenuTileBottom
;
191 md
->img_menu_ti
->TileTop
= data
->dc
->MenuTileTop
;
194 if ((msg
->mdp_MenuDecorFlags
& MDP_MDF_MENU
) && !(msg
->mdp_MenuDecorFlags
& MDP_MDF_MENUS_UNDERMOUSE
))
196 /* Special handling for pulled down menu bar */
197 LONG height
= msg
->mdp_Height
;
199 /* Increase height for rendering if needed */
200 if ((data
->dc
->MenuIsTiled
) && (height
< (md
->img_menu_ti
->TileBottom
+ md
->img_menu_ti
->TileTop
)))
201 height
= (md
->img_menu_ti
->TileBottom
+ md
->img_menu_ti
->TileTop
);
203 md
->ni
= NewImageContainer(msg
->mdp_Width
, height
);
207 RenderMenuBarBackground(md
->ni
, md
->img_menu
, md
->img_menu_ti
, 20);
209 /* Scale down if needed */
210 if (height
> msg
->mdp_Height
)
212 struct NewImage
* sni
= ScaleNewImage(md
->ni
, msg
->mdp_Width
, msg
->mdp_Height
);
215 DisposeImageContainer(md
->ni
);
224 md
->ni
= GetImageFromRP(rp
, msg
->mdp_Left
, msg
->mdp_Top
, msg
->mdp_Width
, msg
->mdp_Height
);
228 RenderMenuBackground(md
->ni
, md
->img_menu
, md
->img_menu_ti
, 20);
236 static IPTR
menudecor_exitmenu(Class
*cl
, Object
*obj
, struct mdpExitMenu
*msg
)
238 struct MenuData
*md
= (struct MenuData
*) msg
->mdp_UserBuffer
;
240 if (md
->ni
) DisposeImageContainer(md
->ni
);
241 if (md
->map
) FreeBitMap(md
->map
);
242 if (md
->img_menu_ti
) FreeVec(md
->img_menu_ti
);
247 static void DisposeMenuSkinning(struct menudecor_data
*data
)
251 static BOOL
InitMenuSkinning(struct menudecor_data
*data
, struct DecorImages
* di
, struct DecorConfig
* dc
)
258 /* Set pointers to gadget images, used only to get gadget sizes as they
259 are requested prior to creation of menu object */
260 data
->img_amigakey
= di
->img_amigakey
;
261 data
->img_menucheck
= di
->img_menucheck
;
262 data
->img_submenu
= di
->img_submenu
;
267 static IPTR
menudecor__OM_NEW(Class
*cl
, Object
*obj
, struct opSet
*msg
)
269 struct menudecor_data
*data
;
271 D(bug("menudecor__OM_NEW(tags @ 0x%p)\n", msg
->ops_AttrList
));
273 obj
= (Object
*)DoSuperMethodA(cl
, obj
, (Msg
)msg
);
276 data
= INST_DATA(cl
, obj
);
278 struct DecorImages
* di
= (struct DecorImages
*) GetTagData(MDA_DecorImages
, (IPTR
) NULL
, msg
->ops_AttrList
);
279 struct DecorConfig
* dc
= (struct DecorConfig
*) GetTagData(MDA_DecorConfig
, (IPTR
) NULL
, msg
->ops_AttrList
);
281 D(bug("menudecor__OM_NEW: DecorImages @ 0x%p\n", di
));
282 D(bug("menudecor__OM_NEW: DecorConfig @ 0x%p\n", dc
));
284 if (!InitMenuSkinning(data
, di
, dc
))
286 CoerceMethod(cl
, obj
,OM_DISPOSE
);
294 static IPTR
menudecor__OM_DISPOSE(Class
*cl
, Object
*obj
, struct opSet
*msg
)
296 struct menudecor_data
*data
= INST_DATA(cl
, obj
);
298 DisposeMenuSkinning(data
);
300 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
303 static IPTR
menudecor_dispatcher(struct IClass
*cl
, Object
*obj
, Msg msg
)
307 switch(msg
->MethodID
)
310 retval
= menudecor__OM_NEW(cl
, obj
, (struct opSet
*) msg
);
314 retval
= menudecor__OM_DISPOSE(cl
, obj
, (struct opSet
*) msg
);
317 case MDM_DRAW_SYSIMAGE
:
318 retval
= menudecor_draw_sysimage(cl
, obj
, (struct mdpDrawSysImage
*)msg
);
321 case MDM_GETDEFSIZE_SYSIMAGE
:
322 retval
= menudecor_getdefsizes(cl
, obj
, (struct mdpGetDefSizeSysImage
*) msg
);
325 case MDM_DRAWBACKGROUND
:
326 retval
= menudecor_renderbackground(cl
, obj
, (struct mdpDrawBackground
*)msg
);
330 retval
= menudecor_initmenu(cl
, obj
, (struct mdpInitMenu
*)msg
);
334 retval
= menudecor_exitmenu(cl
, obj
, (struct mdpExitMenu
*)msg
);
337 case MDM_GETMENUSPACES
:
338 retval
= menudecor_getmenuspaces(cl
, obj
, (struct mdpGetMenuSpaces
*)msg
);
342 retval
= DoSuperMethodA(cl
, obj
, msg
);
349 struct IClass
* MakeMenuDecorClass()
351 struct IClass
* cl
= MakeClass(NULL
, MENUDECORCLASS
, NULL
, sizeof(struct menudecor_data
), 0);
354 cl
->cl_Dispatcher
.h_Entry
= HookEntry
;
355 cl
->cl_Dispatcher
.h_SubEntry
= (HOOKFUNC
)menudecor_dispatcher
;