revert between 56095 -> 55830 in arch
[AROS.git] / workbench / libs / muimaster / classes / scrollgroup.c
blob57492d07d464afbcae1db881c7e463bacec74f4d
1 /*
2 Copyright © 2002-2013, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define MUIMASTER_YES_INLINE_STDARG
8 #include <exec/memory.h>
9 #include <intuition/icclass.h>
10 #include <intuition/gadgetclass.h>
11 #include <clib/alib_protos.h>
12 #include <proto/exec.h>
13 #include <proto/intuition.h>
14 #include <proto/utility.h>
15 #include <proto/muimaster.h>
17 /* #define MYDEBUG 1 */
18 #include "debug.h"
19 #include "mui.h"
20 #include "muimaster_intern.h"
21 #include "support.h"
22 #include "support_classes.h"
23 #include "scrollgroup_private.h"
25 extern struct Library *MUIMasterBase;
28 AROS_UFH3(ULONG, Scrollgroup_Layout_Function,
29 AROS_UFHA(struct Hook *, hook, A0),
30 AROS_UFHA(Object *, obj, A2),
31 AROS_UFHA(struct MUI_LayoutMsg *, lm, A1))
33 AROS_USERFUNC_INIT
35 struct Scrollgroup_DATA *data =
36 (struct Scrollgroup_DATA *)hook->h_Data;
38 switch (lm->lm_Type)
40 case MUILM_MINMAX:
42 /* Calculate the minmax dimension of the group.
43 ** We only have a fixed number of children, so we need
44 ** no NextObject()
47 if (data->usewinborder)
49 lm->lm_MinMax.MinWidth = _minwidth(data->contents);
50 lm->lm_MinMax.MinHeight = _minheight(data->contents);
51 lm->lm_MinMax.DefWidth = _defwidth(data->contents);
52 lm->lm_MinMax.DefHeight = _defheight(data->contents);
53 lm->lm_MinMax.MaxWidth = _maxwidth(data->contents);
54 lm->lm_MinMax.MaxHeight = _maxheight(data->contents);
57 else
59 WORD maxxxxwidth = 0;
60 WORD maxxxxheight = 0;
62 maxxxxwidth = _minwidth(data->contents);
63 if (_minwidth(data->horiz) > maxxxxwidth)
64 maxxxxwidth = _minwidth(data->horiz);
65 maxxxxwidth += _minwidth(data->vert);
66 lm->lm_MinMax.MinWidth = maxxxxwidth;
68 maxxxxheight = _minheight(data->contents);
69 if (_minheight(data->vert) > maxxxxheight)
70 maxxxxheight = _minheight(data->vert);
71 maxxxxheight += _minheight(data->horiz);
72 lm->lm_MinMax.MinHeight = maxxxxheight;
74 maxxxxwidth = _defwidth(data->contents);
75 if (_defwidth(data->horiz) > maxxxxwidth)
76 maxxxxwidth = _defwidth(data->horiz);
77 if (maxxxxwidth < lm->lm_MinMax.MinWidth)
78 maxxxxwidth = lm->lm_MinMax.MinWidth;
79 lm->lm_MinMax.DefWidth = maxxxxwidth;
81 maxxxxheight = _defheight(data->contents);
82 if (_defheight(data->vert) > maxxxxheight)
83 maxxxxheight = _defheight(data->vert);
84 if (maxxxxheight < lm->lm_MinMax.MinHeight)
85 maxxxxheight = lm->lm_MinMax.MinHeight;
86 lm->lm_MinMax.DefHeight = maxxxxheight;
88 lm->lm_MinMax.MaxWidth = MUI_MAXMAX;
89 lm->lm_MinMax.MaxHeight = MUI_MAXMAX;
92 //kprintf("scrollgroup minmax: min %d x %d def %d x %d\n",
93 // lm->lm_MinMax.MinWidth, lm->lm_MinMax.MinHeight,
94 // lm->lm_MinMax.DefWidth, lm->lm_MinMax.DefHeight);
96 //kprintf("contents minmax: min %d x %d def %d x %d\n",
97 // _minwidth(data->contents), _minheight(data->contents),
98 // _defwidth(data->contents), _defheight(data->contents));
100 return 0;
103 case MUILM_LAYOUT:
105 /* Now place the objects between
106 * (0,0,lm->lm_Layout.Width-1,lm->lm_Layout.Height-1)
109 LONG virt_width;
110 LONG virt_height;
111 LONG virt_minwidth = 0;
112 LONG virt_minheight = 0;
113 LONG virt_maxwidth;
114 LONG virt_maxheight;
115 LONG vert_width = _minwidth(data->vert);
116 LONG horiz_height = _minheight(data->horiz);
117 LONG lay_width = lm->lm_Layout.Width;
118 LONG lay_height = lm->lm_Layout.Height;
119 LONG cont_width = lay_width - _subwidth(data->contents);
120 LONG cont_height = lay_height - _subheight(data->contents);
121 BOOL vbar = FALSE, hbar = FALSE;
123 if (!data->usewinborder)
125 //kprintf("scrollgroup layout: "
126 // "%d x %d sub contents size %d,%d\n",
127 // lay_width, lay_height, _subwidth(data->contents),
128 // _subheight(data->contents));
130 /* layout the virtual group a first time, to determine
131 * the virtual width/height */
132 //MUI_Layout(data->contents,0,0,lay_width,lay_height,0);
134 get(data->contents, MUIA_Virtgroup_MinWidth,
135 &virt_minwidth);
136 get(data->contents, MUIA_Virtgroup_MinHeight,
137 &virt_minheight);
138 virt_minwidth -= _subwidth(data->contents);
139 virt_minheight -= _subheight(data->contents);
141 virt_maxwidth =
142 _maxwidth(data->contents) - _subwidth(data->contents);
143 virt_maxheight =
144 _maxheight(data->contents) - _subheight(data->contents);
146 virt_width =
147 CLAMP(cont_width, virt_minwidth, virt_maxwidth);
148 virt_height =
149 CLAMP(cont_height, virt_minheight, virt_maxheight);
151 if (virt_width > cont_width)
153 cont_height -= horiz_height;
154 virt_height =
155 CLAMP(cont_height, virt_minheight, virt_maxheight);
156 hbar = TRUE;
158 //kprintf(" 1: %d x %d hbar %d vbar %d\n",
159 // cont_width, cont_height, hbar, vbar);
161 if (virt_height > cont_height)
163 cont_width -= vert_width;
164 virt_width =
165 CLAMP(cont_width, virt_minwidth, virt_maxheight);
166 vbar = TRUE;
168 //kprintf(" 2: %d x %d hbar %d vbar %d\n",
169 // cont_width, cont_height, hbar, vbar);
171 /* We need to check this a 2nd time!! */
172 if (!hbar && (virt_width > cont_width))
174 cont_height -= horiz_height;
175 virt_height =
176 CLAMP(cont_height, virt_minheight, virt_maxheight);
177 hbar = TRUE;
179 //kprintf(" 3: %d x %d hbar %d vbar %d\n",
180 // cont_width, cont_height, hbar, vbar);
183 cont_width += _subwidth(data->contents);
184 cont_height += _subheight(data->contents);
186 //kprintf("cont_size layouted to %d,%d\n",
187 // cont_width, cont_height);
189 if (hbar && vbar)
191 /* We need all scrollbars and the button */
192 set(data->vert, MUIA_ShowMe, TRUE);
193 /* We could also overload MUIM_Show... */
194 set(data->horiz, MUIA_ShowMe, TRUE);
195 set(data->button, MUIA_ShowMe, TRUE);
196 MUI_Layout(data->vert, cont_width, 0, vert_width,
197 cont_height, 0);
198 MUI_Layout(data->horiz, 0, cont_height, cont_width,
199 horiz_height, 0);
200 MUI_Layout(data->button, cont_width, cont_height,
201 vert_width, horiz_height, 0);
203 else if (vbar)
205 set(data->vert, MUIA_ShowMe, TRUE);
206 set(data->horiz, MUIA_ShowMe, FALSE);
207 set(data->button, MUIA_ShowMe, FALSE);
209 MUI_Layout(data->vert, cont_width, 0, vert_width,
210 cont_height, 0);
212 else if (hbar)
214 set(data->vert, MUIA_ShowMe, FALSE);
215 set(data->horiz, MUIA_ShowMe, TRUE);
216 set(data->button, MUIA_ShowMe, FALSE);
218 MUI_Layout(data->horiz, 0, cont_height, cont_width,
219 horiz_height, 0);
221 else if (!data->usewinborder)
223 set(data->vert, MUIA_ShowMe, FALSE);
224 set(data->horiz, MUIA_ShowMe, FALSE);
225 set(data->button, MUIA_ShowMe, FALSE);
228 /* Layout the group a second time, note that setting _mwidth()
229 * and _mheight() should be enough, or we invent a new flag */
230 MUI_Layout(data->contents, 0, 0, cont_width, cont_height, 0);
232 //kprintf(" contents size after layout: %d x %d inner %d x %d\n",
233 // _width(data->contents), _height(data->contents),
234 // _mwidth(data->contents), _mheight(data->contents));
235 return 1;
238 return 0;
240 AROS_USERFUNC_EXIT
244 AROS_UFH3(ULONG, Scrollgroup_Function,
245 AROS_UFHA(struct Hook *, hook, A0),
246 AROS_UFHA(APTR, dummy, A2),
247 AROS_UFHA(void **, msg, A1))
249 AROS_USERFUNC_INIT
251 struct Scrollgroup_DATA *data =
252 (struct Scrollgroup_DATA *)hook->h_Data;
254 SIPTR type = (SIPTR) msg[0];
255 SIPTR val = (SIPTR) msg[1];
257 switch (type)
259 case 1:
261 get(data->vert, MUIA_Prop_First, &val);
262 SetAttrs(data->contents, MUIA_Virtgroup_Top, val, MUIA_NoNotify,
263 TRUE, MUIA_Group_Forward, FALSE, TAG_DONE);
264 break;
267 case 2:
269 get(data->horiz, MUIA_Prop_First, &val);
270 SetAttrs(data->contents, MUIA_Virtgroup_Left, val,
271 MUIA_NoNotify, TRUE, MUIA_Group_Forward, FALSE, TAG_DONE);
272 break;
274 case 3:
275 nnset(data->horiz, MUIA_Prop_First, val);
276 break;
277 case 4:
278 nnset(data->vert, MUIA_Prop_First, val);
279 break;
281 return 0;
283 AROS_USERFUNC_EXIT
286 IPTR Scrollgroup__OM_NEW(struct IClass *cl, Object *obj,
287 struct opSet *msg)
289 struct Scrollgroup_DATA *data;
290 //struct TagItem *tags,*tag;
291 Object *contents =
292 (Object *) GetTagData(MUIA_Scrollgroup_Contents, 0,
293 msg->ops_AttrList);
294 Object *vert, *horiz, *button, *group;
295 BOOL usewinborder;
296 Tag hbordertag = TAG_IGNORE;
297 Tag vbordertag = TAG_IGNORE;
299 struct Hook *layout_hook = mui_alloc_struct(struct Hook);
300 if (!layout_hook)
301 return 0;
303 layout_hook->h_Entry = (HOOKFUNC) Scrollgroup_Layout_Function;
305 usewinborder =
306 GetTagData(MUIA_Scrollgroup_UseWinBorder, FALSE, msg->ops_AttrList);
307 if (usewinborder)
309 hbordertag = MUIA_Prop_UseWinBorder;
310 vbordertag = MUIA_Prop_UseWinBorder;
313 obj = (Object *) DoSuperNewTags
314 (cl, obj, NULL,
315 MUIA_Group_Horiz, FALSE,
316 Child, (IPTR) (group = (Object *) GroupObject,
317 MUIA_Group_LayoutHook, (IPTR) layout_hook,
318 Child, (IPTR) contents,
319 Child, (IPTR) (vert =
320 (Object *) ScrollbarObject, MUIA_Group_Horiz, FALSE,
321 vbordertag, MUIV_Prop_UseWinBorder_Right,
322 End),
323 Child, (IPTR) (horiz =
324 (Object *) ScrollbarObject, MUIA_Group_Horiz, TRUE,
325 hbordertag, MUIV_Prop_UseWinBorder_Bottom,
326 End),
327 Child, (IPTR) (button =
328 (Object *) ScrollbuttonObject,
329 End),
330 End),
331 TAG_MORE, msg->ops_AttrList);
333 if (!obj)
335 mui_free(layout_hook);
336 return 0;
339 data = INST_DATA(cl, obj);
340 data->vert = vert;
341 data->horiz = horiz;
342 data->button = button;
343 data->contents = contents;
344 data->usewinborder = usewinborder;
346 data->hook.h_Entry = (HOOKFUNC) Scrollgroup_Function;
347 data->hook.h_Data = data;
348 data->layout_hook = layout_hook;
349 layout_hook->h_Data = data;
351 DoMethod(vert, MUIM_Notify, MUIA_Prop_First, MUIV_EveryTime, (IPTR) obj,
352 4, MUIM_CallHook, (IPTR) & data->hook, 1, MUIV_TriggerValue);
353 DoMethod(horiz, MUIM_Notify, MUIA_Prop_First, MUIV_EveryTime,
354 (IPTR) obj, 4, MUIM_CallHook, (IPTR) & data->hook, 2,
355 MUIV_TriggerValue);
356 DoMethod(contents, MUIM_Group_DoMethodNoForward, MUIM_Notify,
357 MUIA_Virtgroup_Left, MUIV_EveryTime, (IPTR) obj, 4, MUIM_CallHook,
358 (IPTR) & data->hook, 3, MUIV_TriggerValue);
359 DoMethod(contents, MUIM_Group_DoMethodNoForward, MUIM_Notify,
360 MUIA_Virtgroup_Top, MUIV_EveryTime, (IPTR) obj, 4, MUIM_CallHook,
361 (IPTR) & data->hook, 4, MUIV_TriggerValue);
363 D(bug("Scrollgroup_New(%lx)\n", obj));
364 D(bug(" vert = %lx, horiz = %lx, button = %lx\n", vert, horiz, button));
365 return (IPTR) obj;
368 IPTR Scrollgroup__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
370 struct Scrollgroup_DATA *data = INST_DATA(cl, obj);
371 #define STORE *(msg->opg_Storage)
373 switch (msg->opg_AttrID)
375 case MUIA_Scrollgroup_Contents:
376 STORE = (IPTR) data->contents;
377 return 1;
378 case MUIA_Scrollgroup_HorizBar:
379 STORE = (IPTR) data->horiz;
380 return 1;
381 case MUIA_Scrollgroup_VertBar:
382 STORE = (IPTR) data->vert;
383 return 1;
386 return DoSuperMethodA(cl, obj, (Msg) msg);
389 IPTR Scrollgroup__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
391 struct Scrollgroup_DATA *data = INST_DATA(cl, obj);
392 mui_free(data->layout_hook);
393 return DoSuperMethodA(cl, obj, msg);
396 IPTR Scrollgroup__MUIM_Show(struct IClass *cl, Object *obj,
397 struct MUIP_Show *msg)
399 struct Scrollgroup_DATA *data = INST_DATA(cl, obj);
400 LONG top = 0, left = 0, width = 0, height = 0;
402 get(data->contents, MUIA_Virtgroup_Left, &left);
403 get(data->contents, MUIA_Virtgroup_Top, &top);
404 get(data->contents, MUIA_Virtgroup_Width, &width);
405 get(data->contents, MUIA_Virtgroup_Height, &height);
407 SetAttrs(data->horiz, MUIA_Prop_First, left,
408 MUIA_Prop_Entries, width,
409 MUIA_Prop_Visible, _mwidth(data->contents), TAG_DONE);
411 SetAttrs(data->vert, MUIA_Prop_First, top,
412 MUIA_Prop_Entries, height,
413 MUIA_Prop_Visible, _mheight(data->contents), TAG_DONE);
415 return DoSuperMethodA(cl, obj, (Msg) msg);
418 #if ZUNE_BUILTIN_SCROLLGROUP
419 BOOPSI_DISPATCHER(IPTR, Scrollgroup_Dispatcher, cl, obj, msg)
421 switch (msg->MethodID)
423 case OM_NEW:
424 return Scrollgroup__OM_NEW(cl, obj, (struct opSet *)msg);
425 case OM_GET:
426 return Scrollgroup__OM_GET(cl, obj, (struct opGet *)msg);
427 case OM_DISPOSE:
428 return Scrollgroup__OM_DISPOSE(cl, obj, msg);
429 case MUIM_Show:
430 return Scrollgroup__MUIM_Show(cl, obj, (struct MUIP_Show *)msg);
431 default:
432 return DoSuperMethodA(cl, obj, msg);
435 BOOPSI_DISPATCHER_END
437 const struct __MUIBuiltinClass _MUI_Scrollgroup_desc =
439 MUIC_Scrollgroup,
440 MUIC_Group,
441 sizeof(struct Scrollgroup_DATA),
442 (void *) Scrollgroup_Dispatcher
444 #endif /* ZUNE_BUILTIN_SCROLLGROUP */