2 Copyright © 2002-2013, The AROS Development Team. All rights reserved.
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 */
20 #include "muimaster_intern.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
))
35 struct Scrollgroup_DATA
*data
=
36 (struct Scrollgroup_DATA
*)hook
->h_Data
;
42 /* Calculate the minmax dimension of the group.
43 ** We only have a fixed number of children, so we need
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
);
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));
105 /* Now place the objects between
106 * (0,0,lm->lm_Layout.Width-1,lm->lm_Layout.Height-1)
111 LONG virt_minwidth
= 0;
112 LONG virt_minheight
= 0;
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
,
136 get(data
->contents
, MUIA_Virtgroup_MinHeight
,
138 virt_minwidth
-= _subwidth(data
->contents
);
139 virt_minheight
-= _subheight(data
->contents
);
142 _maxwidth(data
->contents
) - _subwidth(data
->contents
);
144 _maxheight(data
->contents
) - _subheight(data
->contents
);
147 CLAMP(cont_width
, virt_minwidth
, virt_maxwidth
);
149 CLAMP(cont_height
, virt_minheight
, virt_maxheight
);
151 if (virt_width
> cont_width
)
153 cont_height
-= horiz_height
;
155 CLAMP(cont_height
, virt_minheight
, virt_maxheight
);
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
;
165 CLAMP(cont_width
, virt_minwidth
, virt_maxheight
);
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
;
176 CLAMP(cont_height
, virt_minheight
, virt_maxheight
);
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);
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
,
198 MUI_Layout(data
->horiz
, 0, cont_height
, cont_width
,
200 MUI_Layout(data
->button
, cont_width
, cont_height
,
201 vert_width
, horiz_height
, 0);
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
,
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
,
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));
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
))
251 struct Scrollgroup_DATA
*data
=
252 (struct Scrollgroup_DATA
*)hook
->h_Data
;
254 SIPTR type
= (SIPTR
) msg
[0];
255 SIPTR val
= (SIPTR
) msg
[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
);
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
);
275 nnset(data
->horiz
, MUIA_Prop_First
, val
);
278 nnset(data
->vert
, MUIA_Prop_First
, val
);
286 IPTR
Scrollgroup__OM_NEW(struct IClass
*cl
, Object
*obj
,
289 struct Scrollgroup_DATA
*data
;
290 //struct TagItem *tags,*tag;
292 (Object
*) GetTagData(MUIA_Scrollgroup_Contents
, 0,
294 Object
*vert
, *horiz
, *button
, *group
;
296 Tag hbordertag
= TAG_IGNORE
;
297 Tag vbordertag
= TAG_IGNORE
;
299 struct Hook
*layout_hook
= mui_alloc_struct(struct Hook
);
303 layout_hook
->h_Entry
= (HOOKFUNC
) Scrollgroup_Layout_Function
;
306 GetTagData(MUIA_Scrollgroup_UseWinBorder
, FALSE
, msg
->ops_AttrList
);
309 hbordertag
= MUIA_Prop_UseWinBorder
;
310 vbordertag
= MUIA_Prop_UseWinBorder
;
313 obj
= (Object
*) DoSuperNewTags
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
,
323 Child
, (IPTR
) (horiz
=
324 (Object
*) ScrollbarObject
, MUIA_Group_Horiz
, TRUE
,
325 hbordertag
, MUIV_Prop_UseWinBorder_Bottom
,
327 Child
, (IPTR
) (button
=
328 (Object
*) ScrollbuttonObject
,
331 TAG_MORE
, msg
->ops_AttrList
);
335 mui_free(layout_hook
);
339 data
= INST_DATA(cl
, obj
);
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,
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
));
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
;
378 case MUIA_Scrollgroup_HorizBar
:
379 STORE
= (IPTR
) data
->horiz
;
381 case MUIA_Scrollgroup_VertBar
:
382 STORE
= (IPTR
) data
->vert
;
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
)
424 return Scrollgroup__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
426 return Scrollgroup__OM_GET(cl
, obj
, (struct opGet
*)msg
);
428 return Scrollgroup__OM_DISPOSE(cl
, obj
, msg
);
430 return Scrollgroup__MUIM_Show(cl
, obj
, (struct MUIP_Show
*)msg
);
432 return DoSuperMethodA(cl
, obj
, msg
);
435 BOOPSI_DISPATCHER_END
437 const struct __MUIBuiltinClass _MUI_Scrollgroup_desc
=
441 sizeof(struct Scrollgroup_DATA
),
442 (void *) Scrollgroup_Dispatcher
444 #endif /* ZUNE_BUILTIN_SCROLLGROUP */