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.3 2004/06/16 20:16:48 verhaegs
15 * Use METHODPROTO, METHOD_END and REGFUNCPROTOn where needed.
17 * Revision 42.2 2000/05/15 19:27:02 stegerg
18 * another hundreds of REG() macro replacements in func headers/protos.
20 * Revision 42.1 2000/05/14 23:32:48 stegerg
21 * changed over 200 function headers which all use register
22 * parameters (oh boy ...), because the simple REG() macro
23 * doesn't work with AROS. And there are still hundreds
24 * of headers left to be fixed :(
26 * Many of these functions would also work with stack
27 * params, but since i have fixed every single one
28 * I encountered up to now, I guess will have to do
29 * the same for the rest.
31 * Revision 42.0 2000/05/09 22:09:50 mlemos
32 * Bumped to revision 42.0 before handing BGUI to AROS team
34 * Revision 41.11 2000/05/09 19:54:51 mlemos
35 * Merged with the branch Manuel_Lemos_fixes.
37 * Revision 41.10.2.4 1999/08/30 04:57:39 mlemos
38 * Made the methods that change group members on-fly setup the gadget
39 * attributes using the window WINDOW_SETUPGADGET method.
41 * Revision 41.10.2.3 1999/08/30 00:22:54 mlemos
42 * Made the BASE_INHIBIT method call the superclass to set the base object
44 * Made an added, inserted or replaced page member object be inhibited if it
45 * is not active or the page object is inhibited.
46 * Adjusted the active page number and node pointer when removing a page
49 * Revision 41.10.2.2 1999/08/29 18:58:49 mlemos
50 * Added support to the LGO_Relayout attribute to be able to not relayout a
51 * when calling GRM_ADDMEMBER, GRM_INSERTMEMBER, GRM_REPLACEMEMBER.
53 * Revision 41.10.2.1 1999/08/29 17:08:39 mlemos
54 * Added the implementation of the methods GRM_ADDMEMBER, GRM_REMMEMBER,
55 * GRM_INSERTMEMBER, GRM_REPLACEMEMBER.
57 * Revision 41.10 1998/02/25 21:12:47 mlemos
60 * Revision 1.1 1998/02/25 17:09:20 mlemos
66 /// Class definitions.
68 #include "include/classdefs.h"
71 * Page members are tied together
72 * using these structures.
74 typedef struct PMember
{
75 struct PMember
*pm_Next
; /* next member */
76 struct PMember
*pm_Prev
; /* previous member */
77 Object
*pm_Object
; /* the member */
81 PM
*pl_First
; /* first memeber */
82 PM
*pl_EndMark
; /* end-of-list marker */
83 PM
*pl_Last
; /* last member */
87 * Object instance data.
90 ULONG pd_Flags
; /* see below */
91 PML pd_Members
; /* list of members */
92 PM
*pd_Active
; /* points to the active member */
93 ULONG pd_Num
; /* member number. */
96 #define PDF_ADDFAILURE (1<<0) /* create time failure */
97 #define PDF_INVERTED (1<<1) /* AddHead() */
98 #define PDF_INHIBIT (1<<2) /* Inhibited? */
103 * Get the member 'num'.
105 //STATIC ASM PM *GetMember(REG(a0) PML *l, REG(d0) ULONG mnum)
106 STATIC ASM
REGFUNC2(PM
*, GetMember
,
107 REGPARAM(A0
, PML
*, l
),
108 REGPARAM(D0
, ULONG
, mnum
))
113 for (pm
= l
->pl_First
; pm
->pm_Next
; pm
= pm
->pm_Next
, num
++)
125 //STATIC ASM VOID AddMembers( REG(a0) Class *cl, REG(a1) Object *obj, REG(a2) struct TagItem *attr)
126 STATIC ASM
REGFUNC3(VOID
, AddMembers
,
127 REGPARAM(A0
, Class
*, cl
),
128 REGPARAM(A1
, Object
*, obj
),
129 REGPARAM(A2
, struct TagItem
*, attr
))
131 PD
*pd
= INST_DATA(cl
, obj
);
133 struct TagItem
*tstate
= attr
, *tag
;
138 while (tag
= NextTagItem(&tstate
))
144 * We do not allow NULL-objects.
149 * Allocate PMember structure.
151 if (pm
= (PM
*)BGUI_AllocPoolMem(sizeof(PM
)))
154 * Initialize structure and add it to the list.
156 pm
->pm_Object
= (Object
*)tag
->ti_Data
;
157 if (pd
->pd_Flags
& PDF_INVERTED
)
158 AddHead((struct List
*)&pd
->pd_Members
, (struct Node
*)pm
);
160 AddTail((struct List
*)&pd
->pd_Members
, (struct Node
*)pm
);
165 pd
->pd_Flags
|= PDF_ADDFAILURE
;
170 pd
->pd_Flags
|= PDF_ADDFAILURE
;
178 * Set members active/deactive.
180 //STATIC ASM VOID DoMembers(REG(a0) PD *pd)
181 STATIC ASM
REGFUNC1(VOID
, DoMembers
,
182 REGPARAM(A0
, PD
*, pd
))
184 PM
*pm
, *active
= pd
->pd_Active
;
185 BOOL inhibit
= pd
->pd_Flags
& PDF_INHIBIT
;
190 for (pm
= pd
->pd_Members
.pl_First
; pm
->pm_Next
; pm
= pm
->pm_Next
)
193 * (De)activate members.
195 AsmDoMethod(pm
->pm_Object
, BASE_INHIBIT
, inhibit
|| (pm
!= active
));
202 * Create a shiny new object.
204 METHOD(PageClassNew
, struct opSet
*, ops
)
207 struct TagItem
*tags
, *tag
;
210 tags
= DefTagList(BGUI_PAGE_GADGET
, ops
->ops_AttrList
);
213 * First we let the superclass
216 if (rc
= NewSuperObject(cl
, obj
, tags
))
218 pd
= INST_DATA(cl
, rc
);
220 if (tag
= FindTagItem(PAGE_NoBufferRP
, tags
))
222 DoSetMethodNG((Object
*)rc
, BT_Buffer
, !(tag
->ti_Data
), TAG_DONE
);
226 * Initialize the page
229 NewList((struct List
*)&pd
->pd_Members
);
231 GADGET(rc
)->Activation
|= GACT_RELVERIFY
;
233 if (GetTagData(PAGE_Inverted
, FALSE
, tags
))
234 pd
->pd_Flags
|= PDF_INVERTED
;
237 * Add all page members.
239 AddMembers(cl
, (Object
*)rc
, ops
->ops_AttrList
);
241 pd
->pd_Flags
&= ~PDF_INVERTED
;
244 * When successfull return the object.
246 if (!(pd
->pd_Flags
& PDF_ADDFAILURE
))
249 * Get the active member.
251 pd
->pd_Num
= GetTagData(PAGE_Active
, 0, tags
);
252 pd
->pd_Active
= GetMember(&pd
->pd_Members
, pd
->pd_Num
);
258 * Otherwise dispose of the page.
260 AsmCoerceMethod(cl
, (Object
*)rc
, OM_DISPOSE
);
270 /// OM_SET, OM_UPDATE
272 * Set/update page attributes.
274 METHOD(PageClassSetUpdate
, struct opUpdate
*, opu
)
276 PD
*pd
= INST_DATA( cl
, obj
);
277 struct TagItem
*attr
= opu
->opu_AttrList
, *tstate
= attr
, *tag
;
278 struct GadgetInfo
*gi
= opu
->opu_GInfo
;
284 * First we let the superclass
287 AsmDoSuperMethodA(cl
, obj
, (Msg
)opu
);
289 GADGET(obj
)->Activation
|= GACT_RELVERIFY
;
293 * to interim messages.
295 if ((opu
->MethodID
== OM_UPDATE
) && (opu
->opu_Flags
& OPUF_INTERIM
))
298 while (tag
= NextTagItem(&tstate
))
304 case GA_BottomBorder
:
307 case BT_ParentWindow
:
312 * Pass on attribute to the members.
314 for (pm
= pd
->pd_Members
.pl_First
; pm
->pm_Next
; pm
= pm
->pm_Next
)
315 DoSetMethod(pm
->pm_Object
, gi
, tag
->ti_Tag
, data
, TAG_DONE
);
319 if (pd
->pd_Num
!= data
)
322 pd
->pd_Active
= GetMember(&pd
->pd_Members
, data
);
331 * When a visual change is necessary we re-render.
335 DoRenderMethod(obj
, gi
, GREDRAW_REDRAW
);
336 DoNotifyMethod(obj
, gi
, 0, PAGE_Active
, pd
->pd_Num
, TAG_END
);
346 METHOD(PageClassRender
, struct bmRender
*, bmr
)
348 PD
*pd
= INST_DATA(cl
, obj
);
349 BC
*bc
= BASE_DATA(obj
);
350 struct BaseInfo
*bi
= bmr
->bmr_BInfo
;
353 * Render the baseclass.
355 AsmDoSuperMethodA(cl
, obj
, (Msg
)bmr
);
363 * Setup the active member size.
365 DoSetMethodNG(pd
->pd_Active
->pm_Object
, GA_Left
, bc
->bc_InnerBox
.Left
, GA_Top
, bc
->bc_InnerBox
.Top
,
366 GA_Width
, bc
->bc_InnerBox
.Width
, GA_Height
, bc
->bc_InnerBox
.Height
,
367 BT_ParentGroup
, obj
, TAG_DONE
);
371 AsmDoMethod(pd
->pd_Active
->pm_Object
, GM_RENDER
, bi
, bi
->bi_RPort
, GREDRAW_REDRAW
);
379 * They want to know something.
381 METHOD(PageClassGet
, struct opGet
*, opg
)
383 PD
*pd
= INST_DATA(cl
, obj
);
384 ULONG rc
= 1, *store
= opg
->opg_Storage
;
386 switch (opg
->opg_AttrID
)
389 if (pd
->pd_Active
) STORE pd
->pd_Num
;
394 rc
= AsmDoSuperMethodA(cl
, obj
, (Msg
)opg
);
403 * Dispose of all objects added to the page-list
404 * and then dispose of the page itself.
406 METHOD(PageClassDispose
, Msg
, msg
)
408 PD
*pd
= INST_DATA(cl
, obj
);
412 * Remove all objects from the list.
414 while (pm
= (PM
*)RemHead((struct List
*)&pd
->pd_Members
))
420 AsmDoMethod(pm
->pm_Object
, OM_DISPOSE
);
423 * Deallocate the object
426 BGUI_FreePoolMem(pm
);
430 * Call the super class
431 * to dispose the pageclass object.
433 return AsmDoSuperMethodA(cl
, obj
, msg
);
439 * They want to know something about
442 METHOD(PageClassDimensions
, struct bmDimensions
*, bmd
)
444 PD
*pd
= INST_DATA(cl
, obj
);
445 struct BaseInfo
*bi
= bmd
->bmd_BInfo
;
450 for (pm
= pd
->pd_Members
.pl_First
; pm
->pm_Next
; pm
= pm
->pm_Next
)
453 AsmDoMethod(pm
->pm_Object
, GRM_DIMENSIONS
, bi
, bi
->bi_RPort
, &w
, &h
, 0);
457 return CalcDimensions(cl
, obj
, bmd
, mw
, mh
);
463 * Get the object under the mouse.
465 METHOD(PageClassWhichObject
, struct grmWhichObject
*, grwo
)
467 PD
*pd
= INST_DATA(cl
, obj
);
468 Object
*ob
= pd
->pd_Active
->pm_Object
;
470 * Current page member a group?
476 ob
= (Object
*)AsmDoMethodA(ob
, (Msg
)grwo
);
484 * Forward a message to the active page.
486 METHOD(PageClassForward
, Msg
, msg
)
488 PD
*pd
= INST_DATA(cl
, obj
);
489 ULONG rc
= GMR_NOREUSE
;
492 * Do we have an active member?
497 * Forward the message to the
500 rc
= AsmDoMethodA(pd
->pd_Active
->pm_Object
, msg
);
503 * Take over the active member's GadgetID.
505 GADGET(obj
)->GadgetID
= GADGET(pd
->pd_Active
->pm_Object
)->GadgetID
;
513 * Pass the message to all submembers.
515 METHOD(PageClassAll
, Msg
, msg
)
517 PD
*pd
= INST_DATA(cl
, obj
);
521 for (pm
= pd
->pd_Members
.pl_First
; pm
->pm_Next
; pm
= pm
->pm_Next
)
523 rc
+= AsmDoMethodA(pm
->pm_Object
, msg
);
531 * Inhibit an entire page object.
533 METHOD(PageClassInhibit
, struct bmInhibit
*, bmi
)
535 PD
*pd
= INST_DATA(cl
, obj
);
536 PM
*pm
, *active
= pd
->pd_Active
;
537 BOOL inhibit
= bmi
->bmi_Inhibit
;
539 if(!AsmDoSuperMethodA(cl
, obj
, (Msg
)bmi
))
541 if (inhibit
) pd
->pd_Flags
|= PDF_INHIBIT
;
542 else pd
->pd_Flags
&= ~PDF_INHIBIT
;
544 for (pm
= pd
->pd_Members
.pl_First
; pm
->pm_Next
; pm
= pm
->pm_Next
)
546 AsmDoMethod(pm
->pm_Object
, BASE_INHIBIT
, inhibit
|| (pm
!= active
));
554 METHOD(PageClassIsMulti
, Msg
, msg
)
564 * Add a member to the group.
566 METHOD(PageClassAddMember
, struct grmAddMember
*, grma
)
568 PD
*pd
= INST_DATA(cl
, obj
);
571 if(!(pm
= (PM
*)BGUI_AllocPoolMem(sizeof(PM
))))
573 pm
->pm_Object
=grma
->grma_Member
;
575 AddTail((struct List
*)&pd
->pd_Members
, (struct Node
*)pm
);
578 if(BASE_DATA(obj
)->bc_Window
)
580 struct TagItem tags
[2];
582 tags
[0].ti_Tag
=BT_Inhibit
;
583 tags
[0].ti_Data
=TRUE
;
584 tags
[1].ti_Tag
=TAG_END
;
585 AsmDoMethod(BASE_DATA(obj
)->bc_Window
, WM_SETUPGADGET
,pm
->pm_Object
,&tags
);
589 * Try to re-layout the group.
592 if(GetTagData(LGO_Relayout
, TRUE
, (struct TagItem
*)&grma
->grma_Attr
)
593 && !RelayoutGroup(obj
))
596 Remove((struct Node
*)pm
);
598 BGUI_FreePoolMem(pm
);
610 * Remove an object from the list.
612 METHOD(PageClassRemMember
, struct grmRemMember
*, grmr
)
614 PD
*pd
= INST_DATA(cl
, obj
);
617 if(!grmr
->grmr_Member
)
620 for (pm
= pd
->pd_Members
.pl_First
; pm
->pm_Next
; pm
= pm
->pm_Next
)
622 if(pm
->pm_Object
==grmr
->grmr_Member
)
624 if(pm
==pd
->pd_Active
)
625 pd
->pd_Active
=(pm
->pm_Prev
->pm_Prev
? pm
->pm_Prev
: pm
->pm_Next
);
626 Remove((struct Node
*)pm
);
627 BGUI_FreePoolMem(pm
);
628 for(pd
->pd_Num
=0,pm
=pd
->pd_Members
.pl_First
;pm
->pm_Next
&& pm
!=pd
->pd_Active
;pd
->pd_Num
++,pm
=pm
->pm_Next
);
631 return((ULONG
)grmr
->grmr_Member
);
642 * Insert a member in the group.
644 METHOD(PageClassInsert
, struct grmInsertMember
*, grmi
)
646 PD
*pd
= INST_DATA(cl
, obj
);
649 if(!grmi
->grmi_Member
650 || !(new_pm
= (PM
*)BGUI_AllocPoolMem(sizeof(PM
))))
652 new_pm
->pm_Object
=grmi
->grmi_Member
;
654 for (pm
= pd
->pd_Members
.pl_First
; pm
->pm_Next
; pm
= pm
->pm_Next
)
656 if(pm
->pm_Object
==grmi
->grmi_Pred
)
658 Insert((struct List
*)&pd
->pd_Members
,(struct Node
*)new_pm
,(struct Node
*)pm
);
661 if(BASE_DATA(obj
)->bc_Window
)
663 struct TagItem tags
[2];
665 tags
[0].ti_Tag
=BT_Inhibit
;
666 tags
[0].ti_Data
=TRUE
;
667 tags
[1].ti_Tag
=TAG_END
;
668 AsmDoMethod(BASE_DATA(obj
)->bc_Window
, WM_SETUPGADGET
,pm
->pm_Object
,&tags
);
672 * Try to re-layout the group.
674 if(GetTagData(LGO_Relayout
, TRUE
, (struct TagItem
*)&grmi
->grmi_Attr
)
675 && !RelayoutGroup(obj
))
678 Remove((struct Node
*)new_pm
);
680 BGUI_FreePoolMem(new_pm
);
689 BGUI_FreePoolMem(new_pm
);
695 /// GRM_REPLACEMEMBER
697 * Replace a member in the group.
699 METHOD(PageClassReplace
, struct grmReplaceMember
*, grrm
)
701 PD
*pd
= INST_DATA(cl
, obj
);
707 if(!grrm
->grrm_MemberA
708 || !grrm
->grrm_MemberB
)
711 for (pm
= pd
->pd_Members
.pl_First
; pm
->pm_Next
; pm
= pm
->pm_Next
)
713 if(pm
->pm_Object
==grrm
->grrm_MemberA
)
715 pm
->pm_Object
=grrm
->grrm_MemberB
;
718 if(BASE_DATA(obj
)->bc_Window
)
720 struct TagItem tags
[2];
722 tags
[0].ti_Tag
=BT_Inhibit
;
723 tags
[0].ti_Data
=((pd
->pd_Flags
& PDF_INHIBIT
)!=0 || (pm
!= pd
->pd_Active
));
724 tags
[1].ti_Tag
=TAG_END
;
725 AsmDoMethod(BASE_DATA(obj
)->bc_Window
, WM_SETUPGADGET
,pm
->pm_Object
,&tags
);
729 * Try to re-layout the group.
731 if(GetTagData(LGO_Relayout
, TRUE
, (struct TagItem
*)&grrm
->grrm_Attr
)
732 && !RelayoutGroup(obj
))
735 pm
->pm_Object
=grrm
->grrm_MemberA
;
741 return((ULONG
)grrm
->grrm_MemberA
);
749 /// Class initialization.
753 STATIC DPFUNC ClassFunc
[] = {
754 BASE_RENDER
, (FUNCPTR
)PageClassRender
,
755 BASE_DIMENSIONS
, (FUNCPTR
)PageClassDimensions
,
756 OM_NEW
, (FUNCPTR
)PageClassNew
,
757 OM_SET
, (FUNCPTR
)PageClassSetUpdate
,
758 OM_UPDATE
, (FUNCPTR
)PageClassSetUpdate
,
759 OM_DISPOSE
, (FUNCPTR
)PageClassDispose
,
760 OM_GET
, (FUNCPTR
)PageClassGet
,
761 GM_GOINACTIVE
, (FUNCPTR
)PageClassForward
,
762 GM_GOACTIVE
, (FUNCPTR
)PageClassForward
,
763 GM_HANDLEINPUT
, (FUNCPTR
)PageClassForward
,
764 GM_HITTEST
, (FUNCPTR
)PageClassForward
,
765 GRM_WHICHOBJECT
, (FUNCPTR
)PageClassWhichObject
,
766 BASE_INHIBIT
, (FUNCPTR
)PageClassInhibit
,
767 BASE_MOVEBOUNDS
, (FUNCPTR
)PageClassForward
,
768 BASE_LOCALIZE
, (FUNCPTR
)PageClassAll
,
769 BASE_KEYLABEL
, (FUNCPTR
)PageClassAll
,
770 BASE_FINDKEY
, (FUNCPTR
)PageClassForward
,
771 BASE_SHOWHELP
, (FUNCPTR
)PageClassForward
,
772 BASE_IS_MULTI
, (FUNCPTR
)PageClassIsMulti
,
773 GRM_ADDMEMBER
, (FUNCPTR
)PageClassAddMember
,
774 GRM_REMMEMBER
, (FUNCPTR
)PageClassRemMember
,
775 GRM_INSERTMEMBER
, (FUNCPTR
)PageClassInsert
,
776 GRM_REPLACEMEMBER
, (FUNCPTR
)PageClassReplace
,
781 * Simple initialization of the page class.
783 makeproto Class
*InitPageClass(void)
785 return BGUI_MakeClass(CLASS_SuperClassBGUI
, BGUI_BASE_GADGET
,
786 CLASS_ObjectSize
, sizeof(PD
),
787 CLASS_DFTable
, ClassFunc
,