fix remapping behavior. Remapping is only necessary if we are rendering on the workbe...
[AROS-Contrib.git] / bgui / rootclass.c
blobcb3a7e9f9cc22d9fc72ecf011120cabd9611d0b3
1 /*
2 * @(#) $Header$
4 * BGUI library
5 * rootclass.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:10:00 chodorowski
18 * Instead of using the _AROS or __AROS preprocessor symbols, use __AROS__.
20 * Revision 42.3 2000/08/17 15:09:18 chodorowski
21 * Fixed compiler warnings.
23 * Revision 42.2 2000/05/29 00:40:24 bergers
24 * Update to compile with AROS now. Should also still compile with SASC etc since I only made changes that test the define __AROS__. The compilation is still very noisy but it does the trick for the main directory. Maybe members of the BGUI team should also have a look at the compiler warnings because some could also cause problems on other systems... (Comparison always TRUE due to datatype (or something like that)). And please compile it on an Amiga to see whether it still works... Thanks.
26 * Revision 42.1 2000/05/15 19:27:02 stegerg
27 * another hundreds of REG() macro replacements in func headers/protos.
29 * Revision 42.0 2000/05/09 22:10:06 mlemos
30 * Bumped to revision 42.0 before handing BGUI to AROS team
32 * Revision 41.11 2000/05/09 19:55:01 mlemos
33 * Merged with the branch Manuel_Lemos_fixes.
35 * Revision 41.10.2.7 1999/07/31 01:56:37 mlemos
36 * Added calls to the code that keeps track of the created objects.
38 * Revision 41.10.2.6 1999/07/03 15:17:45 mlemos
39 * Replaced the calls to CallHookPkt to BGUI_CallHookPkt.
41 * Revision 41.10.2.5 1998/11/21 00:27:15 mlemos
42 * Fixed erroneous code in OM_UPDATE.
44 * Revision 41.10.2.4 1998/11/19 01:23:33 mlemos
45 * Fixed the return value type of BASE_ADDMAP value.
47 * Revision 41.10.2.3 1998/09/19 01:54:21 mlemos
48 * Made BASE_ADDHOOK method return TRUE on success rather than the hook linet
49 * entry pointer.
51 * Revision 41.10.2.2 1998/03/02 23:49:04 mlemos
52 * Switched vector allocation functions calls to BGUI allocation functions.
54 * Revision 41.10.2.1 1998/03/01 15:39:19 mlemos
55 * Added support to track BaseInfo memory leaks.
57 * Revision 41.10 1998/02/25 21:13:01 mlemos
58 * Bumping to 41.10
60 * Revision 1.1 1998/02/25 17:09:41 mlemos
61 * Ian sources
66 #include "include/classdefs.h"
68 #define NOTIFY_MAP 1
69 #define NOTIFY_ATTR 2
70 #define NOTIFY_METHOD 3
71 #define NOTIFY_HOOK 4
73 typedef struct Notif {
74 struct Notif *n_Next;
75 struct Notif *n_Prev;
76 UBYTE n_Type;
77 BYTE n_Pri;
78 ULONG n_Flags;
79 struct TagItem n_Condition;
80 Object *n_Object;
81 } NOTIF;
84 * Structures to track notification
86 typedef struct {
87 NOTIF m_Node;
88 struct TagItem *m_MapList;
89 } MAP;
91 typedef struct {
92 NOTIF a_Node;
93 struct TagItem a_Attr;
94 } ATTR;
96 typedef struct {
97 NOTIF m_Node;
98 IPTR m_Method[1];
99 } METHOD;
101 typedef struct {
102 NOTIF h_Node;
103 struct Hook *h_Hook;
104 } HOOK;
108 * Object instance data.
110 typedef struct {
111 struct MinNode rd_Node; /* Node for adding to objects. */
112 WORD rd_NodeOffset; /* Offset of node from object. */
113 struct MinList rd_NotifyList; /* Notification list. */
114 UWORD rd_LoopCount; /* To prevent infinite notification. */
115 } RD;
117 /// OM_NEW
119 * Create a shiny new object.
121 METHOD(RootClassNew, struct opSet *, ops)
123 RD *rd;
124 IPTR rc;
127 * We let the superclass setup an object
128 * for us.
130 if ((rc = AsmDoSuperMethodA(cl, obj, (Msg)ops)))
133 * Get the instance data.
135 rd = INST_DATA(cl, rc);
137 rd->rd_NodeOffset = (BYTE *)rc - (BYTE *)rd;
140 * Initialize the notification lists.
142 NewList((struct List *)&rd->rd_NotifyList);
143 #ifdef DEBUG_BGUI
144 TrackNewObject((Object *)rc,ops->ops_AttrList);
145 #endif
147 return rc;
149 METHOD_END
151 /// OM_NOTIFY
153 * We need to update our targets.
155 METHOD(RootClassNotify, struct opUpdate *, opu)
157 RD *rd = INST_DATA(cl, obj);
158 NOTIF *n = (NOTIF *)rd->rd_NotifyList.mlh_Head;
159 struct TagItem *clones;
160 Object *target;
161 struct TagItem *tag;
162 IPTR *msg;
163 IPTR rc;
164 BOOL cond;
165 int type;
168 * Make sure that the ICA_xxx
169 * attributes will function.
171 rc = AsmDoSuperMethodA(cl, obj, (Msg)opu);
174 * Broadcast the message to all
175 * targets mapping the attributes
176 * when necessary.
178 while (n->n_Next)
180 type = n->n_Type;
181 target = n->n_Object;
184 * Object counter not 0? Do not update.
186 if (target)
189 * Peng...
191 if (AsmDoMethod(target, RM_SETLOOP))
193 * Break the loop...we are done.
195 return rc;
199 * Check condition, if we have one.
201 if (n->n_Flags & (RAF_FALSE|RAF_TRUE))
203 cond = FALSE;
205 * Conditional tag present in
206 * the notification tags?
208 if ((tag = FindTagItem(n->n_Condition.ti_Tag, opu->opu_AttrList)))
210 cond = (n->n_Condition.ti_Data == tag->ti_Data);
211 if (n->n_Flags & RAF_FALSE) cond = !cond;
213 if (!cond) type = 0;
217 * Skip interim messages?
219 if (n->n_Flags & RAF_NO_INTERIM)
221 if (opu->opu_Flags & OPUF_INTERIM) type = 0;
224 switch (type)
226 case NOTIFY_MAP:
228 * When the object has a maplist
229 * we map the clones.
231 if (((MAP *)n)->m_MapList)
234 * Clone the original attribute list.
236 if ((clones = CloneTagItems(opu->opu_AttrList)))
238 MapTags(clones, ((MAP *)n)->m_MapList, MAP_KEEP_NOT_FOUND);
240 AsmDoMethod(target, OM_UPDATE, clones, (n->n_Flags & RAF_NO_GINFO) ? NULL : opu->opu_GInfo, opu->opu_Flags);
243 * Free the clones.
245 FreeTagItems(clones);
248 else
250 AsmDoMethodA(n->n_Object, (Msg)opu);
252 break;
254 case NOTIFY_ATTR:
256 * Set tag.
258 DoSetMethod(target, (n->n_Flags & RAF_NO_GINFO) ? NULL : opu->opu_GInfo,
259 ((ATTR *)n)->a_Attr.ti_Tag, ((ATTR *)n)->a_Attr.ti_Data, TAG_DONE);
260 break;
262 case NOTIFY_METHOD:
263 msg = ((METHOD *)n)->m_Method;
266 * Set GadgetInfo?
268 if (!(n->n_Flags & RAF_NO_GINFO))
270 switch (msg[0])
272 case OM_NEW:
273 case OM_SET:
274 case OM_UPDATE:
275 case OM_NOTIFY:
277 * These methods get the GadgetInfo in the third long-word.
279 msg[2] = (IPTR)opu->opu_GInfo;
280 break;
282 default:
284 * All others in the second long-word.
286 msg[1] = (IPTR)opu->opu_GInfo;
287 break;
290 AsmDoMethodA(target, (Msg)msg);
291 break;
293 case NOTIFY_HOOK:
294 if (!BGUI_CallHookPkt(((HOOK *)n)->h_Hook, (void *)obj, (void *)opu))
295 return rc;
296 break;
299 if (target) AsmDoMethod(target, RM_CLEARLOOP);
301 n = n->n_Next;
303 return rc;
305 METHOD_END
307 /// OM_DISPOSE
309 STATIC VOID FreeNotif(NOTIF *n)
311 switch (n->n_Type)
313 case NOTIFY_MAP:
314 FreeTagItems(((MAP *)n)->m_MapList);
315 break;
317 BGUI_FreePoolMem(n);
321 * They do not need us anymore.
323 METHOD(RootClassDispose, Msg, msg)
325 RD *rd = INST_DATA(cl, obj);
326 NOTIF *n;
329 * Remove all targets and deallocate all resources.
331 while ((n = (NOTIF *)RemHead((struct List *)&rd->rd_NotifyList)))
332 FreeNotif(n);
335 * Remove us from any list we may be in.
337 AsmDoMethod(obj, RM_REMOVE);
340 * Let the superclass dispose of us.
342 #ifdef DEBUG_BGUI
343 TrackDisposedObject(obj);
344 #endif
345 return AsmDoSuperMethodA(cl, obj, msg);
347 METHOD_END
349 /// OM_UPDATE
351 * Emulate OM_UPDATE with new methods.
353 METHOD(RootClassUpdateX, struct opUpdate *, opu)
355 ULONG rc = (ULONG)AsmCoerceMethod(cl,obj, RM_SETM, opu->opu_AttrList, (opu->opu_Flags & OPUF_INTERIM) ? RAF_INTERIM|RAF_UPDATE : RAF_UPDATE);
357 if (opu->opu_GInfo
358 && !(opu->opu_Flags & OPUF_INTERIM))
359 AsmDoMethod(obj, RM_REFRESH, opu->opu_GInfo, rc);
361 return (IPTR)rc;
363 METHOD_END
365 /// OM_SET
367 * Emulate OM_SET with new methods.
369 METHOD(RootClassSetX, struct opSet *, ops)
371 ULONG rc = (ULONG)AsmDoMethod(obj, RM_SETM, ops->ops_AttrList, 0);
373 if (ops->ops_GInfo) AsmDoMethod(obj, RM_REFRESH, ops->ops_GInfo, rc);
375 return (IPTR)rc;
377 METHOD_END
379 /// OM_GET
381 * Emulate OM_GET with new methods.
383 METHOD(RootClassGetX, struct opGet *, opg)
385 return AsmDoMethod(obj, RM_GET, &opg->opg_AttrID, 0);
387 METHOD_END
389 /// RM_SET
391 * Emulate RM_SET for any superclass.
393 METHOD(RootClassSet, struct rmAttr *, ra)
395 struct TagItem tags[2];
396 ULONG rc;
398 tags[0].ti_Tag = ra->ra_Attr->ti_Tag;
399 tags[0].ti_Data = ra->ra_Attr->ti_Data;
400 tags[1].ti_Tag = TAG_DONE;
402 rc = (ULONG)AsmDoSuperMethod(cl, obj, (ra->ra_Flags & RAF_UPDATE) ? OM_UPDATE : OM_SET, tags, NULL,
403 (ra->ra_Flags & RAF_INTERIM) ? OPUF_INTERIM : 0);
405 return ((rc > 0) ? /* (RAF_UNDERSTOOD|RAF_REDRAW) */ 0 : 0);
407 METHOD_END
409 /// RM_GET
411 * Emulate RM_GET for any superclass.
413 METHOD(RootClassGet, struct rmAttr *, ra)
415 AsmDoSuperMethod(cl, obj, OM_GET, ra->ra_Attr->ti_Tag, ra->ra_Attr->ti_Data);
417 return 0;
419 METHOD_END
421 /// RM_SETM
423 METHOD(RootClassSetM, struct rmAttr *, ra1)
425 struct rmAttr ra;
426 struct TagItem *tstate = ra1->ra_Attr;
427 ULONG rc = 0;
429 ra.MethodID = RM_SET;
430 ra.ra_Flags = ra1->ra_Flags;
432 while ((ra.ra_Attr = BGUI_NextTagItem(&tstate)))
433 rc |= (ULONG)AsmDoMethodA(obj, (Msg)&ra);
435 return (IPTR)rc;
437 METHOD_END
439 /// RM_GETM
441 METHOD(RootClassGetM, struct rmAttr *, ra1)
443 struct rmAttr ra;
444 struct TagItem *tstate = ra1->ra_Attr;
445 ULONG rc = 0;
447 ra.MethodID = RM_GET;
448 ra.ra_Flags = ra1->ra_Flags;
450 while ((ra.ra_Attr = BGUI_NextTagItem(&tstate)))
451 rc |= (ULONG)AsmDoMethodA(obj, (Msg)&ra);
453 return (IPTR)rc;
455 METHOD_END
458 /// AddNotify
460 void AddNotify(RD *rd, NOTIF *n, Msg msg, int type)
463 * Set notify object.
465 n->n_Type = type;
466 n->n_Pri = ((struct rmAddAttr *)msg)->raa_Priority;
467 n->n_Flags = ((struct rmAddAttr *)msg)->raa_Flags;
468 n->n_Condition = ((struct rmAddAttr *)msg)->raa_Condition;
469 n->n_Object = ((struct rmAddAttr *)msg)->raa_Object;
472 * Add the target to the list.
474 Enqueue((struct List *)&rd->rd_NotifyList, (struct Node *)n);
477 /// RM_ADDMAP
479 * Add a map object to the list.
481 METHOD(RootClassAddMap, struct rmAddMap *, ram)
483 RD *rd = INST_DATA(cl, obj);
484 MAP *am = NULL;
487 * Check if the object is valid.
489 if (ram->ram_Object && (ram->ram_Object != obj))
492 * Allocate and initialize a MAP structure.
494 if ((am = (MAP *)BGUI_AllocPoolMem(sizeof(MAP))))
497 * Check if we need to make a map list.
499 if (ram->ram_MapList)
502 * Clone the maplist.
504 if (!(am->m_MapList = CloneTagItems(ram->ram_MapList)))
506 BGUI_FreePoolMem(am);
507 return (IPTR)NULL;
512 * Add notification.
514 AddNotify(rd, (NOTIF *)am, (Msg)ram, NOTIFY_MAP);
517 return (IPTR)am;
519 METHOD_END
521 /// RM_ADDATTR
523 * Add an attribute conditional object to the list.
525 METHOD(RootClassAddAttr, struct rmAddAttr *, raa)
527 RD *rd = INST_DATA(cl, obj);
528 ATTR *aa = NULL;
531 * Check if the object is valid.
533 if (raa->raa_Object && (raa->raa_Object != obj))
536 * Allocate and initialize an ATTR structure.
538 if ((aa = (ATTR *)BGUI_AllocPoolMem(sizeof(ATTR))))
541 * Copy the attribute.
543 aa->a_Attr = raa->raa_Attr;
546 * Add notification.
548 AddNotify(rd, (NOTIF *)aa, (Msg)raa, NOTIFY_ATTR);
551 return (IPTR)aa;
553 METHOD_END
555 /// RM_ADDMETHOD
557 * Add a method object to the list.
559 METHOD(RootClassAddMethod, struct rmAddMethod *, ram)
561 RD *rd = INST_DATA(cl, obj);
562 METHOD *am = NULL;
565 * Check if the object is valid.
567 if (ram->ram_Size && ram->ram_Object && (ram->ram_Object != obj))
570 * Allocate and initialize a METHOD structure.
572 if ((am = (METHOD *)BGUI_AllocPoolMem(sizeof(METHOD) + ram->ram_Size - sizeof(ULONG))))
575 * Copy the method.
577 CopyMem((void *)&ram->ram_MethodID, (void *)am->m_Method, ram->ram_Size);
580 * Add notification.
582 AddNotify(rd, (NOTIF *)am, (Msg)ram, NOTIFY_METHOD);
585 return (IPTR)am;
587 METHOD_END
589 /// RM_ADDHOOK
591 * Add a hook to the list.
593 METHOD(RootClassAddHook, struct rmAddHook *, rah)
595 RD *rd = INST_DATA(cl, obj);
596 HOOK *ah = NULL;
599 * Check if the hook is valid.
601 if (rah->rah_Hook)
604 * Allocate and initialize a HOOK structure.
606 if ((ah = (HOOK *)BGUI_AllocPoolMem(sizeof(HOOK))))
609 * Copy the hook.
611 ah->h_Hook = rah->rah_Hook;
614 * Add notification.
616 AddNotify(rd, (NOTIF *)ah, (Msg)rah, NOTIFY_HOOK);
618 ah->h_Node.n_Object = NULL;
621 return (IPTR)ah;
623 METHOD_END
627 * Remove an object from a list.
629 METHOD(NotifyClassRemove, struct bmRemove *, brt)
631 #if 0
632 RD *rd = INST_DATA(cl, obj);
633 NOTIF *n = (NOTIF *)rd->rd_NotifyList.mlh_Head;
634 ULONG type;
636 switch (brt->MethodID)
638 case BASE_REMMAP:
639 type = NOTIFY_TARGET;
640 break;
641 case BASE_REMCONDITIONAL:
642 type = NOTIFY_CONDITIONAL;
643 break;
644 case BASE_REMMETHOD:
645 type = NOTIFY_METHOD;
646 break;
647 case BASE_REMHOOK:
648 type = NOTIFY_HOOK;
649 break;
653 * Find an object in the target list.
655 while (n->n_Next)
657 if ((n->n_Type == type) && ((n->n_Object == brt->bar_Object) || (!n->n_Object)))
660 * Remove it from the list.
662 Remove((struct Node *)n);
665 * Deallocate the structure.
667 FreeNotif(n);
669 return 1;
671 n = n->n_Next;
673 #endif
675 return 0;
677 METHOD_END
679 /// RM_SETLOOP
681 * Set infinite loop counter.
683 METHOD(RootClassSetLoop, Msg, msg)
685 RD *rd = INST_DATA(cl, obj);
687 if (rd->rd_LoopCount)
688 return (IPTR)TRUE;
690 rd->rd_LoopCount++;
692 return (IPTR)FALSE;
694 METHOD_END
696 /// RM_CLEARLOOP
698 * Clear infinite loop counter.
700 METHOD(RootClassClearLoop, Msg, msg)
702 RD *rd = INST_DATA(cl, obj);
704 rd->rd_LoopCount--;
706 return FALSE;
708 METHOD_END
711 /// RM_REMOVE
713 METHOD(RootClassRemove, Msg, msg)
715 RD *rd = INST_DATA(cl, obj);
716 struct MinNode *mln = &rd->rd_Node;
718 if (mln->mln_Succ && mln->mln_Pred)
720 Remove((struct Node *)mln);
721 mln->mln_Succ = mln->mln_Pred = NULL;
722 return (IPTR)TRUE;
724 return (IPTR)FALSE;
726 METHOD_END
728 /// RM_ADDHEAD
730 METHOD(RootClassAddHead, struct rmAdd *, ra)
732 RD *rd = INST_DATA(cl, obj);
734 AddHead(ra->ra_List, (struct Node *)&rd->rd_Node);
736 return (IPTR)TRUE;
738 METHOD_END
740 /// RM_ADDTAIL
742 METHOD(RootClassAddTail, struct rmAdd *, ra)
744 RD *rd = INST_DATA(cl, obj);
746 AddTail(ra->ra_List, (struct Node *)&rd->rd_Node);
748 return (IPTR)TRUE;
750 METHOD_END
752 /// RM_INSERT
754 METHOD(RootClassInsert, struct rmInsert *, ri)
756 RD *rd = INST_DATA(cl, obj), *rd2;
758 if (ri->ri_Previous)
760 rd2 = INST_DATA(cl, ri->ri_Previous);
761 Insert(ri->ri_List, (struct Node *)&rd->rd_Node, (struct Node *)&rd2->rd_Node);
763 else
765 AddHead(ri->ri_List, (struct Node *)&rd->rd_Node);
767 return (IPTR)TRUE;
769 METHOD_END
771 /// RM_PREV
773 METHOD(RootClassPrev, Msg, msg)
775 RD *rd = INST_DATA(cl, obj);
776 struct MinNode *mn = rd->rd_Node.mln_Pred;
778 if (mn && mn->mln_Pred)
779 return (IPTR)((UBYTE *)mn + rd->rd_NodeOffset);
781 return (IPTR)NULL;
783 METHOD_END
785 /// RM_NEXT
787 METHOD(RootClassNext, Msg, msg)
789 RD *rd = INST_DATA(cl, obj);
790 struct MinNode *mn = rd->rd_Node.mln_Succ;
792 if (mn && mn->mln_Succ)
793 return (IPTR)((UBYTE *)mn + rd->rd_NodeOffset);
795 return (IPTR)NULL;
797 METHOD_END
800 makeproto Object *ListHeadObject(struct List *lh)
802 RD *rd = (RD *)(lh->lh_Head);
804 if (rd->rd_Node.mln_Succ) return (Object *)(((UBYTE *)rd) + rd->rd_NodeOffset);
805 else return NULL;
807 makeproto Object *ListTailObject(struct List *lh)
809 RD *rd = (RD *)(lh->lh_TailPred);
811 if (rd->rd_Node.mln_Pred) return (Object *)(((UBYTE *)rd) + rd->rd_NodeOffset);
812 else return NULL;
815 /// BASE_ADDMAP
817 METHOD(BaseClassAddMap, struct bmAddMap *, bam)
819 return (IPTR)(AsmDoMethod(obj, RM_ADDMAP, 0, 0, 0, 0, bam->bam_Object, bam->bam_MapList)!=0);
821 METHOD_END
823 /// BASE_ADDMETHOD
825 METHOD(BaseClassAddMethod, struct bmAddMethod *, bam)
827 struct rmAddMethod *ram;
829 int size = bam->bam_Size * sizeof(ULONG);
830 IPTR nh = 0;
832 if ((ram = BGUI_AllocPoolMem(sizeof(struct bmAddMethod) + size)))
834 ram->MethodID = RM_ADDMETHOD;
835 ram->ram_Object = bam->bam_Object;
836 ram->ram_Flags = bam->bam_Flags;
837 ram->ram_Size = size;
839 CopyMem((void *)&bam->bam_MethodID, (void *)&ram->ram_MethodID, size);
841 nh = AsmDoMethodA(obj, (Msg)ram);
843 BGUI_FreePoolMem(ram);
845 return nh;
847 METHOD_END
849 /// BASE_ADDCONDITIONAL
851 METHOD(BaseClassAddConditional, struct bmAddConditional *, bac)
853 IPTR nh;
855 if ((nh = AsmDoMethod(obj, RM_ADDATTR, 0, RAF_FALSE, bac->bac_Condition.ti_Tag, bac->bac_Condition.ti_Data,
856 bac->bac_Object, bac->bac_FALSE.ti_Tag, bac->bac_FALSE.ti_Data)))
858 if (AsmDoMethod(obj, RM_ADDATTR, 0, RAF_TRUE, bac->bac_Condition.ti_Tag, bac->bac_Condition.ti_Data,
859 bac->bac_Object, bac->bac_TRUE.ti_Tag, bac->bac_TRUE.ti_Data))
860 return (IPTR)TRUE;
862 AsmDoMethod(obj, RM_REMNOTIFY, 0, nh);
864 return (IPTR)FALSE;
866 METHOD_END
868 /// BASE_ADDHOOK
870 METHOD(BaseClassAddHook, struct bmAddHook *, bah)
872 return (IPTR)(AsmDoMethod(obj, RM_ADDHOOK, 0, 0, 0, 0, bah->bah_Hook)!=0);
874 METHOD_END
877 /// IM_DRAW
879 METHOD(ImageClassDraw, struct impDraw *, imp)
881 int x = imp->imp_Offset.X;
882 int y = imp->imp_Offset.Y;
883 IPTR rc = (IPTR)0;
884 struct BaseInfo *bi;
886 #ifdef DEBUG_BGUI
887 if ((bi = AllocBaseInfoDebug(__FILE__,__LINE__,BI_RastPort, imp->imp_RPort, BI_DrawInfo, imp->imp_DrInfo, TAG_DONE)))
888 #else
889 if ((bi = AllocBaseInfo(BI_RastPort, imp->imp_RPort, BI_DrawInfo, imp->imp_DrInfo, TAG_DONE)))
890 #endif
892 if (x) IMAGE(obj)->LeftEdge += x;
893 if (y) IMAGE(obj)->TopEdge += y;
895 rc = AsmDoMethod(obj, BASE_RENDER, bi, imp->imp_State);
897 if (x) IMAGE(obj)->LeftEdge -= x;
898 if (y) IMAGE(obj)->TopEdge -= y;
900 FreeBaseInfo(bi);
902 return rc;
904 METHOD_END
907 /// Class initialization.
909 * Class function array.
911 STATIC DPFUNC ClassFunc[] =
913 { RM_SET, RootClassSet },
914 { RM_GET, RootClassGet },
915 { RM_SETM, RootClassSetM },
916 { RM_GETM, RootClassGetM },
917 { OM_SET, RootClassSetX },
918 { OM_GET, RootClassGetX },
919 { OM_UPDATE, RootClassUpdateX },
920 { OM_NEW, RootClassNew },
921 { OM_DISPOSE, RootClassDispose },
922 { OM_NOTIFY, RootClassNotify },
923 { RM_SETLOOP, RootClassSetLoop },
924 { RM_CLEARLOOP, RootClassClearLoop },
926 { RM_REMOVE, RootClassRemove },
927 { RM_ADDHEAD, RootClassAddHead },
928 { RM_ADDTAIL, RootClassAddTail },
929 { RM_INSERT, RootClassInsert },
930 { RM_NEXT, RootClassNext },
931 { RM_PREV, RootClassPrev },
933 { RM_ADDMAP, RootClassAddMap },
934 { RM_ADDATTR, RootClassAddAttr },
935 { RM_ADDMETHOD, RootClassAddMethod },
936 { RM_ADDHOOK, RootClassAddHook },
938 { BASE_ADDMAP, BaseClassAddMap },
939 { BASE_ADDCONDITIONAL, BaseClassAddConditional },
940 { BASE_ADDMETHOD, BaseClassAddMethod },
941 { BASE_ADDHOOK, BaseClassAddHook },
942 { BASE_REMMAP, NotifyClassRemove },
943 { BASE_REMCONDITIONAL, NotifyClassRemove },
944 { BASE_REMMETHOD, NotifyClassRemove },
945 { BASE_REMHOOK, NotifyClassRemove },
947 { IM_DRAW, ImageClassDraw },
949 { DF_END }
952 Class *InitRootSubClass(char *superclass)
954 return BGUI_MakeClass(CLASS_SuperClassID, superclass,
955 CLASS_ObjectSize, sizeof(RD),
956 CLASS_DFTable, ClassFunc,
957 TAG_DONE);
961 * Simple class initialization.
963 makeproto Class *InitRootClass(void)
965 return InitRootSubClass("rootclass");
968 makeproto Class *InitGadgetClass(void)
970 return InitRootSubClass("gadgetclass");
973 makeproto Class *InitImageClass(void)
975 return InitRootSubClass("imageclass");