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.
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
47 * Ensured that BASE_LAYOUT method calls are not forwarded to the external
50 * Revision 41.10 1998/02/25 21:11:58 mlemos
53 * Revision 1.1 1998/02/25 17:08:07 mlemos
60 #include "include/classdefs.h"
63 * Object instance data.
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. */
77 #define EDF_NO_REBUILD (1<<0) /* No need to rebuild the object. */
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
;
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
;
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
);
126 * Set the track changes.
128 STATIC ASM VOID
GetTrackChanges( REG(a0
) ED
*ed
)
130 struct TagItem
*tstate
= ed
->ed_TrackList
;
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
);
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
;
154 * Set values in the taglist.
156 while ((tag
= NextTagItem(&tstate
)))
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;
172 STATIC ASM IPTR
ExtClassNew(REG(a0
) Class
*cl
, REG(a2
) Object
*obj
, REG(a1
) struct opSet
* ops
)
176 struct TagItem
*attr
;
178 if (( rc
= AsmDoSuperMethodA(cl
,obj
,(Msg
)ops
) ))
181 * Get to the instance data.
183 ed
= INST_DATA(cl
, rc
);
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
)
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
);
218 * Setup attribute list.
220 if (SetupAttrList(ed
, attr
))
229 AsmCoerceMethod(cl
, (Object
*)rc
, 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
);
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
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
);
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
);
278 switch (opg
->opg_AttrID
)
281 *(opg
->opg_Storage
) = (IPTR
)ed
->ed_Object
;
285 rc
= AsmDoSuperMethodA(cl
, obj
, (Msg
)opg
);
288 rc
= AsmDoMethodA(ed
->ed_Object
, (Msg
)opg
);
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
);
303 * Setup minimum size.
305 rc
= CalcDimensions(cl
, obj
, msg
, ed
->ed_MinWidth
, ed
->ed_MinHeight
);
311 STATIC ASM IPTR
ExtClassHitTest(REG(a0
) Class
*cl
, REG(a2
) Object
*obj
, REG(a1
) Msg msg
)
313 ED
*ed
= INST_DATA(cl
,obj
);
316 rc
= AsmDoSuperMethodA(cl
, obj
, msg
);
320 if (rc
== GMR_GADGETHIT
) {
324 if (ed
->ed_Object
) rc
= ForwardMsg(obj
, ed
->ed_Object
, msg
);
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
);
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
);
354 * Render the baseclass.
356 rc
= AsmDoSuperMethodA(cl
, obj
, (Msg
)bmr
);
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
;
376 AsmDoMethod(ed
->ed_Object
, OM_DISPOSE
);
377 ed
->ed_Object
= NULL
;
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
);
391 SetGadgetBounds(ed
->ed_Object
, &bc
->bc_InnerBox
);
394 rc
= AsmDoMethod(ed
->ed_Object
, GM_RENDER
, bi
, bi
->bi_RPort
, bmr
->bmr_Flags
);
406 ///ExtClassDispatch()
411 STATIC SAVEDS ASM
REGFUNC3(IPTR
, ExtClassDispatch
,
412 REGPARAM(A0
, Class
*, cl
),
413 REGPARAM(A2
, Object
*, obj
),
414 REGPARAM(A1
, Msg
, msg
))
422 * What have we got here...
424 switch (msg
->MethodID
)
427 rc
= ExtClassNew( cl
, obj
, (struct opSet
*)msg
);
431 rc
= ExtClassDispose( cl
, obj
, msg
);
437 * We ignore it for now.
439 rc
= AsmDoSuperMethodA(cl
, obj
, msg
);
443 rc
= ExtClassRender(cl
,obj
, (struct bmRender
*)msg
);
447 rc
= ExtClassGet(cl
,obj
, (struct opGet
*)msg
);
451 rc
= ExtClassHitTest(cl
,obj
,msg
);
456 rc
= ExtClassHandleInput(cl
,obj
,msg
);
459 case BASE_DIMENSIONS
:
460 rc
= ExtClassDimensions(cl
,obj
, (struct bmDimensions
*)msg
);
467 rc
= AsmDoSuperMethodA(cl
, obj
, msg
);
470 * Pass the message to the object.
472 ed
= INST_DATA(cl
,obj
);
475 rc
= AsmDoMethodA(ed
->ed_Object
, msg
);
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
,