Fix for BCPL string handling.
[AROS-Contrib.git] / vpdf / mcc / lay_class.c
blobb9f64ad75ec09b1e9892877343f9298c9a09a039
2 #include <proto/exec.h>
3 #include <proto/dos.h>
4 #include <proto/muimaster.h>
5 #include <proto/utility.h>
6 #include <proto/intuition.h>
7 #include <proto/graphics.h>
8 #include <clib/alib_protos.h>
9 #include <string.h>
10 #include <stdio.h>
11 #include <math.h>
13 #include <private/vapor/vapor.h>
14 #include "lay_class.h"
16 #include "util.h"
18 struct Data
20 int n; /* number of children */
21 int w; /* width of children */
22 int h; /* height of children */
23 int hs; /* horiz spacing */
24 int vs; /* vert spacing */
26 int columns;
28 int width, height;
29 int center;
30 int vertdist;
31 int childcount;
32 int keeppos;
35 MUI_HOOK(layoutfunc, APTR grp, struct MUI_LayoutMsg *lm)
37 struct IClass *cl = (struct IClass*)(h->h_Data);
38 struct Data *data = INST_DATA(cl, grp);
39 float vgpos = (float)xget(grp, MUIA_Virtgroup_Top) / xget(grp, MUIA_Virtgroup_Height);
41 switch (lm->lm_Type)
43 case MUILM_MINMAX:
45 register Object *child;
46 Object *cstate;
47 unsigned int n, done = FALSE;
49 // look for first visible child dimensions (reference)
51 for (n = 0, cstate = (Object *)lm->lm_Children->mlh_Head; (child = NextObject(&cstate)); n++)
53 ULONG sm;
55 get(child,MUIA_ShowMe,&sm);
56 if (!sm) continue;
58 if (!done)
60 data->w = _minwidth(child);
61 data->h = _minheight(child);
63 done = TRUE;
67 data->n = n;
69 lm->lm_MinMax.MinWidth = data->w;
70 lm->lm_MinMax.MinHeight = data->h;
71 lm->lm_MinMax.DefWidth = data->w;
72 lm->lm_MinMax.DefHeight = data->h;
73 lm->lm_MinMax.MaxWidth = MUI_MAXMAX;
74 lm->lm_MinMax.MaxHeight = MUI_MAXMAX;
76 return 0;
79 case MUILM_LAYOUT:
81 register Object *child;
82 Object *cstate;
83 int il, it, ir, ib, w, h, c, r, x, y, n, nd, wd, hd, hsd, vsd;
84 int hborder;
85 int count = 0;
86 int height;
88 get(grp, MUIA_InnerLeft, &il);
89 get(grp, MUIA_InnerTop, &it);
90 get(grp, MUIA_InnerRight, &ir);
91 get(grp, MUIA_InnerBottom, &ib);
93 il = it = ir = ib = 0;
95 get(grp, MUIA_Width, &w);
96 get(grp, MUIA_Height, &h);
98 w = _mwidth(grp);
99 h = _mheight(grp);
101 nd = data->n;
102 wd = data->w;
103 hd = data->h;
104 hsd = data->hs;
105 vsd = data->vs;
107 for (c = 1; ; c++)
109 x = il+hsd*(c-1)+c*wd+ir;
111 if (x == w) break;
113 if (x>w)
115 if (c > 1)
116 c--;
118 break;
122 x = il;
123 y = it;
125 if (data->center)
126 hborder = ( w - ( c - 1 ) * hsd - c * wd ) / 2;
127 else
128 hborder = 0;
130 r = nd/c;
131 if (nd%c>0)
132 r++;
134 height = it+r*hd+vsd*(r-1)+ib;
136 /* keep focus on same entry */
138 if (data->keeppos)
140 nfset(grp, MUIA_Virtgroup_Top, (int)(height * vgpos));
141 data->keeppos = FALSE;
144 for (n = 0, cstate = (Object *)lm->lm_Children->mlh_Head; (child = NextObject(&cstate)); )
146 //ULONG sm;
148 //get(child,MUIA_ShowMe,&sm);
149 //if (!sm) continue;
151 if (!MUI_Layout(child,x + hborder,y,wd,hd,0))
152 return FALSE;
154 n++;
156 if (n == c)
158 x = il;
159 y += hd+vsd;
160 n = 0;
162 else
164 x += wd+hsd;
167 count++;
170 lm->lm_Layout.Width = il+c*wd+hsd*(c-1)+ir;
171 lm->lm_Layout.Height = height;
173 data->columns = c;
174 data->vertdist = hd + vsd;
175 data->childcount = count;
177 return TRUE;
181 return MUILM_UNKNOWN;
184 DEFNEW
186 obj = DoSuperNew(cl,obj,
187 MUIA_Group_LayoutHook, (ULONG)&layoutfunc_hook,
188 MUIA_CustomBackfill, TRUE,
189 MUIA_Group_SameSize, TRUE,
190 TAG_MORE, INITTAGS);
192 layoutfunc_hook.h_Data = cl;
194 if (obj != NULL)
196 GETDATA;
198 data->hs = GetTagData(MUIA_Lay_HorizSpacing, 4, INITTAGS);
199 data->vs = GetTagData(MUIA_Lay_VertSpacing, 4, INITTAGS);
200 data->center = GetTagData(MUIA_Lay_Center, TRUE, INITTAGS);
201 data->columns = 1;
205 return (ULONG)obj;
208 void kprintf(char *fmt, ...);
209 #ifndef min
210 #define min(a,b) ((a)<(b)?(a):(b))
211 #endif
213 static void *buildregionfromicons(struct Data *data, Object *obj, int x1, int y1, int x2, int y2)
215 struct Region *clipregion = NewRegion();
217 if (clipregion != NULL)
219 int vpos = xget(obj, MUIA_Virtgroup_Top);
220 int vtop = _top(obj) + vpos;
221 struct Rectangle r;
222 int columns = data->columns;
223 int n = 0;
224 int cwidth = 0, cheight = 0;
225 int cleft = 0;
226 int ctop = 0;
227 int i;
228 int count = data->childcount;
230 void *first = (void*)DoMethod(obj, MUIM_Group_GetChild, MUIV_Group_GetChild_First);
232 /* initial region */
234 r.MinX = x1;
235 r.MinY = y1;
236 r.MaxX = x2;
237 r.MaxY = y2;
238 OrRectRegion(clipregion, &r);
240 /* first child position */
242 if (first != NULL)
244 ctop = xget(first, MUIA_TopEdge) + vpos;
245 cleft = _left(first);
246 cwidth = _width(first);
247 cheight = _height(first);
249 else
251 return clipregion;
255 int skip;
257 /* skip entries which are avobe top */
259 skip = (vtop - ctop) / (data->vertdist);
260 ctop += skip * data->vertdist;
261 count -= columns * skip;
263 /* calculate number of remaining entries we need to process */
265 count = min(count, columns * ( 1 + ceil((float)xget(obj, MUIA_Height) / data->vertdist)));
268 for(i = 0; i<count; i++)
270 if (n == columns)
272 ctop += data->vertdist;
273 cleft = _left(first);
274 n = 0;
277 r.MinX = cleft;
278 r.MinY = ctop - vpos;
279 r.MaxX = r.MinX + cwidth - 1;
280 r.MaxY = ctop + cheight - 1 - vpos;
282 /* remove the area */
283 ClearRectRegion(clipregion, &r);
285 cleft += cwidth + data->hs;
286 n++;
292 #if 0
294 int i = 0;
295 struct RegionRectangle *rr = clipregion->RegionRectangle;
296 while(rr)
298 i++;
299 rr = rr->Next;
302 kprintf("Number of regions:%d for blit:%d,%d,%d,%d\n", i, x1, y1, x2, y2);
304 #endif
306 return clipregion;
309 DEFMMETHOD(Backfill)
311 GETDATA;
314 APTR cliphandle = NULL;
315 struct Region *clipregion = NULL;
317 if (msg->bottom < msg->top)
318 return 0;
319 if (msg->right < msg->left)
320 return 0;
323 if (muiRenderInfo(obj) != NULL && (data->width != _width(obj) || data->height != _height(obj) || (msg->right - msg->left + 1 == _mwidth(obj) && msg->bottom - msg->top + 1 == _mheight(obj)) ))
326 * Iterate through thumbs and mask them from backfill.
329 data->width = _width(obj);
330 data->height = _height(obj);
331 clipregion = buildregionfromicons(data, obj, msg->left, msg->top, msg->right, msg->bottom);
333 if (clipregion != NULL)
335 cliphandle = MUI_AddClipRegion(muiRenderInfo(obj), clipregion);
339 /* draw */
341 DOSUPER;
343 if (clipregion != NULL)
345 MUI_RemoveClipRegion(muiRenderInfo(obj), cliphandle); /* DisposeRegion() is done by MUI */
349 return (0);
352 DEFSET
354 GETDATA;
356 FORTAG(INITTAGS)
358 case MUIA_Lay_KeepPosition:
359 data->keeppos = tag->ti_Data;
360 break;
362 NEXTTAG
364 return DOSUPER;
367 BEGINMTABLE
368 DECMMETHOD(Backfill)
369 DECSET
370 DECNEW
371 ENDMTABLE
373 DECSUBCLASS_NC(MUIC_Virtgroup, LayClass)