2 Copyright © 2002-2007, The AROS Development Team. All rights reserved.
6 #include <exec/memory.h>
7 #include <intuition/icclass.h>
8 #include <intuition/gadgetclass.h>
9 #include <libraries/gadtools.h>
10 #include <clib/alib_protos.h>
11 #include <proto/exec.h>
12 #include <proto/intuition.h>
13 #include <proto/utility.h>
14 #include <proto/muimaster.h>
16 /* #define MYDEBUG 1 */
19 #include "muimaster_intern.h"
22 extern struct Library
*MUIMasterBase
;
24 #define MENUF_CHECKED (1<<0)
25 #define MENUF_CHECKIT (1<<1)
26 #define MENUF_COMMANDSTRING (1<<2)
27 #define MENUF_ENABLED (1<<3)
28 #define MENUF_TOGGLE (1<<4)
30 struct MUI_MenuitemData
38 struct NewMenu
*newmenu
;
40 struct MenuItem
*trigger
;
43 static int Menuitem_GetTotalChildren(Object
*obj
)
47 struct MinList
*ChildList
;
50 get(obj
, MUIA_Family_List
, &ChildList
);
51 cstate
= (Object
*)ChildList
->mlh_Head
;
52 while ((child
= NextObject(&cstate
)))
55 num
+= Menuitem_GetTotalChildren(child
);
60 static int Menuitem_FillNewMenu(Object
*obj
, struct NewMenu
*menu
, int depth
)
64 struct MinList
*ChildList
;
67 if (depth
> 2) return 0;
69 get(obj
, MUIA_Family_List
, &ChildList
);
70 cstate
= (Object
*)ChildList
->mlh_Head
;
71 while ((child
= NextObject(&cstate
)))
74 ULONG checkit
= 0, checked
= 0, toggle
= 0, enabled
= 0;
76 get(child
, MUIA_Menuitem_Title
, &menu
->nm_Label
);
77 get(child
, MUIA_Menuitem_Shortcut
, &menu
->nm_CommKey
);
78 get(child
, MUIA_Menuitem_Checkit
, &checkit
);
79 get(child
, MUIA_Menuitem_Checked
, &checked
);
80 get(child
, MUIA_Menuitem_Toggle
, &toggle
);
81 get(child
, MUIA_Menuitem_Enabled
, &enabled
);
82 if (checkit
) menu
->nm_Flags
|= CHECKIT
;
83 if (checked
) menu
->nm_Flags
|= CHECKED
;
84 if (toggle
) menu
->nm_Flags
|= MENUTOGGLE
;
85 get(child
, MUIA_Menuitem_Exclude
, &menu
->nm_MutualExclude
);
89 menu
->nm_Type
= NM_TITLE
;
90 if ( ! enabled
) menu
->nm_Flags
|= NM_MENUDISABLED
;
94 menu
->nm_Type
= NM_ITEM
;
95 if ( ! enabled
) menu
->nm_Flags
|= NM_ITEMDISABLED
;
99 menu
->nm_Type
= NM_SUB
;
100 if ( ! enabled
) menu
->nm_Flags
|= NM_ITEMDISABLED
;
103 menu
->nm_UserData
= child
;
107 entries
= Menuitem_FillNewMenu(child
,menu
,depth
+1);
115 /**************************************************************************
117 **************************************************************************/
118 static struct NewMenu
*Menuitem_BuildNewMenu(struct MUI_MenuitemData
*data
, Object
*obj
)
120 int entries
= Menuitem_GetTotalChildren(obj
);
121 if (data
->newmenu
) FreeVec(data
->newmenu
);
122 data
->newmenu
= NULL
;
123 if (!entries
) return NULL
;
125 if ((data
->newmenu
= (struct NewMenu
*)AllocVec((entries
+1)*sizeof(struct NewMenu
),MEMF_CLEAR
)))
127 Menuitem_FillNewMenu(obj
,data
->newmenu
,0);
129 return data
->newmenu
;
132 /**************************************************************************
134 **************************************************************************/
135 IPTR
Menuitem__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
137 struct MUI_MenuitemData
*data
;
138 struct TagItem
*tags
,*tag
;
140 obj
= (Object
*)DoSuperMethodA(cl
, obj
, (Msg
)msg
); /* We need no tags */
143 data
= INST_DATA(cl
, obj
);
145 data
->flags
= MENUF_ENABLED
;
147 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem((const struct TagItem
**)&tags
)); )
151 case MUIA_Menuitem_Checked
:
152 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MENUF_CHECKED
);
155 case MUIA_Menuitem_Checkit
:
156 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MENUF_CHECKIT
);
159 case MUIA_Menuitem_CommandString
:
160 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MENUF_COMMANDSTRING
);
163 case MUIA_Menu_Enabled
:
164 case MUIA_Menuitem_Enabled
:
165 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MENUF_ENABLED
);
168 case MUIA_Menuitem_Toggle
:
169 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MENUF_TOGGLE
);
172 case MUIA_Menuitem_Exclude
:
173 data
->exclude
= tag
->ti_Data
;
176 case MUIA_Menuitem_Shortcut
:
177 data
->shortcut
= (char*)tag
->ti_Data
;
180 case MUIA_Menu_Title
:
181 case MUIA_Menuitem_Title
:
182 data
->title
= (char*)tag
->ti_Data
;
190 /**************************************************************************
192 **************************************************************************/
193 IPTR
Menuitem__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
195 struct MUI_MenuitemData
*data
;
196 struct TagItem
*tags
,*tag
;
198 data
= INST_DATA(cl
, obj
);
200 BOOL rebuild
= FALSE
;
202 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem((const struct TagItem
**)&tags
)); )
206 case MUIA_Menuitem_Checked
:
207 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MENUF_CHECKED
);
208 if (data
->exclude
&& (data
->flags
& MENUF_CHECKED
))
211 get(obj
, MUIA_Parent
, &parent
);
217 struct MinList
*ChildList
;
220 get(parent
, MUIA_Family_List
, &ChildList
);
221 cstate
= (Object
*)ChildList
->mlh_Head
;
222 while ((child
= NextObject(&cstate
)))
224 if ((i
& data
->exclude
) && (child
!= obj
))
226 IPTR checkit
, checked
;
228 get(child
, MUIA_Menuitem_Checkit
, &checkit
);
229 get(child
, MUIA_Menuitem_Checked
, &checked
);
231 if (checkit
&& checked
)
233 set(child
, MUIA_Menuitem_Checked
, FALSE
);
245 case MUIA_Menuitem_Checkit
:
246 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MENUF_CHECKIT
);
250 case MUIA_Menuitem_CommandString
:
251 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MENUF_COMMANDSTRING
);
255 case MUIA_Menu_Enabled
:
256 case MUIA_Menuitem_Enabled
:
257 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MENUF_ENABLED
);
258 tag
->ti_Tag
= TAG_IGNORE
;
262 case MUIA_Menuitem_Toggle
:
263 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MENUF_TOGGLE
);
267 case MUIA_Menuitem_Exclude
:
268 data
->exclude
= tag
->ti_Data
;
272 case MUIA_Menuitem_Shortcut
:
273 data
->shortcut
= (char*)tag
->ti_Data
;
277 case MUIA_Menu_Title
:
278 case MUIA_Menuitem_Title
:
279 data
->title
= (char*)tag
->ti_Data
;
280 tag
->ti_Tag
= TAG_IGNORE
;
284 case MUIA_Menuitem_Trigger
:
285 data
->trigger
= (struct MenuItem
*)tag
->ti_Data
;
295 muiNotifyData(obj
) &&
296 muiNotifyData(obj
)->mnd_GlobalInfo
&&
297 muiNotifyData(obj
)->mnd_GlobalInfo
->mgi_ApplicationObject
300 DoMethod(_app(obj
), MUIM_Application_UpdateMenus
);
304 return DoSuperMethodA(cl
,obj
,(Msg
)msg
);
307 /**************************************************************************
309 **************************************************************************/
310 #define STORE *(msg->opg_Storage)
311 IPTR
Menuitem__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
313 struct MUI_MenuitemData
*data
= INST_DATA(cl
, obj
);
315 switch (msg
->opg_AttrID
)
317 case MUIA_Menuitem_Checked
:
318 STORE
= ((data
->flags
& MENUF_CHECKED
) != 0);
321 case MUIA_Menuitem_Checkit
:
322 STORE
= ((data
->flags
& MENUF_CHECKIT
) != 0);
325 case MUIA_Menuitem_CommandString
:
326 STORE
= ((data
->flags
& MENUF_COMMANDSTRING
) != 0);
329 case MUIA_Menu_Enabled
:
330 case MUIA_Menuitem_Enabled
:
331 STORE
= ((data
->flags
& MENUF_ENABLED
) != 0);
334 case MUIA_Menuitem_Toggle
:
335 STORE
= ((data
->flags
& MENUF_TOGGLE
) != 0);
338 case MUIA_Menuitem_Exclude
:
339 STORE
= data
->exclude
;
342 case MUIA_Menuitem_Shortcut
:
343 STORE
= (IPTR
)data
->shortcut
;
346 case MUIA_Menu_Title
:
347 case MUIA_Menuitem_Title
:
348 STORE
= (IPTR
)data
->title
;
351 case MUIA_Menuitem_NewMenu
:
352 Menuitem_BuildNewMenu(data
,obj
);
353 STORE
= (IPTR
)data
->newmenu
;
356 case MUIA_Menuitem_Trigger
:
357 STORE
= (IPTR
)data
->trigger
;
361 return DoSuperMethodA(cl
,obj
,(Msg
)msg
);
366 /**************************************************************************
368 **************************************************************************/
369 IPTR
Menuitem__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
371 struct MUI_MenuitemData
*data
= INST_DATA(cl
, obj
);
373 FreeVec(data
->newmenu
);
375 return DoSuperMethodA(cl
, obj
, msg
);
379 /**************************************************************************
381 **************************************************************************/
382 IPTR
Menuitem__MUIM_ConnectParent(struct IClass
*cl
, Object
*obj
, struct MUIP_ConnectParent
*msg
)
386 struct MinList
*ChildList
;
388 D(bug("Menuitem_ConnectParent(%p) %s\n", obj
, OCLASS(obj
)->cl_ID
));
390 DoSuperMethodA(cl
,obj
,(Msg
)msg
);
392 muiNotifyData(obj
)->mnd_ParentObject
= msg
->parent
;
394 get(obj
, MUIA_Family_List
, &ChildList
);
395 cstate
= (Object
*)ChildList
->mlh_Head
;
396 while ((child
= NextObject(&cstate
)))
398 DoMethod(child
, MUIM_ConnectParent
, (IPTR
)obj
);
403 /**************************************************************************
404 MUIM_DisconnectParent
405 **************************************************************************/
406 IPTR
Menuitem__MUIM_DisconnectParent(struct IClass
*cl
, Object
*obj
, struct MUIP_ConnectParent
*msg
)
410 struct MinList
*ChildList
;
412 D(bug("Menuitem_DisconnectParent(%p) %s\n", obj
, OCLASS(obj
)->cl_ID
));
414 get(obj
, MUIA_Family_List
, &ChildList
);
415 cstate
= (Object
*)ChildList
->mlh_Head
;
416 while ((child
= NextObject(&cstate
)))
418 DoMethodA(child
, (Msg
)msg
);
420 muiNotifyData(obj
)->mnd_ParentObject
= NULL
;
421 DoSuperMethodA(cl
,obj
,(Msg
)msg
);
425 BOOPSI_DISPATCHER(IPTR
, Menuitem_Dispatcher
, cl
, obj
, msg
)
427 switch (msg
->MethodID
)
429 case OM_NEW
: return Menuitem__OM_NEW(cl
, obj
, (struct opSet
*) msg
);
430 case OM_DISPOSE
: return Menuitem__OM_DISPOSE(cl
, obj
, msg
);
431 case OM_SET
: return Menuitem__OM_SET(cl
, obj
, (struct opSet
*) msg
);
432 case OM_GET
: return Menuitem__OM_GET(cl
, obj
, (struct opGet
*) msg
);
433 case MUIM_ConnectParent
: return Menuitem__MUIM_ConnectParent(cl
, obj
, (APTR
)msg
);
434 case MUIM_DisconnectParent
: return Menuitem__MUIM_DisconnectParent(cl
, obj
, (APTR
)msg
);
436 return DoSuperMethodA(cl
, obj
, msg
);
438 BOOPSI_DISPATCHER_END
444 const struct __MUIBuiltinClass _MUI_Menuitem_desc
= {
447 sizeof(struct MUI_MenuitemData
),
448 (void*)Menuitem_Dispatcher
452 * Class descriptor.- this class is the same like menuitem
454 const struct __MUIBuiltinClass _MUI_Menu_desc
= {
457 sizeof(struct MUI_MenuitemData
),
458 (void*)Menuitem_Dispatcher
462 * Class descriptor.- this class is the same like menuitem
464 const struct __MUIBuiltinClass _MUI_Menustrip_desc
= {
467 sizeof(struct MUI_MenuitemData
),
468 (void*)Menuitem_Dispatcher