2 Copyright © 2011, The AROS Development Team. All rights reserved.
5 Desc: Workbook Icon Set Class
10 #include <aros/debug.h>
15 #include <proto/dos.h>
16 #include <proto/exec.h>
17 #include <proto/intuition.h>
18 #include <proto/utility.h>
19 #include <proto/gadtools.h>
20 #include <proto/workbench.h>
21 #include <proto/graphics.h>
23 #include <intuition/classusr.h>
24 #include <libraries/gadtools.h>
26 #include "workbook_intern.h"
30 struct MinNode sn_Node
;
31 Object
*sn_Object
; /* Gadget object */
36 struct List FixedObjects
;
37 struct List AutoObjects
;
40 static void wbGABox(struct WorkbookBase
*wb
, Object
*obj
, struct IBox
*box
)
42 struct Gadget
*gadget
= (struct Gadget
*)obj
;
44 box
->Top
= gadget
->TopEdge
;
45 box
->Left
= gadget
->LeftEdge
;
46 box
->Width
= gadget
->Width
;
47 box
->Height
= gadget
->Height
;
50 static void rearrange(Class
*cl
, Object
*obj
)
52 struct WorkbookBase
*wb
= (APTR
)cl
->cl_UserData
;
53 struct wbSet
*my
= INST_DATA(cl
, obj
);
54 struct wbSetNode
*node
;
56 WORD CurrRight
, CurrBottom
;
58 /* First, remove all autoobjects from the superclass */
59 ForeachNode(&my
->AutoObjects
, node
) {
60 DoSuperMethod(cl
, obj
, OM_REMMEMBER
, node
->sn_Object
);
63 /* Find the set size with just the fixed objects */
64 wbGABox(wb
, obj
, &sbox
);
66 /* Set the start of the auto area to be
67 * immediately below the fixed objects.
69 CurrRight
= sbox
.Left
;
70 CurrBottom
= sbox
.Top
+ sbox
.Height
;
72 /* For each item in the auto list, add it to the right */
73 ForeachNode(&my
->AutoObjects
, node
) {
74 Object
*iobj
= node
->sn_Object
;
77 wbGABox(wb
, iobj
, &ibox
);
79 if ((CurrRight
+ ibox
.Width
) < my
->MaxWidth
) {
80 ibox
.Left
= CurrRight
;
82 wbGABox(wb
, obj
, &sbox
);
83 ibox
.Left
= sbox
.Left
;
84 CurrRight
= sbox
.Left
;
85 CurrBottom
= sbox
.Top
+ sbox
.Height
;
87 ibox
.Top
= CurrBottom
;
88 CurrRight
+= ibox
.Width
;
90 D(bug("New icon position: @%d,%d\n", ibox
.Left
, ibox
.Top
));
92 SetAttrs(iobj
, GA_Left
, ibox
.Left
, GA_Top
, ibox
.Top
, TAG_END
);
94 DoSuperMethod(cl
, obj
, OM_ADDMEMBER
, iobj
);
99 static IPTR
WBSetAddMember(Class
*cl
, Object
*obj
, struct opMember
*opm
)
101 struct WorkbookBase
*wb
= (APTR
)cl
->cl_UserData
;
102 Object
*iobj
= opm
->opam_Object
;
104 struct wbSet
*my
= INST_DATA(cl
, obj
);
105 struct wbSetNode
*node
;
108 node
= AllocMem(sizeof(*node
), MEMF_ANY
);
109 node
->sn_Object
= iobj
;
111 /* Get bounding box of item to add */
112 wbGABox(wb
, iobj
, &ibox
);
114 if (ibox
.Left
== ~0 ||
116 AddHead(&my
->AutoObjects
, (struct Node
*)&node
->sn_Node
);
118 AddHead(&my
->FixedObjects
, (struct Node
*)&node
->sn_Node
);
121 rc
= DoSuperMethodA(cl
, obj
, (Msg
)opm
);
123 /* Recalculate the set's positions */
129 static IPTR
WBSetRemMember(Class
*cl
, Object
*obj
, struct opMember
*opm
)
131 Object
*iobj
= opm
->opam_Object
;
132 struct wbSet
*my
= INST_DATA(cl
, obj
);
133 struct wbSetNode
*node
, *next
;
136 rc
= DoSuperMethodA(cl
, obj
, (Msg
)opm
);
138 ForeachNodeSafe(&my
->FixedObjects
, node
, next
) {
139 if (node
->sn_Object
== iobj
) {
140 Remove((struct Node
*)node
);
141 FreeMem(node
, sizeof(*node
));
145 ForeachNodeSafe(&my
->AutoObjects
, node
, next
) {
146 if (node
->sn_Object
== iobj
) {
147 Remove((struct Node
*)node
);
148 FreeMem(node
, sizeof(*node
));
152 /* Recalculate the set's positions */
159 static IPTR
WBSetNew(Class
*cl
, Object
*obj
, struct opSet
*ops
)
161 struct WorkbookBase
*wb
= (APTR
)cl
->cl_UserData
;
165 rc
= DoSuperMethodA(cl
, obj
, (Msg
)ops
);
169 my
= INST_DATA(cl
, rc
);
171 my
->MaxWidth
= (WORD
)GetTagData(WBSA_MaxWidth
, 0, ops
->ops_AttrList
);
173 NEWLIST(&my
->FixedObjects
);
174 NEWLIST(&my
->AutoObjects
);
179 static IPTR
WBSetGet(Class
*cl
, Object
*obj
, struct opGet
*opg
)
181 struct wbSet
*my
= INST_DATA(cl
, obj
);
184 switch (opg
->opg_AttrID
) {
186 *(opg
->opg_Storage
) = (IPTR
)my
->MaxWidth
;
189 rc
= DoSuperMethodA(cl
, obj
, (Msg
)opg
);
197 static IPTR
WBSetUpdate(Class
*cl
, Object
*obj
, struct opUpdate
*opu
)
199 struct WorkbookBase
*wb
= (APTR
)cl
->cl_UserData
;
200 struct wbSet
*my
= INST_DATA(cl
, obj
);
203 struct TagItem
*tstate
;
205 rc
= DoSuperMethodA(cl
, obj
, (Msg
)opu
);
207 if ((opu
->MethodID
== OM_UPDATE
) && (opu
->opu_Flags
& OPUF_INTERIM
))
210 tstate
= opu
->opu_AttrList
;
211 while ((tag
= NextTagItem(&tstate
))) {
212 switch (tag
->ti_Tag
) {
214 my
->MaxWidth
= (WORD
)tag
->ti_Data
;
228 static IPTR
WBSetDispose(Class
*cl
, Object
*obj
, Msg msg
)
230 struct wbSet
*my
= INST_DATA(cl
, obj
);
231 struct wbSetNode
*node
, *next
;
233 /* Remove all the nodes */
234 ForeachNodeSafe(&my
->FixedObjects
, node
, next
) {
235 Remove((struct Node
*)node
);
236 FreeMem(node
, sizeof(*node
));
239 ForeachNodeSafe(&my
->AutoObjects
, node
, next
) {
240 Remove((struct Node
*)node
);
241 FreeMem(node
, sizeof(*node
));
244 return DoSuperMethodA(cl
, obj
, msg
);
248 static IPTR
WBSetRender(Class
*cl
, Object
*obj
, struct gpRender
*gpr
)
250 struct WorkbookBase
*wb
= (APTR
)cl
->cl_UserData
;
253 wbGABox(wb
, obj
, &box
);
255 /* Clear the area first */
256 EraseRect(gpr
->gpr_RPort
, box
.Left
, box
.Top
,
257 box
.Left
+ box
.Width
- 1,
258 box
.Top
+ box
.Height
- 1);
260 return DoSuperMethodA(cl
, obj
, (Msg
)gpr
);
264 static IPTR
dispatcher(Class
*cl
, Object
*obj
, Msg msg
)
268 switch (msg
->MethodID
) {
269 case OM_NEW
: rc
= WBSetNew(cl
, obj
, (APTR
)msg
); break;
270 case OM_DISPOSE
: rc
= WBSetDispose(cl
, obj
, (APTR
)msg
); break;
271 case OM_GET
: rc
= WBSetGet(cl
, obj
, (APTR
)msg
); break;
272 case OM_SET
: rc
= WBSetUpdate(cl
, obj
, (APTR
)msg
); break;
273 case OM_UPDATE
: rc
= WBSetUpdate(cl
, obj
, (APTR
)msg
); break;
274 case OM_ADDMEMBER
: rc
= WBSetAddMember(cl
, obj
, (APTR
)msg
); break;
275 case OM_REMMEMBER
: rc
= WBSetRemMember(cl
, obj
, (APTR
)msg
); break;
276 case GM_RENDER
: rc
= WBSetRender(cl
, obj
, (APTR
)msg
); break;
277 default: rc
= DoSuperMethodA(cl
, obj
, msg
); break;
283 Class
*WBSet_MakeClass(struct WorkbookBase
*wb
)
287 cl
= MakeClass( NULL
, "groupgclass", NULL
,
288 sizeof(struct wbSet
),
291 cl
->cl_Dispatcher
.h_Entry
= HookEntry
;
292 cl
->cl_Dispatcher
.h_SubEntry
= dispatcher
;
293 cl
->cl_Dispatcher
.h_Data
= NULL
;
294 cl
->cl_UserData
= (IPTR
)wb
;