3 * Copyright (C) 2001-2009 Jim Evins <evins@snaught.com>.
5 * This file is part of gLabels.
7 * gLabels is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * gLabels is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
21 #include "label-box.h"
23 #include <glib/gi18n.h>
29 /*========================================================*/
31 /*========================================================*/
33 struct _glLabelBoxPrivate {
35 glColorNode *line_color_node;
36 glColorNode *fill_color_node;
40 /*========================================================*/
41 /* Private globals. */
42 /*========================================================*/
45 /*========================================================*/
46 /* Private function prototypes. */
47 /*========================================================*/
49 static void gl_label_box_finalize (GObject *object);
51 static void copy (glLabelObject *dst_object,
52 glLabelObject *src_object);
54 static void set_fill_color (glLabelObject *object,
55 glColorNode *fill_color_node,
58 static void set_line_color (glLabelObject *object,
59 glColorNode *line_color_node,
62 static void set_line_width (glLabelObject *object,
66 static glColorNode* get_fill_color (glLabelObject *object);
68 static glColorNode* get_line_color (glLabelObject *object);
70 static gdouble get_line_width (glLabelObject *object);
72 static void draw_object (glLabelObject *object,
75 glMergeRecord *record);
77 static void draw_shadow (glLabelObject *object,
80 glMergeRecord *record);
82 static gboolean object_at (glLabelObject *object,
88 /*****************************************************************************/
89 /* Boilerplate object stuff. */
90 /*****************************************************************************/
91 G_DEFINE_TYPE (glLabelBox, gl_label_box, GL_TYPE_LABEL_OBJECT)
95 gl_label_box_class_init (glLabelBoxClass *class)
97 GObjectClass *object_class = G_OBJECT_CLASS (class);
98 glLabelObjectClass *label_object_class = GL_LABEL_OBJECT_CLASS (class);
100 gl_label_box_parent_class = g_type_class_peek_parent (class);
102 label_object_class->copy = copy;
103 label_object_class->set_fill_color = set_fill_color;
104 label_object_class->set_line_color = set_line_color;
105 label_object_class->set_line_width = set_line_width;
106 label_object_class->get_fill_color = get_fill_color;
107 label_object_class->get_line_color = get_line_color;
108 label_object_class->get_line_width = get_line_width;
109 label_object_class->draw_object = draw_object;
110 label_object_class->draw_shadow = draw_shadow;
111 label_object_class->object_at = object_at;
113 object_class->finalize = gl_label_box_finalize;
118 gl_label_box_init (glLabelBox *lbox)
120 lbox->priv = g_new0 (glLabelBoxPrivate, 1);
125 gl_label_box_finalize (GObject *object)
127 glLabelBox *lbox = GL_LABEL_BOX (object);
129 g_return_if_fail (object && GL_IS_LABEL_BOX (object));
131 gl_color_node_free (&(lbox->priv->fill_color_node));
132 gl_color_node_free (&(lbox->priv->line_color_node));
135 G_OBJECT_CLASS (gl_label_box_parent_class)->finalize (object);
139 /*****************************************************************************/
140 /* NEW label "box" object. */
141 /*****************************************************************************/
143 gl_label_box_new (glLabel *label,
147 glColorNode *fill_color_node;
148 glColorNode *line_color_node;
150 lbox = g_object_new (gl_label_box_get_type(), NULL);
156 gl_label_checkpoint (label, _("Create box object"));
159 fill_color_node = gl_color_node_new_default ();
160 line_color_node = gl_color_node_new_default ();
162 line_color_node->color = gl_label_get_default_line_color(label);
163 fill_color_node->color = gl_label_get_default_fill_color(label);
165 lbox->priv->line_width = gl_label_get_default_line_width(label);
166 lbox->priv->line_color_node = line_color_node;
167 lbox->priv->fill_color_node = fill_color_node;
169 gl_label_add_object (label, GL_LABEL_OBJECT (lbox));
170 gl_label_object_set_parent (GL_LABEL_OBJECT (lbox), label);
173 return G_OBJECT (lbox);
177 /*****************************************************************************/
178 /* Copy object contents. */
179 /*****************************************************************************/
181 copy (glLabelObject *dst_object,
182 glLabelObject *src_object)
184 glLabelBox *lbox = (glLabelBox *)src_object;
185 glLabelBox *new_lbox = (glLabelBox *)dst_object;
187 glColorNode *line_color_node;
188 glColorNode *fill_color_node;
190 gl_debug (DEBUG_LABEL, "START");
192 g_return_if_fail (lbox && GL_IS_LABEL_BOX (lbox));
193 g_return_if_fail (new_lbox && GL_IS_LABEL_BOX (new_lbox));
195 line_width = get_line_width (src_object);
196 line_color_node = get_line_color (src_object);
197 fill_color_node = get_fill_color (src_object);
199 set_line_width (dst_object, line_width, FALSE);
200 set_line_color (dst_object, line_color_node, FALSE);
201 set_fill_color (dst_object, fill_color_node, FALSE);
203 gl_color_node_free (&line_color_node);
204 gl_color_node_free (&fill_color_node);
206 gl_debug (DEBUG_LABEL, "END");
210 /*---------------------------------------------------------------------------*/
211 /* PRIVATE. Set fill color method. */
212 /*---------------------------------------------------------------------------*/
214 set_fill_color (glLabelObject *object,
215 glColorNode *fill_color_node,
218 glLabelBox *lbox = (glLabelBox *)object;
221 gl_debug (DEBUG_LABEL, "START");
223 g_return_if_fail (lbox && GL_IS_LABEL_BOX (lbox));
225 if (!gl_color_node_equal (lbox->priv->fill_color_node, fill_color_node))
229 label = gl_label_object_get_parent (GL_LABEL_OBJECT (lbox));
230 gl_label_checkpoint (label, _("Fill color"));
233 gl_color_node_free (&(lbox->priv->fill_color_node));
234 lbox->priv->fill_color_node = gl_color_node_dup (fill_color_node);
236 gl_label_object_emit_changed (GL_LABEL_OBJECT(lbox));
239 gl_debug (DEBUG_LABEL, "END");
243 /*---------------------------------------------------------------------------*/
244 /* PRIVATE. Set line color method. */
245 /*---------------------------------------------------------------------------*/
247 set_line_color (glLabelObject *object,
248 glColorNode *line_color_node,
251 glLabelBox *lbox = (glLabelBox *)object;
254 g_return_if_fail (lbox && GL_IS_LABEL_BOX (lbox));
256 if ( !gl_color_node_equal (lbox->priv->line_color_node, line_color_node ))
260 label = gl_label_object_get_parent (GL_LABEL_OBJECT (lbox));
261 gl_label_checkpoint (label, _("Line color"));
264 gl_color_node_free (&(lbox->priv->line_color_node));
265 lbox->priv->line_color_node = gl_color_node_dup (line_color_node);
266 gl_label_object_emit_changed (GL_LABEL_OBJECT(lbox));
271 /*---------------------------------------------------------------------------*/
272 /* PRIVATE. Set line width method. */
273 /*---------------------------------------------------------------------------*/
275 set_line_width (glLabelObject *object,
279 glLabelBox *lbox = (glLabelBox *)object;
282 g_return_if_fail (lbox && GL_IS_LABEL_BOX (lbox));
284 if ( lbox->priv->line_width != line_width )
288 label = gl_label_object_get_parent (GL_LABEL_OBJECT (lbox));
289 gl_label_checkpoint (label, _("Line width"));
292 lbox->priv->line_width = line_width;
293 gl_label_object_emit_changed (GL_LABEL_OBJECT(lbox));
298 /*---------------------------------------------------------------------------*/
299 /* PRIVATE. Get fill color method. */
300 /*---------------------------------------------------------------------------*/
302 get_line_width (glLabelObject *object)
304 glLabelBox *lbox = (glLabelBox *)object;
306 g_return_val_if_fail (lbox && GL_IS_LABEL_BOX (lbox), 0.0);
308 return lbox->priv->line_width;
312 /*---------------------------------------------------------------------------*/
313 /* PRIVATE. Get line color method. */
314 /*---------------------------------------------------------------------------*/
316 get_line_color (glLabelObject *object)
318 glLabelBox *lbox = (glLabelBox *)object;
320 g_return_val_if_fail (lbox && GL_IS_LABEL_BOX (lbox), 0);
322 return gl_color_node_dup (lbox->priv->line_color_node);
326 /*---------------------------------------------------------------------------*/
327 /* PRIVATE. Get line width method. */
328 /*---------------------------------------------------------------------------*/
330 get_fill_color (glLabelObject *object)
332 glLabelBox *lbox = (glLabelBox *)object;
334 g_return_val_if_fail (lbox && GL_IS_LABEL_BOX (lbox), 0);
336 return gl_color_node_dup (lbox->priv->fill_color_node);
340 /*****************************************************************************/
341 /* Draw object method. */
342 /*****************************************************************************/
344 draw_object (glLabelObject *object,
346 gboolean screen_flag,
347 glMergeRecord *record)
351 glColorNode *line_color_node;
352 glColorNode *fill_color_node;
356 gl_debug (DEBUG_LABEL, "START");
358 gl_label_object_get_size (object, &w, &h);
360 line_width = gl_label_object_get_line_width (object);
362 line_color_node = gl_label_object_get_line_color (object);
363 fill_color_node = gl_label_object_get_fill_color (object);
364 line_color = gl_color_node_expand (line_color_node, record);
365 fill_color = gl_color_node_expand (fill_color_node, record);
366 if (line_color_node->field_flag && screen_flag)
368 line_color = GL_COLOR_MERGE_DEFAULT;
370 if (fill_color_node->field_flag && screen_flag)
372 fill_color = GL_COLOR_FILL_MERGE_DEFAULT;
376 cairo_rectangle (cr, 0.0, 0.0, w, h);
378 /* Paint fill color */
379 cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (fill_color));
380 cairo_fill_preserve (cr);
383 cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (line_color));
384 cairo_set_line_width (cr, line_width);
387 gl_color_node_free (&line_color_node);
388 gl_color_node_free (&fill_color_node);
390 gl_debug (DEBUG_LABEL, "END");
394 /*****************************************************************************/
395 /* Draw shadow method. */
396 /*****************************************************************************/
398 draw_shadow (glLabelObject *object,
400 gboolean screen_flag,
401 glMergeRecord *record)
405 glColorNode *line_color_node;
406 glColorNode *fill_color_node;
409 glColorNode *shadow_color_node;
411 gdouble shadow_opacity;
413 gl_debug (DEBUG_LABEL, "START");
417 gl_label_object_get_size (object, &w, &h);
419 line_width = gl_label_object_get_line_width (object);
421 line_color_node = gl_label_object_get_line_color (object);
422 fill_color_node = gl_label_object_get_fill_color (object);
423 line_color = gl_color_node_expand (line_color_node, record);
424 fill_color = gl_color_node_expand (fill_color_node, record);
425 if (line_color_node->field_flag && screen_flag)
427 line_color = GL_COLOR_MERGE_DEFAULT;
429 if (fill_color_node->field_flag && screen_flag)
431 fill_color = GL_COLOR_FILL_MERGE_DEFAULT;
434 shadow_color_node = gl_label_object_get_shadow_color (object);
435 shadow_color = gl_color_node_expand (shadow_color_node, record);
436 if (shadow_color_node->field_flag && screen_flag)
438 shadow_color = GL_COLOR_SHADOW_MERGE_DEFAULT;
440 shadow_opacity = gl_label_object_get_shadow_opacity (object);
441 shadow_color = gl_color_set_opacity (shadow_color, shadow_opacity);
444 cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (shadow_color));
446 if ( GL_COLOR_F_ALPHA (fill_color) )
448 if ( GL_COLOR_F_ALPHA (line_color) )
450 /* Has FILL and OUTLINE: adjust size to account for line width. */
452 -line_width/2, -line_width/2,
453 w+line_width, h+line_width);
458 /* Has FILL but no OUTLINE. */
459 cairo_rectangle (cr, 0.0, 0.0, w, h);
467 if ( GL_COLOR_F_ALPHA (line_color) )
469 /* Has only OUTLINE. */
470 cairo_rectangle (cr, 0.0, 0.0, w, h);
472 /* Draw shadow of outline */
473 cairo_set_line_width (cr, line_width);
479 gl_color_node_free (&line_color_node);
480 gl_color_node_free (&fill_color_node);
481 gl_color_node_free (&shadow_color_node);
485 gl_debug (DEBUG_LABEL, "END");
489 /*****************************************************************************/
490 /* Is object at coordinates? */
491 /*****************************************************************************/
493 object_at (glLabelObject *object,
501 gl_label_object_get_size (object, &w, &h);
504 cairo_rectangle (cr, 0.0, 0.0, w, h);
506 if (cairo_in_fill (cr, x, y))
511 line_width = gl_label_object_get_line_width (object);
512 cairo_set_line_width (cr, line_width);
513 if (cairo_in_stroke (cr, x, y))
525 * Local Variables: -- emacs
527 * c-basic-offset: 8 -- emacs
528 * tab-width: 8 -- emacs
529 * indent-tabs-mode: nil -- emacs