]> git.sur5r.net Git - glabels/blob - glabels2/src/view-line.c
Created generic "get" methods for text, fill and line properties for all label object...
[glabels] / glabels2 / src / view-line.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  view_line.c:  GLabels label line object widget
5  *
6  *  Copyright (C) 2001-2003  Jim Evins <evins@snaught.com>.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  */
22
23 #include <glib.h>
24
25 #include "view-line.h"
26
27 #include "view-highlight.h"
28
29 #include "color.h"
30 #include "object-editor.h"
31 #include "stock.h"
32
33 #include "pixmaps/cursor_line.xbm"
34 #include "pixmaps/cursor_line_mask.xbm"
35
36 #include "debug.h"
37
38 /*========================================================*/
39 /* Private macros and constants.                          */
40 /*========================================================*/
41
42 /*========================================================*/
43 /* Private types.                                         */
44 /*========================================================*/
45
46 struct _glViewLinePrivate {
47         GnomeCanvasItem       *item;
48 };
49
50 /*========================================================*/
51 /* Private globals.                                       */
52 /*========================================================*/
53
54 static glViewObjectClass *parent_class = NULL;
55
56
57 /*========================================================*/
58 /* Private function prototypes.                           */
59 /*========================================================*/
60
61 static void       gl_view_line_class_init           (glViewLineClass  *klass);
62 static void       gl_view_line_instance_init        (glViewLine       *view_line);
63 static void       gl_view_line_finalize             (GObject          *object);
64
65 static GtkWidget *construct_properties_editor       (glViewObject     *view_object);
66
67 static void       update_canvas_item_from_object_cb (glLabelObject    *object,
68                                                      glViewLine        *view_line);
69
70 static void       update_object_from_editor_cb      (glObjectEditor   *editor,
71                                                      glLabelObject    *object);
72
73 static void       update_editor_from_object_cb      (glLabelObject    *object,
74                                                      glObjectEditor   *editor);
75
76 static void       update_editor_from_move_cb        (glLabelObject    *object,
77                                                      gdouble           dx,
78                                                      gdouble           dy,
79                                                      glObjectEditor   *editor);
80
81 static void       update_editor_from_label_cb       (glLabel          *label,
82                                                      glObjectEditor   *editor);
83
84
85 \f
86 /*****************************************************************************/
87 /* Boilerplate object stuff.                                                 */
88 /*****************************************************************************/
89 GType
90 gl_view_line_get_type (void)
91 {
92         static GType type = 0;
93
94         if (!type) {
95                 GTypeInfo info = {
96                         sizeof (glViewLineClass),
97                         NULL,
98                         NULL,
99                         (GClassInitFunc) gl_view_line_class_init,
100                         NULL,
101                         NULL,
102                         sizeof (glViewLine),
103                         0,
104                         (GInstanceInitFunc) gl_view_line_instance_init,
105                 };
106
107                 type = g_type_register_static (GL_TYPE_VIEW_OBJECT,
108                                                "glViewLine", &info, 0);
109         }
110
111         return type;
112 }
113
114 static void
115 gl_view_line_class_init (glViewLineClass *klass)
116 {
117         GObjectClass      *object_class      = (GObjectClass *) klass;
118         glViewObjectClass *view_object_class = (glViewObjectClass *) klass;
119
120         gl_debug (DEBUG_VIEW, "START");
121
122         parent_class = g_type_class_peek_parent (klass);
123
124         object_class->finalize = gl_view_line_finalize;
125
126         view_object_class->construct_editor = construct_properties_editor;
127
128         gl_debug (DEBUG_VIEW, "END");
129 }
130
131 static void
132 gl_view_line_instance_init (glViewLine *view_line)
133 {
134         gl_debug (DEBUG_VIEW, "START");
135
136         view_line->private = g_new0 (glViewLinePrivate, 1);
137
138         gl_debug (DEBUG_VIEW, "END");
139 }
140
141 static void
142 gl_view_line_finalize (GObject *object)
143 {
144         glLabel       *parent;
145
146         gl_debug (DEBUG_VIEW, "START");
147
148         g_return_if_fail (object && GL_IS_VIEW_LINE (object));
149
150         G_OBJECT_CLASS (parent_class)->finalize (object);
151
152         gl_debug (DEBUG_VIEW, "END");
153 }
154
155 /*****************************************************************************/
156 /* NEW line object view.                                                     */
157 /*****************************************************************************/
158 glViewObject *
159 gl_view_line_new (glLabelLine *object,
160                   glView      *view)
161 {
162         glViewLine        *view_line;
163         gdouble            line_width;
164         guint              line_color;
165         gdouble            w, h;
166         GnomeCanvasPoints *points;
167
168         gl_debug (DEBUG_VIEW, "START");
169         g_return_if_fail (object && GL_IS_LABEL_LINE (object));
170         g_return_if_fail (view && GL_IS_VIEW (view));
171         
172         view_line = g_object_new (gl_view_line_get_type(), NULL);
173
174         gl_view_object_set_view (GL_VIEW_OBJECT(view_line), view);
175         gl_view_object_set_object (GL_VIEW_OBJECT(view_line),
176                                    GL_LABEL_OBJECT(object),
177                                    GL_VIEW_HIGHLIGHT_LINE_RESIZABLE);
178
179         /* Query properties of object. */
180         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
181         line_width = gl_label_object_get_line_width(GL_LABEL_OBJECT(object));
182         line_color = gl_label_object_get_line_color(GL_LABEL_OBJECT(object));
183
184         /* Create analogous canvas item. */
185         points = gnome_canvas_points_new (2);
186         points->coords[0] = 0.0;
187         points->coords[1] = 0.0;
188         points->coords[2] = w;
189         points->coords[3] = h;
190         view_line->private->item =
191                 gl_view_object_item_new (GL_VIEW_OBJECT(view_line),
192                                          gnome_canvas_line_get_type (),
193                                          "points", points,
194                                          "width_units", line_width,
195                                          "fill_color_rgba", line_color,
196                                          NULL);
197         gnome_canvas_points_free (points);
198
199         g_signal_connect (G_OBJECT (object), "changed",
200                           G_CALLBACK (update_canvas_item_from_object_cb), view_line);
201
202         gl_debug (DEBUG_VIEW, "END");
203
204         return GL_VIEW_OBJECT (view_line);
205 }
206
207 /*****************************************************************************/
208 /* Create a properties editor for a line object.                             */
209 /*****************************************************************************/
210 static GtkWidget *
211 construct_properties_editor (glViewObject *view_object)
212 {
213         GtkWidget          *editor;
214         glViewLine         *view_line = (glViewLine *)view_object;
215         glLabelObject      *object;
216
217         gl_debug (DEBUG_VIEW, "START");
218
219         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_line));
220
221         /* Build editor. */
222         editor = gl_object_editor_new (GL_STOCK_LINE, _("Line object properties"),
223                                        GL_OBJECT_EDITOR_POSITION_PAGE,
224                                        GL_OBJECT_EDITOR_SIZE_LINE_PAGE,
225                                        GL_OBJECT_EDITOR_LINE_PAGE,
226                                        0);
227         
228         /* Update */
229         update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
230         update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
231         update_editor_from_label_cb (object->parent, GL_OBJECT_EDITOR(editor));
232
233         /* Connect signals. */
234         g_signal_connect (G_OBJECT (editor), "changed",
235                           G_CALLBACK(update_object_from_editor_cb), object);
236         g_signal_connect (G_OBJECT (object), "changed",
237                           G_CALLBACK (update_editor_from_object_cb), editor);
238         g_signal_connect (G_OBJECT (object), "moved",
239                           G_CALLBACK (update_editor_from_move_cb), editor);
240         g_signal_connect (G_OBJECT (object->parent), "size_changed",
241                           G_CALLBACK (update_editor_from_label_cb), editor);
242
243         gl_debug (DEBUG_VIEW, "END");
244
245         return editor;
246 }
247
248 /*---------------------------------------------------------------------------*/
249 /* PRIVATE. label object "changed" callback.                                 */
250 /*---------------------------------------------------------------------------*/
251 static void
252 update_canvas_item_from_object_cb (glLabelObject *object,
253                                    glViewLine     *view_line)
254 {
255         gdouble            line_width;
256         guint              line_color;
257         gdouble            w, h;
258         GnomeCanvasPoints  *points;
259
260         gl_debug (DEBUG_VIEW, "START");
261
262         /* Query properties of object. */
263         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
264         line_width = gl_label_object_get_line_width(GL_LABEL_OBJECT(object));
265         line_color = gl_label_object_get_line_color(GL_LABEL_OBJECT(object));
266
267         /* Adjust appearance of analogous canvas item. */
268         points = gnome_canvas_points_new (2);
269         points->coords[0] = 0.0;
270         points->coords[1] = 0.0;
271         points->coords[2] = w;
272         points->coords[3] = h;
273         gnome_canvas_item_set (view_line->private->item,
274                                "points", points,
275                                "width_units", line_width,
276                                "fill_color_rgba", line_color,
277                                NULL);
278         gnome_canvas_points_free (points);
279
280         gl_debug (DEBUG_VIEW, "END");
281 }
282
283 /*---------------------------------------------------------------------------*/
284 /* PRIVATE.  editor "changed" callback.                                      */
285 /*---------------------------------------------------------------------------*/
286 static void
287 update_object_from_editor_cb (glObjectEditor *editor,
288                               glLabelObject  *object)
289 {
290         gdouble            x, y, w, h;
291         guint              line_color;
292         gdouble            line_width;
293
294         gl_debug (DEBUG_VIEW, "START");
295
296         g_signal_handlers_block_by_func (G_OBJECT(object),
297                                          update_editor_from_object_cb,
298                                          editor);
299         g_signal_handlers_block_by_func (G_OBJECT(object),
300                                          update_editor_from_move_cb,
301                                          editor);
302
303
304         gl_object_editor_get_position (editor, &x, &y);
305         gl_label_object_set_position (object, x, y);
306
307         gl_object_editor_get_lsize (editor, &w, &h);
308         gl_label_object_set_size (object, w, h);
309
310         line_color = gl_object_editor_get_line_color (editor);
311         gl_label_object_set_line_color (object, line_color);
312
313         line_width = gl_object_editor_get_line_width (editor);
314         gl_label_object_set_line_width (object, line_width);
315
316
317         g_signal_handlers_unblock_by_func (G_OBJECT(object),
318                                            update_editor_from_object_cb,
319                                            editor);
320         g_signal_handlers_unblock_by_func (G_OBJECT(object),
321                                            update_editor_from_move_cb,
322                                            editor);
323
324         gl_debug (DEBUG_VIEW, "END");
325 }
326
327 /*---------------------------------------------------------------------------*/
328 /* PRIVATE. label object "changed" callback.                                 */
329 /*---------------------------------------------------------------------------*/
330 static void
331 update_editor_from_object_cb (glLabelObject  *object,
332                               glObjectEditor *editor)
333 {
334         gdouble            w, h;
335         guint              line_color;
336         gdouble            line_width;
337
338         gl_debug (DEBUG_VIEW, "START");
339
340         gl_label_object_get_size (object, &w, &h);
341         gl_object_editor_set_lsize (editor, w, h);
342
343         line_color = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
344         gl_object_editor_set_line_color (editor, line_color);
345
346         line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
347         gl_object_editor_set_line_width (editor, line_width);
348
349         gl_debug (DEBUG_VIEW, "END");
350 }
351
352 /*---------------------------------------------------------------------------*/
353 /* PRIVATE. label object "moved" callback.                                   */
354 /*---------------------------------------------------------------------------*/
355 static void
356 update_editor_from_move_cb (glLabelObject    *object,
357                             gdouble           dx,
358                             gdouble           dy,
359                             glObjectEditor   *editor)
360 {
361         gdouble            x, y;
362
363         gl_debug (DEBUG_VIEW, "START");
364
365         gl_label_object_get_position (object, &x, &y);
366         gl_object_editor_set_position (editor, x, y);
367
368         gl_debug (DEBUG_VIEW, "END");
369 }
370
371 /*---------------------------------------------------------------------------*/
372 /* PRIVATE. label "changed" callback.                                        */
373 /*---------------------------------------------------------------------------*/
374 static void
375 update_editor_from_label_cb (glLabel        *label,
376                              glObjectEditor *editor)
377 {
378         gdouble            label_width, label_height;
379
380         gl_debug (DEBUG_VIEW, "START");
381
382         gl_label_get_size (label, &label_width, &label_height);
383         gl_object_editor_set_max_position (GL_OBJECT_EDITOR (editor),
384                                            label_width, label_height);
385         gl_object_editor_set_max_lsize (GL_OBJECT_EDITOR (editor),
386                                         label_width, label_height);
387
388         gl_debug (DEBUG_VIEW, "END");
389 }
390
391 /*****************************************************************************/
392 /* Return apropos cursor for create object mode.                             */
393 /*****************************************************************************/
394 GdkCursor *
395 gl_view_line_get_create_cursor (void)
396 {
397         static GdkCursor *cursor = NULL;
398         GdkPixmap        *pixmap_data, *pixmap_mask;
399         GdkColor         fg = { 0, 0, 0, 0 };
400         GdkColor         bg = { 0, 65535, 65535, 65535 };
401
402         gl_debug (DEBUG_VIEW, "START");
403
404         if (!cursor) {
405                 pixmap_data = gdk_bitmap_create_from_data (NULL,
406                                                            cursor_line_bits,
407                                                            cursor_line_width,
408                                                            cursor_line_height);
409                 pixmap_mask = gdk_bitmap_create_from_data (NULL,
410                                                            cursor_line_mask_bits,
411                                                            cursor_line_mask_width,
412                                                            cursor_line_mask_height);
413                 cursor =
414                     gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
415                                                 &bg, cursor_line_x_hot,
416                                                 cursor_line_y_hot);
417         }
418
419         gl_debug (DEBUG_VIEW, "END");
420
421         return cursor;
422 }
423
424 /*****************************************************************************/
425 /* Canvas event handler for creating line objects.                            */
426 /*****************************************************************************/
427 int
428 gl_view_line_create_event_handler (GnomeCanvas *canvas,
429                                    GdkEvent    *event,
430                                    glView      *view)
431 {
432         static gdouble      x0, y0;
433         static gboolean     dragging = FALSE;
434         static glViewObject *view_line;
435         static GObject      *object;
436         gdouble             x, y, w, h;
437
438         gl_debug (DEBUG_VIEW, "");
439
440         switch (event->type) {
441
442         case GDK_BUTTON_PRESS:
443                 switch (event->button.button) {
444                 case 1:
445                         dragging = TRUE;
446                         gnome_canvas_item_grab (canvas->root,
447                                                 GDK_POINTER_MOTION_MASK |
448                                                 GDK_BUTTON_RELEASE_MASK |
449                                                 GDK_BUTTON_PRESS_MASK,
450                                                 NULL, event->button.time);
451                         gnome_canvas_window_to_world (canvas,
452                                                       event->button.x,
453                                                       event->button.y, &x, &y);
454                         object = gl_label_line_new (view->label);
455                         gl_label_object_set_position (GL_LABEL_OBJECT(object),
456                                                       x, y);
457                         gl_label_object_set_size (GL_LABEL_OBJECT(object),
458                                                   0.0, 0.0);
459                         gl_label_object_set_line_width (GL_LABEL_OBJECT(object),
460                                                       gl_view_get_default_line_width(view));
461                         gl_label_object_set_line_color (GL_LABEL_OBJECT(object),
462                                                      gl_color_set_opacity (gl_view_get_default_line_color(view), 0.5));
463                         view_line = gl_view_line_new (GL_LABEL_LINE(object),
464                                                       view);
465                         x0 = x;
466                         y0 = y;
467                         return TRUE;
468
469                 default:
470                         return FALSE;
471                 }
472
473         case GDK_BUTTON_RELEASE:
474                 switch (event->button.button) {
475                 case 1:
476                         dragging = FALSE;
477                         gnome_canvas_item_ungrab (canvas->root, event->button.time);
478                         gnome_canvas_window_to_world (canvas,
479                                                       event->button.x,
480                                                       event->button.y, &x, &y);
481                         if ((x0 == x) && (y0 == y)) {
482                                 x = x0 + 36.0;
483                                 y = y0 + 36.0;
484                         }
485                         w = x - x0;
486                         h = y - y0;
487                         gl_label_object_set_size (GL_LABEL_OBJECT(object),
488                                                   w, h);
489                         gl_label_object_set_line_color (GL_LABEL_OBJECT(object),
490                                                      gl_view_get_default_line_color(view));
491                         gl_view_unselect_all (view);
492                         gl_view_object_select (GL_VIEW_OBJECT(view_line));
493                         gl_view_arrow_mode (view);
494                         return TRUE;
495
496                 default:
497                         return FALSE;
498                 }
499
500         case GDK_MOTION_NOTIFY:
501                 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
502                         gnome_canvas_window_to_world (canvas,
503                                                       event->motion.x,
504                                                       event->motion.y, &x, &y);
505                         w = x - x0;
506                         h = y - y0;
507                         gl_label_object_set_size (GL_LABEL_OBJECT(object),
508                                                   w, h);
509                         return TRUE;
510                 } else {
511                         return FALSE;
512                 }
513
514         default:
515                 return FALSE;
516         }
517
518 }
519