]> git.sur5r.net Git - glabels/blob - glabels2/src/view-highlight.c
Initial revision
[glabels] / glabels2 / src / view-highlight.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  view_highlight.c:  GLabels Resizable Highlight module
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 <config.h>
24
25 #include <math.h>
26
27 #include "view-highlight.h"
28
29 #include "debug.h"
30
31 #define MIN_ITEM_SIZE 1.0
32 #define FG_COLOR GNOME_CANVAS_COLOR_A (0, 0, 255, 255)
33 #define BG_COLOR GNOME_CANVAS_COLOR_A (255, 255, 255, 255)
34
35 /*===========================================*/
36 /* Private data types                        */
37 /*===========================================*/
38
39 /*===========================================*/
40 /* Private globals                           */
41 /*===========================================*/
42
43 /*===========================================*/
44 /* Local function prototypes                 */
45 /*===========================================*/
46
47 static GnomeCanvasItem *highlight_resizable_box  (glViewObject *view_object,
48                                                   glViewHighlightStyle style);
49 static GnomeCanvasItem *highlight_resizable_line (glViewObject *view_object);
50 static GnomeCanvasItem *highlight_simple         (glViewObject *view_object);
51
52 static void update_resizable_box  (GnomeCanvasItem *highlight,
53                                    glViewHighlightStyle style);
54 static void update_resizable_line (GnomeCanvasItem *highlight);
55 static void update_simple         (GnomeCanvasItem *highlight);
56
57 static int tl_resize_event_handler (GnomeCanvasItem * handle_item,
58                                     GdkEvent * event,
59                                     glViewObject *view_object);
60 static int tr_resize_event_handler (GnomeCanvasItem * handle_item,
61                                     GdkEvent * event,
62                                     glViewObject *view_object);
63 static int bl_resize_event_handler (GnomeCanvasItem * handle_item,
64                                     GdkEvent * event,
65                                     glViewObject *view_object);
66 static int br_resize_event_handler (GnomeCanvasItem * handle_item,
67                                     GdkEvent * event,
68                                     glViewObject *view_object);
69
70 static int sl_resize_event_handler (GnomeCanvasItem * handle_item,
71                                     GdkEvent * event,
72                                     glViewObject *view_object);
73 static int sr_resize_event_handler (GnomeCanvasItem * handle_item,
74                                     GdkEvent * event,
75                                     glViewObject *view_object);
76 static int st_resize_event_handler (GnomeCanvasItem * handle_item,
77                                     GdkEvent * event,
78                                     glViewObject *view_object);
79 static int sb_resize_event_handler (GnomeCanvasItem * handle_item,
80                                     GdkEvent * event,
81                                     glViewObject *view_object);
82
83 static int p1_resize_event_handler (GnomeCanvasItem * handle_item,
84                                     GdkEvent * event,
85                                     glViewObject *view_object);
86 static int p2_resize_event_handler (GnomeCanvasItem * handle_item,
87                                     GdkEvent * event,
88                                     glViewObject *view_object);
89
90 static int passthrough_event_handler (GnomeCanvasItem * handle_item,
91                                       GdkEvent * event,
92                                       glViewObject *view_object);
93 \f
94 /*****************************************************************************/
95 /* Create a resizable highlight for given object.                            */
96 /*****************************************************************************/
97 GnomeCanvasItem *
98 gl_view_highlight_new (glViewObject *view_object,
99                        glViewHighlightStyle style)
100 {
101         GnomeCanvasItem *highlight;
102
103         gl_debug (DEBUG_VIEW, "START");
104
105         g_return_if_fail (view_object && GL_IS_VIEW_OBJECT(view_object));
106
107         switch (style) {
108
109         case GL_VIEW_HIGHLIGHT_BOX_RESIZABLE:
110         case GL_VIEW_HIGHLIGHT_ELLIPSE_RESIZABLE:
111                 highlight = highlight_resizable_box (view_object, style);
112                 break;
113
114         case GL_VIEW_HIGHLIGHT_LINE_RESIZABLE:
115                 highlight = highlight_resizable_line (view_object);
116                 break;
117
118         case GL_VIEW_HIGHLIGHT_SIMPLE:
119                 highlight = highlight_simple (view_object);
120                 break;
121
122         default:
123                 g_warning ("Invalid resizable highlight style");
124
125         }
126
127         g_object_set_data (G_OBJECT(highlight), "style",
128                            GINT_TO_POINTER(style));
129
130         gl_debug (DEBUG_VIEW, "END");
131
132         return highlight;
133 }
134
135 /*****************************************************************************/
136 /* Update a resizable highlight for given item.                              */
137 /*****************************************************************************/
138 void
139 gl_view_highlight_update (GnomeCanvasItem * highlight)
140 {
141         glViewHighlightStyle style;
142
143         gl_debug (DEBUG_VIEW, "START");
144
145         g_return_if_fail (GNOME_IS_CANVAS_ITEM (highlight));
146
147         style = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(highlight),
148                                                    "style"));
149
150         switch (style) {
151
152         case GL_VIEW_HIGHLIGHT_BOX_RESIZABLE:
153         case GL_VIEW_HIGHLIGHT_ELLIPSE_RESIZABLE:
154                 update_resizable_box (highlight, style);
155                 break;
156
157         case GL_VIEW_HIGHLIGHT_LINE_RESIZABLE:
158                 update_resizable_line (highlight);
159                 break;
160
161         case GL_VIEW_HIGHLIGHT_SIMPLE:
162                 update_simple (highlight);
163                 break;
164
165         default:
166                 g_warning ("Invalid resizable highlight style");
167
168         }
169
170         gl_debug (DEBUG_VIEW, "END");
171 }
172
173 /*---------------------------------------------------------------------------*/
174 /* PRIVATE.  Create a resizable box highlight.                               */
175 /*---------------------------------------------------------------------------*/
176 static GnomeCanvasItem *
177 highlight_resizable_box  (glViewObject *view_object,
178                           glViewHighlightStyle style)
179 {
180         GnomeCanvasItem *highlight;
181         glLabelObject *object;
182         glView *view;
183         gdouble x, y, w, h;
184         GnomeCanvasItem *outline;               /* Outline around item */
185         GnomeCanvasItem *tl, *tr, *bl, *br;     /* Handles at four corners */
186         GnomeCanvasItem *sl, *sr, *st, *sb;     /* Handles at each side */
187
188         gl_debug (DEBUG_VIEW, "START");
189
190         g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
191
192         object = gl_view_object_get_object (view_object);
193         gl_label_object_get_position (object, &x, &y);
194         gl_label_object_get_size (object, &w, &h);
195
196         view = gl_view_object_get_view (view_object);
197
198         highlight =
199                 gnome_canvas_item_new (gnome_canvas_root
200                                        (GNOME_CANVAS (view->canvas)),
201                                        gnome_canvas_group_get_type (),
202                                        "x", x, "y", y, NULL);
203
204         gnome_canvas_item_hide (highlight);
205
206         switch (style) {
207         case GL_VIEW_HIGHLIGHT_BOX_RESIZABLE:
208                 outline =
209                         gnome_canvas_item_new (GNOME_CANVAS_GROUP (highlight),
210                                                gnome_canvas_rect_get_type (),
211                                                "x1", -0.5,
212                                                "y1", -0.5,
213                                                "x2", w + 0.5,
214                                                "y2", h + 0.5,
215                                                "width_pixels", 2,
216                                                "outline_color_rgba", FG_COLOR,
217                                                NULL);
218                 break;
219         case GL_VIEW_HIGHLIGHT_ELLIPSE_RESIZABLE:
220                 outline =
221                         gnome_canvas_item_new (GNOME_CANVAS_GROUP (highlight),
222                                                gnome_canvas_ellipse_get_type (),
223                                                "x1", -0.5,
224                                                "y1", -0.5,
225                                                "x2", w + 0.5,
226                                                "y2", h + 0.5,
227                                                "width_pixels", 2,
228                                                "outline_color_rgba", FG_COLOR,
229                                                NULL);
230                 break;
231         default:
232                 outline = NULL;
233                 g_warning ("Invalid resizable highlight style");
234         }
235
236         tl = gnome_canvas_item_new (GNOME_CANVAS_GROUP (highlight),
237                                     gnome_canvas_rect_get_type (),
238                                     "x1", -1.0,
239                                     "y1", -1.0,
240                                     "x2", +1.0,
241                                     "y2", +1.0,
242                                     "fill_color_rgba", FG_COLOR,
243                                     "outline_color_rgba", BG_COLOR,
244                                     NULL);
245
246         tr = gnome_canvas_item_new (GNOME_CANVAS_GROUP (highlight),
247                                     gnome_canvas_rect_get_type (),
248                                     "x1", w - 1.0,
249                                     "y1", -1.0,
250                                     "x2", w + 1.0,
251                                     "y2", +1.0,
252                                     "fill_color_rgba", FG_COLOR,
253                                     "outline_color_rgba", BG_COLOR,
254                                     NULL);
255
256         bl = gnome_canvas_item_new (GNOME_CANVAS_GROUP (highlight),
257                                     gnome_canvas_rect_get_type (),
258                                     "x1", -1.0,
259                                     "y1", h - 1.0,
260                                     "x2", +1.0,
261                                     "y2", h + 1.0,
262                                     "fill_color_rgba", FG_COLOR,
263                                     "outline_color_rgba", BG_COLOR,
264                                     NULL);
265
266         br = gnome_canvas_item_new (GNOME_CANVAS_GROUP (highlight),
267                                     gnome_canvas_rect_get_type (),
268                                     "x1", w - 1.0,
269                                     "y1", h - 1.0,
270                                     "x2", w + 1.0,
271                                     "y2", h + 1.0,
272                                     "fill_color_rgba", FG_COLOR,
273                                     "outline_color_rgba", BG_COLOR,
274                                     NULL);
275
276         sl = gnome_canvas_item_new (GNOME_CANVAS_GROUP (highlight),
277                                     gnome_canvas_rect_get_type (),
278                                     "x1", -1.0,
279                                     "y1", h / 2.0 - 1.0,
280                                     "x2", +1.0,
281                                     "y2", h / 2.0 + 1.0,
282                                     "fill_color_rgba", FG_COLOR,
283                                     "outline_color_rgba", BG_COLOR,
284                                     NULL);
285
286         sr = gnome_canvas_item_new (GNOME_CANVAS_GROUP (highlight),
287                                     gnome_canvas_rect_get_type (),
288                                     "x1", w - 1.0,
289                                     "y1", h / 2.0 - 1.0,
290                                     "x2", w + 1.0,
291                                     "y2", h / 2.0 + 1.0,
292                                     "fill_color_rgba", FG_COLOR,
293                                     "outline_color_rgba", BG_COLOR,
294                                     NULL);
295
296         st = gnome_canvas_item_new (GNOME_CANVAS_GROUP (highlight),
297                                     gnome_canvas_rect_get_type (),
298                                     "x1", w / 2.0 - 1.0,
299                                     "y1", -1.0,
300                                     "x2", w / 2.0 + 1.0,
301                                     "y2", +1.0,
302                                     "fill_color_rgba", FG_COLOR,
303                                     "outline_color_rgba", BG_COLOR,
304                                     NULL);
305
306         sb = gnome_canvas_item_new (GNOME_CANVAS_GROUP (highlight),
307                                     gnome_canvas_rect_get_type (),
308                                     "x1", w / 2.0 - 1.0,
309                                     "y1", h - 1.0,
310                                     "x2", w / 2.0 + 1.0,
311                                     "y2", h + 1.0,
312                                     "fill_color_rgba", FG_COLOR,
313                                     "outline_color_rgba", BG_COLOR,
314                                     NULL);
315
316         g_object_set_data (G_OBJECT (highlight), "object", object);
317
318         g_object_set_data (G_OBJECT (highlight), "outline", outline);
319
320         g_object_set_data (G_OBJECT (highlight), "tl", tl);
321         g_object_set_data (G_OBJECT (highlight), "tr", tr);
322         g_object_set_data (G_OBJECT (highlight), "bl", bl);
323         g_object_set_data (G_OBJECT (highlight), "br", br);
324         g_object_set_data (G_OBJECT (highlight), "sl", sl);
325         g_object_set_data (G_OBJECT (highlight), "sr", sr);
326         g_object_set_data (G_OBJECT (highlight), "st", st);
327         g_object_set_data (G_OBJECT (highlight), "sb", sb);
328
329         g_signal_connect (G_OBJECT (tl), "event",
330                           G_CALLBACK (tl_resize_event_handler), view_object);
331         g_signal_connect (G_OBJECT (tr), "event",
332                           G_CALLBACK (tr_resize_event_handler), view_object);
333         g_signal_connect (G_OBJECT (bl), "event",
334                           G_CALLBACK (bl_resize_event_handler), view_object);
335         g_signal_connect (G_OBJECT (br), "event",
336                           G_CALLBACK (br_resize_event_handler), view_object);
337         g_signal_connect (G_OBJECT (sl), "event",
338                           G_CALLBACK (sl_resize_event_handler), view_object);
339         g_signal_connect (G_OBJECT (sr), "event",
340                           G_CALLBACK (sr_resize_event_handler), view_object);
341         g_signal_connect (G_OBJECT (st), "event",
342                           G_CALLBACK (st_resize_event_handler), view_object);
343         g_signal_connect (G_OBJECT (sb), "event",
344                           G_CALLBACK (sb_resize_event_handler), view_object);
345
346         g_signal_connect (G_OBJECT (outline), "event",
347                           G_CALLBACK (passthrough_event_handler), view_object);
348
349         gnome_canvas_item_raise_to_top (highlight);
350
351         gl_debug (DEBUG_VIEW, "END");
352
353         return highlight;
354 }
355
356 /*---------------------------------------------------------------------------*/
357 /* PRIVATE.  Create a resizable line highlight.                              */
358 /*---------------------------------------------------------------------------*/
359 static GnomeCanvasItem *
360 highlight_resizable_line (glViewObject *view_object)
361 {
362         GnomeCanvasItem *highlight;
363         glLabelObject *object;
364         glView *view;
365         gdouble x, y, dx, dy;
366         GnomeCanvasPoints *points;
367         GnomeCanvasItem *outline;       /* Outline around item */
368         GnomeCanvasItem *p1, *p2;       /* Handles at endpoints */
369
370         gl_debug (DEBUG_VIEW, "START");
371
372         g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
373
374         object = gl_view_object_get_object (view_object);
375         gl_label_object_get_position (object, &x, &y);
376         gl_label_object_get_size (object, &dx, &dy);
377
378         view = gl_view_object_get_view (view_object);
379
380         points = gnome_canvas_points_new (2);
381
382
383         highlight =
384                 gnome_canvas_item_new (gnome_canvas_root
385                                        (GNOME_CANVAS (view->canvas)),
386                                        gnome_canvas_group_get_type (),
387                                        "x", x, "y", y, NULL);
388
389         gnome_canvas_item_hide (highlight);
390
391         points->coords[0] = 0.0;
392         points->coords[1] = 0.0;
393         points->coords[2] = dx;
394         points->coords[3] = dy;
395         outline = gnome_canvas_item_new (GNOME_CANVAS_GROUP (highlight),
396                                          gnome_canvas_line_get_type (),
397                                          "points", points,
398                                          "width_pixels", 3,
399                                          "fill_color_rgba", FG_COLOR,
400                                          NULL);
401
402         p1 = gnome_canvas_item_new (GNOME_CANVAS_GROUP (highlight),
403                                     gnome_canvas_rect_get_type (),
404                                     "x1", -1.0,
405                                     "y1", -1.0,
406                                     "x2", +1.0,
407                                     "y2", +1.0,
408                                     "fill_color_rgba", FG_COLOR,
409                                     "outline_color_rgba", BG_COLOR,
410                                     NULL);
411
412         p2 = gnome_canvas_item_new (GNOME_CANVAS_GROUP (highlight),
413                                     gnome_canvas_rect_get_type (),
414                                     "x1", dx - 1.0,
415                                     "y1", dy - 1.0,
416                                     "x2", dx + 1.0,
417                                     "y2", dy + 1.0,
418                                     "fill_color_rgba", FG_COLOR,
419                                     "outline_color_rgba", BG_COLOR,
420                                     NULL);
421
422         g_object_set_data (G_OBJECT (highlight), "object", object);
423
424         g_object_set_data (G_OBJECT (highlight), "outline", outline);
425
426         g_object_set_data (G_OBJECT (highlight), "p1", p1);
427         g_object_set_data (G_OBJECT (highlight), "p2", p2);
428
429         g_signal_connect (G_OBJECT (p1), "event",
430                           G_CALLBACK (p1_resize_event_handler), view_object);
431         g_signal_connect (G_OBJECT (p2), "event",
432                           G_CALLBACK (p2_resize_event_handler), view_object);
433
434         g_signal_connect (G_OBJECT (outline), "event",
435                           G_CALLBACK (passthrough_event_handler), view_object);
436
437         gnome_canvas_points_free (points);
438
439         gnome_canvas_item_raise_to_top (highlight);
440
441         gl_debug (DEBUG_VIEW, "END");
442
443         return highlight;
444 }
445
446 /*---------------------------------------------------------------------------*/
447 /* PRIVATE.  Create a simple box highlight.                                  */
448 /*---------------------------------------------------------------------------*/
449 static GnomeCanvasItem *
450 highlight_simple         (glViewObject *view_object)
451 {
452         GnomeCanvasItem *highlight, *outline;
453         glLabelObject *object;
454         glView *view;
455         gdouble x, y, w, h;
456
457         gl_debug (DEBUG_VIEW, "START");
458
459         g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
460
461         object = gl_view_object_get_object (view_object);
462         gl_label_object_get_position (object, &x, &y);
463         gl_label_object_get_size (object, &w, &h);
464
465         view = gl_view_object_get_view (view_object);
466
467         highlight =
468                 gnome_canvas_item_new (gnome_canvas_root
469                                        (GNOME_CANVAS (view->canvas)),
470                                        gnome_canvas_group_get_type (),
471                                        "x", x, "y", y, NULL);
472
473         gnome_canvas_item_hide (highlight);
474
475         outline =
476                 gnome_canvas_item_new (GNOME_CANVAS_GROUP(highlight),
477                                        gnome_canvas_rect_get_type (),
478                                        "x1", -0.5,
479                                        "y1", -0.5,
480                                        "x2", w + 0.5,
481                                        "y2", h + 0.5,
482                                        "width_pixels", 2,
483                                        "outline_color_rgba", FG_COLOR,
484                                        NULL);
485
486
487         g_object_set_data (G_OBJECT (highlight), "outline", outline);
488
489         g_object_set_data (G_OBJECT (highlight), "object", object);
490
491         g_signal_connect (G_OBJECT (highlight), "event",
492                           G_CALLBACK (passthrough_event_handler), view_object);
493
494         gnome_canvas_item_raise_to_top (highlight);
495
496         gl_debug (DEBUG_VIEW, "END");
497
498         return highlight;
499 }
500
501 /*---------------------------------------------------------------------------*/
502 /* PRIVATE.  Update a resizable box highlight.                               */
503 /*---------------------------------------------------------------------------*/
504 static void
505 update_resizable_box  (GnomeCanvasItem *highlight,
506                        glViewHighlightStyle style)
507 {
508         glLabelObject *object;
509         gdouble w, h;
510         GnomeCanvasItem *outline;               /* Outline around item */
511         GnomeCanvasItem *tl, *tr, *bl, *br;     /* Handles at four corners */
512         GnomeCanvasItem *sl, *sr, *st, *sb;     /* Handles at each side */
513
514         gl_debug (DEBUG_VIEW, "START");
515
516         g_return_if_fail (GNOME_IS_CANVAS_ITEM (highlight));
517
518         object = g_object_get_data (G_OBJECT (highlight), "object");
519         gl_label_object_get_size (object, &w, &h);
520
521         outline = g_object_get_data (G_OBJECT (highlight), "outline");
522
523         tl = g_object_get_data (G_OBJECT (highlight), "tl");
524         tr = g_object_get_data (G_OBJECT (highlight), "tr");
525         bl = g_object_get_data (G_OBJECT (highlight), "bl");
526         br = g_object_get_data (G_OBJECT (highlight), "br");
527         sl = g_object_get_data (G_OBJECT (highlight), "sl");
528         sr = g_object_get_data (G_OBJECT (highlight), "sr");
529         st = g_object_get_data (G_OBJECT (highlight), "st");
530         sb = g_object_get_data (G_OBJECT (highlight), "sb");
531
532         gnome_canvas_item_set (outline,
533                                "x1", -0.5,
534                                "y1", -0.5,
535                                "x2", w + 0.5,
536                                "y2", h + 0.5,
537                                NULL);
538
539         gnome_canvas_item_set (tl,
540                                "x1", -1.0,
541                                "y1", -1.0,
542                                "x2", +1.0,
543                                "y2", +1.0,
544                                NULL);
545
546         gnome_canvas_item_set (tr,
547                                "x1", w - 1.0,
548                                "y1", -1.0,
549                                "x2", w + 1.0,
550                                "y2", +1.0,
551                                NULL);
552
553         gnome_canvas_item_set (bl,
554                                "x1", -1.0,
555                                "y1", h - 1.0,
556                                "x2", +1.0,
557                                "y2", h + 1.0,
558                                NULL);
559
560         gnome_canvas_item_set (br,
561                                "x1", w - 1.0,
562                                "y1", h - 1.0,
563                                "x2", w + 1.0,
564                                "y2", h + 1.0,
565                                NULL);
566
567         gnome_canvas_item_set (sl,
568                                "x1", -1.0,
569                                "y1", h / 2.0 - 1.0,
570                                "x2", +1.0,
571                                "y2", h / 2.0 + 1.0,
572                                NULL);
573
574         gnome_canvas_item_set (sr,
575                                "x1", w - 1.0,
576                                "y1", h / 2.0 - 1.0,
577                                "x2", w + 1.0,
578                                "y2", h / 2.0 + 1.0,
579                                NULL);
580
581         gnome_canvas_item_set (st,
582                                "x1", w / 2.0 - 1.0,
583                                "y1", -1.0,
584                                "x2", w / 2.0 + 1.0,
585                                "y2", +1.0,
586                                NULL);
587
588         gnome_canvas_item_set (sb,
589                                "x1", w / 2.0 - 1.0,
590                                "y1", h - 1.0,
591                                "x2", w / 2.0 + 1.0,
592                                "y2", h + 1.0,
593                                NULL);
594
595         gnome_canvas_item_raise_to_top (highlight);
596
597         gl_debug (DEBUG_VIEW, "END");
598 }
599
600 /*---------------------------------------------------------------------------*/
601 /* PRIVATE.  Update a resizable line highlight.                              */
602 /*---------------------------------------------------------------------------*/
603 static void
604 update_resizable_line (GnomeCanvasItem *highlight)
605 {
606         glLabelObject *object;
607         gdouble dx, dy;
608         GnomeCanvasPoints *points;
609         GnomeCanvasItem *outline;       /* Outline around item */
610         GnomeCanvasItem *p1, *p2;       /* Handles at endpoints */
611
612         gl_debug (DEBUG_VIEW, "START");
613
614         g_return_if_fail (GNOME_IS_CANVAS_ITEM (highlight));
615
616         object = g_object_get_data (G_OBJECT (highlight), "object");
617         gl_label_object_get_size (object, &dx, &dy);
618
619         points = gnome_canvas_points_new (2);
620
621         outline = g_object_get_data (G_OBJECT (highlight), "outline");
622
623         p1 = g_object_get_data (G_OBJECT (highlight), "p1");
624         p2 = g_object_get_data (G_OBJECT (highlight), "p2");
625
626         points->coords[0] = 0.0;
627         points->coords[1] = 0.0;
628         points->coords[2] = dx;
629         points->coords[3] = dy;
630         gnome_canvas_item_set (outline, "points", points, NULL);
631
632         gnome_canvas_item_set (p1,
633                                "x1", -1.0,
634                                "y1", -1.0,
635                                "x2", +1.0,
636                                "y2", +1.0,
637                                NULL);
638
639         gnome_canvas_item_set (p2,
640                                "x1", dx - 1.0,
641                                "y1", dy - 1.0,
642                                "x2", dx + 1.0,
643                                "y2", dy + 1.0,
644                                NULL);
645
646         gnome_canvas_points_free (points);
647
648         gnome_canvas_item_raise_to_top (highlight);
649
650         gl_debug (DEBUG_VIEW, "END");
651 }
652
653 /*---------------------------------------------------------------------------*/
654 /* PRIVATE.  Update a simple box highlight.                                  */
655 /*---------------------------------------------------------------------------*/
656 static void
657 update_simple (GnomeCanvasItem *highlight)
658 {
659         glLabelObject *object;
660         gdouble w, h;
661         GnomeCanvasItem *outline;               /* Outline around item */
662
663         gl_debug (DEBUG_VIEW, "START");
664
665         g_return_if_fail (GNOME_IS_CANVAS_ITEM (highlight));
666
667         object = g_object_get_data (G_OBJECT (highlight), "object");
668         gl_label_object_get_size (object, &w, &h);
669
670         outline = g_object_get_data (G_OBJECT (highlight), "outline");
671
672         gnome_canvas_item_set (outline,
673                                "x2", w + 0.5,
674                                "y2", h + 0.5,
675                                NULL);
676
677         gnome_canvas_item_raise_to_top (highlight);
678
679         gl_debug (DEBUG_VIEW, "END");
680 }
681
682 /*---------------------------------------------------------------------------*/
683 /* PRIVATE.  "Top-left" Resize event handler.                    */
684 /*---------------------------------------------------------------------------*/
685 static int
686 tl_resize_event_handler (GnomeCanvasItem * handle_item,
687                          GdkEvent * event,
688                          glViewObject *view_object)
689 {
690         gdouble x, y, w, h;
691         static gdouble x2, y2;
692         static gboolean dragging = FALSE;
693         glLabelObject *object;
694         glView *view;
695         GdkCursor *cursor;
696
697         gl_debug (DEBUG_VIEW, "");
698
699         view = gl_view_object_get_view (view_object);
700         if ( view->state != GL_VIEW_STATE_ARROW ) {
701                 /* don't interfere with object creation modes */
702                 return FALSE;
703         }
704
705         object = gl_view_object_get_object (view_object);
706         gl_label_object_get_position (object, &x, &y);
707         gl_label_object_get_size (object, &w, &h);
708
709         switch (event->type) {
710
711         case GDK_BUTTON_PRESS:
712                 switch (event->button.button) {
713                 case 1:
714                         dragging = TRUE;
715                         gnome_canvas_item_grab (handle_item,
716                                                 GDK_POINTER_MOTION_MASK |
717                                                 GDK_BUTTON_RELEASE_MASK |
718                                                 GDK_BUTTON_PRESS_MASK,
719                                                 NULL, event->button.time);
720                         /* Anchor to bottom-right corner */
721                         x2 = x + w;
722                         y2 = y + h;
723                         return TRUE;
724
725                 default:
726                         return FALSE;
727                 }
728
729         case GDK_BUTTON_RELEASE:
730                 switch (event->button.button) {
731                 case 1:
732                         dragging = FALSE;
733                         gnome_canvas_item_ungrab (handle_item,
734                                                   event->button.time);
735                         x = MIN (event->button.x, x2 - MIN_ITEM_SIZE);
736                         y = MIN (event->button.y, y2 - MIN_ITEM_SIZE);
737                         w = MAX (x2 - event->button.x, MIN_ITEM_SIZE);
738                         h = MAX (y2 - event->button.y, MIN_ITEM_SIZE);
739                         gl_label_object_set_position (object, x, y);
740                         gl_label_object_set_size (object, w, h);
741                         return TRUE;
742
743                 default:
744                         return FALSE;
745                 }
746
747         case GDK_MOTION_NOTIFY:
748                 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
749                         x = MIN (event->button.x, x2 - MIN_ITEM_SIZE);
750                         y = MIN (event->button.y, y2 - MIN_ITEM_SIZE);
751                         w = MAX (x2 - event->button.x, MIN_ITEM_SIZE);
752                         h = MAX (y2 - event->button.y, MIN_ITEM_SIZE);
753                         gl_label_object_set_position (object, x, y);
754                         gl_label_object_set_size (object, w, h);
755                         return TRUE;
756                 } else {
757                         return FALSE;
758                 }
759
760         case GDK_ENTER_NOTIFY:
761                 cursor = gdk_cursor_new (GDK_CROSSHAIR);
762                 gdk_window_set_cursor (view->canvas->window, cursor);
763                 gdk_cursor_unref (cursor);
764                 return TRUE;
765
766         case GDK_LEAVE_NOTIFY:
767                 cursor = gdk_cursor_new (GDK_LEFT_PTR);
768                 gdk_window_set_cursor (view->canvas->window, cursor);
769                 gdk_cursor_unref (cursor);
770                 return TRUE;
771
772         default:
773                 return FALSE;
774         }
775
776 }
777
778 /*---------------------------------------------------------------------------*/
779 /* PRIVATE.  "Top-right" Resize event handler.                               */
780 /*---------------------------------------------------------------------------*/
781 static int
782 tr_resize_event_handler (GnomeCanvasItem * handle_item,
783                          GdkEvent * event,
784                          glViewObject *view_object)
785 {
786         gdouble x, y, w, h;
787         static gdouble x1, y2;
788         static gboolean dragging = FALSE;
789         glLabelObject *object;
790         glView *view;
791         GdkCursor *cursor;
792
793         gl_debug (DEBUG_VIEW, "");
794
795         view = gl_view_object_get_view (view_object);
796         if ( view->state != GL_VIEW_STATE_ARROW ) {
797                 /* don't interfere with object creation modes */
798                 return FALSE;
799         }
800
801         object = gl_view_object_get_object (view_object);
802         gl_label_object_get_position (object, &x, &y);
803         gl_label_object_get_size (object, &w, &h);
804
805         switch (event->type) {
806
807         case GDK_BUTTON_PRESS:
808                 switch (event->button.button) {
809                 case 1:
810                         dragging = TRUE;
811                         gnome_canvas_item_grab (handle_item,
812                                                 GDK_POINTER_MOTION_MASK |
813                                                 GDK_BUTTON_RELEASE_MASK |
814                                                 GDK_BUTTON_PRESS_MASK,
815                                                 NULL, event->button.time);
816                         /* Anchor to bottom-left corner */
817                         x1 = x;
818                         y2 = y + h;
819                         return TRUE;
820
821                 default:
822                         return FALSE;
823                 }
824
825         case GDK_BUTTON_RELEASE:
826                 switch (event->button.button) {
827                 case 1:
828                         dragging = FALSE;
829                         gnome_canvas_item_ungrab (handle_item,
830                                                   event->button.time);
831                         x = x1;
832                         y = MIN (event->button.y, y2 - MIN_ITEM_SIZE);
833                         w = MAX (event->button.x - x1, MIN_ITEM_SIZE);
834                         h = MAX (y2 - event->button.y, MIN_ITEM_SIZE);
835                         gl_label_object_set_position (object, x, y);
836                         gl_label_object_set_size (object, w, h);
837                         return TRUE;
838
839                 default:
840                         return FALSE;
841                 }
842
843         case GDK_MOTION_NOTIFY:
844                 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
845                         x = x1;
846                         y = MIN (event->button.y, y2 - MIN_ITEM_SIZE);
847                         w = MAX (event->button.x - x1, MIN_ITEM_SIZE);
848                         h = MAX (y2 - event->button.y, MIN_ITEM_SIZE);
849                         gl_label_object_set_position (object, x, y);
850                         gl_label_object_set_size (object, w, h);
851                         return TRUE;
852                 } else {
853                         return FALSE;
854                 }
855
856         case GDK_ENTER_NOTIFY:
857                 cursor = gdk_cursor_new (GDK_CROSSHAIR);
858                 gdk_window_set_cursor (view->canvas->window, cursor);
859                 gdk_cursor_unref (cursor);
860                 return TRUE;
861
862         case GDK_LEAVE_NOTIFY:
863                 cursor = gdk_cursor_new (GDK_LEFT_PTR);
864                 gdk_window_set_cursor (view->canvas->window, cursor);
865                 gdk_cursor_unref (cursor);
866                 return TRUE;
867
868         default:
869                 return FALSE;
870         }
871
872 }
873
874 /*---------------------------------------------------------------------------*/
875 /* PRIVATE.  "Bottom-left" Resize event handler.                             */
876 /*---------------------------------------------------------------------------*/
877 static int
878 bl_resize_event_handler (GnomeCanvasItem * handle_item,
879                          GdkEvent * event,
880                          glViewObject *view_object)
881 {
882         gdouble x, y, w, h;
883         static gdouble x2, y1;
884         static gboolean dragging = FALSE;
885         glLabelObject *object;
886         glView *view;
887         GdkCursor *cursor;
888
889         gl_debug (DEBUG_VIEW, "");
890
891         view = gl_view_object_get_view (view_object);
892         if ( view->state != GL_VIEW_STATE_ARROW ) {
893                 /* don't interfere with object creation modes */
894                 return FALSE;
895         }
896
897         object = gl_view_object_get_object (view_object);
898         gl_label_object_get_position (object, &x, &y);
899         gl_label_object_get_size (object, &w, &h);
900
901         switch (event->type) {
902
903         case GDK_BUTTON_PRESS:
904                 switch (event->button.button) {
905                 case 1:
906                         dragging = TRUE;
907                         gnome_canvas_item_grab (handle_item,
908                                                 GDK_POINTER_MOTION_MASK |
909                                                 GDK_BUTTON_RELEASE_MASK |
910                                                 GDK_BUTTON_PRESS_MASK,
911                                                 NULL, event->button.time);
912                         /* Anchor to top-right corner */
913                         x2 = x + w;
914                         y1 = y;
915                         return TRUE;
916
917                 default:
918                         return FALSE;
919                 }
920
921         case GDK_BUTTON_RELEASE:
922                 switch (event->button.button) {
923                 case 1:
924                         dragging = FALSE;
925                         gnome_canvas_item_ungrab (handle_item,
926                                                   event->button.time);
927                         x = MIN (event->button.x, x2 - MIN_ITEM_SIZE);
928                         y = y1;
929                         w = MAX (x2 - event->button.x, MIN_ITEM_SIZE);
930                         h = MAX (event->button.y - y1, MIN_ITEM_SIZE);
931                         gl_label_object_set_position (object, x, y);
932                         gl_label_object_set_size (object, w, h);
933                         return TRUE;
934
935                 default:
936                         return FALSE;
937                 }
938
939         case GDK_MOTION_NOTIFY:
940                 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
941                         x = MIN (event->button.x, x2 - MIN_ITEM_SIZE);
942                         y = y1;
943                         w = MAX (x2 - event->button.x, MIN_ITEM_SIZE);
944                         h = MAX (event->button.y - y1, MIN_ITEM_SIZE);
945                         gl_label_object_set_position (object, x, y);
946                         gl_label_object_set_size (object, w, h);
947                         return TRUE;
948                 } else {
949                         return FALSE;
950                 }
951
952         case GDK_ENTER_NOTIFY:
953                 cursor = gdk_cursor_new (GDK_CROSSHAIR);
954                 gdk_window_set_cursor (view->canvas->window, cursor);
955                 gdk_cursor_unref (cursor);
956                 return TRUE;
957
958         case GDK_LEAVE_NOTIFY:
959                 cursor = gdk_cursor_new (GDK_LEFT_PTR);
960                 gdk_window_set_cursor (view->canvas->window, cursor);
961                 gdk_cursor_unref (cursor);
962                 return TRUE;
963
964         default:
965                 return FALSE;
966         }
967
968 }
969
970 /*---------------------------------------------------------------------------*/
971 /* PRIVATE.  "Bottom-right" Resize event handler.                            */
972 /*---------------------------------------------------------------------------*/
973 static int
974 br_resize_event_handler (GnomeCanvasItem * handle_item,
975                          GdkEvent * event,
976                          glViewObject *view_object)
977 {
978         gdouble x, y, w, h;
979         static gdouble x1, y1;
980         static gboolean dragging = FALSE;
981         glLabelObject *object;
982         glView *view;
983         GdkCursor *cursor;
984
985         view = gl_view_object_get_view (view_object);
986         if ( view->state != GL_VIEW_STATE_ARROW ) {
987                 /* don't interfere with object creation modes */
988                 return FALSE;
989         }
990
991         gl_debug (DEBUG_VIEW, "");
992
993         object = gl_view_object_get_object (view_object);
994         gl_label_object_get_position (object, &x, &y);
995         gl_label_object_get_size (object, &w, &h);
996
997         switch (event->type) {
998
999         case GDK_BUTTON_PRESS:
1000                 switch (event->button.button) {
1001                 case 1:
1002                         dragging = TRUE;
1003                         gnome_canvas_item_grab (handle_item,
1004                                                 GDK_POINTER_MOTION_MASK |
1005                                                 GDK_BUTTON_RELEASE_MASK |
1006                                                 GDK_BUTTON_PRESS_MASK,
1007                                                 NULL, event->button.time);
1008                         /* Anchor to top-left corner */
1009                         x1 = x;
1010                         y1 = y;
1011                         return TRUE;
1012
1013                 default:
1014                         return FALSE;
1015                 }
1016
1017         case GDK_BUTTON_RELEASE:
1018                 switch (event->button.button) {
1019                 case 1:
1020                         dragging = FALSE;
1021                         gnome_canvas_item_ungrab (handle_item,
1022                                                   event->button.time);
1023                         x = x1;
1024                         y = y1;
1025                         w = MAX (event->button.x - x1, MIN_ITEM_SIZE);
1026                         h = MAX (event->button.y - y1, MIN_ITEM_SIZE);
1027                         gl_label_object_set_position (object, x, y);
1028                         gl_label_object_set_size (object, w, h);
1029                         return TRUE;
1030
1031                 default:
1032                         return FALSE;
1033                 }
1034
1035         case GDK_MOTION_NOTIFY:
1036                 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
1037                         x = x1;
1038                         y = y1;
1039                         w = MAX (event->button.x - x1, MIN_ITEM_SIZE);
1040                         h = MAX (event->button.y - y1, MIN_ITEM_SIZE);
1041                         gl_label_object_set_position (object, x, y);
1042                         gl_label_object_set_size (object, w, h);
1043                         return TRUE;
1044                 } else {
1045                         return FALSE;
1046                 }
1047
1048         case GDK_ENTER_NOTIFY:
1049                 cursor = gdk_cursor_new (GDK_CROSSHAIR);
1050                 gdk_window_set_cursor (view->canvas->window, cursor);
1051                 gdk_cursor_unref (cursor);
1052                 return TRUE;
1053
1054         case GDK_LEAVE_NOTIFY:
1055                 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1056                 gdk_window_set_cursor (view->canvas->window, cursor);
1057                 gdk_cursor_unref (cursor);
1058                 return TRUE;
1059
1060         default:
1061                 return FALSE;
1062         }
1063
1064 }
1065
1066 /*---------------------------------------------------------------------------*/
1067 /* PRIVATE.  "Left-side" Resize event handler.                               */
1068 /*---------------------------------------------------------------------------*/
1069 static int
1070 sl_resize_event_handler (GnomeCanvasItem * handle_item,
1071                          GdkEvent * event,
1072                          glViewObject *view_object)
1073 {
1074         gdouble x, y, w, h;
1075         static gdouble x2;
1076         static gboolean dragging = FALSE;
1077         glLabelObject *object;
1078         glView *view;
1079         GdkCursor *cursor;
1080
1081         gl_debug (DEBUG_VIEW, "");
1082
1083         view = gl_view_object_get_view (view_object);
1084         if ( view->state != GL_VIEW_STATE_ARROW ) {
1085                 /* don't interfere with object creation modes */
1086                 return FALSE;
1087         }
1088
1089         object = gl_view_object_get_object (view_object);
1090         gl_label_object_get_position (object, &x, &y);
1091         gl_label_object_get_size (object, &w, &h);
1092
1093         switch (event->type) {
1094
1095         case GDK_BUTTON_PRESS:
1096                 switch (event->button.button) {
1097                 case 1:
1098                         dragging = TRUE;
1099                         gnome_canvas_item_grab (handle_item,
1100                                                 GDK_POINTER_MOTION_MASK |
1101                                                 GDK_BUTTON_RELEASE_MASK |
1102                                                 GDK_BUTTON_PRESS_MASK,
1103                                                 NULL, event->button.time);
1104                         /* Anchor to right side */
1105                         x2 = x + w;
1106                         return TRUE;
1107
1108                 default:
1109                         return FALSE;
1110                 }
1111
1112         case GDK_BUTTON_RELEASE:
1113                 switch (event->button.button) {
1114                 case 1:
1115                         dragging = FALSE;
1116                         gnome_canvas_item_ungrab (handle_item,
1117                                                   event->button.time);
1118                         x = MIN (event->button.x, x2 - MIN_ITEM_SIZE);
1119                         w = MAX (x2 - event->button.x, MIN_ITEM_SIZE);
1120                         gl_label_object_set_position (object, x, y);
1121                         gl_label_object_set_size (object, w, h);
1122                         return TRUE;
1123
1124                 default:
1125                         return FALSE;
1126                 }
1127
1128         case GDK_MOTION_NOTIFY:
1129                 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
1130                         x = MIN (event->button.x, x2 - MIN_ITEM_SIZE);
1131                         w = MAX (x2 - event->button.x, MIN_ITEM_SIZE);
1132                         gl_label_object_set_position (object, x, y);
1133                         gl_label_object_set_size (object, w, h);
1134                         return TRUE;
1135                 } else {
1136                         return FALSE;
1137                 }
1138
1139         case GDK_ENTER_NOTIFY:
1140                 cursor = gdk_cursor_new (GDK_CROSSHAIR);
1141                 gdk_window_set_cursor (view->canvas->window, cursor);
1142                 gdk_cursor_unref (cursor);
1143                 return TRUE;
1144
1145         case GDK_LEAVE_NOTIFY:
1146                 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1147                 gdk_window_set_cursor (view->canvas->window, cursor);
1148                 gdk_cursor_unref (cursor);
1149                 return TRUE;
1150
1151         default:
1152                 return FALSE;
1153         }
1154
1155 }
1156
1157 /*---------------------------------------------------------------------------*/
1158 /* PRIVATE.  "Right-side" Resize event handler.                              */
1159 /*---------------------------------------------------------------------------*/
1160 static int
1161 sr_resize_event_handler (GnomeCanvasItem * handle_item,
1162                          GdkEvent * event,
1163                          glViewObject *view_object)
1164 {
1165         gdouble x, y, w, h;
1166         static gdouble x1;
1167         static gboolean dragging = FALSE;
1168         glLabelObject *object;
1169         glView *view;
1170         GdkCursor *cursor;
1171
1172         gl_debug (DEBUG_VIEW, "");
1173
1174         view = gl_view_object_get_view (view_object);
1175         if ( view->state != GL_VIEW_STATE_ARROW ) {
1176                 /* don't interfere with object creation modes */
1177                 return FALSE;
1178         }
1179
1180         object = gl_view_object_get_object (view_object);
1181         gl_label_object_get_position (object, &x, &y);
1182         gl_label_object_get_size (object, &w, &h);
1183
1184         switch (event->type) {
1185
1186         case GDK_BUTTON_PRESS:
1187                 switch (event->button.button) {
1188                 case 1:
1189                         dragging = TRUE;
1190                         gnome_canvas_item_grab (handle_item,
1191                                                 GDK_POINTER_MOTION_MASK |
1192                                                 GDK_BUTTON_RELEASE_MASK |
1193                                                 GDK_BUTTON_PRESS_MASK,
1194                                                 NULL, event->button.time);
1195                         /* Anchor to left side */
1196                         x1 = x;
1197                         return TRUE;
1198
1199                 default:
1200                         return FALSE;
1201                 }
1202
1203         case GDK_BUTTON_RELEASE:
1204                 switch (event->button.button) {
1205                 case 1:
1206                         dragging = FALSE;
1207                         gnome_canvas_item_ungrab (handle_item,
1208                                                   event->button.time);
1209                         x = x1;
1210                         w = MAX (event->button.x - x1, MIN_ITEM_SIZE);
1211                         gl_label_object_set_position (object, x, y);
1212                         gl_label_object_set_size (object, w, h);
1213                         return TRUE;
1214
1215                 default:
1216                         return FALSE;
1217                 }
1218
1219         case GDK_MOTION_NOTIFY:
1220                 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
1221                         x = x1;
1222                         w = MAX (event->button.x - x1, MIN_ITEM_SIZE);
1223                         gl_label_object_set_position (object, x, y);
1224                         gl_label_object_set_size (object, w, h);
1225                         return TRUE;
1226                 } else {
1227                         return FALSE;
1228                 }
1229
1230         case GDK_ENTER_NOTIFY:
1231                 cursor = gdk_cursor_new (GDK_CROSSHAIR);
1232                 gdk_window_set_cursor (view->canvas->window, cursor);
1233                 gdk_cursor_unref (cursor);
1234                 return TRUE;
1235
1236         case GDK_LEAVE_NOTIFY:
1237                 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1238                 gdk_window_set_cursor (view->canvas->window, cursor);
1239                 gdk_cursor_unref (cursor);
1240                 return TRUE;
1241
1242         default:
1243                 return FALSE;
1244         }
1245
1246 }
1247
1248 /*---------------------------------------------------------------------------*/
1249 /* PRIVATE.  "Top-side" Resize event handler.                                */
1250 /*---------------------------------------------------------------------------*/
1251 static int
1252 st_resize_event_handler (GnomeCanvasItem * handle_item,
1253                          GdkEvent * event,
1254                          glViewObject *view_object)
1255 {
1256         gdouble x, y, w, h;
1257         static gdouble y2;
1258         static gboolean dragging = FALSE;
1259         glLabelObject *object;
1260         glView *view;
1261         GdkCursor *cursor;
1262
1263         gl_debug (DEBUG_VIEW, "");
1264
1265         view = gl_view_object_get_view (view_object);
1266         if ( view->state != GL_VIEW_STATE_ARROW ) {
1267                 /* don't interfere with object creation modes */
1268                 return FALSE;
1269         }
1270
1271         object = gl_view_object_get_object (view_object);
1272         gl_label_object_get_position (object, &x, &y);
1273         gl_label_object_get_size (object, &w, &h);
1274
1275         switch (event->type) {
1276
1277         case GDK_BUTTON_PRESS:
1278                 switch (event->button.button) {
1279                 case 1:
1280                         dragging = TRUE;
1281                         gnome_canvas_item_grab (handle_item,
1282                                                 GDK_POINTER_MOTION_MASK |
1283                                                 GDK_BUTTON_RELEASE_MASK |
1284                                                 GDK_BUTTON_PRESS_MASK,
1285                                                 NULL, event->button.time);
1286                         /* Anchor to bottom-right corner */
1287                         y2 = y + h;
1288                         return TRUE;
1289
1290                 default:
1291                         return FALSE;
1292                 }
1293
1294         case GDK_BUTTON_RELEASE:
1295                 switch (event->button.button) {
1296                 case 1:
1297                         dragging = FALSE;
1298                         gnome_canvas_item_ungrab (handle_item,
1299                                                   event->button.time);
1300                         y = MIN (event->button.y, y2 - MIN_ITEM_SIZE);
1301                         h = MAX (y2 - event->button.y, MIN_ITEM_SIZE);
1302                         gl_label_object_set_position (object, x, y);
1303                         gl_label_object_set_size (object, w, h);
1304                         return TRUE;
1305
1306                 default:
1307                         return FALSE;
1308                 }
1309
1310         case GDK_MOTION_NOTIFY:
1311                 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
1312                         y = MIN (event->button.y, y2 - MIN_ITEM_SIZE);
1313                         h = MAX (y2 - event->button.y, MIN_ITEM_SIZE);
1314                         gl_label_object_set_position (object, x, y);
1315                         gl_label_object_set_size (object, w, h);
1316                         return TRUE;
1317                 } else {
1318                         return FALSE;
1319                 }
1320
1321         case GDK_ENTER_NOTIFY:
1322                 cursor = gdk_cursor_new (GDK_CROSSHAIR);
1323                 gdk_window_set_cursor (view->canvas->window, cursor);
1324                 gdk_cursor_unref (cursor);
1325                 return TRUE;
1326
1327         case GDK_LEAVE_NOTIFY:
1328                 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1329                 gdk_window_set_cursor (view->canvas->window, cursor);
1330                 gdk_cursor_unref (cursor);
1331                 return TRUE;
1332
1333         default:
1334                 return FALSE;
1335         }
1336
1337 }
1338
1339 /*---------------------------------------------------------------------------*/
1340 /* PRIVATE.  "Bottom-side" Resize event handler.                             */
1341 /*---------------------------------------------------------------------------*/
1342 static int
1343 sb_resize_event_handler (GnomeCanvasItem * handle_item,
1344                          GdkEvent * event,
1345                          glViewObject *view_object)
1346 {
1347         gdouble x, y, w, h;
1348         static gdouble y1;
1349         static gboolean dragging = FALSE;
1350         glLabelObject *object;
1351         glView *view;
1352         GdkCursor *cursor;
1353
1354         gl_debug (DEBUG_VIEW, "");
1355
1356         view = gl_view_object_get_view (view_object);
1357         if ( view->state != GL_VIEW_STATE_ARROW ) {
1358                 /* don't interfere with object creation modes */
1359                 return FALSE;
1360         }
1361
1362         object = gl_view_object_get_object (view_object);
1363         gl_label_object_get_position (object, &x, &y);
1364         gl_label_object_get_size (object, &w, &h);
1365
1366         switch (event->type) {
1367
1368         case GDK_BUTTON_PRESS:
1369                 switch (event->button.button) {
1370                 case 1:
1371                         dragging = TRUE;
1372                         gnome_canvas_item_grab (handle_item,
1373                                                 GDK_POINTER_MOTION_MASK |
1374                                                 GDK_BUTTON_RELEASE_MASK |
1375                                                 GDK_BUTTON_PRESS_MASK,
1376                                                 NULL, event->button.time);
1377                         /* Anchor to top side */
1378                         y1 = y;
1379                         return TRUE;
1380
1381                 default:
1382                         return FALSE;
1383                 }
1384
1385         case GDK_BUTTON_RELEASE:
1386                 switch (event->button.button) {
1387                 case 1:
1388                         dragging = FALSE;
1389                         gnome_canvas_item_ungrab (handle_item,
1390                                                   event->button.time);
1391                         y = y1;
1392                         h = MAX (event->button.y - y1, MIN_ITEM_SIZE);
1393                         gl_label_object_set_position (object, x, y);
1394                         gl_label_object_set_size (object, w, h);
1395                         return TRUE;
1396
1397                 default:
1398                         return FALSE;
1399                 }
1400
1401         case GDK_MOTION_NOTIFY:
1402                 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
1403                         y = y1;
1404                         h = MAX (event->button.y - y1, MIN_ITEM_SIZE);
1405                         gl_label_object_set_position (object, x, y);
1406                         gl_label_object_set_size (object, w, h);
1407                         return TRUE;
1408                 } else {
1409                         return FALSE;
1410                 }
1411
1412         case GDK_ENTER_NOTIFY:
1413                 cursor = gdk_cursor_new (GDK_CROSSHAIR);
1414                 gdk_window_set_cursor (view->canvas->window, cursor);
1415                 gdk_cursor_unref (cursor);
1416                 return TRUE;
1417
1418         case GDK_LEAVE_NOTIFY:
1419                 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1420                 gdk_window_set_cursor (view->canvas->window, cursor);
1421                 gdk_cursor_unref (cursor);
1422                 return TRUE;
1423
1424         default:
1425                 return FALSE;
1426         }
1427
1428 }
1429
1430 /*---------------------------------------------------------------------------*/
1431 /* PRIVATE.  Resize "P1" event handler.                                      */
1432 /*---------------------------------------------------------------------------*/
1433 static int
1434 p1_resize_event_handler (GnomeCanvasItem * handle_item,
1435                          GdkEvent * event,
1436                          glViewObject *view_object)
1437 {
1438         gdouble x, y, dx, dy;
1439         static gdouble x0, y0;
1440         static gboolean dragging = FALSE;
1441         glLabelObject *object;
1442         glView *view;
1443         GdkCursor *cursor;
1444
1445         gl_debug (DEBUG_VIEW, "");
1446
1447         view = gl_view_object_get_view (view_object);
1448         if ( view->state != GL_VIEW_STATE_ARROW ) {
1449                 /* don't interfere with object creation modes */
1450                 return FALSE;
1451         }
1452
1453         object = gl_view_object_get_object (view_object);
1454         gl_label_object_get_position (object, &x, &y);
1455         gl_label_object_get_size (object, &dx, &dy);
1456
1457         switch (event->type) {
1458
1459         case GDK_BUTTON_PRESS:
1460                 switch (event->button.button) {
1461                 case 1:
1462                         dragging = TRUE;
1463                         gnome_canvas_item_grab (handle_item,
1464                                                 GDK_POINTER_MOTION_MASK |
1465                                                 GDK_BUTTON_RELEASE_MASK |
1466                                                 GDK_BUTTON_PRESS_MASK,
1467                                                 NULL, event->button.time);
1468                         /* Anchor to P2 */
1469                         x0 = x + dx;
1470                         y0 = y + dy;
1471                         return TRUE;
1472
1473                 default:
1474                         return FALSE;
1475                 }
1476
1477         case GDK_BUTTON_RELEASE:
1478                 switch (event->button.button) {
1479                 case 1:
1480                         dragging = FALSE;
1481                         gnome_canvas_item_ungrab (handle_item,
1482                                                   event->button.time);
1483                         x = x0;
1484                         y = y0;
1485                         dx = (event->button.x - x0);
1486                         dy = (event->button.y - y0);
1487                         gl_label_object_set_position (object, x, y);
1488                         gl_label_object_set_size (object, dx, dy);
1489                         return TRUE;
1490
1491                 default:
1492                         return FALSE;
1493                 }
1494
1495         case GDK_MOTION_NOTIFY:
1496                 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
1497                         x = x0;
1498                         y = y0;
1499                         dx = (event->button.x - x0);
1500                         dy = (event->button.y - y0);
1501                         gl_label_object_set_position (object, x, y);
1502                         gl_label_object_set_size (object, dx, dy);
1503                         return TRUE;
1504                 } else {
1505                         return FALSE;
1506                 }
1507
1508         case GDK_ENTER_NOTIFY:
1509                 cursor = gdk_cursor_new (GDK_CROSSHAIR);
1510                 gdk_window_set_cursor (view->canvas->window, cursor);
1511                 gdk_cursor_unref (cursor);
1512                 return TRUE;
1513
1514         case GDK_LEAVE_NOTIFY:
1515                 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1516                 gdk_window_set_cursor (view->canvas->window, cursor);
1517                 gdk_cursor_unref (cursor);
1518                 return TRUE;
1519
1520         default:
1521                 return FALSE;
1522         }
1523
1524 }
1525
1526 /*---------------------------------------------------------------------------*/
1527 /* PRIVATE.  Resize "P2" event handler.                                      */
1528 /*---------------------------------------------------------------------------*/
1529 static int
1530 p2_resize_event_handler (GnomeCanvasItem * handle_item,
1531                          GdkEvent * event,
1532                          glViewObject *view_object)
1533 {
1534         gdouble x, y, dx, dy;
1535         static gdouble x0, y0;
1536         static gboolean dragging = FALSE;
1537         glLabelObject *object;
1538         glView *view;
1539         GdkCursor *cursor;
1540
1541         gl_debug (DEBUG_VIEW, "");
1542
1543         view = gl_view_object_get_view (view_object);
1544         if ( view->state != GL_VIEW_STATE_ARROW ) {
1545                 /* don't interfere with object creation modes */
1546                 return FALSE;
1547         }
1548
1549         object = gl_view_object_get_object (view_object);
1550         gl_label_object_get_position (object, &x, &y);
1551         gl_label_object_get_size (object, &dx, &dy);
1552
1553         switch (event->type) {
1554
1555         case GDK_BUTTON_PRESS:
1556                 switch (event->button.button) {
1557                 case 1:
1558                         dragging = TRUE;
1559                         gnome_canvas_item_grab (handle_item,
1560                                                 GDK_POINTER_MOTION_MASK |
1561                                                 GDK_BUTTON_RELEASE_MASK |
1562                                                 GDK_BUTTON_PRESS_MASK,
1563                                                 NULL, event->button.time);
1564                         /* Anchor to P1 */
1565                         x0 = x;
1566                         y0 = y;
1567                         return TRUE;
1568
1569                 default:
1570                         return FALSE;
1571                 }
1572
1573         case GDK_BUTTON_RELEASE:
1574                 switch (event->button.button) {
1575                 case 1:
1576                         dragging = FALSE;
1577                         gnome_canvas_item_ungrab (handle_item,
1578                                                   event->button.time);
1579                         x = x0;
1580                         y = y0;
1581                         dx = (event->button.x - x0);
1582                         dy = (event->button.y - y0);
1583                         gl_label_object_set_position (object, x, y);
1584                         gl_label_object_set_size (object, dx, dy);
1585                         return TRUE;
1586
1587                 default:
1588                         return FALSE;
1589                 }
1590
1591         case GDK_MOTION_NOTIFY:
1592                 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
1593                         x = x0;
1594                         y = y0;
1595                         dx = (event->button.x - x0);
1596                         dy = (event->button.y - y0);
1597                         gl_label_object_set_position (object, x, y);
1598                         gl_label_object_set_size (object, dx, dy);
1599                         return TRUE;
1600                 } else {
1601                         return FALSE;
1602                 }
1603
1604         case GDK_ENTER_NOTIFY:
1605                 cursor = gdk_cursor_new (GDK_CROSSHAIR);
1606                 gdk_window_set_cursor (view->canvas->window, cursor);
1607                 gdk_cursor_unref (cursor);
1608                 return TRUE;
1609
1610         case GDK_LEAVE_NOTIFY:
1611                 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1612                 gdk_window_set_cursor (view->canvas->window, cursor);
1613                 gdk_cursor_unref (cursor);
1614                 return TRUE;
1615
1616         default:
1617                 return FALSE;
1618         }
1619
1620 }
1621
1622 /*---------------------------------------------------------------------------*/
1623 /* PRIVATE.  Passthrough event handler.                                      */
1624 /*---------------------------------------------------------------------------*/
1625 static int
1626 passthrough_event_handler (GnomeCanvasItem * handle_item,
1627                            GdkEvent * event,
1628                            glViewObject *view_object)
1629 {
1630         GnomeCanvasItem *group;
1631
1632         gl_debug (DEBUG_VIEW, "");
1633
1634         group = gl_view_object_get_group (view_object);
1635         return gl_view_item_event_handler (group, event, view_object);
1636
1637 }