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
= NULL
;
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
,
65 struct MinList
*ChildList
= NULL
;
71 get(obj
, MUIA_Family_List
, &ChildList
);
72 cstate
= (Object
*) ChildList
->mlh_Head
;
73 while ((child
= NextObject(&cstate
)))
76 ULONG checkit
= 0, checked
= 0, toggle
= 0, enabled
= 0;
78 get(child
, MUIA_Menuitem_Title
, &menu
->nm_Label
);
79 get(child
, MUIA_Menuitem_Shortcut
, &menu
->nm_CommKey
);
80 get(child
, MUIA_Menuitem_Checkit
, &checkit
);
81 get(child
, MUIA_Menuitem_Checked
, &checked
);
82 get(child
, MUIA_Menuitem_Toggle
, &toggle
);
83 get(child
, MUIA_Menuitem_Enabled
, &enabled
);
85 menu
->nm_Flags
|= CHECKIT
;
87 menu
->nm_Flags
|= CHECKED
;
89 menu
->nm_Flags
|= MENUTOGGLE
;
90 get(child
, MUIA_Menuitem_Exclude
, &menu
->nm_MutualExclude
);
94 menu
->nm_Type
= NM_TITLE
;
96 menu
->nm_Flags
|= NM_MENUDISABLED
;
100 menu
->nm_Type
= NM_ITEM
;
102 menu
->nm_Flags
|= NM_ITEMDISABLED
;
106 menu
->nm_Type
= NM_SUB
;
108 menu
->nm_Flags
|= NM_ITEMDISABLED
;
111 menu
->nm_UserData
= child
;
115 entries
= Menuitem_FillNewMenu(child
, menu
, depth
+ 1);
123 /**************************************************************************
125 **************************************************************************/
126 static struct NewMenu
*Menuitem_BuildNewMenu(struct MUI_MenuitemData
*data
,
129 int entries
= Menuitem_GetTotalChildren(obj
);
131 FreeVec(data
->newmenu
);
132 data
->newmenu
= NULL
;
137 (struct NewMenu
*)AllocVec((entries
+
138 1) * sizeof(struct NewMenu
), MEMF_CLEAR
)))
140 Menuitem_FillNewMenu(obj
, data
->newmenu
, 0);
142 return data
->newmenu
;
145 /**************************************************************************
147 **************************************************************************/
148 IPTR
Menuitem__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
150 struct MUI_MenuitemData
*data
;
151 struct TagItem
*tags
, *tag
;
153 obj
= (Object
*) DoSuperMethodA(cl
, obj
, (Msg
) msg
);
154 /* We need no tags */
158 data
= INST_DATA(cl
, obj
);
160 data
->flags
= MENUF_ENABLED
;
162 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
166 case MUIA_Menuitem_Checked
:
167 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MENUF_CHECKED
);
170 case MUIA_Menuitem_Checkit
:
171 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MENUF_CHECKIT
);
174 case MUIA_Menuitem_CommandString
:
175 _handle_bool_tag(data
->flags
, tag
->ti_Data
,
176 MENUF_COMMANDSTRING
);
179 case MUIA_Menu_Enabled
:
180 case MUIA_Menuitem_Enabled
:
181 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MENUF_ENABLED
);
184 case MUIA_Menuitem_Toggle
:
185 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MENUF_TOGGLE
);
188 case MUIA_Menuitem_Exclude
:
189 data
->exclude
= tag
->ti_Data
;
192 case MUIA_Menuitem_Shortcut
:
193 data
->shortcut
= (char *)tag
->ti_Data
;
196 case MUIA_Menu_Title
:
197 case MUIA_Menuitem_Title
:
198 data
->title
= (char *)tag
->ti_Data
;
206 /**************************************************************************
208 **************************************************************************/
209 IPTR
Menuitem__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
211 struct MUI_MenuitemData
*data
;
212 struct TagItem
*tags
, *tag
;
214 data
= INST_DATA(cl
, obj
);
216 BOOL rebuild
= FALSE
;
218 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
222 case MUIA_Menuitem_Checked
:
223 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MENUF_CHECKED
);
224 if (data
->exclude
&& (data
->flags
& MENUF_CHECKED
))
226 Object
*parent
= NULL
;
227 get(obj
, MUIA_Parent
, &parent
);
233 struct MinList
*ChildList
= NULL
;
236 get(parent
, MUIA_Family_List
, &ChildList
);
237 cstate
= (Object
*) ChildList
->mlh_Head
;
238 while ((child
= NextObject(&cstate
)))
240 if ((i
& data
->exclude
) && (child
!= obj
))
242 IPTR checkit
= 0, checked
= 0;
244 get(child
, MUIA_Menuitem_Checkit
, &checkit
);
245 get(child
, MUIA_Menuitem_Checked
, &checked
);
247 if (checkit
&& checked
)
249 set(child
, MUIA_Menuitem_Checked
, FALSE
);
261 case MUIA_Menuitem_Checkit
:
262 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MENUF_CHECKIT
);
266 case MUIA_Menuitem_CommandString
:
267 _handle_bool_tag(data
->flags
, tag
->ti_Data
,
268 MENUF_COMMANDSTRING
);
272 case MUIA_Menu_Enabled
:
273 case MUIA_Menuitem_Enabled
:
274 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MENUF_ENABLED
);
275 tag
->ti_Tag
= TAG_IGNORE
;
279 case MUIA_Menuitem_Toggle
:
280 _handle_bool_tag(data
->flags
, tag
->ti_Data
, MENUF_TOGGLE
);
284 case MUIA_Menuitem_Exclude
:
285 data
->exclude
= tag
->ti_Data
;
289 case MUIA_Menuitem_Shortcut
:
290 data
->shortcut
= (char *)tag
->ti_Data
;
294 case MUIA_Menu_Title
:
295 case MUIA_Menuitem_Title
:
296 data
->title
= (char *)tag
->ti_Data
;
297 tag
->ti_Tag
= TAG_IGNORE
;
301 case MUIA_Menuitem_Trigger
:
302 data
->trigger
= (struct MenuItem
*)tag
->ti_Data
;
310 if (muiNotifyData(obj
) &&
311 muiNotifyData(obj
)->mnd_GlobalInfo
&&
312 muiNotifyData(obj
)->mnd_GlobalInfo
->mgi_ApplicationObject
)
314 DoMethod(_app(obj
), MUIM_Application_UpdateMenus
);
318 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
321 /**************************************************************************
323 **************************************************************************/
324 #define STORE *(msg->opg_Storage)
325 IPTR
Menuitem__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
327 struct MUI_MenuitemData
*data
= INST_DATA(cl
, obj
);
329 switch (msg
->opg_AttrID
)
331 case MUIA_Menuitem_Checked
:
332 STORE
= ((data
->flags
& MENUF_CHECKED
) != 0);
335 case MUIA_Menuitem_Checkit
:
336 STORE
= ((data
->flags
& MENUF_CHECKIT
) != 0);
339 case MUIA_Menuitem_CommandString
:
340 STORE
= ((data
->flags
& MENUF_COMMANDSTRING
) != 0);
343 case MUIA_Menu_Enabled
:
344 case MUIA_Menuitem_Enabled
:
345 STORE
= ((data
->flags
& MENUF_ENABLED
) != 0);
348 case MUIA_Menuitem_Toggle
:
349 STORE
= ((data
->flags
& MENUF_TOGGLE
) != 0);
352 case MUIA_Menuitem_Exclude
:
353 STORE
= data
->exclude
;
356 case MUIA_Menuitem_Shortcut
:
357 STORE
= (IPTR
) data
->shortcut
;
360 case MUIA_Menu_Title
:
361 case MUIA_Menuitem_Title
:
362 STORE
= (IPTR
) data
->title
;
365 case MUIA_Menuitem_NewMenu
:
366 Menuitem_BuildNewMenu(data
, obj
);
367 STORE
= (IPTR
) data
->newmenu
;
370 case MUIA_Menuitem_Trigger
:
371 STORE
= (IPTR
) data
->trigger
;
375 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
380 /**************************************************************************
382 **************************************************************************/
383 IPTR
Menuitem__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
385 struct MUI_MenuitemData
*data
= INST_DATA(cl
, obj
);
387 FreeVec(data
->newmenu
);
389 return DoSuperMethodA(cl
, obj
, msg
);
393 /**************************************************************************
395 **************************************************************************/
396 IPTR
Menuitem__MUIM_ConnectParent(struct IClass
*cl
, Object
*obj
,
397 struct MUIP_ConnectParent
*msg
)
401 struct MinList
*ChildList
= NULL
;
403 D(bug("Menuitem_ConnectParent(%p) %s\n", obj
, OCLASS(obj
)->cl_ID
));
405 DoSuperMethodA(cl
, obj
, (Msg
) msg
);
407 muiNotifyData(obj
)->mnd_ParentObject
= msg
->parent
;
409 get(obj
, MUIA_Family_List
, &ChildList
);
410 cstate
= (Object
*) ChildList
->mlh_Head
;
411 while ((child
= NextObject(&cstate
)))
413 DoMethod(child
, MUIM_ConnectParent
, (IPTR
) obj
);
418 /**************************************************************************
419 MUIM_DisconnectParent
420 **************************************************************************/
421 IPTR
Menuitem__MUIM_DisconnectParent(struct IClass
*cl
, Object
*obj
,
422 struct MUIP_ConnectParent
*msg
)
426 struct MinList
*ChildList
= NULL
;
428 D(bug("Menuitem_DisconnectParent(%p) %s\n", obj
, OCLASS(obj
)->cl_ID
));
430 get(obj
, MUIA_Family_List
, &ChildList
);
431 cstate
= (Object
*) ChildList
->mlh_Head
;
432 while ((child
= NextObject(&cstate
)))
434 DoMethodA(child
, (Msg
) msg
);
436 muiNotifyData(obj
)->mnd_ParentObject
= NULL
;
437 DoSuperMethodA(cl
, obj
, (Msg
) msg
);
441 /**************************************************************************
442 MUIM_Family_Insert, MUIM_Family_Remove
443 **************************************************************************/
444 IPTR
Menuitem__MUIM_Update(struct IClass
*cl
, Object
*obj
, Msg msg
)
446 // struct MUI_MenuitemData *data = INST_DATA(cl, obj);
448 IPTR retval
= DoSuperMethodA(cl
, obj
, msg
);
450 if (muiNotifyData(obj
) &&
451 muiNotifyData(obj
)->mnd_GlobalInfo
&&
452 muiNotifyData(obj
)->mnd_GlobalInfo
->mgi_ApplicationObject
)
454 DoMethod(_app(obj
), MUIM_Application_UpdateMenus
);
461 BOOPSI_DISPATCHER(IPTR
, Menuitem_Dispatcher
, cl
, obj
, msg
)
463 switch (msg
->MethodID
)
466 return Menuitem__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
468 return Menuitem__OM_DISPOSE(cl
, obj
, msg
);
470 return Menuitem__OM_SET(cl
, obj
, (struct opSet
*)msg
);
472 return Menuitem__OM_GET(cl
, obj
, (struct opGet
*)msg
);
473 case MUIM_ConnectParent
:
474 return Menuitem__MUIM_ConnectParent(cl
, obj
, (APTR
) msg
);
475 case MUIM_DisconnectParent
:
476 return Menuitem__MUIM_DisconnectParent(cl
, obj
, (APTR
) msg
);
477 case MUIM_Family_Insert
:
478 return Menuitem__MUIM_Update(cl
, obj
, (APTR
) msg
);
479 case MUIM_Family_Remove
:
480 return Menuitem__MUIM_Update(cl
, obj
, (APTR
) msg
);
481 case MUIM_Family_AddTail
:
482 return Menuitem__MUIM_Update(cl
, obj
, (APTR
) msg
);
483 case MUIM_Family_AddHead
:
484 return Menuitem__MUIM_Update(cl
, obj
, (APTR
) msg
);
486 return Menuitem__MUIM_Update(cl
, obj
, (APTR
) msg
);
488 return Menuitem__MUIM_Update(cl
, obj
, (APTR
) msg
);
490 return DoSuperMethodA(cl
, obj
, msg
);
492 BOOPSI_DISPATCHER_END
497 const struct __MUIBuiltinClass _MUI_Menuitem_desc
=
501 sizeof(struct MUI_MenuitemData
),
502 (void *) Menuitem_Dispatcher
506 * Class descriptor.- this class is the same like menuitem
508 const struct __MUIBuiltinClass _MUI_Menu_desc
=
512 sizeof(struct MUI_MenuitemData
),
513 (void *) Menuitem_Dispatcher
517 * Class descriptor.- this class is the same like menuitem
519 const struct __MUIBuiltinClass _MUI_Menustrip_desc
=
523 sizeof(struct MUI_MenuitemData
),
524 (void *) Menuitem_Dispatcher