]> git.sur5r.net Git - glabels/blob - glabels2/src/view-box.c
d45729adf26837e400d8bc69d2fec97ec3a07ca1
[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         /* Adjust highlight */
258         gl_view_object_update_highlight (GL_VIEW_OBJECT(view_box));
259
260         gl_debug (DEBUG_VIEW, "END");
261 }
262
263 /*****************************************************************************/
264 /* Create a properties dialog for a box object.                              */
265 /*****************************************************************************/
266 static GtkWidget *
267 construct_properties_dialog (glViewBox *view_box)
268 {
269         GtkWidget          *dialog, *wsection;
270         glLabelObject      *object;
271         gdouble            line_width;
272         guint              line_color, fill_color;
273         gdouble            x, y, w, h, label_width, label_height;
274         GtkSizeGroup       *label_size_group;
275         GtkWidget          *window;
276
277         gl_debug (DEBUG_VIEW, "START");
278
279         /* retrieve object and query parameters */
280         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_box));
281         gl_label_object_get_position (GL_LABEL_OBJECT(object), &x, &y);
282         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
283         line_width = gl_label_box_get_line_width(GL_LABEL_BOX(object));
284         line_color = gl_label_box_get_line_color(GL_LABEL_BOX(object));
285         fill_color = gl_label_box_get_fill_color(GL_LABEL_BOX(object));
286         gl_label_get_size (GL_LABEL(object->parent),
287                            &label_width, &label_height);
288
289         /*-----------------------------------------------------------------*/
290         /* Build dialog with notebook.                                     */
291         /*-----------------------------------------------------------------*/
292         window = gtk_widget_get_toplevel (
293                 GTK_WIDGET(gl_view_object_get_view(GL_VIEW_OBJECT(view_box))));
294         dialog = gl_hig_dialog_new_with_buttons ( _("Edit box object properties"),
295                                                   GTK_WINDOW (window),
296                                                   GTK_DIALOG_DESTROY_WITH_PARENT,
297                                                   GTK_STOCK_CLOSE,
298                                                            GTK_RESPONSE_CLOSE,
299                                                   NULL );
300         gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
301         g_signal_connect (G_OBJECT (dialog), "response",
302                           G_CALLBACK (response_cb), view_box);
303
304         label_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
305
306
307         /*---------------------------*/
308         /* Outline section           */
309         /*---------------------------*/
310         wsection = gl_hig_category_new (_("Outline"));
311         gl_hig_dialog_add_widget (GL_HIG_DIALOG(dialog), wsection);
312         view_box->private->line = gl_wdgt_line_new ();
313         gl_wdgt_line_set_label_size_group (GL_WDGT_LINE(view_box->private->line),
314                                            label_size_group);
315         gl_wdgt_line_set_params (GL_WDGT_LINE (view_box->private->line),
316                                  line_width,
317                                  line_color);
318         gl_hig_category_add_widget (GL_HIG_CATEGORY(wsection),
319                                     view_box->private->line);
320         g_signal_connect (G_OBJECT (view_box->private->line), "changed",
321                           G_CALLBACK(line_changed_cb), view_box);
322
323         /*---------------------------*/
324         /* Fill section              */
325         /*---------------------------*/
326         wsection = gl_hig_category_new (_("Fill"));
327         gl_hig_dialog_add_widget (GL_HIG_DIALOG(dialog), wsection);
328         view_box->private->fill = gl_wdgt_fill_new ();
329         gl_wdgt_fill_set_label_size_group (GL_WDGT_FILL(view_box->private->fill),
330                                            label_size_group);
331         gl_wdgt_fill_set_params (GL_WDGT_FILL (view_box->private->fill),
332                                  fill_color);
333         gl_hig_category_add_widget (GL_HIG_CATEGORY(wsection),
334                                     view_box->private->fill);
335         g_signal_connect (G_OBJECT (view_box->private->fill), "changed",
336                           G_CALLBACK(fill_changed_cb), view_box);
337
338
339         /*---------------------------*/
340         /* Position section          */
341         /*---------------------------*/
342         wsection = gl_hig_category_new (_("Position"));
343         gl_hig_dialog_add_widget (GL_HIG_DIALOG(dialog), wsection);
344         view_box->private->position = gl_wdgt_position_new ();
345         gl_wdgt_position_set_label_size_group (GL_WDGT_POSITION(view_box->private->position),
346                                                label_size_group);
347         gl_wdgt_position_set_params (GL_WDGT_POSITION (view_box->private->position),
348                                      x, y, label_width, label_height);
349         gl_hig_category_add_widget (GL_HIG_CATEGORY(wsection),
350                                     view_box->private->position);
351         g_signal_connect (G_OBJECT (view_box->private->position), "changed",
352                           G_CALLBACK(position_changed_cb), view_box);
353
354         /*---------------------------*/
355         /* Size section              */
356         /*---------------------------*/
357         wsection = gl_hig_category_new (_("Size"));
358         gl_hig_dialog_add_widget (GL_HIG_DIALOG(dialog), wsection);
359         view_box->private->size = gl_wdgt_size_new ();
360         gl_wdgt_size_set_label_size_group (GL_WDGT_SIZE(view_box->private->size),
361                                            label_size_group);
362         gl_wdgt_size_set_params (GL_WDGT_SIZE (view_box->private->size),
363                                  w, h, TRUE, label_width, label_height);
364         gl_hig_category_add_widget (GL_HIG_CATEGORY(wsection),
365                                     view_box->private->size);
366         g_signal_connect (G_OBJECT (view_box->private->size), "changed",
367                           G_CALLBACK(size_changed_cb), view_box);
368
369
370         /*----------------------------*/
371         /* Track object changes.      */
372         /*----------------------------*/
373         g_signal_connect (G_OBJECT (object), "changed",
374                           G_CALLBACK (update_dialog_cb), view_box);
375         g_signal_connect (G_OBJECT (object), "moved",
376                           G_CALLBACK (update_dialog_from_move_cb), view_box);
377
378         gl_debug (DEBUG_VIEW, "END");
379
380         return dialog;
381 }
382
383 /*---------------------------------------------------------------------------*/
384 /* PRIVATE.  "Response" callback.                                            */
385 /*---------------------------------------------------------------------------*/
386 static void
387 response_cb (GtkDialog *dialog,
388              gint      response,
389              glViewBox *view_box)
390 {
391         gl_debug (DEBUG_VIEW, "START");
392
393         g_return_if_fail(dialog != NULL);
394         g_return_if_fail(GTK_IS_DIALOG(dialog));
395
396         switch(response) {
397         case GTK_RESPONSE_CLOSE:
398                 gtk_widget_hide (GTK_WIDGET(dialog));
399                 break;
400         case GTK_RESPONSE_DELETE_EVENT:
401                 break;
402         default:
403                 g_print ("response = %d", response);
404                 g_assert_not_reached ();
405         }
406
407         gl_debug (DEBUG_VIEW, "END");
408 }
409
410 /*---------------------------------------------------------------------------*/
411 /* PRIVATE.  line properties "changed" callback.                             */
412 /*---------------------------------------------------------------------------*/
413 static void
414 line_changed_cb (glWdgtLine *line,
415                  glViewBox  *view_box)
416 {
417         glLabelObject      *object;
418         gdouble            line_width;
419         guint              line_color;
420
421         gl_debug (DEBUG_VIEW, "START");
422
423         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_box));
424
425         gl_wdgt_line_get_params (GL_WDGT_LINE (line),
426                                  &line_width,
427                                  &line_color);
428
429         g_signal_handlers_block_by_func (G_OBJECT(object),
430                                          update_dialog_cb, view_box);
431         gl_label_box_set_line_width(GL_LABEL_BOX(object), line_width);
432         gl_label_box_set_line_color(GL_LABEL_BOX(object), line_color);
433         g_signal_handlers_unblock_by_func (G_OBJECT(object),
434                                            update_dialog_cb, view_box);
435
436         gl_debug (DEBUG_VIEW, "END");
437 }
438
439 /*---------------------------------------------------------------------------*/
440 /* PRIVATE.  fill properties "changed" callback.                             */
441 /*---------------------------------------------------------------------------*/
442 static void
443 fill_changed_cb (glWdgtFill *fill,
444                  glViewBox  *view_box)
445 {
446         glLabelObject    *object;
447         guint            fill_color;
448
449         gl_debug (DEBUG_VIEW, "START");
450
451         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_box));
452
453         gl_wdgt_fill_get_params (GL_WDGT_FILL (fill),
454                                  &fill_color);
455
456         g_signal_handlers_block_by_func (G_OBJECT(object),
457                                          update_dialog_cb, view_box);
458         gl_label_box_set_fill_color(GL_LABEL_BOX(object), fill_color);
459         g_signal_handlers_unblock_by_func (G_OBJECT(object),
460                                            update_dialog_cb, view_box);
461
462         gl_debug (DEBUG_VIEW, "END");
463 }
464
465 /*---------------------------------------------------------------------------*/
466 /* PRIVATE.  position "changed" callback.                                    */
467 /*---------------------------------------------------------------------------*/
468 static void
469 position_changed_cb (glWdgtPosition *position,
470                      glViewBox      *view_box)
471 {
472         glLabelObject      *object;
473         gdouble            x, y;
474
475         gl_debug (DEBUG_VIEW, "START");
476
477         gl_wdgt_position_get_position (GL_WDGT_POSITION (position), &x, &y);
478
479         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_box));
480
481         g_signal_handlers_block_by_func (G_OBJECT(object),
482                                          update_dialog_cb, view_box);
483         gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
484         g_signal_handlers_unblock_by_func (G_OBJECT(object),
485                                            update_dialog_cb, view_box);
486
487         gl_debug (DEBUG_VIEW, "END");
488 }
489
490 /*---------------------------------------------------------------------------*/
491 /* PRIVATE.  size "changed" callback.                                        */
492 /*---------------------------------------------------------------------------*/
493 static void
494 size_changed_cb (glWdgtSize *size,
495                  glViewBox  *view_box)
496 {
497         glLabelObject *object;
498         gdouble       w, h;
499         gboolean      keep_aspect_ratio_flag;
500
501         gl_debug (DEBUG_VIEW, "START");
502
503         gl_wdgt_size_get_size (GL_WDGT_SIZE (size),
504                                &w, &h, &keep_aspect_ratio_flag);
505
506         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_box));
507
508         g_signal_handlers_block_by_func (G_OBJECT(object),
509                                          update_dialog_cb, view_box);
510         gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
511         g_signal_handlers_unblock_by_func (G_OBJECT(object),
512                                            update_dialog_cb, view_box);
513
514         gl_debug (DEBUG_VIEW, "END");
515 }
516
517 /*---------------------------------------------------------------------------*/
518 /* PRIVATE. label object "changed" callback.                                 */
519 /*---------------------------------------------------------------------------*/
520 static void
521 update_dialog_cb (glLabelObject *object,
522                   glViewBox     *view_box)
523 {
524         gdouble            line_width;
525         guint              line_color, fill_color;
526         gdouble            x, y, w, h;
527
528         gl_debug (DEBUG_VIEW, "START");
529
530         /* Query properties of object. */
531         gl_label_object_get_position (GL_LABEL_OBJECT(object), &x, &y);
532         gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
533         line_width = gl_label_box_get_line_width(GL_LABEL_BOX(object));
534         line_color = gl_label_box_get_line_color(GL_LABEL_BOX(object));
535         fill_color = gl_label_box_get_fill_color(GL_LABEL_BOX(object));
536
537         /* Block widget handlers to prevent recursion */
538         g_signal_handlers_block_by_func (G_OBJECT(view_box->private->line),
539                                          line_changed_cb, view_box);
540         g_signal_handlers_block_by_func (G_OBJECT(view_box->private->fill),
541                                          fill_changed_cb, view_box);
542         g_signal_handlers_block_by_func (G_OBJECT(view_box->private->position),
543                                          position_changed_cb, view_box);
544         g_signal_handlers_block_by_func (G_OBJECT(view_box->private->size),
545                                          size_changed_cb, view_box);
546
547         /* Update widgets in property dialog */
548         gl_wdgt_line_set_params (GL_WDGT_LINE (view_box->private->line),
549                                  line_width,
550                                  line_color);
551         gl_wdgt_fill_set_params (GL_WDGT_FILL (view_box->private->fill),
552                                  fill_color);
553         gl_wdgt_position_set_position (GL_WDGT_POSITION(view_box->private->position),
554                                        x, y);
555         gl_wdgt_size_set_size (GL_WDGT_SIZE(view_box->private->size), w, h);
556
557         /* Unblock widget handlers */
558         g_signal_handlers_unblock_by_func (G_OBJECT(view_box->private->line),
559                                            line_changed_cb, view_box);
560         g_signal_handlers_unblock_by_func (G_OBJECT(view_box->private->fill),
561                                            fill_changed_cb, view_box);
562         g_signal_handlers_unblock_by_func (G_OBJECT(view_box->private->position),
563                                            position_changed_cb, view_box);
564         g_signal_handlers_unblock_by_func (G_OBJECT(view_box->private->size),
565                                            size_changed_cb, view_box);
566
567
568         gl_debug (DEBUG_VIEW, "END");
569 }
570
571 /*---------------------------------------------------------------------------*/
572 /* PRIVATE. label object "moved" callback.                                   */
573 /*---------------------------------------------------------------------------*/
574 static void
575 update_dialog_from_move_cb (glLabelObject *object,
576                             gdouble        dx,
577                             gdouble        dy,
578                             glViewBox     *view_box)
579 {
580         gdouble            x, y;
581
582         gl_debug (DEBUG_VIEW, "START");
583
584         /* Query properties of object. */
585         gl_label_object_get_position (GL_LABEL_OBJECT(object), &x, &y);
586
587         /* Block widget handlers to prevent recursion */
588         g_signal_handlers_block_by_func (G_OBJECT(view_box->private->position),
589                                          position_changed_cb, view_box);
590
591         /* Update widgets in property dialog */
592         gl_wdgt_position_set_position (GL_WDGT_POSITION(view_box->private->position),
593                                        x, y);
594
595         /* Unblock widget handlers */
596         g_signal_handlers_unblock_by_func (G_OBJECT(view_box->private->position),
597                                            position_changed_cb, view_box);
598
599         gl_debug (DEBUG_VIEW, "END");
600 }
601
602 /*****************************************************************************/
603 /* Return apropos cursor for create object mode.                             */
604 /*****************************************************************************/
605 GdkCursor *
606 gl_view_box_get_create_cursor (void)
607 {
608         static GdkCursor *cursor = NULL;
609         GdkPixmap        *pixmap_data, *pixmap_mask;
610         GdkColor         fg = { 0, 0, 0, 0 };
611         GdkColor         bg = { 0, 65535, 65535, 65535 };
612
613         gl_debug (DEBUG_VIEW, "START");
614
615         if (!cursor) {
616                 pixmap_data = gdk_bitmap_create_from_data (NULL,
617                                                            cursor_box_bits,
618                                                            cursor_box_width,
619                                                            cursor_box_height);
620                 pixmap_mask = gdk_bitmap_create_from_data (NULL,
621                                                            cursor_box_mask_bits,
622                                                            cursor_box_mask_width,
623                                                            cursor_box_mask_height);
624                 cursor =
625                     gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
626                                                 &bg, cursor_box_x_hot,
627                                                 cursor_box_y_hot);
628         }
629
630         gl_debug (DEBUG_VIEW, "END");
631
632         return cursor;
633 }
634
635 /*****************************************************************************/
636 /* Canvas event handler for creating box objects.                            */
637 /*****************************************************************************/
638 int
639 gl_view_box_create_event_handler (GnomeCanvas *canvas,
640                                   GdkEvent    *event,
641                                   glView      *view)
642 {
643         static gdouble      x0, y0;
644         static gboolean     dragging = FALSE;
645         static glViewObject *view_box;
646         static GObject      *object;
647         guint               line_color, fill_color;
648         gdouble             x, y, w, h;
649
650         gl_debug (DEBUG_VIEW, "");
651
652         switch (event->type) {
653
654         case GDK_BUTTON_PRESS:
655                 switch (event->button.button) {
656                 case 1:
657                         dragging = TRUE;
658                         gdk_pointer_grab (GTK_WIDGET (view->canvas)->window,
659                                           FALSE,
660                                           GDK_POINTER_MOTION_MASK |
661                                           GDK_BUTTON_RELEASE_MASK |
662                                           GDK_BUTTON_PRESS_MASK,
663                                           NULL, NULL, event->button.time);
664                         gnome_canvas_window_to_world (canvas,
665                                                       event->button.x,
666                                                       event->button.y, &x, &y);
667                         object = gl_label_box_new (view->label);
668                         gl_label_object_set_position (GL_LABEL_OBJECT(object),
669                                                      x, y);
670                         gl_label_object_set_size (GL_LABEL_OBJECT(object),
671                                                   0.0, 0.0);
672                         line_color = gl_color_set_opacity (gl_prefs->default_line_color, 0.5);
673                         fill_color = gl_color_set_opacity (gl_prefs->default_fill_color, 0.5);
674                         gl_label_box_set_line_width (GL_LABEL_BOX(object),
675                                                      gl_prefs->default_line_width);
676                         gl_label_box_set_line_color (GL_LABEL_BOX(object),
677                                                      line_color);
678                         gl_label_box_set_fill_color (GL_LABEL_BOX(object),
679                                                      fill_color);
680                         view_box = gl_view_box_new (GL_LABEL_BOX(object),
681                                                     view);
682                         x0 = x;
683                         y0 = y;
684                         return TRUE;
685
686                 default:
687                         return FALSE;
688                 }
689
690         case GDK_BUTTON_RELEASE:
691                 switch (event->button.button) {
692                 case 1:
693                         dragging = FALSE;
694                         gdk_pointer_ungrab (event->button.time);
695                         gnome_canvas_window_to_world (canvas,
696                                                       event->button.x,
697                                                       event->button.y, &x, &y);
698                         if ((x0 == x) && (y0 == y)) {
699                                 x = x0 + 36.0;
700                                 y = y0 + 36.0;
701                         }
702                         gl_label_object_set_position (GL_LABEL_OBJECT(object),
703                                                      MIN (x, x0), MIN (y, y0));
704                         w = MAX (x, x0) - MIN (x, x0);
705                         h = MAX (y, y0) - MIN (y, y0);
706                         gl_label_object_set_size (GL_LABEL_OBJECT(object),
707                                                   w, h);
708                         gl_label_box_set_line_color (GL_LABEL_BOX(object),
709                                                      gl_prefs->default_line_color);
710                         gl_label_box_set_fill_color (GL_LABEL_BOX(object),
711                                                      gl_prefs->default_fill_color);
712                         gl_view_unselect_all (view);
713                         gl_view_object_select (GL_VIEW_OBJECT(view_box));
714                         gl_view_arrow_mode (view);
715                         return TRUE;
716
717                 default:
718                         return FALSE;
719                 }
720
721         case GDK_MOTION_NOTIFY:
722                 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
723                         gnome_canvas_window_to_world (canvas,
724                                                       event->motion.x,
725                                                       event->motion.y, &x, &y);
726                         gl_label_object_set_position (GL_LABEL_OBJECT(object),
727                                                      MIN (x, x0), MIN (y, y0));
728                         w = MAX (x, x0) - MIN (x, x0);
729                         h = MAX (y, y0) - MIN (y, y0);
730                         gl_label_object_set_size (GL_LABEL_OBJECT(object),
731                                                   w, h);
732                         return TRUE;
733                 } else {
734                         return FALSE;
735                 }
736
737         default:
738                 return FALSE;
739         }
740
741 }