]> git.sur5r.net Git - glabels/blob - src/label-line.c
Imported Upstream version 3.0.0
[glabels] / src / label-line.c
1 /*
2  *  label-line.c
3  *  Copyright (C) 2001-2009  Jim Evins <evins@snaught.com>.
4  *
5  *  This file is part of gLabels.
6  *
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.
11  *
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.
16  *
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/>.
19  */
20
21 #include "label-line.h"
22
23 #include <glib/gi18n.h>
24 #include <glib.h>
25
26 #include "debug.h"
27
28
29 /*========================================================*/
30 /* Private types.                                         */
31 /*========================================================*/
32
33 struct _glLabelLinePrivate {
34         gdouble          line_width;
35         glColorNode     *line_color_node;
36 };
37
38
39 /*========================================================*/
40 /* Private globals.                                       */
41 /*========================================================*/
42
43
44 /*========================================================*/
45 /* Private function prototypes.                           */
46 /*========================================================*/
47
48 static void    gl_label_line_finalize     (GObject           *object);
49
50 static void    copy                       (glLabelObject     *dst_object,
51                                            glLabelObject     *src_object);
52
53 static void    set_line_color             (glLabelObject     *object,
54                                            glColorNode       *line_color_node,
55                                            gboolean           checkpoint);
56
57 static void    set_line_width             (glLabelObject     *object,
58                                            gdouble            line_width,
59                                            gboolean           checkpoint);
60
61 static glColorNode   *get_line_color      (glLabelObject     *object);
62
63 static gdouble get_line_width             (glLabelObject     *object);
64
65 static void    draw_object                (glLabelObject     *object,
66                                            cairo_t           *cr,
67                                            gboolean           screen_flag,
68                                            glMergeRecord     *record);
69
70 static void    draw_shadow                (glLabelObject     *object,
71                                            cairo_t           *cr,
72                                            gboolean           screen_flag,
73                                            glMergeRecord     *record);
74
75 static gboolean object_at                 (glLabelObject     *object,
76                                            cairo_t           *cr,
77                                            gdouble            x_pixels,
78                                            gdouble            y_pixels);
79
80
81 /*****************************************************************************/
82 /* Boilerplate object stuff.                                                 */
83 /*****************************************************************************/
84 G_DEFINE_TYPE (glLabelLine, gl_label_line, GL_TYPE_LABEL_OBJECT)
85
86
87 static void
88 gl_label_line_class_init (glLabelLineClass *class)
89 {
90         GObjectClass       *object_class       = G_OBJECT_CLASS (class);
91         glLabelObjectClass *label_object_class = GL_LABEL_OBJECT_CLASS (class);
92
93         gl_label_line_parent_class = g_type_class_peek_parent (class);
94
95         label_object_class->copy           = copy;
96         label_object_class->set_line_color = set_line_color;
97         label_object_class->set_line_width = set_line_width;
98         label_object_class->get_line_color = get_line_color;
99         label_object_class->get_line_width = get_line_width;
100         label_object_class->draw_object    = draw_object;
101         label_object_class->draw_shadow    = draw_shadow;
102         label_object_class->draw_handles   = gl_label_object_draw_handles_line;
103         label_object_class->object_at      = object_at;
104         label_object_class->handle_at      = gl_label_object_line_handle_at;
105
106         object_class->finalize = gl_label_line_finalize;
107 }
108
109
110 static void
111 gl_label_line_init (glLabelLine *lline)
112 {
113         lline->priv = g_new0 (glLabelLinePrivate, 1);
114 }
115
116
117 static void
118 gl_label_line_finalize (GObject *object)
119 {
120         glLabelLine *lline = GL_LABEL_LINE (object);
121
122         g_return_if_fail (object && GL_IS_LABEL_LINE (object));
123
124         gl_color_node_free (&(lline->priv->line_color_node));
125         g_free (lline->priv);
126
127         G_OBJECT_CLASS (gl_label_line_parent_class)->finalize (object);
128 }
129
130
131 /*****************************************************************************/
132 /* NEW label "line" object.                                               */
133 /*****************************************************************************/
134 GObject *
135 gl_label_line_new (glLabel *label,
136                    gboolean checkpoint)
137 {
138         glLabelLine         *lline;
139         glColorNode         *line_color_node;
140
141         lline = g_object_new (gl_label_line_get_type(), NULL);
142
143         if (label != NULL)
144         {
145                 if ( checkpoint )
146                 {
147                         gl_label_checkpoint (label, _("Create line object"));
148                 }
149
150                 line_color_node = gl_color_node_new_default ();
151
152                 line_color_node->color = gl_label_get_default_line_color(label);
153
154                 lline->priv->line_width      = gl_label_get_default_line_width(label);
155                 lline->priv->line_color_node = line_color_node;
156
157                 gl_label_add_object (label, GL_LABEL_OBJECT (lline));
158                 gl_label_object_set_parent (GL_LABEL_OBJECT (lline), label);
159         }
160
161         return G_OBJECT (lline);
162 }
163
164
165 /*****************************************************************************/
166 /* Copy object contents.                                                     */
167 /*****************************************************************************/
168 static void
169 copy (glLabelObject *dst_object,
170       glLabelObject *src_object)
171 {
172         glLabelLine *lline     = (glLabelLine *)src_object;
173         glLabelLine *new_lline = (glLabelLine *)dst_object;
174         gdouble      line_width;
175         glColorNode *line_color_node;
176
177         gl_debug (DEBUG_LABEL, "START");
178
179         g_return_if_fail (lline && GL_IS_LABEL_LINE (lline));
180         g_return_if_fail (new_lline && GL_IS_LABEL_LINE (new_lline));
181
182         line_width = get_line_width (src_object);
183         line_color_node = get_line_color (src_object);
184
185         set_line_width (dst_object, line_width, FALSE);
186         set_line_color (dst_object, line_color_node, FALSE);
187
188         gl_color_node_free (&line_color_node);
189         
190         gl_debug (DEBUG_LABEL, "END");
191 }
192
193
194 /*---------------------------------------------------------------------------*/
195 /* PRIVATE.  Set line color method.                                          */
196 /*---------------------------------------------------------------------------*/
197 static void
198 set_line_color (glLabelObject *object,
199                 glColorNode   *line_color_node,
200                 gboolean       checkpoint)
201 {
202         glLabelLine *lline = (glLabelLine *)object;
203         glLabel     *label;
204
205         g_return_if_fail (lline && GL_IS_LABEL_LINE (lline));
206
207         if ( !gl_color_node_equal (lline->priv->line_color_node, line_color_node))
208         {
209                 if ( checkpoint )
210                 {
211                         label = gl_label_object_get_parent (GL_LABEL_OBJECT (lline));
212                         gl_label_checkpoint (label, _("Line color"));
213                 }
214
215                 gl_color_node_free (&(lline->priv->line_color_node ));
216                 lline->priv->line_color_node = gl_color_node_dup (line_color_node);
217                 
218                 gl_label_object_emit_changed (GL_LABEL_OBJECT(lline));
219         }
220 }
221
222
223 /*---------------------------------------------------------------------------*/
224 /* PRIVATE.  Set line width method.                                          */
225 /*---------------------------------------------------------------------------*/
226 static void
227 set_line_width (glLabelObject *object,
228                 gdouble        line_width,
229                 gboolean       checkpoint)
230 {
231         glLabelLine *lline = (glLabelLine *)object;
232         glLabel     *label;
233
234         g_return_if_fail (lline && GL_IS_LABEL_LINE (lline));
235
236         if ( lline->priv->line_width != line_width )
237         {
238                 if ( checkpoint )
239                 {
240                         label = gl_label_object_get_parent (GL_LABEL_OBJECT (lline));
241                         gl_label_checkpoint (label, _("Line width"));
242                 }
243
244                 lline->priv->line_width = line_width;
245                 gl_label_object_emit_changed (GL_LABEL_OBJECT(lline));
246         }
247 }
248
249
250 /*---------------------------------------------------------------------------*/
251 /* PRIVATE.  Get line color method.                                          */
252 /*---------------------------------------------------------------------------*/
253 static gdouble
254 get_line_width (glLabelObject *object)
255 {
256         glLabelLine *lline = (glLabelLine *)object;
257
258         g_return_val_if_fail (lline && GL_IS_LABEL_LINE (lline), 0.0);
259
260         return lline->priv->line_width;
261 }
262
263
264 /*---------------------------------------------------------------------------*/
265 /* PRIVATE.  Get line width method.                                          */
266 /*---------------------------------------------------------------------------*/
267 static glColorNode*
268 get_line_color (glLabelObject *object)
269 {
270         glLabelLine *lline = (glLabelLine *)object;
271
272         g_return_val_if_fail (lline && GL_IS_LABEL_LINE (lline), 0);
273
274         return gl_color_node_dup (lline->priv->line_color_node);
275 }
276
277
278 /*****************************************************************************/
279 /* Draw object method.                                                       */
280 /*****************************************************************************/
281 static void
282 draw_object (glLabelObject *object,
283              cairo_t       *cr,
284              gboolean       screen_flag,
285              glMergeRecord *record)
286 {
287         gdouble        w, h;
288         gdouble        line_width;
289         glColorNode   *line_color_node;
290         guint          line_color;
291
292         gl_debug (DEBUG_LABEL, "START");
293
294         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
295
296         line_width = gl_label_object_get_line_width (object);
297         
298         line_color_node = gl_label_object_get_line_color (object);
299         line_color = gl_color_node_expand (line_color_node, record);
300         if (line_color_node->field_flag && screen_flag)
301         {
302                 line_color = GL_COLOR_MERGE_DEFAULT;
303         }
304
305
306         cairo_move_to (cr, 0.0, 0.0);
307         cairo_line_to (cr, w, h);
308
309
310         /* Draw line */
311         cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (line_color));
312         cairo_set_line_width (cr, line_width);
313         cairo_stroke (cr);
314
315         gl_color_node_free (&line_color_node);
316
317         gl_debug (DEBUG_LABEL, "END");
318 }
319
320
321 /*****************************************************************************/
322 /* Draw shadow method.                                                       */
323 /*****************************************************************************/
324 static void
325 draw_shadow (glLabelObject *object,
326              cairo_t       *cr,
327              gboolean       screen_flag,
328              glMergeRecord *record)
329 {
330         gdouble        w, h;
331         gdouble        line_width;
332         glColorNode   *line_color_node;
333         glColorNode   *shadow_color_node;
334         gdouble        shadow_opacity;
335         guint          shadow_line_color;
336
337         gl_debug (DEBUG_LABEL, "START");
338
339         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
340
341         line_width = gl_label_object_get_line_width (object);
342         
343         line_color_node = gl_label_object_get_line_color (object);
344         if (line_color_node->field_flag)
345         {
346                 line_color_node->color = GL_COLOR_MERGE_DEFAULT;
347         }
348
349         shadow_color_node = gl_label_object_get_shadow_color (object);
350         if (shadow_color_node->field_flag)
351         {
352                 shadow_color_node->color = GL_COLOR_SHADOW_MERGE_DEFAULT;
353         }
354         shadow_opacity = gl_label_object_get_shadow_opacity (object);
355         shadow_line_color = gl_color_shadow (shadow_color_node->color, shadow_opacity, line_color_node->color);
356
357
358         cairo_move_to (cr, 0.0, 0.0);
359         cairo_line_to (cr, w, h);
360
361
362         /* Draw outline shadow */
363         cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (shadow_line_color));
364         cairo_set_line_width (cr, line_width);
365         cairo_stroke (cr);
366
367
368         gl_color_node_free (&line_color_node);
369         gl_color_node_free (&shadow_color_node);
370
371         gl_debug (DEBUG_LABEL, "END");
372 }
373
374
375 /*****************************************************************************/
376 /* Is object at coordinates?                                                 */
377 /*****************************************************************************/
378 static gboolean
379 object_at (glLabelObject *object,
380            cairo_t       *cr,
381            gdouble        x,
382            gdouble        y)
383 {
384         gdouble           w, h;
385         gdouble           line_width;
386
387         gl_label_object_get_size (object, &w, &h);
388
389         cairo_new_path (cr);
390         cairo_move_to (cr, 0, 0);
391         cairo_line_to (cr, w, h);
392
393         line_width = gl_label_object_get_line_width (object);
394         cairo_set_line_width (cr, line_width);
395         if (cairo_in_stroke (cr, x, y))
396         {
397                 return TRUE;
398         }
399
400         return FALSE;
401 }
402
403
404
405
406 /*
407  * Local Variables:       -- emacs
408  * mode: C                -- emacs
409  * c-basic-offset: 8      -- emacs
410  * tab-width: 8           -- emacs
411  * indent-tabs-mode: nil  -- emacs
412  * End:                   -- emacs
413  */