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