Icons for Radium and Shellplayer.
[AROS-Contrib.git] / bgui / externalclass.c
blobdabc3a411a4b0ba9617d180bb6ddbe21af02d382
1 /*
2 * @(#) $Header$
4 * BGUI library
5 * externalclass.c
7 * (C) Copyright 1998 Manuel Lemos.
8 * (C) Copyright 1996-1997 Ian J. Einman.
9 * (C) Copyright 1993-1996 Jaba Development.
10 * (C) Copyright 1993-1996 Jan van den Baard.
11 * All Rights Reserved.
13 * $Log$
14 * Revision 42.5 2004/06/16 20:16:48 verhaegs
15 * Use METHODPROTO, METHOD_END and REGFUNCPROTOn where needed.
17 * Revision 42.4 2003/01/18 19:09:56 chodorowski
18 * Instead of using the _AROS or __AROS preprocessor symbols, use __AROS__.
20 * Revision 42.3 2000/06/01 01:41:37 bergers
21 * Only 2 linker problems left: stch_l & stcu_d. Somebody might want to replace them (embraced by #ifdef __AROS__), please.
23 * Revision 42.2 2000/05/15 19:27:01 stegerg
24 * another hundreds of REG() macro replacements in func headers/protos.
26 * Revision 42.1 2000/05/14 23:32:47 stegerg
27 * changed over 200 function headers which all use register
28 * parameters (oh boy ...), because the simple REG() macro
29 * doesn't work with AROS. And there are still hundreds
30 * of headers left to be fixed :(
32 * Many of these functions would also work with stack
33 * params, but since i have fixed every single one
34 * I encountered up to now, I guess will have to do
35 * the same for the rest.
37 * Revision 42.0 2000/05/09 22:08:50 mlemos
38 * Bumped to revision 42.0 before handing BGUI to AROS team
40 * Revision 41.11 2000/05/09 19:54:12 mlemos
41 * Merged with the branch Manuel_Lemos_fixes.
43 * Revision 41.10.2.1 1998/10/12 01:26:10 mlemos
44 * Integrated Janne patch to ensure enough stack space when the methods are
45 * called and to restructured the code to be more inline with the other
46 * classes.
47 * Ensured that BASE_LAYOUT method calls are not forwarded to the external
48 * object.
50 * Revision 41.10 1998/02/25 21:11:58 mlemos
51 * Bumping to 41.10
53 * Revision 1.1 1998/02/25 17:08:07 mlemos
54 * Ian sources
59 /// Class definitions
60 #include "include/classdefs.h"
63 * Object instance data.
65 typedef struct {
66 Object *ed_Object; /* Pointer to external object. */
67 UWORD ed_MinWidth; /* Minimum width. */
68 UWORD ed_MinHeight; /* Minimum height. */
69 UBYTE *ed_ClassID; /* Public class name. */
70 Class *ed_Class; /* External class pointer. */
71 struct TagItem *ed_AttrList; /* Create time attributes. */
72 struct TagItem *ed_TrackList; /* Tracked attributes. */
73 UWORD ed_Flags; /* See below. */
74 WORD ed_W, ed_H; /* Width and height of gadget. */
75 } ED;
77 #define EDF_NO_REBUILD (1<<0) /* No need to rebuild the object. */
80 /// SetupAttrList()
82 * Build the create tags and tracked tags.
84 STATIC ASM BOOL SetupAttrList(REG(a0) ED *ed, REG(a1) struct TagItem *attr)
86 struct TagItem *tstate;
87 struct TagItem *tag;
90 * Clone the original tag-list.
92 if ((ed->ed_AttrList = CloneTagItems(attr)))
94 tstate = ed->ed_AttrList;
97 * Set up attributes for tracking.
99 while ((tag = NextTagItem(&tstate)))
101 if (tag->ti_Tag == EXT_TrackAttr)
103 tag->ti_Tag = tag->ti_Data;
105 else
107 tag->ti_Tag = TAG_IGNORE;
111 * Allocate the tracked tag array.
113 if ((ed->ed_TrackList = CloneTagItems(ed->ed_AttrList)))
115 RefreshTagItemClones(ed->ed_AttrList, attr);
117 return TRUE;
121 return FALSE;
124 ///GetTrackChanges()
126 * Set the track changes.
128 STATIC ASM VOID GetTrackChanges( REG(a0) ED *ed )
130 struct TagItem *tstate = ed->ed_TrackList;
131 struct TagItem *tag;
134 * Get the attributes to track in the new object.
136 while ((tag = NextTagItem(&tstate)))
137 AsmDoMethod(ed->ed_Object, OM_GET, tag->ti_Tag, &tag->ti_Data);
141 ///SetupSize()
143 * Setup object size.
145 STATIC ASM VOID SetupSize(REG(a0) Class *cl, REG(a1) Object *obj)
147 ED *ed = INST_DATA(cl, obj);
148 BC *bc = BASE_DATA(obj);
149 struct IBox *box = &bc->bc_InnerBox;
150 struct TagItem *tstate = ed->ed_AttrList;
151 struct TagItem *tag;
154 * Set values in the taglist.
156 while ((tag = NextTagItem(&tstate)))
158 switch (tag->ti_Tag)
160 case GA_Left: tag->ti_Data = box->Left; break;
161 case GA_Top: tag->ti_Data = box->Top; break;
162 case GA_Width: tag->ti_Data = box->Width; break;
163 case GA_Height: tag->ti_Data = box->Height; break;
164 case GA_Bounds: tag->ti_Data = (IPTR)box; break;
171 /// OM_NEW
172 STATIC ASM IPTR ExtClassNew(REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct opSet * ops)
174 ED *ed;
175 IPTR rc;
176 struct TagItem *attr;
178 if (( rc = AsmDoSuperMethodA(cl,obj,(Msg)ops) ))
181 * Get to the instance data.
183 ed = INST_DATA(cl, rc);
186 * Get tag pointer.
188 attr = ops->ops_AttrList;
191 * Initialize attributes.
193 ed->ed_MinWidth = GetTagData(EXT_MinWidth, 0, attr);
194 ed->ed_MinHeight = GetTagData(EXT_MinHeight, 0, attr);
195 ed->ed_ClassID = (UBYTE *)GetTagData(EXT_ClassID, (IPTR)NULL, attr);
196 ed->ed_Class = (Class *)GetTagData(EXT_Class, (IPTR)NULL, attr);
197 ed->ed_Flags = GetTagData(EXT_NoRebuild, FALSE, attr) ? EDF_NO_REBUILD : 0;
200 * Do we have a class pointer or ID?
202 if (ed->ed_ClassID || ed->ed_Class)
205 * Rebuild?
207 if (ed->ed_Flags & EDF_NO_REBUILD)
209 if ((ed->ed_Object = NewObjectA(ed->ed_Class, ed->ed_Class ? NULL : ed->ed_ClassID, attr)))
211 DoSetMethodNG(ed->ed_Object, ICA_TARGET, ICTARGET_IDCMP, TAG_END);
212 return rc;
215 else
218 * Setup attribute list.
220 if (SetupAttrList(ed, attr))
222 return rc;
227 * Oops... Screwup.
229 AsmCoerceMethod(cl, (Object *)rc, OM_DISPOSE);
230 rc = 0;
232 return rc;
235 /// OM_DISPOSE
236 STATIC ASM IPTR ExtClassDispose(REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) Msg msg)
238 ED *ed = INST_DATA(cl,obj);
239 IPTR rc;
242 * Dispose the object. We need to reset the ed_Object,
243 * because otherwise the dispatcher will crash. This is
244 * due to the rootclass calling OM_REMOVE *after* the OM_DISPOSE -method
245 * of this class has been executed. I believe this cannot really
246 * be prevented, due to the order which the method travels in the
247 * class hierarchy. /JJ
249 if (ed->ed_Object) {
250 AsmDoMethod(ed->ed_Object, OM_DISPOSE);
251 ed->ed_Object = NULL;
255 * Free the attrlist and the tracked attributes.
257 if( ed->ed_AttrList) FreeTagItems(ed->ed_AttrList);
258 if( ed->ed_TrackList) FreeTagItems(ed->ed_TrackList);
261 * The rest is done by the superclass...
263 rc = AsmDoSuperMethodA(cl, obj, msg);
265 return rc;
268 /// OM_GET
269 STATIC ASM IPTR ExtClassGet(REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct opGet * opg )
271 ED *ed = INST_DATA(cl,obj);
272 IPTR rc;
275 * What do they want?
277 rc = 1;
278 switch (opg->opg_AttrID)
280 case EXT_Object:
281 *(opg->opg_Storage) = (IPTR)ed->ed_Object;
282 break;
284 default:
285 rc = AsmDoSuperMethodA(cl, obj, (Msg)opg);
287 if (ed->ed_Object)
288 rc = AsmDoMethodA(ed->ed_Object, (Msg)opg);
290 break;
293 return rc;
296 ///BASE_DIMENSIONS
297 STATIC ASM IPTR ExtClassDimensions(REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct bmDimensions * msg)
299 ED *ed = INST_DATA(cl,obj);
300 IPTR rc;
303 * Setup minimum size.
305 rc = CalcDimensions(cl, obj, msg, ed->ed_MinWidth, ed->ed_MinHeight);
307 return rc;
310 ///GM_HITTEST
311 STATIC ASM IPTR ExtClassHitTest(REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) Msg msg)
313 ED *ed = INST_DATA(cl,obj);
314 IPTR rc;
316 rc = AsmDoSuperMethodA(cl, obj, msg);
318 * Are we hit?
320 if (rc == GMR_GADGETHIT) {
322 * Forward message.
324 if (ed->ed_Object) rc = ForwardMsg(obj, ed->ed_Object, msg);
327 return rc;
330 ///GM_HANDLEINPUT,GM_GOACTIVE
331 STATIC ASM IPTR ExtClassHandleInput(REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) Msg msg)
333 ED *ed = INST_DATA(cl,obj);
334 IPTR rc = GMR_NOREUSE;
337 * Forward message. The message is thrown away if there's no object.
339 if (ed->ed_Object) rc = ForwardMsg(obj, ed->ed_Object, msg);
341 return rc;
344 /// BASE_RENDER
345 STATIC ASM IPTR ExtClassRender(REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct bmRender * bmr)
347 ED *ed = INST_DATA(cl,obj);
348 BC *bc;
349 IPTR rc;
350 BOOL set;
351 struct BaseInfo *bi;
354 * Render the baseclass.
356 rc = AsmDoSuperMethodA(cl, obj, (Msg)bmr);
358 bc = BASE_DATA(obj);
361 * Then the object.
364 if (!(ed->ed_Flags & EDF_NO_REBUILD))
366 if ((ed->ed_W != bc->bc_InnerBox.Width) || (ed->ed_H != bc->bc_InnerBox.Height))
368 ed->ed_W = bc->bc_InnerBox.Width;
369 ed->ed_H = bc->bc_InnerBox.Height;
370 set = FALSE;
372 if (ed->ed_Object)
374 GetTrackChanges(ed);
375 set = TRUE;
376 AsmDoMethod(ed->ed_Object, OM_DISPOSE);
377 ed->ed_Object = NULL;
380 SetupSize(cl, obj);
383 * Create a new object.
385 if ((ed->ed_Object = NewObjectA(ed->ed_Class, ed->ed_Class ? NULL : ed->ed_ClassID, ed->ed_AttrList)))
386 DoSetMethodNG(ed->ed_Object, ICA_TARGET, ICTARGET_IDCMP, set ? TAG_MORE : TAG_DONE, ed->ed_TrackList);
389 if (ed->ed_Object)
391 SetGadgetBounds(ed->ed_Object, &bc->bc_InnerBox);
393 bi = bmr->bmr_BInfo;
394 rc = AsmDoMethod(ed->ed_Object, GM_RENDER, bi, bi->bi_RPort, bmr->bmr_Flags);
396 else
398 DisplayBeep(NULL);
399 rc = 0;
402 return rc;
406 ///ExtClassDispatch()
409 * Class dispatcher.
411 STATIC SAVEDS ASM REGFUNC3(IPTR, ExtClassDispatch,
412 REGPARAM(A0, Class *, cl),
413 REGPARAM(A2, Object *, obj),
414 REGPARAM(A1, Msg, msg))
416 ED *ed;
417 IPTR rc;
418 APTR stk;
420 stk = EnsureStack();
422 * What have we got here...
424 switch (msg->MethodID)
426 case OM_NEW:
427 rc = ExtClassNew( cl, obj, (struct opSet *)msg );
428 break;
430 case OM_DISPOSE:
431 rc = ExtClassDispose( cl, obj, msg );
432 break;
434 case GM_RENDER:
435 case BASE_LAYOUT:
437 * We ignore it for now.
439 rc = AsmDoSuperMethodA(cl, obj, msg);
440 break;
442 case BASE_RENDER:
443 rc = ExtClassRender(cl,obj, (struct bmRender *)msg);
444 break;
446 case OM_GET:
447 rc = ExtClassGet(cl,obj, (struct opGet *)msg);
448 break;
450 case GM_HITTEST:
451 rc = ExtClassHitTest(cl,obj,msg);
452 break;
454 case GM_GOACTIVE:
455 case GM_HANDLEINPUT:
456 rc = ExtClassHandleInput(cl,obj,msg);
457 break;
459 case BASE_DIMENSIONS:
460 rc = ExtClassDimensions(cl,obj, (struct bmDimensions *)msg);
461 break;
463 default:
465 * First we go.
467 rc = AsmDoSuperMethodA(cl, obj, msg);
470 * Pass the message to the object.
472 ed = INST_DATA(cl,obj);
474 if (ed->ed_Object)
475 rc = AsmDoMethodA(ed->ed_Object, msg);
477 break;
480 RevertStack(stk);
481 return rc;
484 REGFUNC_END
488 /// Class initialization
491 * Class initialization.
493 makeproto Class *InitExtClass( void )
495 return BGUI_MakeClass(CLASS_SuperClassBGUI, BGUI_BASE_GADGET,
496 CLASS_ObjectSize, sizeof(ED),
497 CLASS_Dispatcher, ExtClassDispatch,
498 TAG_DONE);