Tabs to spaces, more consistent formatting.
[AROS.git] / workbench / libs / muimaster / classes / boopsi.c
blob01c807ce01b5a8e3b67668cd688e8c0b5be29d7a
1 /*
2 Copyright © 2002-2003, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define MUIMASTER_YES_INLINE_STDARG
8 #include <exec/memory.h>
9 #include <intuition/icclass.h>
10 #include <intuition/gadgetclass.h>
11 #include <clib/alib_protos.h>
12 #include <proto/exec.h>
13 #include <proto/intuition.h>
14 #include <proto/utility.h>
15 #include <proto/muimaster.h>
17 #include "debug.h"
18 #include "mui.h"
19 #include "support_classes.h"
20 #include "muimaster_intern.h"
21 #include "boopsi_private.h"
23 extern struct Library *MUIMasterBase;
25 IPTR Boopsi__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
27 struct Boopsi_DATA *data;
28 struct TagItem *tags, *tag;
30 obj = (Object *) DoSuperNewTags(cl, obj, NULL,
31 MUIA_FillArea, FALSE, TAG_MORE, (IPTR) msg->ops_AttrList);
32 if (!obj)
33 return FALSE;
35 data = INST_DATA(cl, obj);
37 data->boopsi_taglist = CloneTagItems(msg->ops_AttrList);
38 data->boopsi_maxwidth = data->boopsi_maxheight = MUI_MAXMAX;
40 /* parse initial taglist */
41 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags));)
43 switch (tag->ti_Tag)
45 case MUIA_Boopsi_Class:
46 data->boopsi_class = (struct IClass *)tag->ti_Data;
47 break;
49 case MUIA_Boopsi_ClassID:
50 data->boopsi_classid = (char *)tag->ti_Data;
51 break;
53 case MUIA_Boopsi_MaxHeight:
54 data->boopsi_minwidth = tag->ti_Data;
55 break;
57 case MUIA_Boopsi_MaxWidth:
58 data->boopsi_maxwidth = tag->ti_Data;
59 break;
61 case MUIA_Boopsi_MinHeight:
62 data->boopsi_minheight = tag->ti_Data;
63 break;
65 case MUIA_Boopsi_MinWidth:
66 data->boopsi_minwidth = tag->ti_Data;
67 break;
69 case MUIA_Boopsi_Remember:
71 struct TagItem *new_remember;
72 if ((new_remember = AllocVec(sizeof(struct TagItem)
73 * (data->remember_len + 2), MEMF_CLEAR)))
74 /* +2 because of the TAG_DONE */
76 if (data->remember)
77 CopyMem(data->remember, new_remember,
78 sizeof(struct TagItem) * data->remember_len);
79 new_remember[data->remember_len].ti_Tag = tag->ti_Data;
80 if (data->remember)
81 FreeVec(data->remember);
82 data->remember = new_remember;
83 data->remember_len++;
86 break;
88 case MUIA_Boopsi_Smart:
89 data->boopsi_smart = tag->ti_Data;
90 break;
92 case MUIA_Boopsi_TagDrawInfo:
93 data->boopsi_tagdrawinfo = tag->ti_Data;
94 break;
96 case MUIA_Boopsi_TagScreen:
97 data->boopsi_tagscreen = tag->ti_Data;
98 break;
100 case MUIA_Boopsi_TagWindow:
101 data->boopsi_tagwindow = tag->ti_Data;
102 break;
107 /* Now fill in the initial remember tag datas in our remember tag list */
108 for (tags = data->remember; (tag = NextTagItem(&tags));)
110 struct TagItem *set_tag =
111 FindTagItem(tag->ti_Tag, msg->ops_AttrList);
112 if (set_tag)
113 tag->ti_Data = set_tag->ti_Data;
116 data->ehn.ehn_Events = IDCMP_IDCMPUPDATE;
117 data->ehn.ehn_Priority = 0;
118 data->ehn.ehn_Flags = 0;
119 data->ehn.ehn_Object = obj;
120 data->ehn.ehn_Class = cl;
122 return (IPTR) obj;
125 IPTR Boopsi__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
127 struct Boopsi_DATA *data = INST_DATA(cl, obj);
129 if (data->boopsi_taglist)
130 FreeTagItems(data->boopsi_taglist);
131 if (data->remember)
132 FreeVec(data->remember);
133 return DoSuperMethodA(cl, obj, msg);
136 IPTR Boopsi__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
138 struct TagItem *tags, *tag;
139 struct Boopsi_DATA *data = INST_DATA(cl, obj);
140 int only_trigger = 0;
141 int no_notify = 0;
143 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags));)
145 switch (tag->ti_Tag)
147 case MUIA_Boopsi_Class:
148 data->boopsi_class = (struct IClass *)tag->ti_Data;
149 break;
151 case MUIA_Boopsi_ClassID:
152 data->boopsi_classid = (char *)tag->ti_Data;
153 break;
155 case MUIA_Boopsi_MaxHeight:
156 data->boopsi_minwidth = tag->ti_Data;
157 break;
159 case MUIA_Boopsi_MaxWidth:
160 data->boopsi_maxwidth = tag->ti_Data;
161 break;
163 case MUIA_Boopsi_MinHeight:
164 data->boopsi_minheight = tag->ti_Data;
165 break;
167 case MUIA_Boopsi_MinWidth:
168 data->boopsi_minwidth = tag->ti_Data;
169 break;
171 case MUIA_Boopsi_TagDrawInfo:
172 data->boopsi_tagdrawinfo = tag->ti_Data;
173 break;
175 case MUIA_Boopsi_TagScreen:
176 data->boopsi_tagscreen = tag->ti_Data;
177 break;
179 case MUIA_Boopsi_TagWindow:
180 data->boopsi_tagwindow = tag->ti_Data;
181 break;
183 case MUIA_Boopsi_OnlyTrigger:
184 only_trigger = 1;
185 break;
187 case MUIA_NoNotify:
188 no_notify = tag->ti_Data;
189 break;
193 /* Now fill in remember list tag datas in our remember tag list */
194 for (tags = data->remember; (tag = NextTagItem(&tags));)
196 struct TagItem *set_tag =
197 FindTagItem(tag->ti_Tag, msg->ops_AttrList);
198 if (set_tag)
199 tag->ti_Data = set_tag->ti_Data;
202 if (!only_trigger)
204 if (data->boopsi_object)
206 /* Rendering will happen here!! This could make problems with
207 * virtual groups, forward this to MUIM_Draw??? */
208 if (no_notify)
209 SetAttrs(data->boopsi_object, ICA_TARGET, NULL, TAG_DONE);
210 if (SetGadgetAttrsA((struct Gadget *)data->boopsi_object,
211 _window(obj), NULL, msg->ops_AttrList))
212 RefreshGList((struct Gadget *)data->boopsi_object,
213 _window(obj), NULL, 1);
214 if (no_notify)
215 SetAttrs(data->boopsi_object, ICA_TARGET, ICTARGET_IDCMP,
216 TAG_DONE);
220 return DoSuperMethodA(cl, obj, (Msg) msg);
224 #define STORE *(msg->opg_Storage)
225 IPTR Boopsi__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
227 struct Boopsi_DATA *data = INST_DATA(cl, obj);
229 switch (msg->opg_AttrID)
231 case MUIA_Boopsi_Object:
232 STORE = (IPTR) data->boopsi_object;
234 default:
236 struct TagItem *tags, *tag;
238 /* look in the rember list first */
239 for (tags = data->remember; (tag = NextTagItem(&tags));)
241 if (tag->ti_Tag == msg->opg_AttrID)
243 if (data->boopsi_object)
245 /* Call the get method of the boopsi object
246 * and update the remember list */
247 IPTR val;
249 if (GetAttr(msg->opg_AttrID, data->boopsi_object,
250 &val))
251 tag->ti_Data = val;
254 STORE = tag->ti_Data;
255 return 1;
259 /* The id is not in the attr list, so we try the boopsi object
260 * first (fills in the msg then) */
261 if (data->boopsi_object)
263 IPTR val;
265 if (GetAttr(msg->opg_AttrID, data->boopsi_object, &val))
267 STORE = val;
268 return 1;
272 /* No success so we try the superclass */
273 return DoSuperMethodA(cl, obj, (Msg) msg);
277 return 1;
279 #undef STORE
281 IPTR Boopsi__MUIM_AskMinMax(struct IClass *cl, Object *obj,
282 struct MUIP_AskMinMax *msg)
284 struct Boopsi_DATA *data = INST_DATA(cl, obj);
287 ** let our superclass first fill in what it thinks about sizes.
288 ** this will e.g. add the size of frame and inner spacing.
290 DoSuperMethodA(cl, obj, (Msg) msg);
292 msg->MinMaxInfo->MinWidth += data->boopsi_minwidth;
293 msg->MinMaxInfo->MinHeight += data->boopsi_minheight;
294 msg->MinMaxInfo->DefWidth += data->boopsi_minwidth;
295 msg->MinMaxInfo->DefHeight += data->boopsi_minheight;
296 msg->MinMaxInfo->MaxWidth += data->boopsi_maxwidth;
297 msg->MinMaxInfo->MaxHeight += data->boopsi_maxheight;
298 return TRUE;
301 IPTR Boopsi__MUIM_Setup(struct IClass *cl, Object *obj,
302 struct MUIP_Setup *msg)
304 struct Boopsi_DATA *data = INST_DATA(cl, obj);
305 IPTR rc = DoSuperMethodA(cl, obj, (Msg) msg);
306 if (!rc)
307 return 0;
309 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR) & data->ehn);
311 return 1;
314 IPTR Boopsi__MUIM_Cleanup(struct IClass *cl, Object *obj,
315 struct MUIP_Cleanup *msg)
317 struct Boopsi_DATA *data = INST_DATA(cl, obj);
318 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR) & data->ehn);
319 return DoSuperMethodA(cl, obj, (Msg) msg);
322 IPTR Boopsi__MUIM_Show(struct IClass *cl, Object *obj,
323 struct MUIP_Show *msg)
325 struct Boopsi_DATA *data = INST_DATA(cl, obj);
326 IPTR rc = DoSuperMethodA(cl, obj, (Msg) msg);
327 struct TagItem *tag;
328 BOOL completely_visible = TRUE;
330 D(bug("boopsi_show: obj coord %d,%d - %d,%d\n",
331 _mleft(obj), _mtop(obj), _mright(obj), _mbottom(obj)));
333 if (_flags(obj) & MADF_INVIRTUALGROUP)
335 Object *wnd = NULL, *parent;
337 get(obj, MUIA_WindowObject, &wnd);
338 parent = obj;
339 while (get(parent, MUIA_Parent, &parent))
341 if (!parent)
342 break;
343 if (parent == wnd)
344 break;
346 if (_flags(parent) & MADF_ISVIRTUALGROUP)
348 if ((_mleft(obj) < _mleft(parent)) ||
349 (_mright(obj) > _mright(parent)) ||
350 (_mtop(obj) < _mtop(parent)) ||
351 (_mbottom(obj) > _mbottom(parent)))
353 completely_visible = FALSE;
354 D(bug("=== boopsi object: completely visible FALSE "
355 "for obj %x at %d,%d - %d,%d\n",
356 obj, _mleft(obj), _mtop(obj), _mright(obj),
357 _mbottom(obj)));
358 break;
364 if (completely_visible)
366 if ((tag = FindTagItem(GA_Left, data->boopsi_taglist)))
367 tag->ti_Data = _mleft(obj);
368 if ((tag = FindTagItem(GA_Top, data->boopsi_taglist)))
369 tag->ti_Data = _mtop(obj);
370 if ((tag = FindTagItem(GA_Width, data->boopsi_taglist)))
371 tag->ti_Data = _mwidth(obj);
372 if ((tag = FindTagItem(GA_Height, data->boopsi_taglist)))
373 tag->ti_Data = _mheight(obj);
374 if (data->boopsi_tagscreen
375 && (tag =
376 FindTagItem(data->boopsi_tagscreen, data->boopsi_taglist)))
377 tag->ti_Data = (IPTR) _screen(obj);
378 if (data->boopsi_tagwindow
379 && (tag =
380 FindTagItem(data->boopsi_tagwindow, data->boopsi_taglist)))
381 tag->ti_Data = (IPTR) _window(obj);
382 if (data->boopsi_tagdrawinfo
383 && (tag =
384 FindTagItem(data->boopsi_tagdrawinfo,
385 data->boopsi_taglist)))
386 tag->ti_Data = (IPTR) _dri(obj);
388 if ((data->boopsi_object =
389 NewObjectA(data->boopsi_class, data->boopsi_classid,
390 data->boopsi_taglist)))
392 SetAttrsA(data->boopsi_object, data->remember);
393 AddGadget(_window(obj), (struct Gadget *)data->boopsi_object, ~0);
397 return rc;
400 IPTR Boopsi__MUIM_Draw(struct IClass *cl, Object *obj,
401 struct MUIP_Draw *msg)
403 struct Boopsi_DATA *data = INST_DATA(cl, obj);
404 DoSuperMethodA(cl, obj, (Msg) msg);
406 if (!(msg->flags & (MADF_DRAWOBJECT | MADF_DRAWUPDATE)))
407 return 1;
408 if (data->boopsi_object)
409 RefreshGList((struct Gadget *)data->boopsi_object, _window(obj),
410 NULL, 1);
411 return 1;
414 IPTR Boopsi__MUIM_Hide(struct IClass *cl, Object *obj,
415 struct MUIP_Hide *msg)
417 struct Boopsi_DATA *data = INST_DATA(cl, obj);
418 if (data->boopsi_object)
420 struct TagItem *tags, *tag;
422 /* Fill in the initial remember tag data in our remember tag list */
423 for (tags = data->remember; (tag = NextTagItem(&tags));)
425 GetAttr(tag->ti_Tag, data->boopsi_object, &tag->ti_Data);
428 RemoveGadget(_window(obj), (struct Gadget *)data->boopsi_object);
429 DisposeObject(data->boopsi_object);
430 data->boopsi_object = NULL;
433 return DoSuperMethodA(cl, obj, (Msg) msg);
436 IPTR Boopsi__MUIM_HandleEvent(struct IClass *cl, Object *obj,
437 struct MUIP_HandleEvent *msg)
439 //struct Boopsi_DATA *data = INST_DATA(cl, obj);
441 if (msg->imsg)
443 if (msg->imsg->Class == IDCMP_IDCMPUPDATE)
445 // struct TagItem *tags,*tag;
447 /* Go through the tag list (iaddress) and set all the tags;
448 ** this is somewhat stupid, because all objects which hear on
449 ** the same notifies will receive the notify although their
450 ** value has not changed really, but this is how MUI seems to
451 ** mange it (this could really make big problems if using
452 ** MUIV_TriggerValue). A better idea, is to distinguish this
453 ** via an allocatable gadgetid, and the object checks wheather
454 ** the gadget id equals to its allocated one
457 SetAttrs(obj, MUIA_Boopsi_OnlyTrigger, TRUE, TAG_MORE,
458 (IPTR) msg->imsg->IAddress);
460 // for (tags = (struct TagItem*)msg->imsg->IAddress;
461 // (tag = NextTagItem(&tags)); )
462 // {
463 // }
467 return 0;
470 #if ZUNE_BUILTIN_BOOPSI
471 BOOPSI_DISPATCHER(IPTR, Boopsi_Dispatcher, cl, obj, msg)
473 switch (msg->MethodID)
475 case OM_NEW:
476 return Boopsi__OM_NEW(cl, obj, (struct opSet *)msg);
477 case OM_DISPOSE:
478 return Boopsi__OM_DISPOSE(cl, obj, msg);
479 case OM_GET:
480 return Boopsi__OM_GET(cl, obj, (struct opGet *)msg);
481 case OM_SET:
482 return Boopsi__OM_SET(cl, obj, (struct opSet *)msg);
483 case MUIM_Setup:
484 return Boopsi__MUIM_Setup(cl, obj, (APTR) msg);
485 case MUIM_Cleanup:
486 return Boopsi__MUIM_Cleanup(cl, obj, (APTR) msg);
487 case MUIM_Show:
488 return Boopsi__MUIM_Show(cl, obj, (APTR) msg);
489 case MUIM_Hide:
490 return Boopsi__MUIM_Hide(cl, obj, (APTR) msg);
491 case MUIM_AskMinMax:
492 return Boopsi__MUIM_AskMinMax(cl, obj, (APTR) msg);
493 case MUIM_Draw:
494 return Boopsi__MUIM_Draw(cl, obj, (APTR) msg);
495 case MUIM_HandleEvent:
496 return Boopsi__MUIM_HandleEvent(cl, obj, (APTR) msg);
499 struct Boopsi_DATA *data = INST_DATA(cl, obj);
500 if (((msg->MethodID >> 16) != ((TAG_USER >> 16) | 0x0042))
501 && data->boopsi_object)
503 return DoMethodA(data->boopsi_object, msg);
505 return DoSuperMethodA(cl, obj, msg);
508 BOOPSI_DISPATCHER_END
510 const struct __MUIBuiltinClass _MUI_Boopsi_desc =
512 MUIC_Boopsi,
513 MUIC_Area,
514 sizeof(struct Boopsi_DATA),
515 (void *) Boopsi_Dispatcher
517 #endif /* ZUNE_BUILTIN_BOOPSI */