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 /*==========================================================================*/
67 /*==========================================================================*/
69 /*==========================================================================*/
71 static GtkContainerClass *parent_class;
73 static guint signals[LAST_SIGNAL] = {0};
75 /* "CLIPBOARD" selection */
76 static GdkAtom clipboard_atom = GDK_NONE;
78 static gdouble scales[] = {
83 #define N_SCALES G_N_ELEMENTS(scales)
84 #define HOME_SCALE 2.0
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[POINTER_EXIT] =
236 g_signal_new ("pointer_exit",
237 G_OBJECT_CLASS_TYPE (object_class),
239 G_STRUCT_OFFSET (glViewClass, pointer_exit),
241 gl_marshal_VOID__VOID,
245 signals[MODE_CHANGED] =
246 g_signal_new ("mode_changed",
247 G_OBJECT_CLASS_TYPE (object_class),
249 G_STRUCT_OFFSET (glViewClass, mode_changed),
251 gl_marshal_VOID__VOID,
255 gl_debug (DEBUG_VIEW, "END");
259 gl_view_init (glView *view)
261 gl_debug (DEBUG_VIEW, "START");
265 gl_debug (DEBUG_VIEW, "END");
269 gl_view_finalize (GObject *object)
273 gl_debug (DEBUG_VIEW, "START");
275 g_return_if_fail (object != NULL);
276 g_return_if_fail (GL_IS_VIEW (object));
278 view = GL_VIEW (object);
280 G_OBJECT_CLASS (parent_class)->finalize (object);
282 gl_debug (DEBUG_VIEW, "END");
285 /****************************************************************************/
286 /* NEW view object. */
287 /****************************************************************************/
289 gl_view_new (glLabel *label)
291 glView *view = g_object_new (gl_view_get_type (), NULL);
293 gl_debug (DEBUG_VIEW, "START");
297 gl_view_construct (view);
299 gl_debug (DEBUG_VIEW, "END");
301 return GTK_WIDGET (view);
304 /*---------------------------------------------------------------------------*/
305 /* PRIVATE. Construct composite widget. */
306 /*---------------------------------------------------------------------------*/
308 gl_view_construct (glView *view)
310 GtkWidget *wvbox, *wscroll;
312 gl_debug (DEBUG_VIEW, "START");
314 g_return_if_fail (GL_IS_VIEW (view));
316 wvbox = GTK_WIDGET (view);
318 view->state = GL_VIEW_STATE_ARROW;
319 view->object_list = NULL;
321 gl_view_construct_canvas (view);
322 wscroll = gtk_scrolled_window_new (NULL, NULL);
323 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (wscroll),
324 GTK_POLICY_AUTOMATIC,
325 GTK_POLICY_AUTOMATIC);
326 gtk_box_pack_start (GTK_BOX (wvbox), wscroll, TRUE, TRUE, 0);
327 gtk_container_add (GTK_CONTAINER (wscroll), view->canvas);
329 gl_view_construct_selection (view);
331 view->menu = new_selection_menu (view);
333 gl_debug (DEBUG_VIEW, "END");
336 /*---------------------------------------------------------------------------*/
337 /* PRIVATE. Create canvas w/ a background in the shape of the label/card. */
338 /*---------------------------------------------------------------------------*/
340 gl_view_construct_canvas (glView *view)
343 glLabel *label = view->label;
344 gdouble label_width, label_height;
346 glLabelObject *object;
347 glViewObject *view_object;
349 gl_debug (DEBUG_VIEW, "START");
351 g_return_val_if_fail (GL_IS_VIEW (view), NULL);
352 g_return_val_if_fail (label != NULL, NULL);
354 gtk_widget_push_colormap (gdk_rgb_get_colormap ());
355 view->canvas = gnome_canvas_new_aa ();
356 gtk_widget_pop_colormap ();
358 gl_label_get_size (label, &label_width, &label_height);
359 gl_debug (DEBUG_VIEW, "Label size: w=%lf, h=%lf",
360 label_width, label_height);
362 scale = get_apropriate_scale (label_width, label_height);
363 gl_debug (DEBUG_VIEW, "scale =%lf", scale);
365 gl_debug (DEBUG_VIEW, "Canvas size: w=%lf, h=%lf",
366 scale * label_width + 40,
367 scale * label_height + 40);
368 gtk_widget_set_size_request (GTK_WIDGET(view->canvas),
369 scale * label_width + 40,
370 scale * label_height + 40);
371 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
375 gnome_canvas_set_scroll_region (GNOME_CANVAS (view->canvas),
376 0.0, 0.0, label_width, label_height);
378 /* Draw background shape of label/card */
380 gl_debug (DEBUG_VIEW, "n_bg_items = %d, n_fg_items = %d",
381 view->n_bg_items, view->n_fg_items);
383 g_signal_connect (G_OBJECT (view->canvas), "event",
384 G_CALLBACK (canvas_event), view);
386 for (p_obj = label->objects; p_obj != NULL; p_obj = p_obj->next) {
387 object = (glLabelObject *) p_obj->data;
389 if (GL_IS_LABEL_BOX (object)) {
390 view_object = gl_view_box_new (GL_LABEL_BOX(object),
392 } else if (GL_IS_LABEL_ELLIPSE (object)) {
393 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object),
395 } else if (GL_IS_LABEL_LINE (object)) {
396 view_object = gl_view_line_new (GL_LABEL_LINE(object),
398 } else if (GL_IS_LABEL_IMAGE (object)) {
399 view_object = gl_view_image_new (GL_LABEL_IMAGE(object),
401 } else if (GL_IS_LABEL_TEXT (object)) {
402 view_object = gl_view_text_new (GL_LABEL_TEXT(object),
404 } else if (GL_IS_LABEL_BARCODE (object)) {
405 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(object),
408 /* Should not happen! */
410 g_warning ("Invalid label object type.");
414 gl_debug (DEBUG_VIEW, "END");
419 /*---------------------------------------------------------------------------*/
420 /* PRIVATE. Create clipboard selection targets. */
421 /*---------------------------------------------------------------------------*/
423 gl_view_construct_selection (glView *view)
425 gl_debug (DEBUG_VIEW, "START");
427 g_return_if_fail (GL_IS_VIEW (view));
429 view->have_selection = FALSE;
430 view->selection_data = NULL;
431 view->invisible = gtk_invisible_new ();
433 view->selected_object_list = NULL;
435 if (!clipboard_atom) {
436 clipboard_atom = gdk_atom_intern ("GLABELS_CLIPBOARD", FALSE);
439 gtk_selection_add_target (view->invisible,
440 clipboard_atom, GDK_SELECTION_TYPE_STRING, 1);
442 g_signal_connect (G_OBJECT (view->invisible),
443 "selection_clear_event",
444 G_CALLBACK (selection_clear_cb), view);
446 g_signal_connect (G_OBJECT (view->invisible), "selection_get",
447 G_CALLBACK (selection_get_cb), view);
449 g_signal_connect (G_OBJECT (view->invisible),
450 "selection_received",
451 G_CALLBACK (selection_received_cb), view);
453 gl_debug (DEBUG_VIEW, "END");
456 /*---------------------------------------------------------------------------*/
457 /* PRIVATE. Determine an apropriate scale for given label & screen size */
458 /*---------------------------------------------------------------------------*/
460 get_apropriate_scale (gdouble w, gdouble h)
462 gdouble w_screen, h_screen;
466 gl_debug (DEBUG_VIEW, "");
468 w_screen = (gdouble) gdk_screen_width ();
469 h_screen = (gdouble) gdk_screen_height ();
471 for (i = 0; i < N_SCALES; i++) {
473 if (k <= HOME_SCALE) {
474 if ((k * w < (w_screen - 256))
475 && (k * h < (h_screen - 256)))
483 /*---------------------------------------------------------------------------*/
484 /* PRIVATE. Draw background and foreground outlines. */
485 /*---------------------------------------------------------------------------*/
487 draw_bg_fg (glView *view)
490 glTemplate *template;
492 view->n_bg_items = 0;
493 view->bg_item_list = NULL;
494 view->n_fg_items = 0;
495 view->fg_item_list = NULL;
498 template = gl_label_get_template (label);
500 switch (template->label.style) {
502 case GL_TEMPLATE_STYLE_RECT:
503 if (template->label.rect.r == 0.0) {
504 /* Square corners. */
505 draw_bg_fg_rect (view);
507 /* Rounded corners. */
508 draw_bg_fg_rounded_rect (view);
512 case GL_TEMPLATE_STYLE_ROUND:
513 draw_bg_fg_round (view);
516 case GL_TEMPLATE_STYLE_CD:
517 draw_bg_fg_cd (view);
521 g_warning ("Unknown template label style");
526 /*---------------------------------------------------------------------------*/
527 /* PRIVATE. Draw simple recangular background. */
528 /*---------------------------------------------------------------------------*/
530 draw_bg_fg_rect (glView *view)
532 glLabel *label = view->label;
533 glTemplate *template;
535 GnomeCanvasItem *item;
536 GnomeCanvasGroup *group;
538 gl_debug (DEBUG_VIEW, "START");
540 g_return_if_fail (GL_IS_VIEW (view));
541 g_return_if_fail (label != NULL);
543 gl_label_get_size (label, &w, &h);
544 template = gl_label_get_template (label);
546 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
549 item = gnome_canvas_item_new (group,
550 gnome_canvas_rect_get_type (),
555 "fill_color", "white",
558 view->bg_item_list = g_list_append (view->bg_item_list, item);
564 item = gnome_canvas_item_new (group,
565 gnome_canvas_rect_get_type (),
571 "outline_color", "light blue",
574 view->fg_item_list = g_list_append (view->fg_item_list, item);
576 gl_debug (DEBUG_VIEW, "END");
579 /*---------------------------------------------------------------------------*/
580 /* PRIVATE. Draw rounded recangular background. */
581 /*---------------------------------------------------------------------------*/
583 draw_bg_fg_rounded_rect (glView *view)
585 glLabel *label = view->label;
586 GnomeCanvasPoints *points;
587 gint i_coords, i_theta;
588 glTemplate *template;
590 GnomeCanvasItem *item;
591 GnomeCanvasGroup *group;
593 gl_debug (DEBUG_VIEW, "START");
595 g_return_if_fail (GL_IS_VIEW (view));
596 g_return_if_fail (label != NULL);
598 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
600 gl_label_get_size (label, &w, &h);
601 template = gl_label_get_template (label);
602 r = template->label.rect.r;
604 points = gnome_canvas_points_new (4 * (1 + 90 / 5));
606 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
607 points->coords[i_coords++] =
608 r - r * sin (i_theta * M_PI / 180.0);
609 points->coords[i_coords++] =
610 r - r * cos (i_theta * M_PI / 180.0);
612 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
613 points->coords[i_coords++] =
614 r - r * cos (i_theta * M_PI / 180.0);
615 points->coords[i_coords++] =
616 (h - r) + r * sin (i_theta * M_PI / 180.0);
618 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
619 points->coords[i_coords++] =
620 (w - r) + r * sin (i_theta * M_PI / 180.0);
621 points->coords[i_coords++] =
622 (h - r) + r * cos (i_theta * M_PI / 180.0);
624 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
625 points->coords[i_coords++] =
626 (w - r) + r * cos (i_theta * M_PI / 180.0);
627 points->coords[i_coords++] =
628 r - r * sin (i_theta * M_PI / 180.0);
632 item = gnome_canvas_item_new (group,
633 gnome_canvas_polygon_get_type (),
635 "fill_color", "white",
638 view->bg_item_list = g_list_append (view->bg_item_list, item);
644 item = gnome_canvas_item_new (group,
645 gnome_canvas_polygon_get_type (),
648 "outline_color", "light blue",
651 view->fg_item_list = g_list_append (view->fg_item_list, item);
653 gnome_canvas_points_free (points);
655 gl_debug (DEBUG_VIEW, "END");
658 /*---------------------------------------------------------------------------*/
659 /* PRIVATE. Draw round background. */
660 /*---------------------------------------------------------------------------*/
662 draw_bg_fg_round (glView *view)
664 glLabel *label = view->label;
665 glTemplate *template;
667 GnomeCanvasItem *item;
668 GnomeCanvasGroup *group;
670 gl_debug (DEBUG_VIEW, "START");
672 g_return_if_fail (GL_IS_VIEW (view));
673 g_return_if_fail (label != NULL);
675 template = gl_label_get_template (label);
677 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
679 r = template->label.round.r;
682 item = gnome_canvas_item_new (group,
683 gnome_canvas_ellipse_get_type (),
688 "fill_color", "white",
691 view->bg_item_list = g_list_append (view->bg_item_list, item);
697 item = gnome_canvas_item_new (group,
698 gnome_canvas_ellipse_get_type (),
704 "outline_color", "light blue",
707 view->fg_item_list = g_list_append (view->fg_item_list, item);
709 gl_debug (DEBUG_VIEW, "END");
712 /*---------------------------------------------------------------------------*/
713 /* PRIVATE. Draw CD style background, circular w/ concentric hole. */
714 /*---------------------------------------------------------------------------*/
716 draw_bg_fg_cd (glView *view)
718 glLabel *label = view->label;
719 glTemplate *template;
721 GnomeCanvasItem *item;
722 GnomeCanvasGroup *group;
724 gl_debug (DEBUG_VIEW, "START");
726 g_return_if_fail (GL_IS_VIEW (view));
727 g_return_if_fail (label != NULL);
729 template = gl_label_get_template (label);
731 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
733 r1 = template->label.cd.r1;
734 r2 = template->label.cd.r2;
738 item = gnome_canvas_item_new (group,
739 gnome_canvas_ellipse_get_type (),
744 "fill_color", "white",
747 view->bg_item_list = g_list_append (view->bg_item_list, item);
749 item = gnome_canvas_item_new (group,
750 gnome_canvas_ellipse_get_type (),
755 "fill_color", "gray",
758 view->bg_item_list = g_list_append (view->bg_item_list, item);
765 item = gnome_canvas_item_new (group,
766 gnome_canvas_ellipse_get_type (),
772 "outline_color", "light blue",
775 view->fg_item_list = g_list_append (view->fg_item_list, item);
777 item = gnome_canvas_item_new (group,
778 gnome_canvas_ellipse_get_type (),
784 "outline_color", "light blue",
787 view->fg_item_list = g_list_append (view->fg_item_list, item);
789 gl_debug (DEBUG_VIEW, "END");
792 /*---------------------------------------------------------------------------*/
793 /* PRIVATE. Draw markup lines. */
794 /*---------------------------------------------------------------------------*/
796 draw_markup (glView *view)
799 glTemplate *template;
801 glTemplateMarkup *markup;
804 template = gl_label_get_template (label);
806 for ( p=template->label.any.markups; p != NULL; p=p->next ) {
807 markup = (glTemplateMarkup *)p->data;
809 switch (markup->type) {
810 case GL_TEMPLATE_MARKUP_MARGIN:
811 draw_markup_margin (view,
812 (glTemplateMarkupMargin *)markup);
815 g_warning ("Unknown template markup type");
821 /*---------------------------------------------------------------------------*/
822 /* PRIVATE. Draw margin markup. */
823 /*---------------------------------------------------------------------------*/
825 draw_markup_margin (glView *view,
826 glTemplateMarkupMargin *margin)
829 glTemplate *template;
832 template = gl_label_get_template (label);
834 switch (template->label.style) {
836 case GL_TEMPLATE_STYLE_RECT:
837 if (template->label.rect.r == 0.0) {
838 /* Square corners. */
839 draw_markup_margin_rect (view, margin);
841 if ( margin->size < template->label.rect.r) {
842 /* Rounded corners. */
843 draw_markup_margin_rounded_rect (view, margin);
845 /* Square corners. */
846 draw_markup_margin_rect (view, margin);
851 case GL_TEMPLATE_STYLE_ROUND:
852 draw_markup_margin_round (view, margin);
855 case GL_TEMPLATE_STYLE_CD:
856 draw_markup_margin_cd (view, margin);
860 g_warning ("Unknown template label style");
865 /*---------------------------------------------------------------------------*/
866 /* PRIVATE. Draw simple recangular margin. */
867 /*---------------------------------------------------------------------------*/
869 draw_markup_margin_rect (glView *view,
870 glTemplateMarkupMargin *margin)
872 glLabel *label = view->label;
873 glTemplate *template;
875 GnomeCanvasItem *item;
876 GnomeCanvasGroup *group;
878 gl_debug (DEBUG_VIEW, "START");
880 g_return_if_fail (GL_IS_VIEW (view));
881 g_return_if_fail (label != NULL);
883 gl_label_get_size (label, &w, &h);
884 template = gl_label_get_template (label);
887 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
889 /* Bounding box @ margin */
890 gnome_canvas_item_new (group,
891 gnome_canvas_rect_get_type (),
897 "outline_color", "light blue",
900 view->bg_item_list = g_list_append (view->bg_item_list, item);
902 gl_debug (DEBUG_VIEW, "END");
905 /*---------------------------------------------------------------------------*/
906 /* PRIVATE. Draw rounded recangular markup. */
907 /*---------------------------------------------------------------------------*/
909 draw_markup_margin_rounded_rect (glView *view,
910 glTemplateMarkupMargin *margin)
912 glLabel *label = view->label;
913 GnomeCanvasPoints *points;
914 gint i_coords, i_theta;
915 glTemplate *template;
917 GnomeCanvasItem *item;
918 GnomeCanvasGroup *group;
920 gl_debug (DEBUG_VIEW, "START");
922 g_return_if_fail (GL_IS_VIEW (view));
923 g_return_if_fail (label != NULL);
925 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
927 gl_label_get_size (label, &w, &h);
928 template = gl_label_get_template (label);
929 r = template->label.rect.r;
936 /* rectangle with rounded corners */
937 points = gnome_canvas_points_new (4 * (1 + 90 / 5));
939 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
940 points->coords[i_coords++] =
941 m + r - r * sin (i_theta * M_PI / 180.0);
942 points->coords[i_coords++] =
943 m + r - r * cos (i_theta * M_PI / 180.0);
945 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
946 points->coords[i_coords++] =
947 m + r - r * cos (i_theta * M_PI / 180.0);
948 points->coords[i_coords++] =
949 m + (h - r) + r * sin (i_theta * M_PI / 180.0);
951 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
952 points->coords[i_coords++] =
953 m + (w - r) + r * sin (i_theta * M_PI / 180.0);
954 points->coords[i_coords++] =
955 m + (h - r) + r * cos (i_theta * M_PI / 180.0);
957 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
958 points->coords[i_coords++] =
959 m + (w - r) + r * cos (i_theta * M_PI / 180.0);
960 points->coords[i_coords++] =
961 m + r - r * sin (i_theta * M_PI / 180.0);
963 item = gnome_canvas_item_new (group,
964 gnome_canvas_polygon_get_type (),
967 "outline_color", "light blue",
969 gnome_canvas_points_free (points);
971 view->bg_item_list = g_list_append (view->bg_item_list, item);
973 gl_debug (DEBUG_VIEW, "END");
976 /*---------------------------------------------------------------------------*/
977 /* PRIVATE. Draw round margin. */
978 /*---------------------------------------------------------------------------*/
980 draw_markup_margin_round (glView *view,
981 glTemplateMarkupMargin *margin)
983 glLabel *label = view->label;
984 glTemplate *template;
986 GnomeCanvasItem *item;
987 GnomeCanvasGroup *group;
989 gl_debug (DEBUG_VIEW, "START");
991 g_return_if_fail (GL_IS_VIEW (view));
992 g_return_if_fail (label != NULL);
994 template = gl_label_get_template (label);
996 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
998 r = template->label.round.r;
1001 /* Margin outline */
1002 item = gnome_canvas_item_new (group,
1003 gnome_canvas_ellipse_get_type (),
1009 "outline_color", "light blue", NULL);
1011 view->bg_item_list = g_list_append (view->bg_item_list, item);
1013 gl_debug (DEBUG_VIEW, "END");
1016 /*---------------------------------------------------------------------------*/
1017 /* PRIVATE. Draw CD margins. */
1018 /*---------------------------------------------------------------------------*/
1020 draw_markup_margin_cd (glView *view,
1021 glTemplateMarkupMargin *margin)
1023 glLabel *label = view->label;
1024 glTemplate *template;
1026 GnomeCanvasItem *item;
1027 GnomeCanvasGroup *group;
1029 gl_debug (DEBUG_VIEW, "START");
1031 g_return_if_fail (GL_IS_VIEW (view));
1032 g_return_if_fail (label != NULL);
1034 template = gl_label_get_template (label);
1036 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
1038 r1 = template->label.cd.r1;
1039 r2 = template->label.cd.r2;
1043 item = gnome_canvas_item_new (group,
1044 gnome_canvas_ellipse_get_type (),
1050 "outline_color", "light blue", NULL);
1052 view->bg_item_list = g_list_append (view->bg_item_list, item);
1054 item = gnome_canvas_item_new (group,
1055 gnome_canvas_ellipse_get_type (),
1061 "outline_color", "light blue",
1064 view->bg_item_list = g_list_append (view->bg_item_list, item);
1066 gl_debug (DEBUG_VIEW, "END");
1069 /*****************************************************************************/
1070 /* Raise foreground items to top. */
1071 /*****************************************************************************/
1073 gl_view_raise_fg (glView *view)
1077 for (p = view->fg_item_list; p != NULL; p = p->next) {
1078 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(p->data));
1082 /*****************************************************************************/
1083 /* Set arrow mode. */
1084 /*****************************************************************************/
1086 gl_view_arrow_mode (glView *view)
1088 static GdkCursor *cursor = NULL;
1090 gl_debug (DEBUG_VIEW, "START");
1092 g_return_if_fail (GL_IS_VIEW (view));
1095 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1098 gdk_window_set_cursor (view->canvas->window, cursor);
1100 view->state = GL_VIEW_STATE_ARROW;
1102 gl_debug (DEBUG_VIEW, "END");
1105 /*****************************************************************************/
1106 /* Set create text object mode. */
1107 /*****************************************************************************/
1109 gl_view_object_create_mode (glView *view,
1110 glLabelObjectType type)
1114 gl_debug (DEBUG_VIEW, "START");
1116 g_return_if_fail (GL_IS_VIEW (view));
1119 case GL_LABEL_OBJECT_BOX:
1120 cursor = gl_view_box_get_create_cursor ();
1122 case GL_LABEL_OBJECT_ELLIPSE:
1123 cursor = gl_view_ellipse_get_create_cursor ();
1125 case GL_LABEL_OBJECT_LINE:
1126 cursor = gl_view_line_get_create_cursor ();
1128 case GL_LABEL_OBJECT_IMAGE:
1129 cursor = gl_view_image_get_create_cursor ();
1131 case GL_LABEL_OBJECT_TEXT:
1132 cursor = gl_view_text_get_create_cursor ();
1134 case GL_LABEL_OBJECT_BARCODE:
1135 cursor = gl_view_barcode_get_create_cursor ();
1138 g_warning ("Invalid label object type.");/*Should not happen!*/
1142 gdk_window_set_cursor (view->canvas->window, cursor);
1144 view->state = GL_VIEW_STATE_OBJECT_CREATE;
1145 view->create_type = type;
1147 gl_debug (DEBUG_VIEW, "END");
1150 /*****************************************************************************/
1151 /* Select given object (adding to current selection). */
1152 /*****************************************************************************/
1154 gl_view_select_object (glView *view,
1155 glViewObject *view_object)
1157 gl_debug (DEBUG_VIEW, "START");
1159 select_object_real (view, view_object);
1161 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1163 gl_debug (DEBUG_VIEW, "END");
1166 /*****************************************************************************/
1167 /* Unselect given object (removing from current selection). */
1168 /*****************************************************************************/
1170 gl_view_unselect_object (glView *view,
1171 glViewObject *view_object)
1173 gl_debug (DEBUG_VIEW, "START");
1175 unselect_object_real (view, view_object);
1177 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1179 gl_debug (DEBUG_VIEW, "END");
1182 /*****************************************************************************/
1183 /* Select all items. */
1184 /*****************************************************************************/
1186 gl_view_select_all (glView *view)
1190 gl_debug (DEBUG_VIEW, "START");
1192 g_return_if_fail (GL_IS_VIEW (view));
1194 /* 1st unselect anything already selected. */
1195 for (p = view->selected_object_list; p != NULL; p = p_next) {
1197 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1200 /* Finally select all objects. */
1201 for (p = view->object_list; p != NULL; p = p->next) {
1202 select_object_real (view, GL_VIEW_OBJECT (p->data));
1205 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1207 gl_debug (DEBUG_VIEW, "END");
1210 /*****************************************************************************/
1211 /* Remove all selections */
1212 /*****************************************************************************/
1214 gl_view_unselect_all (glView *view)
1218 gl_debug (DEBUG_VIEW, "START");
1220 g_return_if_fail (GL_IS_VIEW (view));
1222 for (p = view->selected_object_list; p != NULL; p = p_next) {
1224 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1227 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1229 gl_debug (DEBUG_VIEW, "END");
1232 /*****************************************************************************/
1233 /* Select all objects within given rectangular region (adding to selection). */
1234 /*****************************************************************************/
1236 gl_view_select_region (glView *view,
1243 glViewObject *view_object;
1244 glLabelObject *object;
1245 gdouble i_x1, i_y1, i_x2, i_y2, w, h;
1247 gl_debug (DEBUG_VIEW, "START");
1249 g_return_if_fail (GL_IS_VIEW (view));
1250 g_return_if_fail ((x1 <= x2) && (y1 <= y2));
1252 for (p = view->object_list; p != NULL; p = p->next) {
1253 view_object = GL_VIEW_OBJECT(p->data);
1254 if (!is_object_selected (view, view_object)) {
1256 object = gl_view_object_get_object (view_object);
1258 gl_label_object_get_position (object, &i_x1, &i_y1);
1259 gl_label_object_get_size (object, &w, &h);
1262 if ((i_x1 >= x1) && (i_x2 <= x2) && (i_y1 >= y1)
1264 select_object_real (view, view_object);
1270 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1272 gl_debug (DEBUG_VIEW, "END");
1275 /*---------------------------------------------------------------------------*/
1276 /* PRIVATE. Select an object. */
1277 /*---------------------------------------------------------------------------*/
1279 select_object_real (glView *view,
1280 glViewObject *view_object)
1282 gl_debug (DEBUG_VIEW, "START");
1284 g_return_if_fail (GL_IS_VIEW (view));
1285 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1287 if (!is_object_selected (view, view_object)) {
1288 view->selected_object_list =
1289 g_list_prepend (view->selected_object_list, view_object);
1291 gl_view_object_show_highlight (view_object);
1292 gtk_widget_grab_focus (GTK_WIDGET (view->canvas));
1294 gl_debug (DEBUG_VIEW, "END");
1297 /*---------------------------------------------------------------------------*/
1298 /* PRIVATE. Un-select object. */
1299 /*---------------------------------------------------------------------------*/
1301 unselect_object_real (glView *view,
1302 glViewObject *view_object)
1304 gl_debug (DEBUG_VIEW, "START");
1306 g_return_if_fail (GL_IS_VIEW (view));
1307 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1309 gl_view_object_hide_highlight (view_object);
1311 view->selected_object_list =
1312 g_list_remove (view->selected_object_list, view_object);
1314 gl_debug (DEBUG_VIEW, "END");
1317 /*---------------------------------------------------------------------------*/
1318 /* PRIVATE. Return object at (x,y). */
1319 /*---------------------------------------------------------------------------*/
1321 object_at (glView *view,
1325 GnomeCanvasItem *item, *p_item;
1328 gl_debug (DEBUG_VIEW, "");
1330 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1332 item = gnome_canvas_get_item_at (GNOME_CANVAS (view->canvas), x, y);
1334 /* No item is at x, y */
1338 /* ignore our background items */
1339 if (g_list_find (view->bg_item_list, item) != NULL)
1345 /*---------------------------------------------------------------------------*/
1346 /* PRIVATE. Is the object in our current selection? */
1347 /*---------------------------------------------------------------------------*/
1349 is_object_selected (glView *view,
1350 glViewObject *view_object)
1352 gl_debug (DEBUG_VIEW, "");
1354 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1355 g_return_val_if_fail (GL_IS_VIEW_OBJECT (view_object), FALSE);
1357 if (g_list_find (view->selected_object_list, view_object) == NULL) {
1363 /*****************************************************************************/
1364 /* Is our current selection empty? */
1365 /*****************************************************************************/
1367 gl_view_is_selection_empty (glView *view)
1369 gl_debug (DEBUG_VIEW, "");
1371 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1373 if (view->selected_object_list == NULL) {
1380 /*****************************************************************************/
1381 /* Is our current selection atomic? I.e. only one item selected. */
1382 /*****************************************************************************/
1384 gl_view_is_selection_atomic (glView *view)
1386 gl_debug (DEBUG_VIEW, "");
1388 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1390 if (view->selected_object_list == NULL)
1392 if (view->selected_object_list->next == NULL)
1397 /*****************************************************************************/
1398 /* Delete selected objects. (Bypass clipboard) */
1399 /*****************************************************************************/
1401 gl_view_delete_selection (glView *view)
1405 gl_debug (DEBUG_VIEW, "START");
1407 g_return_if_fail (GL_IS_VIEW (view));
1409 for (p = view->selected_object_list; p != NULL; p = p_next) {
1411 g_object_unref (G_OBJECT (p->data));
1414 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1416 gl_debug (DEBUG_VIEW, "END");
1419 /*****************************************************************************/
1420 /* Edit properties of selected object. */
1421 /*****************************************************************************/
1423 gl_view_edit_object_props (glView *view)
1425 glViewObject *view_object;
1427 gl_debug (DEBUG_VIEW, "START");
1429 g_return_if_fail (GL_IS_VIEW (view));
1431 if (gl_view_is_selection_atomic (view)) {
1433 view_object = GL_VIEW_OBJECT(view->selected_object_list->data);
1434 gl_view_object_show_dialog (view_object);
1438 gl_debug (DEBUG_VIEW, "END");
1441 /*****************************************************************************/
1442 /* Raise selected items to top. */
1443 /*****************************************************************************/
1445 gl_view_raise_selection (glView *view)
1448 glViewObject *view_object;
1449 glLabelObject *label_object;
1451 gl_debug (DEBUG_VIEW, "START");
1453 g_return_if_fail (GL_IS_VIEW (view));
1455 for (p = view->selected_object_list; p != NULL; p = p->next) {
1456 view_object = GL_VIEW_OBJECT (p->data);
1457 label_object = gl_view_object_get_object (view_object);
1458 gl_label_object_raise_to_top (label_object);
1461 gl_debug (DEBUG_VIEW, "END");
1464 /*****************************************************************************/
1465 /* Lower selected items to bottom. */
1466 /*****************************************************************************/
1468 gl_view_lower_selection (glView *view)
1471 glViewObject *view_object;
1472 glLabelObject *label_object;
1474 gl_debug (DEBUG_VIEW, "START");
1476 g_return_if_fail (GL_IS_VIEW (view));
1478 for (p = view->selected_object_list; p != NULL; p = p->next) {
1479 view_object = GL_VIEW_OBJECT (p->data);
1480 label_object = gl_view_object_get_object (view_object);
1481 gl_label_object_lower_to_bottom (label_object);
1484 gl_debug (DEBUG_VIEW, "END");
1487 /*****************************************************************************/
1488 /* Flip selected objects horizontally. */
1489 /*****************************************************************************/
1491 gl_view_flip_selection_horiz (glView *view)
1494 glViewObject *view_object;
1495 glLabelObject *label_object;
1497 gl_debug (DEBUG_VIEW, "START");
1499 g_return_if_fail (GL_IS_VIEW (view));
1501 for (p = view->selected_object_list; p != NULL; p = p->next) {
1502 view_object = GL_VIEW_OBJECT (p->data);
1503 label_object = gl_view_object_get_object (view_object);
1504 gl_label_object_flip_horiz (label_object);
1507 gl_debug (DEBUG_VIEW, "END");
1510 /*****************************************************************************/
1511 /* Flip selected objects vertically. */
1512 /*****************************************************************************/
1514 gl_view_flip_selection_vert (glView *view)
1517 glViewObject *view_object;
1518 glLabelObject *label_object;
1520 gl_debug (DEBUG_VIEW, "START");
1522 g_return_if_fail (GL_IS_VIEW (view));
1524 for (p = view->selected_object_list; p != NULL; p = p->next) {
1525 view_object = GL_VIEW_OBJECT (p->data);
1526 label_object = gl_view_object_get_object (view_object);
1527 gl_label_object_flip_vert (label_object);
1530 gl_debug (DEBUG_VIEW, "END");
1533 /*****************************************************************************/
1534 /* "Cut" selected items and place in clipboard selections. */
1535 /*****************************************************************************/
1537 gl_view_cut (glView *view)
1539 gl_debug (DEBUG_VIEW, "START");
1541 g_return_if_fail (GL_IS_VIEW (view));
1543 gl_view_copy (view);
1544 gl_view_delete_selection (view);
1546 gl_debug (DEBUG_VIEW, "END");
1549 /*****************************************************************************/
1550 /* "Copy" selected items to clipboard selections. */
1551 /*****************************************************************************/
1553 gl_view_copy (glView *view)
1556 glViewObject *view_object;
1557 glLabelObject *object;
1558 glTemplate *template;
1559 gboolean rotate_flag;
1561 gl_debug (DEBUG_VIEW, "START");
1563 g_return_if_fail (GL_IS_VIEW (view));
1565 if (view->selected_object_list) {
1567 if ( view->selection_data ) {
1568 g_object_unref (view->selection_data);
1570 template = gl_label_get_template (view->label);
1571 rotate_flag = gl_label_get_rotate_flag (view->label);
1572 view->selection_data = GL_LABEL(gl_label_new ());
1573 gl_label_set_template (view->selection_data, template);
1574 gl_label_set_rotate_flag (view->selection_data, rotate_flag);
1575 gl_template_free (&template);
1577 for (p = view->selected_object_list; p != NULL; p = p->next) {
1579 view_object = GL_VIEW_OBJECT (p->data);
1580 object = gl_view_object_get_object (view_object);
1582 gl_debug (DEBUG_VIEW, "Object copied");
1584 if (GL_IS_LABEL_BOX (object)) {
1585 gl_label_box_dup (GL_LABEL_BOX(object),
1586 view->selection_data);
1587 } else if (GL_IS_LABEL_ELLIPSE (object)) {
1588 gl_label_ellipse_dup (GL_LABEL_ELLIPSE(object),
1589 view->selection_data);
1590 } else if (GL_IS_LABEL_LINE (object)) {
1591 gl_label_line_dup (GL_LABEL_LINE(object),
1592 view->selection_data);
1593 } else if (GL_IS_LABEL_IMAGE (object)) {
1594 gl_label_image_dup (GL_LABEL_IMAGE(object),
1595 view->selection_data);
1596 } else if (GL_IS_LABEL_TEXT (object)) {
1597 gl_label_text_dup (GL_LABEL_TEXT(object),
1598 view->selection_data);
1599 } else if (GL_IS_LABEL_BARCODE (object)) {
1600 gl_label_barcode_dup (GL_LABEL_BARCODE(object),
1601 view->selection_data);
1603 /* Should not happen! */
1604 g_warning ("Invalid label object type.");
1610 gtk_selection_owner_set (view->invisible,
1611 clipboard_atom, GDK_CURRENT_TIME);
1612 view->have_selection = TRUE;
1616 gl_debug (DEBUG_VIEW, "END");
1619 /*****************************************************************************/
1620 /* "Paste" from private clipboard selection. */
1621 /*****************************************************************************/
1623 gl_view_paste (glView *view)
1625 gl_debug (DEBUG_VIEW, "START");
1627 g_return_if_fail (GL_IS_VIEW (view));
1629 gtk_selection_convert (GTK_WIDGET (view->invisible),
1630 clipboard_atom, GDK_SELECTION_TYPE_STRING,
1633 gl_debug (DEBUG_VIEW, "END");
1636 /*---------------------------------------------------------------------------*/
1637 /* PRIVATE. move selected objects */
1638 /*---------------------------------------------------------------------------*/
1640 move_selection (glView *view,
1645 glLabelObject *object;
1647 gl_debug (DEBUG_VIEW, "START");
1649 g_return_if_fail (GL_IS_VIEW (view));
1651 for (p = view->selected_object_list; p != NULL; p = p->next) {
1653 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
1654 gl_label_object_set_position_relative (object, dx, dy);
1658 gl_debug (DEBUG_VIEW, "END");
1661 /*****************************************************************************/
1662 /* Zoom in one "notch" */
1663 /*****************************************************************************/
1665 gl_view_zoom_in (glView *view)
1668 gdouble dist, dist_min;
1670 gl_debug (DEBUG_VIEW, "START");
1672 g_return_if_fail (GL_IS_VIEW (view));
1674 /* Find index of current scale (or best match) */
1675 i_min = 1; /* start with 2nd largest scale */
1676 dist_min = fabs (scales[1] - view->scale);
1677 for (i = 2; i < N_SCALES; i++) {
1678 dist = fabs (scales[i] - view->scale);
1679 if (dist < dist_min) {
1685 /* zoom in one "notch" */
1686 i = MAX (0, i_min - 1);
1687 gl_view_set_zoom (view, scales[i] / HOME_SCALE);
1689 gl_debug (DEBUG_VIEW, "END");
1692 /*****************************************************************************/
1693 /* Zoom out one "notch" */
1694 /*****************************************************************************/
1696 gl_view_zoom_out (glView *view)
1699 gdouble dist, dist_min;
1701 gl_debug (DEBUG_VIEW, "START");
1703 g_return_if_fail (GL_IS_VIEW (view));
1705 /* Find index of current scale (or best match) */
1706 i_min = 0; /* start with largest scale */
1707 dist_min = fabs (scales[0] - view->scale);
1708 for (i = 1; i < N_SCALES; i++) {
1709 dist = fabs (scales[i] - view->scale);
1710 if (dist < dist_min) {
1716 /* zoom out one "notch" */
1717 if (i_min >= N_SCALES)
1722 gl_view_set_zoom (view, scales[i] / HOME_SCALE);
1724 gl_debug (DEBUG_VIEW, "END");
1727 /*****************************************************************************/
1728 /* Set current zoom factor to explicit value. */
1729 /*****************************************************************************/
1731 gl_view_set_zoom (glView *view,
1734 gl_debug (DEBUG_VIEW, "START");
1736 g_return_if_fail (GL_IS_VIEW (view));
1737 g_return_if_fail (scale > 0.0);
1739 view->scale = scale * HOME_SCALE;
1740 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
1741 scale * HOME_SCALE);
1743 g_signal_emit (G_OBJECT(view), signals[ZOOM_CHANGED], 0, scale);
1745 gl_debug (DEBUG_VIEW, "END");
1748 /*****************************************************************************/
1749 /* Get current zoom factor. */
1750 /*****************************************************************************/
1752 gl_view_get_zoom (glView *view)
1754 gl_debug (DEBUG_VIEW, "");
1756 g_return_val_if_fail (GL_IS_VIEW (view), 1.0);
1758 return view->scale / HOME_SCALE;
1761 /*****************************************************************************/
1762 /* Is this the maximum zoom level. */
1763 /*****************************************************************************/
1765 gl_view_is_zoom_max (glView *view)
1767 gl_debug (DEBUG_VIEW, "");
1769 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1771 return view->scale >= scales[0];
1774 /*****************************************************************************/
1775 /* Is this the minimum zoom level. */
1776 /*****************************************************************************/
1778 gl_view_is_zoom_min (glView *view)
1780 gl_debug (DEBUG_VIEW, "");
1782 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1784 return view->scale <= scales[N_SCALES-1];
1787 /*---------------------------------------------------------------------------*/
1788 /* PRIVATE. Canvas event handler. */
1789 /*---------------------------------------------------------------------------*/
1791 canvas_event (GnomeCanvas *canvas,
1795 gl_debug (DEBUG_VIEW, "");
1797 switch (view->state) {
1799 case GL_VIEW_STATE_ARROW:
1800 return canvas_event_arrow_mode (canvas, event, view);
1802 case GL_VIEW_STATE_OBJECT_CREATE:
1803 switch (view->create_type) {
1804 case GL_LABEL_OBJECT_BOX:
1805 return gl_view_box_create_event_handler (canvas,
1809 case GL_LABEL_OBJECT_ELLIPSE:
1810 return gl_view_ellipse_create_event_handler (canvas,
1814 case GL_LABEL_OBJECT_LINE:
1815 return gl_view_line_create_event_handler (canvas,
1819 case GL_LABEL_OBJECT_IMAGE:
1820 return gl_view_image_create_event_handler (canvas,
1824 case GL_LABEL_OBJECT_TEXT:
1825 return gl_view_text_create_event_handler (canvas,
1829 case GL_LABEL_OBJECT_BARCODE:
1830 return gl_view_barcode_create_event_handler (canvas,
1835 /*Should not happen!*/
1836 g_warning ("Invalid label object type.");
1841 g_warning ("Invalid view state."); /*Should not happen!*/
1847 /*---------------------------------------------------------------------------*/
1848 /* PRIVATE. Canvas event handler (arrow mode) */
1849 /*---------------------------------------------------------------------------*/
1851 canvas_event_arrow_mode (GnomeCanvas *canvas,
1855 static gdouble x0, y0;
1856 static gboolean dragging = FALSE;
1857 static GnomeCanvasItem *item;
1858 gdouble x, y, x1, y1, x2, y2;
1859 GnomeCanvasGroup *group;
1862 gl_debug (DEBUG_VIEW, "");
1864 switch (event->type) {
1866 case GDK_BUTTON_PRESS:
1867 gl_debug (DEBUG_VIEW, "BUTTON_PRESS");
1868 switch (event->button.button) {
1870 gnome_canvas_window_to_world (canvas,
1872 event->button.y, &x, &y);
1874 if (!object_at (view, x, y)) {
1875 if (!(event->button.state & GDK_CONTROL_MASK)) {
1876 gl_view_unselect_all (view);
1880 gdk_pointer_grab (GTK_WIDGET (view->canvas)->
1882 GDK_POINTER_MOTION_MASK |
1883 GDK_BUTTON_RELEASE_MASK |
1884 GDK_BUTTON_PRESS_MASK, NULL,
1885 NULL, event->button.time);
1887 gnome_canvas_root (GNOME_CANVAS
1890 gnome_canvas_item_new (group,
1891 gnome_canvas_rect_get_type (),
1895 "outline_color_rgba",
1910 case GDK_BUTTON_RELEASE:
1911 gl_debug (DEBUG_VIEW, "BUTTON_RELEASE");
1912 switch (event->button.button) {
1916 gdk_pointer_ungrab (event->button.time);
1917 gnome_canvas_window_to_world (canvas,
1925 gl_view_select_region (view, x1, y1, x2, y2);
1926 gtk_object_destroy (GTK_OBJECT (item));
1935 case GDK_MOTION_NOTIFY:
1936 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
1937 gnome_canvas_window_to_world (canvas,
1939 event->motion.y, &x, &y);
1940 g_signal_emit (G_OBJECT(view), signals[POINTER_MOVED], 0, x, y);
1941 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
1942 gnome_canvas_item_set (item,
1946 "y2", MAX (y, y0), NULL);
1952 case GDK_LEAVE_NOTIFY:
1953 gl_debug (DEBUG_VIEW, "LEAVEW_NOTIFY");
1954 g_signal_emit (G_OBJECT(view), signals[POINTER_EXIT], 0);
1958 gl_debug (DEBUG_VIEW, "KEY_PRESS");
1960 switch (event->key.keyval) {
1963 move_selection (view,
1964 -1.0 / (view->scale), 0.0);
1968 move_selection (view,
1969 0.0, -1.0 / (view->scale));
1973 move_selection (view,
1974 1.0 / (view->scale), 0.0);
1978 move_selection (view,
1979 0.0, 1.0 / (view->scale));
1983 gl_view_delete_selection (view);
1984 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1985 gdk_window_set_cursor (view->canvas->window,
1987 gdk_cursor_unref (cursor);
1993 return TRUE; /* We handled this or we were dragging. */
1996 gl_debug (DEBUG_VIEW, "default");
2002 /*****************************************************************************/
2003 /* Item event handler. */
2004 /*****************************************************************************/
2006 gl_view_item_event_handler (GnomeCanvasItem *item,
2008 glViewObject *view_object)
2012 gl_debug (DEBUG_VIEW, "");
2014 view = gl_view_object_get_view(view_object);
2015 switch (view->state) {
2017 case GL_VIEW_STATE_ARROW:
2018 return item_event_arrow_mode (item, event, view_object);
2027 /*---------------------------------------------------------------------------*/
2028 /* PRIVATE. Item event handler (arrow mode) */
2029 /*---------------------------------------------------------------------------*/
2031 item_event_arrow_mode (GnomeCanvasItem *item,
2033 glViewObject *view_object)
2035 static gdouble x, y;
2036 static gboolean dragging = FALSE;
2039 gdouble item_x, item_y;
2040 gdouble new_x, new_y;
2041 gboolean control_key_pressed;
2043 gl_debug (DEBUG_VIEW, "");
2045 item_x = event->button.x;
2046 item_y = event->button.y;
2047 gnome_canvas_item_w2i (item->parent, &item_x, &item_y);
2049 view = gl_view_object_get_view(view_object);
2051 switch (event->type) {
2053 case GDK_BUTTON_PRESS:
2054 gl_debug (DEBUG_VIEW, "BUTTON_PRESS");
2055 control_key_pressed = event->button.state & GDK_CONTROL_MASK;
2056 switch (event->button.button) {
2058 if (control_key_pressed) {
2059 if (is_object_selected (view, view_object)) {
2060 /* Un-selecting a selected item */
2061 gl_view_unselect_object (view,
2065 /* Add to current selection */
2066 gl_view_select_object (view,
2070 if (!is_object_selected (view, view_object)) {
2071 /* No control, key so remove any selections before adding */
2072 gl_view_unselect_all (view);
2073 /* Add to current selection */
2074 gl_view_select_object (view,
2078 /* Go into dragging mode while button remains pressed. */
2081 cursor = gdk_cursor_new (GDK_FLEUR);
2082 gnome_canvas_item_grab (item,
2083 GDK_POINTER_MOTION_MASK |
2084 GDK_BUTTON_RELEASE_MASK |
2085 GDK_BUTTON_PRESS_MASK,
2086 cursor, event->button.time);
2087 gdk_cursor_unref (cursor);
2092 if (!is_object_selected (view, view_object)) {
2093 if (!control_key_pressed) {
2094 /* No control, key so remove any selections before adding */
2095 gl_view_unselect_all (view);
2098 /* Add to current selection */
2099 gl_view_select_object (view, view_object);
2100 /* bring up apropriate menu for selection. */
2101 popup_selection_menu (view, view_object, event);
2108 case GDK_BUTTON_RELEASE:
2109 gl_debug (DEBUG_VIEW, "BUTTON_RELEASE");
2110 switch (event->button.button) {
2112 /* Exit dragging mode */
2113 gnome_canvas_item_ungrab (item, event->button.time);
2121 case GDK_MOTION_NOTIFY:
2122 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
2123 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
2124 /* Dragging mode, move selection */
2127 move_selection (view, (new_x - x), (new_y - y));
2135 case GDK_2BUTTON_PRESS:
2136 gl_debug (DEBUG_VIEW, "2BUTTON_PRESS");
2137 switch (event->button.button) {
2139 /* Also exit dragging mode w/ double-click, run dlg */
2140 gnome_canvas_item_ungrab (item, event->button.time);
2142 gl_view_select_object (view, view_object);
2143 gl_view_object_show_dialog (view_object);
2150 case GDK_ENTER_NOTIFY:
2151 gl_debug (DEBUG_VIEW, "ENTER_NOTIFY");
2152 cursor = gdk_cursor_new (GDK_FLEUR);
2153 gdk_window_set_cursor (view->canvas->window, cursor);
2154 gdk_cursor_unref (cursor);
2157 case GDK_LEAVE_NOTIFY:
2158 gl_debug (DEBUG_VIEW, "LEAVE_NOTIFY");
2159 cursor = gdk_cursor_new (GDK_LEFT_PTR);
2160 gdk_window_set_cursor (view->canvas->window, cursor);
2161 gdk_cursor_unref (cursor);
2165 gl_debug (DEBUG_VIEW, "default");
2171 /*---------------------------------------------------------------------------*/
2172 /* PRIVATE. create menu for multiple selections. */
2173 /*---------------------------------------------------------------------------*/
2175 new_selection_menu (glView *view)
2177 GtkWidget *menu, *menuitem;
2179 gl_debug (DEBUG_VIEW, "START");
2181 g_return_val_if_fail (GL_IS_VIEW (view), NULL);
2183 menu = gtk_menu_new ();
2185 menuitem = gtk_menu_item_new_with_label (_("Delete"));
2186 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2187 gtk_widget_show (menuitem);
2188 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2189 G_CALLBACK (gl_view_delete_selection), view);
2191 menuitem = gtk_menu_item_new ();
2192 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2193 gtk_widget_show (menuitem);
2195 menuitem = gtk_menu_item_new_with_label (_("Bring to front"));
2196 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2197 gtk_widget_show (menuitem);
2198 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2199 G_CALLBACK (gl_view_raise_selection), view);
2201 menuitem = gtk_menu_item_new_with_label (_("Send to back"));
2202 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2203 gtk_widget_show (menuitem);
2204 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2205 G_CALLBACK (gl_view_lower_selection), view);
2207 gl_debug (DEBUG_VIEW, "END");
2212 /*---------------------------------------------------------------------------*/
2213 /* PRIVATE. popup menu for given item. */
2214 /*---------------------------------------------------------------------------*/
2216 popup_selection_menu (glView *view,
2217 glViewObject *view_object,
2222 gl_debug (DEBUG_VIEW, "START");
2224 g_return_if_fail (GL_IS_VIEW (view));
2225 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
2227 if (gl_view_is_selection_atomic (view)) {
2229 menu = gl_view_object_get_menu (view_object);
2231 gtk_menu_popup (GTK_MENU (menu),
2232 NULL, NULL, NULL, NULL,
2233 event->button.button,
2234 event->button.time);
2239 if (view->menu != NULL) {
2240 gtk_menu_popup (GTK_MENU (view->menu),
2241 NULL, NULL, NULL, NULL,
2242 event->button.button,
2243 event->button.time);
2248 gl_debug (DEBUG_VIEW, "END");
2251 /*---------------------------------------------------------------------------*/
2252 /* PRIVATE. Handle "selection-clear" signal. */
2253 /*---------------------------------------------------------------------------*/
2255 selection_clear_cb (GtkWidget *widget,
2256 GdkEventSelection *event,
2259 glView *view = GL_VIEW (data);
2261 gl_debug (DEBUG_VIEW, "START");
2263 g_return_if_fail (GL_IS_VIEW (view));
2265 view->have_selection = FALSE;
2266 g_object_unref (view->selection_data);
2267 view->selection_data = NULL;
2269 gl_debug (DEBUG_VIEW, "END");
2272 /*---------------------------------------------------------------------------*/
2273 /* PRIVATE. Handle "selection-get" signal. */
2274 /*---------------------------------------------------------------------------*/
2276 selection_get_cb (GtkWidget *widget,
2277 GtkSelectionData *selection_data,
2282 glView *view = GL_VIEW (data);
2284 glXMLLabelStatus status;
2286 gl_debug (DEBUG_VIEW, "START");
2288 g_return_if_fail (GL_IS_VIEW (view));
2290 if (view->have_selection) {
2292 buffer = gl_xml_label_save_buffer (view->selection_data,
2294 gtk_selection_data_set (selection_data,
2295 GDK_SELECTION_TYPE_STRING, 8, buffer,
2300 gl_debug (DEBUG_VIEW, "END");
2303 /*---------------------------------------------------------------------------*/
2304 /* PRIVATE. Handle "selection-received" signal. (Result of Paste) */
2305 /*---------------------------------------------------------------------------*/
2307 selection_received_cb (GtkWidget *widget,
2308 GtkSelectionData *selection_data,
2312 glView *view = GL_VIEW (data);
2313 glLabel *label = NULL;
2314 glXMLLabelStatus status;
2316 glLabelObject *object, *newobject;
2317 glViewObject *view_object;
2319 gl_debug (DEBUG_VIEW, "START");
2321 g_return_if_fail (GL_IS_VIEW (view));
2323 if (selection_data->length < 0) {
2326 if (selection_data->type != GDK_SELECTION_TYPE_STRING) {
2330 gl_view_unselect_all (view);
2332 label = gl_xml_label_open_buffer (selection_data->data, &status);
2333 for (p = label->objects; p != NULL; p = p_next) {
2336 object = (glLabelObject *) p->data;
2337 gl_label_object_set_parent (object, view->label);
2339 gl_debug (DEBUG_VIEW, "object pasted");
2341 if (GL_IS_LABEL_BOX (object)) {
2342 view_object = gl_view_box_new (GL_LABEL_BOX(object),
2344 } else if (GL_IS_LABEL_ELLIPSE (object)) {
2345 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object),
2347 } else if (GL_IS_LABEL_LINE (object)) {
2348 view_object = gl_view_line_new (GL_LABEL_LINE(object),
2350 } else if (GL_IS_LABEL_IMAGE (object)) {
2351 view_object = gl_view_image_new (GL_LABEL_IMAGE(object),
2353 } else if (GL_IS_LABEL_TEXT (object)) {
2354 view_object = gl_view_text_new (GL_LABEL_TEXT(object),
2356 } else if (GL_IS_LABEL_BARCODE (object)) {
2357 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(object),
2360 /* Should not happen! */
2362 g_warning ("Invalid label object type.");
2364 gl_view_select_object (view, view_object);
2366 g_object_unref (label);
2368 gl_debug (DEBUG_VIEW, "END");