revert between 56095 -> 55830 in arch
[AROS.git] / workbench / system / Workbook / wbset.c
blobdeb07b589c8a12e86e3ec39d6f2daae59d9e2288
1 /*
2 Copyright © 2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Workbook Icon Set Class
6 Lang: english
7 */
9 #define DEBUG 0
10 #include <aros/debug.h>
12 #include <string.h>
13 #include <limits.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"
27 #include "classes.h"
29 struct wbSetNode {
30 struct MinNode sn_Node;
31 Object *sn_Object; /* Gadget object */
34 struct wbSet {
35 WORD MaxWidth;
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;
55 struct IBox sbox;
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;
75 struct IBox ibox;
77 wbGABox(wb, iobj, &ibox);
79 if ((CurrRight + ibox.Width) < my->MaxWidth) {
80 ibox.Left = CurrRight;
81 } else {
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);
98 // OM_ADDMEMBER
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;
103 struct IBox ibox;
104 struct wbSet *my = INST_DATA(cl, obj);
105 struct wbSetNode *node;
106 IPTR rc;
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 ||
115 ibox.Top == ~0) {
116 AddHead(&my->AutoObjects, (struct Node *)&node->sn_Node);
117 } else {
118 AddHead(&my->FixedObjects, (struct Node *)&node->sn_Node);
121 rc = DoSuperMethodA(cl, obj, (Msg)opm);
123 /* Recalculate the set's positions */
124 rearrange(cl, obj);
126 return rc;
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;
134 IPTR rc;
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 */
153 rearrange(cl, obj);
155 return rc;
158 // OM_NEW
159 static IPTR WBSetNew(Class *cl, Object *obj, struct opSet *ops)
161 struct WorkbookBase *wb = (APTR)cl->cl_UserData;
162 struct wbSet *my;
163 IPTR rc;
165 rc = DoSuperMethodA(cl, obj, (Msg)ops);
166 if (rc == 0)
167 return 0;
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);
176 return rc;
179 static IPTR WBSetGet(Class *cl, Object *obj, struct opGet *opg)
181 struct wbSet *my = INST_DATA(cl, obj);
182 IPTR rc = TRUE;
184 switch (opg->opg_AttrID) {
185 case WBSA_MaxWidth:
186 *(opg->opg_Storage) = (IPTR)my->MaxWidth;
187 break;
188 default:
189 rc = DoSuperMethodA(cl, obj, (Msg)opg);
190 break;
193 return rc;
196 // OM_SET/OM_UPDATE
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);
201 IPTR rc;
202 struct TagItem *tag;
203 struct TagItem *tstate;
205 rc = DoSuperMethodA(cl, obj, (Msg)opu);
207 if ((opu->MethodID == OM_UPDATE) && (opu->opu_Flags & OPUF_INTERIM))
208 return rc;
210 tstate = opu->opu_AttrList;
211 while ((tag = NextTagItem(&tstate))) {
212 switch (tag->ti_Tag) {
213 case WBSA_MaxWidth:
214 my->MaxWidth = (WORD)tag->ti_Data;
215 rearrange(cl, obj);
216 rc |= TRUE;
217 default:
218 break;
222 return rc;
227 // OM_DISPOSE
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);
247 // GM_RENDER
248 static IPTR WBSetRender(Class *cl, Object *obj, struct gpRender *gpr)
250 struct WorkbookBase *wb = (APTR)cl->cl_UserData;
251 struct IBox box;
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)
266 IPTR rc = 0;
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;
280 return rc;
283 Class *WBSet_MakeClass(struct WorkbookBase *wb)
285 Class *cl;
287 cl = MakeClass( NULL, "groupgclass", NULL,
288 sizeof(struct wbSet),
290 if (cl != NULL) {
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;
297 return cl;