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);
148 static void select_object_real (glView *view,
149 glViewObject *view_object);
150 static void unselect_object_real (glView *view,
151 glViewObject *view_object);
153 static gboolean object_at (glView *view,
154 gdouble x, gdouble y);
156 static gboolean is_item_member_of_group (glView *view,
157 GnomeCanvasItem *item,
158 GnomeCanvasItem *group);
160 static int canvas_event (GnomeCanvas *canvas,
163 static int canvas_event_arrow_mode (GnomeCanvas *canvas,
167 static void construct_selection_menu (glView *view);
169 static void construct_empty_selection_menu (glView *view);
171 static void selection_clear_cb (GtkWidget *widget,
172 GdkEventSelection *event,
175 static void selection_get_cb (GtkWidget *widget,
176 GtkSelectionData *selection_data,
181 static void selection_received_cb (GtkWidget *widget,
182 GtkSelectionData *selection_data,
186 /****************************************************************************/
187 /* Boilerplate Object stuff. */
188 /****************************************************************************/
190 gl_view_get_type (void)
192 static guint view_type = 0;
195 GTypeInfo view_info = {
196 sizeof (glViewClass),
199 (GClassInitFunc) gl_view_class_init,
204 (GInstanceInitFunc) gl_view_init,
208 g_type_register_static (gtk_vbox_get_type (),
209 "glView", &view_info, 0);
216 gl_view_class_init (glViewClass *class)
218 GObjectClass *object_class = (GObjectClass *) class;
220 gl_debug (DEBUG_VIEW, "START");
222 parent_class = g_type_class_peek_parent (class);
224 object_class->finalize = gl_view_finalize;
226 signals[SELECTION_CHANGED] =
227 g_signal_new ("selection_changed",
228 G_OBJECT_CLASS_TYPE (object_class),
230 G_STRUCT_OFFSET (glViewClass, selection_changed),
232 gl_marshal_VOID__VOID,
236 signals[ZOOM_CHANGED] =
237 g_signal_new ("zoom_changed",
238 G_OBJECT_CLASS_TYPE (object_class),
240 G_STRUCT_OFFSET (glViewClass, zoom_changed),
242 gl_marshal_VOID__DOUBLE,
246 signals[POINTER_MOVED] =
247 g_signal_new ("pointer_moved",
248 G_OBJECT_CLASS_TYPE (object_class),
250 G_STRUCT_OFFSET (glViewClass, pointer_moved),
252 gl_marshal_VOID__DOUBLE_DOUBLE,
254 2, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
256 signals[POINTER_EXIT] =
257 g_signal_new ("pointer_exit",
258 G_OBJECT_CLASS_TYPE (object_class),
260 G_STRUCT_OFFSET (glViewClass, pointer_exit),
262 gl_marshal_VOID__VOID,
266 signals[MODE_CHANGED] =
267 g_signal_new ("mode_changed",
268 G_OBJECT_CLASS_TYPE (object_class),
270 G_STRUCT_OFFSET (glViewClass, mode_changed),
272 gl_marshal_VOID__VOID,
276 gl_debug (DEBUG_VIEW, "END");
280 gl_view_init (glView *view)
282 gl_debug (DEBUG_VIEW, "START");
286 view->grid_spacing = 9;
288 view->default_font_family = NULL;
290 gl_debug (DEBUG_VIEW, "END");
294 gl_view_finalize (GObject *object)
298 gl_debug (DEBUG_VIEW, "START");
300 g_return_if_fail (object != NULL);
301 g_return_if_fail (GL_IS_VIEW (object));
303 view = GL_VIEW (object);
305 G_OBJECT_CLASS (parent_class)->finalize (object);
307 gl_debug (DEBUG_VIEW, "END");
310 /****************************************************************************/
311 /* NEW view object. */
312 /****************************************************************************/
314 gl_view_new (glLabel *label)
318 gl_debug (DEBUG_VIEW, "START");
320 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
322 view = g_object_new (gl_view_get_type (), NULL);
325 gl_view_construct (view);
327 gl_debug (DEBUG_VIEW, "END");
329 return GTK_WIDGET (view);
332 /*---------------------------------------------------------------------------*/
333 /* PRIVATE. Construct composite widget. */
334 /*---------------------------------------------------------------------------*/
336 gl_view_construct (glView *view)
338 GtkWidget *wvbox, *wscroll;
340 gl_debug (DEBUG_VIEW, "START");
342 g_return_if_fail (GL_IS_VIEW (view));
344 wvbox = GTK_WIDGET (view);
346 view->state = GL_VIEW_STATE_ARROW;
347 view->object_list = NULL;
349 gl_view_construct_canvas (view);
350 wscroll = gtk_scrolled_window_new (NULL, NULL);
351 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (wscroll),
352 GTK_POLICY_AUTOMATIC,
353 GTK_POLICY_AUTOMATIC);
354 gtk_box_pack_start (GTK_BOX (wvbox), wscroll, TRUE, TRUE, 0);
355 gtk_container_add (GTK_CONTAINER (wscroll), view->canvas);
357 gl_view_construct_selection (view);
359 construct_selection_menu (view);
360 construct_empty_selection_menu (view);
362 gl_view_set_default_font_family (view, gl_prefs->default_font_family);
363 gl_view_set_default_font_size (view, gl_prefs->default_font_size);
364 gl_view_set_default_font_weight (view, gl_prefs->default_font_weight);
365 gl_view_set_default_font_italic_flag (view, gl_prefs->default_font_italic_flag);
366 gl_view_set_default_text_color (view, gl_prefs->default_text_color);
367 gl_view_set_default_text_alignment (view, gl_prefs->default_text_alignment);
368 gl_view_set_default_line_width (view, gl_prefs->default_line_width);
369 gl_view_set_default_line_color (view, gl_prefs->default_line_color);
370 gl_view_set_default_fill_color (view, gl_prefs->default_fill_color);
372 gl_debug (DEBUG_VIEW, "END");
375 /*---------------------------------------------------------------------------*/
376 /* PRIVATE. Create canvas w/ a background in the shape of the label/card. */
377 /*---------------------------------------------------------------------------*/
379 gl_view_construct_canvas (glView *view)
383 gdouble label_width, label_height;
386 gl_debug (DEBUG_VIEW, "START");
388 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
389 g_return_val_if_fail (view->label && GL_IS_LABEL (view->label), NULL);
393 gtk_widget_push_colormap (gdk_rgb_get_colormap ());
394 view->canvas = gnome_canvas_new_aa ();
395 gtk_widget_pop_colormap ();
397 bg_color = gl_color_to_gdk_color (BG_COLOR);
398 gtk_widget_modify_bg (GTK_WIDGET(view->canvas), GTK_STATE_NORMAL, bg_color);
401 gl_label_get_size (label, &label_width, &label_height);
402 gl_debug (DEBUG_VIEW, "Label size: w=%lf, h=%lf",
403 label_width, label_height);
405 scale = get_apropriate_scale (label_width, label_height);
406 gl_debug (DEBUG_VIEW, "scale =%lf", scale);
408 gl_debug (DEBUG_VIEW, "Canvas size: w=%lf, h=%lf",
409 scale * label_width + 40,
410 scale * label_height + 40);
411 gtk_widget_set_size_request (GTK_WIDGET(view->canvas),
412 scale * label_width + 40,
413 scale * label_height + 40);
414 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
418 gnome_canvas_set_scroll_region (GNOME_CANVAS (view->canvas),
419 0.0, 0.0, label_width, label_height);
423 g_signal_connect (G_OBJECT (view->canvas), "event",
424 G_CALLBACK (canvas_event), view);
426 gl_debug (DEBUG_VIEW, "END");
431 /*---------------------------------------------------------------------------*/
432 /* PRIVATE. Create clipboard selection targets. */
433 /*---------------------------------------------------------------------------*/
435 gl_view_construct_selection (glView *view)
437 gl_debug (DEBUG_VIEW, "START");
439 g_return_if_fail (GL_IS_VIEW (view));
441 view->have_selection = FALSE;
442 view->selection_data = NULL;
443 view->invisible = gtk_invisible_new ();
445 view->selected_object_list = NULL;
447 if (!clipboard_atom) {
448 clipboard_atom = gdk_atom_intern ("GLABELS_CLIPBOARD", FALSE);
451 gtk_selection_add_target (view->invisible,
452 clipboard_atom, GDK_SELECTION_TYPE_STRING, 1);
454 g_signal_connect (G_OBJECT (view->invisible),
455 "selection_clear_event",
456 G_CALLBACK (selection_clear_cb), view);
458 g_signal_connect (G_OBJECT (view->invisible), "selection_get",
459 G_CALLBACK (selection_get_cb), view);
461 g_signal_connect (G_OBJECT (view->invisible),
462 "selection_received",
463 G_CALLBACK (selection_received_cb), view);
465 gl_debug (DEBUG_VIEW, "END");
468 /*---------------------------------------------------------------------------*/
469 /* PRIVATE. Determine an apropriate scale for given label & screen size */
470 /*---------------------------------------------------------------------------*/
472 get_apropriate_scale (gdouble w, gdouble h)
474 gdouble w_screen, h_screen;
478 gl_debug (DEBUG_VIEW, "");
480 w_screen = (gdouble) gdk_screen_width ();
481 h_screen = (gdouble) gdk_screen_height ();
483 for (i = 0; i < N_SCALES; i++) {
485 if (k <= HOME_SCALE) {
486 if ((k * w < (w_screen - 256))
487 && (k * h < (h_screen - 256)))
495 /*---------------------------------------------------------------------------*/
496 /* PRIVATE. Create, draw and order layers. */
497 /*---------------------------------------------------------------------------*/
499 draw_layers (glView *view)
501 g_return_if_fail (view && GL_IS_VIEW (view));
502 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
504 draw_bg_fg_layers (view);
505 draw_grid_layer (view);
506 draw_markup_layer (view);
507 draw_highlight_layer (view); /* Must be done before label layer */
508 draw_label_layer (view);
510 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->fg_group));
511 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->highlight_group));
513 g_signal_connect (G_OBJECT (view->label), "size_changed",
514 G_CALLBACK (label_resized_cb), view);
517 /*---------------------------------------------------------------------------*/
518 /* PRIVATE. Handle label resize event. . */
519 /*---------------------------------------------------------------------------*/
521 label_resized_cb (glLabel *label,
524 g_return_if_fail (label && GL_IS_LABEL (label));
525 g_return_if_fail (view && GL_IS_VIEW (view));
527 gtk_object_destroy (GTK_OBJECT (view->bg_group));
528 gtk_object_destroy (GTK_OBJECT (view->grid_group));
529 gtk_object_destroy (GTK_OBJECT (view->markup_group));
530 gtk_object_destroy (GTK_OBJECT (view->fg_group));
532 draw_bg_fg_layers (view);
533 draw_grid_layer (view);
534 draw_markup_layer (view);
536 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->label_group));
537 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->fg_group));
538 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->highlight_group));
541 /*---------------------------------------------------------------------------*/
542 /* PRIVATE. Draw label layer. */
543 /*---------------------------------------------------------------------------*/
545 draw_label_layer (glView *view)
547 GnomeCanvasGroup *group;
550 glLabelObject *object;
551 glViewObject *view_object;
553 g_return_if_fail (view && GL_IS_VIEW (view));
554 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
556 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
557 view->label_group = GNOME_CANVAS_GROUP(
558 gnome_canvas_item_new (group,
559 gnome_canvas_group_get_type (),
566 for (p_obj = label->objects; p_obj != NULL; p_obj = p_obj->next) {
567 object = (glLabelObject *) p_obj->data;
569 if (GL_IS_LABEL_BOX (object)) {
570 view_object = gl_view_box_new (GL_LABEL_BOX(object),
572 } else if (GL_IS_LABEL_ELLIPSE (object)) {
573 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object),
575 } else if (GL_IS_LABEL_LINE (object)) {
576 view_object = gl_view_line_new (GL_LABEL_LINE(object),
578 } else if (GL_IS_LABEL_IMAGE (object)) {
579 view_object = gl_view_image_new (GL_LABEL_IMAGE(object),
581 } else if (GL_IS_LABEL_TEXT (object)) {
582 view_object = gl_view_text_new (GL_LABEL_TEXT(object),
584 } else if (GL_IS_LABEL_BARCODE (object)) {
585 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(object),
588 /* Should not happen! */
590 g_warning ("Invalid label object type.");
595 /*---------------------------------------------------------------------------*/
596 /* PRIVATE. Create highlight layer. */
597 /*---------------------------------------------------------------------------*/
599 draw_highlight_layer (glView *view)
601 GnomeCanvasGroup *group;
603 g_return_if_fail (view && GL_IS_VIEW (view));
605 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
606 view->highlight_group = GNOME_CANVAS_GROUP(
607 gnome_canvas_item_new (group,
608 gnome_canvas_group_get_type (),
614 /*---------------------------------------------------------------------------*/
615 /* PRIVATE. Draw background and foreground outlines. */
616 /*---------------------------------------------------------------------------*/
618 draw_bg_fg_layers (glView *view)
621 glTemplate *template;
622 GnomeCanvasGroup *group;
624 g_return_if_fail (view && GL_IS_VIEW (view));
625 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
627 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
628 view->bg_group = GNOME_CANVAS_GROUP(
629 gnome_canvas_item_new (group,
630 gnome_canvas_group_get_type (),
634 view->fg_group = GNOME_CANVAS_GROUP(
635 gnome_canvas_item_new (group,
636 gnome_canvas_group_get_type (),
642 template = gl_label_get_template (label);
644 switch (template->label.style) {
646 case GL_TEMPLATE_STYLE_RECT:
647 if (template->label.rect.r == 0.0) {
648 /* Square corners. */
649 draw_bg_fg_rect (view);
651 /* Rounded corners. */
652 draw_bg_fg_rounded_rect (view);
656 case GL_TEMPLATE_STYLE_ROUND:
657 draw_bg_fg_round (view);
660 case GL_TEMPLATE_STYLE_CD:
661 if ((template->label.cd.w == 0.0) && (template->label.cd.h == 0.0) ) {
662 draw_bg_fg_cd (view);
664 draw_bg_fg_cd_bc (view);
669 g_warning ("Unknown template label style");
674 /*---------------------------------------------------------------------------*/
675 /* PRIVATE. Draw simple recangular background. */
676 /*---------------------------------------------------------------------------*/
678 draw_bg_fg_rect (glView *view)
681 glTemplate *template;
683 GnomeCanvasItem *item;
685 gl_debug (DEBUG_VIEW, "START");
687 g_return_if_fail (view && GL_IS_VIEW (view));
688 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
692 gl_label_get_size (label, &w, &h);
693 template = gl_label_get_template (label);
696 item = gnome_canvas_item_new (view->bg_group,
697 gnome_canvas_rect_get_type (),
702 "fill_color_rgba", PAPER_COLOR,
706 item = gnome_canvas_item_new (view->fg_group,
707 gnome_canvas_rect_get_type (),
713 "outline_color_rgba", OUTLINE_COLOR,
716 gl_debug (DEBUG_VIEW, "END");
719 /*---------------------------------------------------------------------------*/
720 /* PRIVATE. Draw rounded recangular background. */
721 /*---------------------------------------------------------------------------*/
723 draw_bg_fg_rounded_rect (glView *view)
726 GnomeCanvasPoints *points;
727 gint i_coords, i_theta;
728 glTemplate *template;
730 GnomeCanvasItem *item;
732 gl_debug (DEBUG_VIEW, "START");
734 g_return_if_fail (view && GL_IS_VIEW (view));
735 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
739 gl_label_get_size (label, &w, &h);
740 template = gl_label_get_template (label);
741 r = template->label.rect.r;
743 points = gnome_canvas_points_new (4 * (1 + 90 / ARC_COURSE));
745 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
746 points->coords[i_coords++] =
747 r - r * sin (i_theta * G_PI / 180.0);
748 points->coords[i_coords++] =
749 r - r * cos (i_theta * G_PI / 180.0);
751 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
752 points->coords[i_coords++] =
753 r - r * cos (i_theta * G_PI / 180.0);
754 points->coords[i_coords++] =
755 (h - r) + r * sin (i_theta * G_PI / 180.0);
757 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
758 points->coords[i_coords++] =
759 (w - r) + r * sin (i_theta * G_PI / 180.0);
760 points->coords[i_coords++] =
761 (h - r) + r * cos (i_theta * G_PI / 180.0);
763 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
764 points->coords[i_coords++] =
765 (w - r) + r * cos (i_theta * G_PI / 180.0);
766 points->coords[i_coords++] =
767 r - r * sin (i_theta * G_PI / 180.0);
771 item = gnome_canvas_item_new (view->bg_group,
772 gnome_canvas_polygon_get_type (),
774 "fill_color_rgba", PAPER_COLOR,
778 item = gnome_canvas_item_new (view->fg_group,
779 gnome_canvas_polygon_get_type (),
782 "outline_color_rgba", OUTLINE_COLOR,
785 gnome_canvas_points_free (points);
787 gl_debug (DEBUG_VIEW, "END");
790 /*---------------------------------------------------------------------------*/
791 /* PRIVATE. Draw round background. */
792 /*---------------------------------------------------------------------------*/
794 draw_bg_fg_round (glView *view)
797 glTemplate *template;
799 GnomeCanvasItem *item;
801 gl_debug (DEBUG_VIEW, "START");
803 g_return_if_fail (view && GL_IS_VIEW (view));
804 g_return_if_fail (view->label && GL_IS_LABEL(view->label));
807 template = gl_label_get_template (label);
809 r = template->label.round.r;
812 item = gnome_canvas_item_new (view->bg_group,
813 gnome_canvas_ellipse_get_type (),
818 "fill_color_rgba", PAPER_COLOR,
822 item = gnome_canvas_item_new (view->fg_group,
823 gnome_canvas_ellipse_get_type (),
829 "outline_color_rgba", OUTLINE_COLOR,
832 gl_debug (DEBUG_VIEW, "END");
835 /*---------------------------------------------------------------------------*/
836 /* PRIVATE. Draw CD style background, circular w/ concentric hole. */
837 /*---------------------------------------------------------------------------*/
839 draw_bg_fg_cd (glView *view)
842 glTemplate *template;
844 GnomeCanvasItem *item;
846 gl_debug (DEBUG_VIEW, "START");
848 g_return_if_fail (view && GL_IS_VIEW (view));
849 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
852 template = gl_label_get_template (label);
854 r1 = template->label.cd.r1;
855 r2 = template->label.cd.r2;
859 item = gnome_canvas_item_new (view->bg_group,
860 gnome_canvas_ellipse_get_type (),
865 "fill_color_rgba", PAPER_COLOR,
868 item = gnome_canvas_item_new (view->bg_group,
869 gnome_canvas_ellipse_get_type (),
874 "fill_color_rgba", GRID_COLOR,
879 item = gnome_canvas_item_new (view->fg_group,
880 gnome_canvas_ellipse_get_type (),
886 "outline_color_rgba", OUTLINE_COLOR,
889 item = gnome_canvas_item_new (view->fg_group,
890 gnome_canvas_ellipse_get_type (),
896 "outline_color_rgba", OUTLINE_COLOR,
899 gl_debug (DEBUG_VIEW, "END");
902 /*---------------------------------------------------------------------------*/
903 /* PRIVATE. Draw Business Card CD style background, CD w/ chopped ends. */
904 /*---------------------------------------------------------------------------*/
906 draw_bg_fg_cd_bc (glView *view)
909 glTemplate *template;
910 GnomeCanvasPoints *points;
911 gint i_coords, i_theta;
912 gdouble theta1, theta2;
913 gdouble x0, y0, w, h, r1, r2;
914 GnomeCanvasItem *item;
916 gl_debug (DEBUG_VIEW, "START");
918 g_return_if_fail (view && GL_IS_VIEW (view));
919 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
923 template = gl_label_get_template (label);
924 gl_label_get_size (label, &w, &h);
928 r1 = template->label.cd.r1;
929 r2 = template->label.cd.r2;
931 theta1 = (180.0/G_PI) * acos (w / (2.0*r1));
932 theta2 = (180.0/G_PI) * asin (h / (2.0*r1));
934 points = gnome_canvas_points_new (360/ARC_FINE + 1);
937 points->coords[i_coords++] = x0 + r1 * cos (theta1 * G_PI / 180.0);
938 points->coords[i_coords++] = y0 + r1 * sin (theta1 * G_PI / 180.0);
940 for ( i_theta = theta1 + ARC_FINE; i_theta < theta2; i_theta +=ARC_FINE ) {
941 points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
942 points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
945 points->coords[i_coords++] = x0 + r1 * cos (theta2 * G_PI / 180.0);
946 points->coords[i_coords++] = y0 + r1 * sin (theta2 * G_PI / 180.0);
949 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
950 points->coords[i_coords++] = x0 + r1 * cos ((180-theta2) * G_PI / 180.0);
951 points->coords[i_coords++] = y0 + r1 * sin ((180-theta2) * G_PI / 180.0);
954 for ( i_theta = 180-theta2+ARC_FINE; i_theta < (180-theta1); i_theta +=ARC_FINE ) {
955 points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
956 points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
959 points->coords[i_coords++] = x0 + r1 * cos ((180-theta1) * G_PI / 180.0);
960 points->coords[i_coords++] = y0 + r1 * sin ((180-theta1) * G_PI / 180.0);
962 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
963 points->coords[i_coords++] = x0 + r1 * cos ((180+theta1) * G_PI / 180.0);
964 points->coords[i_coords++] = y0 + r1 * sin ((180+theta1) * G_PI / 180.0);
967 for ( i_theta = 180+theta1+ARC_FINE; i_theta < (180+theta2); i_theta +=ARC_FINE ) {
968 points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
969 points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
972 points->coords[i_coords++] = x0 + r1 * cos ((180+theta2) * G_PI / 180.0);
973 points->coords[i_coords++] = y0 + r1 * sin ((180+theta2) * G_PI / 180.0);
975 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
976 points->coords[i_coords++] = x0 + r1 * cos ((360-theta2) * G_PI / 180.0);
977 points->coords[i_coords++] = y0 + r1 * sin ((360-theta2) * G_PI / 180.0);
980 for ( i_theta = 360-theta2+ARC_FINE; i_theta < (360-theta1); i_theta +=ARC_FINE ) {
981 points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
982 points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
985 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
986 points->coords[i_coords++] = x0 + r1 * cos ((360-theta1) * G_PI / 180.0);
987 points->coords[i_coords++] = y0 + r1 * sin ((360-theta1) * G_PI / 180.0);
990 points->num_points = i_coords / 2;
994 item = gnome_canvas_item_new (view->bg_group,
995 gnome_canvas_polygon_get_type (),
997 "fill_color_rgba", PAPER_COLOR,
1000 item = gnome_canvas_item_new (view->bg_group,
1001 gnome_canvas_ellipse_get_type (),
1006 "fill_color_rgba", GRID_COLOR,
1011 item = gnome_canvas_item_new (view->fg_group,
1012 gnome_canvas_polygon_get_type (),
1015 "outline_color_rgba", OUTLINE_COLOR,
1018 item = gnome_canvas_item_new (view->fg_group,
1019 gnome_canvas_ellipse_get_type (),
1025 "outline_color_rgba", OUTLINE_COLOR,
1028 gnome_canvas_points_free (points);
1030 gl_debug (DEBUG_VIEW, "END");
1033 /*---------------------------------------------------------------------------*/
1034 /* PRIVATE. Draw grid lines. */
1035 /*---------------------------------------------------------------------------*/
1037 draw_grid_layer (glView *view)
1040 GnomeCanvasPoints *points;
1041 GnomeCanvasItem *item;
1042 GnomeCanvasGroup *group;
1044 gl_debug (DEBUG_VIEW, "START");
1046 g_return_if_fail (view && GL_IS_VIEW (view));
1047 g_return_if_fail (view->label && GL_IS_LABEL(view->label));
1049 gl_label_get_size (view->label, &w, &h);
1051 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
1052 view->grid_group = GNOME_CANVAS_GROUP(
1053 gnome_canvas_item_new (group,
1054 gnome_canvas_group_get_type (),
1058 points = gnome_canvas_points_new (2);
1060 points->coords[1] = 0.0;
1061 points->coords[3] = h;
1062 for ( x=0.0; x < w; x += view->grid_spacing ) {
1063 points->coords[0] = points->coords[2] = x;
1064 item = gnome_canvas_item_new (view->grid_group,
1065 gnome_canvas_line_get_type (),
1068 "fill_color_rgba", GRID_COLOR,
1071 points->coords[0] = points->coords[2] = w;
1072 item = gnome_canvas_item_new (view->grid_group,
1073 gnome_canvas_line_get_type (),
1076 "fill_color_rgba", GRID_COLOR,
1079 points->coords[0] = 0.0;
1080 points->coords[2] = w;
1081 for ( y=0.0; y < h; y += view->grid_spacing ) {
1082 points->coords[1] = points->coords[3] = y;
1083 item = gnome_canvas_item_new (view->grid_group,
1084 gnome_canvas_line_get_type (),
1087 "fill_color_rgba", GRID_COLOR,
1090 points->coords[1] = points->coords[3] = h;
1091 item = gnome_canvas_item_new (view->grid_group,
1092 gnome_canvas_line_get_type (),
1095 "fill_color_rgba", GRID_COLOR,
1098 gnome_canvas_points_free (points);
1100 gl_debug (DEBUG_VIEW, "END");
1103 /*---------------------------------------------------------------------------*/
1104 /* PRIVATE. Draw markup lines. */
1105 /*---------------------------------------------------------------------------*/
1107 draw_markup_layer (glView *view)
1109 GnomeCanvasGroup *group;
1111 glTemplate *template;
1113 glTemplateMarkup *markup;
1115 g_return_if_fail (view && GL_IS_VIEW (view));
1116 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1118 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
1119 view->markup_group = GNOME_CANVAS_GROUP(
1120 gnome_canvas_item_new (group,
1121 gnome_canvas_group_get_type (),
1126 label = view->label;
1127 template = gl_label_get_template (label);
1129 for ( p=template->label.any.markups; p != NULL; p=p->next ) {
1130 markup = (glTemplateMarkup *)p->data;
1132 switch (markup->type) {
1133 case GL_TEMPLATE_MARKUP_MARGIN:
1134 draw_markup_margin (view,
1135 (glTemplateMarkupMargin *)markup);
1137 case GL_TEMPLATE_MARKUP_LINE:
1138 draw_markup_line (view,
1139 (glTemplateMarkupLine *)markup);
1142 g_warning ("Unknown template markup type");
1148 /*---------------------------------------------------------------------------*/
1149 /* PRIVATE. Draw margin markup. */
1150 /*---------------------------------------------------------------------------*/
1152 draw_markup_margin (glView *view,
1153 glTemplateMarkupMargin *margin)
1156 glTemplate *template;
1158 g_return_if_fail (view && GL_IS_VIEW (view));
1159 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1161 label = view->label;
1162 template = gl_label_get_template (label);
1164 switch (template->label.style) {
1166 case GL_TEMPLATE_STYLE_RECT:
1167 if (template->label.rect.r == 0.0) {
1168 /* Square corners. */
1169 draw_markup_margin_rect (view, margin);
1171 if ( margin->size < template->label.rect.r) {
1172 /* Rounded corners. */
1173 draw_markup_margin_rounded_rect (view, margin);
1175 /* Square corners. */
1176 draw_markup_margin_rect (view, margin);
1181 case GL_TEMPLATE_STYLE_ROUND:
1182 draw_markup_margin_round (view, margin);
1185 case GL_TEMPLATE_STYLE_CD:
1186 if ((template->label.cd.w == 0.0) && (template->label.cd.h == 0.0) ) {
1187 draw_markup_margin_cd (view, margin);
1189 draw_markup_margin_cd_bc (view, margin);
1194 g_warning ("Unknown template label style");
1199 /*---------------------------------------------------------------------------*/
1200 /* PRIVATE. Draw simple recangular margin. */
1201 /*---------------------------------------------------------------------------*/
1203 draw_markup_margin_rect (glView *view,
1204 glTemplateMarkupMargin *margin)
1207 glTemplate *template;
1209 GnomeCanvasItem *item;
1211 gl_debug (DEBUG_VIEW, "START");
1213 g_return_if_fail (view && GL_IS_VIEW (view));
1214 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1216 label = view->label;
1218 gl_label_get_size (label, &w, &h);
1219 template = gl_label_get_template (label);
1222 /* Bounding box @ margin */
1223 gnome_canvas_item_new (view->markup_group,
1224 gnome_canvas_rect_get_type (),
1230 "outline_color_rgba", MARKUP_COLOR,
1233 gl_debug (DEBUG_VIEW, "END");
1236 /*---------------------------------------------------------------------------*/
1237 /* PRIVATE. Draw rounded recangular markup. */
1238 /*---------------------------------------------------------------------------*/
1240 draw_markup_margin_rounded_rect (glView *view,
1241 glTemplateMarkupMargin *margin)
1244 GnomeCanvasPoints *points;
1245 gint i_coords, i_theta;
1246 glTemplate *template;
1248 GnomeCanvasItem *item;
1250 gl_debug (DEBUG_VIEW, "START");
1252 g_return_if_fail (view && GL_IS_VIEW (view));
1253 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1255 label = view->label;
1257 gl_label_get_size (label, &w, &h);
1258 template = gl_label_get_template (label);
1259 r = template->label.rect.r;
1266 /* rectangle with rounded corners */
1267 points = gnome_canvas_points_new (4 * (1 + 90 / ARC_COURSE));
1269 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1270 points->coords[i_coords++] =
1271 m + r - r * sin (i_theta * G_PI / 180.0);
1272 points->coords[i_coords++] =
1273 m + r - r * cos (i_theta * G_PI / 180.0);
1275 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1276 points->coords[i_coords++] =
1277 m + r - r * cos (i_theta * G_PI / 180.0);
1278 points->coords[i_coords++] =
1279 m + (h - r) + r * sin (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 + (w - r) + r * sin (i_theta * G_PI / 180.0);
1284 points->coords[i_coords++] =
1285 m + (h - r) + r * cos (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 * cos (i_theta * G_PI / 180.0);
1290 points->coords[i_coords++] =
1291 m + r - r * sin (i_theta * G_PI / 180.0);
1293 item = gnome_canvas_item_new (view->markup_group,
1294 gnome_canvas_polygon_get_type (),
1297 "outline_color_rgba", MARKUP_COLOR,
1299 gnome_canvas_points_free (points);
1301 gl_debug (DEBUG_VIEW, "END");
1304 /*---------------------------------------------------------------------------*/
1305 /* PRIVATE. Draw round margin. */
1306 /*---------------------------------------------------------------------------*/
1308 draw_markup_margin_round (glView *view,
1309 glTemplateMarkupMargin *margin)
1312 glTemplate *template;
1314 GnomeCanvasItem *item;
1316 gl_debug (DEBUG_VIEW, "START");
1318 g_return_if_fail (view && GL_IS_VIEW (view));
1319 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1321 label = view->label;
1322 template = gl_label_get_template (label);
1324 r = template->label.round.r;
1327 /* Margin outline */
1328 item = gnome_canvas_item_new (view->markup_group,
1329 gnome_canvas_ellipse_get_type (),
1335 "outline_color_rgba", MARKUP_COLOR,
1338 gl_debug (DEBUG_VIEW, "END");
1341 /*---------------------------------------------------------------------------*/
1342 /* PRIVATE. Draw CD margins. */
1343 /*---------------------------------------------------------------------------*/
1345 draw_markup_margin_cd (glView *view,
1346 glTemplateMarkupMargin *margin)
1349 glTemplate *template;
1351 GnomeCanvasItem *item;
1353 gl_debug (DEBUG_VIEW, "START");
1355 g_return_if_fail (view && GL_IS_VIEW (view));
1356 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1358 label = view->label;
1359 template = gl_label_get_template (label);
1361 r1 = template->label.cd.r1;
1362 r2 = template->label.cd.r2;
1366 item = gnome_canvas_item_new (view->markup_group,
1367 gnome_canvas_ellipse_get_type (),
1373 "outline_color_rgba", MARKUP_COLOR,
1376 item = gnome_canvas_item_new (view->markup_group,
1377 gnome_canvas_ellipse_get_type (),
1383 "outline_color_rgba", MARKUP_COLOR,
1386 gl_debug (DEBUG_VIEW, "END");
1389 /*---------------------------------------------------------------------------*/
1390 /* PRIVATE. Draw Business Card CD margins. */
1391 /*---------------------------------------------------------------------------*/
1393 draw_markup_margin_cd_bc (glView *view,
1394 glTemplateMarkupMargin *margin)
1397 glTemplate *template;
1399 GnomeCanvasPoints *points;
1400 gint i_coords, i_theta;
1401 gdouble theta1, theta2;
1402 gdouble x0, y0, w, h, r;
1403 GnomeCanvasItem *item;
1405 gl_debug (DEBUG_VIEW, "START");
1407 g_return_if_fail (view && GL_IS_VIEW (view));
1408 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1410 label = view->label;
1411 template = gl_label_get_template (label);
1412 gl_label_get_size (label, &w, &h);
1416 r1 = template->label.cd.r1;
1417 r2 = template->label.cd.r2;
1422 theta1 = (180.0/G_PI) * acos (w / (2.0*r1));
1423 theta2 = (180.0/G_PI) * asin (h / (2.0*r1));
1425 points = gnome_canvas_points_new (360/ARC_FINE + 1);
1428 points->coords[i_coords++] = x0 + r * cos (theta1 * G_PI / 180.0);
1429 points->coords[i_coords++] = y0 + r * sin (theta1 * G_PI / 180.0);
1431 for ( i_theta = theta1 + ARC_FINE; i_theta < theta2; i_theta +=ARC_FINE ) {
1432 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
1433 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
1436 points->coords[i_coords++] = x0 + r * cos (theta2 * G_PI / 180.0);
1437 points->coords[i_coords++] = y0 + r * sin (theta2 * G_PI / 180.0);
1440 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
1441 points->coords[i_coords++] = x0 + r * cos ((180-theta2) * G_PI / 180.0);
1442 points->coords[i_coords++] = y0 + r * sin ((180-theta2) * G_PI / 180.0);
1445 for ( i_theta = 180-theta2+ARC_FINE; i_theta < (180-theta1); i_theta +=ARC_FINE ) {
1446 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
1447 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
1450 points->coords[i_coords++] = x0 + r * cos ((180-theta1) * G_PI / 180.0);
1451 points->coords[i_coords++] = y0 + r * sin ((180-theta1) * G_PI / 180.0);
1453 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
1454 points->coords[i_coords++] = x0 + r * cos ((180+theta1) * G_PI / 180.0);
1455 points->coords[i_coords++] = y0 + r * sin ((180+theta1) * G_PI / 180.0);
1458 for ( i_theta = 180+theta1+ARC_FINE; i_theta < (180+theta2); i_theta +=ARC_FINE ) {
1459 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
1460 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
1463 points->coords[i_coords++] = x0 + r * cos ((180+theta2) * G_PI / 180.0);
1464 points->coords[i_coords++] = y0 + r * sin ((180+theta2) * G_PI / 180.0);
1466 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
1467 points->coords[i_coords++] = x0 + r * cos ((360-theta2) * G_PI / 180.0);
1468 points->coords[i_coords++] = y0 + r * sin ((360-theta2) * G_PI / 180.0);
1471 for ( i_theta = 360-theta2+ARC_FINE; i_theta < (360-theta1); i_theta +=ARC_FINE ) {
1472 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
1473 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
1476 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
1477 points->coords[i_coords++] = x0 + r * cos ((360-theta1) * G_PI / 180.0);
1478 points->coords[i_coords++] = y0 + r * sin ((360-theta1) * G_PI / 180.0);
1481 points->num_points = i_coords / 2;
1483 item = gnome_canvas_item_new (view->markup_group,
1484 gnome_canvas_polygon_get_type (),
1487 "outline_color_rgba", MARKUP_COLOR,
1490 gnome_canvas_points_free (points);
1493 item = gnome_canvas_item_new (view->markup_group,
1494 gnome_canvas_ellipse_get_type (),
1500 "outline_color_rgba", MARKUP_COLOR,
1503 gl_debug (DEBUG_VIEW, "END");
1506 /*---------------------------------------------------------------------------*/
1507 /* PRIVATE. Draw line markup. */
1508 /*---------------------------------------------------------------------------*/
1510 draw_markup_line (glView *view,
1511 glTemplateMarkupLine *line)
1513 GnomeCanvasPoints *points;
1515 gl_debug (DEBUG_VIEW, "START");
1517 g_return_if_fail (view && GL_IS_VIEW (view));
1519 points = gnome_canvas_points_new (2);
1520 points->coords[0] = line->x1;
1521 points->coords[1] = line->y1;
1522 points->coords[2] = line->x2;
1523 points->coords[3] = line->y2;
1525 /* Bounding box @ margin */
1526 gnome_canvas_item_new (view->markup_group,
1527 gnome_canvas_line_get_type (),
1530 "fill_color_rgba", MARKUP_COLOR,
1533 gnome_canvas_points_free (points);
1535 gl_debug (DEBUG_VIEW, "END");
1538 /*****************************************************************************/
1540 /*****************************************************************************/
1541 void gl_view_show_grid (glView *view)
1543 g_return_if_fail (view && GL_IS_VIEW (view));
1545 gnome_canvas_item_show (GNOME_CANVAS_ITEM(view->grid_group));
1548 /*****************************************************************************/
1550 /*****************************************************************************/
1551 void gl_view_hide_grid (glView *view)
1553 g_return_if_fail (view && GL_IS_VIEW (view));
1555 gnome_canvas_item_hide (GNOME_CANVAS_ITEM(view->grid_group));
1558 /*****************************************************************************/
1559 /* Set grid spacing. */
1560 /*****************************************************************************/
1561 void gl_view_set_grid_spacing (glView *view,
1564 g_return_if_fail (view && GL_IS_VIEW (view));
1566 view->grid_spacing = spacing;
1568 gtk_object_destroy (GTK_OBJECT(view->grid_group));
1569 draw_grid_layer (view);
1572 /*****************************************************************************/
1574 /*****************************************************************************/
1575 void gl_view_show_markup (glView *view)
1577 g_return_if_fail (view && GL_IS_VIEW (view));
1579 gnome_canvas_item_show (GNOME_CANVAS_ITEM(view->markup_group));
1582 /*****************************************************************************/
1584 /*****************************************************************************/
1585 void gl_view_hide_markup (glView *view)
1587 g_return_if_fail (view && GL_IS_VIEW (view));
1589 gnome_canvas_item_hide (GNOME_CANVAS_ITEM(view->markup_group));
1592 /*****************************************************************************/
1593 /* Set arrow mode. */
1594 /*****************************************************************************/
1596 gl_view_arrow_mode (glView *view)
1598 static GdkCursor *cursor = NULL;
1600 gl_debug (DEBUG_VIEW, "START");
1602 g_return_if_fail (view && GL_IS_VIEW (view));
1605 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1608 gdk_window_set_cursor (view->canvas->window, cursor);
1610 view->state = GL_VIEW_STATE_ARROW;
1612 gl_debug (DEBUG_VIEW, "END");
1615 /*****************************************************************************/
1616 /* Set create text object mode. */
1617 /*****************************************************************************/
1619 gl_view_object_create_mode (glView *view,
1620 glLabelObjectType type)
1624 gl_debug (DEBUG_VIEW, "START");
1626 g_return_if_fail (view && GL_IS_VIEW (view));
1629 case GL_LABEL_OBJECT_BOX:
1630 cursor = gl_view_box_get_create_cursor ();
1632 case GL_LABEL_OBJECT_ELLIPSE:
1633 cursor = gl_view_ellipse_get_create_cursor ();
1635 case GL_LABEL_OBJECT_LINE:
1636 cursor = gl_view_line_get_create_cursor ();
1638 case GL_LABEL_OBJECT_IMAGE:
1639 cursor = gl_view_image_get_create_cursor ();
1641 case GL_LABEL_OBJECT_TEXT:
1642 cursor = gl_view_text_get_create_cursor ();
1644 case GL_LABEL_OBJECT_BARCODE:
1645 cursor = gl_view_barcode_get_create_cursor ();
1648 g_warning ("Invalid label object type.");/*Should not happen!*/
1652 gdk_window_set_cursor (view->canvas->window, cursor);
1654 view->state = GL_VIEW_STATE_OBJECT_CREATE;
1655 view->create_type = type;
1657 gl_debug (DEBUG_VIEW, "END");
1660 /*****************************************************************************/
1661 /* Select given object (adding to current selection). */
1662 /*****************************************************************************/
1664 gl_view_select_object (glView *view,
1665 glViewObject *view_object)
1667 gl_debug (DEBUG_VIEW, "START");
1669 g_return_if_fail (view && GL_IS_VIEW (view));
1671 select_object_real (view, view_object);
1673 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1675 gl_debug (DEBUG_VIEW, "END");
1678 /*****************************************************************************/
1679 /* Unselect given object (removing from current selection). */
1680 /*****************************************************************************/
1682 gl_view_unselect_object (glView *view,
1683 glViewObject *view_object)
1685 gl_debug (DEBUG_VIEW, "START");
1687 g_return_if_fail (view && GL_IS_VIEW (view));
1689 unselect_object_real (view, view_object);
1691 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1693 gl_debug (DEBUG_VIEW, "END");
1696 /*****************************************************************************/
1697 /* Select all items. */
1698 /*****************************************************************************/
1700 gl_view_select_all (glView *view)
1704 gl_debug (DEBUG_VIEW, "START");
1706 g_return_if_fail (view && GL_IS_VIEW (view));
1708 /* 1st unselect anything already selected. */
1709 for (p = view->selected_object_list; p != NULL; p = p_next) {
1711 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1714 /* Finally select all objects. */
1715 for (p = view->object_list; p != NULL; p = p->next) {
1716 select_object_real (view, GL_VIEW_OBJECT (p->data));
1719 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1721 gl_debug (DEBUG_VIEW, "END");
1724 /*****************************************************************************/
1725 /* Remove all selections */
1726 /*****************************************************************************/
1728 gl_view_unselect_all (glView *view)
1732 gl_debug (DEBUG_VIEW, "START");
1734 g_return_if_fail (view && GL_IS_VIEW (view));
1736 for (p = view->selected_object_list; p != NULL; p = p_next) {
1738 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1741 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1743 gl_debug (DEBUG_VIEW, "END");
1746 /*****************************************************************************/
1747 /* Select all objects within given rectangular region (adding to selection). */
1748 /*****************************************************************************/
1750 gl_view_select_region (glView *view,
1757 glViewObject *view_object;
1758 glLabelObject *object;
1759 gdouble i_x1, i_y1, i_x2, i_y2;
1761 gl_debug (DEBUG_VIEW, "START");
1763 g_return_if_fail (view && GL_IS_VIEW (view));
1764 g_return_if_fail ((x1 <= x2) && (y1 <= y2));
1766 for (p = view->object_list; p != NULL; p = p->next) {
1767 view_object = GL_VIEW_OBJECT(p->data);
1768 if (!gl_view_is_object_selected (view, view_object)) {
1770 object = gl_view_object_get_object (view_object);
1772 gl_label_object_get_extent (object, &i_x1, &i_y1, &i_x2, &i_y2);
1773 if ((i_x1 >= x1) && (i_x2 <= x2) && (i_y1 >= y1)
1775 select_object_real (view, view_object);
1781 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1783 gl_debug (DEBUG_VIEW, "END");
1786 /*---------------------------------------------------------------------------*/
1787 /* PRIVATE. Select an object. */
1788 /*---------------------------------------------------------------------------*/
1790 select_object_real (glView *view,
1791 glViewObject *view_object)
1793 gl_debug (DEBUG_VIEW, "START");
1795 g_return_if_fail (view && GL_IS_VIEW (view));
1796 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1798 if (!gl_view_is_object_selected (view, view_object)) {
1799 view->selected_object_list =
1800 g_list_prepend (view->selected_object_list, view_object);
1802 gl_view_object_show_highlight (view_object);
1803 gtk_widget_grab_focus (GTK_WIDGET (view->canvas));
1805 gl_debug (DEBUG_VIEW, "END");
1808 /*---------------------------------------------------------------------------*/
1809 /* PRIVATE. Un-select object. */
1810 /*---------------------------------------------------------------------------*/
1812 unselect_object_real (glView *view,
1813 glViewObject *view_object)
1815 gl_debug (DEBUG_VIEW, "START");
1817 g_return_if_fail (view && GL_IS_VIEW (view));
1818 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1820 gl_view_object_hide_highlight (view_object);
1822 view->selected_object_list =
1823 g_list_remove (view->selected_object_list, view_object);
1825 gl_debug (DEBUG_VIEW, "END");
1828 /*---------------------------------------------------------------------------*/
1829 /* PRIVATE. Return object at (x,y). */
1830 /*---------------------------------------------------------------------------*/
1832 object_at (glView *view,
1836 GnomeCanvasItem *item, *p_item;
1839 gl_debug (DEBUG_VIEW, "");
1841 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1843 item = gnome_canvas_get_item_at (GNOME_CANVAS (view->canvas), x, y);
1845 /* No item is at x, y */
1849 /* ignore items not in label or highlight layers, e.g. background items */
1850 if (!is_item_member_of_group(view, item, GNOME_CANVAS_ITEM(view->label_group)) &&
1851 !is_item_member_of_group(view, item, GNOME_CANVAS_ITEM(view->highlight_group)))
1857 /*---------------------------------------------------------------------------*/
1858 /* PRIVATE. Is the item a child (or grandchild, etc.) of group. */
1859 /*---------------------------------------------------------------------------*/
1861 is_item_member_of_group (glView *view,
1862 GnomeCanvasItem *item,
1863 GnomeCanvasItem *group)
1865 GnomeCanvasItem *parent;
1866 GnomeCanvasItem *root_group;
1868 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1870 root_group = GNOME_CANVAS_ITEM(gnome_canvas_root (GNOME_CANVAS (view->canvas)));
1872 for ( parent=item->parent; parent && (parent!=root_group); parent=parent->parent) {
1873 if (parent == group) return TRUE;
1878 /*****************************************************************************/
1879 /* Is the object in our current selection? */
1880 /*****************************************************************************/
1882 gl_view_is_object_selected (glView *view,
1883 glViewObject *view_object)
1885 gl_debug (DEBUG_VIEW, "");
1887 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1888 g_return_val_if_fail (GL_IS_VIEW_OBJECT (view_object), FALSE);
1890 if (g_list_find (view->selected_object_list, view_object) == NULL) {
1896 /*****************************************************************************/
1897 /* Is our current selection empty? */
1898 /*****************************************************************************/
1900 gl_view_is_selection_empty (glView *view)
1902 gl_debug (DEBUG_VIEW, "");
1904 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1906 if (view->selected_object_list == NULL) {
1913 /*****************************************************************************/
1914 /* Is our current selection atomic? I.e. only one item selected. */
1915 /*****************************************************************************/
1917 gl_view_is_selection_atomic (glView *view)
1919 gl_debug (DEBUG_VIEW, "");
1921 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1923 if (view->selected_object_list == NULL)
1925 if (view->selected_object_list->next == NULL)
1930 /*****************************************************************************/
1931 /* Delete selected objects. (Bypass clipboard) */
1932 /*****************************************************************************/
1934 gl_view_delete_selection (glView *view)
1938 gl_debug (DEBUG_VIEW, "START");
1940 g_return_if_fail (view && GL_IS_VIEW (view));
1942 for (p = view->selected_object_list; p != NULL; p = p_next) {
1944 g_object_unref (G_OBJECT (p->data));
1947 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1949 gl_debug (DEBUG_VIEW, "END");
1952 /*****************************************************************************/
1953 /* Edit properties of selected object. */
1954 /*****************************************************************************/
1956 gl_view_edit_object_props (glView *view)
1958 glViewObject *view_object;
1960 gl_debug (DEBUG_VIEW, "START");
1962 g_return_if_fail (view && GL_IS_VIEW (view));
1964 if (gl_view_is_selection_atomic (view)) {
1966 view_object = GL_VIEW_OBJECT(view->selected_object_list->data);
1967 gl_view_object_show_dialog (view_object);
1971 gl_debug (DEBUG_VIEW, "END");
1974 /*****************************************************************************/
1975 /* Raise selected items to top. */
1976 /*****************************************************************************/
1978 gl_view_raise_selection (glView *view)
1981 glViewObject *view_object;
1982 glLabelObject *object;
1984 gl_debug (DEBUG_VIEW, "START");
1986 g_return_if_fail (view && GL_IS_VIEW (view));
1988 for (p = view->selected_object_list; p != NULL; p = p->next) {
1989 view_object = GL_VIEW_OBJECT (p->data);
1990 object = gl_view_object_get_object (view_object);
1991 gl_label_object_raise_to_top (object);
1994 gl_debug (DEBUG_VIEW, "END");
1997 /*****************************************************************************/
1998 /* Lower selected items to bottom. */
1999 /*****************************************************************************/
2001 gl_view_lower_selection (glView *view)
2004 glViewObject *view_object;
2005 glLabelObject *object;
2007 gl_debug (DEBUG_VIEW, "START");
2009 g_return_if_fail (view && GL_IS_VIEW (view));
2011 for (p = view->selected_object_list; p != NULL; p = p->next) {
2012 view_object = GL_VIEW_OBJECT (p->data);
2013 object = gl_view_object_get_object (view_object);
2014 gl_label_object_lower_to_bottom (object);
2017 gl_debug (DEBUG_VIEW, "END");
2020 /*****************************************************************************/
2021 /* Rotate selected objects by given angle. */
2022 /*****************************************************************************/
2024 gl_view_rotate_selection (glView *view,
2028 glViewObject *view_object;
2029 glLabelObject *object;
2031 gl_debug (DEBUG_VIEW, "START");
2033 g_return_if_fail (view && GL_IS_VIEW (view));
2035 for (p = view->selected_object_list; p != NULL; p = p->next) {
2036 view_object = GL_VIEW_OBJECT (p->data);
2037 object = gl_view_object_get_object (view_object);
2038 gl_label_object_rotate (object, theta_degs);
2041 gl_debug (DEBUG_VIEW, "END");
2044 /*****************************************************************************/
2045 /* Rotate selected objects 90 degrees left. */
2046 /*****************************************************************************/
2048 gl_view_rotate_selection_left (glView *view)
2051 glViewObject *view_object;
2052 glLabelObject *object;
2054 gl_debug (DEBUG_VIEW, "START");
2056 g_return_if_fail (view && GL_IS_VIEW (view));
2058 for (p = view->selected_object_list; p != NULL; p = p->next) {
2059 view_object = GL_VIEW_OBJECT (p->data);
2060 object = gl_view_object_get_object (view_object);
2061 gl_label_object_rotate (object, -90.0);
2064 gl_debug (DEBUG_VIEW, "END");
2067 /*****************************************************************************/
2068 /* Rotate selected objects 90 degrees right. */
2069 /*****************************************************************************/
2071 gl_view_rotate_selection_right (glView *view)
2074 glViewObject *view_object;
2075 glLabelObject *object;
2077 gl_debug (DEBUG_VIEW, "START");
2079 g_return_if_fail (view && GL_IS_VIEW (view));
2081 for (p = view->selected_object_list; p != NULL; p = p->next) {
2082 view_object = GL_VIEW_OBJECT (p->data);
2083 object = gl_view_object_get_object (view_object);
2084 gl_label_object_rotate (object, 90.0);
2087 gl_debug (DEBUG_VIEW, "END");
2090 /*****************************************************************************/
2091 /* Flip selected objects horizontally. */
2092 /*****************************************************************************/
2094 gl_view_flip_selection_horiz (glView *view)
2097 glViewObject *view_object;
2098 glLabelObject *object;
2100 gl_debug (DEBUG_VIEW, "START");
2102 g_return_if_fail (view && GL_IS_VIEW (view));
2104 for (p = view->selected_object_list; p != NULL; p = p->next) {
2105 view_object = GL_VIEW_OBJECT (p->data);
2106 object = gl_view_object_get_object (view_object);
2107 gl_label_object_flip_horiz (object);
2110 gl_debug (DEBUG_VIEW, "END");
2113 /*****************************************************************************/
2114 /* Flip selected objects vertically. */
2115 /*****************************************************************************/
2117 gl_view_flip_selection_vert (glView *view)
2120 glViewObject *view_object;
2121 glLabelObject *object;
2123 gl_debug (DEBUG_VIEW, "START");
2125 g_return_if_fail (view && GL_IS_VIEW (view));
2127 for (p = view->selected_object_list; p != NULL; p = p->next) {
2128 view_object = GL_VIEW_OBJECT (p->data);
2129 object = gl_view_object_get_object (view_object);
2130 gl_label_object_flip_vert (object);
2133 gl_debug (DEBUG_VIEW, "END");
2136 /*****************************************************************************/
2137 /* Align selected objects to left most edge. */
2138 /*****************************************************************************/
2140 gl_view_align_selection_left (glView *view)
2143 glViewObject *view_object;
2144 glLabelObject *object;
2145 gdouble dx, x1min, x1, y1, x2, y2;
2147 gl_debug (DEBUG_VIEW, "START");
2149 g_return_if_fail (view && GL_IS_VIEW (view));
2151 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2152 !gl_view_is_selection_atomic (view));
2154 /* find left most edge */
2155 p = view->selected_object_list;
2156 view_object = GL_VIEW_OBJECT (p->data);
2157 object = gl_view_object_get_object (view_object);
2158 gl_label_object_get_extent (object, &x1min, &y1, &x2, &y2);
2159 for (p = p->next; p != NULL; p = p->next) {
2160 view_object = GL_VIEW_OBJECT (p->data);
2161 object = gl_view_object_get_object (view_object);
2162 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2163 if ( x1 < x1min ) x1min = x1;
2166 /* now adjust the object positions to line up the left edges */
2167 for (p = view->selected_object_list; p != NULL; p = p->next) {
2168 view_object = GL_VIEW_OBJECT (p->data);
2169 object = gl_view_object_get_object (view_object);
2170 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2172 gl_label_object_set_position_relative (object, dx, 0.0);
2175 gl_debug (DEBUG_VIEW, "END");
2179 /*****************************************************************************/
2180 /* Align selected objects to right most edge. */
2181 /*****************************************************************************/
2183 gl_view_align_selection_right (glView *view)
2186 glViewObject *view_object;
2187 glLabelObject *object;
2188 gdouble dx, x2max, x1, y1, x2, y2;
2190 gl_debug (DEBUG_VIEW, "START");
2192 g_return_if_fail (view && GL_IS_VIEW (view));
2194 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2195 !gl_view_is_selection_atomic (view));
2197 /* find right most edge */
2198 p = view->selected_object_list;
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, &x2max, &y2);
2202 for (p = p->next; p != NULL; p = p->next) {
2203 view_object = GL_VIEW_OBJECT (p->data);
2204 object = gl_view_object_get_object (view_object);
2205 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2206 if ( x2 > x2max ) x2max = x2;
2209 /* now adjust the object positions to line up the right edges */
2210 for (p = view->selected_object_list; p != NULL; p = p->next) {
2211 view_object = GL_VIEW_OBJECT (p->data);
2212 object = gl_view_object_get_object (view_object);
2213 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2215 gl_label_object_set_position_relative (object, dx, 0.0);
2218 gl_debug (DEBUG_VIEW, "END");
2221 /*****************************************************************************/
2222 /* Align selected objects to horizontal center of objects. */
2223 /*****************************************************************************/
2225 gl_view_align_selection_hcenter (glView *view)
2228 glViewObject *view_object;
2229 glLabelObject *object;
2230 gdouble dx, dxmin, xsum, xavg, xcenter, x1, y1, x2, y2;
2233 gl_debug (DEBUG_VIEW, "START");
2235 g_return_if_fail (view && GL_IS_VIEW (view));
2237 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2238 !gl_view_is_selection_atomic (view));
2240 /* find average center of objects */
2243 for (p = view->selected_object_list; p != NULL; p = p->next) {
2244 view_object = GL_VIEW_OBJECT (p->data);
2245 object = gl_view_object_get_object (view_object);
2246 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2247 xsum += (x1 + x2) / 2.0;
2252 /* find center of object closest to average center */
2253 p = view->selected_object_list;
2254 view_object = GL_VIEW_OBJECT (p->data);
2255 object = gl_view_object_get_object (view_object);
2256 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2257 dxmin = fabs (xavg - (x1 + x2)/2.0);
2258 xcenter = (x1 + x2)/2.0;
2259 for (p = p->next; p != NULL; p = p->next) {
2260 view_object = GL_VIEW_OBJECT (p->data);
2261 object = gl_view_object_get_object (view_object);
2262 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2263 dx = fabs (xavg - (x1 + x2)/2.0);
2266 xcenter = (x1 + x2)/2.0;
2270 /* now adjust the object positions to line up this center */
2271 for (p = view->selected_object_list; p != NULL; p = p->next) {
2272 view_object = GL_VIEW_OBJECT (p->data);
2273 object = gl_view_object_get_object (view_object);
2274 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2275 dx = xcenter - (x1 + x2)/2.0;
2276 gl_label_object_set_position_relative (object, dx, 0.0);
2279 gl_debug (DEBUG_VIEW, "END");
2282 /*****************************************************************************/
2283 /* Align selected objects to top most edge. */
2284 /*****************************************************************************/
2286 gl_view_align_selection_top (glView *view)
2289 glViewObject *view_object;
2290 glLabelObject *object;
2291 gdouble dy, y1min, x1, y1, x2, y2;
2293 gl_debug (DEBUG_VIEW, "START");
2295 g_return_if_fail (view && GL_IS_VIEW (view));
2297 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2298 !gl_view_is_selection_atomic (view));
2300 /* find top most edge */
2301 p = view->selected_object_list;
2302 view_object = GL_VIEW_OBJECT (p->data);
2303 object = gl_view_object_get_object (view_object);
2304 gl_label_object_get_extent (object, &x1, &y1min, &x2, &y2);
2305 for (p = p->next; p != NULL; p = p->next) {
2306 view_object = GL_VIEW_OBJECT (p->data);
2307 object = gl_view_object_get_object (view_object);
2308 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2309 if ( y1 < y1min ) y1min = y1;
2312 /* now adjust the object positions to line up the top edges */
2313 for (p = view->selected_object_list; p != NULL; p = p->next) {
2314 view_object = GL_VIEW_OBJECT (p->data);
2315 object = gl_view_object_get_object (view_object);
2316 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2318 gl_label_object_set_position_relative (object, 0.0, dy);
2321 gl_debug (DEBUG_VIEW, "END");
2324 /*****************************************************************************/
2325 /* Align selected objects to bottom most edge. */
2326 /*****************************************************************************/
2328 gl_view_align_selection_bottom (glView *view)
2331 glViewObject *view_object;
2332 glLabelObject *object;
2333 gdouble dy, y2max, x1, y1, x2, y2;
2335 gl_debug (DEBUG_VIEW, "START");
2337 g_return_if_fail (view && GL_IS_VIEW (view));
2339 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2340 !gl_view_is_selection_atomic (view));
2342 /* find bottom most edge */
2343 p = view->selected_object_list;
2344 view_object = GL_VIEW_OBJECT (p->data);
2345 object = gl_view_object_get_object (view_object);
2346 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2max);
2347 for (p = p->next; p != NULL; p = p->next) {
2348 view_object = GL_VIEW_OBJECT (p->data);
2349 object = gl_view_object_get_object (view_object);
2350 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2351 if ( y2 > y2max ) y2max = y2;
2354 /* now adjust the object positions to line up the bottom edges */
2355 for (p = view->selected_object_list; p != NULL; p = p->next) {
2356 view_object = GL_VIEW_OBJECT (p->data);
2357 object = gl_view_object_get_object (view_object);
2358 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2360 gl_label_object_set_position_relative (object, 0.0, dy);
2363 gl_debug (DEBUG_VIEW, "END");
2366 /*****************************************************************************/
2367 /* Align selected objects to viertical center of objects. */
2368 /*****************************************************************************/
2370 gl_view_align_selection_vcenter (glView *view)
2373 glViewObject *view_object;
2374 glLabelObject *object;
2375 gdouble dy, dymin, ysum, yavg, ycenter, x1, y1, x2, y2;
2378 gl_debug (DEBUG_VIEW, "START");
2380 g_return_if_fail (view && GL_IS_VIEW (view));
2382 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2383 !gl_view_is_selection_atomic (view));
2385 /* find average center of objects */
2388 for (p = view->selected_object_list; p != NULL; p = p->next) {
2389 view_object = GL_VIEW_OBJECT (p->data);
2390 object = gl_view_object_get_object (view_object);
2391 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2392 ysum += (y1 + y2) / 2.0;
2397 /* find center of object closest to average center */
2398 p = view->selected_object_list;
2399 view_object = GL_VIEW_OBJECT (p->data);
2400 object = gl_view_object_get_object (view_object);
2401 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2402 dymin = fabs (yavg - (y1 + y2)/2.0);
2403 ycenter = (y1 + y2)/2.0;
2404 for (p = p->next; p != NULL; p = p->next) {
2405 view_object = GL_VIEW_OBJECT (p->data);
2406 object = gl_view_object_get_object (view_object);
2407 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2408 dy = fabs (yavg - (y1 + y2)/2.0);
2411 ycenter = (y1 + y2)/2.0;
2415 /* now adjust the object positions to line up this center */
2416 for (p = view->selected_object_list; p != NULL; p = p->next) {
2417 view_object = GL_VIEW_OBJECT (p->data);
2418 object = gl_view_object_get_object (view_object);
2419 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2420 dy = ycenter - (y1 + y2)/2.0;
2421 gl_label_object_set_position_relative (object, 0.0, dy);
2424 gl_debug (DEBUG_VIEW, "END");
2427 /*****************************************************************************/
2428 /* Center selected objects to in center of label. */
2429 /*****************************************************************************/
2431 gl_view_center_selection_horiz (glView *view)
2434 glViewObject *view_object;
2435 glLabelObject *object;
2436 gdouble dx, x_label_center, x_obj_center, x1, y1, x2, y2, w, h;
2438 gl_debug (DEBUG_VIEW, "START");
2440 g_return_if_fail (view && GL_IS_VIEW (view));
2442 g_return_if_fail (!gl_view_is_selection_empty (view));
2444 gl_label_get_size (view->label, &w, &h);
2445 x_label_center = w / 2.0;
2447 /* adjust the object positions */
2448 for (p = view->selected_object_list; p != NULL; p = p->next) {
2449 view_object = GL_VIEW_OBJECT (p->data);
2450 object = gl_view_object_get_object (view_object);
2451 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2452 x_obj_center = (x1 + x2) / 2.0;
2453 dx = x_label_center - x_obj_center;
2454 gl_label_object_set_position_relative (object, dx, 0.0);
2457 gl_debug (DEBUG_VIEW, "END");
2461 /*****************************************************************************/
2462 /* Center selected objects to in center of label. */
2463 /*****************************************************************************/
2465 gl_view_center_selection_vert (glView *view)
2468 glViewObject *view_object;
2469 glLabelObject *object;
2470 gdouble dy, y_label_center, y_obj_center, x1, y1, x2, y2, w, h;
2472 gl_debug (DEBUG_VIEW, "START");
2474 g_return_if_fail (view && GL_IS_VIEW (view));
2476 g_return_if_fail (!gl_view_is_selection_empty (view));
2478 gl_label_get_size (view->label, &w, &h);
2479 y_label_center = h / 2.0;
2481 /* adjust the object positions */
2482 for (p = view->selected_object_list; p != NULL; p = p->next) {
2483 view_object = GL_VIEW_OBJECT (p->data);
2484 object = gl_view_object_get_object (view_object);
2485 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2486 y_obj_center = (y1 + y2) / 2.0;
2487 dy = y_label_center - y_obj_center;
2488 gl_label_object_set_position_relative (object, 0.0, dy);
2491 gl_debug (DEBUG_VIEW, "END");
2495 /*****************************************************************************/
2496 /* Move selected objects */
2497 /*****************************************************************************/
2499 gl_view_move_selection (glView *view,
2504 glLabelObject *object;
2506 gl_debug (DEBUG_VIEW, "START");
2508 g_return_if_fail (view && GL_IS_VIEW (view));
2510 for (p = view->selected_object_list; p != NULL; p = p->next) {
2512 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2513 gl_label_object_set_position_relative (object, dx, dy);
2517 gl_debug (DEBUG_VIEW, "END");
2520 /*****************************************************************************/
2521 /* Can text properties be set for selection? */
2522 /*****************************************************************************/
2524 gl_view_can_selection_text (glView *view)
2527 glLabelObject *object;
2529 gl_debug (DEBUG_VIEW, "");
2531 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2533 for (p = view->selected_object_list; p != NULL; p = p->next) {
2535 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2536 if (gl_label_object_can_text (object)) {
2545 /*****************************************************************************/
2546 /* Set font family for all text contained in selected objects. */
2547 /*****************************************************************************/
2549 gl_view_set_selection_font_family (glView *view,
2550 const gchar *font_family)
2553 glLabelObject *object;
2555 gl_debug (DEBUG_VIEW, "START");
2557 g_return_if_fail (view && GL_IS_VIEW (view));
2559 for (p = view->selected_object_list; p != NULL; p = p->next) {
2561 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2562 gl_label_object_set_font_family (object, font_family);
2566 gl_debug (DEBUG_VIEW, "END");
2569 /*****************************************************************************/
2570 /* Set font size for all text contained in selected objects. */
2571 /*****************************************************************************/
2573 gl_view_set_selection_font_size (glView *view,
2577 glLabelObject *object;
2579 gl_debug (DEBUG_VIEW, "START");
2581 g_return_if_fail (view && GL_IS_VIEW (view));
2583 for (p = view->selected_object_list; p != NULL; p = p->next) {
2585 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2586 gl_label_object_set_font_size (object, font_size);
2590 gl_debug (DEBUG_VIEW, "END");
2593 /*****************************************************************************/
2594 /* Set font weight for all text contained in selected objects. */
2595 /*****************************************************************************/
2597 gl_view_set_selection_font_weight (glView *view,
2598 GnomeFontWeight font_weight)
2601 glLabelObject *object;
2603 gl_debug (DEBUG_VIEW, "START");
2605 g_return_if_fail (view && GL_IS_VIEW (view));
2607 for (p = view->selected_object_list; p != NULL; p = p->next) {
2609 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2610 gl_label_object_set_font_weight (object, font_weight);
2614 gl_debug (DEBUG_VIEW, "END");
2617 /*****************************************************************************/
2618 /* Set font italic flag for all text contained in selected objects. */
2619 /*****************************************************************************/
2621 gl_view_set_selection_font_italic_flag (glView *view,
2622 gboolean font_italic_flag)
2625 glLabelObject *object;
2627 gl_debug (DEBUG_VIEW, "START");
2629 g_return_if_fail (view && GL_IS_VIEW (view));
2631 for (p = view->selected_object_list; p != NULL; p = p->next) {
2633 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2634 gl_label_object_set_font_italic_flag (object, font_italic_flag);
2638 gl_debug (DEBUG_VIEW, "END");
2641 /*****************************************************************************/
2642 /* Set text alignment for all text contained in selected objects. */
2643 /*****************************************************************************/
2645 gl_view_set_selection_text_alignment (glView *view,
2646 GtkJustification text_alignment)
2649 glLabelObject *object;
2651 gl_debug (DEBUG_VIEW, "START");
2653 g_return_if_fail (view && GL_IS_VIEW (view));
2655 for (p = view->selected_object_list; p != NULL; p = p->next) {
2657 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2658 gl_label_object_set_text_alignment (object, text_alignment);
2662 gl_debug (DEBUG_VIEW, "END");
2665 /*****************************************************************************/
2666 /* Set text color for all text contained in selected objects. */
2667 /*****************************************************************************/
2669 gl_view_set_selection_text_color (glView *view,
2673 glLabelObject *object;
2675 gl_debug (DEBUG_VIEW, "START");
2677 g_return_if_fail (view && GL_IS_VIEW (view));
2679 for (p = view->selected_object_list; p != NULL; p = p->next) {
2681 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2682 gl_label_object_set_text_color (object, text_color);
2686 gl_debug (DEBUG_VIEW, "END");
2689 /*****************************************************************************/
2690 /* Can fill properties be set for selection? */
2691 /*****************************************************************************/
2693 gl_view_can_selection_fill (glView *view)
2696 glLabelObject *object;
2698 gl_debug (DEBUG_VIEW, "");
2700 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2702 for (p = view->selected_object_list; p != NULL; p = p->next) {
2704 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2705 if (gl_label_object_can_fill (object)) {
2714 /*****************************************************************************/
2715 /* Set fill color for all selected objects. */
2716 /*****************************************************************************/
2718 gl_view_set_selection_fill_color (glView *view,
2722 glLabelObject *object;
2724 gl_debug (DEBUG_VIEW, "START");
2726 g_return_if_fail (view && GL_IS_VIEW (view));
2728 for (p = view->selected_object_list; p != NULL; p = p->next) {
2730 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2731 gl_label_object_set_fill_color (object, fill_color);
2735 gl_debug (DEBUG_VIEW, "END");
2738 /*****************************************************************************/
2739 /* Can line color properties be set for selection? */
2740 /*****************************************************************************/
2742 gl_view_can_selection_line_color (glView *view)
2745 glLabelObject *object;
2747 gl_debug (DEBUG_VIEW, "");
2749 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2751 for (p = view->selected_object_list; p != NULL; p = p->next) {
2753 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2754 if (gl_label_object_can_line_color (object)) {
2763 /*****************************************************************************/
2764 /* Set line color for all selected objects. */
2765 /*****************************************************************************/
2767 gl_view_set_selection_line_color (glView *view,
2771 glLabelObject *object;
2773 gl_debug (DEBUG_VIEW, "START");
2775 g_return_if_fail (view && GL_IS_VIEW (view));
2777 for (p = view->selected_object_list; p != NULL; p = p->next) {
2779 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2780 gl_label_object_set_line_color (object, line_color);
2784 gl_debug (DEBUG_VIEW, "END");
2787 /*****************************************************************************/
2788 /* Can line width properties be set for selection? */
2789 /*****************************************************************************/
2791 gl_view_can_selection_line_width (glView *view)
2794 glLabelObject *object;
2796 gl_debug (DEBUG_VIEW, "");
2798 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2800 for (p = view->selected_object_list; p != NULL; p = p->next) {
2802 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2803 if (gl_label_object_can_line_width (object)) {
2812 /*****************************************************************************/
2813 /* Set line width for all selected objects. */
2814 /*****************************************************************************/
2816 gl_view_set_selection_line_width (glView *view,
2820 glLabelObject *object;
2822 gl_debug (DEBUG_VIEW, "START");
2824 g_return_if_fail (view && GL_IS_VIEW (view));
2826 for (p = view->selected_object_list; p != NULL; p = p->next) {
2828 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2829 gl_label_object_set_line_width (object, line_width);
2833 gl_debug (DEBUG_VIEW, "END");
2836 /*****************************************************************************/
2837 /* "Cut" selected items and place in clipboard selections. */
2838 /*****************************************************************************/
2840 gl_view_cut (glView *view)
2842 gl_debug (DEBUG_VIEW, "START");
2844 g_return_if_fail (view && GL_IS_VIEW (view));
2846 gl_view_copy (view);
2847 gl_view_delete_selection (view);
2849 gl_debug (DEBUG_VIEW, "END");
2852 /*****************************************************************************/
2853 /* "Copy" selected items to clipboard selections. */
2854 /*****************************************************************************/
2856 gl_view_copy (glView *view)
2859 glViewObject *view_object;
2860 glLabelObject *object;
2861 glTemplate *template;
2862 gboolean rotate_flag;
2864 gl_debug (DEBUG_VIEW, "START");
2866 g_return_if_fail (view && GL_IS_VIEW (view));
2868 if (view->selected_object_list) {
2870 if ( view->selection_data ) {
2871 g_object_unref (view->selection_data);
2873 template = gl_label_get_template (view->label);
2874 rotate_flag = gl_label_get_rotate_flag (view->label);
2875 view->selection_data = GL_LABEL(gl_label_new ());
2876 gl_label_set_template (view->selection_data, template);
2877 gl_label_set_rotate_flag (view->selection_data, rotate_flag);
2878 gl_template_free (&template);
2880 for (p = view->selected_object_list; p != NULL; p = p->next) {
2882 view_object = GL_VIEW_OBJECT (p->data);
2883 object = gl_view_object_get_object (view_object);
2885 gl_label_object_dup (object, view->selection_data);
2889 gtk_selection_owner_set (view->invisible,
2890 clipboard_atom, GDK_CURRENT_TIME);
2891 view->have_selection = TRUE;
2895 gl_debug (DEBUG_VIEW, "END");
2898 /*****************************************************************************/
2899 /* "Paste" from private clipboard selection. */
2900 /*****************************************************************************/
2902 gl_view_paste (glView *view)
2904 gl_debug (DEBUG_VIEW, "START");
2906 g_return_if_fail (view && GL_IS_VIEW (view));
2908 gtk_selection_convert (GTK_WIDGET (view->invisible),
2909 clipboard_atom, GDK_SELECTION_TYPE_STRING,
2912 gl_debug (DEBUG_VIEW, "END");
2915 /*****************************************************************************/
2916 /* Zoom in one "notch" */
2917 /*****************************************************************************/
2919 gl_view_zoom_in (glView *view)
2922 gdouble dist, dist_min;
2924 gl_debug (DEBUG_VIEW, "START");
2926 g_return_if_fail (view && GL_IS_VIEW (view));
2928 /* Find index of current scale (or best match) */
2929 i_min = 1; /* start with 2nd largest scale */
2930 dist_min = fabs (scales[1] - view->scale);
2931 for (i = 2; i < N_SCALES; i++) {
2932 dist = fabs (scales[i] - view->scale);
2933 if (dist < dist_min) {
2939 /* zoom in one "notch" */
2940 i = MAX (0, i_min - 1);
2941 gl_view_set_zoom (view, scales[i] / HOME_SCALE);
2943 gl_debug (DEBUG_VIEW, "END");
2946 /*****************************************************************************/
2947 /* Zoom out one "notch" */
2948 /*****************************************************************************/
2950 gl_view_zoom_out (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 = 0; /* start with largest scale */
2961 dist_min = fabs (scales[0] - view->scale);
2962 for (i = 1; i < N_SCALES; i++) {
2963 dist = fabs (scales[i] - view->scale);
2964 if (dist < dist_min) {
2970 /* zoom out one "notch" */
2971 if (i_min >= N_SCALES)
2976 gl_view_set_zoom (view, scales[i] / HOME_SCALE);
2978 gl_debug (DEBUG_VIEW, "END");
2981 /*****************************************************************************/
2982 /* Set current zoom factor to explicit value. */
2983 /*****************************************************************************/
2985 gl_view_set_zoom (glView *view,
2988 gl_debug (DEBUG_VIEW, "START");
2990 g_return_if_fail (view && GL_IS_VIEW (view));
2991 g_return_if_fail (scale > 0.0);
2993 view->scale = scale * HOME_SCALE;
2994 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
2995 scale * HOME_SCALE);
2997 g_signal_emit (G_OBJECT(view), signals[ZOOM_CHANGED], 0, scale);
2999 gl_debug (DEBUG_VIEW, "END");
3002 /*****************************************************************************/
3003 /* Get current zoom factor. */
3004 /*****************************************************************************/
3006 gl_view_get_zoom (glView *view)
3008 gl_debug (DEBUG_VIEW, "");
3010 g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
3012 return view->scale / HOME_SCALE;
3015 /*****************************************************************************/
3016 /* Is this the maximum zoom level. */
3017 /*****************************************************************************/
3019 gl_view_is_zoom_max (glView *view)
3021 gl_debug (DEBUG_VIEW, "");
3023 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
3025 return view->scale >= scales[0];
3028 /*****************************************************************************/
3029 /* Is this the minimum zoom level. */
3030 /*****************************************************************************/
3032 gl_view_is_zoom_min (glView *view)
3034 gl_debug (DEBUG_VIEW, "");
3036 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3038 return view->scale <= scales[N_SCALES-1];
3041 /*****************************************************************************/
3042 /* Launch merge properties dialog. */
3043 /*****************************************************************************/
3045 gl_view_edit_merge_props (glView *view)
3047 gl_debug (DEBUG_VIEW, "");
3049 g_return_if_fail (view && GL_IS_VIEW (view));
3051 if (view->merge_props_dialog != NULL) {
3052 gtk_widget_show_all (view->merge_props_dialog);
3053 gtk_window_present (GTK_WINDOW(view->merge_props_dialog));
3057 view->merge_props_dialog = gl_merge_properties_dialog_new (view);
3058 gtk_widget_show_all (view->merge_props_dialog);
3060 g_signal_connect (G_OBJECT(view->merge_props_dialog), "destroy",
3061 G_CALLBACK (gtk_widget_destroyed),
3062 &view->merge_props_dialog);
3065 /*---------------------------------------------------------------------------*/
3066 /* PRIVATE. Canvas event handler. */
3067 /*---------------------------------------------------------------------------*/
3069 canvas_event (GnomeCanvas *canvas,
3075 gl_debug (DEBUG_VIEW, "");
3077 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3079 /* emit pointer signals regardless of state */
3080 switch (event->type) {
3081 case GDK_MOTION_NOTIFY:
3082 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
3083 gnome_canvas_window_to_world (canvas,
3085 event->motion.y, &x, &y);
3086 g_signal_emit (G_OBJECT(view), signals[POINTER_MOVED], 0, x, y);
3087 break; /* fall through */
3089 case GDK_LEAVE_NOTIFY:
3090 gl_debug (DEBUG_VIEW, "LEAVEW_NOTIFY");
3091 g_signal_emit (G_OBJECT(view), signals[POINTER_EXIT], 0);
3092 break; /* fall through */
3095 break; /* fall through */
3099 switch (view->state) {
3101 case GL_VIEW_STATE_ARROW:
3102 return canvas_event_arrow_mode (canvas, event, view);
3104 case GL_VIEW_STATE_OBJECT_CREATE:
3105 switch (view->create_type) {
3106 case GL_LABEL_OBJECT_BOX:
3107 return gl_view_box_create_event_handler (canvas,
3111 case GL_LABEL_OBJECT_ELLIPSE:
3112 return gl_view_ellipse_create_event_handler (canvas,
3116 case GL_LABEL_OBJECT_LINE:
3117 return gl_view_line_create_event_handler (canvas,
3121 case GL_LABEL_OBJECT_IMAGE:
3122 return gl_view_image_create_event_handler (canvas,
3126 case GL_LABEL_OBJECT_TEXT:
3127 return gl_view_text_create_event_handler (canvas,
3131 case GL_LABEL_OBJECT_BARCODE:
3132 return gl_view_barcode_create_event_handler (canvas,
3137 /*Should not happen!*/
3138 g_warning ("Invalid label object type.");
3143 g_warning ("Invalid view state."); /*Should not happen!*/
3149 /*---------------------------------------------------------------------------*/
3150 /* PRIVATE. Canvas event handler (arrow mode) */
3151 /*---------------------------------------------------------------------------*/
3153 canvas_event_arrow_mode (GnomeCanvas *canvas,
3157 static gdouble x0, y0;
3158 static gboolean dragging = FALSE;
3159 static GnomeCanvasItem *item;
3160 gdouble x, y, x1, y1, x2, y2;
3161 GnomeCanvasGroup *group;
3164 gl_debug (DEBUG_VIEW, "");
3166 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3168 switch (event->type) {
3170 case GDK_BUTTON_PRESS:
3171 gl_debug (DEBUG_VIEW, "BUTTON_PRESS");
3172 switch (event->button.button) {
3174 gnome_canvas_window_to_world (canvas,
3176 event->button.y, &x, &y);
3178 if (!object_at (view, x, y)) {
3179 if (!(event->button.state & GDK_CONTROL_MASK)) {
3180 gl_view_unselect_all (view);
3184 gnome_canvas_item_grab (canvas->root,
3185 GDK_POINTER_MOTION_MASK |
3186 GDK_BUTTON_RELEASE_MASK |
3187 GDK_BUTTON_PRESS_MASK,
3188 NULL, event->button.time);
3190 gnome_canvas_root (GNOME_CANVAS
3193 gnome_canvas_item_new (group,
3194 gnome_canvas_rect_get_type (),
3198 "outline_color_rgba",
3209 gnome_canvas_window_to_world (canvas,
3211 event->button.y, &x, &y);
3213 if (!object_at (view, x, y)) {
3214 /* bring up apropriate menu for selection. */
3215 gl_view_popup_menu (view, event);
3222 case GDK_BUTTON_RELEASE:
3223 gl_debug (DEBUG_VIEW, "BUTTON_RELEASE");
3224 switch (event->button.button) {
3228 gnome_canvas_item_ungrab (canvas->root,
3229 event->button.time);
3230 gnome_canvas_window_to_world (canvas,
3238 gl_view_select_region (view, x1, y1, x2, y2);
3239 gtk_object_destroy (GTK_OBJECT (item));
3248 case GDK_MOTION_NOTIFY:
3249 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
3250 gnome_canvas_window_to_world (canvas,
3252 event->motion.y, &x, &y);
3253 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
3254 gnome_canvas_item_set (item,
3258 "y2", MAX (y, y0), NULL);
3265 gl_debug (DEBUG_VIEW, "KEY_PRESS");
3267 switch (event->key.keyval) {
3270 gl_view_move_selection (view,
3271 -1.0 / (view->scale), 0.0);
3275 gl_view_move_selection (view,
3276 0.0, -1.0 / (view->scale));
3280 gl_view_move_selection (view,
3281 1.0 / (view->scale), 0.0);
3285 gl_view_move_selection (view,
3286 0.0, 1.0 / (view->scale));
3290 gl_view_delete_selection (view);
3291 cursor = gdk_cursor_new (GDK_LEFT_PTR);
3292 gdk_window_set_cursor (view->canvas->window,
3294 gdk_cursor_unref (cursor);
3300 return TRUE; /* We handled this or we were dragging. */
3303 gl_debug (DEBUG_VIEW, "default");
3309 /*---------------------------------------------------------------------------*/
3310 /* PRIVATE. create menu for selections. */
3311 /*---------------------------------------------------------------------------*/
3313 construct_selection_menu (glView *view)
3315 GtkWidget *menu, *menuitem, *submenu;
3317 gl_debug (DEBUG_VIEW, "START");
3319 g_return_if_fail (view && GL_IS_VIEW (view));
3321 menu = gtk_menu_new ();
3323 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_PROPERTIES, NULL);
3324 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3325 gtk_widget_show (menuitem);
3326 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3327 G_CALLBACK (gl_view_edit_object_props), view);
3328 view->atomic_selection_items =
3329 g_list_prepend (view->atomic_selection_items, menuitem);
3332 * Separator -------------------------
3334 menuitem = gtk_menu_item_new ();
3335 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3336 gtk_widget_show (menuitem);
3341 menuitem = gtk_menu_item_new_with_mnemonic (_("_Order"));
3342 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3343 gtk_widget_show (menuitem);
3344 submenu = gtk_menu_new ();
3345 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3347 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ORDER_TOP, NULL);
3348 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3349 gtk_widget_show (menuitem);
3350 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3351 G_CALLBACK (gl_view_raise_selection), view);
3353 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ORDER_BOTTOM, NULL);
3354 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3355 gtk_widget_show (menuitem);
3356 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3357 G_CALLBACK (gl_view_lower_selection), view);
3360 * Submenu: Rotate/Flip
3362 menuitem = gtk_menu_item_new_with_mnemonic (_("_Rotate/Flip"));
3363 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3364 gtk_widget_show (menuitem);
3365 submenu = gtk_menu_new ();
3366 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3368 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ROTATE_LEFT, NULL);
3369 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3370 gtk_widget_show (menuitem);
3371 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3372 G_CALLBACK (gl_view_rotate_selection_left), view);
3374 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ROTATE_RIGHT, NULL);
3375 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3376 gtk_widget_show (menuitem);
3377 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3378 G_CALLBACK (gl_view_rotate_selection_right), view);
3380 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_FLIP_HORIZ, NULL);
3381 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3382 gtk_widget_show (menuitem);
3383 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3384 G_CALLBACK (gl_view_flip_selection_horiz), view);
3386 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_FLIP_VERT, NULL);
3387 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3388 gtk_widget_show (menuitem);
3389 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3390 G_CALLBACK (gl_view_flip_selection_vert), view);
3393 * Submenu: Align Horizontally
3395 menuitem = gtk_menu_item_new_with_mnemonic (_("Align _Horizontally"));
3396 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3397 gtk_widget_show (menuitem);
3398 submenu = gtk_menu_new ();
3399 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3401 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_LEFT, NULL);
3402 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3403 gtk_widget_show (menuitem);
3404 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3405 G_CALLBACK (gl_view_align_selection_left), view);
3406 view->multi_selection_items =
3407 g_list_prepend (view->multi_selection_items, menuitem);
3409 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_HCENTER, NULL);
3410 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3411 gtk_widget_show (menuitem);
3412 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3413 G_CALLBACK (gl_view_align_selection_hcenter), view);
3414 view->multi_selection_items =
3415 g_list_prepend (view->multi_selection_items, menuitem);
3417 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_RIGHT, 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_align_selection_right), view);
3422 view->multi_selection_items =
3423 g_list_prepend (view->multi_selection_items, menuitem);
3425 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_CENTER_HORIZ, NULL);
3426 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3427 gtk_widget_show (menuitem);
3428 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3429 G_CALLBACK (gl_view_center_selection_horiz), view);
3432 * Submenu: Align Vertically
3434 menuitem = gtk_menu_item_new_with_mnemonic (_("Align _Vertically"));
3435 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3436 gtk_widget_show (menuitem);
3437 submenu = gtk_menu_new ();
3438 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3440 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_TOP, 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_top), 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_VCENTER, 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_vcenter), 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_ALIGN_BOTTOM, 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_align_selection_bottom), view);
3461 view->multi_selection_items =
3462 g_list_prepend (view->multi_selection_items, menuitem);
3464 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_CENTER_VERT, NULL);
3465 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3466 gtk_widget_show (menuitem);
3467 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3468 G_CALLBACK (gl_view_center_selection_vert), view);
3471 * Separator -------------------------
3473 menuitem = gtk_menu_item_new ();
3474 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3475 gtk_widget_show (menuitem);
3477 menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_CUT, NULL);
3478 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3479 gtk_widget_show (menuitem);
3480 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3481 G_CALLBACK (gl_view_cut), view);
3483 menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_COPY, NULL);
3484 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3485 gtk_widget_show (menuitem);
3486 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3487 G_CALLBACK (gl_view_copy), view);
3489 menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_PASTE, NULL);
3490 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3491 gtk_widget_show (menuitem);
3492 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3493 G_CALLBACK (gl_view_paste), view);
3495 menuitem = gtk_menu_item_new_with_mnemonic (_("_Delete"));
3496 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3497 gtk_widget_show (menuitem);
3498 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3499 G_CALLBACK (gl_view_delete_selection), view);
3502 view->selection_menu = menu;
3504 gl_debug (DEBUG_VIEW, "END");
3507 /*---------------------------------------------------------------------------*/
3508 /* PRIVATE. create menu for empty selections. */
3509 /*---------------------------------------------------------------------------*/
3511 construct_empty_selection_menu (glView *view)
3513 GtkWidget *menu, *menuitem, *submenu;
3515 gl_debug (DEBUG_VIEW, "START");
3517 g_return_if_fail (view && GL_IS_VIEW (view));
3519 menu = gtk_menu_new ();
3521 menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_PASTE, NULL);
3522 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3523 gtk_widget_show (menuitem);
3524 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3525 G_CALLBACK (gl_view_paste), view);
3528 view->empty_selection_menu = menu;
3530 gl_debug (DEBUG_VIEW, "END");
3533 /****************************************************************************/
3535 /****************************************************************************/
3537 gl_view_popup_menu (glView *view,
3543 gl_debug (DEBUG_VIEW, "START");
3545 g_return_if_fail (view && GL_IS_VIEW (view));
3547 if (gl_view_is_selection_empty (view)) {
3549 if (view->empty_selection_menu != NULL) {
3550 gtk_menu_popup (GTK_MENU (view->empty_selection_menu),
3551 NULL, NULL, NULL, NULL,
3552 event->button.button,
3553 event->button.time);
3558 for (p=view->atomic_selection_items; p!=NULL; p=p->next) {
3559 gtk_widget_set_sensitive (GTK_WIDGET(p->data),
3560 gl_view_is_selection_atomic(view));
3563 for (p=view->multi_selection_items; p!=NULL; p=p->next) {
3564 gtk_widget_set_sensitive (GTK_WIDGET(p->data),
3565 !gl_view_is_selection_atomic(view));
3568 if (view->selection_menu != NULL) {
3569 gtk_menu_popup (GTK_MENU (view->selection_menu),
3570 NULL, NULL, NULL, NULL,
3571 event->button.button,
3572 event->button.time);
3577 gl_debug (DEBUG_VIEW, "END");
3580 /*---------------------------------------------------------------------------*/
3581 /* PRIVATE. Handle "selection-clear" signal. */
3582 /*---------------------------------------------------------------------------*/
3584 selection_clear_cb (GtkWidget *widget,
3585 GdkEventSelection *event,
3588 glView *view = GL_VIEW (data);
3590 gl_debug (DEBUG_VIEW, "START");
3592 g_return_if_fail (view && GL_IS_VIEW (view));
3594 view->have_selection = FALSE;
3595 g_object_unref (view->selection_data);
3596 view->selection_data = NULL;
3598 gl_debug (DEBUG_VIEW, "END");
3601 /*---------------------------------------------------------------------------*/
3602 /* PRIVATE. Handle "selection-get" signal. */
3603 /*---------------------------------------------------------------------------*/
3605 selection_get_cb (GtkWidget *widget,
3606 GtkSelectionData *selection_data,
3611 glView *view = GL_VIEW (data);
3613 glXMLLabelStatus status;
3615 gl_debug (DEBUG_VIEW, "START");
3617 g_return_if_fail (view && GL_IS_VIEW (view));
3619 if (view->have_selection) {
3621 buffer = gl_xml_label_save_buffer (view->selection_data,
3623 gtk_selection_data_set (selection_data,
3624 GDK_SELECTION_TYPE_STRING, 8, buffer,
3629 gl_debug (DEBUG_VIEW, "END");
3632 /*---------------------------------------------------------------------------*/
3633 /* PRIVATE. Handle "selection-received" signal. (Result of Paste) */
3634 /*---------------------------------------------------------------------------*/
3636 selection_received_cb (GtkWidget *widget,
3637 GtkSelectionData *selection_data,
3641 glView *view = GL_VIEW (data);
3642 glLabel *label = NULL;
3643 glXMLLabelStatus status;
3645 glLabelObject *object, *newobject;
3646 glViewObject *view_object;
3648 gl_debug (DEBUG_VIEW, "START");
3650 g_return_if_fail (view && GL_IS_VIEW (view));
3652 if (selection_data->length < 0) {
3655 if (selection_data->type != GDK_SELECTION_TYPE_STRING) {
3659 gl_view_unselect_all (view);
3661 label = gl_xml_label_open_buffer (selection_data->data, &status);
3662 for (p = label->objects; p != NULL; p = p_next) {
3665 object = (glLabelObject *) p->data;
3666 newobject = gl_label_object_dup (object, view->label);
3668 gl_debug (DEBUG_VIEW, "object pasted");
3670 if (GL_IS_LABEL_BOX (newobject)) {
3671 view_object = gl_view_box_new (GL_LABEL_BOX(newobject),
3673 } else if (GL_IS_LABEL_ELLIPSE (newobject)) {
3674 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(newobject),
3676 } else if (GL_IS_LABEL_LINE (newobject)) {
3677 view_object = gl_view_line_new (GL_LABEL_LINE(newobject),
3679 } else if (GL_IS_LABEL_IMAGE (newobject)) {
3680 view_object = gl_view_image_new (GL_LABEL_IMAGE(newobject),
3682 } else if (GL_IS_LABEL_TEXT (newobject)) {
3683 view_object = gl_view_text_new (GL_LABEL_TEXT(newobject),
3685 } else if (GL_IS_LABEL_BARCODE (newobject)) {
3686 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(newobject),
3689 /* Should not happen! */
3691 g_warning ("Invalid label object type.");
3693 gl_view_select_object (view, view_object);
3695 g_object_unref (label);
3697 gl_debug (DEBUG_VIEW, "END");
3700 /****************************************************************************/
3701 /* Set default font family. */
3702 /****************************************************************************/
3704 gl_view_set_default_font_family (glView *view,
3705 const gchar *font_family)
3707 gl_debug (DEBUG_VIEW, "START");
3709 g_return_if_fail (view && GL_IS_VIEW (view));
3711 if (view->default_font_family) {
3712 g_free (view->default_font_family);
3714 view->default_font_family = g_strdup (font_family);
3716 gl_debug (DEBUG_VIEW, "END");
3720 /****************************************************************************/
3721 /* Set default font size. */
3722 /****************************************************************************/
3724 gl_view_set_default_font_size (glView *view,
3727 gl_debug (DEBUG_VIEW, "START");
3729 g_return_if_fail (view && GL_IS_VIEW (view));
3731 view->default_font_size = font_size;
3733 gl_debug (DEBUG_VIEW, "END");
3737 /****************************************************************************/
3738 /* Set default font weight. */
3739 /****************************************************************************/
3741 gl_view_set_default_font_weight (glView *view,
3742 GnomeFontWeight font_weight)
3744 gl_debug (DEBUG_VIEW, "START");
3746 g_return_if_fail (view && GL_IS_VIEW (view));
3748 view->default_font_weight = font_weight;
3750 gl_debug (DEBUG_VIEW, "END");
3754 /****************************************************************************/
3755 /* Set default font italic flag. */
3756 /****************************************************************************/
3758 gl_view_set_default_font_italic_flag (glView *view,
3759 gboolean font_italic_flag)
3761 gl_debug (DEBUG_VIEW, "START");
3763 g_return_if_fail (view && GL_IS_VIEW (view));
3765 view->default_font_italic_flag = font_italic_flag;
3767 gl_debug (DEBUG_VIEW, "END");
3771 /****************************************************************************/
3772 /* Set default text color. */
3773 /****************************************************************************/
3775 gl_view_set_default_text_color (glView *view,
3778 gl_debug (DEBUG_VIEW, "START");
3780 g_return_if_fail (view && GL_IS_VIEW (view));
3782 view->default_text_color = text_color;
3784 gl_debug (DEBUG_VIEW, "END");
3788 /****************************************************************************/
3789 /* Set default text alignment. */
3790 /****************************************************************************/
3792 gl_view_set_default_text_alignment (glView *view,
3793 GtkJustification text_alignment)
3795 gl_debug (DEBUG_VIEW, "START");
3797 g_return_if_fail (view && GL_IS_VIEW (view));
3799 view->default_text_alignment = text_alignment;
3800 gl_debug (DEBUG_VIEW, "END");
3804 /****************************************************************************/
3805 /* Set default line width. */
3806 /****************************************************************************/
3808 gl_view_set_default_line_width (glView *view,
3811 gl_debug (DEBUG_VIEW, "START");
3813 g_return_if_fail (view && GL_IS_VIEW (view));
3815 view->default_line_width = line_width;
3817 gl_debug (DEBUG_VIEW, "END");
3821 /****************************************************************************/
3822 /* Set default line color. */
3823 /****************************************************************************/
3825 gl_view_set_default_line_color (glView *view,
3828 gl_debug (DEBUG_VIEW, "START");
3830 g_return_if_fail (view && GL_IS_VIEW (view));
3832 view->default_line_color = line_color;
3834 gl_debug (DEBUG_VIEW, "END");
3838 /****************************************************************************/
3839 /* Set default fill color. */
3840 /****************************************************************************/
3842 gl_view_set_default_fill_color (glView *view,
3845 gl_debug (DEBUG_VIEW, "START");
3847 g_return_if_fail (view && GL_IS_VIEW (view));
3849 view->default_fill_color = fill_color;
3851 gl_debug (DEBUG_VIEW, "END");
3856 /****************************************************************************/
3857 /* Get default font family. */
3858 /****************************************************************************/
3860 gl_view_get_default_font_family (glView *view)
3862 gl_debug (DEBUG_VIEW, "START");
3864 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
3866 gl_debug (DEBUG_VIEW, "END");
3868 return g_strdup (view->default_font_family);
3872 /****************************************************************************/
3873 /* Get default font size. */
3874 /****************************************************************************/
3876 gl_view_get_default_font_size (glView *view)
3878 gl_debug (DEBUG_VIEW, "START");
3880 g_return_val_if_fail (view && GL_IS_VIEW (view), 12.0);
3882 gl_debug (DEBUG_VIEW, "END");
3884 return view->default_font_size;
3888 /****************************************************************************/
3889 /* Get default font weight. */
3890 /****************************************************************************/
3892 gl_view_get_default_font_weight (glView *view)
3894 gl_debug (DEBUG_VIEW, "START");
3896 g_return_val_if_fail (view && GL_IS_VIEW (view), GNOME_FONT_BOOK);
3898 gl_debug (DEBUG_VIEW, "END");
3900 return view->default_font_weight;
3904 /****************************************************************************/
3905 /* Get default font italic flag. */
3906 /****************************************************************************/
3908 gl_view_get_default_font_italic_flag (glView *view)
3910 gl_debug (DEBUG_VIEW, "START");
3912 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3914 gl_debug (DEBUG_VIEW, "END");
3916 return view->default_font_italic_flag;
3920 /****************************************************************************/
3921 /* Get default text color. */
3922 /****************************************************************************/
3924 gl_view_get_default_text_color (glView *view)
3926 gl_debug (DEBUG_VIEW, "START");
3928 g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
3930 gl_debug (DEBUG_VIEW, "END");
3932 return view->default_text_color;
3936 /****************************************************************************/
3937 /* Get default text alignment. */
3938 /****************************************************************************/
3940 gl_view_get_default_text_alignment (glView *view)
3942 gl_debug (DEBUG_VIEW, "START");
3944 g_return_val_if_fail (view && GL_IS_VIEW (view), GTK_JUSTIFY_LEFT);
3946 gl_debug (DEBUG_VIEW, "END");
3948 return view->default_text_alignment;
3952 /****************************************************************************/
3953 /* Get default line width. */
3954 /****************************************************************************/
3956 gl_view_get_default_line_width (glView *view)
3958 gl_debug (DEBUG_VIEW, "START");
3960 g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
3962 gl_debug (DEBUG_VIEW, "END");
3964 return view->default_line_width;
3968 /****************************************************************************/
3969 /* Get default line color. */
3970 /****************************************************************************/
3971 guint gl_view_get_default_line_color (glView *view)
3973 gl_debug (DEBUG_VIEW, "START");
3975 g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
3977 gl_debug (DEBUG_VIEW, "END");
3979 return view->default_line_color;
3983 /****************************************************************************/
3984 /* Get default fill color. */
3985 /****************************************************************************/
3986 guint gl_view_get_default_fill_color (glView *view)
3988 gl_debug (DEBUG_VIEW, "START");
3990 g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
3992 gl_debug (DEBUG_VIEW, "END");
3994 return view->default_fill_color;