]> git.sur5r.net Git - glabels/blob - glabels2/src/view-box.c
Initial revision
[glabels] / glabels2 / src / view-box.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  view_box.c:  GLabels label box 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-box.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_box.xbm"
36 #include "pixmaps/cursor_box_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 _glViewBoxPrivate {
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_box_class_init       (glViewBoxClass *klass);
79 static void      gl_view_box_instance_init    (glViewBox *view_box);
80 static void      gl_view_box_finalize         (GObject *object);
81
82 static void      update_view_box_cb           (glLabelObject *object,
83                                                glViewBox *view_box);
84
85 static GtkWidget *construct_properties_dialog (glViewBox *view_box);
86
87 static void      response_cb                  (GtkDialog *dialog,
88                                                gint response,
89                                                glViewBox *view_box);
90
91 static void      line_changed_cb              (glWdgtLine *line,
92                                                glViewBox *view_box);
93
94 static void      fill_changed_cb              (glWdgtFill *fill,
95                                                glViewBox *view_box);
96
97 static void      position_changed_cb          (glWdgtPosition *position,
98                                                glViewBox *view_box);
99
100 static void      size_changed_cb              (glWdgtSize *size,
101                                                glViewBox *view_box);
102
103 static void      update_dialog_cb             (glLabelObject *object,
104                                                glViewBox *view_box);
105
106 \f
107 /*****************************************************************************/
108 /* Boilerplate object stuff.                                                 */
109 /*****************************************************************************/
110 GType
111 gl_view_box_get_type (void)
112 {
113         static GType type = 0;
114
115         if (!type) {
116                 GTypeInfo info = {
117                         sizeof (glViewBoxClass),
118                         NULL,
119                         NULL,
120                         (GClassInitFunc) gl_view_box_class_init,
121                         NULL,
122                         NULL,
123                         sizeof (glViewBox),
124                         0,
125                         (GInstanceInitFunc) gl_view_box_instance_init,
126                 };
127
128                 type = g_type_register_static (GL_TYPE_VIEW_OBJECT,
129                                                "glViewBox", &info, 0);
130         }
131
132         return type;
133 }
134
135 static void
136 gl_view_box_class_init (glViewBoxClass *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_box_finalize;
145
146         gl_debug (DEBUG_VIEW, "END");
147 }
148
149 static void
150 gl_view_box_instance_init (glViewBox *view_box)
151 {
152         gl_debug (DEBUG_VIEW, "START");
153
154         view_box->private = g_new0 (glViewBoxPrivate, 1);
155
156         gl_debug (DEBUG_VIEW, "END");
157 }
158
159 static void
160 gl_view_box_finalize (GObject *object)
161 {
162         glLabel       *parent;
163
164         gl_debug (DEBUG_VIEW, "START");
165
166         g_return_if_fail (object && GL_IS_VIEW_BOX (object));
167
168         G_OBJECT_CLASS (parent_class)->finalize (object);
169
170         gl_debug (DEBUG_VIEW, "END");
171 }
172
173 /*****************************************************************************/
174 /* NEW box object view.                                                      */
175 /*****************************************************************************/
176 glViewObject *
177 gl_view_box_new (glLabelBox *object,
178                  glView     *view)
179 {
180         glViewBox          *view_box;
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_BOX (object));
190         g_return_if_fail (view && GL_IS_VIEW (view));
191         
192         view_box = g_object_new (gl_view_box_get_type(), NULL);
193
194         gl_view_object_set_view (GL_VIEW_OBJECT(view_box), view);
195         gl_view_object_set_object (GL_VIEW_OBJECT(view_box),
196                                    GL_LABEL_OBJECT(object),
197                                    GL_VIEW_HIGHLIGHT_BOX_RESIZABLE);
198
199         /* Query properties of object. */
200         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
201         line_width = gl_label_box_get_line_width(object);
202         line_color = gl_label_box_get_line_color(object);
203         fill_color = gl_label_box_get_fill_color(object);
204
205         /* Create analogous canvas item. */
206         group = gl_view_object_get_group (GL_VIEW_OBJECT(view_box));
207         view_box->private->item =
208                 gnome_canvas_item_new (GNOME_CANVAS_GROUP(group),
209                                        gnome_canvas_rect_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_box_cb), view_box);
221
222         /* Create a dialog for controlling/viewing object properties. */
223         dialog = construct_properties_dialog (view_box);
224         gl_view_object_set_dialog     (GL_VIEW_OBJECT(view_box), dialog);
225
226         gl_debug (DEBUG_VIEW, "END");
227
228         return GL_VIEW_OBJECT (view_box);
229 }
230
231 /*---------------------------------------------------------------------------*/
232 /* PRIVATE. label object "changed" callback.                                 */
233 /*---------------------------------------------------------------------------*/
234 static void
235 update_view_box_cb (glLabelObject *object,
236                     glViewBox     *view_box)
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_box_get_line_width(GL_LABEL_BOX(object));
247         line_color = gl_label_box_get_line_color(GL_LABEL_BOX(object));
248         fill_color = gl_label_box_get_fill_color(GL_LABEL_BOX(object));
249
250         /* Adjust appearance of analogous canvas item. */
251         gnome_canvas_item_set (view_box->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_box));
261
262         gl_debug (DEBUG_VIEW, "END");
263 }
264
265 /*****************************************************************************/
266 /* Create a properties dialog for a box object.                              */
267 /*****************************************************************************/
268 static GtkWidget *
269 construct_properties_dialog (glViewBox *view_box)
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_box));
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_box_get_line_width(GL_LABEL_BOX(object));
285         line_color = gl_label_box_get_line_color(GL_LABEL_BOX(object));
286         fill_color = gl_label_box_get_fill_color(GL_LABEL_BOX(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 box 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_box);
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 box ------ */
315         view_box->private->line = gl_wdgt_line_new (_("Outline"));
316         gl_wdgt_line_set_params (GL_WDGT_LINE (view_box->private->line),
317                                  line_width,
318                                  line_color);
319         gtk_box_pack_start (GTK_BOX (wvbox), view_box->private->line,
320                             FALSE, FALSE, 0);
321         g_signal_connect (G_OBJECT (view_box->private->line), "changed",
322                           G_CALLBACK(line_changed_cb), view_box);
323
324         /* ------ Fill box ------ */
325         view_box->private->fill = gl_wdgt_fill_new (_("Fill"));
326         gl_wdgt_fill_set_params (GL_WDGT_FILL (view_box->private->fill),
327                                  fill_color);
328         gtk_box_pack_start (GTK_BOX (wvbox), view_box->private->fill,
329                             FALSE, FALSE, 0);
330         g_signal_connect (G_OBJECT (view_box->private->fill), "changed",
331                           G_CALLBACK(fill_changed_cb), view_box);
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_box->private->position = gl_wdgt_position_new (_("Position"));
344         gl_wdgt_position_set_params (GL_WDGT_POSITION (view_box->private->position),
345                                      x, y,
346                                      label_width, label_height);
347         gtk_box_pack_start (GTK_BOX (wvbox), view_box->private->position,
348                             FALSE, FALSE, 0);
349         g_signal_connect (G_OBJECT (view_box->private->position), "changed",
350                           G_CALLBACK(position_changed_cb), view_box);
351
352
353         /* ------ Size Frame ------ */
354         view_box->private->size = gl_wdgt_size_new (_("Size"));
355         gl_wdgt_size_set_params (GL_WDGT_SIZE (view_box->private->size),
356                                  w, h,
357                                  TRUE,
358                                  label_width, label_height);
359         gtk_box_pack_start (GTK_BOX (wvbox), view_box->private->size,
360                             FALSE, FALSE, 0);
361         g_signal_connect (G_OBJECT (view_box->private->size), "changed",
362                           G_CALLBACK(size_changed_cb), view_box);
363
364
365         /*----------------------------*/
366         /* Track object changes.      */
367         /*----------------------------*/
368         g_signal_connect (G_OBJECT (object), "changed",
369                           G_CALLBACK (update_dialog_cb), view_box);
370
371         gl_debug (DEBUG_VIEW, "END");
372
373         return dialog;
374 }
375
376 /*---------------------------------------------------------------------------*/
377 /* PRIVATE.  "Response" callback.                                            */
378 /*---------------------------------------------------------------------------*/
379 static void
380 response_cb (GtkDialog *dialog,
381              gint      response,
382              glViewBox *view_box)
383 {
384         gl_debug (DEBUG_VIEW, "START");
385
386         g_return_if_fail(dialog != NULL);
387         g_return_if_fail(GTK_IS_DIALOG(dialog));
388
389         switch(response) {
390         case GTK_RESPONSE_CLOSE:
391                 gtk_widget_hide (GTK_WIDGET(dialog));
392                 break;
393         default:
394                 g_assert_not_reached();
395         }
396
397         gl_debug (DEBUG_VIEW, "END");
398 }
399
400 /*---------------------------------------------------------------------------*/
401 /* PRIVATE.  line properties "changed" callback.                             */
402 /*---------------------------------------------------------------------------*/
403 static void
404 line_changed_cb (glWdgtLine *line,
405                  glViewBox  *view_box)
406 {
407         glLabelObject      *object;
408         gdouble            line_width;
409         guint              line_color;
410
411         gl_debug (DEBUG_VIEW, "START");
412
413         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_box));
414
415         gl_wdgt_line_get_params (GL_WDGT_LINE (line),
416                                  &line_width,
417                                  &line_color);
418
419         g_signal_handlers_block_by_func (G_OBJECT(object),
420                                          update_dialog_cb, view_box);
421         gl_label_box_set_line_width(GL_LABEL_BOX(object), line_width);
422         gl_label_box_set_line_color(GL_LABEL_BOX(object), line_color);
423         g_signal_handlers_unblock_by_func (G_OBJECT(object),
424                                            update_dialog_cb, view_box);
425
426         gl_debug (DEBUG_VIEW, "END");
427 }
428
429 /*---------------------------------------------------------------------------*/
430 /* PRIVATE.  fill properties "changed" callback.                             */
431 /*---------------------------------------------------------------------------*/
432 static void
433 fill_changed_cb (glWdgtFill *fill,
434                  glViewBox  *view_box)
435 {
436         glLabelObject    *object;
437         guint            fill_color;
438
439         gl_debug (DEBUG_VIEW, "START");
440
441         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_box));
442
443         gl_wdgt_fill_get_params (GL_WDGT_FILL (fill),
444                                  &fill_color);
445
446         g_signal_handlers_block_by_func (G_OBJECT(object),
447                                          update_dialog_cb, view_box);
448         gl_label_box_set_fill_color(GL_LABEL_BOX(object), fill_color);
449         g_signal_handlers_unblock_by_func (G_OBJECT(object),
450                                            update_dialog_cb, view_box);
451
452         gl_debug (DEBUG_VIEW, "END");
453 }
454
455 /*---------------------------------------------------------------------------*/
456 /* PRIVATE.  position "changed" callback.                                    */
457 /*---------------------------------------------------------------------------*/
458 static void
459 position_changed_cb (glWdgtPosition *position,
460                      glViewBox      *view_box)
461 {
462         glLabelObject      *object;
463         gdouble            x, y;
464
465         gl_debug (DEBUG_VIEW, "START");
466
467         gl_wdgt_position_get_position (GL_WDGT_POSITION (position), &x, &y);
468
469         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_box));
470
471         g_signal_handlers_block_by_func (G_OBJECT(object),
472                                          update_dialog_cb, view_box);
473         gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
474         g_signal_handlers_unblock_by_func (G_OBJECT(object),
475                                            update_dialog_cb, view_box);
476
477         gl_debug (DEBUG_VIEW, "END");
478 }
479
480 /*---------------------------------------------------------------------------*/
481 /* PRIVATE.  size "changed" callback.                                        */
482 /*---------------------------------------------------------------------------*/
483 static void
484 size_changed_cb (glWdgtSize *size,
485                  glViewBox  *view_box)
486 {
487         glLabelObject *object;
488         gdouble       w, h;
489         gboolean      keep_aspect_ratio_flag;
490
491         gl_debug (DEBUG_VIEW, "START");
492
493         gl_wdgt_size_get_size (GL_WDGT_SIZE (size),
494                                &w, &h, &keep_aspect_ratio_flag);
495
496         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_box));
497
498         g_signal_handlers_block_by_func (G_OBJECT(object),
499                                          update_dialog_cb, view_box);
500         gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
501         g_signal_handlers_unblock_by_func (G_OBJECT(object),
502                                            update_dialog_cb, view_box);
503
504         gl_debug (DEBUG_VIEW, "END");
505 }
506
507 /*---------------------------------------------------------------------------*/
508 /* PRIVATE. label object "changed" callback.                                 */
509 /*---------------------------------------------------------------------------*/
510 static void
511 update_dialog_cb (glLabelObject *object,
512                   glViewBox     *view_box)
513 {
514         gdouble            line_width;
515         guint              line_color, fill_color;
516         gdouble            x, y, w, h;
517
518         gl_debug (DEBUG_VIEW, "START");
519
520         /* Query properties of object. */
521         gl_label_object_get_position (GL_LABEL_OBJECT(object), &x, &y);
522         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
523         line_width = gl_label_box_get_line_width(GL_LABEL_BOX(object));
524         line_color = gl_label_box_get_line_color(GL_LABEL_BOX(object));
525         fill_color = gl_label_box_get_fill_color(GL_LABEL_BOX(object));
526
527         /* Block widget handlers to prevent recursion */
528         g_signal_handlers_block_by_func (G_OBJECT(view_box->private->line),
529                                          line_changed_cb, view_box);
530         g_signal_handlers_block_by_func (G_OBJECT(view_box->private->fill),
531                                          fill_changed_cb, view_box);
532         g_signal_handlers_block_by_func (G_OBJECT(view_box->private->position),
533                                          position_changed_cb, view_box);
534         g_signal_handlers_block_by_func (G_OBJECT(view_box->private->size),
535                                          size_changed_cb, view_box);
536
537         /* Update widgets in property dialog */
538         gl_wdgt_line_set_params (GL_WDGT_LINE (view_box->private->line),
539                                  line_width,
540                                  line_color);
541         gl_wdgt_fill_set_params (GL_WDGT_FILL (view_box->private->fill),
542                                  fill_color);
543         gl_wdgt_position_set_position (GL_WDGT_POSITION(view_box->private->position),
544                                        x, y);
545         gl_wdgt_size_set_size (GL_WDGT_SIZE(view_box->private->size), w, h);
546
547         /* Unblock widget handlers */
548         g_signal_handlers_unblock_by_func (G_OBJECT(view_box->private->line),
549                                            line_changed_cb, view_box);
550         g_signal_handlers_unblock_by_func (G_OBJECT(view_box->private->fill),
551                                            fill_changed_cb, view_box);
552         g_signal_handlers_unblock_by_func (G_OBJECT(view_box->private->position),
553                                            position_changed_cb, view_box);
554         g_signal_handlers_unblock_by_func (G_OBJECT(view_box->private->size),
555                                            size_changed_cb, view_box);
556
557
558         gl_debug (DEBUG_VIEW, "END");
559 }
560
561 /*****************************************************************************/
562 /* Return apropos cursor for create object mode.                             */
563 /*****************************************************************************/
564 GdkCursor *
565 gl_view_box_get_create_cursor (void)
566 {
567         static GdkCursor *cursor = NULL;
568         GdkPixmap        *pixmap_data, *pixmap_mask;
569         GdkColor         fg = { 0, 0, 0, 0 };
570         GdkColor         bg = { 0, 65535, 65535, 65535 };
571
572         gl_debug (DEBUG_VIEW, "START");
573
574         if (!cursor) {
575                 pixmap_data = gdk_bitmap_create_from_data (NULL,
576                                                            cursor_box_bits,
577                                                            cursor_box_width,
578                                                            cursor_box_height);
579                 pixmap_mask = gdk_bitmap_create_from_data (NULL,
580                                                            cursor_box_mask_bits,
581                                                            cursor_box_mask_width,
582                                                            cursor_box_mask_height);
583                 cursor =
584                     gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
585                                                 &bg, cursor_box_x_hot,
586                                                 cursor_box_y_hot);
587         }
588
589         gl_debug (DEBUG_VIEW, "END");
590
591         return cursor;
592 }
593
594 /*****************************************************************************/
595 /* Canvas event handler for creating box objects.                            */
596 /*****************************************************************************/
597 int
598 gl_view_box_create_event_handler (GnomeCanvas *canvas,
599                                   GdkEvent    *event,
600                                   glView      *view)
601 {
602         static gdouble      x0, y0;
603         static gboolean     dragging = FALSE;
604         static glViewObject *view_box;
605         static GObject      *object;
606         gdouble             line_width;
607         guint               line_color, fill_color;
608         gdouble             x, y, w, h;
609
610         gl_debug (DEBUG_VIEW, "");
611
612         switch (event->type) {
613
614         case GDK_BUTTON_PRESS:
615                 switch (event->button.button) {
616                 case 1:
617                         dragging = TRUE;
618                         gdk_pointer_grab (GTK_WIDGET (view->canvas)->window,
619                                           FALSE,
620                                           GDK_POINTER_MOTION_MASK |
621                                           GDK_BUTTON_RELEASE_MASK |
622                                           GDK_BUTTON_PRESS_MASK,
623                                           NULL, NULL, event->button.time);
624                         gnome_canvas_window_to_world (canvas,
625                                                       event->button.x,
626                                                       event->button.y, &x, &y);
627                         gl_debug (DEBUG_VIEW, "BUTTON_PRESS (%f, %f) -> (%f, %f)", event->button.x, event->button.y, x, y);
628                         object = gl_label_box_new (view->label);
629                         gl_label_object_set_position (GL_LABEL_OBJECT(object),
630                                                      x, y);
631                         gl_label_object_set_size (GL_LABEL_OBJECT(object),
632                                                   0.0, 0.0);
633                         line_width = 1.0;
634                         line_color = CREATE_LINE_COLOR;
635                         fill_color = CREATE_FILL_COLOR;
636                         gl_label_box_set_line_width (GL_LABEL_BOX(object),
637                                                      line_width);
638                         gl_label_box_set_line_color (GL_LABEL_BOX(object),
639                                                      line_color);
640                         gl_label_box_set_fill_color (GL_LABEL_BOX(object),
641                                                      fill_color);
642                         view_box = gl_view_box_new (GL_LABEL_BOX(object),
643                                                     view);
644                         x0 = x;
645                         y0 = y;
646                         return TRUE;
647
648                 default:
649                         return FALSE;
650                 }
651
652         case GDK_BUTTON_RELEASE:
653                 switch (event->button.button) {
654                 case 1:
655                         dragging = FALSE;
656                         gdk_pointer_ungrab (event->button.time);
657                         gnome_canvas_window_to_world (canvas,
658                                                       event->button.x,
659                                                       event->button.y, &x, &y);
660                         gl_debug (DEBUG_VIEW, "BUTTON_RELEASE (%f, %f) -> (%f, %f)", event->button.x, 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_box_set_line_color (GL_LABEL_BOX(object),
674                                                      line_color);
675                         gl_label_box_set_fill_color (GL_LABEL_BOX(object),
676                                                      fill_color);
677                         gl_view_unselect_all (view);
678                         gl_view_object_select (GL_VIEW_OBJECT(view_box));
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                         gl_debug (DEBUG_VIEW, "BUTTON_MOTION (%f, %f) -> (%f, %f)", event->button.x, event->button.y, x, y);
694                         w = MAX (x, x0) - MIN (x, x0);
695                         h = MAX (y, y0) - MIN (y, y0);
696                         gl_label_object_set_size (GL_LABEL_OBJECT(object),
697                                                   w, h);
698                         return TRUE;
699                 } else {
700                         return FALSE;
701                 }
702
703         default:
704                 return FALSE;
705         }
706
707 }