1 /* Monolith table layout class.
2 * - by Richard W.M. Jones <rich@annexia.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 * $Id: ml_table_layout.c,v 1.3 2002/11/13 20:46:38 rich Exp $
27 #include <pthr_iolib.h>
29 #include "ml_widget.h"
31 #include "ml_table_layout.h"
33 static void repaint (void *, ml_session, const char *, io_handle);
34 static struct ml_widget_property properties[];
36 struct ml_widget_operations table_layout_ops =
39 properties: properties
44 ml_widget w; /* Widget stored in the cell. */
45 const char *clazz; /* Stylesheet class. */
46 unsigned char rowspan; /* Rowspan. */
47 unsigned char colspan; /* Colspan. */
48 unsigned char flags; /* Various flags. */
49 #define CELL_FLAGS_NO_PAINT 0x01
50 #define CELL_FLAGS_IS_HEADER 0x02
51 char align; /* l|r|c */
52 char valign; /* t|b|m */
55 struct ml_table_layout
57 struct ml_widget_operations *ops;
58 pool pool; /* Pool for allocations. */
59 int rows, cols; /* Number of rows, columns. */
60 const char *clazz; /* Stylesheet class for the whole table. */
62 /* Cells are stored in this 2D array. */
66 static struct ml_widget_property properties[] =
69 offset: ml_offsetof (struct ml_table_layout, clazz),
70 type: ML_PROP_STRING },
74 static inline struct cell *
75 get_cell (ml_table_layout w, int row, int col)
77 assert (0 <= row && row < w->rows);
78 assert (0 <= col && col < w->cols);
79 return &w->cells[row][col];
83 init_cell (ml_table_layout w, int r, int c)
86 w->cells[r][c].clazz = 0;
87 w->cells[r][c].rowspan = 1;
88 w->cells[r][c].colspan = 1;
89 w->cells[r][c].flags = 0;
90 w->cells[r][c].align = 'l';
91 w->cells[r][c].valign = 'm';
95 new_ml_table_layout (pool pool, int rows, int cols)
97 ml_table_layout w = pmalloc (pool, sizeof *w);
100 w->ops = &table_layout_ops;
106 w->cells = pmalloc (pool, sizeof (struct cell *) * rows);
107 for (r = 0; r < rows; ++r)
109 w->cells[r] = pmalloc (pool, sizeof (struct cell) * cols);
110 for (c = 0; c < cols; ++c)
118 ml_table_layout_pack (ml_table_layout w, ml_widget _w, int row, int col)
120 get_cell (w, row, col)->w = _w;
124 ml_table_layout_add_row (ml_table_layout w)
128 w->cells = prealloc (w->pool,
129 w->cells, sizeof (struct cell *) * (w->rows+1));
130 w->cells[w->rows] = pmalloc (w->pool, sizeof (struct cell) * w->cols);
132 for (c = 0; c < w->cols; ++c)
133 init_cell (w, w->rows, c);
139 ml_table_layout_set_colspan (ml_table_layout w, int row, int col, int colspan)
141 assert (colspan > 0);
142 assert (col + colspan <= w->cols);
143 get_cell (w, row, col)->colspan = colspan;
147 ml_table_layout_set_rowspan (ml_table_layout w, int row, int col, int rowspan)
149 assert (rowspan > 0);
150 assert (row + rowspan <= w->rows);
151 get_cell (w, row, col)->rowspan = rowspan;
155 ml_table_layout_set_align (ml_table_layout w, int row, int col,
158 get_cell (w, row, col)->align = align[0];
162 ml_table_layout_set_valign (ml_table_layout w, int row, int col,
165 get_cell (w, row, col)->valign = valign[0];
169 ml_table_layout_set_class (ml_table_layout w, int row, int col,
172 get_cell (w, row, col)->clazz = clazz;
176 ml_table_layout_set_header (ml_table_layout w, int row, int col,
180 get_cell (w, row, col)->flags |= CELL_FLAGS_IS_HEADER;
182 get_cell (w, row, col)->flags &= ~CELL_FLAGS_IS_HEADER;
186 repaint (void *vw, ml_session session, const char *windowid, io_handle io)
188 ml_table_layout w = (ml_table_layout) vw;
191 /* Clear all the NO_PAINT flags. */
192 for (r = 0; r < w->rows; ++r)
193 for (c = 0; c < w->cols; ++c)
194 get_cell (w, r, c)->flags &= ~CELL_FLAGS_NO_PAINT;
196 /* Start of the table. */
197 io_fputs ("<table", io);
198 if (w->clazz) io_fprintf (io, " class=\"%s\"", w->clazz);
201 /* Paint the cells. */
202 for (r = 0; r < w->rows; ++r)
204 io_fprintf (io, "<tr>");
206 for (c = 0; c < w->cols; ++c)
208 struct cell *cl = get_cell (w, r, c);
210 if (!(cl->flags & CELL_FLAGS_NO_PAINT))
214 /* If there is a row or column span > 1, then we need to mark
215 * the cells in the "shadow" as not painted.
217 for (i = 0; i < cl->rowspan; ++i)
218 for (j = 0; j < cl->colspan; ++j)
219 get_cell (w, r+i, c+j)->flags |= CELL_FLAGS_NO_PAINT;
221 if (!(cl->flags & CELL_FLAGS_IS_HEADER))
222 io_fprintf (io, "<td");
224 io_fprintf (io, "<th");
226 io_fprintf (io, " class=\"%s\"", cl->clazz);
228 io_fprintf (io, " rowspan=\"%d\"", cl->rowspan);
230 io_fprintf (io, " colspan=\"%d\"", cl->colspan);
231 if (cl->align == 'r')
232 io_fprintf (io, " align=\"right\"");
233 else if (cl->align == 'c')
234 io_fprintf (io, " align=\"center\"");
235 if (cl->valign == 't')
236 io_fprintf (io, " valign=\"top\"");
237 else if (cl->valign == 'b')
238 io_fprintf (io, " valign=\"bottom\"");
239 io_fprintf (io, ">");
241 ml_widget_repaint (cl->w, session, windowid, io);
243 io_fprintf (io, " ");
244 if (!(cl->flags & CELL_FLAGS_IS_HEADER))
245 io_fprintf (io, "</td>\n");
247 io_fprintf (io, "</th>\n");
251 io_fprintf (io, "</tr>\n");
254 io_fprintf (io, "</table>");