[AdgDress] Rearranged builtin dresses
[adg.git] / src / adg / adg-table-style.c
blob0e751b73128127344a8ae0deb523c02f0d0514a1
1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007,2008,2009,2010 Nicola Fontana <ntd at entidi.it>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
21 /**
22 * SECTION:adg-table-style
23 * @short_description: Customization of table rendering
25 * Contains parameters on how to build tables such as the lines to
26 * use for frames and grids and the font dresses for titles or values.
29 /**
30 * AdgTableStyle:
32 * All fields are private and should not be used directly.
33 * Use its public methods instead.
34 **/
37 #include "adg-internal.h"
38 #include "adg-table-style.h"
39 #include "adg-table-style-private.h"
40 #include "adg-dress-builtins.h"
41 #include "adg-font-style.h"
42 #include "adg-line-style.h"
43 #include "adg-util.h"
46 enum {
47 PROP_0,
48 PROP_COLOR_DRESS,
49 PROP_GRID_DRESS,
50 PROP_FRAME_DRESS,
51 PROP_TITLE_DRESS,
52 PROP_VALUE_DRESS,
53 PROP_ROW_HEIGHT,
54 PROP_CELL_PADDING,
55 PROP_CELL_SPACING
59 static void get_property (GObject *object,
60 guint prop_id,
61 GValue *value,
62 GParamSpec *pspec);
63 static void set_property (GObject *object,
64 guint prop_id,
65 const GValue *value,
66 GParamSpec *pspec);
67 static void apply (AdgStyle *style,
68 AdgEntity *entity,
69 cairo_t *cr);
70 static gboolean set_row_height (AdgTableStyle *table_style,
71 gdouble height);
72 static gboolean set_cell_padding (AdgTableStyle *table_style,
73 const AdgPair *padding);
74 static gboolean set_cell_spacing (AdgTableStyle *table_style,
75 const AdgPair *spacing);
78 G_DEFINE_TYPE(AdgTableStyle, adg_table_style, ADG_TYPE_STYLE);
81 static void
82 adg_table_style_class_init(AdgTableStyleClass *klass)
84 GObjectClass *gobject_class;
85 AdgStyleClass *style_class;
86 GParamSpec *param;
88 gobject_class = (GObjectClass *) klass;
89 style_class = (AdgStyleClass *) klass;
91 g_type_class_add_private(klass, sizeof(AdgTableStylePrivate));
93 gobject_class->get_property = get_property;
94 gobject_class->set_property = set_property;
96 style_class->apply = apply;
98 param = adg_param_spec_dress("color-dress",
99 P_("Color Dress"),
100 P_("Color dress for the whole tableension"),
101 ADG_DRESS_COLOR_TABLE,
102 G_PARAM_READWRITE);
103 g_object_class_install_property(gobject_class, PROP_COLOR_DRESS, param);
105 param = adg_param_spec_dress("grid-dress",
106 P_("Grid Dress"),
107 P_("Line dress to use while rendering the grid of the table"),
108 ADG_DRESS_LINE_TABLE,
109 G_PARAM_READWRITE);
110 g_object_class_install_property(gobject_class, PROP_GRID_DRESS, param);
112 param = adg_param_spec_dress("frame-dress",
113 P_("Frame Dress"),
114 P_("Line dress to use while drawing the table frame"),
115 ADG_DRESS_LINE_TABLE,
116 G_PARAM_READWRITE);
117 g_object_class_install_property(gobject_class, PROP_FRAME_DRESS, param);
119 param = adg_param_spec_dress("title-dress",
120 P_("Title Dress"),
121 P_("Font dress to use for titles"),
122 ADG_DRESS_TEXT_LIMIT,
123 G_PARAM_READWRITE);
124 g_object_class_install_property(gobject_class, PROP_TITLE_DRESS, param);
126 param = adg_param_spec_dress("value-dress",
127 P_("Value Dress"),
128 P_("Font dress to use for values inside the cells"),
129 ADG_DRESS_TEXT_VALUE,
130 G_PARAM_READWRITE);
131 g_object_class_install_property(gobject_class, PROP_VALUE_DRESS, param);
133 param = g_param_spec_double("row-height",
134 P_("Row Height"),
135 P_("The fallback row height when not explicitely specified while creating a new row"),
136 0, G_MAXDOUBLE, 30,
137 G_PARAM_READWRITE);
138 g_object_class_install_property(gobject_class, PROP_ROW_HEIGHT, param);
140 param = g_param_spec_boxed("cell-padding",
141 P_("Cell Padding"),
142 P_("How much space from the bounding box must left inside every cell"),
143 ADG_TYPE_PAIR,
144 G_PARAM_READWRITE);
145 g_object_class_install_property(gobject_class, PROP_CELL_PADDING, param);
147 param = g_param_spec_boxed("cell-spacing",
148 P_("Cell Spacing"),
149 P_("How much space to left between the cells"),
150 ADG_TYPE_PAIR,
151 G_PARAM_READWRITE);
152 g_object_class_install_property(gobject_class, PROP_CELL_SPACING, param);
155 static void
156 adg_table_style_init(AdgTableStyle *table_style)
158 AdgTableStylePrivate *data;
160 data = G_TYPE_INSTANCE_GET_PRIVATE(table_style, ADG_TYPE_TABLE_STYLE,
161 AdgTableStylePrivate);
163 data->color_dress = ADG_DRESS_COLOR_TABLE,
164 data->grid_dress = ADG_DRESS_LINE_TABLE;
165 data->frame_dress = ADG_DRESS_LINE_TABLE;
166 data->title_dress = ADG_DRESS_TEXT_LIMIT;
167 data->value_dress = ADG_DRESS_TEXT_VALUE;
168 data->row_height = 30;
169 data->cell_padding.x = 5;
170 data->cell_padding.y = 5;
171 data->cell_spacing.x = 0;
172 data->cell_spacing.y = 0;
174 table_style->data = data;
177 static void
178 get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
180 AdgTableStylePrivate *data = ((AdgTableStyle *) object)->data;
182 switch (prop_id) {
183 case PROP_COLOR_DRESS:
184 g_value_set_int(value, data->color_dress);
185 break;
186 case PROP_GRID_DRESS:
187 g_value_set_int(value, data->grid_dress);
188 break;
189 case PROP_FRAME_DRESS:
190 g_value_set_int(value, data->frame_dress);
191 break;
192 case PROP_TITLE_DRESS:
193 g_value_set_int(value, data->title_dress);
194 break;
195 case PROP_VALUE_DRESS:
196 g_value_set_int(value, data->value_dress);
197 break;
198 case PROP_ROW_HEIGHT:
199 g_value_set_double(value, data->row_height);
200 break;
201 case PROP_CELL_PADDING:
202 g_value_set_boxed(value, &data->cell_padding);
203 break;
204 case PROP_CELL_SPACING:
205 g_value_set_boxed(value, &data->cell_spacing);
206 break;
207 default:
208 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
209 break;
213 static void
214 set_property(GObject *object, guint prop_id,
215 const GValue *value, GParamSpec *pspec)
217 AdgTableStyle *table_style;
218 AdgTableStylePrivate *data;
220 table_style = (AdgTableStyle *) object;
221 data = table_style->data;
223 switch (prop_id) {
224 case PROP_COLOR_DRESS:
225 adg_dress_set(&data->color_dress, g_value_get_int(value));
226 break;
227 case PROP_GRID_DRESS:
228 adg_dress_set(&data->grid_dress, g_value_get_int(value));
229 break;
230 case PROP_FRAME_DRESS:
231 adg_dress_set(&data->frame_dress, g_value_get_int(value));
232 break;
233 case PROP_TITLE_DRESS:
234 adg_dress_set(&data->title_dress, g_value_get_int(value));
235 break;
236 case PROP_VALUE_DRESS:
237 adg_dress_set(&data->value_dress, g_value_get_int(value));
238 break;
239 case PROP_ROW_HEIGHT:
240 set_row_height(table_style, g_value_get_double(value));
241 break;
242 case PROP_CELL_PADDING:
243 set_cell_padding(table_style, g_value_get_boxed(value));
244 break;
245 case PROP_CELL_SPACING:
246 set_cell_spacing(table_style, g_value_get_boxed(value));
247 break;
248 default:
249 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
250 break;
256 * adg_table_style_new:
258 * Constructs a new empty table style initialized with default params.
260 * Returns: a new table style
262 AdgTableStyle *
263 adg_table_style_new(void)
265 return g_object_new(ADG_TYPE_TABLE_STYLE, NULL);
269 * adg_table_style_set_color_dress:
270 * @table_style: an #AdgTableStyle object
271 * @dress: the new color dress
273 * Sets a new color dress on @table_style.
275 void
276 adg_table_style_set_color_dress(AdgTableStyle *table_style, AdgDress dress)
278 AdgTableStylePrivate *data;
280 g_return_if_fail(ADG_IS_TABLE_STYLE(table_style));
282 data = table_style->data;
284 if (adg_dress_set(&data->color_dress, dress))
285 g_object_notify((GObject *) table_style, "color-dress");
289 * adg_table_style_get_color_dress:
290 * @table_style: an #AdgTableStyle object
292 * Gets the @table_style color dress to be used. This dress should be
293 * intended as a fallback color as it could be overriden by more
294 * specific dresses, such as a color explicitely specified on the
295 * #AdgTableStyle:value-dress.
297 * Returns: the color dress
299 AdgDress
300 adg_table_style_get_color_dress(AdgTableStyle *table_style)
302 AdgTableStylePrivate *data;
304 g_return_val_if_fail(ADG_IS_TABLE_STYLE(table_style), ADG_DRESS_UNDEFINED);
306 data = table_style->data;
308 return data->color_dress;
312 * adg_table_style_set_frame_dress:
313 * @table_style: an #AdgTableStyle object
314 * @dress: the new line dress
316 * Sets a new line dress on @table_style for rendering the frames.
318 void
319 adg_table_style_set_frame_dress(AdgTableStyle *table_style, AdgDress dress)
321 AdgTableStylePrivate *data;
323 g_return_if_fail(ADG_IS_TABLE_STYLE(table_style));
325 data = table_style->data;
327 if (adg_dress_set(&data->frame_dress, dress))
328 g_object_notify((GObject *) table_style, "frame-dress");
332 * adg_table_style_get_frame_dress:
333 * @table_style: an #AdgTableStyle object
335 * Gets the line dress to be used for rendering the frames with
336 * @table_style.
338 * Returns: the line dress
340 AdgDress
341 adg_table_style_get_frame_dress(AdgTableStyle *table_style)
343 AdgTableStylePrivate *data;
345 g_return_val_if_fail(ADG_IS_TABLE_STYLE(table_style), ADG_DRESS_UNDEFINED);
347 data = table_style->data;
349 return data->frame_dress;
353 * adg_table_style_set_grid_dress:
354 * @table_style: an #AdgTableStyle object
355 * @dress: the new line dress
357 * Sets a new line dress on @table_style for rendering the grids.
359 void
360 adg_table_style_set_grid_dress(AdgTableStyle *table_style, AdgDress dress)
362 AdgTableStylePrivate *data;
364 g_return_if_fail(ADG_IS_TABLE_STYLE(table_style));
366 data = table_style->data;
368 if (adg_dress_set(&data->grid_dress, dress))
369 g_object_notify((GObject *) table_style, "grid-dress");
373 * adg_table_style_get_grid_dress:
374 * @table_style: an #AdgTableStyle object
376 * Gets the line dress to be used for rendering the grids with
377 * @table_style.
379 * Returns: the line dress
381 AdgDress
382 adg_table_style_get_grid_dress(AdgTableStyle *table_style)
384 AdgTableStylePrivate *data;
386 g_return_val_if_fail(ADG_IS_TABLE_STYLE(table_style), ADG_DRESS_UNDEFINED);
388 data = table_style->data;
390 return data->grid_dress;
394 * adg_table_style_set_title_dress:
395 * @table_style: an #AdgTableStyle object
396 * @dress: the new font dress
398 * Sets a new font dress on @table_style for rendering cell titles.
400 void
401 adg_table_style_set_title_dress(AdgTableStyle *table_style, AdgDress dress)
403 AdgTableStylePrivate *data;
405 g_return_if_fail(ADG_IS_TABLE_STYLE(table_style));
407 data = table_style->data;
409 if (adg_dress_set(&data->title_dress, dress))
410 g_object_notify((GObject *) table_style, "title-dress");
414 * adg_table_style_get_title_dress:
415 * @table_style: an #AdgTableStyle object
417 * Gets the font dress to be used for rendering cell titles
418 * with @table_style.
420 * Returns: the font dress
422 AdgDress
423 adg_table_style_get_title_dress(AdgTableStyle *table_style)
425 AdgTableStylePrivate *data;
427 g_return_val_if_fail(ADG_IS_TABLE_STYLE(table_style), ADG_DRESS_UNDEFINED);
429 data = table_style->data;
431 return data->title_dress;
435 * adg_table_style_set_value_dress:
436 * @table_style: an #AdgTableStyle object
437 * @dress: the new font dress
439 * Sets a new font dress on @table_style for rendering cell values.
441 void
442 adg_table_style_set_value_dress(AdgTableStyle *table_style, AdgDress dress)
444 AdgTableStylePrivate *data;
446 g_return_if_fail(ADG_IS_TABLE_STYLE(table_style));
448 data = table_style->data;
450 if (adg_dress_set(&data->value_dress, dress))
451 g_object_notify((GObject *) table_style, "value-dress");
455 * adg_table_style_get_value_dress:
456 * @table_style: an #AdgTableStyle object
458 * Gets the font dress to be used for rendering cell values
459 * with @table_style.
461 * Returns: the font dress
463 AdgDress
464 adg_table_style_get_value_dress(AdgTableStyle *table_style)
466 AdgTableStylePrivate *data;
468 g_return_val_if_fail(ADG_IS_TABLE_STYLE(table_style), ADG_DRESS_UNDEFINED);
470 data = table_style->data;
472 return data->value_dress;
476 * adg_table_style_set_row_height:
477 * @table_style: an #AdgTableStyle object
478 * @heigth: the new row heigth fallback
480 * Sets a new #AdgTableStyle:row-height fallback. @height must
481 * be a valid row height greather than %0 or a warning will be
482 * raised and this function will fail.
484 void
485 adg_table_style_set_row_height(AdgTableStyle *table_style, gdouble height)
487 g_return_if_fail(ADG_IS_TABLE_STYLE(table_style));
489 if (set_row_height(table_style, height))
490 g_object_notify((GObject *) table_style, "row-height");
494 * adg_table_style_get_row_height:
495 * @table_style: an #AdgTableStyle object
497 * Gets the row height fallback value.
499 * Returns: the fallback row height or %0 on errors
501 gdouble
502 adg_table_style_get_row_height(AdgTableStyle *table_style)
504 AdgTableStylePrivate *data;
506 g_return_val_if_fail(ADG_IS_TABLE_STYLE(table_style), 0);
508 data = table_style->data;
510 return data->row_height;
514 * adg_table_style_set_cell_padding:
515 * @table_style: an #AdgTableStyle object
516 * @padding: the new padding values
518 * Sets new #AdgTableStyle:cell-padding values.
520 void
521 adg_table_style_set_cell_padding(AdgTableStyle *table_style,
522 const AdgPair *padding)
524 g_return_if_fail(ADG_IS_TABLE_STYLE(table_style));
526 if (set_cell_padding(table_style, padding))
527 g_object_notify((GObject *) table_style, "cell-padding");
531 * adg_table_style_get_cell_padding:
532 * @table_style: an #AdgTableStyle object
534 * Gets the padding values in x and y to be left clear inside the cells.
535 * The returned pointer refers to an internal allocated struct and
536 * must not be modified or freed.
538 * The cell padding is a symmetric value, that is the padding on the
539 * left will always be equal to the padding on the right and the top
540 * will always be equal to the bottom.
542 * Returns: the cell padding values or %NULL on errors
544 const AdgPair *
545 adg_table_style_get_cell_padding(AdgTableStyle *table_style)
547 AdgTableStylePrivate *data;
549 g_return_val_if_fail(ADG_IS_TABLE_STYLE(table_style), NULL);
551 data = table_style->data;
553 return &data->cell_padding;
557 * adg_table_style_set_cell_spacing:
558 * @table_style: an #AdgTableStyle object
559 * @spacing: the new spacing values
561 * Sets new #AdgTableStyle:cell-spacing values.
563 void
564 adg_table_style_set_cell_spacing(AdgTableStyle *table_style,
565 const AdgPair *spacing)
567 g_return_if_fail(ADG_IS_TABLE_STYLE(table_style));
569 if (set_cell_spacing(table_style, spacing))
570 g_object_notify((GObject *) table_style, "cell-spacing");
574 * adg_table_style_get_cell_spacing:
575 * @table_style: an #AdgTableStyle object
577 * Gets the spacing values in x and y to be left between the cell
578 * boundary boxes. The returned pointer refers to an internal
579 * allocated struct and must not be modified or freed.
581 * The cell spacing is a symmetric value, that is the spacing on the
582 * left will always be equal to the spacing on the right and the top
583 * will always be equal to the bottom.
585 * Returns: the cell spacing values or %NULL on errors
587 const AdgPair *
588 adg_table_style_get_cell_spacing(AdgTableStyle *table_style)
590 AdgTableStylePrivate *data;
592 g_return_val_if_fail(ADG_IS_TABLE_STYLE(table_style), NULL);
594 data = table_style->data;
596 return &data->cell_spacing;
600 static void
601 apply(AdgStyle *style, AdgEntity *entity, cairo_t *cr)
603 AdgTableStylePrivate *data = ((AdgTableStyle *) style)->data;
605 adg_entity_apply_dress(entity, data->color_dress, cr);
608 static gboolean
609 set_row_height(AdgTableStyle *table_style, gdouble height)
611 AdgTableStylePrivate *data = table_style->data;
613 /* A better approach would be to use the GParamSpec of this property */
614 g_return_val_if_fail(height >= 0, FALSE);
616 if (data->row_height == height)
617 return FALSE;
619 data->row_height = height;
620 return TRUE;
623 static gboolean
624 set_cell_padding(AdgTableStyle *table_style, const AdgPair *padding)
626 AdgTableStylePrivate *data;
628 g_return_val_if_fail(padding != NULL, FALSE);
630 data = table_style->data;
632 if (adg_pair_equal(&data->cell_padding, padding))
633 return FALSE;
635 data->cell_padding = *padding;
637 return TRUE;
640 static gboolean
641 set_cell_spacing(AdgTableStyle *table_style, const AdgPair *spacing)
643 AdgTableStylePrivate *data;
645 g_return_val_if_fail(spacing != NULL, FALSE);
647 data = table_style->data;
649 if (adg_pair_equal(&data->cell_spacing, spacing))
650 return FALSE;
652 data->cell_spacing = *spacing;
654 return TRUE;