gwenhywfar
4.3.1
|
00001 /*************************************************************************** 00002 begin : Mon Feb 22 2010 00003 copyright : (C) 2010 by Martin Preuss 00004 email : martin@libchipcard.de 00005 00006 *************************************************************************** 00007 * Please see toplevel file COPYING for license details * 00008 ***************************************************************************/ 00009 00010 #ifdef HAVE_CONFIG_H 00011 # include <config.h> 00012 #endif 00013 00014 #define DISABLE_DEBUGLOG 00015 00016 00017 #include "o_grid_p.h" 00018 #include "o_gridentry_l.h" 00019 00020 #include <gwenhywfar/debug.h> 00021 00022 00023 00024 GWEN_INHERIT(HTML_OBJECT, OBJECT_GRID); 00025 00026 00027 #define MAX_COLUMN 32 00028 #define COLUMN_SPACING 4 00029 #define ROW_SPACING 4 00030 00031 00032 00033 static int HtmlObject_Grid_Layout(HTML_OBJECT *o) { 00034 OBJECT_GRID *xo; 00035 HTML_OBJECT *c; 00036 int w; 00037 int h; 00038 int x; 00039 int y; 00040 int rv; 00041 int i; 00042 int j; 00043 int cw[MAX_COLUMN]; 00044 int maxLineHeight; 00045 int maxLineWidth; 00046 int currentRow; 00047 00048 assert(o); 00049 xo=GWEN_INHERIT_GETDATA(HTML_OBJECT, OBJECT_GRID, o); 00050 assert(xo); 00051 00052 w=HtmlObject_GetWidth(o); 00053 h=HtmlObject_GetHeight(o); 00054 00055 /* subtract spacing from available width */ 00056 if (w!=-1) 00057 w-=(xo->columns+1)*COLUMN_SPACING; 00058 00059 /* determine the maximum width of each column */ 00060 for (i=0; i<xo->columns; i++) 00061 cw[i]=0; 00062 c=HtmlObject_Tree_GetFirstChild(o); 00063 while(c) { 00064 int k; 00065 00066 i=HtmlObject_GridEntry_GetColumn(c); 00067 HtmlObject_SetHeight(c, -1); 00068 HtmlObject_SetWidth(c, -1); 00069 rv=HtmlObject_Layout(c); 00070 if (rv<0) { 00071 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00072 return rv; 00073 } 00074 k=HtmlObject_GetWidth(c); 00075 if (k>cw[i]) 00076 cw[i]=k; 00077 c=HtmlObject_Tree_GetNext(c); 00078 } 00079 00080 if (w!=-1) { 00081 /* do the columns all fit into the width? */ 00082 x=0; 00083 for (i=0; i<xo->columns; i++) 00084 x+=cw[i]; 00085 00086 if (x>w) { 00087 int fullw[MAX_COLUMN]; 00088 int meanColumnWidth; 00089 int k; 00090 00091 /* doesn't fit, so we need to adjust the columns */ 00092 meanColumnWidth=w/xo->columns; 00093 00094 /* reset full width of every column */ 00095 for (i=0; i<xo->columns; i++) 00096 fullw[i]=0; 00097 /* calculate full width of every column */ 00098 c=HtmlObject_Tree_GetFirstChild(o); 00099 while(c) { 00100 i=HtmlObject_GridEntry_GetColumn(c); 00101 k=HtmlObject_GetWidth(c); 00102 if (k>fullw[i]) 00103 fullw[i]=k; 00104 c=HtmlObject_Tree_GetNext(c); 00105 } 00106 00107 for (i=0; i<xo->columns; i++) 00108 cw[i]=0; 00109 00110 /* set fixed widths to those columns which are smaller than fullWidth/columns */ 00111 k=0; 00112 for (i=0; i<xo->columns; i++) { 00113 int p; 00114 00115 p=fullw[i]; 00116 if (p<=meanColumnWidth) { 00117 k+=p; 00118 cw[i]=p; 00119 } 00120 } 00121 /* now get the remaining width */ 00122 j=0; 00123 k=w-k; 00124 for (i=0; i<xo->columns; i++) { 00125 if (cw[i]==0) 00126 j+=fullw[i]; 00127 } 00128 00129 if (j>0) { 00130 /* calculate percentual width of each remaining column */ 00131 for (i=0; i<xo->columns; i++) { 00132 if (cw[i]==0) { 00133 int p; 00134 00135 p=fullw[i]*100/j; 00136 cw[i]=p*k/100; 00137 } 00138 } 00139 } 00140 00141 /* re-layout columns */ 00142 c=HtmlObject_Tree_GetFirstChild(o); 00143 while(c) { 00144 i=HtmlObject_GridEntry_GetColumn(c); 00145 HtmlObject_SetHeight(c, -1); 00146 HtmlObject_SetWidth(c, cw[i]); 00147 rv=HtmlObject_Layout(c); 00148 if (rv<0) { 00149 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00150 return rv; 00151 } 00152 c=HtmlObject_Tree_GetNext(c); 00153 } 00154 } 00155 } 00156 00157 /* now layout elements according to column sizes */ 00158 x=COLUMN_SPACING/2; 00159 y=ROW_SPACING/2; 00160 maxLineHeight=0; 00161 maxLineWidth=0; 00162 currentRow=0; 00163 c=HtmlObject_Tree_GetFirstChild(o); 00164 while(c) { 00165 int r; 00166 int ch; 00167 00168 i=HtmlObject_GridEntry_GetColumn(c); 00169 r=HtmlObject_GridEntry_GetRow(c); 00170 if (r!=currentRow) { 00171 /* next row */ 00172 y+=maxLineHeight+ROW_SPACING; 00173 x=COLUMN_SPACING/2; 00174 currentRow=r; 00175 maxLineHeight=0; 00176 } 00177 00178 HtmlObject_SetWidth(c, cw[i]); 00179 HtmlObject_Layout(c); 00180 00181 /* place object */ 00182 HtmlObject_SetX(c, x); 00183 HtmlObject_SetY(c, y); 00184 00185 /* calculate maximum height */ 00186 ch=HtmlObject_GetHeight(c); 00187 if (ch>maxLineHeight) 00188 maxLineHeight=ch; 00189 00190 /* advance */ 00191 x+=cw[i]+COLUMN_SPACING; 00192 if (x>maxLineWidth) 00193 maxLineWidth=x; 00194 c=HtmlObject_Tree_GetNext(c); 00195 } 00196 y+=maxLineHeight+(ROW_SPACING/2); 00197 00198 HtmlObject_SetWidth(o, maxLineWidth); 00199 HtmlObject_SetHeight(o, y); 00200 00201 return 0; 00202 } 00203 00204 00205 00206 HTML_OBJECT *HtmlObject_Grid_new(GWEN_XML_CONTEXT *ctx) { 00207 HTML_OBJECT *o; 00208 OBJECT_GRID *xo; 00209 00210 o=HtmlObject_new(ctx, HtmlObjectType_Grid); 00211 GWEN_NEW_OBJECT(OBJECT_GRID, xo); 00212 GWEN_INHERIT_SETDATA(HTML_OBJECT, OBJECT_GRID, o, xo, HtmlObject_Grid_FreeData); 00213 00214 HtmlObject_AddFlags(o, 00215 HTML_OBJECT_FLAGS_START_ON_NEWLINE | 00216 HTML_OBJECT_FLAGS_END_WITH_NEWLINE); 00217 HtmlObject_SetLayoutFn(o, HtmlObject_Grid_Layout); 00218 00219 return o; 00220 } 00221 00222 00223 00224 void GWENHYWFAR_CB HtmlObject_Grid_FreeData(void *bp, void *p) { 00225 OBJECT_GRID *xo; 00226 00227 xo=(OBJECT_GRID*) p; 00228 00229 GWEN_FREE_OBJECT(xo); 00230 } 00231 00232 00233 00234 int HtmlObject_Grid_GetRows(const HTML_OBJECT *o) { 00235 OBJECT_GRID *xo; 00236 00237 assert(o); 00238 xo=GWEN_INHERIT_GETDATA(HTML_OBJECT, OBJECT_GRID, o); 00239 assert(xo); 00240 00241 return xo->rows; 00242 } 00243 00244 00245 00246 void HtmlObject_Grid_SetRows(HTML_OBJECT *o, int i) { 00247 OBJECT_GRID *xo; 00248 00249 assert(o); 00250 xo=GWEN_INHERIT_GETDATA(HTML_OBJECT, OBJECT_GRID, o); 00251 assert(xo); 00252 00253 xo->rows=i; 00254 } 00255 00256 00257 00258 int HtmlObject_Grid_GetColumns(const HTML_OBJECT *o) { 00259 OBJECT_GRID *xo; 00260 00261 assert(o); 00262 xo=GWEN_INHERIT_GETDATA(HTML_OBJECT, OBJECT_GRID, o); 00263 assert(xo); 00264 00265 return xo->columns; 00266 } 00267 00268 00269 00270 void HtmlObject_Grid_SetColumns(HTML_OBJECT *o, int i) { 00271 OBJECT_GRID *xo; 00272 00273 assert(o); 00274 xo=GWEN_INHERIT_GETDATA(HTML_OBJECT, OBJECT_GRID, o); 00275 assert(xo); 00276 00277 xo->columns=i; 00278 } 00279 00280 00281 00282 00283 00284