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"
48 /*==========================================================================*/
49 /* Private macros and constants. */
50 /*==========================================================================*/
52 #define BG_COLOR GL_COLOR (192, 192, 192)
53 #define OUTLINE_COLOR GL_COLOR (173, 216, 230)
54 #define PAPER_COLOR GL_COLOR (255, 255, 255)
55 #define GRID_COLOR BG_COLOR
56 #define MARKUP_COLOR GL_COLOR (240, 100, 100)
58 #define SEL_LINE_COLOR GL_COLOR_A (0, 0, 255, 128)
59 #define SEL_FILL_COLOR GL_COLOR_A (192, 192, 255, 128)
61 #define ARC_FINE 2 /* Resolution in degrees of large arcs */
62 #define ARC_COURSE 5 /* Resolution in degrees of small arcs */
64 /*==========================================================================*/
66 /*==========================================================================*/
78 /*==========================================================================*/
80 /*==========================================================================*/
82 static GtkContainerClass *parent_class;
84 static guint signals[LAST_SIGNAL] = {0};
86 /* "CLIPBOARD" selection */
87 static GdkAtom clipboard_atom = GDK_NONE;
89 static gdouble scales[] = {
94 #define N_SCALES G_N_ELEMENTS(scales)
95 #define HOME_SCALE 2.0
97 /*==========================================================================*/
98 /* Local function prototypes */
99 /*==========================================================================*/
101 static void gl_view_class_init (glViewClass *class);
102 static void gl_view_init (glView *view);
103 static void gl_view_finalize (GObject *object);
105 static void gl_view_construct (glView *view);
106 static GtkWidget *gl_view_construct_canvas (glView *view);
107 static void gl_view_construct_selection (glView *view);
109 static gdouble get_apropriate_scale (gdouble w, gdouble h);
111 static void draw_layers (glView *view);
113 static void label_resized_cb (glLabel *label,
116 static void draw_label_layer (glView *view);
118 static void draw_highlight_layer (glView *view);
120 static void draw_bg_fg_layers (glView *view);
121 static void draw_bg_fg_rect (glView *view);
122 static void draw_bg_fg_rounded_rect (glView *view);
123 static void draw_bg_fg_round (glView *view);
124 static void draw_bg_fg_cd (glView *view);
125 static void draw_bg_fg_cd_bc (glView *view);
127 static void draw_grid_layer (glView *view);
129 static void draw_markup_layer (glView *view);
131 static void draw_markup_margin (glView *view,
132 glTemplateMarkupMargin *margin);
133 static void draw_markup_margin_rect (glView *view,
134 glTemplateMarkupMargin *margin);
135 static void draw_markup_margin_rounded_rect (glView *view,
136 glTemplateMarkupMargin *margin);
137 static void draw_markup_margin_round (glView *view,
138 glTemplateMarkupMargin *margin);
139 static void draw_markup_margin_cd (glView *view,
140 glTemplateMarkupMargin *margin);
141 static void draw_markup_margin_cd_bc (glView *view,
142 glTemplateMarkupMargin *margin);
144 static void draw_markup_line (glView *view,
145 glTemplateMarkupLine *line);
147 static void draw_markup_circle (glView *view,
148 glTemplateMarkupCircle *circle);
151 static void select_object_real (glView *view,
152 glViewObject *view_object);
153 static void unselect_object_real (glView *view,
154 glViewObject *view_object);
156 static gboolean object_at (glView *view,
157 gdouble x, gdouble y);
159 static gboolean is_item_member_of_group (glView *view,
160 GnomeCanvasItem *item,
161 GnomeCanvasItem *group);
163 static int canvas_event (GnomeCanvas *canvas,
166 static int canvas_event_arrow_mode (GnomeCanvas *canvas,
170 static void construct_selection_menu (glView *view);
172 static void construct_empty_selection_menu (glView *view);
174 static void selection_clear_cb (GtkWidget *widget,
175 GdkEventSelection *event,
178 static void selection_get_cb (GtkWidget *widget,
179 GtkSelectionData *selection_data,
184 static void selection_received_cb (GtkWidget *widget,
185 GtkSelectionData *selection_data,
189 /****************************************************************************/
190 /* Boilerplate Object stuff. */
191 /****************************************************************************/
193 gl_view_get_type (void)
195 static guint view_type = 0;
198 GTypeInfo view_info = {
199 sizeof (glViewClass),
202 (GClassInitFunc) gl_view_class_init,
207 (GInstanceInitFunc) gl_view_init,
211 g_type_register_static (gtk_vbox_get_type (),
212 "glView", &view_info, 0);
219 gl_view_class_init (glViewClass *class)
221 GObjectClass *object_class = (GObjectClass *) class;
223 gl_debug (DEBUG_VIEW, "START");
225 parent_class = g_type_class_peek_parent (class);
227 object_class->finalize = gl_view_finalize;
229 signals[SELECTION_CHANGED] =
230 g_signal_new ("selection_changed",
231 G_OBJECT_CLASS_TYPE (object_class),
233 G_STRUCT_OFFSET (glViewClass, selection_changed),
235 gl_marshal_VOID__VOID,
239 signals[ZOOM_CHANGED] =
240 g_signal_new ("zoom_changed",
241 G_OBJECT_CLASS_TYPE (object_class),
243 G_STRUCT_OFFSET (glViewClass, zoom_changed),
245 gl_marshal_VOID__DOUBLE,
249 signals[POINTER_MOVED] =
250 g_signal_new ("pointer_moved",
251 G_OBJECT_CLASS_TYPE (object_class),
253 G_STRUCT_OFFSET (glViewClass, pointer_moved),
255 gl_marshal_VOID__DOUBLE_DOUBLE,
257 2, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
259 signals[POINTER_EXIT] =
260 g_signal_new ("pointer_exit",
261 G_OBJECT_CLASS_TYPE (object_class),
263 G_STRUCT_OFFSET (glViewClass, pointer_exit),
265 gl_marshal_VOID__VOID,
269 signals[MODE_CHANGED] =
270 g_signal_new ("mode_changed",
271 G_OBJECT_CLASS_TYPE (object_class),
273 G_STRUCT_OFFSET (glViewClass, mode_changed),
275 gl_marshal_VOID__VOID,
279 gl_debug (DEBUG_VIEW, "END");
283 gl_view_init (glView *view)
285 gl_debug (DEBUG_VIEW, "START");
289 view->grid_spacing = 9;
291 view->default_font_family = NULL;
293 gl_debug (DEBUG_VIEW, "END");
297 gl_view_finalize (GObject *object)
301 gl_debug (DEBUG_VIEW, "START");
303 g_return_if_fail (object != NULL);
304 g_return_if_fail (GL_IS_VIEW (object));
306 view = GL_VIEW (object);
308 G_OBJECT_CLASS (parent_class)->finalize (object);
310 gl_debug (DEBUG_VIEW, "END");
313 /****************************************************************************/
314 /* NEW view object. */
315 /****************************************************************************/
317 gl_view_new (glLabel *label)
321 gl_debug (DEBUG_VIEW, "START");
323 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
325 view = g_object_new (gl_view_get_type (), NULL);
328 gl_view_construct (view);
330 gl_debug (DEBUG_VIEW, "END");
332 return GTK_WIDGET (view);
335 /*---------------------------------------------------------------------------*/
336 /* PRIVATE. Construct composite widget. */
337 /*---------------------------------------------------------------------------*/
339 gl_view_construct (glView *view)
341 GtkWidget *wvbox, *wscroll;
343 gl_debug (DEBUG_VIEW, "START");
345 g_return_if_fail (GL_IS_VIEW (view));
347 wvbox = GTK_WIDGET (view);
349 view->state = GL_VIEW_STATE_ARROW;
350 view->object_list = NULL;
352 gl_view_construct_canvas (view);
353 wscroll = gtk_scrolled_window_new (NULL, NULL);
354 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (wscroll),
355 GTK_POLICY_AUTOMATIC,
356 GTK_POLICY_AUTOMATIC);
357 gtk_box_pack_start (GTK_BOX (wvbox), wscroll, TRUE, TRUE, 0);
358 gtk_container_add (GTK_CONTAINER (wscroll), view->canvas);
360 gl_view_construct_selection (view);
362 construct_selection_menu (view);
363 construct_empty_selection_menu (view);
365 gl_view_set_default_font_family (view, gl_prefs->default_font_family);
366 gl_view_set_default_font_size (view, gl_prefs->default_font_size);
367 gl_view_set_default_font_weight (view, gl_prefs->default_font_weight);
368 gl_view_set_default_font_italic_flag (view, gl_prefs->default_font_italic_flag);
369 gl_view_set_default_text_color (view, gl_prefs->default_text_color);
370 gl_view_set_default_text_alignment (view, gl_prefs->default_text_alignment);
371 gl_view_set_default_line_width (view, gl_prefs->default_line_width);
372 gl_view_set_default_line_color (view, gl_prefs->default_line_color);
373 gl_view_set_default_fill_color (view, gl_prefs->default_fill_color);
375 gl_debug (DEBUG_VIEW, "END");
378 /*---------------------------------------------------------------------------*/
379 /* PRIVATE. Create canvas w/ a background in the shape of the label/card. */
380 /*---------------------------------------------------------------------------*/
382 gl_view_construct_canvas (glView *view)
386 gdouble label_width, label_height;
389 gl_debug (DEBUG_VIEW, "START");
391 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
392 g_return_val_if_fail (view->label && GL_IS_LABEL (view->label), NULL);
396 gtk_widget_push_colormap (gdk_rgb_get_colormap ());
397 view->canvas = gnome_canvas_new_aa ();
398 gtk_widget_pop_colormap ();
400 bg_color = gl_color_to_gdk_color (BG_COLOR);
401 gtk_widget_modify_bg (GTK_WIDGET(view->canvas), GTK_STATE_NORMAL, bg_color);
404 gl_label_get_size (label, &label_width, &label_height);
405 gl_debug (DEBUG_VIEW, "Label size: w=%lf, h=%lf",
406 label_width, label_height);
408 scale = get_apropriate_scale (label_width, label_height);
409 gl_debug (DEBUG_VIEW, "scale =%lf", scale);
411 gl_debug (DEBUG_VIEW, "Canvas size: w=%lf, h=%lf",
412 scale * label_width + 40,
413 scale * label_height + 40);
414 gtk_widget_set_size_request (GTK_WIDGET(view->canvas),
415 scale * label_width + 40,
416 scale * label_height + 40);
417 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
421 gnome_canvas_set_scroll_region (GNOME_CANVAS (view->canvas),
422 0.0, 0.0, label_width, label_height);
426 g_signal_connect (G_OBJECT (view->canvas), "event",
427 G_CALLBACK (canvas_event), view);
429 gl_debug (DEBUG_VIEW, "END");
434 /*---------------------------------------------------------------------------*/
435 /* PRIVATE. Create clipboard selection targets. */
436 /*---------------------------------------------------------------------------*/
438 gl_view_construct_selection (glView *view)
440 gl_debug (DEBUG_VIEW, "START");
442 g_return_if_fail (GL_IS_VIEW (view));
444 view->have_selection = FALSE;
445 view->selection_data = NULL;
446 view->invisible = gtk_invisible_new ();
448 view->selected_object_list = NULL;
450 if (!clipboard_atom) {
451 clipboard_atom = gdk_atom_intern ("GLABELS_CLIPBOARD", FALSE);
454 gtk_selection_add_target (view->invisible,
455 clipboard_atom, GDK_SELECTION_TYPE_STRING, 1);
457 g_signal_connect (G_OBJECT (view->invisible),
458 "selection_clear_event",
459 G_CALLBACK (selection_clear_cb), view);
461 g_signal_connect (G_OBJECT (view->invisible), "selection_get",
462 G_CALLBACK (selection_get_cb), view);
464 g_signal_connect (G_OBJECT (view->invisible),
465 "selection_received",
466 G_CALLBACK (selection_received_cb), view);
468 gl_debug (DEBUG_VIEW, "END");
471 /*---------------------------------------------------------------------------*/
472 /* PRIVATE. Determine an apropriate scale for given label & screen size */
473 /*---------------------------------------------------------------------------*/
475 get_apropriate_scale (gdouble w, gdouble h)
477 gdouble w_screen, h_screen;
481 gl_debug (DEBUG_VIEW, "");
483 w_screen = (gdouble) gdk_screen_width ();
484 h_screen = (gdouble) gdk_screen_height ();
486 for (i = 0; i < N_SCALES; i++) {
488 if (k <= HOME_SCALE) {
489 if ((k * w < (w_screen - 256))
490 && (k * h < (h_screen - 256)))
498 /*---------------------------------------------------------------------------*/
499 /* PRIVATE. Create, draw and order layers. */
500 /*---------------------------------------------------------------------------*/
502 draw_layers (glView *view)
504 g_return_if_fail (view && GL_IS_VIEW (view));
505 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
507 draw_bg_fg_layers (view);
508 draw_grid_layer (view);
509 draw_markup_layer (view);
510 draw_highlight_layer (view); /* Must be done before label layer */
511 draw_label_layer (view);
513 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->fg_group));
514 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->highlight_group));
516 g_signal_connect (G_OBJECT (view->label), "size_changed",
517 G_CALLBACK (label_resized_cb), view);
520 /*---------------------------------------------------------------------------*/
521 /* PRIVATE. Handle label resize event. . */
522 /*---------------------------------------------------------------------------*/
524 label_resized_cb (glLabel *label,
527 g_return_if_fail (label && GL_IS_LABEL (label));
528 g_return_if_fail (view && GL_IS_VIEW (view));
530 gtk_object_destroy (GTK_OBJECT (view->bg_group));
531 gtk_object_destroy (GTK_OBJECT (view->grid_group));
532 gtk_object_destroy (GTK_OBJECT (view->markup_group));
533 gtk_object_destroy (GTK_OBJECT (view->fg_group));
535 draw_bg_fg_layers (view);
536 draw_grid_layer (view);
537 draw_markup_layer (view);
539 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->label_group));
540 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->fg_group));
541 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->highlight_group));
544 /*---------------------------------------------------------------------------*/
545 /* PRIVATE. Draw label layer. */
546 /*---------------------------------------------------------------------------*/
548 draw_label_layer (glView *view)
550 GnomeCanvasGroup *group;
553 glLabelObject *object;
554 glViewObject *view_object;
556 g_return_if_fail (view && GL_IS_VIEW (view));
557 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
559 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
560 view->label_group = GNOME_CANVAS_GROUP(
561 gnome_canvas_item_new (group,
562 gnome_canvas_group_get_type (),
569 for (p_obj = label->objects; p_obj != NULL; p_obj = p_obj->next) {
570 object = (glLabelObject *) p_obj->data;
572 if (GL_IS_LABEL_BOX (object)) {
573 view_object = gl_view_box_new (GL_LABEL_BOX(object),
575 } else if (GL_IS_LABEL_ELLIPSE (object)) {
576 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object),
578 } else if (GL_IS_LABEL_LINE (object)) {
579 view_object = gl_view_line_new (GL_LABEL_LINE(object),
581 } else if (GL_IS_LABEL_IMAGE (object)) {
582 view_object = gl_view_image_new (GL_LABEL_IMAGE(object),
584 } else if (GL_IS_LABEL_TEXT (object)) {
585 view_object = gl_view_text_new (GL_LABEL_TEXT(object),
587 } else if (GL_IS_LABEL_BARCODE (object)) {
588 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(object),
591 /* Should not happen! */
593 g_warning ("Invalid label object type.");
598 /*---------------------------------------------------------------------------*/
599 /* PRIVATE. Create highlight layer. */
600 /*---------------------------------------------------------------------------*/
602 draw_highlight_layer (glView *view)
604 GnomeCanvasGroup *group;
606 g_return_if_fail (view && GL_IS_VIEW (view));
608 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
609 view->highlight_group = GNOME_CANVAS_GROUP(
610 gnome_canvas_item_new (group,
611 gnome_canvas_group_get_type (),
617 /*---------------------------------------------------------------------------*/
618 /* PRIVATE. Draw background and foreground outlines. */
619 /*---------------------------------------------------------------------------*/
621 draw_bg_fg_layers (glView *view)
624 glTemplate *template;
625 GnomeCanvasGroup *group;
627 g_return_if_fail (view && GL_IS_VIEW (view));
628 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
630 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
631 view->bg_group = GNOME_CANVAS_GROUP(
632 gnome_canvas_item_new (group,
633 gnome_canvas_group_get_type (),
637 view->fg_group = GNOME_CANVAS_GROUP(
638 gnome_canvas_item_new (group,
639 gnome_canvas_group_get_type (),
645 template = gl_label_get_template (label);
647 switch (template->label.style) {
649 case GL_TEMPLATE_STYLE_RECT:
650 if (template->label.rect.r == 0.0) {
651 /* Square corners. */
652 draw_bg_fg_rect (view);
654 /* Rounded corners. */
655 draw_bg_fg_rounded_rect (view);
659 case GL_TEMPLATE_STYLE_ROUND:
660 draw_bg_fg_round (view);
663 case GL_TEMPLATE_STYLE_CD:
664 if ((template->label.cd.w == 0.0) && (template->label.cd.h == 0.0) ) {
665 draw_bg_fg_cd (view);
667 draw_bg_fg_cd_bc (view);
672 g_warning ("Unknown template label style");
677 /*---------------------------------------------------------------------------*/
678 /* PRIVATE. Draw simple recangular background. */
679 /*---------------------------------------------------------------------------*/
681 draw_bg_fg_rect (glView *view)
684 glTemplate *template;
686 GnomeCanvasItem *item;
688 gl_debug (DEBUG_VIEW, "START");
690 g_return_if_fail (view && GL_IS_VIEW (view));
691 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
695 gl_label_get_size (label, &w, &h);
696 template = gl_label_get_template (label);
699 item = gnome_canvas_item_new (view->bg_group,
700 gnome_canvas_rect_get_type (),
705 "fill_color_rgba", PAPER_COLOR,
709 item = gnome_canvas_item_new (view->fg_group,
710 gnome_canvas_rect_get_type (),
716 "outline_color_rgba", OUTLINE_COLOR,
719 gl_debug (DEBUG_VIEW, "END");
722 /*---------------------------------------------------------------------------*/
723 /* PRIVATE. Draw rounded recangular background. */
724 /*---------------------------------------------------------------------------*/
726 draw_bg_fg_rounded_rect (glView *view)
729 GnomeCanvasPoints *points;
730 gint i_coords, i_theta;
731 glTemplate *template;
733 GnomeCanvasItem *item;
735 gl_debug (DEBUG_VIEW, "START");
737 g_return_if_fail (view && GL_IS_VIEW (view));
738 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
742 gl_label_get_size (label, &w, &h);
743 template = gl_label_get_template (label);
744 r = template->label.rect.r;
746 points = gnome_canvas_points_new (4 * (1 + 90 / ARC_COURSE));
748 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
749 points->coords[i_coords++] =
750 r - r * sin (i_theta * G_PI / 180.0);
751 points->coords[i_coords++] =
752 r - r * cos (i_theta * G_PI / 180.0);
754 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
755 points->coords[i_coords++] =
756 r - r * cos (i_theta * G_PI / 180.0);
757 points->coords[i_coords++] =
758 (h - r) + r * sin (i_theta * G_PI / 180.0);
760 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
761 points->coords[i_coords++] =
762 (w - r) + r * sin (i_theta * G_PI / 180.0);
763 points->coords[i_coords++] =
764 (h - r) + r * cos (i_theta * G_PI / 180.0);
766 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
767 points->coords[i_coords++] =
768 (w - r) + r * cos (i_theta * G_PI / 180.0);
769 points->coords[i_coords++] =
770 r - r * sin (i_theta * G_PI / 180.0);
774 item = gnome_canvas_item_new (view->bg_group,
775 gnome_canvas_polygon_get_type (),
777 "fill_color_rgba", PAPER_COLOR,
781 item = gnome_canvas_item_new (view->fg_group,
782 gnome_canvas_polygon_get_type (),
785 "outline_color_rgba", OUTLINE_COLOR,
788 gnome_canvas_points_free (points);
790 gl_debug (DEBUG_VIEW, "END");
793 /*---------------------------------------------------------------------------*/
794 /* PRIVATE. Draw round background. */
795 /*---------------------------------------------------------------------------*/
797 draw_bg_fg_round (glView *view)
800 glTemplate *template;
802 GnomeCanvasItem *item;
804 gl_debug (DEBUG_VIEW, "START");
806 g_return_if_fail (view && GL_IS_VIEW (view));
807 g_return_if_fail (view->label && GL_IS_LABEL(view->label));
810 template = gl_label_get_template (label);
812 r = template->label.round.r;
815 item = gnome_canvas_item_new (view->bg_group,
816 gnome_canvas_ellipse_get_type (),
821 "fill_color_rgba", PAPER_COLOR,
825 item = gnome_canvas_item_new (view->fg_group,
826 gnome_canvas_ellipse_get_type (),
832 "outline_color_rgba", OUTLINE_COLOR,
835 gl_debug (DEBUG_VIEW, "END");
838 /*---------------------------------------------------------------------------*/
839 /* PRIVATE. Draw CD style background, circular w/ concentric hole. */
840 /*---------------------------------------------------------------------------*/
842 draw_bg_fg_cd (glView *view)
845 glTemplate *template;
847 GnomeCanvasItem *item;
849 gl_debug (DEBUG_VIEW, "START");
851 g_return_if_fail (view && GL_IS_VIEW (view));
852 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
855 template = gl_label_get_template (label);
857 r1 = template->label.cd.r1;
858 r2 = template->label.cd.r2;
862 item = gnome_canvas_item_new (view->bg_group,
863 gnome_canvas_ellipse_get_type (),
868 "fill_color_rgba", PAPER_COLOR,
871 item = gnome_canvas_item_new (view->bg_group,
872 gnome_canvas_ellipse_get_type (),
877 "fill_color_rgba", GRID_COLOR,
882 item = gnome_canvas_item_new (view->fg_group,
883 gnome_canvas_ellipse_get_type (),
889 "outline_color_rgba", OUTLINE_COLOR,
892 item = gnome_canvas_item_new (view->fg_group,
893 gnome_canvas_ellipse_get_type (),
899 "outline_color_rgba", OUTLINE_COLOR,
902 gl_debug (DEBUG_VIEW, "END");
905 /*---------------------------------------------------------------------------*/
906 /* PRIVATE. Draw Business Card CD style background, CD w/ chopped ends. */
907 /*---------------------------------------------------------------------------*/
909 draw_bg_fg_cd_bc (glView *view)
912 glTemplate *template;
913 GnomeCanvasPoints *points;
914 gint i_coords, i_theta;
915 gdouble theta1, theta2;
916 gdouble x0, y0, w, h, r1, r2;
917 GnomeCanvasItem *item;
919 gl_debug (DEBUG_VIEW, "START");
921 g_return_if_fail (view && GL_IS_VIEW (view));
922 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
926 template = gl_label_get_template (label);
927 gl_label_get_size (label, &w, &h);
931 r1 = template->label.cd.r1;
932 r2 = template->label.cd.r2;
934 theta1 = (180.0/G_PI) * acos (w / (2.0*r1));
935 theta2 = (180.0/G_PI) * asin (h / (2.0*r1));
937 points = gnome_canvas_points_new (360/ARC_FINE + 1);
940 points->coords[i_coords++] = x0 + r1 * cos (theta1 * G_PI / 180.0);
941 points->coords[i_coords++] = y0 + r1 * sin (theta1 * G_PI / 180.0);
943 for ( i_theta = theta1 + ARC_FINE; i_theta < theta2; i_theta +=ARC_FINE ) {
944 points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
945 points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
948 points->coords[i_coords++] = x0 + r1 * cos (theta2 * G_PI / 180.0);
949 points->coords[i_coords++] = y0 + r1 * sin (theta2 * G_PI / 180.0);
952 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
953 points->coords[i_coords++] = x0 + r1 * cos ((180-theta2) * G_PI / 180.0);
954 points->coords[i_coords++] = y0 + r1 * sin ((180-theta2) * G_PI / 180.0);
957 for ( i_theta = 180-theta2+ARC_FINE; i_theta < (180-theta1); i_theta +=ARC_FINE ) {
958 points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
959 points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
962 points->coords[i_coords++] = x0 + r1 * cos ((180-theta1) * G_PI / 180.0);
963 points->coords[i_coords++] = y0 + r1 * sin ((180-theta1) * G_PI / 180.0);
965 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
966 points->coords[i_coords++] = x0 + r1 * cos ((180+theta1) * G_PI / 180.0);
967 points->coords[i_coords++] = y0 + r1 * sin ((180+theta1) * G_PI / 180.0);
970 for ( i_theta = 180+theta1+ARC_FINE; i_theta < (180+theta2); i_theta +=ARC_FINE ) {
971 points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
972 points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
975 points->coords[i_coords++] = x0 + r1 * cos ((180+theta2) * G_PI / 180.0);
976 points->coords[i_coords++] = y0 + r1 * sin ((180+theta2) * G_PI / 180.0);
978 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
979 points->coords[i_coords++] = x0 + r1 * cos ((360-theta2) * G_PI / 180.0);
980 points->coords[i_coords++] = y0 + r1 * sin ((360-theta2) * G_PI / 180.0);
983 for ( i_theta = 360-theta2+ARC_FINE; i_theta < (360-theta1); i_theta +=ARC_FINE ) {
984 points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
985 points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
988 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
989 points->coords[i_coords++] = x0 + r1 * cos ((360-theta1) * G_PI / 180.0);
990 points->coords[i_coords++] = y0 + r1 * sin ((360-theta1) * G_PI / 180.0);
993 points->num_points = i_coords / 2;
997 item = gnome_canvas_item_new (view->bg_group,
998 gnome_canvas_polygon_get_type (),
1000 "fill_color_rgba", PAPER_COLOR,
1003 item = gnome_canvas_item_new (view->bg_group,
1004 gnome_canvas_ellipse_get_type (),
1009 "fill_color_rgba", GRID_COLOR,
1014 item = gnome_canvas_item_new (view->fg_group,
1015 gnome_canvas_polygon_get_type (),
1018 "outline_color_rgba", OUTLINE_COLOR,
1021 item = gnome_canvas_item_new (view->fg_group,
1022 gnome_canvas_ellipse_get_type (),
1028 "outline_color_rgba", OUTLINE_COLOR,
1031 gnome_canvas_points_free (points);
1033 gl_debug (DEBUG_VIEW, "END");
1036 /*---------------------------------------------------------------------------*/
1037 /* PRIVATE. Draw grid lines. */
1038 /*---------------------------------------------------------------------------*/
1040 draw_grid_layer (glView *view)
1043 GnomeCanvasPoints *points;
1044 GnomeCanvasItem *item;
1045 GnomeCanvasGroup *group;
1047 gl_debug (DEBUG_VIEW, "START");
1049 g_return_if_fail (view && GL_IS_VIEW (view));
1050 g_return_if_fail (view->label && GL_IS_LABEL(view->label));
1052 gl_label_get_size (view->label, &w, &h);
1054 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
1055 view->grid_group = GNOME_CANVAS_GROUP(
1056 gnome_canvas_item_new (group,
1057 gnome_canvas_group_get_type (),
1061 points = gnome_canvas_points_new (2);
1063 points->coords[1] = 0.0;
1064 points->coords[3] = h;
1065 for ( x=0.0; x < w; x += view->grid_spacing ) {
1066 points->coords[0] = points->coords[2] = x;
1067 item = gnome_canvas_item_new (view->grid_group,
1068 gnome_canvas_line_get_type (),
1071 "fill_color_rgba", GRID_COLOR,
1074 points->coords[0] = points->coords[2] = w;
1075 item = gnome_canvas_item_new (view->grid_group,
1076 gnome_canvas_line_get_type (),
1079 "fill_color_rgba", GRID_COLOR,
1082 points->coords[0] = 0.0;
1083 points->coords[2] = w;
1084 for ( y=0.0; y < h; y += view->grid_spacing ) {
1085 points->coords[1] = points->coords[3] = y;
1086 item = gnome_canvas_item_new (view->grid_group,
1087 gnome_canvas_line_get_type (),
1090 "fill_color_rgba", GRID_COLOR,
1093 points->coords[1] = points->coords[3] = h;
1094 item = gnome_canvas_item_new (view->grid_group,
1095 gnome_canvas_line_get_type (),
1098 "fill_color_rgba", GRID_COLOR,
1101 gnome_canvas_points_free (points);
1103 gl_debug (DEBUG_VIEW, "END");
1106 /*---------------------------------------------------------------------------*/
1107 /* PRIVATE. Draw markup lines. */
1108 /*---------------------------------------------------------------------------*/
1110 draw_markup_layer (glView *view)
1112 GnomeCanvasGroup *group;
1114 glTemplate *template;
1116 glTemplateMarkup *markup;
1118 g_return_if_fail (view && GL_IS_VIEW (view));
1119 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1121 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
1122 view->markup_group = GNOME_CANVAS_GROUP(
1123 gnome_canvas_item_new (group,
1124 gnome_canvas_group_get_type (),
1129 label = view->label;
1130 template = gl_label_get_template (label);
1132 for ( p=template->label.any.markups; p != NULL; p=p->next ) {
1133 markup = (glTemplateMarkup *)p->data;
1135 switch (markup->type) {
1136 case GL_TEMPLATE_MARKUP_MARGIN:
1137 draw_markup_margin (view,
1138 (glTemplateMarkupMargin *)markup);
1140 case GL_TEMPLATE_MARKUP_LINE:
1141 draw_markup_line (view,
1142 (glTemplateMarkupLine *)markup);
1143 case GL_TEMPLATE_MARKUP_CIRCLE:
1144 draw_markup_circle (view,
1145 (glTemplateMarkupCircle *)markup);
1148 g_warning ("Unknown template markup type");
1154 /*---------------------------------------------------------------------------*/
1155 /* PRIVATE. Draw margin markup. */
1156 /*---------------------------------------------------------------------------*/
1158 draw_markup_margin (glView *view,
1159 glTemplateMarkupMargin *margin)
1162 glTemplate *template;
1164 g_return_if_fail (view && GL_IS_VIEW (view));
1165 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1167 label = view->label;
1168 template = gl_label_get_template (label);
1170 switch (template->label.style) {
1172 case GL_TEMPLATE_STYLE_RECT:
1173 if (template->label.rect.r == 0.0) {
1174 /* Square corners. */
1175 draw_markup_margin_rect (view, margin);
1177 if ( margin->size < template->label.rect.r) {
1178 /* Rounded corners. */
1179 draw_markup_margin_rounded_rect (view, margin);
1181 /* Square corners. */
1182 draw_markup_margin_rect (view, margin);
1187 case GL_TEMPLATE_STYLE_ROUND:
1188 draw_markup_margin_round (view, margin);
1191 case GL_TEMPLATE_STYLE_CD:
1192 if ((template->label.cd.w == 0.0) && (template->label.cd.h == 0.0) ) {
1193 draw_markup_margin_cd (view, margin);
1195 draw_markup_margin_cd_bc (view, margin);
1200 g_warning ("Unknown template label style");
1205 /*---------------------------------------------------------------------------*/
1206 /* PRIVATE. Draw simple recangular margin. */
1207 /*---------------------------------------------------------------------------*/
1209 draw_markup_margin_rect (glView *view,
1210 glTemplateMarkupMargin *margin)
1213 glTemplate *template;
1215 GnomeCanvasItem *item;
1217 gl_debug (DEBUG_VIEW, "START");
1219 g_return_if_fail (view && GL_IS_VIEW (view));
1220 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1222 label = view->label;
1224 gl_label_get_size (label, &w, &h);
1225 template = gl_label_get_template (label);
1228 /* Bounding box @ margin */
1229 gnome_canvas_item_new (view->markup_group,
1230 gnome_canvas_rect_get_type (),
1236 "outline_color_rgba", MARKUP_COLOR,
1239 gl_debug (DEBUG_VIEW, "END");
1242 /*---------------------------------------------------------------------------*/
1243 /* PRIVATE. Draw rounded recangular markup. */
1244 /*---------------------------------------------------------------------------*/
1246 draw_markup_margin_rounded_rect (glView *view,
1247 glTemplateMarkupMargin *margin)
1250 GnomeCanvasPoints *points;
1251 gint i_coords, i_theta;
1252 glTemplate *template;
1254 GnomeCanvasItem *item;
1256 gl_debug (DEBUG_VIEW, "START");
1258 g_return_if_fail (view && GL_IS_VIEW (view));
1259 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1261 label = view->label;
1263 gl_label_get_size (label, &w, &h);
1264 template = gl_label_get_template (label);
1265 r = template->label.rect.r;
1272 /* rectangle with rounded corners */
1273 points = gnome_canvas_points_new (4 * (1 + 90 / ARC_COURSE));
1275 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1276 points->coords[i_coords++] =
1277 m + r - r * sin (i_theta * G_PI / 180.0);
1278 points->coords[i_coords++] =
1279 m + r - r * cos (i_theta * G_PI / 180.0);
1281 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1282 points->coords[i_coords++] =
1283 m + r - r * cos (i_theta * G_PI / 180.0);
1284 points->coords[i_coords++] =
1285 m + (h - r) + r * sin (i_theta * G_PI / 180.0);
1287 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1288 points->coords[i_coords++] =
1289 m + (w - r) + r * sin (i_theta * G_PI / 180.0);
1290 points->coords[i_coords++] =
1291 m + (h - r) + r * cos (i_theta * G_PI / 180.0);
1293 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1294 points->coords[i_coords++] =
1295 m + (w - r) + r * cos (i_theta * G_PI / 180.0);
1296 points->coords[i_coords++] =
1297 m + r - r * sin (i_theta * G_PI / 180.0);
1299 item = gnome_canvas_item_new (view->markup_group,
1300 gnome_canvas_polygon_get_type (),
1303 "outline_color_rgba", MARKUP_COLOR,
1305 gnome_canvas_points_free (points);
1307 gl_debug (DEBUG_VIEW, "END");
1310 /*---------------------------------------------------------------------------*/
1311 /* PRIVATE. Draw round margin. */
1312 /*---------------------------------------------------------------------------*/
1314 draw_markup_margin_round (glView *view,
1315 glTemplateMarkupMargin *margin)
1318 glTemplate *template;
1320 GnomeCanvasItem *item;
1322 gl_debug (DEBUG_VIEW, "START");
1324 g_return_if_fail (view && GL_IS_VIEW (view));
1325 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1327 label = view->label;
1328 template = gl_label_get_template (label);
1330 r = template->label.round.r;
1333 /* Margin outline */
1334 item = gnome_canvas_item_new (view->markup_group,
1335 gnome_canvas_ellipse_get_type (),
1341 "outline_color_rgba", MARKUP_COLOR,
1344 gl_debug (DEBUG_VIEW, "END");
1347 /*---------------------------------------------------------------------------*/
1348 /* PRIVATE. Draw CD margins. */
1349 /*---------------------------------------------------------------------------*/
1351 draw_markup_margin_cd (glView *view,
1352 glTemplateMarkupMargin *margin)
1355 glTemplate *template;
1357 GnomeCanvasItem *item;
1359 gl_debug (DEBUG_VIEW, "START");
1361 g_return_if_fail (view && GL_IS_VIEW (view));
1362 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1364 label = view->label;
1365 template = gl_label_get_template (label);
1367 r1 = template->label.cd.r1;
1368 r2 = template->label.cd.r2;
1372 item = gnome_canvas_item_new (view->markup_group,
1373 gnome_canvas_ellipse_get_type (),
1379 "outline_color_rgba", MARKUP_COLOR,
1382 item = gnome_canvas_item_new (view->markup_group,
1383 gnome_canvas_ellipse_get_type (),
1389 "outline_color_rgba", MARKUP_COLOR,
1392 gl_debug (DEBUG_VIEW, "END");
1395 /*---------------------------------------------------------------------------*/
1396 /* PRIVATE. Draw Business Card CD margins. */
1397 /*---------------------------------------------------------------------------*/
1399 draw_markup_margin_cd_bc (glView *view,
1400 glTemplateMarkupMargin *margin)
1403 glTemplate *template;
1405 GnomeCanvasPoints *points;
1406 gint i_coords, i_theta;
1407 gdouble theta1, theta2;
1408 gdouble x0, y0, w, h, r;
1409 GnomeCanvasItem *item;
1411 gl_debug (DEBUG_VIEW, "START");
1413 g_return_if_fail (view && GL_IS_VIEW (view));
1414 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1416 label = view->label;
1417 template = gl_label_get_template (label);
1418 gl_label_get_size (label, &w, &h);
1422 r1 = template->label.cd.r1;
1423 r2 = template->label.cd.r2;
1428 theta1 = (180.0/G_PI) * acos (w / (2.0*r1));
1429 theta2 = (180.0/G_PI) * asin (h / (2.0*r1));
1431 points = gnome_canvas_points_new (360/ARC_FINE + 1);
1434 points->coords[i_coords++] = x0 + r * cos (theta1 * G_PI / 180.0);
1435 points->coords[i_coords++] = y0 + r * sin (theta1 * G_PI / 180.0);
1437 for ( i_theta = theta1 + ARC_FINE; i_theta < theta2; i_theta +=ARC_FINE ) {
1438 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
1439 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
1442 points->coords[i_coords++] = x0 + r * cos (theta2 * G_PI / 180.0);
1443 points->coords[i_coords++] = y0 + r * sin (theta2 * G_PI / 180.0);
1446 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
1447 points->coords[i_coords++] = x0 + r * cos ((180-theta2) * G_PI / 180.0);
1448 points->coords[i_coords++] = y0 + r * sin ((180-theta2) * G_PI / 180.0);
1451 for ( i_theta = 180-theta2+ARC_FINE; i_theta < (180-theta1); i_theta +=ARC_FINE ) {
1452 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
1453 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
1456 points->coords[i_coords++] = x0 + r * cos ((180-theta1) * G_PI / 180.0);
1457 points->coords[i_coords++] = y0 + r * sin ((180-theta1) * G_PI / 180.0);
1459 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
1460 points->coords[i_coords++] = x0 + r * cos ((180+theta1) * G_PI / 180.0);
1461 points->coords[i_coords++] = y0 + r * sin ((180+theta1) * G_PI / 180.0);
1464 for ( i_theta = 180+theta1+ARC_FINE; i_theta < (180+theta2); i_theta +=ARC_FINE ) {
1465 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
1466 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
1469 points->coords[i_coords++] = x0 + r * cos ((180+theta2) * G_PI / 180.0);
1470 points->coords[i_coords++] = y0 + r * sin ((180+theta2) * G_PI / 180.0);
1472 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
1473 points->coords[i_coords++] = x0 + r * cos ((360-theta2) * G_PI / 180.0);
1474 points->coords[i_coords++] = y0 + r * sin ((360-theta2) * G_PI / 180.0);
1477 for ( i_theta = 360-theta2+ARC_FINE; i_theta < (360-theta1); i_theta +=ARC_FINE ) {
1478 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
1479 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
1482 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
1483 points->coords[i_coords++] = x0 + r * cos ((360-theta1) * G_PI / 180.0);
1484 points->coords[i_coords++] = y0 + r * sin ((360-theta1) * G_PI / 180.0);
1487 points->num_points = i_coords / 2;
1489 item = gnome_canvas_item_new (view->markup_group,
1490 gnome_canvas_polygon_get_type (),
1493 "outline_color_rgba", MARKUP_COLOR,
1496 gnome_canvas_points_free (points);
1499 item = gnome_canvas_item_new (view->markup_group,
1500 gnome_canvas_ellipse_get_type (),
1506 "outline_color_rgba", MARKUP_COLOR,
1509 gl_debug (DEBUG_VIEW, "END");
1512 /*---------------------------------------------------------------------------*/
1513 /* PRIVATE. Draw line markup. */
1514 /*---------------------------------------------------------------------------*/
1516 draw_markup_line (glView *view,
1517 glTemplateMarkupLine *line)
1519 GnomeCanvasPoints *points;
1521 gl_debug (DEBUG_VIEW, "START");
1523 g_return_if_fail (view && GL_IS_VIEW (view));
1525 points = gnome_canvas_points_new (2);
1526 points->coords[0] = line->x1;
1527 points->coords[1] = line->y1;
1528 points->coords[2] = line->x2;
1529 points->coords[3] = line->y2;
1531 /* Bounding box @ margin */
1532 gnome_canvas_item_new (view->markup_group,
1533 gnome_canvas_line_get_type (),
1536 "fill_color_rgba", MARKUP_COLOR,
1539 gnome_canvas_points_free (points);
1541 gl_debug (DEBUG_VIEW, "END");
1544 /*---------------------------------------------------------------------------*/
1545 /* PRIVATE. Draw circle markup. */
1546 /*---------------------------------------------------------------------------*/
1548 draw_markup_circle (glView *view,
1549 glTemplateMarkupCircle *circle)
1551 gl_debug (DEBUG_VIEW, "START");
1553 g_return_if_fail (view && GL_IS_VIEW (view));
1555 /* Circle outline */
1556 gnome_canvas_item_new (view->markup_group,
1557 gnome_canvas_ellipse_get_type (),
1558 "x1", circle->x0 - circle->r,
1559 "y1", circle->y0 - circle->r,
1560 "x2", circle->x0 + circle->r,
1561 "y2", circle->y0 + circle->r,
1563 "outline_color_rgba", MARKUP_COLOR,
1566 gl_debug (DEBUG_VIEW, "END");
1569 /*****************************************************************************/
1571 /*****************************************************************************/
1572 void gl_view_show_grid (glView *view)
1574 g_return_if_fail (view && GL_IS_VIEW (view));
1576 gnome_canvas_item_show (GNOME_CANVAS_ITEM(view->grid_group));
1579 /*****************************************************************************/
1581 /*****************************************************************************/
1582 void gl_view_hide_grid (glView *view)
1584 g_return_if_fail (view && GL_IS_VIEW (view));
1586 gnome_canvas_item_hide (GNOME_CANVAS_ITEM(view->grid_group));
1589 /*****************************************************************************/
1590 /* Set grid spacing. */
1591 /*****************************************************************************/
1592 void gl_view_set_grid_spacing (glView *view,
1595 g_return_if_fail (view && GL_IS_VIEW (view));
1597 view->grid_spacing = spacing;
1599 gtk_object_destroy (GTK_OBJECT(view->grid_group));
1600 draw_grid_layer (view);
1603 /*****************************************************************************/
1605 /*****************************************************************************/
1606 void gl_view_show_markup (glView *view)
1608 g_return_if_fail (view && GL_IS_VIEW (view));
1610 gnome_canvas_item_show (GNOME_CANVAS_ITEM(view->markup_group));
1613 /*****************************************************************************/
1615 /*****************************************************************************/
1616 void gl_view_hide_markup (glView *view)
1618 g_return_if_fail (view && GL_IS_VIEW (view));
1620 gnome_canvas_item_hide (GNOME_CANVAS_ITEM(view->markup_group));
1623 /*****************************************************************************/
1624 /* Set arrow mode. */
1625 /*****************************************************************************/
1627 gl_view_arrow_mode (glView *view)
1629 static GdkCursor *cursor = NULL;
1631 gl_debug (DEBUG_VIEW, "START");
1633 g_return_if_fail (view && GL_IS_VIEW (view));
1636 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1639 gdk_window_set_cursor (view->canvas->window, cursor);
1641 view->state = GL_VIEW_STATE_ARROW;
1643 gl_debug (DEBUG_VIEW, "END");
1646 /*****************************************************************************/
1647 /* Set create text object mode. */
1648 /*****************************************************************************/
1650 gl_view_object_create_mode (glView *view,
1651 glLabelObjectType type)
1655 gl_debug (DEBUG_VIEW, "START");
1657 g_return_if_fail (view && GL_IS_VIEW (view));
1660 case GL_LABEL_OBJECT_BOX:
1661 cursor = gl_view_box_get_create_cursor ();
1663 case GL_LABEL_OBJECT_ELLIPSE:
1664 cursor = gl_view_ellipse_get_create_cursor ();
1666 case GL_LABEL_OBJECT_LINE:
1667 cursor = gl_view_line_get_create_cursor ();
1669 case GL_LABEL_OBJECT_IMAGE:
1670 cursor = gl_view_image_get_create_cursor ();
1672 case GL_LABEL_OBJECT_TEXT:
1673 cursor = gl_view_text_get_create_cursor ();
1675 case GL_LABEL_OBJECT_BARCODE:
1676 cursor = gl_view_barcode_get_create_cursor ();
1679 g_warning ("Invalid label object type.");/*Should not happen!*/
1683 gdk_window_set_cursor (view->canvas->window, cursor);
1685 view->state = GL_VIEW_STATE_OBJECT_CREATE;
1686 view->create_type = type;
1688 gl_debug (DEBUG_VIEW, "END");
1691 /*****************************************************************************/
1692 /* Select given object (adding to current selection). */
1693 /*****************************************************************************/
1695 gl_view_select_object (glView *view,
1696 glViewObject *view_object)
1698 gl_debug (DEBUG_VIEW, "START");
1700 g_return_if_fail (view && GL_IS_VIEW (view));
1702 select_object_real (view, view_object);
1704 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1706 gl_debug (DEBUG_VIEW, "END");
1709 /*****************************************************************************/
1710 /* Unselect given object (removing from current selection). */
1711 /*****************************************************************************/
1713 gl_view_unselect_object (glView *view,
1714 glViewObject *view_object)
1716 gl_debug (DEBUG_VIEW, "START");
1718 g_return_if_fail (view && GL_IS_VIEW (view));
1720 unselect_object_real (view, view_object);
1722 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1724 gl_debug (DEBUG_VIEW, "END");
1727 /*****************************************************************************/
1728 /* Select all items. */
1729 /*****************************************************************************/
1731 gl_view_select_all (glView *view)
1735 gl_debug (DEBUG_VIEW, "START");
1737 g_return_if_fail (view && GL_IS_VIEW (view));
1739 /* 1st unselect anything already selected. */
1740 for (p = view->selected_object_list; p != NULL; p = p_next) {
1742 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1745 /* Finally select all objects. */
1746 for (p = view->object_list; p != NULL; p = p->next) {
1747 select_object_real (view, GL_VIEW_OBJECT (p->data));
1750 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1752 gl_debug (DEBUG_VIEW, "END");
1755 /*****************************************************************************/
1756 /* Remove all selections */
1757 /*****************************************************************************/
1759 gl_view_unselect_all (glView *view)
1763 gl_debug (DEBUG_VIEW, "START");
1765 g_return_if_fail (view && GL_IS_VIEW (view));
1767 for (p = view->selected_object_list; p != NULL; p = p_next) {
1769 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1772 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1774 gl_debug (DEBUG_VIEW, "END");
1777 /*****************************************************************************/
1778 /* Select all objects within given rectangular region (adding to selection). */
1779 /*****************************************************************************/
1781 gl_view_select_region (glView *view,
1788 glViewObject *view_object;
1789 glLabelObject *object;
1790 gdouble i_x1, i_y1, i_x2, i_y2;
1792 gl_debug (DEBUG_VIEW, "START");
1794 g_return_if_fail (view && GL_IS_VIEW (view));
1795 g_return_if_fail ((x1 <= x2) && (y1 <= y2));
1797 for (p = view->object_list; p != NULL; p = p->next) {
1798 view_object = GL_VIEW_OBJECT(p->data);
1799 if (!gl_view_is_object_selected (view, view_object)) {
1801 object = gl_view_object_get_object (view_object);
1803 gl_label_object_get_extent (object, &i_x1, &i_y1, &i_x2, &i_y2);
1804 if ((i_x1 >= x1) && (i_x2 <= x2) && (i_y1 >= y1)
1806 select_object_real (view, view_object);
1812 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1814 gl_debug (DEBUG_VIEW, "END");
1817 /*---------------------------------------------------------------------------*/
1818 /* PRIVATE. Select an object. */
1819 /*---------------------------------------------------------------------------*/
1821 select_object_real (glView *view,
1822 glViewObject *view_object)
1824 gl_debug (DEBUG_VIEW, "START");
1826 g_return_if_fail (view && GL_IS_VIEW (view));
1827 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1829 if (!gl_view_is_object_selected (view, view_object)) {
1830 view->selected_object_list =
1831 g_list_prepend (view->selected_object_list, view_object);
1833 gl_view_object_show_highlight (view_object);
1834 gtk_widget_grab_focus (GTK_WIDGET (view->canvas));
1836 gl_debug (DEBUG_VIEW, "END");
1839 /*---------------------------------------------------------------------------*/
1840 /* PRIVATE. Un-select object. */
1841 /*---------------------------------------------------------------------------*/
1843 unselect_object_real (glView *view,
1844 glViewObject *view_object)
1846 gl_debug (DEBUG_VIEW, "START");
1848 g_return_if_fail (view && GL_IS_VIEW (view));
1849 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1851 gl_view_object_hide_highlight (view_object);
1853 view->selected_object_list =
1854 g_list_remove (view->selected_object_list, view_object);
1856 gl_debug (DEBUG_VIEW, "END");
1859 /*---------------------------------------------------------------------------*/
1860 /* PRIVATE. Return object at (x,y). */
1861 /*---------------------------------------------------------------------------*/
1863 object_at (glView *view,
1867 GnomeCanvasItem *item, *p_item;
1870 gl_debug (DEBUG_VIEW, "");
1872 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1874 item = gnome_canvas_get_item_at (GNOME_CANVAS (view->canvas), x, y);
1876 /* No item is at x, y */
1880 /* ignore items not in label or highlight layers, e.g. background items */
1881 if (!is_item_member_of_group(view, item, GNOME_CANVAS_ITEM(view->label_group)) &&
1882 !is_item_member_of_group(view, item, GNOME_CANVAS_ITEM(view->highlight_group)))
1888 /*---------------------------------------------------------------------------*/
1889 /* PRIVATE. Is the item a child (or grandchild, etc.) of group. */
1890 /*---------------------------------------------------------------------------*/
1892 is_item_member_of_group (glView *view,
1893 GnomeCanvasItem *item,
1894 GnomeCanvasItem *group)
1896 GnomeCanvasItem *parent;
1897 GnomeCanvasItem *root_group;
1899 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1901 root_group = GNOME_CANVAS_ITEM(gnome_canvas_root (GNOME_CANVAS (view->canvas)));
1903 for ( parent=item->parent; parent && (parent!=root_group); parent=parent->parent) {
1904 if (parent == group) return TRUE;
1909 /*****************************************************************************/
1910 /* Is the object in our current selection? */
1911 /*****************************************************************************/
1913 gl_view_is_object_selected (glView *view,
1914 glViewObject *view_object)
1916 gl_debug (DEBUG_VIEW, "");
1918 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1919 g_return_val_if_fail (GL_IS_VIEW_OBJECT (view_object), FALSE);
1921 if (g_list_find (view->selected_object_list, view_object) == NULL) {
1927 /*****************************************************************************/
1928 /* Is our current selection empty? */
1929 /*****************************************************************************/
1931 gl_view_is_selection_empty (glView *view)
1933 gl_debug (DEBUG_VIEW, "");
1935 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1937 if (view->selected_object_list == NULL) {
1944 /*****************************************************************************/
1945 /* Is our current selection atomic? I.e. only one item selected. */
1946 /*****************************************************************************/
1948 gl_view_is_selection_atomic (glView *view)
1950 gl_debug (DEBUG_VIEW, "");
1952 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1954 if (view->selected_object_list == NULL)
1956 if (view->selected_object_list->next == NULL)
1961 /*****************************************************************************/
1962 /* Delete selected objects. (Bypass clipboard) */
1963 /*****************************************************************************/
1965 gl_view_delete_selection (glView *view)
1969 gl_debug (DEBUG_VIEW, "START");
1971 g_return_if_fail (view && GL_IS_VIEW (view));
1973 for (p = view->selected_object_list; p != NULL; p = p_next) {
1975 g_object_unref (G_OBJECT (p->data));
1978 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1980 gl_debug (DEBUG_VIEW, "END");
1983 /*****************************************************************************/
1984 /* Edit properties of selected object. */
1985 /*****************************************************************************/
1987 gl_view_edit_object_props (glView *view)
1989 glViewObject *view_object;
1991 gl_debug (DEBUG_VIEW, "START");
1993 g_return_if_fail (view && GL_IS_VIEW (view));
1995 if (gl_view_is_selection_atomic (view)) {
1997 view_object = GL_VIEW_OBJECT(view->selected_object_list->data);
1998 gl_view_object_show_dialog (view_object);
2002 gl_debug (DEBUG_VIEW, "END");
2005 /*****************************************************************************/
2006 /* Raise selected items to top. */
2007 /*****************************************************************************/
2009 gl_view_raise_selection (glView *view)
2012 glViewObject *view_object;
2013 glLabelObject *object;
2015 gl_debug (DEBUG_VIEW, "START");
2017 g_return_if_fail (view && GL_IS_VIEW (view));
2019 for (p = view->selected_object_list; p != NULL; p = p->next) {
2020 view_object = GL_VIEW_OBJECT (p->data);
2021 object = gl_view_object_get_object (view_object);
2022 gl_label_object_raise_to_top (object);
2025 gl_debug (DEBUG_VIEW, "END");
2028 /*****************************************************************************/
2029 /* Lower selected items to bottom. */
2030 /*****************************************************************************/
2032 gl_view_lower_selection (glView *view)
2035 glViewObject *view_object;
2036 glLabelObject *object;
2038 gl_debug (DEBUG_VIEW, "START");
2040 g_return_if_fail (view && GL_IS_VIEW (view));
2042 for (p = view->selected_object_list; p != NULL; p = p->next) {
2043 view_object = GL_VIEW_OBJECT (p->data);
2044 object = gl_view_object_get_object (view_object);
2045 gl_label_object_lower_to_bottom (object);
2048 gl_debug (DEBUG_VIEW, "END");
2051 /*****************************************************************************/
2052 /* Rotate selected objects by given angle. */
2053 /*****************************************************************************/
2055 gl_view_rotate_selection (glView *view,
2059 glViewObject *view_object;
2060 glLabelObject *object;
2062 gl_debug (DEBUG_VIEW, "START");
2064 g_return_if_fail (view && GL_IS_VIEW (view));
2066 for (p = view->selected_object_list; p != NULL; p = p->next) {
2067 view_object = GL_VIEW_OBJECT (p->data);
2068 object = gl_view_object_get_object (view_object);
2069 gl_label_object_rotate (object, theta_degs);
2072 gl_debug (DEBUG_VIEW, "END");
2075 /*****************************************************************************/
2076 /* Rotate selected objects 90 degrees left. */
2077 /*****************************************************************************/
2079 gl_view_rotate_selection_left (glView *view)
2082 glViewObject *view_object;
2083 glLabelObject *object;
2085 gl_debug (DEBUG_VIEW, "START");
2087 g_return_if_fail (view && GL_IS_VIEW (view));
2089 for (p = view->selected_object_list; p != NULL; p = p->next) {
2090 view_object = GL_VIEW_OBJECT (p->data);
2091 object = gl_view_object_get_object (view_object);
2092 gl_label_object_rotate (object, -90.0);
2095 gl_debug (DEBUG_VIEW, "END");
2098 /*****************************************************************************/
2099 /* Rotate selected objects 90 degrees right. */
2100 /*****************************************************************************/
2102 gl_view_rotate_selection_right (glView *view)
2105 glViewObject *view_object;
2106 glLabelObject *object;
2108 gl_debug (DEBUG_VIEW, "START");
2110 g_return_if_fail (view && GL_IS_VIEW (view));
2112 for (p = view->selected_object_list; p != NULL; p = p->next) {
2113 view_object = GL_VIEW_OBJECT (p->data);
2114 object = gl_view_object_get_object (view_object);
2115 gl_label_object_rotate (object, 90.0);
2118 gl_debug (DEBUG_VIEW, "END");
2121 /*****************************************************************************/
2122 /* Flip selected objects horizontally. */
2123 /*****************************************************************************/
2125 gl_view_flip_selection_horiz (glView *view)
2128 glViewObject *view_object;
2129 glLabelObject *object;
2131 gl_debug (DEBUG_VIEW, "START");
2133 g_return_if_fail (view && GL_IS_VIEW (view));
2135 for (p = view->selected_object_list; p != NULL; p = p->next) {
2136 view_object = GL_VIEW_OBJECT (p->data);
2137 object = gl_view_object_get_object (view_object);
2138 gl_label_object_flip_horiz (object);
2141 gl_debug (DEBUG_VIEW, "END");
2144 /*****************************************************************************/
2145 /* Flip selected objects vertically. */
2146 /*****************************************************************************/
2148 gl_view_flip_selection_vert (glView *view)
2151 glViewObject *view_object;
2152 glLabelObject *object;
2154 gl_debug (DEBUG_VIEW, "START");
2156 g_return_if_fail (view && GL_IS_VIEW (view));
2158 for (p = view->selected_object_list; p != NULL; p = p->next) {
2159 view_object = GL_VIEW_OBJECT (p->data);
2160 object = gl_view_object_get_object (view_object);
2161 gl_label_object_flip_vert (object);
2164 gl_debug (DEBUG_VIEW, "END");
2167 /*****************************************************************************/
2168 /* Align selected objects to left most edge. */
2169 /*****************************************************************************/
2171 gl_view_align_selection_left (glView *view)
2174 glViewObject *view_object;
2175 glLabelObject *object;
2176 gdouble dx, x1min, x1, y1, x2, y2;
2178 gl_debug (DEBUG_VIEW, "START");
2180 g_return_if_fail (view && GL_IS_VIEW (view));
2182 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2183 !gl_view_is_selection_atomic (view));
2185 /* find left most edge */
2186 p = view->selected_object_list;
2187 view_object = GL_VIEW_OBJECT (p->data);
2188 object = gl_view_object_get_object (view_object);
2189 gl_label_object_get_extent (object, &x1min, &y1, &x2, &y2);
2190 for (p = p->next; p != NULL; p = p->next) {
2191 view_object = GL_VIEW_OBJECT (p->data);
2192 object = gl_view_object_get_object (view_object);
2193 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2194 if ( x1 < x1min ) x1min = x1;
2197 /* now adjust the object positions to line up the left edges */
2198 for (p = view->selected_object_list; p != NULL; p = p->next) {
2199 view_object = GL_VIEW_OBJECT (p->data);
2200 object = gl_view_object_get_object (view_object);
2201 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2203 gl_label_object_set_position_relative (object, dx, 0.0);
2206 gl_debug (DEBUG_VIEW, "END");
2210 /*****************************************************************************/
2211 /* Align selected objects to right most edge. */
2212 /*****************************************************************************/
2214 gl_view_align_selection_right (glView *view)
2217 glViewObject *view_object;
2218 glLabelObject *object;
2219 gdouble dx, x2max, x1, y1, x2, y2;
2221 gl_debug (DEBUG_VIEW, "START");
2223 g_return_if_fail (view && GL_IS_VIEW (view));
2225 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2226 !gl_view_is_selection_atomic (view));
2228 /* find right most edge */
2229 p = view->selected_object_list;
2230 view_object = GL_VIEW_OBJECT (p->data);
2231 object = gl_view_object_get_object (view_object);
2232 gl_label_object_get_extent (object, &x1, &y1, &x2max, &y2);
2233 for (p = p->next; p != NULL; p = p->next) {
2234 view_object = GL_VIEW_OBJECT (p->data);
2235 object = gl_view_object_get_object (view_object);
2236 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2237 if ( x2 > x2max ) x2max = x2;
2240 /* now adjust the object positions to line up the right edges */
2241 for (p = view->selected_object_list; p != NULL; p = p->next) {
2242 view_object = GL_VIEW_OBJECT (p->data);
2243 object = gl_view_object_get_object (view_object);
2244 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2246 gl_label_object_set_position_relative (object, dx, 0.0);
2249 gl_debug (DEBUG_VIEW, "END");
2252 /*****************************************************************************/
2253 /* Align selected objects to horizontal center of objects. */
2254 /*****************************************************************************/
2256 gl_view_align_selection_hcenter (glView *view)
2259 glViewObject *view_object;
2260 glLabelObject *object;
2261 gdouble dx, dxmin, xsum, xavg, xcenter, x1, y1, x2, y2;
2264 gl_debug (DEBUG_VIEW, "START");
2266 g_return_if_fail (view && GL_IS_VIEW (view));
2268 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2269 !gl_view_is_selection_atomic (view));
2271 /* find average center of objects */
2274 for (p = view->selected_object_list; p != NULL; p = p->next) {
2275 view_object = GL_VIEW_OBJECT (p->data);
2276 object = gl_view_object_get_object (view_object);
2277 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2278 xsum += (x1 + x2) / 2.0;
2283 /* find center of object closest to average center */
2284 p = view->selected_object_list;
2285 view_object = GL_VIEW_OBJECT (p->data);
2286 object = gl_view_object_get_object (view_object);
2287 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2288 dxmin = fabs (xavg - (x1 + x2)/2.0);
2289 xcenter = (x1 + x2)/2.0;
2290 for (p = p->next; p != NULL; p = p->next) {
2291 view_object = GL_VIEW_OBJECT (p->data);
2292 object = gl_view_object_get_object (view_object);
2293 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2294 dx = fabs (xavg - (x1 + x2)/2.0);
2297 xcenter = (x1 + x2)/2.0;
2301 /* now adjust the object positions to line up this center */
2302 for (p = view->selected_object_list; p != NULL; p = p->next) {
2303 view_object = GL_VIEW_OBJECT (p->data);
2304 object = gl_view_object_get_object (view_object);
2305 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2306 dx = xcenter - (x1 + x2)/2.0;
2307 gl_label_object_set_position_relative (object, dx, 0.0);
2310 gl_debug (DEBUG_VIEW, "END");
2313 /*****************************************************************************/
2314 /* Align selected objects to top most edge. */
2315 /*****************************************************************************/
2317 gl_view_align_selection_top (glView *view)
2320 glViewObject *view_object;
2321 glLabelObject *object;
2322 gdouble dy, y1min, x1, y1, x2, y2;
2324 gl_debug (DEBUG_VIEW, "START");
2326 g_return_if_fail (view && GL_IS_VIEW (view));
2328 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2329 !gl_view_is_selection_atomic (view));
2331 /* find top most edge */
2332 p = view->selected_object_list;
2333 view_object = GL_VIEW_OBJECT (p->data);
2334 object = gl_view_object_get_object (view_object);
2335 gl_label_object_get_extent (object, &x1, &y1min, &x2, &y2);
2336 for (p = p->next; p != NULL; p = p->next) {
2337 view_object = GL_VIEW_OBJECT (p->data);
2338 object = gl_view_object_get_object (view_object);
2339 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2340 if ( y1 < y1min ) y1min = y1;
2343 /* now adjust the object positions to line up the top edges */
2344 for (p = view->selected_object_list; p != NULL; p = p->next) {
2345 view_object = GL_VIEW_OBJECT (p->data);
2346 object = gl_view_object_get_object (view_object);
2347 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2349 gl_label_object_set_position_relative (object, 0.0, dy);
2352 gl_debug (DEBUG_VIEW, "END");
2355 /*****************************************************************************/
2356 /* Align selected objects to bottom most edge. */
2357 /*****************************************************************************/
2359 gl_view_align_selection_bottom (glView *view)
2362 glViewObject *view_object;
2363 glLabelObject *object;
2364 gdouble dy, y2max, x1, y1, x2, y2;
2366 gl_debug (DEBUG_VIEW, "START");
2368 g_return_if_fail (view && GL_IS_VIEW (view));
2370 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2371 !gl_view_is_selection_atomic (view));
2373 /* find bottom most edge */
2374 p = view->selected_object_list;
2375 view_object = GL_VIEW_OBJECT (p->data);
2376 object = gl_view_object_get_object (view_object);
2377 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2max);
2378 for (p = p->next; p != NULL; p = p->next) {
2379 view_object = GL_VIEW_OBJECT (p->data);
2380 object = gl_view_object_get_object (view_object);
2381 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2382 if ( y2 > y2max ) y2max = y2;
2385 /* now adjust the object positions to line up the bottom edges */
2386 for (p = view->selected_object_list; p != NULL; p = p->next) {
2387 view_object = GL_VIEW_OBJECT (p->data);
2388 object = gl_view_object_get_object (view_object);
2389 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2391 gl_label_object_set_position_relative (object, 0.0, dy);
2394 gl_debug (DEBUG_VIEW, "END");
2397 /*****************************************************************************/
2398 /* Align selected objects to viertical center of objects. */
2399 /*****************************************************************************/
2401 gl_view_align_selection_vcenter (glView *view)
2404 glViewObject *view_object;
2405 glLabelObject *object;
2406 gdouble dy, dymin, ysum, yavg, ycenter, x1, y1, x2, y2;
2409 gl_debug (DEBUG_VIEW, "START");
2411 g_return_if_fail (view && GL_IS_VIEW (view));
2413 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2414 !gl_view_is_selection_atomic (view));
2416 /* find average center of objects */
2419 for (p = view->selected_object_list; p != NULL; p = p->next) {
2420 view_object = GL_VIEW_OBJECT (p->data);
2421 object = gl_view_object_get_object (view_object);
2422 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2423 ysum += (y1 + y2) / 2.0;
2428 /* find center of object closest to average center */
2429 p = view->selected_object_list;
2430 view_object = GL_VIEW_OBJECT (p->data);
2431 object = gl_view_object_get_object (view_object);
2432 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2433 dymin = fabs (yavg - (y1 + y2)/2.0);
2434 ycenter = (y1 + y2)/2.0;
2435 for (p = p->next; p != NULL; p = p->next) {
2436 view_object = GL_VIEW_OBJECT (p->data);
2437 object = gl_view_object_get_object (view_object);
2438 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2439 dy = fabs (yavg - (y1 + y2)/2.0);
2442 ycenter = (y1 + y2)/2.0;
2446 /* now adjust the object positions to line up this center */
2447 for (p = view->selected_object_list; p != NULL; p = p->next) {
2448 view_object = GL_VIEW_OBJECT (p->data);
2449 object = gl_view_object_get_object (view_object);
2450 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2451 dy = ycenter - (y1 + y2)/2.0;
2452 gl_label_object_set_position_relative (object, 0.0, dy);
2455 gl_debug (DEBUG_VIEW, "END");
2458 /*****************************************************************************/
2459 /* Center selected objects to in center of label. */
2460 /*****************************************************************************/
2462 gl_view_center_selection_horiz (glView *view)
2465 glViewObject *view_object;
2466 glLabelObject *object;
2467 gdouble dx, x_label_center, x_obj_center, x1, y1, x2, y2, w, h;
2469 gl_debug (DEBUG_VIEW, "START");
2471 g_return_if_fail (view && GL_IS_VIEW (view));
2473 g_return_if_fail (!gl_view_is_selection_empty (view));
2475 gl_label_get_size (view->label, &w, &h);
2476 x_label_center = w / 2.0;
2478 /* adjust the object positions */
2479 for (p = view->selected_object_list; p != NULL; p = p->next) {
2480 view_object = GL_VIEW_OBJECT (p->data);
2481 object = gl_view_object_get_object (view_object);
2482 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2483 x_obj_center = (x1 + x2) / 2.0;
2484 dx = x_label_center - x_obj_center;
2485 gl_label_object_set_position_relative (object, dx, 0.0);
2488 gl_debug (DEBUG_VIEW, "END");
2492 /*****************************************************************************/
2493 /* Center selected objects to in center of label. */
2494 /*****************************************************************************/
2496 gl_view_center_selection_vert (glView *view)
2499 glViewObject *view_object;
2500 glLabelObject *object;
2501 gdouble dy, y_label_center, y_obj_center, x1, y1, x2, y2, w, h;
2503 gl_debug (DEBUG_VIEW, "START");
2505 g_return_if_fail (view && GL_IS_VIEW (view));
2507 g_return_if_fail (!gl_view_is_selection_empty (view));
2509 gl_label_get_size (view->label, &w, &h);
2510 y_label_center = h / 2.0;
2512 /* adjust the object positions */
2513 for (p = view->selected_object_list; p != NULL; p = p->next) {
2514 view_object = GL_VIEW_OBJECT (p->data);
2515 object = gl_view_object_get_object (view_object);
2516 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2517 y_obj_center = (y1 + y2) / 2.0;
2518 dy = y_label_center - y_obj_center;
2519 gl_label_object_set_position_relative (object, 0.0, dy);
2522 gl_debug (DEBUG_VIEW, "END");
2526 /*****************************************************************************/
2527 /* Move selected objects */
2528 /*****************************************************************************/
2530 gl_view_move_selection (glView *view,
2535 glLabelObject *object;
2537 gl_debug (DEBUG_VIEW, "START");
2539 g_return_if_fail (view && GL_IS_VIEW (view));
2541 for (p = view->selected_object_list; p != NULL; p = p->next) {
2543 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2544 gl_label_object_set_position_relative (object, dx, dy);
2548 gl_debug (DEBUG_VIEW, "END");
2551 /*****************************************************************************/
2552 /* Can text properties be set for selection? */
2553 /*****************************************************************************/
2555 gl_view_can_selection_text (glView *view)
2558 glLabelObject *object;
2560 gl_debug (DEBUG_VIEW, "");
2562 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2564 for (p = view->selected_object_list; p != NULL; p = p->next) {
2566 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2567 if (gl_label_object_can_text (object)) {
2576 /*****************************************************************************/
2577 /* Set font family for all text contained in selected objects. */
2578 /*****************************************************************************/
2580 gl_view_set_selection_font_family (glView *view,
2581 const gchar *font_family)
2584 glLabelObject *object;
2586 gl_debug (DEBUG_VIEW, "START");
2588 g_return_if_fail (view && GL_IS_VIEW (view));
2590 for (p = view->selected_object_list; p != NULL; p = p->next) {
2592 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2593 gl_label_object_set_font_family (object, font_family);
2597 gl_debug (DEBUG_VIEW, "END");
2600 /*****************************************************************************/
2601 /* Set font size for all text contained in selected objects. */
2602 /*****************************************************************************/
2604 gl_view_set_selection_font_size (glView *view,
2608 glLabelObject *object;
2610 gl_debug (DEBUG_VIEW, "START");
2612 g_return_if_fail (view && GL_IS_VIEW (view));
2614 for (p = view->selected_object_list; p != NULL; p = p->next) {
2616 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2617 gl_label_object_set_font_size (object, font_size);
2621 gl_debug (DEBUG_VIEW, "END");
2624 /*****************************************************************************/
2625 /* Set font weight for all text contained in selected objects. */
2626 /*****************************************************************************/
2628 gl_view_set_selection_font_weight (glView *view,
2629 GnomeFontWeight font_weight)
2632 glLabelObject *object;
2634 gl_debug (DEBUG_VIEW, "START");
2636 g_return_if_fail (view && GL_IS_VIEW (view));
2638 for (p = view->selected_object_list; p != NULL; p = p->next) {
2640 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2641 gl_label_object_set_font_weight (object, font_weight);
2645 gl_debug (DEBUG_VIEW, "END");
2648 /*****************************************************************************/
2649 /* Set font italic flag for all text contained in selected objects. */
2650 /*****************************************************************************/
2652 gl_view_set_selection_font_italic_flag (glView *view,
2653 gboolean font_italic_flag)
2656 glLabelObject *object;
2658 gl_debug (DEBUG_VIEW, "START");
2660 g_return_if_fail (view && GL_IS_VIEW (view));
2662 for (p = view->selected_object_list; p != NULL; p = p->next) {
2664 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2665 gl_label_object_set_font_italic_flag (object, font_italic_flag);
2669 gl_debug (DEBUG_VIEW, "END");
2672 /*****************************************************************************/
2673 /* Set text alignment for all text contained in selected objects. */
2674 /*****************************************************************************/
2676 gl_view_set_selection_text_alignment (glView *view,
2677 GtkJustification text_alignment)
2680 glLabelObject *object;
2682 gl_debug (DEBUG_VIEW, "START");
2684 g_return_if_fail (view && GL_IS_VIEW (view));
2686 for (p = view->selected_object_list; p != NULL; p = p->next) {
2688 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2689 gl_label_object_set_text_alignment (object, text_alignment);
2693 gl_debug (DEBUG_VIEW, "END");
2696 /*****************************************************************************/
2697 /* Set text color for all text contained in selected objects. */
2698 /*****************************************************************************/
2700 gl_view_set_selection_text_color (glView *view,
2704 glLabelObject *object;
2706 gl_debug (DEBUG_VIEW, "START");
2708 g_return_if_fail (view && GL_IS_VIEW (view));
2710 for (p = view->selected_object_list; p != NULL; p = p->next) {
2712 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2713 gl_label_object_set_text_color (object, text_color);
2717 gl_debug (DEBUG_VIEW, "END");
2720 /*****************************************************************************/
2721 /* Can fill properties be set for selection? */
2722 /*****************************************************************************/
2724 gl_view_can_selection_fill (glView *view)
2727 glLabelObject *object;
2729 gl_debug (DEBUG_VIEW, "");
2731 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2733 for (p = view->selected_object_list; p != NULL; p = p->next) {
2735 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2736 if (gl_label_object_can_fill (object)) {
2745 /*****************************************************************************/
2746 /* Set fill color for all selected objects. */
2747 /*****************************************************************************/
2749 gl_view_set_selection_fill_color (glView *view,
2753 glLabelObject *object;
2755 gl_debug (DEBUG_VIEW, "START");
2757 g_return_if_fail (view && GL_IS_VIEW (view));
2759 for (p = view->selected_object_list; p != NULL; p = p->next) {
2761 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2762 gl_label_object_set_fill_color (object, fill_color);
2766 gl_debug (DEBUG_VIEW, "END");
2769 /*****************************************************************************/
2770 /* Can line color properties be set for selection? */
2771 /*****************************************************************************/
2773 gl_view_can_selection_line_color (glView *view)
2776 glLabelObject *object;
2778 gl_debug (DEBUG_VIEW, "");
2780 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2782 for (p = view->selected_object_list; p != NULL; p = p->next) {
2784 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2785 if (gl_label_object_can_line_color (object)) {
2794 /*****************************************************************************/
2795 /* Set line color for all selected objects. */
2796 /*****************************************************************************/
2798 gl_view_set_selection_line_color (glView *view,
2802 glLabelObject *object;
2804 gl_debug (DEBUG_VIEW, "START");
2806 g_return_if_fail (view && GL_IS_VIEW (view));
2808 for (p = view->selected_object_list; p != NULL; p = p->next) {
2810 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2811 gl_label_object_set_line_color (object, line_color);
2815 gl_debug (DEBUG_VIEW, "END");
2818 /*****************************************************************************/
2819 /* Can line width properties be set for selection? */
2820 /*****************************************************************************/
2822 gl_view_can_selection_line_width (glView *view)
2825 glLabelObject *object;
2827 gl_debug (DEBUG_VIEW, "");
2829 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2831 for (p = view->selected_object_list; p != NULL; p = p->next) {
2833 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2834 if (gl_label_object_can_line_width (object)) {
2843 /*****************************************************************************/
2844 /* Set line width for all selected objects. */
2845 /*****************************************************************************/
2847 gl_view_set_selection_line_width (glView *view,
2851 glLabelObject *object;
2853 gl_debug (DEBUG_VIEW, "START");
2855 g_return_if_fail (view && GL_IS_VIEW (view));
2857 for (p = view->selected_object_list; p != NULL; p = p->next) {
2859 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2860 gl_label_object_set_line_width (object, line_width);
2864 gl_debug (DEBUG_VIEW, "END");
2867 /*****************************************************************************/
2868 /* "Cut" selected items and place in clipboard selections. */
2869 /*****************************************************************************/
2871 gl_view_cut (glView *view)
2873 gl_debug (DEBUG_VIEW, "START");
2875 g_return_if_fail (view && GL_IS_VIEW (view));
2877 gl_view_copy (view);
2878 gl_view_delete_selection (view);
2880 gl_debug (DEBUG_VIEW, "END");
2883 /*****************************************************************************/
2884 /* "Copy" selected items to clipboard selections. */
2885 /*****************************************************************************/
2887 gl_view_copy (glView *view)
2890 glViewObject *view_object;
2891 glLabelObject *object;
2892 glTemplate *template;
2893 gboolean rotate_flag;
2895 gl_debug (DEBUG_VIEW, "START");
2897 g_return_if_fail (view && GL_IS_VIEW (view));
2899 if (view->selected_object_list) {
2901 if ( view->selection_data ) {
2902 g_object_unref (view->selection_data);
2904 template = gl_label_get_template (view->label);
2905 rotate_flag = gl_label_get_rotate_flag (view->label);
2906 view->selection_data = GL_LABEL(gl_label_new ());
2907 gl_label_set_template (view->selection_data, template);
2908 gl_label_set_rotate_flag (view->selection_data, rotate_flag);
2909 gl_template_free (&template);
2911 for (p = view->selected_object_list; p != NULL; p = p->next) {
2913 view_object = GL_VIEW_OBJECT (p->data);
2914 object = gl_view_object_get_object (view_object);
2916 gl_label_object_dup (object, view->selection_data);
2920 gtk_selection_owner_set (view->invisible,
2921 clipboard_atom, GDK_CURRENT_TIME);
2922 view->have_selection = TRUE;
2926 gl_debug (DEBUG_VIEW, "END");
2929 /*****************************************************************************/
2930 /* "Paste" from private clipboard selection. */
2931 /*****************************************************************************/
2933 gl_view_paste (glView *view)
2935 gl_debug (DEBUG_VIEW, "START");
2937 g_return_if_fail (view && GL_IS_VIEW (view));
2939 gtk_selection_convert (GTK_WIDGET (view->invisible),
2940 clipboard_atom, GDK_SELECTION_TYPE_STRING,
2943 gl_debug (DEBUG_VIEW, "END");
2946 /*****************************************************************************/
2947 /* Zoom in one "notch" */
2948 /*****************************************************************************/
2950 gl_view_zoom_in (glView *view)
2953 gdouble dist, dist_min;
2955 gl_debug (DEBUG_VIEW, "START");
2957 g_return_if_fail (view && GL_IS_VIEW (view));
2959 /* Find index of current scale (or best match) */
2960 i_min = 1; /* start with 2nd largest scale */
2961 dist_min = fabs (scales[1] - view->scale);
2962 for (i = 2; i < N_SCALES; i++) {
2963 dist = fabs (scales[i] - view->scale);
2964 if (dist < dist_min) {
2970 /* zoom in one "notch" */
2971 i = MAX (0, i_min - 1);
2972 gl_view_set_zoom (view, scales[i] / HOME_SCALE);
2974 gl_debug (DEBUG_VIEW, "END");
2977 /*****************************************************************************/
2978 /* Zoom out one "notch" */
2979 /*****************************************************************************/
2981 gl_view_zoom_out (glView *view)
2984 gdouble dist, dist_min;
2986 gl_debug (DEBUG_VIEW, "START");
2988 g_return_if_fail (view && GL_IS_VIEW (view));
2990 /* Find index of current scale (or best match) */
2991 i_min = 0; /* start with largest scale */
2992 dist_min = fabs (scales[0] - view->scale);
2993 for (i = 1; i < N_SCALES; i++) {
2994 dist = fabs (scales[i] - view->scale);
2995 if (dist < dist_min) {
3001 /* zoom out one "notch" */
3002 if (i_min >= N_SCALES)
3007 gl_view_set_zoom (view, scales[i] / HOME_SCALE);
3009 gl_debug (DEBUG_VIEW, "END");
3012 /*****************************************************************************/
3013 /* Set current zoom factor to explicit value. */
3014 /*****************************************************************************/
3016 gl_view_set_zoom (glView *view,
3019 gl_debug (DEBUG_VIEW, "START");
3021 g_return_if_fail (view && GL_IS_VIEW (view));
3022 g_return_if_fail (scale > 0.0);
3024 view->scale = scale * HOME_SCALE;
3025 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
3026 scale * HOME_SCALE);
3028 g_signal_emit (G_OBJECT(view), signals[ZOOM_CHANGED], 0, scale);
3030 gl_debug (DEBUG_VIEW, "END");
3033 /*****************************************************************************/
3034 /* Get current zoom factor. */
3035 /*****************************************************************************/
3037 gl_view_get_zoom (glView *view)
3039 gl_debug (DEBUG_VIEW, "");
3041 g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
3043 return view->scale / HOME_SCALE;
3046 /*****************************************************************************/
3047 /* Is this the maximum zoom level. */
3048 /*****************************************************************************/
3050 gl_view_is_zoom_max (glView *view)
3052 gl_debug (DEBUG_VIEW, "");
3054 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
3056 return view->scale >= scales[0];
3059 /*****************************************************************************/
3060 /* Is this the minimum zoom level. */
3061 /*****************************************************************************/
3063 gl_view_is_zoom_min (glView *view)
3065 gl_debug (DEBUG_VIEW, "");
3067 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3069 return view->scale <= scales[N_SCALES-1];
3072 /*****************************************************************************/
3073 /* Launch merge properties dialog. */
3074 /*****************************************************************************/
3076 gl_view_edit_merge_props (glView *view)
3078 gl_debug (DEBUG_VIEW, "");
3080 g_return_if_fail (view && GL_IS_VIEW (view));
3082 if (view->merge_props_dialog != NULL) {
3083 gtk_widget_show_all (view->merge_props_dialog);
3084 gtk_window_present (GTK_WINDOW(view->merge_props_dialog));
3088 view->merge_props_dialog = gl_merge_properties_dialog_new (view);
3089 gtk_widget_show_all (view->merge_props_dialog);
3091 g_signal_connect (G_OBJECT(view->merge_props_dialog), "destroy",
3092 G_CALLBACK (gtk_widget_destroyed),
3093 &view->merge_props_dialog);
3096 /*---------------------------------------------------------------------------*/
3097 /* PRIVATE. Canvas event handler. */
3098 /*---------------------------------------------------------------------------*/
3100 canvas_event (GnomeCanvas *canvas,
3106 gl_debug (DEBUG_VIEW, "");
3108 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3110 /* emit pointer signals regardless of state */
3111 switch (event->type) {
3112 case GDK_MOTION_NOTIFY:
3113 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
3114 gnome_canvas_window_to_world (canvas,
3116 event->motion.y, &x, &y);
3117 g_signal_emit (G_OBJECT(view), signals[POINTER_MOVED], 0, x, y);
3118 break; /* fall through */
3120 case GDK_LEAVE_NOTIFY:
3121 gl_debug (DEBUG_VIEW, "LEAVEW_NOTIFY");
3122 g_signal_emit (G_OBJECT(view), signals[POINTER_EXIT], 0);
3123 break; /* fall through */
3126 break; /* fall through */
3130 switch (view->state) {
3132 case GL_VIEW_STATE_ARROW:
3133 return canvas_event_arrow_mode (canvas, event, view);
3135 case GL_VIEW_STATE_OBJECT_CREATE:
3136 switch (view->create_type) {
3137 case GL_LABEL_OBJECT_BOX:
3138 return gl_view_box_create_event_handler (canvas,
3142 case GL_LABEL_OBJECT_ELLIPSE:
3143 return gl_view_ellipse_create_event_handler (canvas,
3147 case GL_LABEL_OBJECT_LINE:
3148 return gl_view_line_create_event_handler (canvas,
3152 case GL_LABEL_OBJECT_IMAGE:
3153 return gl_view_image_create_event_handler (canvas,
3157 case GL_LABEL_OBJECT_TEXT:
3158 return gl_view_text_create_event_handler (canvas,
3162 case GL_LABEL_OBJECT_BARCODE:
3163 return gl_view_barcode_create_event_handler (canvas,
3168 /*Should not happen!*/
3169 g_warning ("Invalid label object type.");
3174 g_warning ("Invalid view state."); /*Should not happen!*/
3180 /*---------------------------------------------------------------------------*/
3181 /* PRIVATE. Canvas event handler (arrow mode) */
3182 /*---------------------------------------------------------------------------*/
3184 canvas_event_arrow_mode (GnomeCanvas *canvas,
3188 static gdouble x0, y0;
3189 static gboolean dragging = FALSE;
3190 static GnomeCanvasItem *item;
3191 gdouble x, y, x1, y1, x2, y2;
3192 GnomeCanvasGroup *group;
3195 gl_debug (DEBUG_VIEW, "");
3197 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3199 switch (event->type) {
3201 case GDK_BUTTON_PRESS:
3202 gl_debug (DEBUG_VIEW, "BUTTON_PRESS");
3203 switch (event->button.button) {
3205 gnome_canvas_window_to_world (canvas,
3207 event->button.y, &x, &y);
3209 if (!object_at (view, x, y)) {
3210 if (!(event->button.state & GDK_CONTROL_MASK)) {
3211 gl_view_unselect_all (view);
3215 gnome_canvas_item_grab (canvas->root,
3216 GDK_POINTER_MOTION_MASK |
3217 GDK_BUTTON_RELEASE_MASK |
3218 GDK_BUTTON_PRESS_MASK,
3219 NULL, event->button.time);
3221 gnome_canvas_root (GNOME_CANVAS
3224 gnome_canvas_item_new (group,
3225 gnome_canvas_rect_get_type (),
3229 "outline_color_rgba",
3240 gnome_canvas_window_to_world (canvas,
3242 event->button.y, &x, &y);
3244 if (!object_at (view, x, y)) {
3245 /* bring up apropriate menu for selection. */
3246 gl_view_popup_menu (view, event);
3253 case GDK_BUTTON_RELEASE:
3254 gl_debug (DEBUG_VIEW, "BUTTON_RELEASE");
3255 switch (event->button.button) {
3259 gnome_canvas_item_ungrab (canvas->root,
3260 event->button.time);
3261 gnome_canvas_window_to_world (canvas,
3269 gl_view_select_region (view, x1, y1, x2, y2);
3270 gtk_object_destroy (GTK_OBJECT (item));
3279 case GDK_MOTION_NOTIFY:
3280 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
3281 gnome_canvas_window_to_world (canvas,
3283 event->motion.y, &x, &y);
3284 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
3285 gnome_canvas_item_set (item,
3289 "y2", MAX (y, y0), NULL);
3296 gl_debug (DEBUG_VIEW, "KEY_PRESS");
3298 switch (event->key.keyval) {
3301 gl_view_move_selection (view,
3302 -1.0 / (view->scale), 0.0);
3306 gl_view_move_selection (view,
3307 0.0, -1.0 / (view->scale));
3311 gl_view_move_selection (view,
3312 1.0 / (view->scale), 0.0);
3316 gl_view_move_selection (view,
3317 0.0, 1.0 / (view->scale));
3321 gl_view_delete_selection (view);
3322 cursor = gdk_cursor_new (GDK_LEFT_PTR);
3323 gdk_window_set_cursor (view->canvas->window,
3325 gdk_cursor_unref (cursor);
3331 return TRUE; /* We handled this or we were dragging. */
3334 gl_debug (DEBUG_VIEW, "default");
3340 /*---------------------------------------------------------------------------*/
3341 /* PRIVATE. create menu for selections. */
3342 /*---------------------------------------------------------------------------*/
3344 construct_selection_menu (glView *view)
3346 GtkWidget *menu, *menuitem, *submenu;
3348 gl_debug (DEBUG_VIEW, "START");
3350 g_return_if_fail (view && GL_IS_VIEW (view));
3352 menu = gtk_menu_new ();
3354 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_PROPERTIES, NULL);
3355 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3356 gtk_widget_show (menuitem);
3357 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3358 G_CALLBACK (gl_view_edit_object_props), view);
3359 view->atomic_selection_items =
3360 g_list_prepend (view->atomic_selection_items, menuitem);
3363 * Separator -------------------------
3365 menuitem = gtk_menu_item_new ();
3366 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3367 gtk_widget_show (menuitem);
3372 menuitem = gtk_menu_item_new_with_mnemonic (_("_Order"));
3373 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3374 gtk_widget_show (menuitem);
3375 submenu = gtk_menu_new ();
3376 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3378 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ORDER_TOP, NULL);
3379 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3380 gtk_widget_show (menuitem);
3381 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3382 G_CALLBACK (gl_view_raise_selection), view);
3384 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ORDER_BOTTOM, NULL);
3385 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3386 gtk_widget_show (menuitem);
3387 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3388 G_CALLBACK (gl_view_lower_selection), view);
3391 * Submenu: Rotate/Flip
3393 menuitem = gtk_menu_item_new_with_mnemonic (_("_Rotate/Flip"));
3394 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3395 gtk_widget_show (menuitem);
3396 submenu = gtk_menu_new ();
3397 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3399 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ROTATE_LEFT, NULL);
3400 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3401 gtk_widget_show (menuitem);
3402 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3403 G_CALLBACK (gl_view_rotate_selection_left), view);
3405 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ROTATE_RIGHT, NULL);
3406 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3407 gtk_widget_show (menuitem);
3408 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3409 G_CALLBACK (gl_view_rotate_selection_right), view);
3411 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_FLIP_HORIZ, NULL);
3412 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3413 gtk_widget_show (menuitem);
3414 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3415 G_CALLBACK (gl_view_flip_selection_horiz), view);
3417 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_FLIP_VERT, NULL);
3418 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3419 gtk_widget_show (menuitem);
3420 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3421 G_CALLBACK (gl_view_flip_selection_vert), view);
3424 * Submenu: Align Horizontally
3426 menuitem = gtk_menu_item_new_with_mnemonic (_("Align _Horizontally"));
3427 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3428 gtk_widget_show (menuitem);
3429 submenu = gtk_menu_new ();
3430 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3432 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_LEFT, NULL);
3433 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3434 gtk_widget_show (menuitem);
3435 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3436 G_CALLBACK (gl_view_align_selection_left), view);
3437 view->multi_selection_items =
3438 g_list_prepend (view->multi_selection_items, menuitem);
3440 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_HCENTER, NULL);
3441 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3442 gtk_widget_show (menuitem);
3443 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3444 G_CALLBACK (gl_view_align_selection_hcenter), view);
3445 view->multi_selection_items =
3446 g_list_prepend (view->multi_selection_items, menuitem);
3448 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_RIGHT, NULL);
3449 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3450 gtk_widget_show (menuitem);
3451 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3452 G_CALLBACK (gl_view_align_selection_right), view);
3453 view->multi_selection_items =
3454 g_list_prepend (view->multi_selection_items, menuitem);
3456 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_CENTER_HORIZ, NULL);
3457 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3458 gtk_widget_show (menuitem);
3459 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3460 G_CALLBACK (gl_view_center_selection_horiz), view);
3463 * Submenu: Align Vertically
3465 menuitem = gtk_menu_item_new_with_mnemonic (_("Align _Vertically"));
3466 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3467 gtk_widget_show (menuitem);
3468 submenu = gtk_menu_new ();
3469 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3471 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_TOP, NULL);
3472 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3473 gtk_widget_show (menuitem);
3474 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3475 G_CALLBACK (gl_view_align_selection_top), view);
3476 view->multi_selection_items =
3477 g_list_prepend (view->multi_selection_items, menuitem);
3479 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_VCENTER, NULL);
3480 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3481 gtk_widget_show (menuitem);
3482 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3483 G_CALLBACK (gl_view_align_selection_vcenter), view);
3484 view->multi_selection_items =
3485 g_list_prepend (view->multi_selection_items, menuitem);
3487 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_BOTTOM, NULL);
3488 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3489 gtk_widget_show (menuitem);
3490 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3491 G_CALLBACK (gl_view_align_selection_bottom), view);
3492 view->multi_selection_items =
3493 g_list_prepend (view->multi_selection_items, menuitem);
3495 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_CENTER_VERT, NULL);
3496 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3497 gtk_widget_show (menuitem);
3498 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3499 G_CALLBACK (gl_view_center_selection_vert), view);
3502 * Separator -------------------------
3504 menuitem = gtk_menu_item_new ();
3505 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3506 gtk_widget_show (menuitem);
3508 menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_CUT, NULL);
3509 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3510 gtk_widget_show (menuitem);
3511 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3512 G_CALLBACK (gl_view_cut), view);
3514 menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_COPY, NULL);
3515 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3516 gtk_widget_show (menuitem);
3517 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3518 G_CALLBACK (gl_view_copy), view);
3520 menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_PASTE, NULL);
3521 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3522 gtk_widget_show (menuitem);
3523 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3524 G_CALLBACK (gl_view_paste), view);
3526 menuitem = gtk_menu_item_new_with_mnemonic (_("_Delete"));
3527 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3528 gtk_widget_show (menuitem);
3529 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3530 G_CALLBACK (gl_view_delete_selection), view);
3533 view->selection_menu = menu;
3535 gl_debug (DEBUG_VIEW, "END");
3538 /*---------------------------------------------------------------------------*/
3539 /* PRIVATE. create menu for empty selections. */
3540 /*---------------------------------------------------------------------------*/
3542 construct_empty_selection_menu (glView *view)
3544 GtkWidget *menu, *menuitem, *submenu;
3546 gl_debug (DEBUG_VIEW, "START");
3548 g_return_if_fail (view && GL_IS_VIEW (view));
3550 menu = gtk_menu_new ();
3552 menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_PASTE, NULL);
3553 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3554 gtk_widget_show (menuitem);
3555 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3556 G_CALLBACK (gl_view_paste), view);
3559 view->empty_selection_menu = menu;
3561 gl_debug (DEBUG_VIEW, "END");
3564 /****************************************************************************/
3566 /****************************************************************************/
3568 gl_view_popup_menu (glView *view,
3574 gl_debug (DEBUG_VIEW, "START");
3576 g_return_if_fail (view && GL_IS_VIEW (view));
3578 if (gl_view_is_selection_empty (view)) {
3580 if (view->empty_selection_menu != NULL) {
3581 gtk_menu_popup (GTK_MENU (view->empty_selection_menu),
3582 NULL, NULL, NULL, NULL,
3583 event->button.button,
3584 event->button.time);
3589 for (p=view->atomic_selection_items; p!=NULL; p=p->next) {
3590 gtk_widget_set_sensitive (GTK_WIDGET(p->data),
3591 gl_view_is_selection_atomic(view));
3594 for (p=view->multi_selection_items; p!=NULL; p=p->next) {
3595 gtk_widget_set_sensitive (GTK_WIDGET(p->data),
3596 !gl_view_is_selection_atomic(view));
3599 if (view->selection_menu != NULL) {
3600 gtk_menu_popup (GTK_MENU (view->selection_menu),
3601 NULL, NULL, NULL, NULL,
3602 event->button.button,
3603 event->button.time);
3608 gl_debug (DEBUG_VIEW, "END");
3611 /*---------------------------------------------------------------------------*/
3612 /* PRIVATE. Handle "selection-clear" signal. */
3613 /*---------------------------------------------------------------------------*/
3615 selection_clear_cb (GtkWidget *widget,
3616 GdkEventSelection *event,
3619 glView *view = GL_VIEW (data);
3621 gl_debug (DEBUG_VIEW, "START");
3623 g_return_if_fail (view && GL_IS_VIEW (view));
3625 view->have_selection = FALSE;
3626 g_object_unref (view->selection_data);
3627 view->selection_data = NULL;
3629 gl_debug (DEBUG_VIEW, "END");
3632 /*---------------------------------------------------------------------------*/
3633 /* PRIVATE. Handle "selection-get" signal. */
3634 /*---------------------------------------------------------------------------*/
3636 selection_get_cb (GtkWidget *widget,
3637 GtkSelectionData *selection_data,
3642 glView *view = GL_VIEW (data);
3644 glXMLLabelStatus status;
3646 gl_debug (DEBUG_VIEW, "START");
3648 g_return_if_fail (view && GL_IS_VIEW (view));
3650 if (view->have_selection) {
3652 buffer = gl_xml_label_save_buffer (view->selection_data,
3654 gtk_selection_data_set (selection_data,
3655 GDK_SELECTION_TYPE_STRING, 8, buffer,
3660 gl_debug (DEBUG_VIEW, "END");
3663 /*---------------------------------------------------------------------------*/
3664 /* PRIVATE. Handle "selection-received" signal. (Result of Paste) */
3665 /*---------------------------------------------------------------------------*/
3667 selection_received_cb (GtkWidget *widget,
3668 GtkSelectionData *selection_data,
3672 glView *view = GL_VIEW (data);
3673 glLabel *label = NULL;
3674 glXMLLabelStatus status;
3676 glLabelObject *object, *newobject;
3677 glViewObject *view_object;
3679 gl_debug (DEBUG_VIEW, "START");
3681 g_return_if_fail (view && GL_IS_VIEW (view));
3683 if (selection_data->length < 0) {
3686 if (selection_data->type != GDK_SELECTION_TYPE_STRING) {
3690 gl_view_unselect_all (view);
3692 label = gl_xml_label_open_buffer (selection_data->data, &status);
3693 for (p = label->objects; p != NULL; p = p_next) {
3696 object = (glLabelObject *) p->data;
3697 newobject = gl_label_object_dup (object, view->label);
3699 gl_debug (DEBUG_VIEW, "object pasted");
3701 if (GL_IS_LABEL_BOX (newobject)) {
3702 view_object = gl_view_box_new (GL_LABEL_BOX(newobject),
3704 } else if (GL_IS_LABEL_ELLIPSE (newobject)) {
3705 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(newobject),
3707 } else if (GL_IS_LABEL_LINE (newobject)) {
3708 view_object = gl_view_line_new (GL_LABEL_LINE(newobject),
3710 } else if (GL_IS_LABEL_IMAGE (newobject)) {
3711 view_object = gl_view_image_new (GL_LABEL_IMAGE(newobject),
3713 } else if (GL_IS_LABEL_TEXT (newobject)) {
3714 view_object = gl_view_text_new (GL_LABEL_TEXT(newobject),
3716 } else if (GL_IS_LABEL_BARCODE (newobject)) {
3717 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(newobject),
3720 /* Should not happen! */
3722 g_warning ("Invalid label object type.");
3724 gl_view_select_object (view, view_object);
3726 g_object_unref (label);
3728 gl_debug (DEBUG_VIEW, "END");
3731 /****************************************************************************/
3732 /* Set default font family. */
3733 /****************************************************************************/
3735 gl_view_set_default_font_family (glView *view,
3736 const gchar *font_family)
3738 gl_debug (DEBUG_VIEW, "START");
3740 g_return_if_fail (view && GL_IS_VIEW (view));
3742 if (view->default_font_family) {
3743 g_free (view->default_font_family);
3745 view->default_font_family = g_strdup (font_family);
3747 gl_debug (DEBUG_VIEW, "END");
3751 /****************************************************************************/
3752 /* Set default font size. */
3753 /****************************************************************************/
3755 gl_view_set_default_font_size (glView *view,
3758 gl_debug (DEBUG_VIEW, "START");
3760 g_return_if_fail (view && GL_IS_VIEW (view));
3762 view->default_font_size = font_size;
3764 gl_debug (DEBUG_VIEW, "END");
3768 /****************************************************************************/
3769 /* Set default font weight. */
3770 /****************************************************************************/
3772 gl_view_set_default_font_weight (glView *view,
3773 GnomeFontWeight font_weight)
3775 gl_debug (DEBUG_VIEW, "START");
3777 g_return_if_fail (view && GL_IS_VIEW (view));
3779 view->default_font_weight = font_weight;
3781 gl_debug (DEBUG_VIEW, "END");
3785 /****************************************************************************/
3786 /* Set default font italic flag. */
3787 /****************************************************************************/
3789 gl_view_set_default_font_italic_flag (glView *view,
3790 gboolean font_italic_flag)
3792 gl_debug (DEBUG_VIEW, "START");
3794 g_return_if_fail (view && GL_IS_VIEW (view));
3796 view->default_font_italic_flag = font_italic_flag;
3798 gl_debug (DEBUG_VIEW, "END");
3802 /****************************************************************************/
3803 /* Set default text color. */
3804 /****************************************************************************/
3806 gl_view_set_default_text_color (glView *view,
3809 gl_debug (DEBUG_VIEW, "START");
3811 g_return_if_fail (view && GL_IS_VIEW (view));
3813 view->default_text_color = text_color;
3815 gl_debug (DEBUG_VIEW, "END");
3819 /****************************************************************************/
3820 /* Set default text alignment. */
3821 /****************************************************************************/
3823 gl_view_set_default_text_alignment (glView *view,
3824 GtkJustification text_alignment)
3826 gl_debug (DEBUG_VIEW, "START");
3828 g_return_if_fail (view && GL_IS_VIEW (view));
3830 view->default_text_alignment = text_alignment;
3831 gl_debug (DEBUG_VIEW, "END");
3835 /****************************************************************************/
3836 /* Set default line width. */
3837 /****************************************************************************/
3839 gl_view_set_default_line_width (glView *view,
3842 gl_debug (DEBUG_VIEW, "START");
3844 g_return_if_fail (view && GL_IS_VIEW (view));
3846 view->default_line_width = line_width;
3848 gl_debug (DEBUG_VIEW, "END");
3852 /****************************************************************************/
3853 /* Set default line color. */
3854 /****************************************************************************/
3856 gl_view_set_default_line_color (glView *view,
3859 gl_debug (DEBUG_VIEW, "START");
3861 g_return_if_fail (view && GL_IS_VIEW (view));
3863 view->default_line_color = line_color;
3865 gl_debug (DEBUG_VIEW, "END");
3869 /****************************************************************************/
3870 /* Set default fill color. */
3871 /****************************************************************************/
3873 gl_view_set_default_fill_color (glView *view,
3876 gl_debug (DEBUG_VIEW, "START");
3878 g_return_if_fail (view && GL_IS_VIEW (view));
3880 view->default_fill_color = fill_color;
3882 gl_debug (DEBUG_VIEW, "END");
3887 /****************************************************************************/
3888 /* Get default font family. */
3889 /****************************************************************************/
3891 gl_view_get_default_font_family (glView *view)
3893 gl_debug (DEBUG_VIEW, "START");
3895 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
3897 gl_debug (DEBUG_VIEW, "END");
3899 return g_strdup (view->default_font_family);
3903 /****************************************************************************/
3904 /* Get default font size. */
3905 /****************************************************************************/
3907 gl_view_get_default_font_size (glView *view)
3909 gl_debug (DEBUG_VIEW, "START");
3911 g_return_val_if_fail (view && GL_IS_VIEW (view), 12.0);
3913 gl_debug (DEBUG_VIEW, "END");
3915 return view->default_font_size;
3919 /****************************************************************************/
3920 /* Get default font weight. */
3921 /****************************************************************************/
3923 gl_view_get_default_font_weight (glView *view)
3925 gl_debug (DEBUG_VIEW, "START");
3927 g_return_val_if_fail (view && GL_IS_VIEW (view), GNOME_FONT_BOOK);
3929 gl_debug (DEBUG_VIEW, "END");
3931 return view->default_font_weight;
3935 /****************************************************************************/
3936 /* Get default font italic flag. */
3937 /****************************************************************************/
3939 gl_view_get_default_font_italic_flag (glView *view)
3941 gl_debug (DEBUG_VIEW, "START");
3943 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3945 gl_debug (DEBUG_VIEW, "END");
3947 return view->default_font_italic_flag;
3951 /****************************************************************************/
3952 /* Get default text color. */
3953 /****************************************************************************/
3955 gl_view_get_default_text_color (glView *view)
3957 gl_debug (DEBUG_VIEW, "START");
3959 g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
3961 gl_debug (DEBUG_VIEW, "END");
3963 return view->default_text_color;
3967 /****************************************************************************/
3968 /* Get default text alignment. */
3969 /****************************************************************************/
3971 gl_view_get_default_text_alignment (glView *view)
3973 gl_debug (DEBUG_VIEW, "START");
3975 g_return_val_if_fail (view && GL_IS_VIEW (view), GTK_JUSTIFY_LEFT);
3977 gl_debug (DEBUG_VIEW, "END");
3979 return view->default_text_alignment;
3983 /****************************************************************************/
3984 /* Get default line width. */
3985 /****************************************************************************/
3987 gl_view_get_default_line_width (glView *view)
3989 gl_debug (DEBUG_VIEW, "START");
3991 g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
3993 gl_debug (DEBUG_VIEW, "END");
3995 return view->default_line_width;
3999 /****************************************************************************/
4000 /* Get default line color. */
4001 /****************************************************************************/
4002 guint gl_view_get_default_line_color (glView *view)
4004 gl_debug (DEBUG_VIEW, "START");
4006 g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
4008 gl_debug (DEBUG_VIEW, "END");
4010 return view->default_line_color;
4014 /****************************************************************************/
4015 /* Get default fill color. */
4016 /****************************************************************************/
4017 guint gl_view_get_default_fill_color (glView *view)
4019 gl_debug (DEBUG_VIEW, "START");
4021 g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
4023 gl_debug (DEBUG_VIEW, "END");
4025 return view->default_fill_color;