]> git.sur5r.net Git - glabels/blob - src/view-line.c
Imported Upstream version 2.2.8
[glabels] / src / view-line.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2
3 /*
4  *  (GLABELS) Label and Business Card Creation program for GNOME
5  *
6  *  view_line.c:  GLabels label line object view
7  *
8  *  Copyright (C) 2001-2007  Jim Evins <evins@snaught.com>.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23  */
24 #include <config.h>
25
26 #include "view-line.h"
27
28 #include <glib/gi18n.h>
29 #include <glib/gmem.h>
30
31 #include "color.h"
32 #include "object-editor.h"
33 #include "stock.h"
34
35 #include "pixmaps/cursor_line.xbm"
36 #include "pixmaps/cursor_line_mask.xbm"
37
38 #include "debug.h"
39
40 /*========================================================*/
41 /* Private macros and constants.                          */
42 /*========================================================*/
43
44
45 /*========================================================*/
46 /* Private types.                                         */
47 /*========================================================*/
48
49 struct _glViewLinePrivate {
50         int place_holder; /* Place holder for future private data. */
51 };
52
53 /*========================================================*/
54 /* Private globals.                                       */
55 /*========================================================*/
56
57
58 /*========================================================*/
59 /* Private function prototypes.                           */
60 /*========================================================*/
61
62 static void       gl_view_line_finalize             (GObject          *object);
63
64 static GtkWidget *construct_properties_editor       (glViewObject     *view_object);
65
66 static void       update_object_from_editor_cb      (glObjectEditor   *editor,
67                                                      glLabelObject    *object);
68
69 static void       update_editor_from_object_cb      (glLabelObject    *object,
70                                                      glObjectEditor   *editor);
71
72 static void       update_editor_from_move_cb        (glLabelObject    *object,
73                                                      gdouble           dx,
74                                                      gdouble           dy,
75                                                      glObjectEditor   *editor);
76
77 static gboolean   object_at                         (glViewObject     *view_object,
78                                                      cairo_t          *cr,
79                                                      gdouble           x,
80                                                      gdouble           y);
81
82
83 \f
84 /*****************************************************************************/
85 /* Boilerplate object stuff.                                                 */
86 /*****************************************************************************/
87 G_DEFINE_TYPE (glViewLine, gl_view_line, GL_TYPE_VIEW_OBJECT);
88
89
90 static void
91 gl_view_line_class_init (glViewLineClass *class)
92 {
93         GObjectClass      *object_class      = G_OBJECT_CLASS (class);
94         glViewObjectClass *view_object_class = GL_VIEW_OBJECT_CLASS (class);
95
96         gl_debug (DEBUG_VIEW, "START");
97
98         gl_view_line_parent_class = g_type_class_peek_parent (class);
99
100         object_class->finalize = gl_view_line_finalize;
101
102         view_object_class->construct_editor = construct_properties_editor;
103         view_object_class->object_at        = object_at;
104
105         gl_debug (DEBUG_VIEW, "END");
106 }
107
108 static void
109 gl_view_line_init (glViewLine *view_line)
110 {
111         gl_debug (DEBUG_VIEW, "START");
112
113         view_line->priv = g_new0 (glViewLinePrivate, 1);
114
115         gl_debug (DEBUG_VIEW, "END");
116 }
117
118 static void
119 gl_view_line_finalize (GObject *object)
120 {
121         glViewLine *view_line = GL_VIEW_LINE (object);
122
123         gl_debug (DEBUG_VIEW, "START");
124
125         g_return_if_fail (object && GL_IS_VIEW_LINE (object));
126
127         g_free (view_line->priv);
128
129         G_OBJECT_CLASS (gl_view_line_parent_class)->finalize (object);
130
131         gl_debug (DEBUG_VIEW, "END");
132 }
133
134 /*****************************************************************************/
135 /* NEW line object view.                                                  */
136 /*****************************************************************************/
137 glViewObject *
138 gl_view_line_new (glLabelLine *object,
139                   glView     *view)
140 {
141         glViewLine         *view_line;
142
143         gl_debug (DEBUG_VIEW, "START");
144
145         g_return_val_if_fail (object && GL_IS_LABEL_LINE (object), NULL);
146         g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
147         
148         view_line = g_object_new (gl_view_line_get_type(), NULL);
149
150         gl_view_object_set_object (GL_VIEW_OBJECT(view_line),
151                                    GL_LABEL_OBJECT(object),
152                                    GL_VIEW_OBJECT_HANDLES_LINE);
153         gl_view_object_set_view (GL_VIEW_OBJECT(view_line), view);
154
155         gl_debug (DEBUG_VIEW, "END");
156
157         return GL_VIEW_OBJECT (view_line);
158 }
159
160 /*****************************************************************************/
161 /* Create a properties dialog for a line object.                             */
162 /*****************************************************************************/
163 static GtkWidget *
164 construct_properties_editor (glViewObject *view_object)
165 {
166         GtkWidget          *editor;
167         glViewLine         *view_line = (glViewLine *)view_object;
168         glLabelObject      *object;
169
170         gl_debug (DEBUG_VIEW, "START");
171
172         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_line));
173
174         /* Build editor. */
175         editor = gl_object_editor_new (GL_STOCK_LINE, _("Line object properties"),
176                                        object->parent,
177                                        GL_OBJECT_EDITOR_SHADOW_PAGE,
178                                        GL_OBJECT_EDITOR_POSITION_PAGE,
179                                        GL_OBJECT_EDITOR_SIZE_LINE_PAGE,
180                                        GL_OBJECT_EDITOR_LINE_PAGE,
181                                        0);
182         
183         /* Update */
184         update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
185         update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
186
187         /* Connect signals. */
188         g_signal_connect (G_OBJECT (editor), "changed",
189                           G_CALLBACK(update_object_from_editor_cb), object);
190         g_signal_connect (G_OBJECT (object), "changed",
191                           G_CALLBACK (update_editor_from_object_cb), editor);
192         g_signal_connect (G_OBJECT (object), "moved",
193                           G_CALLBACK (update_editor_from_move_cb), editor);
194
195         gl_debug (DEBUG_VIEW, "END");
196
197         return editor;
198 }
199
200 /*---------------------------------------------------------------------------*/
201 /* PRIVATE.  editor "changed" callback.                                      */
202 /*---------------------------------------------------------------------------*/
203 static void
204 update_object_from_editor_cb (glObjectEditor *editor,
205                               glLabelObject  *object)
206 {
207         gdouble            x, y, w, h;
208         glColorNode       *line_color_node;
209         gdouble            line_width;
210         gboolean           shadow_state;
211         gdouble            shadow_x, shadow_y;
212         glColorNode       *shadow_color_node;
213         gdouble            shadow_opacity;
214         
215
216         gl_debug (DEBUG_VIEW, "START");
217
218         g_signal_handlers_block_by_func (G_OBJECT(object),
219                                          update_editor_from_object_cb,
220                                          editor);
221         g_signal_handlers_block_by_func (G_OBJECT(object),
222                                          update_editor_from_move_cb,
223                                          editor);
224
225         gl_object_editor_get_position (editor, &x, &y);
226         gl_label_object_set_position (object, x, y);
227
228         gl_object_editor_get_lsize (editor, &w, &h);
229         gl_label_object_set_size (object, w, h);
230
231         line_color_node = gl_object_editor_get_line_color (editor);
232         gl_label_object_set_line_color (object, line_color_node);
233         gl_color_node_free (&line_color_node);
234
235         line_width = gl_object_editor_get_line_width (editor);
236         gl_label_object_set_line_width (object, line_width);
237
238         shadow_state = gl_object_editor_get_shadow_state (editor);
239         gl_label_object_set_shadow_state (object, shadow_state);
240
241         gl_object_editor_get_shadow_offset (editor, &shadow_x, &shadow_y);
242         gl_label_object_set_shadow_offset (object, shadow_x, shadow_y);
243
244         shadow_color_node = gl_object_editor_get_shadow_color (editor);
245         gl_label_object_set_shadow_color (object, shadow_color_node);
246         gl_color_node_free (&shadow_color_node);
247
248         shadow_opacity = gl_object_editor_get_shadow_opacity (editor);
249         gl_label_object_set_shadow_opacity (object, shadow_opacity);
250
251         g_signal_handlers_unblock_by_func (G_OBJECT(object),
252                                            update_editor_from_object_cb,
253                                            editor);
254         g_signal_handlers_unblock_by_func (G_OBJECT(object),
255                                            update_editor_from_move_cb,
256                                            editor);
257
258         gl_debug (DEBUG_VIEW, "END");
259 }
260
261 /*---------------------------------------------------------------------------*/
262 /* PRIVATE. label object "changed" callback.                                 */
263 /*---------------------------------------------------------------------------*/
264 static void
265 update_editor_from_object_cb (glLabelObject  *object,
266                               glObjectEditor *editor)
267 {
268         gdouble            w, h;
269         glColorNode       *line_color_node;
270         gdouble            line_width;
271         gboolean           shadow_state;
272         gdouble            shadow_x, shadow_y;
273         glColorNode       *shadow_color_node;
274         gdouble            shadow_opacity;
275         glMerge           *merge;
276
277         gl_debug (DEBUG_VIEW, "START");
278
279         gl_label_object_get_size (object, &w, &h);
280         gl_object_editor_set_lsize (editor, w, h);
281         merge = gl_label_get_merge (GL_LABEL(object->parent));
282         
283         line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
284         gl_object_editor_set_line_color (editor, (merge != NULL), line_color_node);
285         gl_color_node_free (&line_color_node);
286
287         line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
288         gl_object_editor_set_line_width (editor, line_width);
289
290         shadow_state = gl_label_object_get_shadow_state (object);
291         gl_object_editor_set_shadow_state (editor, shadow_state);
292
293         gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
294         gl_object_editor_set_shadow_offset (editor, shadow_x, shadow_y);
295
296         shadow_color_node = gl_label_object_get_shadow_color (object);
297         gl_object_editor_set_shadow_color (editor, (merge != NULL), shadow_color_node);
298         gl_color_node_free (&shadow_color_node);
299
300         shadow_opacity = gl_label_object_get_shadow_opacity (object);
301         gl_object_editor_set_shadow_opacity (editor, shadow_opacity);
302
303         gl_debug (DEBUG_VIEW, "END");
304 }
305
306 /*---------------------------------------------------------------------------*/
307 /* PRIVATE. label object "moved" callback.                                   */
308 /*---------------------------------------------------------------------------*/
309 static void
310 update_editor_from_move_cb (glLabelObject    *object,
311                             gdouble           dx,
312                             gdouble           dy,
313                             glObjectEditor   *editor)
314 {
315         gdouble            x, y;
316
317         gl_debug (DEBUG_VIEW, "START");
318
319         gl_label_object_get_position (object, &x, &y);
320         gl_object_editor_set_position (editor, x, y);
321
322         gl_debug (DEBUG_VIEW, "END");
323 }
324
325 /*****************************************************************************/
326 /* Is object at (x,y)?                                                       */
327 /*****************************************************************************/
328 static gboolean
329 object_at (glViewObject  *view_object,
330            cairo_t       *cr,
331            gdouble        x,
332            gdouble        y)
333 {
334         glLabelObject    *object;
335         gdouble           w, h;
336         gdouble           line_width;
337
338         object = gl_view_object_get_object (view_object);
339
340         gl_label_object_get_size (object, &w, &h);
341
342         cairo_move_to (cr, 0.0, 0.0);
343         cairo_line_to (cr, w, h);
344
345         line_width = gl_label_object_get_line_width (object);
346         cairo_set_line_width (cr, line_width);
347         if (cairo_in_stroke (cr, x, y))
348         {
349                 return TRUE;
350         }
351
352         return FALSE;
353 }
354
355
356 /*****************************************************************************/
357 /* Return apropos cursor for create object mode.                             */
358 /*****************************************************************************/
359 GdkCursor *
360 gl_view_line_get_create_cursor (void)
361 {
362         GdkCursor       *cursor = NULL;
363         GdkPixmap       *pixmap_data, *pixmap_mask;
364         GdkColor         fg = { 0, 0, 0, 0 };
365         GdkColor         bg = { 0, 65535, 65535, 65535 };
366
367         gl_debug (DEBUG_VIEW, "START");
368
369         pixmap_data = gdk_bitmap_create_from_data (NULL,
370                                                    (gchar *)cursor_line_bits,
371                                                    cursor_line_width,
372                                                    cursor_line_height);
373         pixmap_mask = gdk_bitmap_create_from_data (NULL,
374                                                    (gchar *)cursor_line_mask_bits,
375                                                    cursor_line_mask_width,
376                                                    cursor_line_mask_height);
377         cursor = gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
378                                              &bg, cursor_line_x_hot,
379                                              cursor_line_y_hot);
380
381         gl_debug (DEBUG_VIEW, "END");
382
383         return cursor;
384 }
385
386 /*****************************************************************************/
387 /* Object creation handler: button press event.                              */
388 /*****************************************************************************/
389 void
390 gl_view_line_create_button_press_event   (glView *view,
391                                           gdouble x,
392                                           gdouble y)
393 {
394         GObject             *object;
395         glColorNode         *line_color_node;
396
397         gl_view_unselect_all (view);
398
399         line_color_node = gl_color_node_new_default ();
400                 
401         object = gl_label_line_new (view->label);
402         gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
403         gl_label_object_set_size (GL_LABEL_OBJECT(object), 0.0, 0.0);
404         line_color_node->color = gl_color_set_opacity (gl_view_get_default_line_color(view), 0.5);
405         gl_label_object_set_line_width (GL_LABEL_OBJECT(object),
406                                         gl_view_get_default_line_width(view));
407         gl_label_object_set_line_color (GL_LABEL_OBJECT(object),
408                                         line_color_node);
409
410         gl_color_node_free (&line_color_node);
411
412         view->create_object = GL_LABEL_OBJECT (object);
413         view->create_x0 = x;
414         view->create_y0 = y;
415 }
416
417 /*****************************************************************************/
418 /* Object creation handler: motion event.                                    */
419 /*****************************************************************************/
420 void
421 gl_view_line_create_motion_event     (glView *view,
422                                       gdouble x,
423                                       gdouble y)
424 {
425         gdouble w, h;
426
427         w = x - view->create_x0;
428         h = y - view->create_y0;
429         gl_label_object_set_size (GL_LABEL_OBJECT(view->create_object), w, h);
430 }
431
432 /*****************************************************************************/
433 /* Object creation handler: button relesase event.                           */
434 /*****************************************************************************/
435 void
436 gl_view_line_create_button_release_event (glView *view,
437                                           gdouble x,
438                                           gdouble y)
439 {
440         glColorNode         *line_color_node;
441         gdouble              w, h;
442
443         line_color_node = gl_color_node_new_default ();
444                 
445         if ((view->create_x0 == x) && (view->create_y0 == y)) {
446                 x = view->create_x0 + 36.0;
447                 y = view->create_y0 + 36.0;
448         }
449         w = x - view->create_x0;
450         h = y - view->create_y0;
451         gl_label_object_set_size (GL_LABEL_OBJECT(view->create_object), w, h);
452         line_color_node->color = gl_view_get_default_line_color(view);
453         gl_label_object_set_line_color (GL_LABEL_OBJECT(view->create_object), line_color_node);
454         gl_color_node_free (&line_color_node);
455 }
456