]> git.sur5r.net Git - glabels/blob - glabels2/src/view-ellipse.c
Initial revision
[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-2002  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 "glabels.h"
30 #include "wdgt-line.h"
31 #include "wdgt-fill.h"
32 #include "wdgt-size.h"
33 #include "wdgt-position.h"
34
35 #include "pixmaps/cursor_ellipse.xbm"
36 #include "pixmaps/cursor_ellipse_mask.xbm"
37
38 #include "debug.h"
39
40 /*========================================================*/
41 /* Private macros and constants.                          */
42 /*========================================================*/
43 #define CREATE_LINE_COLOR   GNOME_CANVAS_COLOR_A (0, 0, 0, 192)
44 #define CREATE_FILL_COLOR   GNOME_CANVAS_COLOR_A (0, 255, 0, 192)
45
46 #define DEFAULT_LINE_COLOR  GNOME_CANVAS_COLOR_A (0, 0, 0, 255)
47 #define DEFAULT_FILL_COLOR  GNOME_CANVAS_COLOR_A (0, 255, 0, 255)
48
49 #define DELTA 0.01
50
51 /*========================================================*/
52 /* Private types.                                         */
53 /*========================================================*/
54
55 struct _glViewEllipsePrivate {
56         GnomeCanvasItem *item;
57
58         /* Property dialog Page 0 widgets */
59         GtkWidget             *line;
60         GtkWidget             *fill;
61
62         /* Property dialog Page 1 widgets */
63         GtkWidget             *position;
64         GtkWidget             *size;
65 };
66
67 /*========================================================*/
68 /* Private globals.                                       */
69 /*========================================================*/
70
71 static glViewObjectClass *parent_class = NULL;
72
73
74 /*========================================================*/
75 /* Private function prototypes.                           */
76 /*========================================================*/
77
78 static void      gl_view_ellipse_class_init    (glViewEllipseClass *klass);
79 static void      gl_view_ellipse_instance_init (glViewEllipse *view_ellipse);
80 static void      gl_view_ellipse_finalize      (GObject *object);
81
82 static void      update_view_ellipse_cb        (glLabelObject *object,
83                                                 glViewEllipse *view_ellipse);
84
85 static GtkWidget *construct_properties_dialog  (glViewEllipse *view_ellipse);
86
87 static void      response_cb                   (GtkDialog *dialog,
88                                                 gint response,
89                                                 glViewEllipse *view_ellipse);
90
91 static void      line_changed_cb               (glWdgtLine *line,
92                                                 glViewEllipse *view_ellipse);
93
94 static void      fill_changed_cb               (glWdgtFill *fill,
95                                                 glViewEllipse *view_ellipse);
96
97 static void      position_changed_cb           (glWdgtPosition *position,
98                                                 glViewEllipse *view_ellipse);
99
100 static void      size_changed_cb               (glWdgtSize *size,
101                                                 glViewEllipse *view_ellipse);
102
103 static void      update_dialog_cb              (glLabelObject *object,
104                                                 glViewEllipse *view_ellipse);
105
106 \f
107 /*****************************************************************************/
108 /* Boilerplate object stuff.                                                 */
109 /*****************************************************************************/
110 GType
111 gl_view_ellipse_get_type (void)
112 {
113         static GType type = 0;
114
115         if (!type) {
116                 GTypeInfo info = {
117                         sizeof (glViewEllipseClass),
118                         NULL,
119                         NULL,
120                         (GClassInitFunc) gl_view_ellipse_class_init,
121                         NULL,
122                         NULL,
123                         sizeof (glViewEllipse),
124                         0,
125                         (GInstanceInitFunc) gl_view_ellipse_instance_init,
126                 };
127
128                 type = g_type_register_static (GL_TYPE_VIEW_OBJECT,
129                                                "glViewEllipse", &info, 0);
130         }
131
132         return type;
133 }
134
135 static void
136 gl_view_ellipse_class_init (glViewEllipseClass *klass)
137 {
138         GObjectClass *object_class = (GObjectClass *) klass;
139
140         gl_debug (DEBUG_VIEW, "START");
141
142         parent_class = g_type_class_peek_parent (klass);
143
144         object_class->finalize = gl_view_ellipse_finalize;
145
146         gl_debug (DEBUG_VIEW, "END");
147 }
148
149 static void
150 gl_view_ellipse_instance_init (glViewEllipse *view_ellipse)
151 {
152         gl_debug (DEBUG_VIEW, "START");
153
154         view_ellipse->private = g_new0 (glViewEllipsePrivate, 1);
155
156         gl_debug (DEBUG_VIEW, "END");
157 }
158
159 static void
160 gl_view_ellipse_finalize (GObject *object)
161 {
162         glLabel       *parent;
163
164         gl_debug (DEBUG_VIEW, "START");
165
166         g_return_if_fail (object && GL_IS_VIEW_ELLIPSE (object));
167
168         G_OBJECT_CLASS (parent_class)->finalize (object);
169
170         gl_debug (DEBUG_VIEW, "END");
171 }
172
173 /*****************************************************************************/
174 /* NEW ellipse object view.                                                  */
175 /*****************************************************************************/
176 glViewObject *
177 gl_view_ellipse_new (glLabelEllipse *object,
178                      glView     *view)
179 {
180         glViewEllipse      *view_ellipse;
181         GnomeCanvasItem    *group;
182         gdouble            line_width;
183         guint              line_color, fill_color;
184         gdouble            w, h;
185         GtkMenu            *menu;
186         GtkWidget          *dialog;
187
188         gl_debug (DEBUG_VIEW, "START");
189         g_return_if_fail (object && GL_IS_LABEL_ELLIPSE (object));
190         g_return_if_fail (view && GL_IS_VIEW (view));
191         
192         view_ellipse = g_object_new (gl_view_ellipse_get_type(), NULL);
193
194         gl_view_object_set_view (GL_VIEW_OBJECT(view_ellipse), view);
195         gl_view_object_set_object (GL_VIEW_OBJECT(view_ellipse),
196                                    GL_LABEL_OBJECT(object),
197                                    GL_VIEW_HIGHLIGHT_ELLIPSE_RESIZABLE);
198
199         /* Query properties of object. */
200         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
201         line_width = gl_label_ellipse_get_line_width(object);
202         line_color = gl_label_ellipse_get_line_color(object);
203         fill_color = gl_label_ellipse_get_fill_color(object);
204
205         /* Create analogous canvas item. */
206         group = gl_view_object_get_group (GL_VIEW_OBJECT(view_ellipse));
207         view_ellipse->private->item =
208                 gnome_canvas_item_new (GNOME_CANVAS_GROUP(group),
209                                        gnome_canvas_ellipse_get_type (),
210                                        "x1", 0.0,
211                                        "y1", 0.0,
212                                        "x2", w + DELTA,
213                                        "y2", h + DELTA,
214                                        "width_units", line_width,
215                                        "outline_color_rgba", line_color,
216                                        "fill_color_rgba", fill_color,
217                                        NULL);
218
219         g_signal_connect (G_OBJECT (object), "changed",
220                           G_CALLBACK (update_view_ellipse_cb), view_ellipse);
221
222         /* Create a dialog for controlling/viewing object properties. */
223         dialog = construct_properties_dialog (view_ellipse);
224         gl_view_object_set_dialog     (GL_VIEW_OBJECT(view_ellipse), dialog);
225
226         gl_debug (DEBUG_VIEW, "END");
227
228         return GL_VIEW_OBJECT (view_ellipse);
229 }
230
231 /*---------------------------------------------------------------------------*/
232 /* PRIVATE. label object "changed" callback.                                 */
233 /*---------------------------------------------------------------------------*/
234 static void
235 update_view_ellipse_cb (glLabelObject *object,
236                         glViewEllipse     *view_ellipse)
237 {
238         gdouble            line_width;
239         guint              line_color, fill_color;
240         gdouble            w, h;
241
242         gl_debug (DEBUG_VIEW, "START");
243
244         /* Query properties of object. */
245         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
246         line_width = gl_label_ellipse_get_line_width(GL_LABEL_ELLIPSE(object));
247         line_color = gl_label_ellipse_get_line_color(GL_LABEL_ELLIPSE(object));
248         fill_color = gl_label_ellipse_get_fill_color(GL_LABEL_ELLIPSE(object));
249
250         /* Adjust appearance of analogous canvas item. */
251         gnome_canvas_item_set (view_ellipse->private->item,
252                                "x2", w + DELTA,
253                                "y2", h + DELTA,
254                                "width_units", line_width,
255                                "outline_color_rgba", line_color,
256                                "fill_color_rgba", fill_color,
257                                NULL);
258
259         /* Adjust highlight */
260         gl_view_object_update_highlight (GL_VIEW_OBJECT(view_ellipse));
261
262         gl_debug (DEBUG_VIEW, "END");
263 }
264
265 /*****************************************************************************/
266 /* Create a properties dialog for a ellipse object.                          */
267 /*****************************************************************************/
268 static GtkWidget *
269 construct_properties_dialog (glViewEllipse *view_ellipse)
270 {
271         GtkWidget          *dialog, *notebook, *wvbox;
272         BonoboWindow       *win = glabels_get_active_window ();
273         glLabelObject      *object;
274         gdouble            line_width;
275         guint              line_color, fill_color;
276         gdouble            x, y, w, h, label_width, label_height;
277
278         gl_debug (DEBUG_VIEW, "START");
279
280         /* retrieve object and query parameters */
281         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_ellipse));
282         gl_label_object_get_position (GL_LABEL_OBJECT(object), &x, &y);
283         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
284         line_width = gl_label_ellipse_get_line_width(GL_LABEL_ELLIPSE(object));
285         line_color = gl_label_ellipse_get_line_color(GL_LABEL_ELLIPSE(object));
286         fill_color = gl_label_ellipse_get_fill_color(GL_LABEL_ELLIPSE(object));
287         gl_label_get_size (GL_LABEL(object->parent),
288                            &label_width, &label_height);
289
290         /*-----------------------------------------------------------------*/
291         /* Build dialog with notebook.                                     */
292         /*-----------------------------------------------------------------*/
293         dialog = gtk_dialog_new_with_buttons ( _("Edit ellipse object properties"),
294                                                GTK_WINDOW (win),
295                                                GTK_DIALOG_DESTROY_WITH_PARENT,
296                                                GTK_STOCK_CLOSE,
297                                                            GTK_RESPONSE_CLOSE,
298                                                NULL );
299         g_signal_connect (G_OBJECT (dialog), "response",
300                           G_CALLBACK (response_cb), view_ellipse);
301
302         notebook = gtk_notebook_new ();
303         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
304                             notebook, TRUE, TRUE, 0);
305
306         /*---------------------------*/
307         /* Appearance Notebook Tab   */
308         /*---------------------------*/
309         wvbox = gtk_vbox_new (FALSE, GNOME_PAD);
310         gtk_container_set_border_width (GTK_CONTAINER (wvbox), 10);
311         gtk_notebook_append_page (GTK_NOTEBOOK (notebook), wvbox,
312                                   gtk_label_new (_("Appearance")));
313
314         /* ------ Line ellipse ------ */
315         view_ellipse->private->line = gl_wdgt_line_new (_("Outline"));
316         gl_wdgt_line_set_params (GL_WDGT_LINE (view_ellipse->private->line),
317                                  line_width,
318                                  line_color);
319         gtk_box_pack_start (GTK_BOX (wvbox), view_ellipse->private->line,
320                                 FALSE, FALSE, 0);
321         g_signal_connect (G_OBJECT (view_ellipse->private->line), "changed",
322                           G_CALLBACK(line_changed_cb), view_ellipse);
323
324         /* ------ Fill ellipse ------ */
325         view_ellipse->private->fill = gl_wdgt_fill_new (_("Fill"));
326         gl_wdgt_fill_set_params (GL_WDGT_FILL (view_ellipse->private->fill),
327                                  fill_color);
328         gtk_box_pack_start (GTK_BOX (wvbox), view_ellipse->private->fill,
329                                 FALSE, FALSE, 0);
330         g_signal_connect (G_OBJECT (view_ellipse->private->fill), "changed",
331                           G_CALLBACK(fill_changed_cb), view_ellipse);
332
333
334         /*----------------------------*/
335         /* Position/Size Notebook Tab */
336         /*----------------------------*/
337         wvbox = gtk_vbox_new (FALSE, GNOME_PAD);
338         gtk_container_set_border_width (GTK_CONTAINER (wvbox), 10);
339         gtk_notebook_append_page (GTK_NOTEBOOK (notebook), wvbox,
340                                   gtk_label_new (_("Position/Size")));
341
342         /* ------ Position Frame ------ */
343         view_ellipse->private->position = gl_wdgt_position_new (_("Position"));
344         gl_wdgt_position_set_params (GL_WDGT_POSITION (view_ellipse->private->position),
345                                      x, y,
346                                      label_width, label_height);
347         gtk_box_pack_start (GTK_BOX (wvbox),
348                                 view_ellipse->private->position,
349                             FALSE, FALSE, 0);
350         g_signal_connect (G_OBJECT (view_ellipse->private->position),
351                           "changed",
352                           G_CALLBACK(position_changed_cb), view_ellipse);
353
354
355         /* ------ Size Frame ------ */
356         view_ellipse->private->size = gl_wdgt_size_new (_("Size"));
357         gl_wdgt_size_set_params (GL_WDGT_SIZE (view_ellipse->private->size),
358                                  w, h,
359                                  TRUE,
360                                  label_width, label_height);
361         gtk_box_pack_start (GTK_BOX (wvbox), view_ellipse->private->size,
362                                 FALSE, FALSE, 0);
363         g_signal_connect (G_OBJECT (view_ellipse->private->size), "changed",
364                           G_CALLBACK(size_changed_cb), view_ellipse);
365
366
367         /*----------------------------*/
368         /* Track object changes.      */
369         /*----------------------------*/
370         g_signal_connect (G_OBJECT (object), "changed",
371                           G_CALLBACK (update_dialog_cb), view_ellipse);
372
373         gl_debug (DEBUG_VIEW, "END");
374
375         return dialog;
376 }
377
378 /*---------------------------------------------------------------------------*/
379 /* PRIVATE.  "Response" callback.                                            */
380 /*---------------------------------------------------------------------------*/
381 static void
382 response_cb (GtkDialog     *dialog,
383              gint          response,
384              glViewEllipse *view_ellipse)
385 {
386         gl_debug (DEBUG_VIEW, "START");
387
388         g_return_if_fail(dialog != NULL);
389         g_return_if_fail(GTK_IS_DIALOG(dialog));
390
391         switch(response) {
392         case GTK_RESPONSE_CLOSE:
393                 gtk_widget_hide (GTK_WIDGET(dialog));
394                 break;
395         default:
396                 g_assert_not_reached();
397         }
398
399         gl_debug (DEBUG_VIEW, "END");
400 }
401
402 /*---------------------------------------------------------------------------*/
403 /* PRIVATE.  line properties "changed" callback.                             */
404 /*---------------------------------------------------------------------------*/
405 static void
406 line_changed_cb (glWdgtLine     *line,
407                  glViewEllipse  *view_ellipse)
408 {
409         glLabelObject      *object;
410         gdouble            line_width;
411         guint              line_color;
412
413         gl_debug (DEBUG_VIEW, "START");
414
415         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_ellipse));
416
417         gl_wdgt_line_get_params (GL_WDGT_LINE (line),
418                                  &line_width,
419                                  &line_color);
420
421         g_signal_handlers_block_by_func (G_OBJECT(object),
422                                          update_dialog_cb, view_ellipse);
423         gl_label_ellipse_set_line_width(GL_LABEL_ELLIPSE(object), line_width);
424         gl_label_ellipse_set_line_color(GL_LABEL_ELLIPSE(object), line_color);
425         g_signal_handlers_unblock_by_func (G_OBJECT(object),
426                                            update_dialog_cb, view_ellipse);
427
428         gl_debug (DEBUG_VIEW, "END");
429 }
430
431 /*---------------------------------------------------------------------------*/
432 /* PRIVATE.  fill properties "changed" callback.                             */
433 /*---------------------------------------------------------------------------*/
434 static void
435 fill_changed_cb (glWdgtFill     *fill,
436                  glViewEllipse  *view_ellipse)
437 {
438         glLabelObject    *object;
439         guint            fill_color;
440
441         gl_debug (DEBUG_VIEW, "START");
442
443         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_ellipse));
444
445         gl_wdgt_fill_get_params (GL_WDGT_FILL (fill),
446                                  &fill_color);
447
448         g_signal_handlers_block_by_func (G_OBJECT(object),
449                                          update_dialog_cb, view_ellipse);
450         gl_label_ellipse_set_fill_color(GL_LABEL_ELLIPSE(object), fill_color);
451         g_signal_handlers_unblock_by_func (G_OBJECT(object),
452                                            update_dialog_cb, view_ellipse);
453
454         gl_debug (DEBUG_VIEW, "END");
455 }
456
457 /*---------------------------------------------------------------------------*/
458 /* PRIVATE.  position "changed" callback.                                    */
459 /*---------------------------------------------------------------------------*/
460 static void
461 position_changed_cb (glWdgtPosition     *position,
462                      glViewEllipse      *view_ellipse)
463 {
464         glLabelObject      *object;
465         gdouble            x, y;
466
467         gl_debug (DEBUG_VIEW, "START");
468
469         gl_wdgt_position_get_position (GL_WDGT_POSITION (position), &x, &y);
470
471         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_ellipse));
472
473         g_signal_handlers_block_by_func (G_OBJECT(object),
474                                          update_dialog_cb, view_ellipse);
475         gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
476         g_signal_handlers_unblock_by_func (G_OBJECT(object),
477                                            update_dialog_cb, view_ellipse);
478
479         gl_debug (DEBUG_VIEW, "END");
480 }
481
482 /*---------------------------------------------------------------------------*/
483 /* PRIVATE.  size "changed" callback.                                        */
484 /*---------------------------------------------------------------------------*/
485 static void
486 size_changed_cb (glWdgtSize     *size,
487                  glViewEllipse  *view_ellipse)
488 {
489         glLabelObject *object;
490         gdouble       w, h;
491         gboolean      keep_aspect_ratio_flag;
492
493         gl_debug (DEBUG_VIEW, "START");
494
495         gl_wdgt_size_get_size (GL_WDGT_SIZE (size),
496                                &w, &h, &keep_aspect_ratio_flag);
497
498         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_ellipse));
499
500         g_signal_handlers_block_by_func (G_OBJECT(object),
501                                          update_dialog_cb, view_ellipse);
502         gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
503         g_signal_handlers_unblock_by_func (G_OBJECT(object),
504                                            update_dialog_cb, view_ellipse);
505
506         gl_debug (DEBUG_VIEW, "END");
507 }
508
509 /*---------------------------------------------------------------------------*/
510 /* PRIVATE. label object "changed" callback.                                 */
511 /*---------------------------------------------------------------------------*/
512 static void
513 update_dialog_cb (glLabelObject     *object,
514                   glViewEllipse     *view_ellipse)
515 {
516         gdouble            line_width;
517         guint              line_color, fill_color;
518         gdouble            x, y, w, h;
519
520         gl_debug (DEBUG_VIEW, "START");
521
522         /* Query properties of object. */
523         gl_label_object_get_position (GL_LABEL_OBJECT(object), &x, &y);
524         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
525         line_width = gl_label_ellipse_get_line_width(GL_LABEL_ELLIPSE(object));
526         line_color = gl_label_ellipse_get_line_color(GL_LABEL_ELLIPSE(object));
527         fill_color = gl_label_ellipse_get_fill_color(GL_LABEL_ELLIPSE(object));
528
529         /* Block widget handlers to prevent recursion */
530         g_signal_handlers_block_by_func (G_OBJECT(view_ellipse->private->line),
531                                          line_changed_cb, view_ellipse);
532         g_signal_handlers_block_by_func (G_OBJECT(view_ellipse->private->fill),
533                                          fill_changed_cb, view_ellipse);
534         g_signal_handlers_block_by_func (G_OBJECT(view_ellipse->private->position),
535                                          position_changed_cb, view_ellipse);
536         g_signal_handlers_block_by_func (G_OBJECT(view_ellipse->private->size),
537                                          size_changed_cb, view_ellipse);
538
539         /* Update widgets in property dialog */
540         gl_wdgt_line_set_params (GL_WDGT_LINE (view_ellipse->private->line),
541                                  line_width,
542                                  line_color);
543         gl_wdgt_fill_set_params (GL_WDGT_FILL (view_ellipse->private->fill),
544                                  fill_color);
545         gl_wdgt_position_set_position (GL_WDGT_POSITION(view_ellipse->private->position),
546                                        x, y);
547         gl_wdgt_size_set_size (GL_WDGT_SIZE(view_ellipse->private->size), w, h);
548
549         /* Unblock widget handlers */
550         g_signal_handlers_unblock_by_func (G_OBJECT(view_ellipse->private->line),
551                                            line_changed_cb, view_ellipse);
552         g_signal_handlers_unblock_by_func (G_OBJECT(view_ellipse->private->fill),
553                                            fill_changed_cb, view_ellipse);
554         g_signal_handlers_unblock_by_func (G_OBJECT(view_ellipse->private->position),
555                                            position_changed_cb, view_ellipse);
556         g_signal_handlers_unblock_by_func (G_OBJECT(view_ellipse->private->size),
557                                            size_changed_cb, view_ellipse);
558
559
560         gl_debug (DEBUG_VIEW, "END");
561 }
562
563 /*****************************************************************************/
564 /* Return apropos cursor for create object mode.                             */
565 /*****************************************************************************/
566 GdkCursor *
567 gl_view_ellipse_get_create_cursor (void)
568 {
569         static GdkCursor *cursor = NULL;
570         GdkPixmap        *pixmap_data, *pixmap_mask;
571         GdkColor         fg = { 0, 0, 0, 0 };
572         GdkColor         bg = { 0, 65535, 65535, 65535 };
573
574         gl_debug (DEBUG_VIEW, "START");
575
576         if (!cursor) {
577                 pixmap_data = gdk_bitmap_create_from_data (NULL,
578                                                            cursor_ellipse_bits,
579                                                            cursor_ellipse_width,
580                                                            cursor_ellipse_height);
581                 pixmap_mask = gdk_bitmap_create_from_data (NULL,
582                                                            cursor_ellipse_mask_bits,
583                                                            cursor_ellipse_mask_width,
584                                                            cursor_ellipse_mask_height);
585                 cursor =
586                     gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
587                                                 &bg, cursor_ellipse_x_hot,
588                                                 cursor_ellipse_y_hot);
589         }
590
591         gl_debug (DEBUG_VIEW, "END");
592
593         return cursor;
594 }
595
596 /*****************************************************************************/
597 /* Canvas event handler for creating ellipse objects.                            */
598 /*****************************************************************************/
599 int
600 gl_view_ellipse_create_event_handler (GnomeCanvas *canvas,
601                                       GdkEvent    *event,
602                                       glView      *view)
603 {
604         static gdouble      x0, y0;
605         static gboolean     dragging = FALSE;
606         static glViewObject *view_ellipse;
607         static GObject      *object;
608         gdouble             line_width;
609         guint               line_color, fill_color;
610         gdouble             x, y, w, h;
611
612         gl_debug (DEBUG_VIEW, "");
613
614         switch (event->type) {
615
616         case GDK_BUTTON_PRESS:
617                 switch (event->button.button) {
618                 case 1:
619                         dragging = TRUE;
620                         gdk_pointer_grab (GTK_WIDGET (view->canvas)->window,
621                                           FALSE,
622                                           GDK_POINTER_MOTION_MASK |
623                                           GDK_BUTTON_RELEASE_MASK |
624                                           GDK_BUTTON_PRESS_MASK,
625                                           NULL, NULL, event->button.time);
626                         gnome_canvas_window_to_world (canvas,
627                                                       event->button.x,
628                                                       event->button.y, &x, &y);
629                         object = gl_label_ellipse_new (view->label);
630                         gl_label_object_set_position (GL_LABEL_OBJECT(object),
631                                                      x, y);
632                         gl_label_object_set_size (GL_LABEL_OBJECT(object),
633                                                   0.0, 0.0);
634                         line_width = 1.0;
635                         line_color = CREATE_LINE_COLOR;
636                         fill_color = CREATE_FILL_COLOR;
637                         gl_label_ellipse_set_line_width (GL_LABEL_ELLIPSE(object),
638                                                      line_width);
639                         gl_label_ellipse_set_line_color (GL_LABEL_ELLIPSE(object),
640                                                      line_color);
641                         gl_label_ellipse_set_fill_color (GL_LABEL_ELLIPSE(object),
642                                                      fill_color);
643                         view_ellipse = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object),
644                                                     view);
645                         x0 = x;
646                         y0 = y;
647                         return TRUE;
648
649                 default:
650                         return FALSE;
651                 }
652
653         case GDK_BUTTON_RELEASE:
654                 switch (event->button.button) {
655                 case 1:
656                         dragging = FALSE;
657                         gdk_pointer_ungrab (event->button.time);
658                         gnome_canvas_window_to_world (canvas,
659                                                       event->button.x,
660                                                       event->button.y, &x, &y);
661                         if ((x0 == x) && (y0 == y)) {
662                                 x = x0 + 36.0;
663                                 y = y0 + 36.0;
664                         }
665                         gl_label_object_set_position (GL_LABEL_OBJECT(object),
666                                                      MIN (x, x0), MIN (y, y0));
667                         w = MAX (x, x0) - MIN (x, x0);
668                         h = MAX (y, y0) - MIN (y, y0);
669                         gl_label_object_set_size (GL_LABEL_OBJECT(object),
670                                                   w, h);
671                         line_color = DEFAULT_LINE_COLOR;
672                         fill_color = DEFAULT_FILL_COLOR;
673                         gl_label_ellipse_set_line_color (GL_LABEL_ELLIPSE(object),
674                                                      line_color);
675                         gl_label_ellipse_set_fill_color (GL_LABEL_ELLIPSE(object),
676                                                      fill_color);
677                         gl_view_unselect_all (view);
678                         gl_view_object_select (GL_VIEW_OBJECT(view_ellipse));
679                         gl_view_arrow_mode (view);
680                         return TRUE;
681
682                 default:
683                         return FALSE;
684                 }
685
686         case GDK_MOTION_NOTIFY:
687                 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
688                         gnome_canvas_window_to_world (canvas,
689                                                       event->button.x,
690                                                       event->button.y, &x, &y);
691                         gl_label_object_set_position (GL_LABEL_OBJECT(object),
692                                                      MIN (x, x0), MIN (y, y0));
693                         w = MAX (x, x0) - MIN (x, x0);
694                         h = MAX (y, y0) - MIN (y, y0);
695                         gl_label_object_set_size (GL_LABEL_OBJECT(object),
696                                                   w, h);
697                         return TRUE;
698                 } else {
699                         return FALSE;
700                 }
701
702         default:
703                 return FALSE;
704         }
705
706 }