2 * (GLABELS) Label and Business Card Creation program for GNOME
4 * view.c: GLabels View module
6 * Copyright (C) 2001-2002 Jim Evins <evins@snaught.com>.
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.
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.
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
26 #include <gtk/gtkinvisible.h>
32 #include "view-object.h"
34 #include "view-ellipse.h"
35 #include "view-line.h"
36 #include "view-image.h"
37 #include "view-text.h"
38 #include "view-barcode.h"
39 #include "xml-label.h"
45 /*==========================================================================*/
46 /* Private macros and constants. */
47 /*==========================================================================*/
49 #define SEL_LINE_COLOR GL_COLOR_A (0, 0, 255, 128)
50 #define SEL_FILL_COLOR GL_COLOR_A (192, 192, 255, 128)
53 /*==========================================================================*/
55 /*==========================================================================*/
66 /*==========================================================================*/
68 /*==========================================================================*/
70 static GtkContainerClass *parent_class;
72 static guint signals[LAST_SIGNAL] = {0};
74 /* "CLIPBOARD" selection */
75 static GdkAtom clipboard_atom = GDK_NONE;
77 #define HOME_SCALE 2.0
78 static gdouble scales[] = {
86 /*==========================================================================*/
87 /* Local function prototypes */
88 /*==========================================================================*/
90 static void gl_view_class_init (glViewClass *class);
91 static void gl_view_init (glView *view);
92 static void gl_view_finalize (GObject *object);
94 static void gl_view_construct (glView *view);
95 static GtkWidget *gl_view_construct_canvas (glView *view);
96 static void gl_view_construct_selection (glView *view);
98 static gdouble get_apropriate_scale (gdouble w, gdouble h);
100 static void draw_bg_fg (glView *view);
101 static void draw_bg_fg_rect (glView *view);
102 static void draw_bg_fg_rounded_rect (glView *view);
103 static void draw_bg_fg_round (glView *view);
104 static void draw_bg_fg_cd (glView *view);
106 static void draw_markup (glView *view);
108 static void draw_markup_margin (glView *view,
109 glTemplateMarkupMargin *margin);
110 static void draw_markup_margin_rect (glView *view,
111 glTemplateMarkupMargin *margin);
112 static void draw_markup_margin_rounded_rect (glView *view,
113 glTemplateMarkupMargin *margin);
114 static void draw_markup_margin_round (glView *view,
115 glTemplateMarkupMargin *margin);
116 static void draw_markup_margin_cd (glView *view,
117 glTemplateMarkupMargin *margin);
120 static void select_object_real (glView *view,
121 glViewObject *view_object);
122 static void unselect_object_real (glView *view,
123 glViewObject *view_object);
125 static gboolean object_at (glView *view,
126 gdouble x, gdouble y);
127 static gboolean is_object_selected (glView *view,
128 glViewObject *view_object);
130 static void move_selection (glView *view,
131 gdouble dx, gdouble dy);
133 static int canvas_event (GnomeCanvas *canvas,
136 static int canvas_event_arrow_mode (GnomeCanvas *canvas,
140 static int item_event_arrow_mode (GnomeCanvasItem *item,
142 glViewObject *view_object);
144 static GtkWidget *new_selection_menu (glView *view);
146 static void popup_selection_menu (glView *view,
147 glViewObject *view_object,
150 static void selection_clear_cb (GtkWidget *widget,
151 GdkEventSelection *event,
154 static void selection_get_cb (GtkWidget *widget,
155 GtkSelectionData *selection_data,
160 static void selection_received_cb (GtkWidget *widget,
161 GtkSelectionData *selection_data,
165 /****************************************************************************/
166 /* Boilerplate Object stuff. */
167 /****************************************************************************/
169 gl_view_get_type (void)
171 static guint view_type = 0;
174 GTypeInfo view_info = {
175 sizeof (glViewClass),
178 (GClassInitFunc) gl_view_class_init,
183 (GInstanceInitFunc) gl_view_init,
187 g_type_register_static (gtk_vbox_get_type (),
188 "glView", &view_info, 0);
195 gl_view_class_init (glViewClass *class)
197 GObjectClass *object_class = (GObjectClass *) class;
199 gl_debug (DEBUG_VIEW, "START");
201 parent_class = g_type_class_peek_parent (class);
203 object_class->finalize = gl_view_finalize;
205 signals[SELECTION_CHANGED] =
206 g_signal_new ("selection_changed",
207 G_OBJECT_CLASS_TYPE (object_class),
209 G_STRUCT_OFFSET (glViewClass, selection_changed),
211 gl_marshal_VOID__VOID,
215 signals[ZOOM_CHANGED] =
216 g_signal_new ("zoom_changed",
217 G_OBJECT_CLASS_TYPE (object_class),
219 G_STRUCT_OFFSET (glViewClass, zoom_changed),
221 gl_marshal_VOID__DOUBLE,
225 signals[POINTER_MOVED] =
226 g_signal_new ("pointer_moved",
227 G_OBJECT_CLASS_TYPE (object_class),
229 G_STRUCT_OFFSET (glViewClass, pointer_moved),
231 gl_marshal_VOID__DOUBLE_DOUBLE,
233 2, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
235 signals[MODE_CHANGED] =
236 g_signal_new ("mode_changed",
237 G_OBJECT_CLASS_TYPE (object_class),
239 G_STRUCT_OFFSET (glViewClass, mode_changed),
241 gl_marshal_VOID__VOID,
245 gl_debug (DEBUG_VIEW, "END");
249 gl_view_init (glView *view)
251 gl_debug (DEBUG_VIEW, "START");
255 gl_debug (DEBUG_VIEW, "END");
259 gl_view_finalize (GObject *object)
263 gl_debug (DEBUG_VIEW, "START");
265 g_return_if_fail (object != NULL);
266 g_return_if_fail (GL_IS_VIEW (object));
268 view = GL_VIEW (object);
270 G_OBJECT_CLASS (parent_class)->finalize (object);
272 gl_debug (DEBUG_VIEW, "END");
275 /****************************************************************************/
276 /* NEW view object. */
277 /****************************************************************************/
279 gl_view_new (glLabel *label)
281 glView *view = g_object_new (gl_view_get_type (), NULL);
283 gl_debug (DEBUG_VIEW, "START");
287 gl_view_construct (view);
289 gl_debug (DEBUG_VIEW, "END");
291 return GTK_WIDGET (view);
294 /*---------------------------------------------------------------------------*/
295 /* PRIVATE. Construct composite widget. */
296 /*---------------------------------------------------------------------------*/
298 gl_view_construct (glView *view)
300 GtkWidget *wvbox, *wscroll;
302 gl_debug (DEBUG_VIEW, "START");
304 g_return_if_fail (GL_IS_VIEW (view));
306 wvbox = GTK_WIDGET (view);
308 view->state = GL_VIEW_STATE_ARROW;
309 view->object_list = NULL;
311 gl_view_construct_canvas (view);
312 wscroll = gtk_scrolled_window_new (NULL, NULL);
313 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (wscroll),
314 GTK_POLICY_AUTOMATIC,
315 GTK_POLICY_AUTOMATIC);
316 gtk_box_pack_start (GTK_BOX (wvbox), wscroll, TRUE, TRUE, 0);
317 gtk_container_add (GTK_CONTAINER (wscroll), view->canvas);
319 gl_view_construct_selection (view);
321 view->menu = new_selection_menu (view);
323 gl_debug (DEBUG_VIEW, "END");
326 /*---------------------------------------------------------------------------*/
327 /* PRIVATE. Create canvas w/ a background in the shape of the label/card. */
328 /*---------------------------------------------------------------------------*/
330 gl_view_construct_canvas (glView *view)
333 glLabel *label = view->label;
334 gdouble label_width, label_height;
336 glLabelObject *object;
337 glViewObject *view_object;
339 gl_debug (DEBUG_VIEW, "START");
341 g_return_val_if_fail (GL_IS_VIEW (view), NULL);
342 g_return_val_if_fail (label != NULL, NULL);
344 gtk_widget_push_colormap (gdk_rgb_get_colormap ());
345 view->canvas = gnome_canvas_new_aa ();
346 gtk_widget_pop_colormap ();
348 gl_label_get_size (label, &label_width, &label_height);
349 gl_debug (DEBUG_VIEW, "Label size: w=%lf, h=%lf",
350 label_width, label_height);
352 scale = get_apropriate_scale (label_width, label_height);
353 gl_debug (DEBUG_VIEW, "scale =%lf", scale);
355 gl_debug (DEBUG_VIEW, "Canvas size: w=%lf, h=%lf",
356 scale * label_width + 40,
357 scale * label_height + 40);
358 gtk_widget_set_size_request (GTK_WIDGET(view->canvas),
359 scale * label_width + 40,
360 scale * label_height + 40);
361 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
365 gnome_canvas_set_scroll_region (GNOME_CANVAS (view->canvas),
366 0.0, 0.0, label_width, label_height);
368 /* Draw background shape of label/card */
370 gl_debug (DEBUG_VIEW, "n_bg_items = %d, n_fg_items = %d",
371 view->n_bg_items, view->n_fg_items);
373 g_signal_connect (G_OBJECT (view->canvas), "event",
374 G_CALLBACK (canvas_event), view);
376 for (p_obj = label->objects; p_obj != NULL; p_obj = p_obj->next) {
377 object = (glLabelObject *) p_obj->data;
379 if (GL_IS_LABEL_BOX (object)) {
380 view_object = gl_view_box_new (GL_LABEL_BOX(object),
382 } else if (GL_IS_LABEL_ELLIPSE (object)) {
383 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object),
385 } else if (GL_IS_LABEL_LINE (object)) {
386 view_object = gl_view_line_new (GL_LABEL_LINE(object),
388 } else if (GL_IS_LABEL_IMAGE (object)) {
389 view_object = gl_view_image_new (GL_LABEL_IMAGE(object),
391 } else if (GL_IS_LABEL_TEXT (object)) {
392 view_object = gl_view_text_new (GL_LABEL_TEXT(object),
394 } else if (GL_IS_LABEL_BARCODE (object)) {
395 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(object),
398 /* Should not happen! */
400 g_warning ("Invalid label object type.");
404 gl_debug (DEBUG_VIEW, "END");
409 /*---------------------------------------------------------------------------*/
410 /* PRIVATE. Create clipboard selection targets. */
411 /*---------------------------------------------------------------------------*/
413 gl_view_construct_selection (glView *view)
415 gl_debug (DEBUG_VIEW, "START");
417 g_return_if_fail (GL_IS_VIEW (view));
419 view->have_selection = FALSE;
420 view->selection_data = NULL;
421 view->invisible = gtk_invisible_new ();
423 view->selected_object_list = NULL;
425 if (!clipboard_atom) {
426 clipboard_atom = gdk_atom_intern ("GLABELS_CLIPBOARD", FALSE);
429 gtk_selection_add_target (view->invisible,
430 clipboard_atom, GDK_SELECTION_TYPE_STRING, 1);
432 g_signal_connect (G_OBJECT (view->invisible),
433 "selection_clear_event",
434 G_CALLBACK (selection_clear_cb), view);
436 g_signal_connect (G_OBJECT (view->invisible), "selection_get",
437 G_CALLBACK (selection_get_cb), view);
439 g_signal_connect (G_OBJECT (view->invisible),
440 "selection_received",
441 G_CALLBACK (selection_received_cb), view);
443 gl_debug (DEBUG_VIEW, "END");
446 /*---------------------------------------------------------------------------*/
447 /* PRIVATE. Determine an apropriate scale for given label & screen size */
448 /*---------------------------------------------------------------------------*/
450 get_apropriate_scale (gdouble w, gdouble h)
452 gdouble w_screen, h_screen;
456 gl_debug (DEBUG_VIEW, "");
458 w_screen = (gdouble) gdk_screen_width ();
459 h_screen = (gdouble) gdk_screen_height ();
461 for (i = 0; scales[i] > 0.0; i++) {
463 if (k <= HOME_SCALE) {
464 if ((k * w < (w_screen - 256))
465 && (k * h < (h_screen - 256)))
473 /*---------------------------------------------------------------------------*/
474 /* PRIVATE. Draw background and foreground outlines. */
475 /*---------------------------------------------------------------------------*/
477 draw_bg_fg (glView *view)
480 glTemplate *template;
482 view->n_bg_items = 0;
483 view->bg_item_list = NULL;
484 view->n_fg_items = 0;
485 view->fg_item_list = NULL;
488 template = gl_label_get_template (label);
490 switch (template->label.style) {
492 case GL_TEMPLATE_STYLE_RECT:
493 if (template->label.rect.r == 0.0) {
494 /* Square corners. */
495 draw_bg_fg_rect (view);
497 /* Rounded corners. */
498 draw_bg_fg_rounded_rect (view);
502 case GL_TEMPLATE_STYLE_ROUND:
503 draw_bg_fg_round (view);
506 case GL_TEMPLATE_STYLE_CD:
507 draw_bg_fg_cd (view);
511 g_warning ("Unknown template label style");
516 /*---------------------------------------------------------------------------*/
517 /* PRIVATE. Draw simple recangular background. */
518 /*---------------------------------------------------------------------------*/
520 draw_bg_fg_rect (glView *view)
522 glLabel *label = view->label;
523 glTemplate *template;
525 GnomeCanvasItem *item;
526 GnomeCanvasGroup *group;
528 gl_debug (DEBUG_VIEW, "START");
530 g_return_if_fail (GL_IS_VIEW (view));
531 g_return_if_fail (label != NULL);
533 gl_label_get_size (label, &w, &h);
534 template = gl_label_get_template (label);
536 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
539 item = gnome_canvas_item_new (group,
540 gnome_canvas_rect_get_type (),
545 "fill_color", "white",
548 view->bg_item_list = g_list_append (view->bg_item_list, item);
554 item = gnome_canvas_item_new (group,
555 gnome_canvas_rect_get_type (),
561 "outline_color", "light blue",
564 view->fg_item_list = g_list_append (view->fg_item_list, item);
566 gl_debug (DEBUG_VIEW, "END");
569 /*---------------------------------------------------------------------------*/
570 /* PRIVATE. Draw rounded recangular background. */
571 /*---------------------------------------------------------------------------*/
573 draw_bg_fg_rounded_rect (glView *view)
575 glLabel *label = view->label;
576 GnomeCanvasPoints *points;
577 gint i_coords, i_theta;
578 glTemplate *template;
580 GnomeCanvasItem *item;
581 GnomeCanvasGroup *group;
583 gl_debug (DEBUG_VIEW, "START");
585 g_return_if_fail (GL_IS_VIEW (view));
586 g_return_if_fail (label != NULL);
588 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
590 gl_label_get_size (label, &w, &h);
591 template = gl_label_get_template (label);
592 r = template->label.rect.r;
594 points = gnome_canvas_points_new (4 * (1 + 90 / 5));
596 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
597 points->coords[i_coords++] =
598 r - r * sin (i_theta * M_PI / 180.0);
599 points->coords[i_coords++] =
600 r - r * cos (i_theta * M_PI / 180.0);
602 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
603 points->coords[i_coords++] =
604 r - r * cos (i_theta * M_PI / 180.0);
605 points->coords[i_coords++] =
606 (h - r) + r * sin (i_theta * M_PI / 180.0);
608 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
609 points->coords[i_coords++] =
610 (w - r) + r * sin (i_theta * M_PI / 180.0);
611 points->coords[i_coords++] =
612 (h - r) + r * cos (i_theta * M_PI / 180.0);
614 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
615 points->coords[i_coords++] =
616 (w - r) + r * cos (i_theta * M_PI / 180.0);
617 points->coords[i_coords++] =
618 r - r * sin (i_theta * M_PI / 180.0);
622 item = gnome_canvas_item_new (group,
623 gnome_canvas_polygon_get_type (),
625 "fill_color", "white",
628 view->bg_item_list = g_list_append (view->bg_item_list, item);
634 item = gnome_canvas_item_new (group,
635 gnome_canvas_polygon_get_type (),
638 "outline_color", "light blue",
641 view->fg_item_list = g_list_append (view->fg_item_list, item);
643 gnome_canvas_points_free (points);
645 gl_debug (DEBUG_VIEW, "END");
648 /*---------------------------------------------------------------------------*/
649 /* PRIVATE. Draw round background. */
650 /*---------------------------------------------------------------------------*/
652 draw_bg_fg_round (glView *view)
654 glLabel *label = view->label;
655 glTemplate *template;
657 GnomeCanvasItem *item;
658 GnomeCanvasGroup *group;
660 gl_debug (DEBUG_VIEW, "START");
662 g_return_if_fail (GL_IS_VIEW (view));
663 g_return_if_fail (label != NULL);
665 template = gl_label_get_template (label);
667 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
669 r = template->label.round.r;
672 item = gnome_canvas_item_new (group,
673 gnome_canvas_ellipse_get_type (),
678 "fill_color", "white",
681 view->bg_item_list = g_list_append (view->bg_item_list, item);
687 item = gnome_canvas_item_new (group,
688 gnome_canvas_ellipse_get_type (),
694 "outline_color", "light blue",
697 view->fg_item_list = g_list_append (view->fg_item_list, item);
699 gl_debug (DEBUG_VIEW, "END");
702 /*---------------------------------------------------------------------------*/
703 /* PRIVATE. Draw CD style background, circular w/ concentric hole. */
704 /*---------------------------------------------------------------------------*/
706 draw_bg_fg_cd (glView *view)
708 glLabel *label = view->label;
709 glTemplate *template;
711 GnomeCanvasItem *item;
712 GnomeCanvasGroup *group;
714 gl_debug (DEBUG_VIEW, "START");
716 g_return_if_fail (GL_IS_VIEW (view));
717 g_return_if_fail (label != NULL);
719 template = gl_label_get_template (label);
721 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
723 r1 = template->label.cd.r1;
724 r2 = template->label.cd.r2;
728 item = gnome_canvas_item_new (group,
729 gnome_canvas_ellipse_get_type (),
734 "fill_color", "white",
737 view->bg_item_list = g_list_append (view->bg_item_list, item);
739 item = gnome_canvas_item_new (group,
740 gnome_canvas_ellipse_get_type (),
745 "fill_color", "gray",
748 view->bg_item_list = g_list_append (view->bg_item_list, item);
755 item = gnome_canvas_item_new (group,
756 gnome_canvas_ellipse_get_type (),
762 "outline_color", "light blue",
765 view->fg_item_list = g_list_append (view->fg_item_list, item);
767 item = gnome_canvas_item_new (group,
768 gnome_canvas_ellipse_get_type (),
774 "outline_color", "light blue",
777 view->fg_item_list = g_list_append (view->fg_item_list, item);
779 gl_debug (DEBUG_VIEW, "END");
782 /*---------------------------------------------------------------------------*/
783 /* PRIVATE. Draw markup lines. */
784 /*---------------------------------------------------------------------------*/
786 draw_markup (glView *view)
789 glTemplate *template;
791 glTemplateMarkup *markup;
794 template = gl_label_get_template (label);
796 for ( p=template->label.any.markups; p != NULL; p=p->next ) {
797 markup = (glTemplateMarkup *)p->data;
799 switch (markup->type) {
800 case GL_TEMPLATE_MARKUP_MARGIN:
801 draw_markup_margin (view,
802 (glTemplateMarkupMargin *)markup);
805 g_warning ("Unknown template markup type");
811 /*---------------------------------------------------------------------------*/
812 /* PRIVATE. Draw margin markup. */
813 /*---------------------------------------------------------------------------*/
815 draw_markup_margin (glView *view,
816 glTemplateMarkupMargin *margin)
819 glTemplate *template;
822 template = gl_label_get_template (label);
824 switch (template->label.style) {
826 case GL_TEMPLATE_STYLE_RECT:
827 if (template->label.rect.r == 0.0) {
828 /* Square corners. */
829 draw_markup_margin_rect (view, margin);
831 if ( margin->size < template->label.rect.r) {
832 /* Rounded corners. */
833 draw_markup_margin_rounded_rect (view, margin);
835 /* Square corners. */
836 draw_markup_margin_rect (view, margin);
841 case GL_TEMPLATE_STYLE_ROUND:
842 draw_markup_margin_round (view, margin);
845 case GL_TEMPLATE_STYLE_CD:
846 draw_markup_margin_cd (view, margin);
850 g_warning ("Unknown template label style");
855 /*---------------------------------------------------------------------------*/
856 /* PRIVATE. Draw simple recangular margin. */
857 /*---------------------------------------------------------------------------*/
859 draw_markup_margin_rect (glView *view,
860 glTemplateMarkupMargin *margin)
862 glLabel *label = view->label;
863 glTemplate *template;
865 GnomeCanvasItem *item;
866 GnomeCanvasGroup *group;
868 gl_debug (DEBUG_VIEW, "START");
870 g_return_if_fail (GL_IS_VIEW (view));
871 g_return_if_fail (label != NULL);
873 gl_label_get_size (label, &w, &h);
874 template = gl_label_get_template (label);
877 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
879 /* Bounding box @ margin */
880 gnome_canvas_item_new (group,
881 gnome_canvas_rect_get_type (),
887 "outline_color", "light blue",
890 view->bg_item_list = g_list_append (view->bg_item_list, item);
892 gl_debug (DEBUG_VIEW, "END");
895 /*---------------------------------------------------------------------------*/
896 /* PRIVATE. Draw rounded recangular markup. */
897 /*---------------------------------------------------------------------------*/
899 draw_markup_margin_rounded_rect (glView *view,
900 glTemplateMarkupMargin *margin)
902 glLabel *label = view->label;
903 GnomeCanvasPoints *points;
904 gint i_coords, i_theta;
905 glTemplate *template;
907 GnomeCanvasItem *item;
908 GnomeCanvasGroup *group;
910 gl_debug (DEBUG_VIEW, "START");
912 g_return_if_fail (GL_IS_VIEW (view));
913 g_return_if_fail (label != NULL);
915 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
917 gl_label_get_size (label, &w, &h);
918 template = gl_label_get_template (label);
919 r = template->label.rect.r;
926 /* rectangle with rounded corners */
927 points = gnome_canvas_points_new (4 * (1 + 90 / 5));
929 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
930 points->coords[i_coords++] =
931 m + r - r * sin (i_theta * M_PI / 180.0);
932 points->coords[i_coords++] =
933 m + r - r * cos (i_theta * M_PI / 180.0);
935 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
936 points->coords[i_coords++] =
937 m + r - r * cos (i_theta * M_PI / 180.0);
938 points->coords[i_coords++] =
939 m + (h - r) + r * sin (i_theta * M_PI / 180.0);
941 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
942 points->coords[i_coords++] =
943 m + (w - r) + r * sin (i_theta * M_PI / 180.0);
944 points->coords[i_coords++] =
945 m + (h - r) + r * cos (i_theta * M_PI / 180.0);
947 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
948 points->coords[i_coords++] =
949 m + (w - r) + r * cos (i_theta * M_PI / 180.0);
950 points->coords[i_coords++] =
951 m + r - r * sin (i_theta * M_PI / 180.0);
953 item = gnome_canvas_item_new (group,
954 gnome_canvas_polygon_get_type (),
957 "outline_color", "light blue",
959 gnome_canvas_points_free (points);
961 view->bg_item_list = g_list_append (view->bg_item_list, item);
963 gl_debug (DEBUG_VIEW, "END");
966 /*---------------------------------------------------------------------------*/
967 /* PRIVATE. Draw round margin. */
968 /*---------------------------------------------------------------------------*/
970 draw_markup_margin_round (glView *view,
971 glTemplateMarkupMargin *margin)
973 glLabel *label = view->label;
974 glTemplate *template;
976 GnomeCanvasItem *item;
977 GnomeCanvasGroup *group;
979 gl_debug (DEBUG_VIEW, "START");
981 g_return_if_fail (GL_IS_VIEW (view));
982 g_return_if_fail (label != NULL);
984 template = gl_label_get_template (label);
986 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
988 r = template->label.round.r;
992 item = gnome_canvas_item_new (group,
993 gnome_canvas_ellipse_get_type (),
999 "outline_color", "light blue", NULL);
1001 view->bg_item_list = g_list_append (view->bg_item_list, item);
1003 gl_debug (DEBUG_VIEW, "END");
1006 /*---------------------------------------------------------------------------*/
1007 /* PRIVATE. Draw CD margins. */
1008 /*---------------------------------------------------------------------------*/
1010 draw_markup_margin_cd (glView *view,
1011 glTemplateMarkupMargin *margin)
1013 glLabel *label = view->label;
1014 glTemplate *template;
1016 GnomeCanvasItem *item;
1017 GnomeCanvasGroup *group;
1019 gl_debug (DEBUG_VIEW, "START");
1021 g_return_if_fail (GL_IS_VIEW (view));
1022 g_return_if_fail (label != NULL);
1024 template = gl_label_get_template (label);
1026 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
1028 r1 = template->label.cd.r1;
1029 r2 = template->label.cd.r2;
1033 item = gnome_canvas_item_new (group,
1034 gnome_canvas_ellipse_get_type (),
1040 "outline_color", "light blue", NULL);
1042 view->bg_item_list = g_list_append (view->bg_item_list, item);
1044 item = gnome_canvas_item_new (group,
1045 gnome_canvas_ellipse_get_type (),
1051 "outline_color", "light blue",
1054 view->bg_item_list = g_list_append (view->bg_item_list, item);
1056 gl_debug (DEBUG_VIEW, "END");
1059 /*****************************************************************************/
1060 /* Raise foreground items to top. */
1061 /*****************************************************************************/
1063 gl_view_raise_fg (glView *view)
1067 for (p = view->fg_item_list; p != NULL; p = p->next) {
1068 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(p->data));
1072 /*****************************************************************************/
1073 /* Set arrow mode. */
1074 /*****************************************************************************/
1076 gl_view_arrow_mode (glView *view)
1078 static GdkCursor *cursor = NULL;
1080 gl_debug (DEBUG_VIEW, "START");
1082 g_return_if_fail (GL_IS_VIEW (view));
1085 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1088 gdk_window_set_cursor (view->canvas->window, cursor);
1090 view->state = GL_VIEW_STATE_ARROW;
1092 gl_debug (DEBUG_VIEW, "END");
1095 /*****************************************************************************/
1096 /* Set create text object mode. */
1097 /*****************************************************************************/
1099 gl_view_object_create_mode (glView *view,
1100 glLabelObjectType type)
1104 gl_debug (DEBUG_VIEW, "START");
1106 g_return_if_fail (GL_IS_VIEW (view));
1109 case GL_LABEL_OBJECT_BOX:
1110 cursor = gl_view_box_get_create_cursor ();
1112 case GL_LABEL_OBJECT_ELLIPSE:
1113 cursor = gl_view_ellipse_get_create_cursor ();
1115 case GL_LABEL_OBJECT_LINE:
1116 cursor = gl_view_line_get_create_cursor ();
1118 case GL_LABEL_OBJECT_IMAGE:
1119 cursor = gl_view_image_get_create_cursor ();
1121 case GL_LABEL_OBJECT_TEXT:
1122 cursor = gl_view_text_get_create_cursor ();
1124 case GL_LABEL_OBJECT_BARCODE:
1125 cursor = gl_view_barcode_get_create_cursor ();
1128 g_warning ("Invalid label object type.");/*Should not happen!*/
1132 gdk_window_set_cursor (view->canvas->window, cursor);
1134 view->state = GL_VIEW_STATE_OBJECT_CREATE;
1135 view->create_type = type;
1137 gl_debug (DEBUG_VIEW, "END");
1140 /*****************************************************************************/
1141 /* Select given object (adding to current selection). */
1142 /*****************************************************************************/
1144 gl_view_select_object (glView *view,
1145 glViewObject *view_object)
1147 gl_debug (DEBUG_VIEW, "START");
1149 select_object_real (view, view_object);
1151 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1153 gl_debug (DEBUG_VIEW, "END");
1156 /*****************************************************************************/
1157 /* Unselect given object (removing from current selection). */
1158 /*****************************************************************************/
1160 gl_view_unselect_object (glView *view,
1161 glViewObject *view_object)
1163 gl_debug (DEBUG_VIEW, "START");
1165 unselect_object_real (view, view_object);
1167 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1169 gl_debug (DEBUG_VIEW, "END");
1172 /*****************************************************************************/
1173 /* Select all items. */
1174 /*****************************************************************************/
1176 gl_view_select_all (glView *view)
1180 gl_debug (DEBUG_VIEW, "START");
1182 g_return_if_fail (GL_IS_VIEW (view));
1184 /* 1st unselect anything already selected. */
1185 for (p = view->selected_object_list; p != NULL; p = p_next) {
1187 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1190 /* Finally select all objects. */
1191 for (p = view->object_list; p != NULL; p = p->next) {
1192 select_object_real (view, GL_VIEW_OBJECT (p->data));
1195 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1197 gl_debug (DEBUG_VIEW, "END");
1200 /*****************************************************************************/
1201 /* Remove all selections */
1202 /*****************************************************************************/
1204 gl_view_unselect_all (glView *view)
1208 gl_debug (DEBUG_VIEW, "START");
1210 g_return_if_fail (GL_IS_VIEW (view));
1212 for (p = view->selected_object_list; p != NULL; p = p_next) {
1214 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1217 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1219 gl_debug (DEBUG_VIEW, "END");
1222 /*****************************************************************************/
1223 /* Select all objects within given rectangular region (adding to selection). */
1224 /*****************************************************************************/
1226 gl_view_select_region (glView *view,
1233 glViewObject *view_object;
1234 glLabelObject *object;
1235 gdouble i_x1, i_y1, i_x2, i_y2, w, h;
1237 gl_debug (DEBUG_VIEW, "START");
1239 g_return_if_fail (GL_IS_VIEW (view));
1240 g_return_if_fail ((x1 <= x2) && (y1 <= y2));
1242 for (p = view->object_list; p != NULL; p = p->next) {
1243 view_object = GL_VIEW_OBJECT(p->data);
1244 if (!is_object_selected (view, view_object)) {
1246 object = gl_view_object_get_object (view_object);
1248 gl_label_object_get_position (object, &i_x1, &i_y1);
1249 gl_label_object_get_size (object, &w, &h);
1252 if ((i_x1 >= x1) && (i_x2 <= x2) && (i_y1 >= y1)
1254 select_object_real (view, view_object);
1260 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1262 gl_debug (DEBUG_VIEW, "END");
1265 /*---------------------------------------------------------------------------*/
1266 /* PRIVATE. Select an object. */
1267 /*---------------------------------------------------------------------------*/
1269 select_object_real (glView *view,
1270 glViewObject *view_object)
1272 gl_debug (DEBUG_VIEW, "START");
1274 g_return_if_fail (GL_IS_VIEW (view));
1275 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1277 if (!is_object_selected (view, view_object)) {
1278 view->selected_object_list =
1279 g_list_prepend (view->selected_object_list, view_object);
1281 gl_view_object_show_highlight (view_object);
1282 gtk_widget_grab_focus (GTK_WIDGET (view->canvas));
1284 gl_debug (DEBUG_VIEW, "END");
1287 /*---------------------------------------------------------------------------*/
1288 /* PRIVATE. Un-select object. */
1289 /*---------------------------------------------------------------------------*/
1291 unselect_object_real (glView *view,
1292 glViewObject *view_object)
1294 gl_debug (DEBUG_VIEW, "START");
1296 g_return_if_fail (GL_IS_VIEW (view));
1297 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1299 gl_view_object_hide_highlight (view_object);
1301 view->selected_object_list =
1302 g_list_remove (view->selected_object_list, view_object);
1304 gl_debug (DEBUG_VIEW, "END");
1307 /*---------------------------------------------------------------------------*/
1308 /* PRIVATE. Return object at (x,y). */
1309 /*---------------------------------------------------------------------------*/
1311 object_at (glView *view,
1315 GnomeCanvasItem *item, *p_item;
1318 gl_debug (DEBUG_VIEW, "");
1320 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1322 item = gnome_canvas_get_item_at (GNOME_CANVAS (view->canvas), x, y);
1324 /* No item is at x, y */
1328 /* ignore our background items */
1329 if (g_list_find (view->bg_item_list, item) != NULL)
1335 /*---------------------------------------------------------------------------*/
1336 /* PRIVATE. Is the object in our current selection? */
1337 /*---------------------------------------------------------------------------*/
1339 is_object_selected (glView *view,
1340 glViewObject *view_object)
1342 gl_debug (DEBUG_VIEW, "");
1344 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1345 g_return_val_if_fail (GL_IS_VIEW_OBJECT (view_object), FALSE);
1347 if (g_list_find (view->selected_object_list, view_object) == NULL) {
1353 /*****************************************************************************/
1354 /* Is our current selection empty? */
1355 /*****************************************************************************/
1357 gl_view_is_selection_empty (glView *view)
1359 gl_debug (DEBUG_VIEW, "");
1361 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1363 if (view->selected_object_list == NULL) {
1370 /*****************************************************************************/
1371 /* Is our current selection atomic? I.e. only one item selected. */
1372 /*****************************************************************************/
1374 gl_view_is_selection_atomic (glView *view)
1376 gl_debug (DEBUG_VIEW, "");
1378 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1380 if (view->selected_object_list == NULL)
1382 if (view->selected_object_list->next == NULL)
1387 /*****************************************************************************/
1388 /* Delete selected objects. (Bypass clipboard) */
1389 /*****************************************************************************/
1391 gl_view_delete_selection (glView *view)
1395 gl_debug (DEBUG_VIEW, "START");
1397 g_return_if_fail (GL_IS_VIEW (view));
1399 for (p = view->selected_object_list; p != NULL; p = p_next) {
1401 g_object_unref (G_OBJECT (p->data));
1404 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1406 gl_debug (DEBUG_VIEW, "END");
1409 /*****************************************************************************/
1410 /* Edit properties of selected object. */
1411 /*****************************************************************************/
1413 gl_view_edit_object_props (glView *view)
1415 glViewObject *view_object;
1417 gl_debug (DEBUG_VIEW, "START");
1419 g_return_if_fail (GL_IS_VIEW (view));
1421 if (gl_view_is_selection_atomic (view)) {
1423 view_object = GL_VIEW_OBJECT(view->selected_object_list->data);
1424 gl_view_object_show_dialog (view_object);
1428 gl_debug (DEBUG_VIEW, "END");
1431 /*****************************************************************************/
1432 /* Raise selected items to top. */
1433 /*****************************************************************************/
1435 gl_view_raise_selection (glView *view)
1438 glViewObject *view_object;
1439 glLabelObject *label_object;
1441 gl_debug (DEBUG_VIEW, "START");
1443 g_return_if_fail (GL_IS_VIEW (view));
1445 for (p = view->selected_object_list; p != NULL; p = p->next) {
1446 view_object = GL_VIEW_OBJECT (p->data);
1447 label_object = gl_view_object_get_object (view_object);
1448 gl_label_object_raise_to_top (label_object);
1451 gl_debug (DEBUG_VIEW, "END");
1454 /*****************************************************************************/
1455 /* Lower selected items to bottom. */
1456 /*****************************************************************************/
1458 gl_view_lower_selection (glView *view)
1461 glViewObject *view_object;
1462 glLabelObject *label_object;
1464 gl_debug (DEBUG_VIEW, "START");
1466 g_return_if_fail (GL_IS_VIEW (view));
1468 for (p = view->selected_object_list; p != NULL; p = p->next) {
1469 view_object = GL_VIEW_OBJECT (p->data);
1470 label_object = gl_view_object_get_object (view_object);
1471 gl_label_object_lower_to_bottom (label_object);
1474 gl_debug (DEBUG_VIEW, "END");
1477 /*****************************************************************************/
1478 /* "Cut" selected items and place in clipboard selections. */
1479 /*****************************************************************************/
1481 gl_view_cut (glView *view)
1483 gl_debug (DEBUG_VIEW, "START");
1485 g_return_if_fail (GL_IS_VIEW (view));
1487 gl_view_copy (view);
1488 gl_view_delete_selection (view);
1490 gl_debug (DEBUG_VIEW, "END");
1493 /*****************************************************************************/
1494 /* "Copy" selected items to clipboard selections. */
1495 /*****************************************************************************/
1497 gl_view_copy (glView *view)
1500 glViewObject *view_object;
1501 glLabelObject *object;
1502 glTemplate *template;
1503 gboolean rotate_flag;
1505 gl_debug (DEBUG_VIEW, "START");
1507 g_return_if_fail (GL_IS_VIEW (view));
1509 if (view->selected_object_list) {
1511 if ( view->selection_data ) {
1512 g_object_unref (view->selection_data);
1514 template = gl_label_get_template (view->label);
1515 rotate_flag = gl_label_get_rotate_flag (view->label);
1516 view->selection_data = GL_LABEL(gl_label_new ());
1517 gl_label_set_template (view->selection_data, template);
1518 gl_label_set_rotate_flag (view->selection_data, rotate_flag);
1519 gl_template_free (&template);
1521 for (p = view->selected_object_list; p != NULL; p = p->next) {
1523 view_object = GL_VIEW_OBJECT (p->data);
1524 object = gl_view_object_get_object (view_object);
1526 gl_debug (DEBUG_VIEW, "Object copied");
1528 if (GL_IS_LABEL_BOX (object)) {
1529 gl_label_box_dup (GL_LABEL_BOX(object),
1530 view->selection_data);
1531 } else if (GL_IS_LABEL_ELLIPSE (object)) {
1532 gl_label_ellipse_dup (GL_LABEL_ELLIPSE(object),
1533 view->selection_data);
1534 } else if (GL_IS_LABEL_LINE (object)) {
1535 gl_label_line_dup (GL_LABEL_LINE(object),
1536 view->selection_data);
1537 } else if (GL_IS_LABEL_IMAGE (object)) {
1538 gl_label_image_dup (GL_LABEL_IMAGE(object),
1539 view->selection_data);
1540 } else if (GL_IS_LABEL_TEXT (object)) {
1541 gl_label_text_dup (GL_LABEL_TEXT(object),
1542 view->selection_data);
1543 } else if (GL_IS_LABEL_BARCODE (object)) {
1544 gl_label_barcode_dup (GL_LABEL_BARCODE(object),
1545 view->selection_data);
1547 /* Should not happen! */
1548 g_warning ("Invalid label object type.");
1554 gtk_selection_owner_set (view->invisible,
1555 clipboard_atom, GDK_CURRENT_TIME);
1556 view->have_selection = TRUE;
1560 gl_debug (DEBUG_VIEW, "END");
1563 /*****************************************************************************/
1564 /* "Paste" from private clipboard selection. */
1565 /*****************************************************************************/
1567 gl_view_paste (glView *view)
1569 gl_debug (DEBUG_VIEW, "START");
1571 g_return_if_fail (GL_IS_VIEW (view));
1573 gtk_selection_convert (GTK_WIDGET (view->invisible),
1574 clipboard_atom, GDK_SELECTION_TYPE_STRING,
1577 gl_debug (DEBUG_VIEW, "END");
1580 /*---------------------------------------------------------------------------*/
1581 /* PRIVATE. move selected objects */
1582 /*---------------------------------------------------------------------------*/
1584 move_selection (glView *view,
1589 glLabelObject *object;
1591 gl_debug (DEBUG_VIEW, "START");
1593 g_return_if_fail (GL_IS_VIEW (view));
1595 for (p = view->selected_object_list; p != NULL; p = p->next) {
1597 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
1598 gl_label_object_set_position_relative (object, dx, dy);
1602 gl_debug (DEBUG_VIEW, "END");
1605 /*****************************************************************************/
1606 /* Zoom in one "notch" */
1607 /*****************************************************************************/
1609 gl_view_zoom_in (glView *view)
1612 gdouble dist, dist_min;
1614 gl_debug (DEBUG_VIEW, "START");
1616 g_return_if_fail (GL_IS_VIEW (view));
1618 /* Find index of current scale (or best match) */
1619 i_min = 1; /* start with 2nd largest scale */
1620 dist_min = fabs (scales[1] - view->scale);
1621 for (i = 2; scales[i] != 0.0; i++) {
1622 dist = fabs (scales[i] - view->scale);
1623 if (dist < dist_min) {
1629 /* zoom in one "notch" */
1630 i = MAX (0, i_min - 1);
1631 gl_view_set_zoom (view, scales[i] / HOME_SCALE);
1633 gl_debug (DEBUG_VIEW, "END");
1636 /*****************************************************************************/
1637 /* Zoom out one "notch" */
1638 /*****************************************************************************/
1640 gl_view_zoom_out (glView *view)
1643 gdouble dist, dist_min;
1645 gl_debug (DEBUG_VIEW, "START");
1647 g_return_if_fail (GL_IS_VIEW (view));
1649 /* Find index of current scale (or best match) */
1650 i_min = 0; /* start with largest scale */
1651 dist_min = fabs (scales[0] - view->scale);
1652 for (i = 1; scales[i] != 0.0; i++) {
1653 dist = fabs (scales[i] - view->scale);
1654 if (dist < dist_min) {
1660 /* zoom out one "notch" */
1661 if (scales[i_min] == 0.0)
1664 if (scales[i] == 0.0)
1666 gl_view_set_zoom (view, scales[i] / HOME_SCALE);
1668 gl_debug (DEBUG_VIEW, "END");
1671 /*****************************************************************************/
1672 /* Set current zoom factor to explicit value. */
1673 /*****************************************************************************/
1675 gl_view_set_zoom (glView *view,
1678 gl_debug (DEBUG_VIEW, "START");
1680 g_return_if_fail (GL_IS_VIEW (view));
1681 g_return_if_fail (scale > 0.0);
1683 view->scale = scale * HOME_SCALE;
1684 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
1685 scale * HOME_SCALE);
1687 g_signal_emit (G_OBJECT(view), signals[ZOOM_CHANGED], 0, scale);
1689 gl_debug (DEBUG_VIEW, "END");
1692 /*****************************************************************************/
1693 /* Get current zoom factor. */
1694 /*****************************************************************************/
1696 gl_view_get_zoom (glView *view)
1698 gl_debug (DEBUG_VIEW, "");
1700 g_return_val_if_fail (GL_IS_VIEW (view), 1.0);
1702 return view->scale / HOME_SCALE;
1705 /*---------------------------------------------------------------------------*/
1706 /* PRIVATE. Canvas event handler. */
1707 /*---------------------------------------------------------------------------*/
1709 canvas_event (GnomeCanvas *canvas,
1713 gl_debug (DEBUG_VIEW, "");
1715 switch (view->state) {
1717 case GL_VIEW_STATE_ARROW:
1718 return canvas_event_arrow_mode (canvas, event, view);
1720 case GL_VIEW_STATE_OBJECT_CREATE:
1721 switch (view->create_type) {
1722 case GL_LABEL_OBJECT_BOX:
1723 return gl_view_box_create_event_handler (canvas,
1727 case GL_LABEL_OBJECT_ELLIPSE:
1728 return gl_view_ellipse_create_event_handler (canvas,
1732 case GL_LABEL_OBJECT_LINE:
1733 return gl_view_line_create_event_handler (canvas,
1737 case GL_LABEL_OBJECT_IMAGE:
1738 return gl_view_image_create_event_handler (canvas,
1742 case GL_LABEL_OBJECT_TEXT:
1743 return gl_view_text_create_event_handler (canvas,
1747 case GL_LABEL_OBJECT_BARCODE:
1748 return gl_view_barcode_create_event_handler (canvas,
1753 /*Should not happen!*/
1754 g_warning ("Invalid label object type.");
1759 g_warning ("Invalid view state."); /*Should not happen!*/
1765 /*---------------------------------------------------------------------------*/
1766 /* PRIVATE. Canvas event handler (arrow mode) */
1767 /*---------------------------------------------------------------------------*/
1769 canvas_event_arrow_mode (GnomeCanvas *canvas,
1773 static gdouble x0, y0;
1774 static gboolean dragging = FALSE;
1775 static GnomeCanvasItem *item;
1776 gdouble x, y, x1, y1, x2, y2;
1777 GnomeCanvasGroup *group;
1780 gl_debug (DEBUG_VIEW, "");
1782 switch (event->type) {
1784 case GDK_BUTTON_PRESS:
1785 gl_debug (DEBUG_VIEW, "BUTTON_PRESS");
1786 switch (event->button.button) {
1788 gnome_canvas_window_to_world (canvas,
1790 event->button.y, &x, &y);
1792 if (!object_at (view, x, y)) {
1793 if (!(event->button.state & GDK_CONTROL_MASK)) {
1794 gl_view_unselect_all (view);
1798 gdk_pointer_grab (GTK_WIDGET (view->canvas)->
1800 GDK_POINTER_MOTION_MASK |
1801 GDK_BUTTON_RELEASE_MASK |
1802 GDK_BUTTON_PRESS_MASK, NULL,
1803 NULL, event->button.time);
1805 gnome_canvas_root (GNOME_CANVAS
1808 gnome_canvas_item_new (group,
1809 gnome_canvas_rect_get_type (),
1813 "outline_color_rgba",
1828 case GDK_BUTTON_RELEASE:
1829 gl_debug (DEBUG_VIEW, "BUTTON_RELEASE");
1830 switch (event->button.button) {
1834 gdk_pointer_ungrab (event->button.time);
1835 gnome_canvas_window_to_world (canvas,
1843 gl_view_select_region (view, x1, y1, x2, y2);
1844 gtk_object_destroy (GTK_OBJECT (item));
1853 case GDK_MOTION_NOTIFY:
1854 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
1855 gnome_canvas_window_to_world (canvas,
1857 event->motion.y, &x, &y);
1858 g_signal_emit (G_OBJECT(view), signals[POINTER_MOVED], 0, x, y);
1859 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
1860 gnome_canvas_item_set (item,
1864 "y2", MAX (y, y0), NULL);
1871 gl_debug (DEBUG_VIEW, "KEY_PRESS");
1873 switch (event->key.keyval) {
1876 move_selection (view,
1877 -1.0 / (view->scale), 0.0);
1881 move_selection (view,
1882 0.0, -1.0 / (view->scale));
1886 move_selection (view,
1887 1.0 / (view->scale), 0.0);
1891 move_selection (view,
1892 0.0, 1.0 / (view->scale));
1896 gl_view_delete_selection (view);
1897 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1898 gdk_window_set_cursor (view->canvas->window,
1900 gdk_cursor_unref (cursor);
1906 return TRUE; /* We handled this or we were dragging. */
1909 gl_debug (DEBUG_VIEW, "default");
1915 /*****************************************************************************/
1916 /* Item event handler. */
1917 /*****************************************************************************/
1919 gl_view_item_event_handler (GnomeCanvasItem *item,
1921 glViewObject *view_object)
1925 gl_debug (DEBUG_VIEW, "");
1927 view = gl_view_object_get_view(view_object);
1928 switch (view->state) {
1930 case GL_VIEW_STATE_ARROW:
1931 return item_event_arrow_mode (item, event, view_object);
1940 /*---------------------------------------------------------------------------*/
1941 /* PRIVATE. Item event handler (arrow mode) */
1942 /*---------------------------------------------------------------------------*/
1944 item_event_arrow_mode (GnomeCanvasItem *item,
1946 glViewObject *view_object)
1948 static gdouble x, y;
1949 static gboolean dragging = FALSE;
1952 gdouble item_x, item_y;
1953 gdouble new_x, new_y;
1954 gboolean control_key_pressed;
1956 gl_debug (DEBUG_VIEW, "");
1958 item_x = event->button.x;
1959 item_y = event->button.y;
1960 gnome_canvas_item_w2i (item->parent, &item_x, &item_y);
1962 view = gl_view_object_get_view(view_object);
1964 switch (event->type) {
1966 case GDK_BUTTON_PRESS:
1967 gl_debug (DEBUG_VIEW, "BUTTON_PRESS");
1968 control_key_pressed = event->button.state & GDK_CONTROL_MASK;
1969 switch (event->button.button) {
1971 if (control_key_pressed) {
1972 if (is_object_selected (view, view_object)) {
1973 /* Un-selecting a selected item */
1974 gl_view_unselect_object (view,
1978 /* Add to current selection */
1979 gl_view_select_object (view,
1983 if (!is_object_selected (view, view_object)) {
1984 /* No control, key so remove any selections before adding */
1985 gl_view_unselect_all (view);
1986 /* Add to current selection */
1987 gl_view_select_object (view,
1991 /* Go into dragging mode while button remains pressed. */
1994 cursor = gdk_cursor_new (GDK_FLEUR);
1995 gnome_canvas_item_grab (item,
1996 GDK_POINTER_MOTION_MASK |
1997 GDK_BUTTON_RELEASE_MASK |
1998 GDK_BUTTON_PRESS_MASK,
1999 cursor, event->button.time);
2000 gdk_cursor_unref (cursor);
2005 if (!is_object_selected (view, view_object)) {
2006 if (!control_key_pressed) {
2007 /* No control, key so remove any selections before adding */
2008 gl_view_unselect_all (view);
2011 /* Add to current selection */
2012 gl_view_select_object (view, view_object);
2013 /* bring up apropriate menu for selection. */
2014 popup_selection_menu (view, view_object, event);
2021 case GDK_BUTTON_RELEASE:
2022 gl_debug (DEBUG_VIEW, "BUTTON_RELEASE");
2023 switch (event->button.button) {
2025 /* Exit dragging mode */
2026 gnome_canvas_item_ungrab (item, event->button.time);
2034 case GDK_MOTION_NOTIFY:
2035 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
2036 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
2037 /* Dragging mode, move selection */
2040 move_selection (view, (new_x - x), (new_y - y));
2048 case GDK_2BUTTON_PRESS:
2049 gl_debug (DEBUG_VIEW, "2BUTTON_PRESS");
2050 switch (event->button.button) {
2052 /* Also exit dragging mode w/ double-click, run dlg */
2053 gnome_canvas_item_ungrab (item, event->button.time);
2055 gl_view_select_object (view, view_object);
2056 gl_view_object_show_dialog (view_object);
2063 case GDK_ENTER_NOTIFY:
2064 gl_debug (DEBUG_VIEW, "ENTER_NOTIFY");
2065 cursor = gdk_cursor_new (GDK_FLEUR);
2066 gdk_window_set_cursor (view->canvas->window, cursor);
2067 gdk_cursor_unref (cursor);
2070 case GDK_LEAVE_NOTIFY:
2071 gl_debug (DEBUG_VIEW, "LEAVE_NOTIFY");
2072 cursor = gdk_cursor_new (GDK_LEFT_PTR);
2073 gdk_window_set_cursor (view->canvas->window, cursor);
2074 gdk_cursor_unref (cursor);
2078 gl_debug (DEBUG_VIEW, "default");
2084 /*---------------------------------------------------------------------------*/
2085 /* PRIVATE. create menu for multiple selections. */
2086 /*---------------------------------------------------------------------------*/
2088 new_selection_menu (glView *view)
2090 GtkWidget *menu, *menuitem;
2092 gl_debug (DEBUG_VIEW, "START");
2094 g_return_val_if_fail (GL_IS_VIEW (view), NULL);
2096 menu = gtk_menu_new ();
2098 menuitem = gtk_menu_item_new_with_label (_("Delete"));
2099 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2100 gtk_widget_show (menuitem);
2101 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2102 G_CALLBACK (gl_view_delete_selection), view);
2104 menuitem = gtk_menu_item_new ();
2105 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2106 gtk_widget_show (menuitem);
2108 menuitem = gtk_menu_item_new_with_label (_("Bring to front"));
2109 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2110 gtk_widget_show (menuitem);
2111 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2112 G_CALLBACK (gl_view_raise_selection), view);
2114 menuitem = gtk_menu_item_new_with_label (_("Send to back"));
2115 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2116 gtk_widget_show (menuitem);
2117 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2118 G_CALLBACK (gl_view_lower_selection), view);
2120 gl_debug (DEBUG_VIEW, "END");
2125 /*---------------------------------------------------------------------------*/
2126 /* PRIVATE. popup menu for given item. */
2127 /*---------------------------------------------------------------------------*/
2129 popup_selection_menu (glView *view,
2130 glViewObject *view_object,
2135 gl_debug (DEBUG_VIEW, "START");
2137 g_return_if_fail (GL_IS_VIEW (view));
2138 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
2140 if (gl_view_is_selection_atomic (view)) {
2142 menu = gl_view_object_get_menu (view_object);
2144 gtk_menu_popup (GTK_MENU (menu),
2145 NULL, NULL, NULL, NULL,
2146 event->button.button,
2147 event->button.time);
2152 if (view->menu != NULL) {
2153 gtk_menu_popup (GTK_MENU (view->menu),
2154 NULL, NULL, NULL, NULL,
2155 event->button.button,
2156 event->button.time);
2161 gl_debug (DEBUG_VIEW, "END");
2164 /*---------------------------------------------------------------------------*/
2165 /* PRIVATE. Handle "selection-clear" signal. */
2166 /*---------------------------------------------------------------------------*/
2168 selection_clear_cb (GtkWidget *widget,
2169 GdkEventSelection *event,
2172 glView *view = GL_VIEW (data);
2174 gl_debug (DEBUG_VIEW, "START");
2176 g_return_if_fail (GL_IS_VIEW (view));
2178 view->have_selection = FALSE;
2179 g_object_unref (view->selection_data);
2180 view->selection_data = NULL;
2182 gl_debug (DEBUG_VIEW, "END");
2185 /*---------------------------------------------------------------------------*/
2186 /* PRIVATE. Handle "selection-get" signal. */
2187 /*---------------------------------------------------------------------------*/
2189 selection_get_cb (GtkWidget *widget,
2190 GtkSelectionData *selection_data,
2195 glView *view = GL_VIEW (data);
2197 glXMLLabelStatus status;
2199 gl_debug (DEBUG_VIEW, "START");
2201 g_return_if_fail (GL_IS_VIEW (view));
2203 if (view->have_selection) {
2205 buffer = gl_xml_label_save_buffer (view->selection_data,
2207 gtk_selection_data_set (selection_data,
2208 GDK_SELECTION_TYPE_STRING, 8, buffer,
2213 gl_debug (DEBUG_VIEW, "END");
2216 /*---------------------------------------------------------------------------*/
2217 /* PRIVATE. Handle "selection-received" signal. (Result of Paste) */
2218 /*---------------------------------------------------------------------------*/
2220 selection_received_cb (GtkWidget *widget,
2221 GtkSelectionData *selection_data,
2225 glView *view = GL_VIEW (data);
2226 glLabel *label = NULL;
2227 glXMLLabelStatus status;
2229 glLabelObject *object, *newobject;
2230 glViewObject *view_object;
2232 gl_debug (DEBUG_VIEW, "START");
2234 g_return_if_fail (GL_IS_VIEW (view));
2236 if (selection_data->length < 0) {
2239 if (selection_data->type != GDK_SELECTION_TYPE_STRING) {
2243 gl_view_unselect_all (view);
2245 label = gl_xml_label_open_buffer (selection_data->data, &status);
2246 for (p = label->objects; p != NULL; p = p_next) {
2249 object = (glLabelObject *) p->data;
2250 gl_label_object_set_parent (object, view->label);
2252 gl_debug (DEBUG_VIEW, "object pasted");
2254 if (GL_IS_LABEL_BOX (object)) {
2255 view_object = gl_view_box_new (GL_LABEL_BOX(object),
2257 } else if (GL_IS_LABEL_ELLIPSE (object)) {
2258 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object),
2260 } else if (GL_IS_LABEL_LINE (object)) {
2261 view_object = gl_view_line_new (GL_LABEL_LINE(object),
2263 } else if (GL_IS_LABEL_IMAGE (object)) {
2264 view_object = gl_view_image_new (GL_LABEL_IMAGE(object),
2266 } else if (GL_IS_LABEL_TEXT (object)) {
2267 view_object = gl_view_text_new (GL_LABEL_TEXT(object),
2269 } else if (GL_IS_LABEL_BARCODE (object)) {
2270 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(object),
2273 /* Should not happen! */
2275 g_warning ("Invalid label object type.");
2277 gl_view_select_object (view, view_object);
2279 g_object_unref (label);
2281 gl_debug (DEBUG_VIEW, "END");