1 /***************************************************************************
2  begin       : Mon Feb 22 2010
3  copyright   : (C) 2010 by Martin Preuss
4  email       : martin@libchipcard.de
5 
6  ***************************************************************************
7  *          Please see toplevel file COPYING for license details           *
8  ***************************************************************************/
9 
10 #ifdef HAVE_CONFIG_H
11 # include <config.h>
12 #endif
13 
14 #define DISABLE_DEBUGLOG
15 
16 
17 #include "o_grid_p.h"
18 #include "o_gridentry_l.h"
19 
20 #include <gwenhywfar/debug.h>
21 
22 
23 
24 GWEN_INHERIT(HTML_OBJECT, OBJECT_GRID);
25 
26 
27 #define MAX_COLUMN     32
28 #define COLUMN_SPACING 4
29 #define ROW_SPACING    4
30 
31 
32 
HtmlObject_Grid_Layout(HTML_OBJECT * o)33 static int HtmlObject_Grid_Layout(HTML_OBJECT *o)
34 {
35   OBJECT_GRID *xo;
36   HTML_OBJECT *c;
37   int w;
38   //int h;
39   int x;
40   int y;
41   int rv;
42   int i;
43   int j;
44   int cw[MAX_COLUMN];
45   int maxLineHeight;
46   int maxLineWidth;
47   int currentRow;
48 
49   assert(o);
50   xo=GWEN_INHERIT_GETDATA(HTML_OBJECT, OBJECT_GRID, o);
51   assert(xo);
52 
53   w=HtmlObject_GetWidth(o);
54   //h=HtmlObject_GetHeight(o);
55 
56   /* subtract spacing from available width */
57   if (w!=-1)
58     w-=(xo->columns+1)*COLUMN_SPACING;
59 
60   /* determine the maximum width of each column */
61   for (i=0; i<xo->columns; i++)
62     cw[i]=0;
63   c=HtmlObject_Tree_GetFirstChild(o);
64   while (c) {
65     int k;
66 
67     i=HtmlObject_GridEntry_GetColumn(c);
68     HtmlObject_SetHeight(c, -1);
69     HtmlObject_SetWidth(c, -1);
70     rv=HtmlObject_Layout(c);
71     if (rv<0) {
72       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
73       return rv;
74     }
75     k=HtmlObject_GetWidth(c);
76     if (k>cw[i])
77       cw[i]=k;
78     c=HtmlObject_Tree_GetNext(c);
79   }
80 
81   if (w!=-1) {
82     /* do the columns all fit into the width? */
83     x=0;
84     for (i=0; i<xo->columns; i++)
85       x+=cw[i];
86 
87     if (x>w) {
88       int fullw[MAX_COLUMN];
89       int meanColumnWidth;
90       int k;
91 
92       /* doesn't fit, so we need to adjust the columns */
93       meanColumnWidth=w/xo->columns;
94 
95       /* reset full width of every column */
96       for (i=0; i<xo->columns; i++)
97         fullw[i]=0;
98       /* calculate full width of every column */
99       c=HtmlObject_Tree_GetFirstChild(o);
100       while (c) {
101         i=HtmlObject_GridEntry_GetColumn(c);
102         k=HtmlObject_GetWidth(c);
103         if (k>fullw[i])
104           fullw[i]=k;
105         c=HtmlObject_Tree_GetNext(c);
106       }
107 
108       for (i=0; i<xo->columns; i++)
109         cw[i]=0;
110 
111       /* set fixed widths to those columns which are smaller than fullWidth/columns */
112       k=0;
113       for (i=0; i<xo->columns; i++) {
114         int p;
115 
116         p=fullw[i];
117         if (p<=meanColumnWidth) {
118           k+=p;
119           cw[i]=p;
120         }
121       }
122       /* now get the remaining width */
123       j=0;
124       k=w-k;
125       for (i=0; i<xo->columns; i++) {
126         if (cw[i]==0)
127           j+=fullw[i];
128       }
129 
130       if (j>0) {
131         /* calculate percentual width of each remaining column */
132         for (i=0; i<xo->columns; i++) {
133           if (cw[i]==0) {
134             int p;
135 
136             p=fullw[i]*100/j;
137             cw[i]=p*k/100;
138           }
139         }
140       }
141 
142       /* re-layout columns */
143       c=HtmlObject_Tree_GetFirstChild(o);
144       while (c) {
145         i=HtmlObject_GridEntry_GetColumn(c);
146         HtmlObject_SetHeight(c, -1);
147         HtmlObject_SetWidth(c, cw[i]);
148         rv=HtmlObject_Layout(c);
149         if (rv<0) {
150           DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
151           return rv;
152         }
153         c=HtmlObject_Tree_GetNext(c);
154       }
155     }
156   }
157 
158   /* now layout elements according to column sizes */
159   x=COLUMN_SPACING/2;
160   y=ROW_SPACING/2;
161   maxLineHeight=0;
162   maxLineWidth=0;
163   currentRow=0;
164   c=HtmlObject_Tree_GetFirstChild(o);
165   while (c) {
166     int r;
167     int ch;
168 
169     i=HtmlObject_GridEntry_GetColumn(c);
170     r=HtmlObject_GridEntry_GetRow(c);
171     if (r!=currentRow) {
172       /* next row */
173       y+=maxLineHeight+ROW_SPACING;
174       x=COLUMN_SPACING/2;
175       currentRow=r;
176       maxLineHeight=0;
177     }
178 
179     HtmlObject_SetWidth(c, cw[i]);
180     HtmlObject_Layout(c);
181 
182     /* place object */
183     HtmlObject_SetX(c, x);
184     HtmlObject_SetY(c, y);
185 
186     /* calculate maximum height */
187     ch=HtmlObject_GetHeight(c);
188     if (ch>maxLineHeight)
189       maxLineHeight=ch;
190 
191     /* advance */
192     x+=cw[i]+COLUMN_SPACING;
193     if (x>maxLineWidth)
194       maxLineWidth=x;
195     c=HtmlObject_Tree_GetNext(c);
196   }
197   y+=maxLineHeight+(ROW_SPACING/2);
198 
199   HtmlObject_SetWidth(o, maxLineWidth);
200   HtmlObject_SetHeight(o, y);
201 
202   return 0;
203 }
204 
205 
206 
HtmlObject_Grid_new(GWEN_XML_CONTEXT * ctx)207 HTML_OBJECT *HtmlObject_Grid_new(GWEN_XML_CONTEXT *ctx)
208 {
209   HTML_OBJECT *o;
210   OBJECT_GRID *xo;
211 
212   o=HtmlObject_new(ctx, HtmlObjectType_Grid);
213   GWEN_NEW_OBJECT(OBJECT_GRID, xo);
214   GWEN_INHERIT_SETDATA(HTML_OBJECT, OBJECT_GRID, o, xo, HtmlObject_Grid_FreeData);
215 
216   HtmlObject_AddFlags(o,
217                       HTML_OBJECT_FLAGS_START_ON_NEWLINE |
218                       HTML_OBJECT_FLAGS_END_WITH_NEWLINE);
219   HtmlObject_SetLayoutFn(o, HtmlObject_Grid_Layout);
220 
221   return o;
222 }
223 
224 
225 
HtmlObject_Grid_FreeData(GWEN_UNUSED void * bp,void * p)226 void GWENHYWFAR_CB HtmlObject_Grid_FreeData(GWEN_UNUSED void *bp, void *p)
227 {
228   OBJECT_GRID *xo;
229 
230   xo=(OBJECT_GRID *) p;
231 
232   GWEN_FREE_OBJECT(xo);
233 }
234 
235 
236 
HtmlObject_Grid_GetRows(const HTML_OBJECT * o)237 int HtmlObject_Grid_GetRows(const HTML_OBJECT *o)
238 {
239   OBJECT_GRID *xo;
240 
241   assert(o);
242   xo=GWEN_INHERIT_GETDATA(HTML_OBJECT, OBJECT_GRID, o);
243   assert(xo);
244 
245   return xo->rows;
246 }
247 
248 
249 
HtmlObject_Grid_SetRows(HTML_OBJECT * o,int i)250 void HtmlObject_Grid_SetRows(HTML_OBJECT *o, int i)
251 {
252   OBJECT_GRID *xo;
253 
254   assert(o);
255   xo=GWEN_INHERIT_GETDATA(HTML_OBJECT, OBJECT_GRID, o);
256   assert(xo);
257 
258   xo->rows=i;
259 }
260 
261 
262 
HtmlObject_Grid_GetColumns(const HTML_OBJECT * o)263 int HtmlObject_Grid_GetColumns(const HTML_OBJECT *o)
264 {
265   OBJECT_GRID *xo;
266 
267   assert(o);
268   xo=GWEN_INHERIT_GETDATA(HTML_OBJECT, OBJECT_GRID, o);
269   assert(xo);
270 
271   return xo->columns;
272 }
273 
274 
275 
HtmlObject_Grid_SetColumns(HTML_OBJECT * o,int i)276 void HtmlObject_Grid_SetColumns(HTML_OBJECT *o, int i)
277 {
278   OBJECT_GRID *xo;
279 
280   assert(o);
281   xo=GWEN_INHERIT_GETDATA(HTML_OBJECT, OBJECT_GRID, o);
282   assert(xo);
283 
284   xo->columns=i;
285 }
286 
287 
288 
289 
290 
291 
292