2 Copyright © 2002-2006, 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
= (struct Scrollgroup_DATA
*)hook
->h_Data
;
40 /* Calulate the minmax dimension of the group,
41 ** We only have a fixed number of children, so we need no NextObject()
44 if (data
->usewinborder
)
46 lm
->lm_MinMax
.MinWidth
= _minwidth(data
->contents
);
47 lm
->lm_MinMax
.MinHeight
= _minheight(data
->contents
);
48 lm
->lm_MinMax
.DefWidth
= _defwidth(data
->contents
);
49 lm
->lm_MinMax
.DefHeight
= _defheight(data
->contents
);
50 lm
->lm_MinMax
.MaxWidth
= _maxwidth(data
->contents
);
51 lm
->lm_MinMax
.MaxHeight
= _maxheight(data
->contents
);
57 WORD maxxxxheight
= 0;
59 maxxxxwidth
= _minwidth(data
->contents
);
60 if (_minwidth(data
->horiz
) > maxxxxwidth
) maxxxxwidth
= _minwidth(data
->horiz
);
61 maxxxxwidth
+= _minwidth(data
->vert
);
62 lm
->lm_MinMax
.MinWidth
= maxxxxwidth
;
64 maxxxxheight
= _minheight(data
->contents
);
65 if (_minheight(data
->vert
) > maxxxxheight
) maxxxxheight
= _minheight(data
->vert
);
66 maxxxxheight
+= _minheight(data
->horiz
);
67 lm
->lm_MinMax
.MinHeight
= maxxxxheight
;
69 maxxxxwidth
= _defwidth(data
->contents
);
70 if (_defwidth(data
->horiz
) > maxxxxwidth
) maxxxxwidth
= _defwidth(data
->horiz
);
71 if (maxxxxwidth
< lm
->lm_MinMax
.MinWidth
) maxxxxwidth
= lm
->lm_MinMax
.MinWidth
;
72 lm
->lm_MinMax
.DefWidth
= maxxxxwidth
;
74 maxxxxheight
= _defheight(data
->contents
);
75 if (_defheight(data
->vert
) > maxxxxheight
) maxxxxheight
= _defheight(data
->vert
);
76 if (maxxxxheight
< lm
->lm_MinMax
.MinHeight
) maxxxxheight
= lm
->lm_MinMax
.MinHeight
;
77 lm
->lm_MinMax
.DefHeight
= maxxxxheight
;
79 lm
->lm_MinMax
.MaxWidth
= MUI_MAXMAX
;
80 lm
->lm_MinMax
.MaxHeight
= MUI_MAXMAX
;
83 //kprintf("scrollgroup minmax: min %d x %d def %d x %d\n",
84 // lm->lm_MinMax.MinWidth, lm->lm_MinMax.MinHeight,
85 // lm->lm_MinMax.DefWidth, lm->lm_MinMax.DefHeight);
87 //kprintf("contents minmax: min %d x %d def %d x %d\n",
88 // _minwidth(data->contents), _minheight(data->contents),
89 // _defwidth(data->contents), _defheight(data->contents));
96 /* Now place the objects between (0,0,lm->lm_Layout.Width-1,lm->lm_Layout.Height-1)
105 LONG vert_width
= _minwidth(data
->vert
);
106 LONG horiz_height
= _minheight(data
->horiz
);
107 LONG lay_width
= lm
->lm_Layout
.Width
;
108 LONG lay_height
= lm
->lm_Layout
.Height
;
109 LONG cont_width
= lay_width
- _subwidth(data
->contents
);
110 LONG cont_height
= lay_height
- _subheight(data
->contents
);
111 BOOL vbar
= FALSE
, hbar
= FALSE
;
113 if (!data
->usewinborder
)
115 //kprintf("scrollgroup layout: %d x %d sub contents size %d,%d\n",
116 // lay_width, lay_height, _subwidth(data->contents), _subheight(data->contents));
118 /* layout the virtual group a first time, to determine the virtual width/height */
119 //MUI_Layout(data->contents,0,0,lay_width,lay_height,0);
121 get(data
->contents
, MUIA_Virtgroup_MinWidth
, &virt_minwidth
);
122 get(data
->contents
, MUIA_Virtgroup_MinHeight
, &virt_minheight
);
123 virt_minwidth
-= _subwidth(data
->contents
);
124 virt_minheight
-= _subheight(data
->contents
);
126 virt_maxwidth
= _maxwidth(data
->contents
) - _subwidth(data
->contents
);
127 virt_maxheight
= _maxheight(data
->contents
) - _subheight(data
->contents
);
129 virt_width
= CLAMP(cont_width
, virt_minwidth
, virt_maxwidth
);
130 virt_height
= CLAMP(cont_height
, virt_minheight
, virt_maxheight
);
132 if (virt_width
> cont_width
)
134 cont_height
-= horiz_height
;
135 virt_height
= CLAMP(cont_height
, virt_minheight
, virt_maxheight
);
138 //kprintf(" 1: %d x %d hbar %d vbar %d\n", cont_width, cont_height, hbar, vbar);
140 if (virt_height
> cont_height
)
142 cont_width
-= vert_width
;
143 virt_width
= CLAMP(cont_width
, virt_minwidth
, virt_maxheight
);
146 //kprintf(" 2: %d x %d hbar %d vbar %d\n", cont_width, cont_height, hbar, vbar);
148 /* We need to check this a 2nd time!! */
149 if (!hbar
&& (virt_width
> cont_width
))
151 cont_height
-= horiz_height
;
152 virt_height
= CLAMP(cont_height
, virt_minheight
, virt_maxheight
);
155 //kprintf(" 3: %d x %d hbar %d vbar %d\n", cont_width, cont_height, hbar, vbar);
157 } /* if (!data->usewinborder) */
159 cont_width
+= _subwidth(data
->contents
);
160 cont_height
+= _subheight(data
->contents
);
162 //kprintf("cont_size layouted to %d,%d\n", cont_width, cont_height);
166 /* We need all scrollbars and the button */
167 set(data
->vert
, MUIA_ShowMe
, TRUE
); /* We could also overload MUIM_Show... */
168 set(data
->horiz
, MUIA_ShowMe
, TRUE
);
169 set(data
->button
, MUIA_ShowMe
, TRUE
);
170 MUI_Layout(data
->vert
, cont_width
, 0, vert_width
, cont_height
,0);
171 MUI_Layout(data
->horiz
, 0, cont_height
, cont_width
, horiz_height
, 0);
172 MUI_Layout(data
->button
, cont_width
, cont_height
, vert_width
, horiz_height
, 0);
176 set(data
->vert
, MUIA_ShowMe
, TRUE
);
177 set(data
->horiz
, MUIA_ShowMe
, FALSE
);
178 set(data
->button
, MUIA_ShowMe
, FALSE
);
180 MUI_Layout(data
->vert
, cont_width
, 0, vert_width
, cont_height
,0);
184 set(data
->vert
, MUIA_ShowMe
, FALSE
);
185 set(data
->horiz
, MUIA_ShowMe
, TRUE
);
186 set(data
->button
, MUIA_ShowMe
, FALSE
);
188 MUI_Layout(data
->horiz
, 0, cont_height
, cont_width
, horiz_height
, 0);
190 else if (!data
->usewinborder
)
192 set(data
->vert
, MUIA_ShowMe
, FALSE
);
193 set(data
->horiz
, MUIA_ShowMe
, FALSE
);
194 set(data
->button
, MUIA_ShowMe
, FALSE
);
197 /* Layout the group a second time, note that setting _mwidth() and _mheight() should be enough, or we invent a new flag */
198 MUI_Layout(data
->contents
,0,0,cont_width
,cont_height
,0);
200 //kprintf(" contents size after layout: %d x %d inner %d x %d\n",
201 // _width(data->contents), _height(data->contents),
202 // _mwidth(data->contents), _mheight(data->contents));
212 AROS_UFH3(ULONG
,Scrollgroup_Function
,
213 AROS_UFHA(struct Hook
*, hook
, A0
),
214 AROS_UFHA(APTR
, dummy
, A2
),
215 AROS_UFHA(void **, msg
, A1
))
219 struct Scrollgroup_DATA
*data
= (struct Scrollgroup_DATA
*)hook
->h_Data
;
220 int type
= (int)msg
[0];
221 LONG val
= (LONG
)msg
[1];
227 get(data
->vert
,MUIA_Prop_First
,&val
);
228 SetAttrs(data
->contents
,MUIA_Virtgroup_Top
, val
, MUIA_NoNotify
, TRUE
, MUIA_Group_Forward
, FALSE
, TAG_DONE
);
234 get(data
->horiz
,MUIA_Prop_First
,&val
);
235 SetAttrs(data
->contents
,MUIA_Virtgroup_Left
, val
, MUIA_NoNotify
, TRUE
, MUIA_Group_Forward
, FALSE
, TAG_DONE
);
238 case 3: nnset(data
->horiz
, MUIA_Prop_First
, val
); break;
239 case 4: nnset(data
->vert
, MUIA_Prop_First
, val
); break;
246 IPTR
Scrollgroup__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
248 struct Scrollgroup_DATA
*data
;
249 //struct TagItem *tags,*tag;
250 Object
*contents
= (Object
*)GetTagData(MUIA_Scrollgroup_Contents
, 0, msg
->ops_AttrList
);
251 Object
*vert
,*horiz
,*button
,*group
;
253 Tag hbordertag
= TAG_IGNORE
;
254 Tag vbordertag
= TAG_IGNORE
;
256 struct Hook
*layout_hook
= mui_alloc_struct(struct Hook
);
257 if (!layout_hook
) return 0;
259 layout_hook
->h_Entry
= (HOOKFUNC
)Scrollgroup_Layout_Function
;
261 usewinborder
= GetTagData(MUIA_Scrollgroup_UseWinBorder
, FALSE
, msg
->ops_AttrList
);
264 hbordertag
= MUIA_Prop_UseWinBorder
;
265 vbordertag
= MUIA_Prop_UseWinBorder
;
268 obj
= (Object
*) DoSuperNewTags
272 MUIA_Group_Horiz
, FALSE
,
273 Child
, (IPTR
) (group
= (Object
*)GroupObject
,
274 MUIA_Group_LayoutHook
, (IPTR
) layout_hook
,
275 Child
, (IPTR
) contents
,
276 Child
, (IPTR
) (vert
= (Object
*)ScrollbarObject
, MUIA_Group_Horiz
, FALSE
, vbordertag
, MUIV_Prop_UseWinBorder_Right
, End
),
277 Child
, (IPTR
) (horiz
= (Object
*)ScrollbarObject
, MUIA_Group_Horiz
, TRUE
, hbordertag
, MUIV_Prop_UseWinBorder_Bottom
, End
),
278 Child
, (IPTR
) (button
= (Object
*)ScrollbuttonObject
, End
),
286 mui_free(layout_hook
);
290 data
= INST_DATA(cl
, obj
);
293 data
->button
= button
;
294 data
->contents
= contents
;
295 data
->usewinborder
= usewinborder
;
297 data
->hook
.h_Entry
= (HOOKFUNC
)Scrollgroup_Function
;
298 data
->hook
.h_Data
= data
;
299 data
->layout_hook
= layout_hook
;
300 layout_hook
->h_Data
= data
;
302 DoMethod(vert
, MUIM_Notify
, MUIA_Prop_First
, MUIV_EveryTime
, (IPTR
)obj
, 4, MUIM_CallHook
, (IPTR
)&data
->hook
, 1, MUIV_TriggerValue
);
303 DoMethod(horiz
, MUIM_Notify
, MUIA_Prop_First
, MUIV_EveryTime
, (IPTR
)obj
, 4, MUIM_CallHook
, (IPTR
)&data
->hook
, 2, MUIV_TriggerValue
);
304 DoMethod(contents
, MUIM_Group_DoMethodNoForward
, MUIM_Notify
, MUIA_Virtgroup_Left
, MUIV_EveryTime
, (IPTR
)obj
, 4, MUIM_CallHook
, (IPTR
)&data
->hook
, 3, MUIV_TriggerValue
);
305 DoMethod(contents
, MUIM_Group_DoMethodNoForward
, MUIM_Notify
, MUIA_Virtgroup_Top
, MUIV_EveryTime
, (IPTR
)obj
, 4, MUIM_CallHook
, (IPTR
)&data
->hook
, 4, MUIV_TriggerValue
);
307 D(bug("Scrollgroup_New(%lx)\n", obj
));
308 D(bug(" vert = %lx, horiz = %lx, button = %lx\n", vert
, horiz
, button
));
312 IPTR
Scrollgroup__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
314 struct Scrollgroup_DATA
*data
= INST_DATA(cl
, obj
);
315 mui_free(data
->layout_hook
);
316 return DoSuperMethodA(cl
,obj
,msg
);
319 IPTR
Scrollgroup__MUIM_Show(struct IClass
*cl
, Object
*obj
, struct MUIP_Show
*msg
)
321 struct Scrollgroup_DATA
*data
= INST_DATA(cl
, obj
);
322 LONG top
,left
,width
,height
;
324 get(data
->contents
, MUIA_Virtgroup_Left
, &left
);
325 get(data
->contents
, MUIA_Virtgroup_Top
, &top
);
326 get(data
->contents
, MUIA_Virtgroup_Width
, &width
);
327 get(data
->contents
, MUIA_Virtgroup_Height
, &height
);
329 SetAttrs(data
->horiz
, MUIA_Prop_First
, left
,
330 MUIA_Prop_Entries
, width
,
331 MUIA_Prop_Visible
, _mwidth(data
->contents
),
335 SetAttrs(data
->vert
, MUIA_Prop_First
, top
,
336 MUIA_Prop_Entries
, height
,
337 MUIA_Prop_Visible
, _mheight(data
->contents
),
340 return DoSuperMethodA(cl
,obj
,(Msg
)msg
);
343 #if ZUNE_BUILTIN_SCROLLGROUP
344 BOOPSI_DISPATCHER(IPTR
, Scrollgroup_Dispatcher
, cl
, obj
, msg
)
346 switch (msg
->MethodID
)
348 case OM_NEW
: return Scrollgroup__OM_NEW(cl
, obj
, (struct opSet
*) msg
);
349 case OM_DISPOSE
: return Scrollgroup__OM_DISPOSE(cl
, obj
, msg
);
350 case MUIM_Show
: return Scrollgroup__MUIM_Show(cl
, obj
, (struct MUIP_Show
*)msg
);
351 default: return DoSuperMethodA(cl
, obj
, msg
);
354 BOOPSI_DISPATCHER_END
356 const struct __MUIBuiltinClass _MUI_Scrollgroup_desc
=
360 sizeof(struct Scrollgroup_DATA
),
361 (void*)Scrollgroup_Dispatcher
363 #endif /* ZUNE_BUILTIN_SCROLLGROUP */