1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
4 * (GLABELS) Label and Business Card Creation program for GNOME
6 * view.c: GLabels View module
8 * Copyright (C) 2001-2005 Jim Evins <evins@snaught.com>.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include <glib/gi18n.h>
30 #include <gtk/gtkscrolledwindow.h>
31 #include <gtk/gtkselection.h>
32 #include <gtk/gtkinvisible.h>
33 #include <gdk/gdkkeysyms.h>
37 #include "view-object.h"
39 #include "view-ellipse.h"
40 #include "view-line.h"
41 #include "view-image.h"
42 #include "view-text.h"
43 #include "view-barcode.h"
44 #include "xml-label.h"
51 /*==========================================================================*/
52 /* Private macros and constants. */
53 /*==========================================================================*/
55 #define BG_COLOR GL_COLOR (192, 192, 192)
56 #define OUTLINE_COLOR GL_COLOR (173, 216, 230)
57 #define PAPER_COLOR GL_COLOR (255, 255, 255)
58 #define GRID_COLOR BG_COLOR
59 #define MARKUP_COLOR GL_COLOR (240, 100, 100)
61 #define SEL_LINE_COLOR GL_COLOR_A (0, 0, 255, 128)
62 #define SEL_FILL_COLOR GL_COLOR_A (192, 192, 255, 128)
64 #define ARC_FINE 2 /* Resolution in degrees of large arcs */
65 #define ARC_COURSE 5 /* Resolution in degrees of small arcs */
67 #define ZOOMTOFIT_PAD 16
69 #define POINTS_PER_MM 2.83464566929
73 /*==========================================================================*/
75 /*==========================================================================*/
79 CONTEXT_MENU_ACTIVATE,
88 /*==========================================================================*/
90 /*==========================================================================*/
92 static GtkContainerClass *parent_class;
94 static guint signals[LAST_SIGNAL] = {0};
96 /* "CLIPBOARD" selection */
97 static GdkAtom clipboard_atom = GDK_NONE;
99 static gdouble zooms[] = {
116 #define N_ZOOMS G_N_ELEMENTS(zooms)
119 /*==========================================================================*/
120 /* Local function prototypes */
121 /*==========================================================================*/
123 static void gl_view_class_init (glViewClass *class);
124 static void gl_view_init (glView *view);
125 static void gl_view_finalize (GObject *object);
127 static void gl_view_construct (glView *view);
128 static GtkWidget *gl_view_construct_canvas (glView *view);
129 static void gl_view_construct_selection (glView *view);
131 static gdouble get_home_scale (glView *view);
133 static void draw_layers (glView *view);
135 static void label_resized_cb (glLabel *label,
138 static void draw_label_layer (glView *view);
140 static void draw_highlight_layer (glView *view);
142 static void draw_bg_fg_layers (glView *view);
143 static void draw_bg_fg_rect (glView *view);
144 static void draw_bg_fg_rounded_rect (glView *view);
145 static void draw_bg_fg_round (glView *view);
146 static void draw_bg_fg_cd (glView *view);
147 static void draw_bg_fg_cd_bc (glView *view);
149 static void draw_grid_layer (glView *view);
151 static void draw_markup_layer (glView *view);
153 static void draw_markup_margin (glView *view,
154 glTemplateMarkup *margin);
155 static void draw_markup_margin_rect (glView *view,
156 glTemplateMarkup *margin);
157 static void draw_markup_margin_rounded_rect (glView *view,
158 glTemplateMarkup *margin);
159 static void draw_markup_margin_round (glView *view,
160 glTemplateMarkup *margin);
161 static void draw_markup_margin_cd (glView *view,
162 glTemplateMarkup *margin);
163 static void draw_markup_margin_cd_bc (glView *view,
164 glTemplateMarkup *margin);
166 static void draw_markup_line (glView *view,
167 glTemplateMarkup *line);
169 static void draw_markup_circle (glView *view,
170 glTemplateMarkup *circle);
173 static void select_object_real (glView *view,
174 glViewObject *view_object);
175 static void unselect_object_real (glView *view,
176 glViewObject *view_object);
178 static gboolean object_at (glView *view,
179 gdouble x, gdouble y);
181 static gboolean is_item_member_of_group (glView *view,
182 GnomeCanvasItem *item,
183 GnomeCanvasItem *group);
185 static void set_zoom_real (glView *view,
187 gboolean scale_to_fit_flag);
189 static void size_allocate_cb (glView *view);
191 static void screen_changed_cb (glView *view);
193 static int canvas_event (GnomeCanvas *canvas,
196 static int canvas_event_arrow_mode (GnomeCanvas *canvas,
200 static void selection_clear_cb (GtkWidget *widget,
201 GdkEventSelection *event,
204 static void selection_get_cb (GtkWidget *widget,
205 GtkSelectionData *selection_data,
210 static void selection_received_cb (GtkWidget *widget,
211 GtkSelectionData *selection_data,
215 /****************************************************************************/
216 /* Boilerplate Object stuff. */
217 /****************************************************************************/
219 gl_view_get_type (void)
221 static GType type = 0;
224 static const GTypeInfo info = {
225 sizeof (glViewClass),
228 (GClassInitFunc) gl_view_class_init,
233 (GInstanceInitFunc) gl_view_init,
237 type = g_type_register_static (GTK_TYPE_VBOX,
245 gl_view_class_init (glViewClass *class)
247 GObjectClass *object_class = (GObjectClass *) class;
249 gl_debug (DEBUG_VIEW, "START");
251 parent_class = g_type_class_peek_parent (class);
253 object_class->finalize = gl_view_finalize;
255 signals[SELECTION_CHANGED] =
256 g_signal_new ("selection_changed",
257 G_OBJECT_CLASS_TYPE (object_class),
259 G_STRUCT_OFFSET (glViewClass, selection_changed),
261 gl_marshal_VOID__VOID,
265 signals[CONTEXT_MENU_ACTIVATE] =
266 g_signal_new ("context_menu_activate",
267 G_OBJECT_CLASS_TYPE (object_class),
269 G_STRUCT_OFFSET (glViewClass, context_menu_activate),
271 gl_marshal_VOID__INT_UINT,
273 2, G_TYPE_INT, G_TYPE_UINT);
275 signals[ZOOM_CHANGED] =
276 g_signal_new ("zoom_changed",
277 G_OBJECT_CLASS_TYPE (object_class),
279 G_STRUCT_OFFSET (glViewClass, zoom_changed),
281 gl_marshal_VOID__DOUBLE,
285 signals[POINTER_MOVED] =
286 g_signal_new ("pointer_moved",
287 G_OBJECT_CLASS_TYPE (object_class),
289 G_STRUCT_OFFSET (glViewClass, pointer_moved),
291 gl_marshal_VOID__DOUBLE_DOUBLE,
293 2, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
295 signals[POINTER_EXIT] =
296 g_signal_new ("pointer_exit",
297 G_OBJECT_CLASS_TYPE (object_class),
299 G_STRUCT_OFFSET (glViewClass, pointer_exit),
301 gl_marshal_VOID__VOID,
305 signals[MODE_CHANGED] =
306 g_signal_new ("mode_changed",
307 G_OBJECT_CLASS_TYPE (object_class),
309 G_STRUCT_OFFSET (glViewClass, mode_changed),
311 gl_marshal_VOID__VOID,
315 gl_debug (DEBUG_VIEW, "END");
319 gl_view_init (glView *view)
321 gl_debug (DEBUG_VIEW, "START");
325 view->grid_spacing = 9;
327 view->default_font_family = NULL;
329 gl_debug (DEBUG_VIEW, "END");
333 gl_view_finalize (GObject *object)
337 gl_debug (DEBUG_VIEW, "START");
339 g_return_if_fail (object != NULL);
340 g_return_if_fail (GL_IS_VIEW (object));
342 view = GL_VIEW (object);
344 G_OBJECT_CLASS (parent_class)->finalize (object);
346 gl_debug (DEBUG_VIEW, "END");
349 /****************************************************************************/
350 /* NEW view object. */
351 /****************************************************************************/
353 gl_view_new (glLabel *label)
357 gl_debug (DEBUG_VIEW, "START");
359 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
361 view = g_object_new (gl_view_get_type (), NULL);
364 gl_view_construct (view);
366 gl_debug (DEBUG_VIEW, "END");
368 return GTK_WIDGET (view);
371 /*---------------------------------------------------------------------------*/
372 /* PRIVATE. Construct composite widget. */
373 /*---------------------------------------------------------------------------*/
375 gl_view_construct (glView *view)
377 GtkWidget *wvbox, *wscroll;
379 gl_debug (DEBUG_VIEW, "START");
381 g_return_if_fail (GL_IS_VIEW (view));
383 wvbox = GTK_WIDGET (view);
385 view->state = GL_VIEW_STATE_ARROW;
386 view->object_list = NULL;
388 gl_view_construct_canvas (view);
389 wscroll = gtk_scrolled_window_new (NULL, NULL);
390 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (wscroll),
391 GTK_POLICY_AUTOMATIC,
392 GTK_POLICY_AUTOMATIC);
393 gtk_box_pack_start (GTK_BOX (wvbox), wscroll, TRUE, TRUE, 0);
394 gtk_container_add (GTK_CONTAINER (wscroll), view->canvas);
396 gl_view_construct_selection (view);
398 gl_view_set_default_font_family (view, gl_prefs->default_font_family);
399 gl_view_set_default_font_size (view, gl_prefs->default_font_size);
400 gl_view_set_default_font_weight (view, gl_prefs->default_font_weight);
401 gl_view_set_default_font_italic_flag (view, gl_prefs->default_font_italic_flag);
402 gl_view_set_default_text_color (view, gl_prefs->default_text_color);
403 gl_view_set_default_text_alignment (view, gl_prefs->default_text_alignment);
404 gl_view_set_default_text_line_spacing (view, gl_prefs->default_text_line_spacing);
405 gl_view_set_default_line_width (view, gl_prefs->default_line_width);
406 gl_view_set_default_line_color (view, gl_prefs->default_line_color);
407 gl_view_set_default_fill_color (view, gl_prefs->default_fill_color);
409 gl_debug (DEBUG_VIEW, "END");
412 /*---------------------------------------------------------------------------*/
413 /* PRIVATE. Create canvas w/ a background in the shape of the label/card. */
414 /*---------------------------------------------------------------------------*/
416 gl_view_construct_canvas (glView *view)
419 gdouble label_width, label_height;
422 gl_debug (DEBUG_VIEW, "START");
424 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
425 g_return_val_if_fail (view->label && GL_IS_LABEL (view->label), NULL);
429 gtk_widget_push_colormap (gdk_rgb_get_colormap ());
430 view->canvas = gnome_canvas_new_aa ();
431 gtk_widget_pop_colormap ();
433 bg_color = gl_color_to_gdk_color (BG_COLOR);
434 gtk_widget_modify_bg (GTK_WIDGET(view->canvas), GTK_STATE_NORMAL, bg_color);
437 gl_label_get_size (label, &label_width, &label_height);
438 gl_debug (DEBUG_VIEW, "Label size: w=%lf, h=%lf",
439 label_width, label_height);
442 view->home_scale = get_home_scale (view);
443 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas), view->home_scale);
445 gnome_canvas_set_scroll_region (GNOME_CANVAS (view->canvas),
446 0.0, 0.0, label_width, label_height);
450 g_signal_connect (G_OBJECT (view->canvas), "event",
451 G_CALLBACK (canvas_event), view);
453 g_signal_connect_swapped (G_OBJECT (view->canvas), "size-allocate",
454 G_CALLBACK (size_allocate_cb), view);
456 g_signal_connect_swapped (G_OBJECT (view->canvas), "screen-changed",
457 G_CALLBACK (screen_changed_cb), view);
459 gl_debug (DEBUG_VIEW, "END");
464 /*---------------------------------------------------------------------------*/
465 /* PRIAVTE. Calculate 1:1 scale for screen. */
466 /*---------------------------------------------------------------------------*/
468 get_home_scale (glView *view)
471 gdouble screen_width_pixels, screen_width_mm;
472 gdouble screen_height_pixels, screen_height_mm;
473 gdouble x_pixels_per_mm, y_pixels_per_mm;
476 if (!gtk_widget_has_screen (GTK_WIDGET (view->canvas))) return 1.0;
478 screen = gtk_widget_get_screen (GTK_WIDGET (view->canvas));
480 gl_debug (DEBUG_VIEW, "Screen = %p", screen);
482 screen_width_pixels = gdk_screen_get_width (screen);
483 screen_width_mm = gdk_screen_get_width_mm (screen);
484 screen_height_pixels = gdk_screen_get_height (screen);
485 screen_height_mm = gdk_screen_get_height_mm (screen);
487 x_pixels_per_mm = screen_width_pixels / screen_width_mm;
488 y_pixels_per_mm = screen_height_pixels / screen_height_mm;
490 gl_debug (DEBUG_VIEW, "Horizontal dot pitch: %g pixels/mm (%g dpi)",
491 x_pixels_per_mm, x_pixels_per_mm * 25.4);
492 gl_debug (DEBUG_VIEW, "Vertical dot pitch: %g pixels/mm (%g dpi)",
493 y_pixels_per_mm, y_pixels_per_mm * 25.4);
495 scale = (x_pixels_per_mm + y_pixels_per_mm) / 2.0;
497 gl_debug (DEBUG_VIEW, "Average dot pitch: %g pixels/mm (%g dpi)",
498 scale, scale * 25.4);
500 scale /= POINTS_PER_MM;
502 gl_debug (DEBUG_VIEW, "Scale = %g pixels/point", scale);
504 /* Make sure scale is somewhat sane. */
505 if ( (scale < 0.25) || (scale > 4.0) ) return 1.0;
510 /*---------------------------------------------------------------------------*/
511 /* PRIVATE. Create clipboard selection targets. */
512 /*---------------------------------------------------------------------------*/
514 gl_view_construct_selection (glView *view)
516 gl_debug (DEBUG_VIEW, "START");
518 g_return_if_fail (GL_IS_VIEW (view));
520 view->have_selection = FALSE;
521 view->selection_data = NULL;
522 view->invisible = gtk_invisible_new ();
524 view->selected_object_list = NULL;
526 if (!clipboard_atom) {
527 clipboard_atom = gdk_atom_intern ("GLABELS_CLIPBOARD", FALSE);
530 gtk_selection_add_target (view->invisible,
531 clipboard_atom, GDK_SELECTION_TYPE_STRING, 1);
533 g_signal_connect (G_OBJECT (view->invisible),
534 "selection_clear_event",
535 G_CALLBACK (selection_clear_cb), view);
537 g_signal_connect (G_OBJECT (view->invisible), "selection_get",
538 G_CALLBACK (selection_get_cb), view);
540 g_signal_connect (G_OBJECT (view->invisible),
541 "selection_received",
542 G_CALLBACK (selection_received_cb), view);
544 gl_debug (DEBUG_VIEW, "END");
547 /*---------------------------------------------------------------------------*/
548 /* PRIVATE. Create, draw and order layers. */
549 /*---------------------------------------------------------------------------*/
551 draw_layers (glView *view)
553 g_return_if_fail (view && GL_IS_VIEW (view));
554 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
556 draw_bg_fg_layers (view);
557 draw_grid_layer (view);
558 draw_markup_layer (view);
559 draw_highlight_layer (view); /* Must be done before label layer */
560 draw_label_layer (view);
562 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->fg_group));
563 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->highlight_group));
565 g_signal_connect (G_OBJECT (view->label), "size_changed",
566 G_CALLBACK (label_resized_cb), view);
569 /*---------------------------------------------------------------------------*/
570 /* PRIVATE. Handle label resize event. . */
571 /*---------------------------------------------------------------------------*/
573 label_resized_cb (glLabel *label,
576 gdouble label_width, label_height;
578 g_return_if_fail (label && GL_IS_LABEL (label));
579 g_return_if_fail (view && GL_IS_VIEW (view));
581 gl_label_get_size (label, &label_width, &label_height);
582 gnome_canvas_set_scroll_region (GNOME_CANVAS (view->canvas),
583 0.0, 0.0, label_width, label_height);
585 gtk_object_destroy (GTK_OBJECT (view->bg_group));
586 gtk_object_destroy (GTK_OBJECT (view->grid_group));
587 gtk_object_destroy (GTK_OBJECT (view->markup_group));
588 gtk_object_destroy (GTK_OBJECT (view->fg_group));
590 draw_bg_fg_layers (view);
591 draw_grid_layer (view);
592 draw_markup_layer (view);
594 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->label_group));
595 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->fg_group));
596 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->highlight_group));
599 /*---------------------------------------------------------------------------*/
600 /* PRIVATE. Draw label layer. */
601 /*---------------------------------------------------------------------------*/
603 draw_label_layer (glView *view)
605 GnomeCanvasGroup *group;
608 glLabelObject *object;
609 glViewObject *view_object;
611 g_return_if_fail (view && GL_IS_VIEW (view));
612 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
614 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
615 view->label_group = GNOME_CANVAS_GROUP(
616 gnome_canvas_item_new (group,
617 gnome_canvas_group_get_type (),
624 for (p_obj = label->objects; p_obj != NULL; p_obj = p_obj->next) {
625 object = (glLabelObject *) p_obj->data;
627 if (GL_IS_LABEL_BOX (object)) {
628 view_object = gl_view_box_new (GL_LABEL_BOX(object),
630 } else if (GL_IS_LABEL_ELLIPSE (object)) {
631 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object),
633 } else if (GL_IS_LABEL_LINE (object)) {
634 view_object = gl_view_line_new (GL_LABEL_LINE(object),
636 } else if (GL_IS_LABEL_IMAGE (object)) {
637 view_object = gl_view_image_new (GL_LABEL_IMAGE(object),
639 } else if (GL_IS_LABEL_TEXT (object)) {
640 view_object = gl_view_text_new (GL_LABEL_TEXT(object),
642 } else if (GL_IS_LABEL_BARCODE (object)) {
643 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(object),
646 /* Should not happen! */
648 g_warning ("Invalid label object type.");
653 /*---------------------------------------------------------------------------*/
654 /* PRIVATE. Create highlight layer. */
655 /*---------------------------------------------------------------------------*/
657 draw_highlight_layer (glView *view)
659 GnomeCanvasGroup *group;
661 g_return_if_fail (view && GL_IS_VIEW (view));
663 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
664 view->highlight_group = GNOME_CANVAS_GROUP(
665 gnome_canvas_item_new (group,
666 gnome_canvas_group_get_type (),
672 /*---------------------------------------------------------------------------*/
673 /* PRIVATE. Draw background and foreground outlines. */
674 /*---------------------------------------------------------------------------*/
676 draw_bg_fg_layers (glView *view)
679 glTemplate *template;
680 const glTemplateLabelType *label_type;
681 GnomeCanvasGroup *group;
683 g_return_if_fail (view && GL_IS_VIEW (view));
684 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
686 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
687 view->bg_group = GNOME_CANVAS_GROUP(
688 gnome_canvas_item_new (group,
689 gnome_canvas_group_get_type (),
693 view->fg_group = GNOME_CANVAS_GROUP(
694 gnome_canvas_item_new (group,
695 gnome_canvas_group_get_type (),
701 template = gl_label_get_template (label);
702 label_type = gl_template_get_first_label_type (template);
704 switch (label_type->shape) {
706 case GL_TEMPLATE_SHAPE_RECT:
707 if (label_type->size.rect.r == 0.0) {
708 /* Square corners. */
709 draw_bg_fg_rect (view);
711 /* Rounded corners. */
712 draw_bg_fg_rounded_rect (view);
716 case GL_TEMPLATE_SHAPE_ROUND:
717 draw_bg_fg_round (view);
720 case GL_TEMPLATE_SHAPE_CD:
721 if ((label_type->size.cd.w == 0.0) && (label_type->size.cd.h == 0.0) ) {
722 draw_bg_fg_cd (view);
724 draw_bg_fg_cd_bc (view);
729 g_warning ("Unknown template label style");
734 /*---------------------------------------------------------------------------*/
735 /* PRIVATE. Draw simple recangular background. */
736 /*---------------------------------------------------------------------------*/
738 draw_bg_fg_rect (glView *view)
742 GnomeCanvasItem *item;
744 gl_debug (DEBUG_VIEW, "START");
746 g_return_if_fail (view && GL_IS_VIEW (view));
747 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
751 gl_label_get_size (label, &w, &h);
754 item = gnome_canvas_item_new (view->bg_group,
755 gnome_canvas_rect_get_type (),
760 "fill_color_rgba", PAPER_COLOR,
764 item = gnome_canvas_item_new (view->fg_group,
765 gnome_canvas_rect_get_type (),
771 "outline_color_rgba", OUTLINE_COLOR,
774 gl_debug (DEBUG_VIEW, "END");
777 /*---------------------------------------------------------------------------*/
778 /* PRIVATE. Draw rounded recangular background. */
779 /*---------------------------------------------------------------------------*/
781 draw_bg_fg_rounded_rect (glView *view)
784 GnomeCanvasPoints *points;
785 gint i_coords, i_theta;
786 glTemplate *template;
787 const glTemplateLabelType *label_type;
789 GnomeCanvasItem *item;
791 gl_debug (DEBUG_VIEW, "START");
793 g_return_if_fail (view && GL_IS_VIEW (view));
794 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
797 template = gl_label_get_template (label);
798 label_type = gl_template_get_first_label_type (template);
800 gl_label_get_size (label, &w, &h);
801 r = label_type->size.rect.r;
803 points = gnome_canvas_points_new (4 * (1 + 90 / ARC_COURSE));
805 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
806 points->coords[i_coords++] =
807 r - r * sin (i_theta * G_PI / 180.0);
808 points->coords[i_coords++] =
809 r - r * cos (i_theta * G_PI / 180.0);
811 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
812 points->coords[i_coords++] =
813 r - r * cos (i_theta * G_PI / 180.0);
814 points->coords[i_coords++] =
815 (h - r) + r * sin (i_theta * G_PI / 180.0);
817 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
818 points->coords[i_coords++] =
819 (w - r) + r * sin (i_theta * G_PI / 180.0);
820 points->coords[i_coords++] =
821 (h - r) + r * cos (i_theta * G_PI / 180.0);
823 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
824 points->coords[i_coords++] =
825 (w - r) + r * cos (i_theta * G_PI / 180.0);
826 points->coords[i_coords++] =
827 r - r * sin (i_theta * G_PI / 180.0);
831 item = gnome_canvas_item_new (view->bg_group,
832 gnome_canvas_polygon_get_type (),
834 "fill_color_rgba", PAPER_COLOR,
838 item = gnome_canvas_item_new (view->fg_group,
839 gnome_canvas_polygon_get_type (),
842 "outline_color_rgba", OUTLINE_COLOR,
845 gnome_canvas_points_free (points);
847 gl_debug (DEBUG_VIEW, "END");
850 /*---------------------------------------------------------------------------*/
851 /* PRIVATE. Draw round background. */
852 /*---------------------------------------------------------------------------*/
854 draw_bg_fg_round (glView *view)
857 glTemplate *template;
858 const glTemplateLabelType *label_type;
860 GnomeCanvasItem *item;
862 gl_debug (DEBUG_VIEW, "START");
864 g_return_if_fail (view && GL_IS_VIEW (view));
865 g_return_if_fail (view->label && GL_IS_LABEL(view->label));
868 template = gl_label_get_template (label);
869 label_type = gl_template_get_first_label_type (template);
871 r = label_type->size.round.r;
874 item = gnome_canvas_item_new (view->bg_group,
875 gnome_canvas_ellipse_get_type (),
880 "fill_color_rgba", PAPER_COLOR,
884 item = gnome_canvas_item_new (view->fg_group,
885 gnome_canvas_ellipse_get_type (),
891 "outline_color_rgba", OUTLINE_COLOR,
894 gl_debug (DEBUG_VIEW, "END");
897 /*---------------------------------------------------------------------------*/
898 /* PRIVATE. Draw CD style background, circular w/ concentric hole. */
899 /*---------------------------------------------------------------------------*/
901 draw_bg_fg_cd (glView *view)
904 glTemplate *template;
905 const glTemplateLabelType *label_type;
907 GnomeCanvasItem *item;
909 gl_debug (DEBUG_VIEW, "START");
911 g_return_if_fail (view && GL_IS_VIEW (view));
912 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
915 template = gl_label_get_template (label);
916 label_type = gl_template_get_first_label_type (template);
918 r1 = label_type->size.cd.r1;
919 r2 = label_type->size.cd.r2;
923 item = gnome_canvas_item_new (view->bg_group,
924 gnome_canvas_ellipse_get_type (),
929 "fill_color_rgba", PAPER_COLOR,
932 item = gnome_canvas_item_new (view->bg_group,
933 gnome_canvas_ellipse_get_type (),
938 "fill_color_rgba", GRID_COLOR,
943 item = gnome_canvas_item_new (view->fg_group,
944 gnome_canvas_ellipse_get_type (),
950 "outline_color_rgba", OUTLINE_COLOR,
953 item = gnome_canvas_item_new (view->fg_group,
954 gnome_canvas_ellipse_get_type (),
960 "outline_color_rgba", OUTLINE_COLOR,
963 gl_debug (DEBUG_VIEW, "END");
966 /*---------------------------------------------------------------------------*/
967 /* PRIVATE. Draw Business Card CD style background, CD w/ chopped ends. */
968 /*---------------------------------------------------------------------------*/
970 draw_bg_fg_cd_bc (glView *view)
973 glTemplate *template;
974 const glTemplateLabelType *label_type;
975 GnomeCanvasPoints *points;
976 gint i_coords, i_theta;
977 gdouble theta1, theta2;
978 gdouble x0, y0, w, h, r1, r2;
979 GnomeCanvasItem *item;
981 gl_debug (DEBUG_VIEW, "START");
983 g_return_if_fail (view && GL_IS_VIEW (view));
984 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
987 template = gl_label_get_template (label);
988 label_type = gl_template_get_first_label_type (template);
990 gl_label_get_size (label, &w, &h);
994 r1 = label_type->size.cd.r1;
995 r2 = label_type->size.cd.r2;
997 theta1 = (180.0/G_PI) * acos (w / (2.0*r1));
998 theta2 = (180.0/G_PI) * asin (h / (2.0*r1));
1000 points = gnome_canvas_points_new (360/ARC_FINE + 1);
1003 points->coords[i_coords++] = x0 + r1 * cos (theta1 * G_PI / 180.0);
1004 points->coords[i_coords++] = y0 + r1 * sin (theta1 * G_PI / 180.0);
1006 for ( i_theta = theta1 + ARC_FINE; i_theta < theta2; i_theta +=ARC_FINE ) {
1007 points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
1008 points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
1011 points->coords[i_coords++] = x0 + r1 * cos (theta2 * G_PI / 180.0);
1012 points->coords[i_coords++] = y0 + r1 * sin (theta2 * G_PI / 180.0);
1015 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
1016 points->coords[i_coords++] = x0 + r1 * cos ((180-theta2) * G_PI / 180.0);
1017 points->coords[i_coords++] = y0 + r1 * sin ((180-theta2) * G_PI / 180.0);
1020 for ( i_theta = 180-theta2+ARC_FINE; i_theta < (180-theta1); i_theta +=ARC_FINE ) {
1021 points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
1022 points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
1025 points->coords[i_coords++] = x0 + r1 * cos ((180-theta1) * G_PI / 180.0);
1026 points->coords[i_coords++] = y0 + r1 * sin ((180-theta1) * G_PI / 180.0);
1028 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
1029 points->coords[i_coords++] = x0 + r1 * cos ((180+theta1) * G_PI / 180.0);
1030 points->coords[i_coords++] = y0 + r1 * sin ((180+theta1) * G_PI / 180.0);
1033 for ( i_theta = 180+theta1+ARC_FINE; i_theta < (180+theta2); i_theta +=ARC_FINE ) {
1034 points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
1035 points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
1038 points->coords[i_coords++] = x0 + r1 * cos ((180+theta2) * G_PI / 180.0);
1039 points->coords[i_coords++] = y0 + r1 * sin ((180+theta2) * G_PI / 180.0);
1041 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
1042 points->coords[i_coords++] = x0 + r1 * cos ((360-theta2) * G_PI / 180.0);
1043 points->coords[i_coords++] = y0 + r1 * sin ((360-theta2) * G_PI / 180.0);
1046 for ( i_theta = 360-theta2+ARC_FINE; i_theta < (360-theta1); i_theta +=ARC_FINE ) {
1047 points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
1048 points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
1051 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
1052 points->coords[i_coords++] = x0 + r1 * cos ((360-theta1) * G_PI / 180.0);
1053 points->coords[i_coords++] = y0 + r1 * sin ((360-theta1) * G_PI / 180.0);
1056 points->num_points = i_coords / 2;
1060 item = gnome_canvas_item_new (view->bg_group,
1061 gnome_canvas_polygon_get_type (),
1063 "fill_color_rgba", PAPER_COLOR,
1066 item = gnome_canvas_item_new (view->bg_group,
1067 gnome_canvas_ellipse_get_type (),
1072 "fill_color_rgba", GRID_COLOR,
1077 item = gnome_canvas_item_new (view->fg_group,
1078 gnome_canvas_polygon_get_type (),
1081 "outline_color_rgba", OUTLINE_COLOR,
1084 item = gnome_canvas_item_new (view->fg_group,
1085 gnome_canvas_ellipse_get_type (),
1091 "outline_color_rgba", OUTLINE_COLOR,
1094 gnome_canvas_points_free (points);
1096 gl_debug (DEBUG_VIEW, "END");
1099 /*---------------------------------------------------------------------------*/
1100 /* PRIVATE. Draw grid lines. */
1101 /*---------------------------------------------------------------------------*/
1103 draw_grid_layer (glView *view)
1105 gdouble w, h, x, y, x0, y0;
1106 GnomeCanvasPoints *points;
1107 GnomeCanvasItem *item;
1108 GnomeCanvasGroup *group;
1109 glTemplate *template;
1110 const glTemplateLabelType *template_type;
1112 gl_debug (DEBUG_VIEW, "START");
1114 g_return_if_fail (view && GL_IS_VIEW (view));
1115 g_return_if_fail (view->label && GL_IS_LABEL(view->label));
1117 gl_label_get_size (view->label, &w, &h);
1118 template = gl_label_get_template (view->label);
1119 template_type = gl_template_get_first_label_type (template);
1121 if (template_type->shape == GL_TEMPLATE_SHAPE_RECT) {
1125 /* for round labels, adjust grid to line up with center of label. */
1126 x0 = fmod (w/2.0, view->grid_spacing);
1127 y0 = fmod (h/2.0, view->grid_spacing);
1130 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
1131 view->grid_group = GNOME_CANVAS_GROUP(
1132 gnome_canvas_item_new (group,
1133 gnome_canvas_group_get_type (),
1137 points = gnome_canvas_points_new (2);
1139 points->coords[1] = 0.0;
1140 points->coords[3] = h;
1141 for ( x=x0+view->grid_spacing; x < w; x += view->grid_spacing ) {
1142 points->coords[0] = points->coords[2] = x;
1143 item = gnome_canvas_item_new (view->grid_group,
1144 gnome_canvas_line_get_type (),
1147 "fill_color_rgba", GRID_COLOR,
1151 points->coords[0] = 0.0;
1152 points->coords[2] = w;
1153 for ( y=y0+view->grid_spacing; y < h; y += view->grid_spacing ) {
1154 points->coords[1] = points->coords[3] = y;
1155 item = gnome_canvas_item_new (view->grid_group,
1156 gnome_canvas_line_get_type (),
1159 "fill_color_rgba", GRID_COLOR,
1163 gnome_canvas_points_free (points);
1164 gl_template_free (template);
1166 gl_debug (DEBUG_VIEW, "END");
1169 /*---------------------------------------------------------------------------*/
1170 /* PRIVATE. Draw markup lines. */
1171 /*---------------------------------------------------------------------------*/
1173 draw_markup_layer (glView *view)
1175 GnomeCanvasGroup *group;
1177 glTemplate *template;
1178 const glTemplateLabelType *label_type;
1180 glTemplateMarkup *markup;
1182 g_return_if_fail (view && GL_IS_VIEW (view));
1183 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1185 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
1186 view->markup_group = GNOME_CANVAS_GROUP(
1187 gnome_canvas_item_new (group,
1188 gnome_canvas_group_get_type (),
1193 label = view->label;
1194 template = gl_label_get_template (label);
1195 label_type = gl_template_get_first_label_type (template);
1197 for ( p=label_type->markups; p != NULL; p=p->next ) {
1198 markup = (glTemplateMarkup *)p->data;
1200 switch (markup->type) {
1201 case GL_TEMPLATE_MARKUP_MARGIN:
1202 draw_markup_margin (view, markup);
1204 case GL_TEMPLATE_MARKUP_LINE:
1205 draw_markup_line (view, markup);
1207 case GL_TEMPLATE_MARKUP_CIRCLE:
1208 draw_markup_circle (view, markup);
1211 g_warning ("Unknown template markup type");
1217 /*---------------------------------------------------------------------------*/
1218 /* PRIVATE. Draw margin markup. */
1219 /*---------------------------------------------------------------------------*/
1221 draw_markup_margin (glView *view,
1222 glTemplateMarkup *markup)
1225 glTemplate *template;
1226 const glTemplateLabelType *label_type;
1228 g_return_if_fail (view && GL_IS_VIEW (view));
1229 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1231 label = view->label;
1232 template = gl_label_get_template (label);
1233 label_type = gl_template_get_first_label_type (template);
1235 switch (label_type->shape) {
1237 case GL_TEMPLATE_SHAPE_RECT:
1238 if (label_type->size.rect.r == 0.0) {
1239 /* Square corners. */
1240 draw_markup_margin_rect (view, markup);
1242 if ( markup->data.margin.size < label_type->size.rect.r) {
1243 /* Rounded corners. */
1244 draw_markup_margin_rounded_rect (view, markup);
1246 /* Square corners. */
1247 draw_markup_margin_rect (view, markup);
1252 case GL_TEMPLATE_SHAPE_ROUND:
1253 draw_markup_margin_round (view, markup);
1256 case GL_TEMPLATE_SHAPE_CD:
1257 if ((label_type->size.cd.w == 0.0) && (label_type->size.cd.h == 0.0) ) {
1258 draw_markup_margin_cd (view, markup);
1260 draw_markup_margin_cd_bc (view, markup);
1265 g_warning ("Unknown template label style");
1270 /*---------------------------------------------------------------------------*/
1271 /* PRIVATE. Draw simple recangular margin. */
1272 /*---------------------------------------------------------------------------*/
1274 draw_markup_margin_rect (glView *view,
1275 glTemplateMarkup *markup)
1278 glTemplate *template;
1279 const glTemplateLabelType *label_type;
1281 GnomeCanvasItem *item;
1283 gl_debug (DEBUG_VIEW, "START");
1285 g_return_if_fail (view && GL_IS_VIEW (view));
1286 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1288 label = view->label;
1289 template = gl_label_get_template (label);
1290 label_type = gl_template_get_first_label_type (template);
1292 gl_label_get_size (label, &w, &h);
1293 m = markup->data.margin.size;
1295 /* Bounding box @ margin */
1296 gnome_canvas_item_new (view->markup_group,
1297 gnome_canvas_rect_get_type (),
1303 "outline_color_rgba", MARKUP_COLOR,
1306 gl_debug (DEBUG_VIEW, "END");
1309 /*---------------------------------------------------------------------------*/
1310 /* PRIVATE. Draw rounded recangular markup. */
1311 /*---------------------------------------------------------------------------*/
1313 draw_markup_margin_rounded_rect (glView *view,
1314 glTemplateMarkup *markup)
1317 glTemplate *template;
1318 const glTemplateLabelType *label_type;
1319 GnomeCanvasPoints *points;
1320 gint i_coords, i_theta;
1322 GnomeCanvasItem *item;
1324 gl_debug (DEBUG_VIEW, "START");
1326 g_return_if_fail (view && GL_IS_VIEW (view));
1327 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1329 label = view->label;
1330 template = gl_label_get_template (label);
1331 label_type = gl_template_get_first_label_type (template);
1333 gl_label_get_size (label, &w, &h);
1334 r = label_type->size.rect.r;
1335 m = markup->data.margin.size;
1341 /* rectangle with rounded corners */
1342 points = gnome_canvas_points_new (4 * (1 + 90 / ARC_COURSE));
1344 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1345 points->coords[i_coords++] =
1346 m + r - r * sin (i_theta * G_PI / 180.0);
1347 points->coords[i_coords++] =
1348 m + r - r * cos (i_theta * G_PI / 180.0);
1350 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1351 points->coords[i_coords++] =
1352 m + r - r * cos (i_theta * G_PI / 180.0);
1353 points->coords[i_coords++] =
1354 m + (h - r) + r * sin (i_theta * G_PI / 180.0);
1356 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1357 points->coords[i_coords++] =
1358 m + (w - r) + r * sin (i_theta * G_PI / 180.0);
1359 points->coords[i_coords++] =
1360 m + (h - r) + r * cos (i_theta * G_PI / 180.0);
1362 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1363 points->coords[i_coords++] =
1364 m + (w - r) + r * cos (i_theta * G_PI / 180.0);
1365 points->coords[i_coords++] =
1366 m + r - r * sin (i_theta * G_PI / 180.0);
1368 item = gnome_canvas_item_new (view->markup_group,
1369 gnome_canvas_polygon_get_type (),
1372 "outline_color_rgba", MARKUP_COLOR,
1374 gnome_canvas_points_free (points);
1376 gl_debug (DEBUG_VIEW, "END");
1379 /*---------------------------------------------------------------------------*/
1380 /* PRIVATE. Draw round margin. */
1381 /*---------------------------------------------------------------------------*/
1383 draw_markup_margin_round (glView *view,
1384 glTemplateMarkup *markup)
1387 glTemplate *template;
1388 const glTemplateLabelType *label_type;
1390 GnomeCanvasItem *item;
1392 gl_debug (DEBUG_VIEW, "START");
1394 g_return_if_fail (view && GL_IS_VIEW (view));
1395 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1397 label = view->label;
1398 template = gl_label_get_template (label);
1399 label_type = gl_template_get_first_label_type (template);
1401 r = label_type->size.round.r;
1402 m = markup->data.margin.size;
1404 /* Margin outline */
1405 item = gnome_canvas_item_new (view->markup_group,
1406 gnome_canvas_ellipse_get_type (),
1412 "outline_color_rgba", MARKUP_COLOR,
1415 gl_debug (DEBUG_VIEW, "END");
1418 /*---------------------------------------------------------------------------*/
1419 /* PRIVATE. Draw CD margins. */
1420 /*---------------------------------------------------------------------------*/
1422 draw_markup_margin_cd (glView *view,
1423 glTemplateMarkup *markup)
1426 glTemplate *template;
1427 const glTemplateLabelType *label_type;
1429 GnomeCanvasItem *item;
1431 gl_debug (DEBUG_VIEW, "START");
1433 g_return_if_fail (view && GL_IS_VIEW (view));
1434 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1436 label = view->label;
1437 template = gl_label_get_template (label);
1438 label_type = gl_template_get_first_label_type (template);
1440 r1 = label_type->size.cd.r1;
1441 r2 = label_type->size.cd.r2;
1442 m = markup->data.margin.size;
1445 item = gnome_canvas_item_new (view->markup_group,
1446 gnome_canvas_ellipse_get_type (),
1452 "outline_color_rgba", MARKUP_COLOR,
1455 item = gnome_canvas_item_new (view->markup_group,
1456 gnome_canvas_ellipse_get_type (),
1462 "outline_color_rgba", MARKUP_COLOR,
1465 gl_debug (DEBUG_VIEW, "END");
1468 /*---------------------------------------------------------------------------*/
1469 /* PRIVATE. Draw Business Card CD margins. */
1470 /*---------------------------------------------------------------------------*/
1472 draw_markup_margin_cd_bc (glView *view,
1473 glTemplateMarkup *markup)
1476 glTemplate *template;
1477 const glTemplateLabelType *label_type;
1479 GnomeCanvasPoints *points;
1480 gint i_coords, i_theta;
1481 gdouble theta1, theta2;
1482 gdouble x0, y0, w, h, r;
1483 GnomeCanvasItem *item;
1485 gl_debug (DEBUG_VIEW, "START");
1487 g_return_if_fail (view && GL_IS_VIEW (view));
1488 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1490 label = view->label;
1491 template = gl_label_get_template (label);
1492 label_type = gl_template_get_first_label_type (template);
1494 gl_label_get_size (label, &w, &h);
1498 r1 = label_type->size.cd.r1;
1499 r2 = label_type->size.cd.r2;
1500 m = markup->data.margin.size;
1504 theta1 = (180.0/G_PI) * acos (w / (2.0*r1));
1505 theta2 = (180.0/G_PI) * asin (h / (2.0*r1));
1507 points = gnome_canvas_points_new (360/ARC_FINE + 1);
1510 points->coords[i_coords++] = x0 + r * cos (theta1 * G_PI / 180.0);
1511 points->coords[i_coords++] = y0 + r * sin (theta1 * G_PI / 180.0);
1513 for ( i_theta = theta1 + ARC_FINE; i_theta < theta2; i_theta +=ARC_FINE ) {
1514 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
1515 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
1518 points->coords[i_coords++] = x0 + r * cos (theta2 * G_PI / 180.0);
1519 points->coords[i_coords++] = y0 + r * sin (theta2 * G_PI / 180.0);
1522 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
1523 points->coords[i_coords++] = x0 + r * cos ((180-theta2) * G_PI / 180.0);
1524 points->coords[i_coords++] = y0 + r * sin ((180-theta2) * G_PI / 180.0);
1527 for ( i_theta = 180-theta2+ARC_FINE; i_theta < (180-theta1); i_theta +=ARC_FINE ) {
1528 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
1529 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
1532 points->coords[i_coords++] = x0 + r * cos ((180-theta1) * G_PI / 180.0);
1533 points->coords[i_coords++] = y0 + r * sin ((180-theta1) * G_PI / 180.0);
1535 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
1536 points->coords[i_coords++] = x0 + r * cos ((180+theta1) * G_PI / 180.0);
1537 points->coords[i_coords++] = y0 + r * sin ((180+theta1) * G_PI / 180.0);
1540 for ( i_theta = 180+theta1+ARC_FINE; i_theta < (180+theta2); i_theta +=ARC_FINE ) {
1541 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
1542 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
1545 points->coords[i_coords++] = x0 + r * cos ((180+theta2) * G_PI / 180.0);
1546 points->coords[i_coords++] = y0 + r * sin ((180+theta2) * G_PI / 180.0);
1548 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
1549 points->coords[i_coords++] = x0 + r * cos ((360-theta2) * G_PI / 180.0);
1550 points->coords[i_coords++] = y0 + r * sin ((360-theta2) * G_PI / 180.0);
1553 for ( i_theta = 360-theta2+ARC_FINE; i_theta < (360-theta1); i_theta +=ARC_FINE ) {
1554 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
1555 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
1558 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
1559 points->coords[i_coords++] = x0 + r * cos ((360-theta1) * G_PI / 180.0);
1560 points->coords[i_coords++] = y0 + r * sin ((360-theta1) * G_PI / 180.0);
1563 points->num_points = i_coords / 2;
1565 item = gnome_canvas_item_new (view->markup_group,
1566 gnome_canvas_polygon_get_type (),
1569 "outline_color_rgba", MARKUP_COLOR,
1572 gnome_canvas_points_free (points);
1575 item = gnome_canvas_item_new (view->markup_group,
1576 gnome_canvas_ellipse_get_type (),
1582 "outline_color_rgba", MARKUP_COLOR,
1585 gl_debug (DEBUG_VIEW, "END");
1588 /*---------------------------------------------------------------------------*/
1589 /* PRIVATE. Draw line markup. */
1590 /*---------------------------------------------------------------------------*/
1592 draw_markup_line (glView *view,
1593 glTemplateMarkup *markup)
1595 GnomeCanvasPoints *points;
1597 gl_debug (DEBUG_VIEW, "START");
1599 g_return_if_fail (view && GL_IS_VIEW (view));
1601 points = gnome_canvas_points_new (2);
1602 points->coords[0] = markup->data.line.x1;
1603 points->coords[1] = markup->data.line.y1;
1604 points->coords[2] = markup->data.line.x2;
1605 points->coords[3] = markup->data.line.y2;
1607 gnome_canvas_item_new (view->markup_group,
1608 gnome_canvas_line_get_type (),
1611 "fill_color_rgba", MARKUP_COLOR,
1614 gnome_canvas_points_free (points);
1616 gl_debug (DEBUG_VIEW, "END");
1619 /*---------------------------------------------------------------------------*/
1620 /* PRIVATE. Draw circle markup. */
1621 /*---------------------------------------------------------------------------*/
1623 draw_markup_circle (glView *view,
1624 glTemplateMarkup *markup)
1626 gl_debug (DEBUG_VIEW, "START");
1628 g_return_if_fail (view && GL_IS_VIEW (view));
1630 /* Circle outline */
1631 gnome_canvas_item_new (view->markup_group,
1632 gnome_canvas_ellipse_get_type (),
1633 "x1", markup->data.circle.x0 - markup->data.circle.r,
1634 "y1", markup->data.circle.y0 - markup->data.circle.r,
1635 "x2", markup->data.circle.x0 + markup->data.circle.r,
1636 "y2", markup->data.circle.y0 + markup->data.circle.r,
1638 "outline_color_rgba", MARKUP_COLOR,
1641 gl_debug (DEBUG_VIEW, "END");
1644 /*****************************************************************************/
1646 /*****************************************************************************/
1647 void gl_view_show_grid (glView *view)
1649 g_return_if_fail (view && GL_IS_VIEW (view));
1651 gnome_canvas_item_show (GNOME_CANVAS_ITEM(view->grid_group));
1654 /*****************************************************************************/
1656 /*****************************************************************************/
1657 void gl_view_hide_grid (glView *view)
1659 g_return_if_fail (view && GL_IS_VIEW (view));
1661 gnome_canvas_item_hide (GNOME_CANVAS_ITEM(view->grid_group));
1664 /*****************************************************************************/
1665 /* Set grid spacing. */
1666 /*****************************************************************************/
1667 void gl_view_set_grid_spacing (glView *view,
1670 g_return_if_fail (view && GL_IS_VIEW (view));
1672 view->grid_spacing = spacing;
1674 gtk_object_destroy (GTK_OBJECT(view->grid_group));
1675 draw_grid_layer (view);
1678 /*****************************************************************************/
1680 /*****************************************************************************/
1681 void gl_view_show_markup (glView *view)
1683 g_return_if_fail (view && GL_IS_VIEW (view));
1685 gnome_canvas_item_show (GNOME_CANVAS_ITEM(view->markup_group));
1688 /*****************************************************************************/
1690 /*****************************************************************************/
1691 void gl_view_hide_markup (glView *view)
1693 g_return_if_fail (view && GL_IS_VIEW (view));
1695 gnome_canvas_item_hide (GNOME_CANVAS_ITEM(view->markup_group));
1698 /*****************************************************************************/
1699 /* Set arrow mode. */
1700 /*****************************************************************************/
1702 gl_view_arrow_mode (glView *view)
1704 static GdkCursor *cursor = NULL;
1706 gl_debug (DEBUG_VIEW, "START");
1708 g_return_if_fail (view && GL_IS_VIEW (view));
1711 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1714 gdk_window_set_cursor (view->canvas->window, cursor);
1716 view->state = GL_VIEW_STATE_ARROW;
1718 gl_debug (DEBUG_VIEW, "END");
1721 /*****************************************************************************/
1722 /* Set create text object mode. */
1723 /*****************************************************************************/
1725 gl_view_object_create_mode (glView *view,
1726 glLabelObjectType type)
1730 gl_debug (DEBUG_VIEW, "START");
1732 g_return_if_fail (view && GL_IS_VIEW (view));
1735 case GL_LABEL_OBJECT_BOX:
1736 cursor = gl_view_box_get_create_cursor ();
1738 case GL_LABEL_OBJECT_ELLIPSE:
1739 cursor = gl_view_ellipse_get_create_cursor ();
1741 case GL_LABEL_OBJECT_LINE:
1742 cursor = gl_view_line_get_create_cursor ();
1744 case GL_LABEL_OBJECT_IMAGE:
1745 cursor = gl_view_image_get_create_cursor ();
1747 case GL_LABEL_OBJECT_TEXT:
1748 cursor = gl_view_text_get_create_cursor ();
1750 case GL_LABEL_OBJECT_BARCODE:
1751 cursor = gl_view_barcode_get_create_cursor ();
1754 g_warning ("Invalid label object type.");/*Should not happen!*/
1758 gdk_window_set_cursor (view->canvas->window, cursor);
1760 view->state = GL_VIEW_STATE_OBJECT_CREATE;
1761 view->create_type = type;
1763 gl_debug (DEBUG_VIEW, "END");
1766 /*****************************************************************************/
1767 /* Select given object (adding to current selection). */
1768 /*****************************************************************************/
1770 gl_view_select_object (glView *view,
1771 glViewObject *view_object)
1773 gl_debug (DEBUG_VIEW, "START");
1775 g_return_if_fail (view && GL_IS_VIEW (view));
1777 select_object_real (view, view_object);
1779 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1781 gl_debug (DEBUG_VIEW, "END");
1784 /*****************************************************************************/
1785 /* Unselect given object (removing from current selection). */
1786 /*****************************************************************************/
1788 gl_view_unselect_object (glView *view,
1789 glViewObject *view_object)
1791 gl_debug (DEBUG_VIEW, "START");
1793 g_return_if_fail (view && GL_IS_VIEW (view));
1795 unselect_object_real (view, view_object);
1797 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1799 gl_debug (DEBUG_VIEW, "END");
1802 /*****************************************************************************/
1803 /* Select all items. */
1804 /*****************************************************************************/
1806 gl_view_select_all (glView *view)
1810 gl_debug (DEBUG_VIEW, "START");
1812 g_return_if_fail (view && GL_IS_VIEW (view));
1814 /* 1st unselect anything already selected. */
1815 for (p = view->selected_object_list; p != NULL; p = p_next) {
1817 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1820 /* Finally select all objects. */
1821 for (p = view->object_list; p != NULL; p = p->next) {
1822 select_object_real (view, GL_VIEW_OBJECT (p->data));
1825 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1827 gl_debug (DEBUG_VIEW, "END");
1830 /*****************************************************************************/
1831 /* Remove all selections */
1832 /*****************************************************************************/
1834 gl_view_unselect_all (glView *view)
1838 gl_debug (DEBUG_VIEW, "START");
1840 g_return_if_fail (view && GL_IS_VIEW (view));
1842 for (p = view->selected_object_list; p != NULL; p = p_next) {
1844 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1847 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1849 gl_debug (DEBUG_VIEW, "END");
1852 /*****************************************************************************/
1853 /* Select all objects within given rectangular region (adding to selection). */
1854 /*****************************************************************************/
1856 gl_view_select_region (glView *view,
1863 glViewObject *view_object;
1864 glLabelObject *object;
1865 gdouble i_x1, i_y1, i_x2, i_y2;
1867 gl_debug (DEBUG_VIEW, "START");
1869 g_return_if_fail (view && GL_IS_VIEW (view));
1870 g_return_if_fail ((x1 <= x2) && (y1 <= y2));
1872 for (p = view->object_list; p != NULL; p = p->next) {
1873 view_object = GL_VIEW_OBJECT(p->data);
1874 if (!gl_view_is_object_selected (view, view_object)) {
1876 object = gl_view_object_get_object (view_object);
1878 gl_label_object_get_extent (object, &i_x1, &i_y1, &i_x2, &i_y2);
1879 if ((i_x1 >= x1) && (i_x2 <= x2) && (i_y1 >= y1)
1881 select_object_real (view, view_object);
1887 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1889 gl_debug (DEBUG_VIEW, "END");
1892 /*---------------------------------------------------------------------------*/
1893 /* PRIVATE. Select an object. */
1894 /*---------------------------------------------------------------------------*/
1896 select_object_real (glView *view,
1897 glViewObject *view_object)
1899 gl_debug (DEBUG_VIEW, "START");
1901 g_return_if_fail (view && GL_IS_VIEW (view));
1902 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1904 if (!gl_view_is_object_selected (view, view_object)) {
1905 view->selected_object_list =
1906 g_list_prepend (view->selected_object_list, view_object);
1908 gl_view_object_show_highlight (view_object);
1909 gtk_widget_grab_focus (GTK_WIDGET (view->canvas));
1911 gl_debug (DEBUG_VIEW, "END");
1914 /*---------------------------------------------------------------------------*/
1915 /* PRIVATE. Un-select object. */
1916 /*---------------------------------------------------------------------------*/
1918 unselect_object_real (glView *view,
1919 glViewObject *view_object)
1921 gl_debug (DEBUG_VIEW, "START");
1923 g_return_if_fail (view && GL_IS_VIEW (view));
1924 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1926 gl_view_object_hide_highlight (view_object);
1928 view->selected_object_list =
1929 g_list_remove (view->selected_object_list, view_object);
1931 gl_debug (DEBUG_VIEW, "END");
1934 /*---------------------------------------------------------------------------*/
1935 /* PRIVATE. Return object at (x,y). */
1936 /*---------------------------------------------------------------------------*/
1938 object_at (glView *view,
1942 GnomeCanvasItem *item, *p_item;
1945 gl_debug (DEBUG_VIEW, "");
1947 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1949 item = gnome_canvas_get_item_at (GNOME_CANVAS (view->canvas), x, y);
1951 /* No item is at x, y */
1955 /* ignore items not in label or highlight layers, e.g. background items */
1956 if (!is_item_member_of_group(view, item, GNOME_CANVAS_ITEM(view->label_group)) &&
1957 !is_item_member_of_group(view, item, GNOME_CANVAS_ITEM(view->highlight_group)))
1963 /*---------------------------------------------------------------------------*/
1964 /* PRIVATE. Is the item a child (or grandchild, etc.) of group. */
1965 /*---------------------------------------------------------------------------*/
1967 is_item_member_of_group (glView *view,
1968 GnomeCanvasItem *item,
1969 GnomeCanvasItem *group)
1971 GnomeCanvasItem *parent;
1972 GnomeCanvasItem *root_group;
1974 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1976 root_group = GNOME_CANVAS_ITEM(gnome_canvas_root (GNOME_CANVAS (view->canvas)));
1978 for ( parent=item->parent; parent && (parent!=root_group); parent=parent->parent) {
1979 if (parent == group) return TRUE;
1984 /*****************************************************************************/
1985 /* Is the object in our current selection? */
1986 /*****************************************************************************/
1988 gl_view_is_object_selected (glView *view,
1989 glViewObject *view_object)
1991 gl_debug (DEBUG_VIEW, "");
1993 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1994 g_return_val_if_fail (GL_IS_VIEW_OBJECT (view_object), FALSE);
1996 if (g_list_find (view->selected_object_list, view_object) == NULL) {
2002 /*****************************************************************************/
2003 /* Is our current selection empty? */
2004 /*****************************************************************************/
2006 gl_view_is_selection_empty (glView *view)
2008 gl_debug (DEBUG_VIEW, "");
2010 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2012 if (view->selected_object_list == NULL) {
2019 /*****************************************************************************/
2020 /* Is our current selection atomic? I.e. only one item selected. */
2021 /*****************************************************************************/
2023 gl_view_is_selection_atomic (glView *view)
2025 gl_debug (DEBUG_VIEW, "");
2027 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2029 if (view->selected_object_list == NULL)
2031 if (view->selected_object_list->next == NULL)
2036 /*****************************************************************************/
2037 /* Delete selected objects. (Bypass clipboard) */
2038 /*****************************************************************************/
2040 gl_view_delete_selection (glView *view)
2042 GList *object_list, *p, *p_next;
2044 gl_debug (DEBUG_VIEW, "START");
2046 g_return_if_fail (view && GL_IS_VIEW (view));
2048 object_list = view->selected_object_list;
2049 view->selected_object_list = NULL;
2050 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
2052 for (p = object_list; p != NULL; p = p_next) {
2054 g_object_unref (G_OBJECT (p->data));
2055 object_list = g_list_delete_link (object_list, p);
2058 gl_debug (DEBUG_VIEW, "END");
2061 /*****************************************************************************/
2062 /* Get object property editor of first selected object. */
2063 /*****************************************************************************/
2065 gl_view_get_editor (glView *view)
2067 glViewObject *view_object;
2068 GtkWidget *editor = NULL;
2070 gl_debug (DEBUG_VIEW, "START");
2072 g_return_if_fail (view && GL_IS_VIEW (view));
2074 if (!gl_view_is_selection_empty (view)) {
2076 view_object = GL_VIEW_OBJECT(view->selected_object_list->data);
2077 editor = gl_view_object_get_editor (view_object);
2081 gl_debug (DEBUG_VIEW, "END");
2086 /*****************************************************************************/
2087 /* Raise selected items to top. */
2088 /*****************************************************************************/
2090 gl_view_raise_selection (glView *view)
2093 glViewObject *view_object;
2094 glLabelObject *object;
2096 gl_debug (DEBUG_VIEW, "START");
2098 g_return_if_fail (view && GL_IS_VIEW (view));
2100 for (p = view->selected_object_list; p != NULL; p = p->next) {
2101 view_object = GL_VIEW_OBJECT (p->data);
2102 object = gl_view_object_get_object (view_object);
2103 gl_label_object_raise_to_top (object);
2106 gl_debug (DEBUG_VIEW, "END");
2109 /*****************************************************************************/
2110 /* Lower selected items to bottom. */
2111 /*****************************************************************************/
2113 gl_view_lower_selection (glView *view)
2116 glViewObject *view_object;
2117 glLabelObject *object;
2119 gl_debug (DEBUG_VIEW, "START");
2121 g_return_if_fail (view && GL_IS_VIEW (view));
2123 for (p = view->selected_object_list; p != NULL; p = p->next) {
2124 view_object = GL_VIEW_OBJECT (p->data);
2125 object = gl_view_object_get_object (view_object);
2126 gl_label_object_lower_to_bottom (object);
2129 gl_debug (DEBUG_VIEW, "END");
2132 /*****************************************************************************/
2133 /* Rotate selected objects by given angle. */
2134 /*****************************************************************************/
2136 gl_view_rotate_selection (glView *view,
2140 glViewObject *view_object;
2141 glLabelObject *object;
2143 gl_debug (DEBUG_VIEW, "START");
2145 g_return_if_fail (view && GL_IS_VIEW (view));
2147 for (p = view->selected_object_list; p != NULL; p = p->next) {
2148 view_object = GL_VIEW_OBJECT (p->data);
2149 object = gl_view_object_get_object (view_object);
2150 gl_label_object_rotate (object, theta_degs);
2153 gl_debug (DEBUG_VIEW, "END");
2156 /*****************************************************************************/
2157 /* Rotate selected objects 90 degrees left. */
2158 /*****************************************************************************/
2160 gl_view_rotate_selection_left (glView *view)
2163 glViewObject *view_object;
2164 glLabelObject *object;
2166 gl_debug (DEBUG_VIEW, "START");
2168 g_return_if_fail (view && GL_IS_VIEW (view));
2170 for (p = view->selected_object_list; p != NULL; p = p->next) {
2171 view_object = GL_VIEW_OBJECT (p->data);
2172 object = gl_view_object_get_object (view_object);
2173 gl_label_object_rotate (object, -90.0);
2176 gl_debug (DEBUG_VIEW, "END");
2179 /*****************************************************************************/
2180 /* Rotate selected objects 90 degrees right. */
2181 /*****************************************************************************/
2183 gl_view_rotate_selection_right (glView *view)
2186 glViewObject *view_object;
2187 glLabelObject *object;
2189 gl_debug (DEBUG_VIEW, "START");
2191 g_return_if_fail (view && GL_IS_VIEW (view));
2193 for (p = view->selected_object_list; p != NULL; p = p->next) {
2194 view_object = GL_VIEW_OBJECT (p->data);
2195 object = gl_view_object_get_object (view_object);
2196 gl_label_object_rotate (object, 90.0);
2199 gl_debug (DEBUG_VIEW, "END");
2202 /*****************************************************************************/
2203 /* Flip selected objects horizontally. */
2204 /*****************************************************************************/
2206 gl_view_flip_selection_horiz (glView *view)
2209 glViewObject *view_object;
2210 glLabelObject *object;
2212 gl_debug (DEBUG_VIEW, "START");
2214 g_return_if_fail (view && GL_IS_VIEW (view));
2216 for (p = view->selected_object_list; p != NULL; p = p->next) {
2217 view_object = GL_VIEW_OBJECT (p->data);
2218 object = gl_view_object_get_object (view_object);
2219 gl_label_object_flip_horiz (object);
2222 gl_debug (DEBUG_VIEW, "END");
2225 /*****************************************************************************/
2226 /* Flip selected objects vertically. */
2227 /*****************************************************************************/
2229 gl_view_flip_selection_vert (glView *view)
2232 glViewObject *view_object;
2233 glLabelObject *object;
2235 gl_debug (DEBUG_VIEW, "START");
2237 g_return_if_fail (view && GL_IS_VIEW (view));
2239 for (p = view->selected_object_list; p != NULL; p = p->next) {
2240 view_object = GL_VIEW_OBJECT (p->data);
2241 object = gl_view_object_get_object (view_object);
2242 gl_label_object_flip_vert (object);
2245 gl_debug (DEBUG_VIEW, "END");
2248 /*****************************************************************************/
2249 /* Align selected objects to left most edge. */
2250 /*****************************************************************************/
2252 gl_view_align_selection_left (glView *view)
2255 glViewObject *view_object;
2256 glLabelObject *object;
2257 gdouble dx, x1min, x1, y1, x2, y2;
2259 gl_debug (DEBUG_VIEW, "START");
2261 g_return_if_fail (view && GL_IS_VIEW (view));
2263 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2264 !gl_view_is_selection_atomic (view));
2266 /* find left most edge */
2267 p = view->selected_object_list;
2268 view_object = GL_VIEW_OBJECT (p->data);
2269 object = gl_view_object_get_object (view_object);
2270 gl_label_object_get_extent (object, &x1min, &y1, &x2, &y2);
2271 for (p = p->next; 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 if ( x1 < x1min ) x1min = x1;
2278 /* now adjust the object positions to line up the left edges */
2279 for (p = view->selected_object_list; p != NULL; p = p->next) {
2280 view_object = GL_VIEW_OBJECT (p->data);
2281 object = gl_view_object_get_object (view_object);
2282 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2284 gl_label_object_set_position_relative (object, dx, 0.0);
2287 gl_debug (DEBUG_VIEW, "END");
2291 /*****************************************************************************/
2292 /* Align selected objects to right most edge. */
2293 /*****************************************************************************/
2295 gl_view_align_selection_right (glView *view)
2298 glViewObject *view_object;
2299 glLabelObject *object;
2300 gdouble dx, x2max, x1, y1, x2, y2;
2302 gl_debug (DEBUG_VIEW, "START");
2304 g_return_if_fail (view && GL_IS_VIEW (view));
2306 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2307 !gl_view_is_selection_atomic (view));
2309 /* find right most edge */
2310 p = view->selected_object_list;
2311 view_object = GL_VIEW_OBJECT (p->data);
2312 object = gl_view_object_get_object (view_object);
2313 gl_label_object_get_extent (object, &x1, &y1, &x2max, &y2);
2314 for (p = p->next; p != NULL; p = p->next) {
2315 view_object = GL_VIEW_OBJECT (p->data);
2316 object = gl_view_object_get_object (view_object);
2317 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2318 if ( x2 > x2max ) x2max = x2;
2321 /* now adjust the object positions to line up the right edges */
2322 for (p = view->selected_object_list; p != NULL; p = p->next) {
2323 view_object = GL_VIEW_OBJECT (p->data);
2324 object = gl_view_object_get_object (view_object);
2325 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2327 gl_label_object_set_position_relative (object, dx, 0.0);
2330 gl_debug (DEBUG_VIEW, "END");
2333 /*****************************************************************************/
2334 /* Align selected objects to horizontal center of objects. */
2335 /*****************************************************************************/
2337 gl_view_align_selection_hcenter (glView *view)
2340 glViewObject *view_object;
2341 glLabelObject *object;
2342 gdouble dx, dxmin, xsum, xavg, xcenter, x1, y1, x2, y2;
2345 gl_debug (DEBUG_VIEW, "START");
2347 g_return_if_fail (view && GL_IS_VIEW (view));
2349 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2350 !gl_view_is_selection_atomic (view));
2352 /* find average center of objects */
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);
2359 xsum += (x1 + x2) / 2.0;
2364 /* find center of object closest to average center */
2365 p = view->selected_object_list;
2366 view_object = GL_VIEW_OBJECT (p->data);
2367 object = gl_view_object_get_object (view_object);
2368 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2369 dxmin = fabs (xavg - (x1 + x2)/2.0);
2370 xcenter = (x1 + x2)/2.0;
2371 for (p = p->next; p != NULL; p = p->next) {
2372 view_object = GL_VIEW_OBJECT (p->data);
2373 object = gl_view_object_get_object (view_object);
2374 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2375 dx = fabs (xavg - (x1 + x2)/2.0);
2378 xcenter = (x1 + x2)/2.0;
2382 /* now adjust the object positions to line up this center */
2383 for (p = view->selected_object_list; p != NULL; p = p->next) {
2384 view_object = GL_VIEW_OBJECT (p->data);
2385 object = gl_view_object_get_object (view_object);
2386 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2387 dx = xcenter - (x1 + x2)/2.0;
2388 gl_label_object_set_position_relative (object, dx, 0.0);
2391 gl_debug (DEBUG_VIEW, "END");
2394 /*****************************************************************************/
2395 /* Align selected objects to top most edge. */
2396 /*****************************************************************************/
2398 gl_view_align_selection_top (glView *view)
2401 glViewObject *view_object;
2402 glLabelObject *object;
2403 gdouble dy, y1min, x1, y1, x2, y2;
2405 gl_debug (DEBUG_VIEW, "START");
2407 g_return_if_fail (view && GL_IS_VIEW (view));
2409 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2410 !gl_view_is_selection_atomic (view));
2412 /* find top most edge */
2413 p = view->selected_object_list;
2414 view_object = GL_VIEW_OBJECT (p->data);
2415 object = gl_view_object_get_object (view_object);
2416 gl_label_object_get_extent (object, &x1, &y1min, &x2, &y2);
2417 for (p = p->next; p != NULL; p = p->next) {
2418 view_object = GL_VIEW_OBJECT (p->data);
2419 object = gl_view_object_get_object (view_object);
2420 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2421 if ( y1 < y1min ) y1min = y1;
2424 /* now adjust the object positions to line up the top edges */
2425 for (p = view->selected_object_list; p != NULL; p = p->next) {
2426 view_object = GL_VIEW_OBJECT (p->data);
2427 object = gl_view_object_get_object (view_object);
2428 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2430 gl_label_object_set_position_relative (object, 0.0, dy);
2433 gl_debug (DEBUG_VIEW, "END");
2436 /*****************************************************************************/
2437 /* Align selected objects to bottom most edge. */
2438 /*****************************************************************************/
2440 gl_view_align_selection_bottom (glView *view)
2443 glViewObject *view_object;
2444 glLabelObject *object;
2445 gdouble dy, y2max, x1, y1, x2, y2;
2447 gl_debug (DEBUG_VIEW, "START");
2449 g_return_if_fail (view && GL_IS_VIEW (view));
2451 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2452 !gl_view_is_selection_atomic (view));
2454 /* find bottom most edge */
2455 p = view->selected_object_list;
2456 view_object = GL_VIEW_OBJECT (p->data);
2457 object = gl_view_object_get_object (view_object);
2458 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2max);
2459 for (p = p->next; p != NULL; p = p->next) {
2460 view_object = GL_VIEW_OBJECT (p->data);
2461 object = gl_view_object_get_object (view_object);
2462 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2463 if ( y2 > y2max ) y2max = y2;
2466 /* now adjust the object positions to line up the bottom edges */
2467 for (p = view->selected_object_list; p != NULL; p = p->next) {
2468 view_object = GL_VIEW_OBJECT (p->data);
2469 object = gl_view_object_get_object (view_object);
2470 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2472 gl_label_object_set_position_relative (object, 0.0, dy);
2475 gl_debug (DEBUG_VIEW, "END");
2478 /*****************************************************************************/
2479 /* Align selected objects to viertical center of objects. */
2480 /*****************************************************************************/
2482 gl_view_align_selection_vcenter (glView *view)
2485 glViewObject *view_object;
2486 glLabelObject *object;
2487 gdouble dy, dymin, ysum, yavg, ycenter, x1, y1, x2, y2;
2490 gl_debug (DEBUG_VIEW, "START");
2492 g_return_if_fail (view && GL_IS_VIEW (view));
2494 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2495 !gl_view_is_selection_atomic (view));
2497 /* find average center of objects */
2500 for (p = view->selected_object_list; p != NULL; p = p->next) {
2501 view_object = GL_VIEW_OBJECT (p->data);
2502 object = gl_view_object_get_object (view_object);
2503 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2504 ysum += (y1 + y2) / 2.0;
2509 /* find center of object closest to average center */
2510 p = view->selected_object_list;
2511 view_object = GL_VIEW_OBJECT (p->data);
2512 object = gl_view_object_get_object (view_object);
2513 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2514 dymin = fabs (yavg - (y1 + y2)/2.0);
2515 ycenter = (y1 + y2)/2.0;
2516 for (p = p->next; p != NULL; p = p->next) {
2517 view_object = GL_VIEW_OBJECT (p->data);
2518 object = gl_view_object_get_object (view_object);
2519 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2520 dy = fabs (yavg - (y1 + y2)/2.0);
2523 ycenter = (y1 + y2)/2.0;
2527 /* now adjust the object positions to line up this center */
2528 for (p = view->selected_object_list; p != NULL; p = p->next) {
2529 view_object = GL_VIEW_OBJECT (p->data);
2530 object = gl_view_object_get_object (view_object);
2531 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2532 dy = ycenter - (y1 + y2)/2.0;
2533 gl_label_object_set_position_relative (object, 0.0, dy);
2536 gl_debug (DEBUG_VIEW, "END");
2539 /*****************************************************************************/
2540 /* Center selected objects to in center of label. */
2541 /*****************************************************************************/
2543 gl_view_center_selection_horiz (glView *view)
2546 glViewObject *view_object;
2547 glLabelObject *object;
2548 gdouble dx, x_label_center, x_obj_center, x1, y1, x2, y2, w, h;
2550 gl_debug (DEBUG_VIEW, "START");
2552 g_return_if_fail (view && GL_IS_VIEW (view));
2554 g_return_if_fail (!gl_view_is_selection_empty (view));
2556 gl_label_get_size (view->label, &w, &h);
2557 x_label_center = w / 2.0;
2559 /* adjust the object positions */
2560 for (p = view->selected_object_list; p != NULL; p = p->next) {
2561 view_object = GL_VIEW_OBJECT (p->data);
2562 object = gl_view_object_get_object (view_object);
2563 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2564 x_obj_center = (x1 + x2) / 2.0;
2565 dx = x_label_center - x_obj_center;
2566 gl_label_object_set_position_relative (object, dx, 0.0);
2569 gl_debug (DEBUG_VIEW, "END");
2573 /*****************************************************************************/
2574 /* Center selected objects to in center of label. */
2575 /*****************************************************************************/
2577 gl_view_center_selection_vert (glView *view)
2580 glViewObject *view_object;
2581 glLabelObject *object;
2582 gdouble dy, y_label_center, y_obj_center, x1, y1, x2, y2, w, h;
2584 gl_debug (DEBUG_VIEW, "START");
2586 g_return_if_fail (view && GL_IS_VIEW (view));
2588 g_return_if_fail (!gl_view_is_selection_empty (view));
2590 gl_label_get_size (view->label, &w, &h);
2591 y_label_center = h / 2.0;
2593 /* adjust the object positions */
2594 for (p = view->selected_object_list; p != NULL; p = p->next) {
2595 view_object = GL_VIEW_OBJECT (p->data);
2596 object = gl_view_object_get_object (view_object);
2597 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2598 y_obj_center = (y1 + y2) / 2.0;
2599 dy = y_label_center - y_obj_center;
2600 gl_label_object_set_position_relative (object, 0.0, dy);
2603 gl_debug (DEBUG_VIEW, "END");
2607 /*****************************************************************************/
2608 /* Move selected objects */
2609 /*****************************************************************************/
2611 gl_view_move_selection (glView *view,
2616 glLabelObject *object;
2618 gl_debug (DEBUG_VIEW, "START");
2620 g_return_if_fail (view && GL_IS_VIEW (view));
2622 for (p = view->selected_object_list; p != NULL; p = p->next) {
2624 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2625 gl_label_object_set_position_relative (object, dx, dy);
2629 gl_debug (DEBUG_VIEW, "END");
2632 /*****************************************************************************/
2633 /* Can text properties be set for selection? */
2634 /*****************************************************************************/
2636 gl_view_can_selection_text (glView *view)
2639 glLabelObject *object;
2641 gl_debug (DEBUG_VIEW, "");
2643 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2645 for (p = view->selected_object_list; p != NULL; p = p->next) {
2647 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2648 if (gl_label_object_can_text (object)) {
2657 /*****************************************************************************/
2658 /* Set font family for all text contained in selected objects. */
2659 /*****************************************************************************/
2661 gl_view_set_selection_font_family (glView *view,
2662 const gchar *font_family)
2665 glLabelObject *object;
2667 gl_debug (DEBUG_VIEW, "START");
2669 g_return_if_fail (view && GL_IS_VIEW (view));
2671 for (p = view->selected_object_list; p != NULL; p = p->next) {
2673 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2674 gl_label_object_set_font_family (object, font_family);
2678 gl_debug (DEBUG_VIEW, "END");
2681 /*****************************************************************************/
2682 /* Set font size for all text contained in selected objects. */
2683 /*****************************************************************************/
2685 gl_view_set_selection_font_size (glView *view,
2689 glLabelObject *object;
2691 gl_debug (DEBUG_VIEW, "START");
2693 g_return_if_fail (view && GL_IS_VIEW (view));
2695 for (p = view->selected_object_list; p != NULL; p = p->next) {
2697 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2698 gl_label_object_set_font_size (object, font_size);
2702 gl_debug (DEBUG_VIEW, "END");
2705 /*****************************************************************************/
2706 /* Set font weight for all text contained in selected objects. */
2707 /*****************************************************************************/
2709 gl_view_set_selection_font_weight (glView *view,
2710 GnomeFontWeight font_weight)
2713 glLabelObject *object;
2715 gl_debug (DEBUG_VIEW, "START");
2717 g_return_if_fail (view && GL_IS_VIEW (view));
2719 for (p = view->selected_object_list; p != NULL; p = p->next) {
2721 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2722 gl_label_object_set_font_weight (object, font_weight);
2726 gl_debug (DEBUG_VIEW, "END");
2729 /*****************************************************************************/
2730 /* Set font italic flag for all text contained in selected objects. */
2731 /*****************************************************************************/
2733 gl_view_set_selection_font_italic_flag (glView *view,
2734 gboolean font_italic_flag)
2737 glLabelObject *object;
2739 gl_debug (DEBUG_VIEW, "START");
2741 g_return_if_fail (view && GL_IS_VIEW (view));
2743 for (p = view->selected_object_list; p != NULL; p = p->next) {
2745 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2746 gl_label_object_set_font_italic_flag (object, font_italic_flag);
2750 gl_debug (DEBUG_VIEW, "END");
2753 /*****************************************************************************/
2754 /* Set text alignment for all text contained in selected objects. */
2755 /*****************************************************************************/
2757 gl_view_set_selection_text_alignment (glView *view,
2758 GtkJustification text_alignment)
2761 glLabelObject *object;
2763 gl_debug (DEBUG_VIEW, "START");
2765 g_return_if_fail (view && GL_IS_VIEW (view));
2767 for (p = view->selected_object_list; p != NULL; p = p->next) {
2769 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2770 gl_label_object_set_text_alignment (object, text_alignment);
2774 gl_debug (DEBUG_VIEW, "END");
2777 /*****************************************************************************/
2778 /* Set text line spacing for all text contained in selected objects. */
2779 /*****************************************************************************/
2781 gl_view_set_selection_text_line_spacing (glView *view,
2782 gdouble text_line_spacing)
2785 glLabelObject *object;
2787 gl_debug (DEBUG_VIEW, "START");
2789 g_return_if_fail (view && GL_IS_VIEW (view));
2791 for (p = view->selected_object_list; p != NULL; p = p->next) {
2793 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2794 gl_label_object_set_text_line_spacing (object, text_line_spacing);
2798 gl_debug (DEBUG_VIEW, "END");
2800 /*****************************************************************************/
2801 /* Set text color for all text contained in selected objects. */
2802 /*****************************************************************************/
2804 gl_view_set_selection_text_color (glView *view,
2805 glColorNode *text_color_node)
2808 glLabelObject *object;
2810 gl_debug (DEBUG_VIEW, "START");
2812 g_return_if_fail (view && GL_IS_VIEW (view));
2814 for (p = view->selected_object_list; p != NULL; p = p->next) {
2816 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2817 gl_label_object_set_text_color (object, text_color_node);
2821 gl_debug (DEBUG_VIEW, "END");
2824 /*****************************************************************************/
2825 /* Can fill properties be set for selection? */
2826 /*****************************************************************************/
2828 gl_view_can_selection_fill (glView *view)
2831 glLabelObject *object;
2833 gl_debug (DEBUG_VIEW, "");
2835 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2837 for (p = view->selected_object_list; p != NULL; p = p->next) {
2839 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2840 if (gl_label_object_can_fill (object)) {
2849 /*****************************************************************************/
2850 /* Set fill color for all selected objects. */
2851 /*****************************************************************************/
2853 gl_view_set_selection_fill_color (glView *view,
2854 glColorNode *fill_color_node)
2857 glLabelObject *object;
2859 gl_debug (DEBUG_VIEW, "START");
2861 g_return_if_fail (view && GL_IS_VIEW (view));
2863 for (p = view->selected_object_list; p != NULL; p = p->next) {
2865 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2866 gl_label_object_set_fill_color (object, fill_color_node);
2870 gl_debug (DEBUG_VIEW, "END");
2873 /*****************************************************************************/
2874 /* Can line color properties be set for selection? */
2875 /*****************************************************************************/
2877 gl_view_can_selection_line_color (glView *view)
2880 glLabelObject *object;
2882 gl_debug (DEBUG_VIEW, "");
2884 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2886 for (p = view->selected_object_list; p != NULL; p = p->next) {
2888 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2889 if (gl_label_object_can_line_color (object)) {
2898 /*****************************************************************************/
2899 /* Set line color for all selected objects. */
2900 /*****************************************************************************/
2902 gl_view_set_selection_line_color (glView *view,
2903 glColorNode *line_color_node)
2906 glLabelObject *object;
2908 gl_debug (DEBUG_VIEW, "START");
2910 g_return_if_fail (view && GL_IS_VIEW (view));
2912 for (p = view->selected_object_list; p != NULL; p = p->next) {
2914 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2915 gl_label_object_set_line_color (object, line_color_node);
2919 gl_debug (DEBUG_VIEW, "END");
2922 /*****************************************************************************/
2923 /* Can line width properties be set for selection? */
2924 /*****************************************************************************/
2926 gl_view_can_selection_line_width (glView *view)
2929 glLabelObject *object;
2931 gl_debug (DEBUG_VIEW, "");
2933 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2935 for (p = view->selected_object_list; p != NULL; p = p->next) {
2937 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2938 if (gl_label_object_can_line_width (object)) {
2947 /*****************************************************************************/
2948 /* Set line width for all selected objects. */
2949 /*****************************************************************************/
2951 gl_view_set_selection_line_width (glView *view,
2955 glLabelObject *object;
2957 gl_debug (DEBUG_VIEW, "START");
2959 g_return_if_fail (view && GL_IS_VIEW (view));
2961 for (p = view->selected_object_list; p != NULL; p = p->next) {
2963 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2964 gl_label_object_set_line_width (object, line_width);
2968 gl_debug (DEBUG_VIEW, "END");
2971 /*****************************************************************************/
2972 /* "Cut" selected items and place in clipboard selections. */
2973 /*****************************************************************************/
2975 gl_view_cut (glView *view)
2977 gl_debug (DEBUG_VIEW, "START");
2979 g_return_if_fail (view && GL_IS_VIEW (view));
2981 gl_view_copy (view);
2982 gl_view_delete_selection (view);
2984 gl_debug (DEBUG_VIEW, "END");
2987 /*****************************************************************************/
2988 /* "Copy" selected items to clipboard selections. */
2989 /*****************************************************************************/
2991 gl_view_copy (glView *view)
2994 glViewObject *view_object;
2995 glLabelObject *object;
2996 glTemplate *template;
2997 gboolean rotate_flag;
2999 gl_debug (DEBUG_VIEW, "START");
3001 g_return_if_fail (view && GL_IS_VIEW (view));
3003 if (view->selected_object_list) {
3005 if ( view->selection_data ) {
3006 g_object_unref (view->selection_data);
3008 template = gl_label_get_template (view->label);
3009 rotate_flag = gl_label_get_rotate_flag (view->label);
3010 view->selection_data = GL_LABEL(gl_label_new ());
3011 gl_label_set_template (view->selection_data, template);
3012 gl_label_set_rotate_flag (view->selection_data, rotate_flag);
3013 gl_template_free (template);
3015 for (p = view->selected_object_list; p != NULL; p = p->next) {
3017 view_object = GL_VIEW_OBJECT (p->data);
3018 object = gl_view_object_get_object (view_object);
3020 gl_label_object_dup (object, view->selection_data);
3024 gtk_selection_owner_set (view->invisible,
3025 clipboard_atom, GDK_CURRENT_TIME);
3026 view->have_selection = TRUE;
3030 gl_debug (DEBUG_VIEW, "END");
3033 /*****************************************************************************/
3034 /* "Paste" from private clipboard selection. */
3035 /*****************************************************************************/
3037 gl_view_paste (glView *view)
3039 gl_debug (DEBUG_VIEW, "START");
3041 g_return_if_fail (view && GL_IS_VIEW (view));
3043 gtk_selection_convert (GTK_WIDGET (view->invisible),
3044 clipboard_atom, GDK_SELECTION_TYPE_STRING,
3047 gl_debug (DEBUG_VIEW, "END");
3050 /*****************************************************************************/
3051 /* Zoom in one "notch" */
3052 /*****************************************************************************/
3054 gl_view_zoom_in (glView *view)
3057 gdouble dist, dist_min;
3059 gl_debug (DEBUG_VIEW, "START");
3061 g_return_if_fail (view && GL_IS_VIEW (view));
3063 /* Find index of current scale (or best match) */
3064 i_min = 1; /* start with 2nd largest scale */
3065 dist_min = fabs (zooms[1] - view->zoom);
3066 for (i = 2; i < N_ZOOMS; i++) {
3067 dist = fabs (zooms[i] - view->zoom);
3068 if (dist < dist_min) {
3074 /* zoom in one "notch" */
3075 i = MAX (0, i_min - 1);
3076 gl_debug (DEBUG_VIEW, "zoom[%d] = %g", i, zooms[i]);
3077 set_zoom_real (view, zooms[i], FALSE);
3079 gl_debug (DEBUG_VIEW, "END");
3082 /*****************************************************************************/
3083 /* Zoom out one "notch" */
3084 /*****************************************************************************/
3086 gl_view_zoom_out (glView *view)
3089 gdouble dist, dist_min;
3091 gl_debug (DEBUG_VIEW, "START");
3093 g_return_if_fail (view && GL_IS_VIEW (view));
3095 /* Find index of current scale (or best match) */
3096 i_min = 0; /* start with largest scale */
3097 dist_min = fabs (zooms[0] - view->zoom);
3098 for (i = 1; i < N_ZOOMS; i++) {
3099 dist = fabs (zooms[i] - view->zoom);
3100 if (dist < dist_min) {
3106 /* zoom out one "notch" */
3107 if (i_min >= N_ZOOMS)
3112 set_zoom_real (view, zooms[i], FALSE);
3114 gl_debug (DEBUG_VIEW, "END");
3117 /*****************************************************************************/
3118 /* Set zoom to best fit. */
3119 /*****************************************************************************/
3121 gl_view_zoom_to_fit (glView *view)
3123 gint w_view, h_view;
3124 gdouble w_label, h_label;
3125 gdouble x_scale, y_scale, scale;
3127 gl_debug (DEBUG_VIEW, "");
3129 if ( ! GTK_WIDGET_VISIBLE(view)) {
3130 set_zoom_real (view, 1.0, TRUE);
3134 w_view = GTK_WIDGET(view)->allocation.width;
3135 h_view = GTK_WIDGET(view)->allocation.height;
3137 gl_label_get_size (GL_LABEL(view->label), &w_label, &h_label);
3139 gl_debug (DEBUG_VIEW, "View size: %d, %d", w_view, h_view);
3140 gl_debug (DEBUG_VIEW, "Label size: %g, %g", w_label, h_label);
3142 /* Calculate best scale */
3143 x_scale = (double)(w_view - ZOOMTOFIT_PAD) / w_label;
3144 y_scale = (double)(h_view - ZOOMTOFIT_PAD) / h_label;
3145 scale = MIN (x_scale, y_scale);
3146 gl_debug (DEBUG_VIEW, "Candidate zooms: %g, %g => %g", x_scale, y_scale, scale);
3149 gl_debug (DEBUG_VIEW, "Scale: %g", scale);
3150 scale = MIN (scale, zooms[0]*view->home_scale);
3151 scale = MAX (scale, zooms[N_ZOOMS-1]*view->home_scale);
3152 gl_debug (DEBUG_VIEW, "Limitted scale: %g", scale);
3154 set_zoom_real (view, scale/view->home_scale, TRUE);
3157 /*****************************************************************************/
3158 /* Set current zoom factor to explicit value. */
3159 /*****************************************************************************/
3161 gl_view_set_zoom (glView *view,
3164 gl_debug (DEBUG_VIEW, "START");
3166 set_zoom_real (view, zoom, FALSE);
3168 gl_debug (DEBUG_VIEW, "END");
3171 /*---------------------------------------------------------------------------*/
3172 /* PRIVATE. Set canvas scale. *
3173 /*---------------------------------------------------------------------------*/
3175 set_zoom_real (glView *view,
3177 gboolean zoom_to_fit_flag)
3179 gl_debug (DEBUG_VIEW, "START");
3181 g_return_if_fail (view && GL_IS_VIEW (view));
3182 g_return_if_fail (zoom > 0.0);
3184 /* Limit, if needed */
3185 gl_debug (DEBUG_VIEW, "Zoom requested: %g", zoom);
3186 zoom = MIN (zoom, zooms[0]);
3187 zoom = MAX (zoom, zooms[N_ZOOMS-1]);
3188 gl_debug (DEBUG_VIEW, "Limitted zoom: %g", zoom);
3190 if ( zoom != view->zoom ) {
3193 view->zoom_to_fit_flag = zoom_to_fit_flag;
3194 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
3195 zoom*view->home_scale);
3197 g_signal_emit (G_OBJECT(view), signals[ZOOM_CHANGED], 0, zoom);
3201 gl_debug (DEBUG_VIEW, "END");
3206 /*---------------------------------------------------------------------------*/
3207 /* PRIVATE. Size allocation changed callback. */
3208 /*---------------------------------------------------------------------------*/
3210 size_allocate_cb (glView *view)
3212 gl_debug (DEBUG_VIEW, "START");
3214 if (view->zoom_to_fit_flag) {
3215 /* Maintain best fit zoom */
3216 gl_view_zoom_to_fit (view);
3219 gl_debug (DEBUG_VIEW, "END");
3224 /*---------------------------------------------------------------------------*/
3225 /* PRIVATE. Screen changed callback. */
3226 /*---------------------------------------------------------------------------*/
3228 screen_changed_cb (glView *view)
3230 gl_debug (DEBUG_VIEW, "START");
3232 if (gtk_widget_has_screen (GTK_WIDGET (view->canvas))) {
3234 view->home_scale = get_home_scale (view);
3236 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
3237 view->zoom * view->home_scale);
3239 if (view->zoom_to_fit_flag) {
3240 /* Maintain best fit zoom */
3241 gl_view_zoom_to_fit (view);
3246 gl_debug (DEBUG_VIEW, "END");
3251 /*****************************************************************************/
3252 /* Get current zoom factor. */
3253 /*****************************************************************************/
3255 gl_view_get_zoom (glView *view)
3257 gl_debug (DEBUG_VIEW, "");
3259 g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
3264 /*****************************************************************************/
3265 /* Is this the maximum zoom level. */
3266 /*****************************************************************************/
3268 gl_view_is_zoom_max (glView *view)
3270 gl_debug (DEBUG_VIEW, "");
3272 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
3274 return view->zoom >= zooms[0];
3277 /*****************************************************************************/
3278 /* Is this the minimum zoom level. */
3279 /*****************************************************************************/
3281 gl_view_is_zoom_min (glView *view)
3283 gl_debug (DEBUG_VIEW, "");
3285 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3287 return view->zoom <= zooms[N_ZOOMS-1];
3290 /*---------------------------------------------------------------------------*/
3291 /* PRIVATE. Canvas event handler. */
3292 /*---------------------------------------------------------------------------*/
3294 canvas_event (GnomeCanvas *canvas,
3300 gl_debug (DEBUG_VIEW, "");
3302 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3304 /* emit pointer signals regardless of state */
3305 switch (event->type) {
3306 case GDK_MOTION_NOTIFY:
3307 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
3308 gnome_canvas_window_to_world (canvas,
3310 event->motion.y, &x, &y);
3311 g_signal_emit (G_OBJECT(view), signals[POINTER_MOVED], 0, x, y);
3312 break; /* fall through */
3314 case GDK_LEAVE_NOTIFY:
3315 gl_debug (DEBUG_VIEW, "LEAVEW_NOTIFY");
3316 g_signal_emit (G_OBJECT(view), signals[POINTER_EXIT], 0);
3317 break; /* fall through */
3320 break; /* fall through */
3324 switch (view->state) {
3326 case GL_VIEW_STATE_ARROW:
3327 return canvas_event_arrow_mode (canvas, event, view);
3329 case GL_VIEW_STATE_OBJECT_CREATE:
3330 switch (view->create_type) {
3331 case GL_LABEL_OBJECT_BOX:
3332 return gl_view_box_create_event_handler (canvas,
3336 case GL_LABEL_OBJECT_ELLIPSE:
3337 return gl_view_ellipse_create_event_handler (canvas,
3341 case GL_LABEL_OBJECT_LINE:
3342 return gl_view_line_create_event_handler (canvas,
3346 case GL_LABEL_OBJECT_IMAGE:
3347 return gl_view_image_create_event_handler (canvas,
3351 case GL_LABEL_OBJECT_TEXT:
3352 return gl_view_text_create_event_handler (canvas,
3356 case GL_LABEL_OBJECT_BARCODE:
3357 return gl_view_barcode_create_event_handler (canvas,
3362 /*Should not happen!*/
3363 g_warning ("Invalid label object type.");
3368 g_warning ("Invalid view state."); /*Should not happen!*/
3374 /*---------------------------------------------------------------------------*/
3375 /* PRIVATE. Canvas event handler (arrow mode) */
3376 /*---------------------------------------------------------------------------*/
3378 canvas_event_arrow_mode (GnomeCanvas *canvas,
3382 static gdouble x0, y0;
3383 static gboolean dragging = FALSE;
3384 static GnomeCanvasItem *item;
3385 gdouble x, y, x1, y1, x2, y2;
3386 GnomeCanvasGroup *group;
3389 gl_debug (DEBUG_VIEW, "");
3391 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3393 switch (event->type) {
3395 case GDK_BUTTON_PRESS:
3396 gl_debug (DEBUG_VIEW, "BUTTON_PRESS");
3397 gtk_widget_grab_focus (GTK_WIDGET(canvas));
3398 switch (event->button.button) {
3400 gnome_canvas_window_to_world (canvas,
3402 event->button.y, &x, &y);
3404 if (!object_at (view, x, y)) {
3405 if (!(event->button.state & GDK_CONTROL_MASK)) {
3406 gl_view_unselect_all (view);
3410 gnome_canvas_item_grab (canvas->root,
3411 GDK_POINTER_MOTION_MASK |
3412 GDK_BUTTON_RELEASE_MASK |
3413 GDK_BUTTON_PRESS_MASK,
3414 NULL, event->button.time);
3416 gnome_canvas_root (GNOME_CANVAS
3419 gnome_canvas_item_new (group,
3420 gnome_canvas_rect_get_type (),
3426 "outline_color_rgba",
3437 /* activate context menu. */
3438 g_signal_emit (G_OBJECT (view),
3439 signals[CONTEXT_MENU_ACTIVATE], 0,
3440 event->button.button, event->button.time);
3446 case GDK_BUTTON_RELEASE:
3447 gl_debug (DEBUG_VIEW, "BUTTON_RELEASE");
3448 switch (event->button.button) {
3452 gnome_canvas_item_ungrab (canvas->root,
3453 event->button.time);
3454 gnome_canvas_window_to_world (canvas,
3462 gl_view_select_region (view, x1, y1, x2, y2);
3463 gtk_object_destroy (GTK_OBJECT (item));
3472 case GDK_MOTION_NOTIFY:
3473 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
3474 gnome_canvas_window_to_world (canvas,
3476 event->motion.y, &x, &y);
3477 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
3478 gl_debug (DEBUG_VIEW,
3479 "Dragging: (x0=%g, y0=%g), (x=%g, y=%g)", x0, y0, x, y);
3480 gnome_canvas_item_set (item,
3481 "x1", MIN (x, x0) - DELTA,
3482 "y1", MIN (y, y0) - DELTA,
3483 "x2", MAX (x, x0) + DELTA,
3484 "y2", MAX (y, y0) + DELTA,
3492 gl_debug (DEBUG_VIEW, "KEY_PRESS");
3494 switch (event->key.keyval) {
3497 gl_view_move_selection (view,
3498 -1.0 / (view->zoom), 0.0);
3502 gl_view_move_selection (view,
3503 0.0, -1.0 / (view->zoom));
3507 gl_view_move_selection (view,
3508 1.0 / (view->zoom), 0.0);
3512 gl_view_move_selection (view,
3513 0.0, 1.0 / (view->zoom));
3517 gl_view_delete_selection (view);
3518 cursor = gdk_cursor_new (GDK_LEFT_PTR);
3519 gdk_window_set_cursor (view->canvas->window,
3521 gdk_cursor_unref (cursor);
3527 return TRUE; /* We handled this or we were dragging. */
3530 gl_debug (DEBUG_VIEW, "default");
3536 /*---------------------------------------------------------------------------*/
3537 /* PRIVATE. Handle "selection-clear" signal. */
3538 /*---------------------------------------------------------------------------*/
3540 selection_clear_cb (GtkWidget *widget,
3541 GdkEventSelection *event,
3544 glView *view = GL_VIEW (data);
3546 gl_debug (DEBUG_VIEW, "START");
3548 g_return_if_fail (view && GL_IS_VIEW (view));
3550 view->have_selection = FALSE;
3551 g_object_unref (view->selection_data);
3552 view->selection_data = NULL;
3554 gl_debug (DEBUG_VIEW, "END");
3557 /*---------------------------------------------------------------------------*/
3558 /* PRIVATE. Handle "selection-get" signal. */
3559 /*---------------------------------------------------------------------------*/
3561 selection_get_cb (GtkWidget *widget,
3562 GtkSelectionData *selection_data,
3567 glView *view = GL_VIEW (data);
3569 glXMLLabelStatus status;
3571 gl_debug (DEBUG_VIEW, "START");
3573 g_return_if_fail (view && GL_IS_VIEW (view));
3575 if (view->have_selection) {
3577 buffer = gl_xml_label_save_buffer (view->selection_data,
3579 gtk_selection_data_set (selection_data,
3580 GDK_SELECTION_TYPE_STRING, 8, buffer,
3585 gl_debug (DEBUG_VIEW, "END");
3588 /*---------------------------------------------------------------------------*/
3589 /* PRIVATE. Handle "selection-received" signal. (Result of Paste) */
3590 /*---------------------------------------------------------------------------*/
3592 selection_received_cb (GtkWidget *widget,
3593 GtkSelectionData *selection_data,
3597 glView *view = GL_VIEW (data);
3598 glLabel *label = NULL;
3599 glXMLLabelStatus status;
3601 glLabelObject *object, *newobject;
3602 glViewObject *view_object;
3604 gl_debug (DEBUG_VIEW, "START");
3606 g_return_if_fail (view && GL_IS_VIEW (view));
3608 if (selection_data->length < 0) {
3611 if (selection_data->type != GDK_SELECTION_TYPE_STRING) {
3615 gl_view_unselect_all (view);
3617 label = gl_xml_label_open_buffer (selection_data->data, &status);
3618 for (p = label->objects; p != NULL; p = p_next) {
3621 object = (glLabelObject *) p->data;
3622 newobject = gl_label_object_dup (object, view->label);
3624 gl_debug (DEBUG_VIEW, "object pasted");
3626 if (GL_IS_LABEL_BOX (newobject)) {
3627 view_object = gl_view_box_new (GL_LABEL_BOX(newobject),
3629 } else if (GL_IS_LABEL_ELLIPSE (newobject)) {
3630 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(newobject),
3632 } else if (GL_IS_LABEL_LINE (newobject)) {
3633 view_object = gl_view_line_new (GL_LABEL_LINE(newobject),
3635 } else if (GL_IS_LABEL_IMAGE (newobject)) {
3636 view_object = gl_view_image_new (GL_LABEL_IMAGE(newobject),
3638 } else if (GL_IS_LABEL_TEXT (newobject)) {
3639 view_object = gl_view_text_new (GL_LABEL_TEXT(newobject),
3641 } else if (GL_IS_LABEL_BARCODE (newobject)) {
3642 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(newobject),
3645 /* Should not happen! */
3647 g_warning ("Invalid label object type.");
3649 gl_view_select_object (view, view_object);
3651 g_object_unref (label);
3653 gl_debug (DEBUG_VIEW, "END");
3656 /****************************************************************************/
3657 /* Set default font family. */
3658 /****************************************************************************/
3660 gl_view_set_default_font_family (glView *view,
3661 const gchar *font_family)
3663 gl_debug (DEBUG_VIEW, "START");
3665 g_return_if_fail (view && GL_IS_VIEW (view));
3667 if (view->default_font_family) {
3668 g_free (view->default_font_family);
3670 view->default_font_family = g_strdup (font_family);
3672 gl_debug (DEBUG_VIEW, "END");
3676 /****************************************************************************/
3677 /* Set default font size. */
3678 /****************************************************************************/
3680 gl_view_set_default_font_size (glView *view,
3683 gl_debug (DEBUG_VIEW, "START");
3685 g_return_if_fail (view && GL_IS_VIEW (view));
3687 view->default_font_size = font_size;
3689 gl_debug (DEBUG_VIEW, "END");
3693 /****************************************************************************/
3694 /* Set default font weight. */
3695 /****************************************************************************/
3697 gl_view_set_default_font_weight (glView *view,
3698 GnomeFontWeight font_weight)
3700 gl_debug (DEBUG_VIEW, "START");
3702 g_return_if_fail (view && GL_IS_VIEW (view));
3704 view->default_font_weight = font_weight;
3706 gl_debug (DEBUG_VIEW, "END");
3710 /****************************************************************************/
3711 /* Set default font italic flag. */
3712 /****************************************************************************/
3714 gl_view_set_default_font_italic_flag (glView *view,
3715 gboolean font_italic_flag)
3717 gl_debug (DEBUG_VIEW, "START");
3719 g_return_if_fail (view && GL_IS_VIEW (view));
3721 view->default_font_italic_flag = font_italic_flag;
3723 gl_debug (DEBUG_VIEW, "END");
3727 /****************************************************************************/
3728 /* Set default text color. */
3729 /****************************************************************************/
3731 gl_view_set_default_text_color (glView *view,
3734 gl_debug (DEBUG_VIEW, "START");
3736 g_return_if_fail (view && GL_IS_VIEW (view));
3738 view->default_text_color = text_color;
3740 gl_debug (DEBUG_VIEW, "END");
3744 /****************************************************************************/
3745 /* Set default text alignment. */
3746 /****************************************************************************/
3748 gl_view_set_default_text_alignment (glView *view,
3749 GtkJustification text_alignment)
3751 gl_debug (DEBUG_VIEW, "START");
3753 g_return_if_fail (view && GL_IS_VIEW (view));
3755 view->default_text_alignment = text_alignment;
3756 gl_debug (DEBUG_VIEW, "END");
3759 /****************************************************************************/
3760 /* Set default text line spacing. */
3761 /****************************************************************************/
3763 gl_view_set_default_text_line_spacing (glView *view,
3764 gdouble text_line_spacing)
3766 gl_debug (DEBUG_VIEW, "START");
3768 g_return_if_fail (view && GL_IS_VIEW (view));
3770 view->default_text_line_spacing = text_line_spacing;
3772 gl_debug (DEBUG_VIEW, "END");
3776 /****************************************************************************/
3777 /* Set default line width. */
3778 /****************************************************************************/
3780 gl_view_set_default_line_width (glView *view,
3783 gl_debug (DEBUG_VIEW, "START");
3785 g_return_if_fail (view && GL_IS_VIEW (view));
3787 view->default_line_width = line_width;
3789 gl_debug (DEBUG_VIEW, "END");
3793 /****************************************************************************/
3794 /* Set default line color. */
3795 /****************************************************************************/
3797 gl_view_set_default_line_color (glView *view,
3800 gl_debug (DEBUG_VIEW, "START");
3802 g_return_if_fail (view && GL_IS_VIEW (view));
3804 view->default_line_color = line_color;
3806 gl_debug (DEBUG_VIEW, "END");
3810 /****************************************************************************/
3811 /* Set default fill color. */
3812 /****************************************************************************/
3814 gl_view_set_default_fill_color (glView *view,
3817 gl_debug (DEBUG_VIEW, "START");
3819 g_return_if_fail (view && GL_IS_VIEW (view));
3821 view->default_fill_color = fill_color;
3823 gl_debug (DEBUG_VIEW, "END");
3828 /****************************************************************************/
3829 /* Get default font family. */
3830 /****************************************************************************/
3832 gl_view_get_default_font_family (glView *view)
3834 gl_debug (DEBUG_VIEW, "START");
3836 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
3838 gl_debug (DEBUG_VIEW, "END");
3840 return g_strdup (view->default_font_family);
3844 /****************************************************************************/
3845 /* Get default font size. */
3846 /****************************************************************************/
3848 gl_view_get_default_font_size (glView *view)
3850 gl_debug (DEBUG_VIEW, "START");
3852 g_return_val_if_fail (view && GL_IS_VIEW (view), 12.0);
3854 gl_debug (DEBUG_VIEW, "END");
3856 return view->default_font_size;
3860 /****************************************************************************/
3861 /* Get default font weight. */
3862 /****************************************************************************/
3864 gl_view_get_default_font_weight (glView *view)
3866 gl_debug (DEBUG_VIEW, "START");
3868 g_return_val_if_fail (view && GL_IS_VIEW (view), GNOME_FONT_BOOK);
3870 gl_debug (DEBUG_VIEW, "END");
3872 return view->default_font_weight;
3876 /****************************************************************************/
3877 /* Get default font italic flag. */
3878 /****************************************************************************/
3880 gl_view_get_default_font_italic_flag (glView *view)
3882 gl_debug (DEBUG_VIEW, "START");
3884 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3886 gl_debug (DEBUG_VIEW, "END");
3888 return view->default_font_italic_flag;
3892 /****************************************************************************/
3893 /* Get default text color. */
3894 /****************************************************************************/
3896 gl_view_get_default_text_color (glView *view)
3898 gl_debug (DEBUG_VIEW, "START");
3900 g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
3902 gl_debug (DEBUG_VIEW, "END");
3904 return view->default_text_color;
3908 /****************************************************************************/
3909 /* Get default text alignment. */
3910 /****************************************************************************/
3912 gl_view_get_default_text_alignment (glView *view)
3914 gl_debug (DEBUG_VIEW, "START");
3916 g_return_val_if_fail (view && GL_IS_VIEW (view), GTK_JUSTIFY_LEFT);
3918 gl_debug (DEBUG_VIEW, "END");
3920 return view->default_text_alignment;
3923 /****************************************************************************/
3924 /* Get default text line spacing. */
3925 /****************************************************************************/
3927 gl_view_get_default_text_line_spacing (glView *view)
3929 gl_debug (DEBUG_VIEW, "START");
3931 g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
3933 gl_debug (DEBUG_VIEW, "END");
3935 return view->default_text_line_spacing;
3940 /****************************************************************************/
3941 /* Get default line width. */
3942 /****************************************************************************/
3944 gl_view_get_default_line_width (glView *view)
3946 gl_debug (DEBUG_VIEW, "START");
3948 g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
3950 gl_debug (DEBUG_VIEW, "END");
3952 return view->default_line_width;
3956 /****************************************************************************/
3957 /* Get default line color. */
3958 /****************************************************************************/
3959 guint gl_view_get_default_line_color (glView *view)
3961 gl_debug (DEBUG_VIEW, "START");
3963 g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
3965 gl_debug (DEBUG_VIEW, "END");
3967 return view->default_line_color;
3971 /****************************************************************************/
3972 /* Get default fill color. */
3973 /****************************************************************************/
3974 guint gl_view_get_default_fill_color (glView *view)
3976 gl_debug (DEBUG_VIEW, "START");
3978 g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
3980 gl_debug (DEBUG_VIEW, "END");
3982 return view->default_fill_color;