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"
42 #include "merge-properties-dialog.h"
47 /*==========================================================================*/
48 /* Private macros and constants. */
49 /*==========================================================================*/
51 #define BG_COLOR GL_COLOR (192, 192, 192)
52 #define OUTLINE_COLOR GL_COLOR (173, 216, 230)
53 #define PAPER_COLOR GL_COLOR (255, 255, 255)
54 #define GRID_COLOR BG_COLOR
55 #define MARKUP_COLOR GL_COLOR (240, 100, 100)
57 #define SEL_LINE_COLOR GL_COLOR_A (0, 0, 255, 128)
58 #define SEL_FILL_COLOR GL_COLOR_A (192, 192, 255, 128)
60 /*==========================================================================*/
62 /*==========================================================================*/
74 /*==========================================================================*/
76 /*==========================================================================*/
78 static GtkContainerClass *parent_class;
80 static guint signals[LAST_SIGNAL] = {0};
82 /* "CLIPBOARD" selection */
83 static GdkAtom clipboard_atom = GDK_NONE;
85 static gdouble scales[] = {
90 #define N_SCALES G_N_ELEMENTS(scales)
91 #define HOME_SCALE 2.0
93 /*==========================================================================*/
94 /* Local function prototypes */
95 /*==========================================================================*/
97 static void gl_view_class_init (glViewClass *class);
98 static void gl_view_init (glView *view);
99 static void gl_view_finalize (GObject *object);
101 static void gl_view_construct (glView *view);
102 static GtkWidget *gl_view_construct_canvas (glView *view);
103 static void gl_view_construct_selection (glView *view);
105 static gdouble get_apropriate_scale (gdouble w, gdouble h);
107 static void draw_layers (glView *view);
109 static void draw_label_layer (glView *view);
111 static void draw_highlight_layer (glView *view);
113 static void draw_bg_fg_layers (glView *view);
114 static void draw_bg_fg_rect (glView *view);
115 static void draw_bg_fg_rounded_rect (glView *view);
116 static void draw_bg_fg_round (glView *view);
117 static void draw_bg_fg_cd (glView *view);
119 static void draw_grid_layer (glView *view);
121 static void draw_markup_layer (glView *view);
123 static void draw_markup_margin (glView *view,
124 glTemplateMarkupMargin *margin);
125 static void draw_markup_margin_rect (glView *view,
126 glTemplateMarkupMargin *margin);
127 static void draw_markup_margin_rounded_rect (glView *view,
128 glTemplateMarkupMargin *margin);
129 static void draw_markup_margin_round (glView *view,
130 glTemplateMarkupMargin *margin);
131 static void draw_markup_margin_cd (glView *view,
132 glTemplateMarkupMargin *margin);
134 static void draw_markup_line (glView *view,
135 glTemplateMarkupLine *line);
138 static void select_object_real (glView *view,
139 glViewObject *view_object);
140 static void unselect_object_real (glView *view,
141 glViewObject *view_object);
143 static gboolean object_at (glView *view,
144 gdouble x, gdouble y);
146 static gboolean is_item_member_of_group (glView *view,
147 GnomeCanvasItem *item,
148 GnomeCanvasItem *group);
150 static int canvas_event (GnomeCanvas *canvas,
153 static int canvas_event_arrow_mode (GnomeCanvas *canvas,
157 static void construct_selection_menu (glView *view);
159 static void construct_empty_selection_menu (glView *view);
161 static void selection_clear_cb (GtkWidget *widget,
162 GdkEventSelection *event,
165 static void selection_get_cb (GtkWidget *widget,
166 GtkSelectionData *selection_data,
171 static void selection_received_cb (GtkWidget *widget,
172 GtkSelectionData *selection_data,
176 /****************************************************************************/
177 /* Boilerplate Object stuff. */
178 /****************************************************************************/
180 gl_view_get_type (void)
182 static guint view_type = 0;
185 GTypeInfo view_info = {
186 sizeof (glViewClass),
189 (GClassInitFunc) gl_view_class_init,
194 (GInstanceInitFunc) gl_view_init,
198 g_type_register_static (gtk_vbox_get_type (),
199 "glView", &view_info, 0);
206 gl_view_class_init (glViewClass *class)
208 GObjectClass *object_class = (GObjectClass *) class;
210 gl_debug (DEBUG_VIEW, "START");
212 parent_class = g_type_class_peek_parent (class);
214 object_class->finalize = gl_view_finalize;
216 signals[SELECTION_CHANGED] =
217 g_signal_new ("selection_changed",
218 G_OBJECT_CLASS_TYPE (object_class),
220 G_STRUCT_OFFSET (glViewClass, selection_changed),
222 gl_marshal_VOID__VOID,
226 signals[ZOOM_CHANGED] =
227 g_signal_new ("zoom_changed",
228 G_OBJECT_CLASS_TYPE (object_class),
230 G_STRUCT_OFFSET (glViewClass, zoom_changed),
232 gl_marshal_VOID__DOUBLE,
236 signals[POINTER_MOVED] =
237 g_signal_new ("pointer_moved",
238 G_OBJECT_CLASS_TYPE (object_class),
240 G_STRUCT_OFFSET (glViewClass, pointer_moved),
242 gl_marshal_VOID__DOUBLE_DOUBLE,
244 2, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
246 signals[POINTER_EXIT] =
247 g_signal_new ("pointer_exit",
248 G_OBJECT_CLASS_TYPE (object_class),
250 G_STRUCT_OFFSET (glViewClass, pointer_exit),
252 gl_marshal_VOID__VOID,
256 signals[MODE_CHANGED] =
257 g_signal_new ("mode_changed",
258 G_OBJECT_CLASS_TYPE (object_class),
260 G_STRUCT_OFFSET (glViewClass, mode_changed),
262 gl_marshal_VOID__VOID,
266 gl_debug (DEBUG_VIEW, "END");
270 gl_view_init (glView *view)
272 gl_debug (DEBUG_VIEW, "START");
276 view->grid_spacing = 9;
278 gl_debug (DEBUG_VIEW, "END");
282 gl_view_finalize (GObject *object)
286 gl_debug (DEBUG_VIEW, "START");
288 g_return_if_fail (object != NULL);
289 g_return_if_fail (GL_IS_VIEW (object));
291 view = GL_VIEW (object);
293 G_OBJECT_CLASS (parent_class)->finalize (object);
295 gl_debug (DEBUG_VIEW, "END");
298 /****************************************************************************/
299 /* NEW view object. */
300 /****************************************************************************/
302 gl_view_new (glLabel *label)
304 glView *view = g_object_new (gl_view_get_type (), NULL);
306 gl_debug (DEBUG_VIEW, "START");
310 gl_view_construct (view);
312 gl_debug (DEBUG_VIEW, "END");
314 return GTK_WIDGET (view);
317 /*---------------------------------------------------------------------------*/
318 /* PRIVATE. Construct composite widget. */
319 /*---------------------------------------------------------------------------*/
321 gl_view_construct (glView *view)
323 GtkWidget *wvbox, *wscroll;
325 gl_debug (DEBUG_VIEW, "START");
327 g_return_if_fail (GL_IS_VIEW (view));
329 wvbox = GTK_WIDGET (view);
331 view->state = GL_VIEW_STATE_ARROW;
332 view->object_list = NULL;
334 gl_view_construct_canvas (view);
335 wscroll = gtk_scrolled_window_new (NULL, NULL);
336 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (wscroll),
337 GTK_POLICY_AUTOMATIC,
338 GTK_POLICY_AUTOMATIC);
339 gtk_box_pack_start (GTK_BOX (wvbox), wscroll, TRUE, TRUE, 0);
340 gtk_container_add (GTK_CONTAINER (wscroll), view->canvas);
342 gl_view_construct_selection (view);
344 construct_selection_menu (view);
345 construct_empty_selection_menu (view);
347 gl_debug (DEBUG_VIEW, "END");
350 /*---------------------------------------------------------------------------*/
351 /* PRIVATE. Create canvas w/ a background in the shape of the label/card. */
352 /*---------------------------------------------------------------------------*/
354 gl_view_construct_canvas (glView *view)
357 glLabel *label = view->label;
358 gdouble label_width, label_height;
361 gl_debug (DEBUG_VIEW, "START");
363 g_return_val_if_fail (GL_IS_VIEW (view), NULL);
364 g_return_val_if_fail (label != NULL, NULL);
366 gtk_widget_push_colormap (gdk_rgb_get_colormap ());
367 view->canvas = gnome_canvas_new_aa ();
368 gtk_widget_pop_colormap ();
370 bg_color = gl_color_to_gdk_color (BG_COLOR);
371 gtk_widget_modify_bg (GTK_WIDGET(view->canvas), GTK_STATE_NORMAL, bg_color);
374 gl_label_get_size (label, &label_width, &label_height);
375 gl_debug (DEBUG_VIEW, "Label size: w=%lf, h=%lf",
376 label_width, label_height);
378 scale = get_apropriate_scale (label_width, label_height);
379 gl_debug (DEBUG_VIEW, "scale =%lf", scale);
381 gl_debug (DEBUG_VIEW, "Canvas size: w=%lf, h=%lf",
382 scale * label_width + 40,
383 scale * label_height + 40);
384 gtk_widget_set_size_request (GTK_WIDGET(view->canvas),
385 scale * label_width + 40,
386 scale * label_height + 40);
387 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
391 gnome_canvas_set_scroll_region (GNOME_CANVAS (view->canvas),
392 0.0, 0.0, label_width, label_height);
396 g_signal_connect (G_OBJECT (view->canvas), "event",
397 G_CALLBACK (canvas_event), view);
399 gl_debug (DEBUG_VIEW, "END");
404 /*---------------------------------------------------------------------------*/
405 /* PRIVATE. Create clipboard selection targets. */
406 /*---------------------------------------------------------------------------*/
408 gl_view_construct_selection (glView *view)
410 gl_debug (DEBUG_VIEW, "START");
412 g_return_if_fail (GL_IS_VIEW (view));
414 view->have_selection = FALSE;
415 view->selection_data = NULL;
416 view->invisible = gtk_invisible_new ();
418 view->selected_object_list = NULL;
420 if (!clipboard_atom) {
421 clipboard_atom = gdk_atom_intern ("GLABELS_CLIPBOARD", FALSE);
424 gtk_selection_add_target (view->invisible,
425 clipboard_atom, GDK_SELECTION_TYPE_STRING, 1);
427 g_signal_connect (G_OBJECT (view->invisible),
428 "selection_clear_event",
429 G_CALLBACK (selection_clear_cb), view);
431 g_signal_connect (G_OBJECT (view->invisible), "selection_get",
432 G_CALLBACK (selection_get_cb), view);
434 g_signal_connect (G_OBJECT (view->invisible),
435 "selection_received",
436 G_CALLBACK (selection_received_cb), view);
438 gl_debug (DEBUG_VIEW, "END");
441 /*---------------------------------------------------------------------------*/
442 /* PRIVATE. Determine an apropriate scale for given label & screen size */
443 /*---------------------------------------------------------------------------*/
445 get_apropriate_scale (gdouble w, gdouble h)
447 gdouble w_screen, h_screen;
451 gl_debug (DEBUG_VIEW, "");
453 w_screen = (gdouble) gdk_screen_width ();
454 h_screen = (gdouble) gdk_screen_height ();
456 for (i = 0; i < N_SCALES; i++) {
458 if (k <= HOME_SCALE) {
459 if ((k * w < (w_screen - 256))
460 && (k * h < (h_screen - 256)))
468 /*---------------------------------------------------------------------------*/
469 /* PRIVATE. Create, draw and order layers. */
470 /*---------------------------------------------------------------------------*/
472 draw_layers (glView *view)
474 draw_bg_fg_layers (view);
475 draw_grid_layer (view);
476 draw_markup_layer (view);
477 draw_highlight_layer (view); /* Must be done before label layer */
478 draw_label_layer (view);
480 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->fg_group));
481 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->highlight_group));
484 /*---------------------------------------------------------------------------*/
485 /* PRIVATE. Draw label layer. */
486 /*---------------------------------------------------------------------------*/
488 draw_label_layer (glView *view)
490 GnomeCanvasGroup *group;
493 glLabelObject *object;
494 glViewObject *view_object;
496 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
497 view->label_group = GNOME_CANVAS_GROUP(
498 gnome_canvas_item_new (group,
499 gnome_canvas_group_get_type (),
506 for (p_obj = label->objects; p_obj != NULL; p_obj = p_obj->next) {
507 object = (glLabelObject *) p_obj->data;
509 if (GL_IS_LABEL_BOX (object)) {
510 view_object = gl_view_box_new (GL_LABEL_BOX(object),
512 } else if (GL_IS_LABEL_ELLIPSE (object)) {
513 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object),
515 } else if (GL_IS_LABEL_LINE (object)) {
516 view_object = gl_view_line_new (GL_LABEL_LINE(object),
518 } else if (GL_IS_LABEL_IMAGE (object)) {
519 view_object = gl_view_image_new (GL_LABEL_IMAGE(object),
521 } else if (GL_IS_LABEL_TEXT (object)) {
522 view_object = gl_view_text_new (GL_LABEL_TEXT(object),
524 } else if (GL_IS_LABEL_BARCODE (object)) {
525 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(object),
528 /* Should not happen! */
530 g_warning ("Invalid label object type.");
535 /*---------------------------------------------------------------------------*/
536 /* PRIVATE. Create highlight layer. */
537 /*---------------------------------------------------------------------------*/
539 draw_highlight_layer (glView *view)
541 GnomeCanvasGroup *group;
543 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
544 view->highlight_group = GNOME_CANVAS_GROUP(
545 gnome_canvas_item_new (group,
546 gnome_canvas_group_get_type (),
552 /*---------------------------------------------------------------------------*/
553 /* PRIVATE. Draw background and foreground outlines. */
554 /*---------------------------------------------------------------------------*/
556 draw_bg_fg_layers (glView *view)
559 glTemplate *template;
560 GnomeCanvasGroup *group;
562 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
563 view->bg_group = GNOME_CANVAS_GROUP(
564 gnome_canvas_item_new (group,
565 gnome_canvas_group_get_type (),
569 view->fg_group = GNOME_CANVAS_GROUP(
570 gnome_canvas_item_new (group,
571 gnome_canvas_group_get_type (),
577 template = gl_label_get_template (label);
579 switch (template->label.style) {
581 case GL_TEMPLATE_STYLE_RECT:
582 if (template->label.rect.r == 0.0) {
583 /* Square corners. */
584 draw_bg_fg_rect (view);
586 /* Rounded corners. */
587 draw_bg_fg_rounded_rect (view);
591 case GL_TEMPLATE_STYLE_ROUND:
592 draw_bg_fg_round (view);
595 case GL_TEMPLATE_STYLE_CD:
596 draw_bg_fg_cd (view);
600 g_warning ("Unknown template label style");
605 /*---------------------------------------------------------------------------*/
606 /* PRIVATE. Draw simple recangular background. */
607 /*---------------------------------------------------------------------------*/
609 draw_bg_fg_rect (glView *view)
611 glLabel *label = view->label;
612 glTemplate *template;
614 GnomeCanvasItem *item;
616 gl_debug (DEBUG_VIEW, "START");
618 g_return_if_fail (GL_IS_VIEW (view));
619 g_return_if_fail (label != NULL);
621 gl_label_get_size (label, &w, &h);
622 template = gl_label_get_template (label);
625 item = gnome_canvas_item_new (view->bg_group,
626 gnome_canvas_rect_get_type (),
631 "fill_color_rgba", PAPER_COLOR,
635 item = gnome_canvas_item_new (view->fg_group,
636 gnome_canvas_rect_get_type (),
642 "outline_color_rgba", OUTLINE_COLOR,
645 gl_debug (DEBUG_VIEW, "END");
648 /*---------------------------------------------------------------------------*/
649 /* PRIVATE. Draw rounded recangular background. */
650 /*---------------------------------------------------------------------------*/
652 draw_bg_fg_rounded_rect (glView *view)
654 glLabel *label = view->label;
655 GnomeCanvasPoints *points;
656 gint i_coords, i_theta;
657 glTemplate *template;
659 GnomeCanvasItem *item;
661 gl_debug (DEBUG_VIEW, "START");
663 g_return_if_fail (GL_IS_VIEW (view));
664 g_return_if_fail (label != NULL);
666 gl_label_get_size (label, &w, &h);
667 template = gl_label_get_template (label);
668 r = template->label.rect.r;
670 points = gnome_canvas_points_new (4 * (1 + 90 / 5));
672 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
673 points->coords[i_coords++] =
674 r - r * sin (i_theta * G_PI / 180.0);
675 points->coords[i_coords++] =
676 r - r * cos (i_theta * G_PI / 180.0);
678 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
679 points->coords[i_coords++] =
680 r - r * cos (i_theta * G_PI / 180.0);
681 points->coords[i_coords++] =
682 (h - r) + r * sin (i_theta * G_PI / 180.0);
684 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
685 points->coords[i_coords++] =
686 (w - r) + r * sin (i_theta * G_PI / 180.0);
687 points->coords[i_coords++] =
688 (h - r) + r * cos (i_theta * G_PI / 180.0);
690 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
691 points->coords[i_coords++] =
692 (w - r) + r * cos (i_theta * G_PI / 180.0);
693 points->coords[i_coords++] =
694 r - r * sin (i_theta * G_PI / 180.0);
698 item = gnome_canvas_item_new (view->bg_group,
699 gnome_canvas_polygon_get_type (),
701 "fill_color_rgba", PAPER_COLOR,
705 item = gnome_canvas_item_new (view->fg_group,
706 gnome_canvas_polygon_get_type (),
709 "outline_color_rgba", OUTLINE_COLOR,
712 gnome_canvas_points_free (points);
714 gl_debug (DEBUG_VIEW, "END");
717 /*---------------------------------------------------------------------------*/
718 /* PRIVATE. Draw round background. */
719 /*---------------------------------------------------------------------------*/
721 draw_bg_fg_round (glView *view)
723 glLabel *label = view->label;
724 glTemplate *template;
726 GnomeCanvasItem *item;
728 gl_debug (DEBUG_VIEW, "START");
730 g_return_if_fail (GL_IS_VIEW (view));
731 g_return_if_fail (label != NULL);
733 template = gl_label_get_template (label);
735 r = template->label.round.r;
738 item = gnome_canvas_item_new (view->bg_group,
739 gnome_canvas_ellipse_get_type (),
744 "fill_color_rgba", PAPER_COLOR,
748 item = gnome_canvas_item_new (view->fg_group,
749 gnome_canvas_ellipse_get_type (),
755 "outline_color_rgba", OUTLINE_COLOR,
758 gl_debug (DEBUG_VIEW, "END");
761 /*---------------------------------------------------------------------------*/
762 /* PRIVATE. Draw CD style background, circular w/ concentric hole. */
763 /*---------------------------------------------------------------------------*/
765 draw_bg_fg_cd (glView *view)
767 glLabel *label = view->label;
768 glTemplate *template;
770 GnomeCanvasItem *item;
772 gl_debug (DEBUG_VIEW, "START");
774 g_return_if_fail (GL_IS_VIEW (view));
775 g_return_if_fail (label != NULL);
777 template = gl_label_get_template (label);
779 r1 = template->label.cd.r1;
780 r2 = template->label.cd.r2;
784 item = gnome_canvas_item_new (view->bg_group,
785 gnome_canvas_ellipse_get_type (),
790 "fill_color_rgba", PAPER_COLOR,
793 item = gnome_canvas_item_new (view->bg_group,
794 gnome_canvas_ellipse_get_type (),
799 "fill_color_rgba", GRID_COLOR,
804 item = gnome_canvas_item_new (view->fg_group,
805 gnome_canvas_ellipse_get_type (),
811 "outline_color_rgba", OUTLINE_COLOR,
814 item = gnome_canvas_item_new (view->fg_group,
815 gnome_canvas_ellipse_get_type (),
821 "outline_color_rgba", OUTLINE_COLOR,
824 gl_debug (DEBUG_VIEW, "END");
827 /*---------------------------------------------------------------------------*/
828 /* PRIVATE. Draw grid lines. */
829 /*---------------------------------------------------------------------------*/
831 draw_grid_layer (glView *view)
834 GnomeCanvasPoints *points;
835 GnomeCanvasItem *item;
836 GnomeCanvasGroup *group;
838 gl_debug (DEBUG_VIEW, "START");
840 g_return_if_fail (view && GL_IS_VIEW (view));
841 g_return_if_fail (view->label && GL_IS_LABEL(view->label));
843 gl_label_get_size (view->label, &w, &h);
845 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
846 view->grid_group = GNOME_CANVAS_GROUP(
847 gnome_canvas_item_new (group,
848 gnome_canvas_group_get_type (),
852 points = gnome_canvas_points_new (2);
854 points->coords[1] = 0.0;
855 points->coords[3] = h;
856 for ( x=0.0; x < w; x += view->grid_spacing ) {
857 points->coords[0] = points->coords[2] = x;
858 item = gnome_canvas_item_new (view->grid_group,
859 gnome_canvas_line_get_type (),
862 "fill_color_rgba", GRID_COLOR,
865 points->coords[0] = points->coords[2] = w;
866 item = gnome_canvas_item_new (view->grid_group,
867 gnome_canvas_line_get_type (),
870 "fill_color_rgba", GRID_COLOR,
873 points->coords[0] = 0.0;
874 points->coords[2] = w;
875 for ( y=0.0; y < h; y += view->grid_spacing ) {
876 points->coords[1] = points->coords[3] = y;
877 item = gnome_canvas_item_new (view->grid_group,
878 gnome_canvas_line_get_type (),
881 "fill_color_rgba", GRID_COLOR,
884 points->coords[1] = points->coords[3] = h;
885 item = gnome_canvas_item_new (view->grid_group,
886 gnome_canvas_line_get_type (),
889 "fill_color_rgba", GRID_COLOR,
892 gnome_canvas_points_free (points);
894 gl_debug (DEBUG_VIEW, "END");
897 /*---------------------------------------------------------------------------*/
898 /* PRIVATE. Draw markup lines. */
899 /*---------------------------------------------------------------------------*/
901 draw_markup_layer (glView *view)
903 GnomeCanvasGroup *group;
905 glTemplate *template;
907 glTemplateMarkup *markup;
909 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
910 view->markup_group = GNOME_CANVAS_GROUP(
911 gnome_canvas_item_new (group,
912 gnome_canvas_group_get_type (),
917 template = gl_label_get_template (label);
919 for ( p=template->label.any.markups; p != NULL; p=p->next ) {
920 markup = (glTemplateMarkup *)p->data;
922 switch (markup->type) {
923 case GL_TEMPLATE_MARKUP_MARGIN:
924 draw_markup_margin (view,
925 (glTemplateMarkupMargin *)markup);
927 case GL_TEMPLATE_MARKUP_LINE:
928 draw_markup_line (view,
929 (glTemplateMarkupLine *)markup);
932 g_warning ("Unknown template markup type");
938 /*---------------------------------------------------------------------------*/
939 /* PRIVATE. Draw margin markup. */
940 /*---------------------------------------------------------------------------*/
942 draw_markup_margin (glView *view,
943 glTemplateMarkupMargin *margin)
946 glTemplate *template;
949 template = gl_label_get_template (label);
951 switch (template->label.style) {
953 case GL_TEMPLATE_STYLE_RECT:
954 if (template->label.rect.r == 0.0) {
955 /* Square corners. */
956 draw_markup_margin_rect (view, margin);
958 if ( margin->size < template->label.rect.r) {
959 /* Rounded corners. */
960 draw_markup_margin_rounded_rect (view, margin);
962 /* Square corners. */
963 draw_markup_margin_rect (view, margin);
968 case GL_TEMPLATE_STYLE_ROUND:
969 draw_markup_margin_round (view, margin);
972 case GL_TEMPLATE_STYLE_CD:
973 draw_markup_margin_cd (view, margin);
977 g_warning ("Unknown template label style");
982 /*---------------------------------------------------------------------------*/
983 /* PRIVATE. Draw simple recangular margin. */
984 /*---------------------------------------------------------------------------*/
986 draw_markup_margin_rect (glView *view,
987 glTemplateMarkupMargin *margin)
989 glLabel *label = view->label;
990 glTemplate *template;
992 GnomeCanvasItem *item;
994 gl_debug (DEBUG_VIEW, "START");
996 g_return_if_fail (GL_IS_VIEW (view));
997 g_return_if_fail (label != NULL);
999 gl_label_get_size (label, &w, &h);
1000 template = gl_label_get_template (label);
1003 /* Bounding box @ margin */
1004 gnome_canvas_item_new (view->markup_group,
1005 gnome_canvas_rect_get_type (),
1011 "outline_color_rgba", MARKUP_COLOR,
1014 gl_debug (DEBUG_VIEW, "END");
1017 /*---------------------------------------------------------------------------*/
1018 /* PRIVATE. Draw rounded recangular markup. */
1019 /*---------------------------------------------------------------------------*/
1021 draw_markup_margin_rounded_rect (glView *view,
1022 glTemplateMarkupMargin *margin)
1024 glLabel *label = view->label;
1025 GnomeCanvasPoints *points;
1026 gint i_coords, i_theta;
1027 glTemplate *template;
1029 GnomeCanvasItem *item;
1031 gl_debug (DEBUG_VIEW, "START");
1033 g_return_if_fail (GL_IS_VIEW (view));
1034 g_return_if_fail (label != NULL);
1036 gl_label_get_size (label, &w, &h);
1037 template = gl_label_get_template (label);
1038 r = template->label.rect.r;
1045 /* rectangle with rounded corners */
1046 points = gnome_canvas_points_new (4 * (1 + 90 / 5));
1048 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
1049 points->coords[i_coords++] =
1050 m + r - r * sin (i_theta * G_PI / 180.0);
1051 points->coords[i_coords++] =
1052 m + r - r * cos (i_theta * G_PI / 180.0);
1054 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
1055 points->coords[i_coords++] =
1056 m + r - r * cos (i_theta * G_PI / 180.0);
1057 points->coords[i_coords++] =
1058 m + (h - r) + r * sin (i_theta * G_PI / 180.0);
1060 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
1061 points->coords[i_coords++] =
1062 m + (w - r) + r * sin (i_theta * G_PI / 180.0);
1063 points->coords[i_coords++] =
1064 m + (h - r) + r * cos (i_theta * G_PI / 180.0);
1066 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
1067 points->coords[i_coords++] =
1068 m + (w - r) + r * cos (i_theta * G_PI / 180.0);
1069 points->coords[i_coords++] =
1070 m + r - r * sin (i_theta * G_PI / 180.0);
1072 item = gnome_canvas_item_new (view->markup_group,
1073 gnome_canvas_polygon_get_type (),
1076 "outline_color_rgba", MARKUP_COLOR,
1078 gnome_canvas_points_free (points);
1080 gl_debug (DEBUG_VIEW, "END");
1083 /*---------------------------------------------------------------------------*/
1084 /* PRIVATE. Draw round margin. */
1085 /*---------------------------------------------------------------------------*/
1087 draw_markup_margin_round (glView *view,
1088 glTemplateMarkupMargin *margin)
1090 glLabel *label = view->label;
1091 glTemplate *template;
1093 GnomeCanvasItem *item;
1095 gl_debug (DEBUG_VIEW, "START");
1097 g_return_if_fail (GL_IS_VIEW (view));
1098 g_return_if_fail (label != NULL);
1100 template = gl_label_get_template (label);
1102 r = template->label.round.r;
1105 /* Margin outline */
1106 item = gnome_canvas_item_new (view->markup_group,
1107 gnome_canvas_ellipse_get_type (),
1113 "outline_color_rgba", MARKUP_COLOR,
1116 gl_debug (DEBUG_VIEW, "END");
1119 /*---------------------------------------------------------------------------*/
1120 /* PRIVATE. Draw CD margins. */
1121 /*---------------------------------------------------------------------------*/
1123 draw_markup_margin_cd (glView *view,
1124 glTemplateMarkupMargin *margin)
1126 glLabel *label = view->label;
1127 glTemplate *template;
1129 GnomeCanvasItem *item;
1131 gl_debug (DEBUG_VIEW, "START");
1133 g_return_if_fail (GL_IS_VIEW (view));
1134 g_return_if_fail (label != NULL);
1136 template = gl_label_get_template (label);
1138 r1 = template->label.cd.r1;
1139 r2 = template->label.cd.r2;
1143 item = gnome_canvas_item_new (view->markup_group,
1144 gnome_canvas_ellipse_get_type (),
1150 "outline_color_rgba", MARKUP_COLOR,
1153 item = gnome_canvas_item_new (view->markup_group,
1154 gnome_canvas_ellipse_get_type (),
1160 "outline_color_rgba", MARKUP_COLOR,
1163 gl_debug (DEBUG_VIEW, "END");
1166 /*---------------------------------------------------------------------------*/
1167 /* PRIVATE. Draw line markup. */
1168 /*---------------------------------------------------------------------------*/
1170 draw_markup_line (glView *view,
1171 glTemplateMarkupLine *line)
1173 GnomeCanvasPoints *points;
1175 gl_debug (DEBUG_VIEW, "START");
1177 g_return_if_fail (GL_IS_VIEW (view));
1179 points = gnome_canvas_points_new (2);
1180 points->coords[0] = line->x1;
1181 points->coords[1] = line->y1;
1182 points->coords[2] = line->x2;
1183 points->coords[3] = line->y2;
1185 /* Bounding box @ margin */
1186 gnome_canvas_item_new (view->markup_group,
1187 gnome_canvas_line_get_type (),
1190 "fill_color_rgba", MARKUP_COLOR,
1193 gnome_canvas_points_free (points);
1195 gl_debug (DEBUG_VIEW, "END");
1198 /*****************************************************************************/
1200 /*****************************************************************************/
1201 void gl_view_show_grid (glView *view)
1203 gnome_canvas_item_show (GNOME_CANVAS_ITEM(view->grid_group));
1206 /*****************************************************************************/
1208 /*****************************************************************************/
1209 void gl_view_hide_grid (glView *view)
1211 gnome_canvas_item_hide (GNOME_CANVAS_ITEM(view->grid_group));
1214 /*****************************************************************************/
1215 /* Set grid spacing. */
1216 /*****************************************************************************/
1217 void gl_view_set_grid_spacing (glView *view,
1220 view->grid_spacing = spacing;
1222 gtk_object_destroy (GTK_OBJECT(view->grid_group));
1223 draw_grid_layer (view);
1226 /*****************************************************************************/
1228 /*****************************************************************************/
1229 void gl_view_show_markup (glView *view)
1231 gnome_canvas_item_show (GNOME_CANVAS_ITEM(view->markup_group));
1234 /*****************************************************************************/
1236 /*****************************************************************************/
1237 void gl_view_hide_markup (glView *view)
1239 gnome_canvas_item_hide (GNOME_CANVAS_ITEM(view->markup_group));
1242 /*****************************************************************************/
1243 /* Set arrow mode. */
1244 /*****************************************************************************/
1246 gl_view_arrow_mode (glView *view)
1248 static GdkCursor *cursor = NULL;
1250 gl_debug (DEBUG_VIEW, "START");
1252 g_return_if_fail (GL_IS_VIEW (view));
1255 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1258 gdk_window_set_cursor (view->canvas->window, cursor);
1260 view->state = GL_VIEW_STATE_ARROW;
1262 gl_debug (DEBUG_VIEW, "END");
1265 /*****************************************************************************/
1266 /* Set create text object mode. */
1267 /*****************************************************************************/
1269 gl_view_object_create_mode (glView *view,
1270 glLabelObjectType type)
1274 gl_debug (DEBUG_VIEW, "START");
1276 g_return_if_fail (GL_IS_VIEW (view));
1279 case GL_LABEL_OBJECT_BOX:
1280 cursor = gl_view_box_get_create_cursor ();
1282 case GL_LABEL_OBJECT_ELLIPSE:
1283 cursor = gl_view_ellipse_get_create_cursor ();
1285 case GL_LABEL_OBJECT_LINE:
1286 cursor = gl_view_line_get_create_cursor ();
1288 case GL_LABEL_OBJECT_IMAGE:
1289 cursor = gl_view_image_get_create_cursor ();
1291 case GL_LABEL_OBJECT_TEXT:
1292 cursor = gl_view_text_get_create_cursor ();
1294 case GL_LABEL_OBJECT_BARCODE:
1295 cursor = gl_view_barcode_get_create_cursor ();
1298 g_warning ("Invalid label object type.");/*Should not happen!*/
1302 gdk_window_set_cursor (view->canvas->window, cursor);
1304 view->state = GL_VIEW_STATE_OBJECT_CREATE;
1305 view->create_type = type;
1307 gl_debug (DEBUG_VIEW, "END");
1310 /*****************************************************************************/
1311 /* Select given object (adding to current selection). */
1312 /*****************************************************************************/
1314 gl_view_select_object (glView *view,
1315 glViewObject *view_object)
1317 gl_debug (DEBUG_VIEW, "START");
1319 select_object_real (view, view_object);
1321 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1323 gl_debug (DEBUG_VIEW, "END");
1326 /*****************************************************************************/
1327 /* Unselect given object (removing from current selection). */
1328 /*****************************************************************************/
1330 gl_view_unselect_object (glView *view,
1331 glViewObject *view_object)
1333 gl_debug (DEBUG_VIEW, "START");
1335 unselect_object_real (view, view_object);
1337 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1339 gl_debug (DEBUG_VIEW, "END");
1342 /*****************************************************************************/
1343 /* Select all items. */
1344 /*****************************************************************************/
1346 gl_view_select_all (glView *view)
1350 gl_debug (DEBUG_VIEW, "START");
1352 g_return_if_fail (GL_IS_VIEW (view));
1354 /* 1st unselect anything already selected. */
1355 for (p = view->selected_object_list; p != NULL; p = p_next) {
1357 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1360 /* Finally select all objects. */
1361 for (p = view->object_list; p != NULL; p = p->next) {
1362 select_object_real (view, GL_VIEW_OBJECT (p->data));
1365 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1367 gl_debug (DEBUG_VIEW, "END");
1370 /*****************************************************************************/
1371 /* Remove all selections */
1372 /*****************************************************************************/
1374 gl_view_unselect_all (glView *view)
1378 gl_debug (DEBUG_VIEW, "START");
1380 g_return_if_fail (GL_IS_VIEW (view));
1382 for (p = view->selected_object_list; p != NULL; p = p_next) {
1384 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1387 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1389 gl_debug (DEBUG_VIEW, "END");
1392 /*****************************************************************************/
1393 /* Select all objects within given rectangular region (adding to selection). */
1394 /*****************************************************************************/
1396 gl_view_select_region (glView *view,
1403 glViewObject *view_object;
1404 glLabelObject *object;
1405 gdouble i_x1, i_y1, i_x2, i_y2;
1407 gl_debug (DEBUG_VIEW, "START");
1409 g_return_if_fail (GL_IS_VIEW (view));
1410 g_return_if_fail ((x1 <= x2) && (y1 <= y2));
1412 for (p = view->object_list; p != NULL; p = p->next) {
1413 view_object = GL_VIEW_OBJECT(p->data);
1414 if (!gl_view_is_object_selected (view, view_object)) {
1416 object = gl_view_object_get_object (view_object);
1418 gl_label_object_get_extent (object, &i_x1, &i_y1, &i_x2, &i_y2);
1419 if ((i_x1 >= x1) && (i_x2 <= x2) && (i_y1 >= y1)
1421 select_object_real (view, view_object);
1427 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1429 gl_debug (DEBUG_VIEW, "END");
1432 /*---------------------------------------------------------------------------*/
1433 /* PRIVATE. Select an object. */
1434 /*---------------------------------------------------------------------------*/
1436 select_object_real (glView *view,
1437 glViewObject *view_object)
1439 gl_debug (DEBUG_VIEW, "START");
1441 g_return_if_fail (GL_IS_VIEW (view));
1442 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1444 if (!gl_view_is_object_selected (view, view_object)) {
1445 view->selected_object_list =
1446 g_list_prepend (view->selected_object_list, view_object);
1448 gl_view_object_show_highlight (view_object);
1449 gtk_widget_grab_focus (GTK_WIDGET (view->canvas));
1451 gl_debug (DEBUG_VIEW, "END");
1454 /*---------------------------------------------------------------------------*/
1455 /* PRIVATE. Un-select object. */
1456 /*---------------------------------------------------------------------------*/
1458 unselect_object_real (glView *view,
1459 glViewObject *view_object)
1461 gl_debug (DEBUG_VIEW, "START");
1463 g_return_if_fail (GL_IS_VIEW (view));
1464 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1466 gl_view_object_hide_highlight (view_object);
1468 view->selected_object_list =
1469 g_list_remove (view->selected_object_list, view_object);
1471 gl_debug (DEBUG_VIEW, "END");
1474 /*---------------------------------------------------------------------------*/
1475 /* PRIVATE. Return object at (x,y). */
1476 /*---------------------------------------------------------------------------*/
1478 object_at (glView *view,
1482 GnomeCanvasItem *item, *p_item;
1485 gl_debug (DEBUG_VIEW, "");
1487 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1489 item = gnome_canvas_get_item_at (GNOME_CANVAS (view->canvas), x, y);
1491 /* No item is at x, y */
1495 /* ignore items not in label or highlight layers, e.g. background items */
1496 if (!is_item_member_of_group(view, item, GNOME_CANVAS_ITEM(view->label_group)) &&
1497 !is_item_member_of_group(view, item, GNOME_CANVAS_ITEM(view->highlight_group)))
1503 /*---------------------------------------------------------------------------*/
1504 /* PRIVATE. Is the item a child (or grandchild, etc.) of group. */
1505 /*---------------------------------------------------------------------------*/
1507 is_item_member_of_group (glView *view,
1508 GnomeCanvasItem *item,
1509 GnomeCanvasItem *group)
1511 GnomeCanvasItem *parent;
1512 GnomeCanvasItem *root_group;
1514 root_group = GNOME_CANVAS_ITEM(gnome_canvas_root (GNOME_CANVAS (view->canvas)));
1516 for ( parent=item->parent; parent && (parent!=root_group); parent=parent->parent) {
1517 if (parent == group) return TRUE;
1522 /*****************************************************************************/
1523 /* Is the object in our current selection? */
1524 /*****************************************************************************/
1526 gl_view_is_object_selected (glView *view,
1527 glViewObject *view_object)
1529 gl_debug (DEBUG_VIEW, "");
1531 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1532 g_return_val_if_fail (GL_IS_VIEW_OBJECT (view_object), FALSE);
1534 if (g_list_find (view->selected_object_list, view_object) == NULL) {
1540 /*****************************************************************************/
1541 /* Is our current selection empty? */
1542 /*****************************************************************************/
1544 gl_view_is_selection_empty (glView *view)
1546 gl_debug (DEBUG_VIEW, "");
1548 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1550 if (view->selected_object_list == NULL) {
1557 /*****************************************************************************/
1558 /* Is our current selection atomic? I.e. only one item selected. */
1559 /*****************************************************************************/
1561 gl_view_is_selection_atomic (glView *view)
1563 gl_debug (DEBUG_VIEW, "");
1565 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1567 if (view->selected_object_list == NULL)
1569 if (view->selected_object_list->next == NULL)
1574 /*****************************************************************************/
1575 /* Delete selected objects. (Bypass clipboard) */
1576 /*****************************************************************************/
1578 gl_view_delete_selection (glView *view)
1582 gl_debug (DEBUG_VIEW, "START");
1584 g_return_if_fail (GL_IS_VIEW (view));
1586 for (p = view->selected_object_list; p != NULL; p = p_next) {
1588 g_object_unref (G_OBJECT (p->data));
1591 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1593 gl_debug (DEBUG_VIEW, "END");
1596 /*****************************************************************************/
1597 /* Edit properties of selected object. */
1598 /*****************************************************************************/
1600 gl_view_edit_object_props (glView *view)
1602 glViewObject *view_object;
1604 gl_debug (DEBUG_VIEW, "START");
1606 g_return_if_fail (GL_IS_VIEW (view));
1608 if (gl_view_is_selection_atomic (view)) {
1610 view_object = GL_VIEW_OBJECT(view->selected_object_list->data);
1611 gl_view_object_show_dialog (view_object);
1615 gl_debug (DEBUG_VIEW, "END");
1618 /*****************************************************************************/
1619 /* Raise selected items to top. */
1620 /*****************************************************************************/
1622 gl_view_raise_selection (glView *view)
1625 glViewObject *view_object;
1626 glLabelObject *object;
1628 gl_debug (DEBUG_VIEW, "START");
1630 g_return_if_fail (GL_IS_VIEW (view));
1632 for (p = view->selected_object_list; p != NULL; p = p->next) {
1633 view_object = GL_VIEW_OBJECT (p->data);
1634 object = gl_view_object_get_object (view_object);
1635 gl_label_object_raise_to_top (object);
1638 gl_debug (DEBUG_VIEW, "END");
1641 /*****************************************************************************/
1642 /* Lower selected items to bottom. */
1643 /*****************************************************************************/
1645 gl_view_lower_selection (glView *view)
1648 glViewObject *view_object;
1649 glLabelObject *object;
1651 gl_debug (DEBUG_VIEW, "START");
1653 g_return_if_fail (GL_IS_VIEW (view));
1655 for (p = view->selected_object_list; p != NULL; p = p->next) {
1656 view_object = GL_VIEW_OBJECT (p->data);
1657 object = gl_view_object_get_object (view_object);
1658 gl_label_object_lower_to_bottom (object);
1661 gl_debug (DEBUG_VIEW, "END");
1664 /*****************************************************************************/
1665 /* Rotate selected objects by given angle. */
1666 /*****************************************************************************/
1668 gl_view_rotate_selection (glView *view,
1672 glViewObject *view_object;
1673 glLabelObject *object;
1675 gl_debug (DEBUG_VIEW, "START");
1677 g_return_if_fail (GL_IS_VIEW (view));
1679 for (p = view->selected_object_list; p != NULL; p = p->next) {
1680 view_object = GL_VIEW_OBJECT (p->data);
1681 object = gl_view_object_get_object (view_object);
1682 gl_label_object_rotate (object, theta_degs);
1685 gl_debug (DEBUG_VIEW, "END");
1688 /*****************************************************************************/
1689 /* Rotate selected objects 90 degrees left. */
1690 /*****************************************************************************/
1692 gl_view_rotate_selection_left (glView *view)
1695 glViewObject *view_object;
1696 glLabelObject *object;
1698 gl_debug (DEBUG_VIEW, "START");
1700 g_return_if_fail (GL_IS_VIEW (view));
1702 for (p = view->selected_object_list; p != NULL; p = p->next) {
1703 view_object = GL_VIEW_OBJECT (p->data);
1704 object = gl_view_object_get_object (view_object);
1705 gl_label_object_rotate (object, -90.0);
1708 gl_debug (DEBUG_VIEW, "END");
1711 /*****************************************************************************/
1712 /* Rotate selected objects 90 degrees right. */
1713 /*****************************************************************************/
1715 gl_view_rotate_selection_right (glView *view)
1718 glViewObject *view_object;
1719 glLabelObject *object;
1721 gl_debug (DEBUG_VIEW, "START");
1723 g_return_if_fail (GL_IS_VIEW (view));
1725 for (p = view->selected_object_list; p != NULL; p = p->next) {
1726 view_object = GL_VIEW_OBJECT (p->data);
1727 object = gl_view_object_get_object (view_object);
1728 gl_label_object_rotate (object, 90.0);
1731 gl_debug (DEBUG_VIEW, "END");
1734 /*****************************************************************************/
1735 /* Flip selected objects horizontally. */
1736 /*****************************************************************************/
1738 gl_view_flip_selection_horiz (glView *view)
1741 glViewObject *view_object;
1742 glLabelObject *object;
1744 gl_debug (DEBUG_VIEW, "START");
1746 g_return_if_fail (GL_IS_VIEW (view));
1748 for (p = view->selected_object_list; p != NULL; p = p->next) {
1749 view_object = GL_VIEW_OBJECT (p->data);
1750 object = gl_view_object_get_object (view_object);
1751 gl_label_object_flip_horiz (object);
1754 gl_debug (DEBUG_VIEW, "END");
1757 /*****************************************************************************/
1758 /* Flip selected objects vertically. */
1759 /*****************************************************************************/
1761 gl_view_flip_selection_vert (glView *view)
1764 glViewObject *view_object;
1765 glLabelObject *object;
1767 gl_debug (DEBUG_VIEW, "START");
1769 g_return_if_fail (GL_IS_VIEW (view));
1771 for (p = view->selected_object_list; p != NULL; p = p->next) {
1772 view_object = GL_VIEW_OBJECT (p->data);
1773 object = gl_view_object_get_object (view_object);
1774 gl_label_object_flip_vert (object);
1777 gl_debug (DEBUG_VIEW, "END");
1780 /*****************************************************************************/
1781 /* Align selected objects to left most edge. */
1782 /*****************************************************************************/
1784 gl_view_align_selection_left (glView *view)
1787 glViewObject *view_object;
1788 glLabelObject *object;
1789 gdouble dx, x1min, x1, y1, x2, y2;
1791 gl_debug (DEBUG_VIEW, "START");
1793 g_return_if_fail (GL_IS_VIEW (view));
1795 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1796 !gl_view_is_selection_atomic (view));
1798 /* find left most edge */
1799 p = view->selected_object_list;
1800 view_object = GL_VIEW_OBJECT (p->data);
1801 object = gl_view_object_get_object (view_object);
1802 gl_label_object_get_extent (object, &x1min, &y1, &x2, &y2);
1803 for (p = p->next; p != NULL; p = p->next) {
1804 view_object = GL_VIEW_OBJECT (p->data);
1805 object = gl_view_object_get_object (view_object);
1806 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1807 if ( x1 < x1min ) x1min = x1;
1810 /* now adjust the object positions to line up the left edges */
1811 for (p = view->selected_object_list; p != NULL; p = p->next) {
1812 view_object = GL_VIEW_OBJECT (p->data);
1813 object = gl_view_object_get_object (view_object);
1814 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1816 gl_label_object_set_position_relative (object, dx, 0.0);
1819 gl_debug (DEBUG_VIEW, "END");
1823 /*****************************************************************************/
1824 /* Align selected objects to right most edge. */
1825 /*****************************************************************************/
1827 gl_view_align_selection_right (glView *view)
1830 glViewObject *view_object;
1831 glLabelObject *object;
1832 gdouble dx, x2max, x1, y1, x2, y2;
1834 gl_debug (DEBUG_VIEW, "START");
1836 g_return_if_fail (GL_IS_VIEW (view));
1838 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1839 !gl_view_is_selection_atomic (view));
1841 /* find right most edge */
1842 p = view->selected_object_list;
1843 view_object = GL_VIEW_OBJECT (p->data);
1844 object = gl_view_object_get_object (view_object);
1845 gl_label_object_get_extent (object, &x1, &y1, &x2max, &y2);
1846 for (p = p->next; p != NULL; p = p->next) {
1847 view_object = GL_VIEW_OBJECT (p->data);
1848 object = gl_view_object_get_object (view_object);
1849 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1850 if ( x2 > x2max ) x2max = x2;
1853 /* now adjust the object positions to line up the right edges */
1854 for (p = view->selected_object_list; p != NULL; p = p->next) {
1855 view_object = GL_VIEW_OBJECT (p->data);
1856 object = gl_view_object_get_object (view_object);
1857 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1859 gl_label_object_set_position_relative (object, dx, 0.0);
1862 gl_debug (DEBUG_VIEW, "END");
1865 /*****************************************************************************/
1866 /* Align selected objects to horizontal center of objects. */
1867 /*****************************************************************************/
1869 gl_view_align_selection_hcenter (glView *view)
1872 glViewObject *view_object;
1873 glLabelObject *object;
1874 gdouble dx, dxmin, xsum, xavg, xcenter, x1, y1, x2, y2;
1877 gl_debug (DEBUG_VIEW, "START");
1879 g_return_if_fail (GL_IS_VIEW (view));
1881 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1882 !gl_view_is_selection_atomic (view));
1884 /* find average center of objects */
1887 for (p = view->selected_object_list; p != NULL; p = p->next) {
1888 view_object = GL_VIEW_OBJECT (p->data);
1889 object = gl_view_object_get_object (view_object);
1890 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1891 xsum += (x1 + x2) / 2.0;
1896 /* find center of object closest to average center */
1897 p = view->selected_object_list;
1898 view_object = GL_VIEW_OBJECT (p->data);
1899 object = gl_view_object_get_object (view_object);
1900 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1901 dxmin = fabs (xavg - (x1 + x2)/2.0);
1902 xcenter = (x1 + x2)/2.0;
1903 for (p = p->next; p != NULL; p = p->next) {
1904 view_object = GL_VIEW_OBJECT (p->data);
1905 object = gl_view_object_get_object (view_object);
1906 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1907 dx = fabs (xavg - (x1 + x2)/2.0);
1910 xcenter = (x1 + x2)/2.0;
1914 /* now adjust the object positions to line up this center */
1915 for (p = view->selected_object_list; p != NULL; p = p->next) {
1916 view_object = GL_VIEW_OBJECT (p->data);
1917 object = gl_view_object_get_object (view_object);
1918 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1919 dx = xcenter - (x1 + x2)/2.0;
1920 gl_label_object_set_position_relative (object, dx, 0.0);
1923 gl_debug (DEBUG_VIEW, "END");
1926 /*****************************************************************************/
1927 /* Align selected objects to top most edge. */
1928 /*****************************************************************************/
1930 gl_view_align_selection_top (glView *view)
1933 glViewObject *view_object;
1934 glLabelObject *object;
1935 gdouble dy, y1min, x1, y1, x2, y2;
1937 gl_debug (DEBUG_VIEW, "START");
1939 g_return_if_fail (GL_IS_VIEW (view));
1941 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1942 !gl_view_is_selection_atomic (view));
1944 /* find top most edge */
1945 p = view->selected_object_list;
1946 view_object = GL_VIEW_OBJECT (p->data);
1947 object = gl_view_object_get_object (view_object);
1948 gl_label_object_get_extent (object, &x1, &y1min, &x2, &y2);
1949 for (p = p->next; p != NULL; p = p->next) {
1950 view_object = GL_VIEW_OBJECT (p->data);
1951 object = gl_view_object_get_object (view_object);
1952 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1953 if ( y1 < y1min ) y1min = y1;
1956 /* now adjust the object positions to line up the top edges */
1957 for (p = view->selected_object_list; p != NULL; p = p->next) {
1958 view_object = GL_VIEW_OBJECT (p->data);
1959 object = gl_view_object_get_object (view_object);
1960 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1962 gl_label_object_set_position_relative (object, 0.0, dy);
1965 gl_debug (DEBUG_VIEW, "END");
1968 /*****************************************************************************/
1969 /* Align selected objects to bottom most edge. */
1970 /*****************************************************************************/
1972 gl_view_align_selection_bottom (glView *view)
1975 glViewObject *view_object;
1976 glLabelObject *object;
1977 gdouble dy, y2max, x1, y1, x2, y2;
1979 gl_debug (DEBUG_VIEW, "START");
1981 g_return_if_fail (GL_IS_VIEW (view));
1983 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1984 !gl_view_is_selection_atomic (view));
1986 /* find bottom most edge */
1987 p = view->selected_object_list;
1988 view_object = GL_VIEW_OBJECT (p->data);
1989 object = gl_view_object_get_object (view_object);
1990 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2max);
1991 for (p = p->next; p != NULL; p = p->next) {
1992 view_object = GL_VIEW_OBJECT (p->data);
1993 object = gl_view_object_get_object (view_object);
1994 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1995 if ( y2 > y2max ) y2max = y2;
1998 /* now adjust the object positions to line up the bottom edges */
1999 for (p = view->selected_object_list; p != NULL; p = p->next) {
2000 view_object = GL_VIEW_OBJECT (p->data);
2001 object = gl_view_object_get_object (view_object);
2002 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2004 gl_label_object_set_position_relative (object, 0.0, dy);
2007 gl_debug (DEBUG_VIEW, "END");
2010 /*****************************************************************************/
2011 /* Align selected objects to viertical center of objects. */
2012 /*****************************************************************************/
2014 gl_view_align_selection_vcenter (glView *view)
2017 glViewObject *view_object;
2018 glLabelObject *object;
2019 gdouble dy, dymin, ysum, yavg, ycenter, x1, y1, x2, y2;
2022 gl_debug (DEBUG_VIEW, "START");
2024 g_return_if_fail (GL_IS_VIEW (view));
2026 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2027 !gl_view_is_selection_atomic (view));
2029 /* find average center of objects */
2032 for (p = view->selected_object_list; p != NULL; p = p->next) {
2033 view_object = GL_VIEW_OBJECT (p->data);
2034 object = gl_view_object_get_object (view_object);
2035 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2036 ysum += (y1 + y2) / 2.0;
2041 /* find center of object closest to average center */
2042 p = view->selected_object_list;
2043 view_object = GL_VIEW_OBJECT (p->data);
2044 object = gl_view_object_get_object (view_object);
2045 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2046 dymin = fabs (yavg - (y1 + y2)/2.0);
2047 ycenter = (y1 + y2)/2.0;
2048 for (p = p->next; p != NULL; p = p->next) {
2049 view_object = GL_VIEW_OBJECT (p->data);
2050 object = gl_view_object_get_object (view_object);
2051 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2052 dy = fabs (yavg - (y1 + y2)/2.0);
2055 ycenter = (y1 + y2)/2.0;
2059 /* now adjust the object positions to line up this center */
2060 for (p = view->selected_object_list; p != NULL; p = p->next) {
2061 view_object = GL_VIEW_OBJECT (p->data);
2062 object = gl_view_object_get_object (view_object);
2063 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2064 dy = ycenter - (y1 + y2)/2.0;
2065 gl_label_object_set_position_relative (object, 0.0, dy);
2068 gl_debug (DEBUG_VIEW, "END");
2071 /*****************************************************************************/
2072 /* Center selected objects to in center of label. */
2073 /*****************************************************************************/
2075 gl_view_center_selection_horiz (glView *view)
2078 glViewObject *view_object;
2079 glLabelObject *object;
2080 gdouble dx, x_label_center, x_obj_center, x1, y1, x2, y2, w, h;
2082 gl_debug (DEBUG_VIEW, "START");
2084 g_return_if_fail (GL_IS_VIEW (view));
2086 g_return_if_fail (!gl_view_is_selection_empty (view));
2088 gl_label_get_size (view->label, &w, &h);
2089 x_label_center = w / 2.0;
2091 /* adjust the object positions */
2092 for (p = view->selected_object_list; p != NULL; p = p->next) {
2093 view_object = GL_VIEW_OBJECT (p->data);
2094 object = gl_view_object_get_object (view_object);
2095 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2096 x_obj_center = (x1 + x2) / 2.0;
2097 dx = x_label_center - x_obj_center;
2098 gl_label_object_set_position_relative (object, dx, 0.0);
2101 gl_debug (DEBUG_VIEW, "END");
2105 /*****************************************************************************/
2106 /* Center selected objects to in center of label. */
2107 /*****************************************************************************/
2109 gl_view_center_selection_vert (glView *view)
2112 glViewObject *view_object;
2113 glLabelObject *object;
2114 gdouble dy, y_label_center, y_obj_center, x1, y1, x2, y2, w, h;
2116 gl_debug (DEBUG_VIEW, "START");
2118 g_return_if_fail (GL_IS_VIEW (view));
2120 g_return_if_fail (!gl_view_is_selection_empty (view));
2122 gl_label_get_size (view->label, &w, &h);
2123 y_label_center = h / 2.0;
2125 /* adjust the object positions */
2126 for (p = view->selected_object_list; p != NULL; p = p->next) {
2127 view_object = GL_VIEW_OBJECT (p->data);
2128 object = gl_view_object_get_object (view_object);
2129 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2130 y_obj_center = (y1 + y2) / 2.0;
2131 dy = y_label_center - y_obj_center;
2132 gl_label_object_set_position_relative (object, 0.0, dy);
2135 gl_debug (DEBUG_VIEW, "END");
2139 /*****************************************************************************/
2140 /* Move selected objects */
2141 /*****************************************************************************/
2143 gl_view_move_selection (glView *view,
2148 glLabelObject *object;
2150 gl_debug (DEBUG_VIEW, "START");
2152 g_return_if_fail (view && GL_IS_VIEW (view));
2154 for (p = view->selected_object_list; p != NULL; p = p->next) {
2156 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2157 gl_label_object_set_position_relative (object, dx, dy);
2161 gl_debug (DEBUG_VIEW, "END");
2164 /*****************************************************************************/
2165 /* "Cut" selected items and place in clipboard selections. */
2166 /*****************************************************************************/
2168 gl_view_cut (glView *view)
2170 gl_debug (DEBUG_VIEW, "START");
2172 g_return_if_fail (GL_IS_VIEW (view));
2174 gl_view_copy (view);
2175 gl_view_delete_selection (view);
2177 gl_debug (DEBUG_VIEW, "END");
2180 /*****************************************************************************/
2181 /* "Copy" selected items to clipboard selections. */
2182 /*****************************************************************************/
2184 gl_view_copy (glView *view)
2187 glViewObject *view_object;
2188 glLabelObject *object;
2189 glTemplate *template;
2190 gboolean rotate_flag;
2192 gl_debug (DEBUG_VIEW, "START");
2194 g_return_if_fail (GL_IS_VIEW (view));
2196 if (view->selected_object_list) {
2198 if ( view->selection_data ) {
2199 g_object_unref (view->selection_data);
2201 template = gl_label_get_template (view->label);
2202 rotate_flag = gl_label_get_rotate_flag (view->label);
2203 view->selection_data = GL_LABEL(gl_label_new ());
2204 gl_label_set_template (view->selection_data, template);
2205 gl_label_set_rotate_flag (view->selection_data, rotate_flag);
2206 gl_template_free (&template);
2208 for (p = view->selected_object_list; p != NULL; p = p->next) {
2210 view_object = GL_VIEW_OBJECT (p->data);
2211 object = gl_view_object_get_object (view_object);
2213 gl_label_object_dup (object, view->selection_data);
2217 gtk_selection_owner_set (view->invisible,
2218 clipboard_atom, GDK_CURRENT_TIME);
2219 view->have_selection = TRUE;
2223 gl_debug (DEBUG_VIEW, "END");
2226 /*****************************************************************************/
2227 /* "Paste" from private clipboard selection. */
2228 /*****************************************************************************/
2230 gl_view_paste (glView *view)
2232 gl_debug (DEBUG_VIEW, "START");
2234 g_return_if_fail (GL_IS_VIEW (view));
2236 gtk_selection_convert (GTK_WIDGET (view->invisible),
2237 clipboard_atom, GDK_SELECTION_TYPE_STRING,
2240 gl_debug (DEBUG_VIEW, "END");
2243 /*****************************************************************************/
2244 /* Zoom in one "notch" */
2245 /*****************************************************************************/
2247 gl_view_zoom_in (glView *view)
2250 gdouble dist, dist_min;
2252 gl_debug (DEBUG_VIEW, "START");
2254 g_return_if_fail (GL_IS_VIEW (view));
2256 /* Find index of current scale (or best match) */
2257 i_min = 1; /* start with 2nd largest scale */
2258 dist_min = fabs (scales[1] - view->scale);
2259 for (i = 2; i < N_SCALES; i++) {
2260 dist = fabs (scales[i] - view->scale);
2261 if (dist < dist_min) {
2267 /* zoom in one "notch" */
2268 i = MAX (0, i_min - 1);
2269 gl_view_set_zoom (view, scales[i] / HOME_SCALE);
2271 gl_debug (DEBUG_VIEW, "END");
2274 /*****************************************************************************/
2275 /* Zoom out one "notch" */
2276 /*****************************************************************************/
2278 gl_view_zoom_out (glView *view)
2281 gdouble dist, dist_min;
2283 gl_debug (DEBUG_VIEW, "START");
2285 g_return_if_fail (GL_IS_VIEW (view));
2287 /* Find index of current scale (or best match) */
2288 i_min = 0; /* start with largest scale */
2289 dist_min = fabs (scales[0] - view->scale);
2290 for (i = 1; i < N_SCALES; i++) {
2291 dist = fabs (scales[i] - view->scale);
2292 if (dist < dist_min) {
2298 /* zoom out one "notch" */
2299 if (i_min >= N_SCALES)
2304 gl_view_set_zoom (view, scales[i] / HOME_SCALE);
2306 gl_debug (DEBUG_VIEW, "END");
2309 /*****************************************************************************/
2310 /* Set current zoom factor to explicit value. */
2311 /*****************************************************************************/
2313 gl_view_set_zoom (glView *view,
2316 gl_debug (DEBUG_VIEW, "START");
2318 g_return_if_fail (GL_IS_VIEW (view));
2319 g_return_if_fail (scale > 0.0);
2321 view->scale = scale * HOME_SCALE;
2322 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
2323 scale * HOME_SCALE);
2325 g_signal_emit (G_OBJECT(view), signals[ZOOM_CHANGED], 0, scale);
2327 gl_debug (DEBUG_VIEW, "END");
2330 /*****************************************************************************/
2331 /* Get current zoom factor. */
2332 /*****************************************************************************/
2334 gl_view_get_zoom (glView *view)
2336 gl_debug (DEBUG_VIEW, "");
2338 g_return_val_if_fail (GL_IS_VIEW (view), 1.0);
2340 return view->scale / HOME_SCALE;
2343 /*****************************************************************************/
2344 /* Is this the maximum zoom level. */
2345 /*****************************************************************************/
2347 gl_view_is_zoom_max (glView *view)
2349 gl_debug (DEBUG_VIEW, "");
2351 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
2353 return view->scale >= scales[0];
2356 /*****************************************************************************/
2357 /* Is this the minimum zoom level. */
2358 /*****************************************************************************/
2360 gl_view_is_zoom_min (glView *view)
2362 gl_debug (DEBUG_VIEW, "");
2364 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
2366 return view->scale <= scales[N_SCALES-1];
2369 /*****************************************************************************/
2370 /* Launch merge properties dialog. */
2371 /*****************************************************************************/
2373 gl_view_edit_merge_props (glView *view)
2375 gl_debug (DEBUG_VIEW, "");
2377 g_return_if_fail (GL_IS_VIEW (view));
2379 if (view->merge_props_dialog != NULL) {
2380 gtk_widget_show_all (view->merge_props_dialog);
2381 gtk_window_present (GTK_WINDOW(view->merge_props_dialog));
2385 view->merge_props_dialog = gl_merge_properties_dialog_new (view);
2386 gtk_widget_show_all (view->merge_props_dialog);
2388 g_signal_connect (G_OBJECT(view->merge_props_dialog), "destroy",
2389 G_CALLBACK (gtk_widget_destroyed),
2390 &view->merge_props_dialog);
2393 /*---------------------------------------------------------------------------*/
2394 /* PRIVATE. Canvas event handler. */
2395 /*---------------------------------------------------------------------------*/
2397 canvas_event (GnomeCanvas *canvas,
2403 gl_debug (DEBUG_VIEW, "");
2405 /* emit pointer signals regardless of state */
2406 switch (event->type) {
2407 case GDK_MOTION_NOTIFY:
2408 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
2409 gnome_canvas_window_to_world (canvas,
2411 event->motion.y, &x, &y);
2412 g_signal_emit (G_OBJECT(view), signals[POINTER_MOVED], 0, x, y);
2413 break; /* fall through */
2415 case GDK_LEAVE_NOTIFY:
2416 gl_debug (DEBUG_VIEW, "LEAVEW_NOTIFY");
2417 g_signal_emit (G_OBJECT(view), signals[POINTER_EXIT], 0);
2418 break; /* fall through */
2421 break; /* fall through */
2425 switch (view->state) {
2427 case GL_VIEW_STATE_ARROW:
2428 return canvas_event_arrow_mode (canvas, event, view);
2430 case GL_VIEW_STATE_OBJECT_CREATE:
2431 switch (view->create_type) {
2432 case GL_LABEL_OBJECT_BOX:
2433 return gl_view_box_create_event_handler (canvas,
2437 case GL_LABEL_OBJECT_ELLIPSE:
2438 return gl_view_ellipse_create_event_handler (canvas,
2442 case GL_LABEL_OBJECT_LINE:
2443 return gl_view_line_create_event_handler (canvas,
2447 case GL_LABEL_OBJECT_IMAGE:
2448 return gl_view_image_create_event_handler (canvas,
2452 case GL_LABEL_OBJECT_TEXT:
2453 return gl_view_text_create_event_handler (canvas,
2457 case GL_LABEL_OBJECT_BARCODE:
2458 return gl_view_barcode_create_event_handler (canvas,
2463 /*Should not happen!*/
2464 g_warning ("Invalid label object type.");
2469 g_warning ("Invalid view state."); /*Should not happen!*/
2475 /*---------------------------------------------------------------------------*/
2476 /* PRIVATE. Canvas event handler (arrow mode) */
2477 /*---------------------------------------------------------------------------*/
2479 canvas_event_arrow_mode (GnomeCanvas *canvas,
2483 static gdouble x0, y0;
2484 static gboolean dragging = FALSE;
2485 static GnomeCanvasItem *item;
2486 gdouble x, y, x1, y1, x2, y2;
2487 GnomeCanvasGroup *group;
2490 gl_debug (DEBUG_VIEW, "");
2492 switch (event->type) {
2494 case GDK_BUTTON_PRESS:
2495 gl_debug (DEBUG_VIEW, "BUTTON_PRESS");
2496 switch (event->button.button) {
2498 gnome_canvas_window_to_world (canvas,
2500 event->button.y, &x, &y);
2502 if (!object_at (view, x, y)) {
2503 if (!(event->button.state & GDK_CONTROL_MASK)) {
2504 gl_view_unselect_all (view);
2508 gnome_canvas_item_grab (canvas->root,
2509 GDK_POINTER_MOTION_MASK |
2510 GDK_BUTTON_RELEASE_MASK |
2511 GDK_BUTTON_PRESS_MASK,
2512 NULL, event->button.time);
2514 gnome_canvas_root (GNOME_CANVAS
2517 gnome_canvas_item_new (group,
2518 gnome_canvas_rect_get_type (),
2522 "outline_color_rgba",
2533 gnome_canvas_window_to_world (canvas,
2535 event->button.y, &x, &y);
2537 if (!object_at (view, x, y)) {
2538 /* bring up apropriate menu for selection. */
2539 gl_view_popup_menu (view, event);
2546 case GDK_BUTTON_RELEASE:
2547 gl_debug (DEBUG_VIEW, "BUTTON_RELEASE");
2548 switch (event->button.button) {
2552 gnome_canvas_item_ungrab (canvas->root,
2553 event->button.time);
2554 gnome_canvas_window_to_world (canvas,
2562 gl_view_select_region (view, x1, y1, x2, y2);
2563 gtk_object_destroy (GTK_OBJECT (item));
2572 case GDK_MOTION_NOTIFY:
2573 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
2574 gnome_canvas_window_to_world (canvas,
2576 event->motion.y, &x, &y);
2577 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
2578 gnome_canvas_item_set (item,
2582 "y2", MAX (y, y0), NULL);
2589 gl_debug (DEBUG_VIEW, "KEY_PRESS");
2591 switch (event->key.keyval) {
2594 gl_view_move_selection (view,
2595 -1.0 / (view->scale), 0.0);
2599 gl_view_move_selection (view,
2600 0.0, -1.0 / (view->scale));
2604 gl_view_move_selection (view,
2605 1.0 / (view->scale), 0.0);
2609 gl_view_move_selection (view,
2610 0.0, 1.0 / (view->scale));
2614 gl_view_delete_selection (view);
2615 cursor = gdk_cursor_new (GDK_LEFT_PTR);
2616 gdk_window_set_cursor (view->canvas->window,
2618 gdk_cursor_unref (cursor);
2624 return TRUE; /* We handled this or we were dragging. */
2627 gl_debug (DEBUG_VIEW, "default");
2633 /*---------------------------------------------------------------------------*/
2634 /* PRIVATE. create menu for selections. */
2635 /*---------------------------------------------------------------------------*/
2637 construct_selection_menu (glView *view)
2639 GtkWidget *menu, *menuitem, *submenu;
2641 gl_debug (DEBUG_VIEW, "START");
2643 g_return_if_fail (GL_IS_VIEW (view));
2645 menu = gtk_menu_new ();
2647 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_PROPERTIES, NULL);
2648 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2649 gtk_widget_show (menuitem);
2650 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2651 G_CALLBACK (gl_view_edit_object_props), view);
2652 view->atomic_selection_items =
2653 g_list_prepend (view->atomic_selection_items, menuitem);
2656 * Separator -------------------------
2658 menuitem = gtk_menu_item_new ();
2659 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2660 gtk_widget_show (menuitem);
2665 menuitem = gtk_menu_item_new_with_mnemonic (_("_Order"));
2666 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2667 gtk_widget_show (menuitem);
2668 submenu = gtk_menu_new ();
2669 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
2671 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ORDER_TOP, NULL);
2672 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2673 gtk_widget_show (menuitem);
2674 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2675 G_CALLBACK (gl_view_raise_selection), view);
2677 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ORDER_BOTTOM, NULL);
2678 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2679 gtk_widget_show (menuitem);
2680 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2681 G_CALLBACK (gl_view_lower_selection), view);
2684 * Submenu: Rotate/Flip
2686 menuitem = gtk_menu_item_new_with_mnemonic (_("_Rotate/Flip"));
2687 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2688 gtk_widget_show (menuitem);
2689 submenu = gtk_menu_new ();
2690 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
2692 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ROTATE_LEFT, NULL);
2693 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2694 gtk_widget_show (menuitem);
2695 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2696 G_CALLBACK (gl_view_rotate_selection_left), view);
2698 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ROTATE_RIGHT, NULL);
2699 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2700 gtk_widget_show (menuitem);
2701 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2702 G_CALLBACK (gl_view_rotate_selection_right), view);
2704 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_FLIP_HORIZ, NULL);
2705 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2706 gtk_widget_show (menuitem);
2707 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2708 G_CALLBACK (gl_view_flip_selection_horiz), view);
2710 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_FLIP_VERT, NULL);
2711 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2712 gtk_widget_show (menuitem);
2713 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2714 G_CALLBACK (gl_view_flip_selection_vert), view);
2717 * Submenu: Align Horizontally
2719 menuitem = gtk_menu_item_new_with_mnemonic (_("Align _Horizontally"));
2720 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2721 gtk_widget_show (menuitem);
2722 submenu = gtk_menu_new ();
2723 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
2725 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_LEFT, NULL);
2726 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2727 gtk_widget_show (menuitem);
2728 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2729 G_CALLBACK (gl_view_align_selection_left), view);
2730 view->multi_selection_items =
2731 g_list_prepend (view->multi_selection_items, menuitem);
2733 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_HCENTER, NULL);
2734 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2735 gtk_widget_show (menuitem);
2736 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2737 G_CALLBACK (gl_view_align_selection_hcenter), view);
2738 view->multi_selection_items =
2739 g_list_prepend (view->multi_selection_items, menuitem);
2741 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_RIGHT, NULL);
2742 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2743 gtk_widget_show (menuitem);
2744 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2745 G_CALLBACK (gl_view_align_selection_right), view);
2746 view->multi_selection_items =
2747 g_list_prepend (view->multi_selection_items, menuitem);
2749 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_CENTER_HORIZ, NULL);
2750 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2751 gtk_widget_show (menuitem);
2752 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2753 G_CALLBACK (gl_view_center_selection_horiz), view);
2756 * Submenu: Align Vertically
2758 menuitem = gtk_menu_item_new_with_mnemonic (_("Align _Vertically"));
2759 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2760 gtk_widget_show (menuitem);
2761 submenu = gtk_menu_new ();
2762 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
2764 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_TOP, NULL);
2765 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2766 gtk_widget_show (menuitem);
2767 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2768 G_CALLBACK (gl_view_align_selection_top), view);
2769 view->multi_selection_items =
2770 g_list_prepend (view->multi_selection_items, menuitem);
2772 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_VCENTER, NULL);
2773 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2774 gtk_widget_show (menuitem);
2775 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2776 G_CALLBACK (gl_view_align_selection_vcenter), view);
2777 view->multi_selection_items =
2778 g_list_prepend (view->multi_selection_items, menuitem);
2780 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_BOTTOM, NULL);
2781 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2782 gtk_widget_show (menuitem);
2783 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2784 G_CALLBACK (gl_view_align_selection_bottom), view);
2785 view->multi_selection_items =
2786 g_list_prepend (view->multi_selection_items, menuitem);
2788 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_CENTER_VERT, NULL);
2789 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2790 gtk_widget_show (menuitem);
2791 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2792 G_CALLBACK (gl_view_center_selection_vert), view);
2795 * Separator -------------------------
2797 menuitem = gtk_menu_item_new ();
2798 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2799 gtk_widget_show (menuitem);
2801 menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_CUT, NULL);
2802 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2803 gtk_widget_show (menuitem);
2804 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2805 G_CALLBACK (gl_view_cut), view);
2807 menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_COPY, NULL);
2808 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2809 gtk_widget_show (menuitem);
2810 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2811 G_CALLBACK (gl_view_copy), view);
2813 menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_PASTE, NULL);
2814 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2815 gtk_widget_show (menuitem);
2816 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2817 G_CALLBACK (gl_view_paste), view);
2819 menuitem = gtk_menu_item_new_with_mnemonic (_("_Delete"));
2820 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2821 gtk_widget_show (menuitem);
2822 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2823 G_CALLBACK (gl_view_delete_selection), view);
2826 view->selection_menu = menu;
2828 gl_debug (DEBUG_VIEW, "END");
2831 /*---------------------------------------------------------------------------*/
2832 /* PRIVATE. create menu for empty selections. */
2833 /*---------------------------------------------------------------------------*/
2835 construct_empty_selection_menu (glView *view)
2837 GtkWidget *menu, *menuitem, *submenu;
2839 gl_debug (DEBUG_VIEW, "START");
2841 g_return_if_fail (GL_IS_VIEW (view));
2843 menu = gtk_menu_new ();
2845 menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_PASTE, NULL);
2846 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2847 gtk_widget_show (menuitem);
2848 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2849 G_CALLBACK (gl_view_paste), view);
2852 view->empty_selection_menu = menu;
2854 gl_debug (DEBUG_VIEW, "END");
2857 /****************************************************************************/
2859 /****************************************************************************/
2861 gl_view_popup_menu (glView *view,
2867 gl_debug (DEBUG_VIEW, "START");
2869 g_return_if_fail (GL_IS_VIEW (view));
2871 if (gl_view_is_selection_empty (view)) {
2873 if (view->empty_selection_menu != NULL) {
2874 gtk_menu_popup (GTK_MENU (view->empty_selection_menu),
2875 NULL, NULL, NULL, NULL,
2876 event->button.button,
2877 event->button.time);
2882 for (p=view->atomic_selection_items; p!=NULL; p=p->next) {
2883 gtk_widget_set_sensitive (GTK_WIDGET(p->data),
2884 gl_view_is_selection_atomic(view));
2887 for (p=view->multi_selection_items; p!=NULL; p=p->next) {
2888 gtk_widget_set_sensitive (GTK_WIDGET(p->data),
2889 !gl_view_is_selection_atomic(view));
2892 if (view->selection_menu != NULL) {
2893 gtk_menu_popup (GTK_MENU (view->selection_menu),
2894 NULL, NULL, NULL, NULL,
2895 event->button.button,
2896 event->button.time);
2901 gl_debug (DEBUG_VIEW, "END");
2904 /*---------------------------------------------------------------------------*/
2905 /* PRIVATE. Handle "selection-clear" signal. */
2906 /*---------------------------------------------------------------------------*/
2908 selection_clear_cb (GtkWidget *widget,
2909 GdkEventSelection *event,
2912 glView *view = GL_VIEW (data);
2914 gl_debug (DEBUG_VIEW, "START");
2916 g_return_if_fail (GL_IS_VIEW (view));
2918 view->have_selection = FALSE;
2919 g_object_unref (view->selection_data);
2920 view->selection_data = NULL;
2922 gl_debug (DEBUG_VIEW, "END");
2925 /*---------------------------------------------------------------------------*/
2926 /* PRIVATE. Handle "selection-get" signal. */
2927 /*---------------------------------------------------------------------------*/
2929 selection_get_cb (GtkWidget *widget,
2930 GtkSelectionData *selection_data,
2935 glView *view = GL_VIEW (data);
2937 glXMLLabelStatus status;
2939 gl_debug (DEBUG_VIEW, "START");
2941 g_return_if_fail (GL_IS_VIEW (view));
2943 if (view->have_selection) {
2945 buffer = gl_xml_label_save_buffer (view->selection_data,
2947 gtk_selection_data_set (selection_data,
2948 GDK_SELECTION_TYPE_STRING, 8, buffer,
2953 gl_debug (DEBUG_VIEW, "END");
2956 /*---------------------------------------------------------------------------*/
2957 /* PRIVATE. Handle "selection-received" signal. (Result of Paste) */
2958 /*---------------------------------------------------------------------------*/
2960 selection_received_cb (GtkWidget *widget,
2961 GtkSelectionData *selection_data,
2965 glView *view = GL_VIEW (data);
2966 glLabel *label = NULL;
2967 glXMLLabelStatus status;
2969 glLabelObject *object, *newobject;
2970 glViewObject *view_object;
2972 gl_debug (DEBUG_VIEW, "START");
2974 g_return_if_fail (GL_IS_VIEW (view));
2976 if (selection_data->length < 0) {
2979 if (selection_data->type != GDK_SELECTION_TYPE_STRING) {
2983 gl_view_unselect_all (view);
2985 label = gl_xml_label_open_buffer (selection_data->data, &status);
2986 for (p = label->objects; p != NULL; p = p_next) {
2989 object = (glLabelObject *) p->data;
2990 gl_label_object_set_parent (object, view->label);
2992 gl_debug (DEBUG_VIEW, "object pasted");
2994 if (GL_IS_LABEL_BOX (object)) {
2995 view_object = gl_view_box_new (GL_LABEL_BOX(object),
2997 } else if (GL_IS_LABEL_ELLIPSE (object)) {
2998 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object),
3000 } else if (GL_IS_LABEL_LINE (object)) {
3001 view_object = gl_view_line_new (GL_LABEL_LINE(object),
3003 } else if (GL_IS_LABEL_IMAGE (object)) {
3004 view_object = gl_view_image_new (GL_LABEL_IMAGE(object),
3006 } else if (GL_IS_LABEL_TEXT (object)) {
3007 view_object = gl_view_text_new (GL_LABEL_TEXT(object),
3009 } else if (GL_IS_LABEL_BARCODE (object)) {
3010 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(object),
3013 /* Should not happen! */
3015 g_warning ("Invalid label object type.");
3017 gl_view_select_object (view, view_object);
3019 g_object_unref (label);
3021 gl_debug (DEBUG_VIEW, "END");