]> git.sur5r.net Git - glabels/blob - glabels2/src/view-ellipse.c
Created generic "get" methods for text, fill and line properties for all label object...
[glabels] / glabels2 / src / view-ellipse.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  view_ellipse.c:  GLabels label ellipse 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-ellipse.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_ellipse.xbm"
34 #include "pixmaps/cursor_ellipse_mask.xbm"
35
36 #include "debug.h"
37
38 /*========================================================*/
39 /* Private macros and constants.                          */
40 /*========================================================*/
41
42 #define DELTA 0.01
43
44 /*========================================================*/
45 /* Private types.                                         */
46 /*========================================================*/
47
48 struct _glViewEllipsePrivate {
49         GnomeCanvasItem       *item;
50 };
51
52 /*========================================================*/
53 /* Private globals.                                       */
54 /*========================================================*/
55
56 static glViewObjectClass *parent_class = NULL;
57
58
59 /*========================================================*/
60 /* Private function prototypes.                           */
61 /*========================================================*/
62
63 static void       gl_view_ellipse_class_init        (glViewEllipseClass   *klass);
64 static void       gl_view_ellipse_instance_init     (glViewEllipse        *view_ellipse);
65 static void       gl_view_ellipse_finalize          (GObject              *object);
66
67 static GtkWidget *construct_properties_editor       (glViewObject         *view_object);
68
69 static void       update_canvas_item_from_object_cb (glLabelObject        *object,
70                                                      glViewEllipse        *view_ellipse);
71
72 static void       update_object_from_editor_cb      (glObjectEditor       *editor,
73                                                      glLabelObject        *object);
74
75 static void       update_editor_from_object_cb      (glLabelObject        *object,
76                                                      glObjectEditor       *editor);
77
78 static void       update_editor_from_move_cb        (glLabelObject        *object,
79                                                      gdouble               dx,
80                                                      gdouble               dy,
81                                                      glObjectEditor       *editor);
82
83 static void       update_editor_from_label_cb       (glLabel          *label,
84                                                      glObjectEditor   *editor);
85
86
87 \f
88 /*****************************************************************************/
89 /* Boilerplate object stuff.                                                 */
90 /*****************************************************************************/
91 GType
92 gl_view_ellipse_get_type (void)
93 {
94         static GType type = 0;
95
96         if (!type) {
97                 GTypeInfo info = {
98                         sizeof (glViewEllipseClass),
99                         NULL,
100                         NULL,
101                         (GClassInitFunc) gl_view_ellipse_class_init,
102                         NULL,
103                         NULL,
104                         sizeof (glViewEllipse),
105                         0,
106                         (GInstanceInitFunc) gl_view_ellipse_instance_init,
107                 };
108
109                 type = g_type_register_static (GL_TYPE_VIEW_OBJECT,
110                                                "glViewEllipse", &info, 0);
111         }
112
113         return type;
114 }
115
116 static void
117 gl_view_ellipse_class_init (glViewEllipseClass *klass)
118 {
119         GObjectClass      *object_class      = (GObjectClass *) klass;
120         glViewObjectClass *view_object_class = (glViewObjectClass *) klass;
121
122         gl_debug (DEBUG_VIEW, "START");
123
124         parent_class = g_type_class_peek_parent (klass);
125
126         object_class->finalize = gl_view_ellipse_finalize;
127
128         view_object_class->construct_editor = construct_properties_editor;
129
130         gl_debug (DEBUG_VIEW, "END");
131 }
132
133 static void
134 gl_view_ellipse_instance_init (glViewEllipse *view_ellipse)
135 {
136         gl_debug (DEBUG_VIEW, "START");
137
138         view_ellipse->private = g_new0 (glViewEllipsePrivate, 1);
139
140         gl_debug (DEBUG_VIEW, "END");
141 }
142
143 static void
144 gl_view_ellipse_finalize (GObject *object)
145 {
146         glLabel       *parent;
147
148         gl_debug (DEBUG_VIEW, "START");
149
150         g_return_if_fail (object && GL_IS_VIEW_ELLIPSE (object));
151
152         G_OBJECT_CLASS (parent_class)->finalize (object);
153
154         gl_debug (DEBUG_VIEW, "END");
155 }
156
157 /*****************************************************************************/
158 /* NEW ellipse object view.                                                  */
159 /*****************************************************************************/
160 glViewObject *
161 gl_view_ellipse_new (glLabelEllipse *object,
162                      glView         *view)
163 {
164         glViewEllipse     *view_ellipse;
165         gdouble            line_width;
166         guint              line_color, fill_color;
167         gdouble            w, h;
168
169         gl_debug (DEBUG_VIEW, "START");
170         g_return_if_fail (object && GL_IS_LABEL_ELLIPSE (object));
171         g_return_if_fail (view && GL_IS_VIEW (view));
172         
173         view_ellipse = g_object_new (gl_view_ellipse_get_type(), NULL);
174
175         gl_view_object_set_view (GL_VIEW_OBJECT(view_ellipse), view);
176         gl_view_object_set_object (GL_VIEW_OBJECT(view_ellipse),
177                                    GL_LABEL_OBJECT(object),
178                                    GL_VIEW_HIGHLIGHT_ELLIPSE_RESIZABLE);
179
180         /* Query properties of object. */
181         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
182         line_width = gl_label_object_get_line_width(GL_LABEL_OBJECT(object));
183         line_color = gl_label_object_get_line_color(GL_LABEL_OBJECT(object));
184         fill_color = gl_label_object_get_fill_color(GL_LABEL_OBJECT(object));
185
186         /* Create analogous canvas item. */
187         view_ellipse->private->item =
188                 gl_view_object_item_new (GL_VIEW_OBJECT(view_ellipse),
189                                          gnome_canvas_ellipse_get_type (),
190                                          "x1", 0.0,
191                                          "y1", 0.0,
192                                          "x2", w + DELTA,
193                                          "y2", h + DELTA,
194                                          "width_units", line_width,
195                                          "outline_color_rgba", line_color,
196                                          "fill_color_rgba", fill_color,
197                                          NULL);
198
199         g_signal_connect (G_OBJECT (object), "changed",
200                           G_CALLBACK (update_canvas_item_from_object_cb), view_ellipse);
201
202         gl_debug (DEBUG_VIEW, "END");
203
204         return GL_VIEW_OBJECT (view_ellipse);
205 }
206
207 /*****************************************************************************/
208 /* Create a properties editor for an ellipse object.                         */
209 /*****************************************************************************/
210 static GtkWidget *
211 construct_properties_editor (glViewObject *view_object)
212 {
213         GtkWidget          *editor;
214         glViewEllipse      *view_ellipse = (glViewEllipse *)view_object;
215         glLabelObject      *object;
216
217         gl_debug (DEBUG_VIEW, "START");
218
219         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_ellipse));
220
221         /* Build editor. */
222         editor = gl_object_editor_new (GL_STOCK_ELLIPSE, _("Ellipse object properties"),
223                                        GL_OBJECT_EDITOR_POSITION_PAGE,
224                                        GL_OBJECT_EDITOR_SIZE_PAGE,
225                                        GL_OBJECT_EDITOR_FILL_PAGE,
226                                        GL_OBJECT_EDITOR_LINE_PAGE,
227                                        0);
228         
229         /* Update */
230         update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
231         update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
232         update_editor_from_label_cb (object->parent, GL_OBJECT_EDITOR(editor));
233
234         /* Connect signals. */
235         g_signal_connect (G_OBJECT (editor), "changed",
236                           G_CALLBACK(update_object_from_editor_cb), object);
237         g_signal_connect (G_OBJECT (object), "changed",
238                           G_CALLBACK (update_editor_from_object_cb), editor);
239         g_signal_connect (G_OBJECT (object), "moved",
240                           G_CALLBACK (update_editor_from_move_cb), editor);
241         g_signal_connect (G_OBJECT (object->parent), "size_changed",
242                           G_CALLBACK (update_editor_from_label_cb), editor);
243
244         gl_debug (DEBUG_VIEW, "END");
245
246         return editor;
247 }
248
249 /*---------------------------------------------------------------------------*/
250 /* PRIVATE. label object "changed" callback.                                 */
251 /*---------------------------------------------------------------------------*/
252 static void
253 update_canvas_item_from_object_cb (glLabelObject *object,
254                                    glViewEllipse *view_ellipse)
255 {
256         gdouble            line_width;
257         guint              line_color, fill_color;
258         gdouble            w, h;
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         fill_color = gl_label_object_get_fill_color(GL_LABEL_OBJECT(object));
267
268         /* Adjust appearance of analogous canvas item. */
269         gnome_canvas_item_set (view_ellipse->private->item,
270                                "x2", w + DELTA,
271                                "y2", h + DELTA,
272                                "width_units", line_width,
273                                "outline_color_rgba", line_color,
274                                "fill_color_rgba", fill_color,
275                                NULL);
276
277         gl_debug (DEBUG_VIEW, "END");
278 }
279
280 /*---------------------------------------------------------------------------*/
281 /* PRIVATE.  editor "changed" callback.                                      */
282 /*---------------------------------------------------------------------------*/
283 static void
284 update_object_from_editor_cb (glObjectEditor *editor,
285                               glLabelObject  *object)
286 {
287         gdouble            x, y, w, h;
288         guint              line_color, fill_color;
289         gdouble            line_width;
290
291         gl_debug (DEBUG_VIEW, "START");
292
293         g_signal_handlers_block_by_func (G_OBJECT(object),
294                                          update_editor_from_object_cb,
295                                          editor);
296         g_signal_handlers_block_by_func (G_OBJECT(object),
297                                          update_editor_from_move_cb,
298                                          editor);
299
300
301         gl_object_editor_get_position (editor, &x, &y);
302         gl_label_object_set_position (object, x, y);
303
304         gl_object_editor_get_size (editor, &w, &h);
305         gl_label_object_set_size (object, w, h);
306
307         fill_color = gl_object_editor_get_fill_color (editor);
308         gl_label_object_set_fill_color (object, fill_color);
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, fill_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_size (editor, w, h);
342
343         fill_color = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
344         gl_object_editor_set_fill_color (editor, fill_color);
345
346         line_color = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
347         gl_object_editor_set_line_color (editor, line_color);
348
349         line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
350         gl_object_editor_set_line_width (editor, line_width);
351
352         gl_debug (DEBUG_VIEW, "END");
353 }
354
355 /*---------------------------------------------------------------------------*/
356 /* PRIVATE. label object "moved" callback.                                   */
357 /*---------------------------------------------------------------------------*/
358 static void
359 update_editor_from_move_cb (glLabelObject    *object,
360                             gdouble           dx,
361                             gdouble           dy,
362                             glObjectEditor   *editor)
363 {
364         gdouble            x, y;
365
366         gl_debug (DEBUG_VIEW, "START");
367
368         gl_label_object_get_position (object, &x, &y);
369         gl_object_editor_set_position (editor, x, y);
370
371         gl_debug (DEBUG_VIEW, "END");
372 }
373
374 /*---------------------------------------------------------------------------*/
375 /* PRIVATE. label "changed" callback.                                        */
376 /*---------------------------------------------------------------------------*/
377 static void
378 update_editor_from_label_cb (glLabel        *label,
379                              glObjectEditor *editor)
380 {
381         gdouble            label_width, label_height;
382
383         gl_debug (DEBUG_VIEW, "START");
384
385         gl_label_get_size (label, &label_width, &label_height);
386         gl_object_editor_set_max_position (GL_OBJECT_EDITOR (editor),
387                                            label_width, label_height);
388         gl_object_editor_set_max_size (GL_OBJECT_EDITOR (editor),
389                                        label_width, label_height);
390
391         gl_debug (DEBUG_VIEW, "END");
392 }
393
394 /*****************************************************************************/
395 /* Return apropos cursor for create object mode.                             */
396 /*****************************************************************************/
397 GdkCursor *
398 gl_view_ellipse_get_create_cursor (void)
399 {
400         static GdkCursor *cursor = NULL;
401         GdkPixmap        *pixmap_data, *pixmap_mask;
402         GdkColor         fg = { 0, 0, 0, 0 };
403         GdkColor         bg = { 0, 65535, 65535, 65535 };
404
405         gl_debug (DEBUG_VIEW, "START");
406
407         if (!cursor) {
408                 pixmap_data = gdk_bitmap_create_from_data (NULL,
409                                                            cursor_ellipse_bits,
410                                                            cursor_ellipse_width,
411                                                            cursor_ellipse_height);
412                 pixmap_mask = gdk_bitmap_create_from_data (NULL,
413                                                            cursor_ellipse_mask_bits,
414                                                            cursor_ellipse_mask_width,
415                                                            cursor_ellipse_mask_height);
416                 cursor =
417                     gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
418                                                 &bg, cursor_ellipse_x_hot,
419                                                 cursor_ellipse_y_hot);
420         }
421
422         gl_debug (DEBUG_VIEW, "END");
423
424         return cursor;
425 }
426
427 /*****************************************************************************/
428 /* Canvas event handler for creating ellipse objects.                        */
429 /*****************************************************************************/
430 int
431 gl_view_ellipse_create_event_handler (GnomeCanvas *canvas,
432                                       GdkEvent    *event,
433                                       glView      *view)
434 {
435         static gdouble       x0, y0;
436         static gboolean      dragging = FALSE;
437         static glViewObject *view_ellipse;
438         static GObject      *object;
439         guint                line_color, fill_color;
440         gdouble              x, y, w, h;
441
442         gl_debug (DEBUG_VIEW, "");
443
444         switch (event->type) {
445
446         case GDK_BUTTON_PRESS:
447                 switch (event->button.button) {
448                 case 1:
449                         dragging = TRUE;
450                         gnome_canvas_item_grab ( canvas->root,
451                                                  GDK_POINTER_MOTION_MASK |
452                                                  GDK_BUTTON_RELEASE_MASK |
453                                                  GDK_BUTTON_PRESS_MASK,
454                                                  NULL, event->button.time);
455                         gnome_canvas_window_to_world (canvas,
456                                                       event->button.x,
457                                                       event->button.y, &x, &y);
458                         object = gl_label_ellipse_new (view->label);
459                         gl_label_object_set_position (GL_LABEL_OBJECT(object),
460                                                      x, y);
461                         gl_label_object_set_size (GL_LABEL_OBJECT(object),
462                                                   0.0, 0.0);
463                         line_color = gl_color_set_opacity (gl_view_get_default_line_color(view), 0.5);
464                         fill_color = gl_color_set_opacity (gl_view_get_default_fill_color(view), 0.5);
465                         gl_label_object_set_line_width (GL_LABEL_OBJECT(object),
466                                                      gl_view_get_default_line_width(view));
467                         gl_label_object_set_line_color (GL_LABEL_OBJECT(object),
468                                                          line_color);
469                         gl_label_object_set_fill_color (GL_LABEL_OBJECT(object),
470                                                          fill_color);
471                         view_ellipse = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object),
472                                                             view);
473                         x0 = x;
474                         y0 = y;
475                         return TRUE;
476
477                 default:
478                         return FALSE;
479                 }
480
481         case GDK_BUTTON_RELEASE:
482                 switch (event->button.button) {
483                 case 1:
484                         dragging = FALSE;
485                         gnome_canvas_item_ungrab (canvas->root, event->button.time);
486                         gnome_canvas_window_to_world (canvas,
487                                                       event->button.x,
488                                                       event->button.y, &x, &y);
489                         if ((x0 == x) && (y0 == y)) {
490                                 x = x0 + 36.0;
491                                 y = y0 + 36.0;
492                         }
493                         gl_label_object_set_position (GL_LABEL_OBJECT(object),
494                                                      MIN (x, x0), MIN (y, y0));
495                         w = MAX (x, x0) - MIN (x, x0);
496                         h = MAX (y, y0) - MIN (y, y0);
497                         gl_label_object_set_size (GL_LABEL_OBJECT(object),
498                                                   w, h);
499                         gl_label_object_set_line_color (GL_LABEL_OBJECT(object),
500                                                      gl_view_get_default_line_color(view));
501                         gl_label_object_set_fill_color (GL_LABEL_OBJECT(object),
502                                                      gl_view_get_default_fill_color(view));
503                         gl_view_unselect_all (view);
504                         gl_view_object_select (GL_VIEW_OBJECT(view_ellipse));
505                         gl_view_arrow_mode (view);
506                         return TRUE;
507
508                 default:
509                         return FALSE;
510                 }
511
512         case GDK_MOTION_NOTIFY:
513                 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
514                         gnome_canvas_window_to_world (canvas,
515                                                       event->motion.x,
516                                                       event->motion.y, &x, &y);
517                         gl_label_object_set_position (GL_LABEL_OBJECT(object),
518                                                      MIN (x, x0), MIN (y, y0));
519                         w = MAX (x, x0) - MIN (x, x0);
520                         h = MAX (y, y0) - MIN (y, y0);
521                         gl_label_object_set_size (GL_LABEL_OBJECT(object),
522                                                   w, h);
523                         return TRUE;
524                 } else {
525                         return FALSE;
526                 }
527
528         default:
529                 return FALSE;
530         }
531
532 }