gwenhywfar  4.3.3
o_grid.c
Go to the documentation of this file.
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