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