1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
4 * (GLABELS) Label and Business Card Creation program for GNOME
6 * view.c: GLabels View module
8 * Copyright (C) 2001-2007 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/gtklayout.h>
32 #include <gtk/gtkselection.h>
33 #include <gtk/gtkinvisible.h>
34 #include <gdk/gdkkeysyms.h>
39 #include "cairo-label-path.h"
40 #include "cairo-markup-path.h"
41 #include "view-object.h"
43 #include "view-ellipse.h"
44 #include "view-line.h"
45 #include "view-image.h"
46 #include "view-text.h"
47 #include "view-barcode.h"
48 #include "xml-label.h"
55 /*==========================================================================*/
56 /* Private macros and constants. */
57 /*==========================================================================*/
59 #define BG_COLOR GL_COLOR (192, 192, 192)
61 #define PAPER_RGB_ARGS 1.0, 1.0, 1.0
62 #define GRID_RGB_ARGS 0.753, 0.753, 0.753
63 #define MARKUP_RGB_ARGS 0.94, 0.39, 0.39
64 #define OUTLINE_RGB_ARGS 0.68, 0.85, 0.90
65 #define SELECT_LINE_RGBA_ARGS 0.0, 0.0, 1.0, 0.5
66 #define SELECT_FILL_RGBA_ARGS 0.75, 0.75, 1.0, 0.5
68 #define GRID_LINE_WIDTH_PIXELS 1.0
69 #define MARKUP_LINE_WIDTH_PIXELS 1.0
70 #define OUTLINE_WIDTH_PIXELS 3.0
71 #define SELECT_LINE_WIDTH_PIXELS 3.0
73 #define ZOOMTOFIT_PAD 16
75 #define POINTS_PER_MM 2.83464566929
77 /*==========================================================================*/
79 /*==========================================================================*/
83 CONTEXT_MENU_ACTIVATE,
92 /*==========================================================================*/
94 /*==========================================================================*/
96 static guint signals[LAST_SIGNAL] = {0};
98 /* "CLIPBOARD" selection */
99 static GdkAtom clipboard_atom = GDK_NONE;
101 static gdouble zooms[] = {
118 #define N_ZOOMS G_N_ELEMENTS(zooms)
121 /*==========================================================================*/
122 /* Local function prototypes */
123 /*==========================================================================*/
125 static void gl_view_finalize (GObject *object);
127 static void gl_view_construct (glView *view,
130 static gdouble get_home_scale (glView *view);
132 static gboolean expose_cb (glView *view,
133 GdkEventExpose *event);
135 static void realize_cb (glView *view);
137 static void size_allocate_cb (glView *view,
138 GtkAllocation *allocation);
140 static void screen_changed_cb (glView *view);
142 static void label_changed_cb (glView *view);
144 static void label_resized_cb (glView *view);
146 static void label_object_added_cb (glView *view,
147 glLabelObject *object);
149 static void draw_layers (glView *view,
152 static void draw_bg_layer (glView *view,
154 static void draw_grid_layer (glView *view,
156 static void draw_markup_layer (glView *view,
158 static void draw_objects_layer (glView *view,
160 static void draw_fg_layer (glView *view,
162 static void draw_highlight_layer (glView *view,
164 static void draw_select_region_layer (glView *view,
167 static void select_object_real (glView *view,
168 glViewObject *view_object);
169 static void unselect_object_real (glView *view,
170 glViewObject *view_object);
172 static glViewObject *view_view_object_at (glView *view,
177 static void set_zoom_real (glView *view,
179 gboolean scale_to_fit_flag);
181 static void selection_clear_cb (GtkWidget *widget,
182 GdkEventSelection *event,
185 static void selection_get_cb (GtkWidget *widget,
186 GtkSelectionData *selection_data,
191 static void selection_received_cb (GtkWidget *widget,
192 GtkSelectionData *selection_data,
196 static gboolean focus_in_event_cb (glView *view,
197 GdkEventFocus *event);
199 static gboolean focus_out_event_cb (glView *view,
200 GdkEventFocus *event);
202 static gboolean enter_notify_event_cb (glView *view,
203 GdkEventCrossing *event);
205 static gboolean leave_notify_event_cb (glView *view,
206 GdkEventCrossing *event);
208 static gboolean motion_notify_event_cb (glView *view,
209 GdkEventMotion *event);
211 static gboolean button_press_event_cb (glView *view,
212 GdkEventButton *event);
214 static gboolean button_release_event_cb (glView *view,
215 GdkEventButton *event);
217 static gboolean key_press_event_cb (glView *view,
221 /****************************************************************************/
222 /* Boilerplate Object stuff. */
223 /****************************************************************************/
224 G_DEFINE_TYPE (glView, gl_view, GTK_TYPE_VBOX);
227 gl_view_class_init (glViewClass *class)
229 GObjectClass *object_class = G_OBJECT_CLASS (class);
231 gl_debug (DEBUG_VIEW, "START");
233 gl_view_parent_class = g_type_class_peek_parent (class);
235 object_class->finalize = gl_view_finalize;
237 signals[SELECTION_CHANGED] =
238 g_signal_new ("selection_changed",
239 G_OBJECT_CLASS_TYPE (object_class),
241 G_STRUCT_OFFSET (glViewClass, selection_changed),
243 gl_marshal_VOID__VOID,
247 signals[CONTEXT_MENU_ACTIVATE] =
248 g_signal_new ("context_menu_activate",
249 G_OBJECT_CLASS_TYPE (object_class),
251 G_STRUCT_OFFSET (glViewClass, context_menu_activate),
253 gl_marshal_VOID__INT_UINT,
255 2, G_TYPE_INT, G_TYPE_UINT);
257 signals[ZOOM_CHANGED] =
258 g_signal_new ("zoom_changed",
259 G_OBJECT_CLASS_TYPE (object_class),
261 G_STRUCT_OFFSET (glViewClass, zoom_changed),
263 gl_marshal_VOID__DOUBLE,
267 signals[POINTER_MOVED] =
268 g_signal_new ("pointer_moved",
269 G_OBJECT_CLASS_TYPE (object_class),
271 G_STRUCT_OFFSET (glViewClass, pointer_moved),
273 gl_marshal_VOID__DOUBLE_DOUBLE,
275 2, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
277 signals[POINTER_EXIT] =
278 g_signal_new ("pointer_exit",
279 G_OBJECT_CLASS_TYPE (object_class),
281 G_STRUCT_OFFSET (glViewClass, pointer_exit),
283 gl_marshal_VOID__VOID,
287 signals[MODE_CHANGED] =
288 g_signal_new ("mode_changed",
289 G_OBJECT_CLASS_TYPE (object_class),
291 G_STRUCT_OFFSET (glViewClass, mode_changed),
293 gl_marshal_VOID__VOID,
297 gl_debug (DEBUG_VIEW, "END");
301 gl_view_init (glView *view)
306 gl_debug (DEBUG_VIEW, "START");
309 view->grid_visible = TRUE;
310 view->grid_spacing = 9;
311 view->markup_visible = TRUE;
312 view->default_font_family = NULL;
313 view->mode = GL_VIEW_MODE_ARROW;
314 view->object_list = NULL;
315 view->selected_object_list = NULL;
317 view->home_scale = get_home_scale (view);
322 view->canvas = gtk_layout_new (NULL, NULL);
323 wscroll = gtk_scrolled_window_new (NULL, NULL);
324 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (wscroll),
325 GTK_POLICY_AUTOMATIC,
326 GTK_POLICY_AUTOMATIC);
327 gtk_box_pack_start (GTK_BOX (view), wscroll, TRUE, TRUE, 0);
328 gtk_container_add (GTK_CONTAINER (wscroll), view->canvas);
330 bg_color = gl_color_to_gdk_color (BG_COLOR);
331 gtk_widget_modify_bg (GTK_WIDGET (view->canvas), GTK_STATE_NORMAL, bg_color);
334 GTK_WIDGET_SET_FLAGS (GTK_WIDGET (view->canvas), GTK_CAN_FOCUS);
336 gtk_widget_add_events (GTK_WIDGET (view->canvas),
337 (GDK_FOCUS_CHANGE_MASK |
338 GDK_ENTER_NOTIFY_MASK |
339 GDK_LEAVE_NOTIFY_MASK |
340 GDK_POINTER_MOTION_MASK |
341 GDK_BUTTON_PRESS_MASK |
342 GDK_BUTTON_RELEASE_MASK |
343 GDK_KEY_PRESS_MASK));
345 g_signal_connect_swapped (G_OBJECT (view->canvas), "expose-event",
346 G_CALLBACK (expose_cb), view);
347 g_signal_connect_swapped (G_OBJECT (view->canvas), "realize",
348 G_CALLBACK (realize_cb), view);
349 g_signal_connect_swapped (G_OBJECT (view->canvas), "size-allocate",
350 G_CALLBACK (size_allocate_cb), view);
351 g_signal_connect_swapped (G_OBJECT (view->canvas), "screen-changed",
352 G_CALLBACK (screen_changed_cb), view);
353 g_signal_connect_swapped (G_OBJECT (view->canvas), "focus-in-event",
354 G_CALLBACK (focus_in_event_cb), view);
355 g_signal_connect_swapped (G_OBJECT (view->canvas), "focus-out-event",
356 G_CALLBACK (focus_out_event_cb), view);
357 g_signal_connect_swapped (G_OBJECT (view->canvas), "enter-notify-event",
358 G_CALLBACK (enter_notify_event_cb), view);
359 g_signal_connect_swapped (G_OBJECT (view->canvas), "leave-notify-event",
360 G_CALLBACK (leave_notify_event_cb), view);
361 g_signal_connect_swapped (G_OBJECT (view->canvas), "motion-notify-event",
362 G_CALLBACK (motion_notify_event_cb), view);
363 g_signal_connect_swapped (G_OBJECT (view->canvas), "button-press-event",
364 G_CALLBACK (button_press_event_cb), view);
365 g_signal_connect_swapped (G_OBJECT (view->canvas), "button-release-event",
366 G_CALLBACK (button_release_event_cb), view);
367 g_signal_connect_swapped (G_OBJECT (view->canvas), "key-press-event",
368 G_CALLBACK (key_press_event_cb), view);
373 view->have_selection = FALSE;
374 view->selection_data = NULL;
375 view->invisible = gtk_invisible_new ();
376 if (!clipboard_atom) {
377 clipboard_atom = gdk_atom_intern ("GLABELS_CLIPBOARD", FALSE);
379 gtk_selection_add_target (view->invisible,
380 clipboard_atom, GDK_SELECTION_TYPE_STRING, 1);
381 g_signal_connect (G_OBJECT (view->invisible),
382 "selection_clear_event",
383 G_CALLBACK (selection_clear_cb), view);
384 g_signal_connect (G_OBJECT (view->invisible), "selection_get",
385 G_CALLBACK (selection_get_cb), view);
386 g_signal_connect (G_OBJECT (view->invisible),
387 "selection_received",
388 G_CALLBACK (selection_received_cb), view);
391 * Defaults from preferences
393 gl_view_set_default_font_family (view, gl_prefs->default_font_family);
394 gl_view_set_default_font_size (view, gl_prefs->default_font_size);
395 gl_view_set_default_font_weight (view, gl_prefs->default_font_weight);
396 gl_view_set_default_font_italic_flag (view, gl_prefs->default_font_italic_flag);
397 gl_view_set_default_text_color (view, gl_prefs->default_text_color);
398 gl_view_set_default_text_alignment (view, gl_prefs->default_text_alignment);
399 gl_view_set_default_text_line_spacing (view, gl_prefs->default_text_line_spacing);
400 gl_view_set_default_line_width (view, gl_prefs->default_line_width);
401 gl_view_set_default_line_color (view, gl_prefs->default_line_color);
402 gl_view_set_default_fill_color (view, gl_prefs->default_fill_color);
404 gl_debug (DEBUG_VIEW, "END");
408 gl_view_finalize (GObject *object)
410 glView *view = GL_VIEW (object);
412 gl_debug (DEBUG_VIEW, "START");
414 g_return_if_fail (object != NULL);
415 g_return_if_fail (GL_IS_VIEW (object));
417 if (view->default_font_family) {
418 g_free (view->default_font_family);
421 G_OBJECT_CLASS (gl_view_parent_class)->finalize (object);
423 gl_debug (DEBUG_VIEW, "END");
426 /****************************************************************************/
427 /* NEW view object. */
428 /****************************************************************************/
430 gl_view_new (glLabel *label)
434 gl_debug (DEBUG_VIEW, "START");
436 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
438 view = g_object_new (GL_TYPE_VIEW, NULL);
440 gl_view_construct (view, label);
442 gl_debug (DEBUG_VIEW, "END");
444 return GTK_WIDGET (view);
447 /*---------------------------------------------------------------------------*/
448 /* PRIVATE. Construct composite widget. */
449 /*---------------------------------------------------------------------------*/
451 gl_view_construct (glView *view,
455 glLabelObject *object;
457 gl_debug (DEBUG_VIEW, "START");
459 g_return_if_fail (GL_IS_VIEW (view));
463 for (p_obj = label->objects; p_obj != NULL; p_obj = p_obj->next)
465 object = GL_LABEL_OBJECT (p_obj->data);
467 if (GL_IS_LABEL_BOX (object)) {
468 gl_view_box_new (GL_LABEL_BOX(object), view);
469 } else if (GL_IS_LABEL_ELLIPSE (object)) {
470 gl_view_ellipse_new (GL_LABEL_ELLIPSE(object), view);
471 } else if (GL_IS_LABEL_LINE (object)) {
472 gl_view_line_new (GL_LABEL_LINE(object), view);
473 } else if (GL_IS_LABEL_IMAGE (object)) {
474 gl_view_image_new (GL_LABEL_IMAGE(object), view);
475 } else if (GL_IS_LABEL_TEXT (object)) {
476 gl_view_text_new (GL_LABEL_TEXT(object), view);
477 } else if (GL_IS_LABEL_BARCODE (object)) {
478 gl_view_barcode_new (GL_LABEL_BARCODE(object), view);
480 /* Should not happen! */
481 g_message ("Invalid label object type.");
485 g_signal_connect_swapped (G_OBJECT (view->label), "changed",
486 G_CALLBACK (label_changed_cb), view);
487 g_signal_connect_swapped (G_OBJECT (view->label), "size_changed",
488 G_CALLBACK (label_resized_cb), view);
489 g_signal_connect_swapped (G_OBJECT (view->label), "object_added",
490 G_CALLBACK (label_object_added_cb), view);
492 gl_debug (DEBUG_VIEW, "END");
495 /*---------------------------------------------------------------------------*/
496 /* PRIAVTE. Calculate 1:1 scale for screen. */
497 /*---------------------------------------------------------------------------*/
499 get_home_scale (glView *view)
502 gdouble screen_width_pixels;
503 gdouble screen_width_mm;
504 gdouble screen_height_pixels;
505 gdouble screen_height_mm;
506 gdouble x_pixels_per_mm;
507 gdouble y_pixels_per_mm;
510 if (view->canvas == NULL) return 1.0;
512 if (!gtk_widget_has_screen (GTK_WIDGET (view->canvas))) return 1.0;
514 screen = gtk_widget_get_screen (GTK_WIDGET (view->canvas));
516 gl_debug (DEBUG_VIEW, "Screen = %p", screen);
518 screen_width_pixels = gdk_screen_get_width (screen);
519 screen_width_mm = gdk_screen_get_width_mm (screen);
520 screen_height_pixels = gdk_screen_get_height (screen);
521 screen_height_mm = gdk_screen_get_height_mm (screen);
523 x_pixels_per_mm = screen_width_pixels / screen_width_mm;
524 y_pixels_per_mm = screen_height_pixels / screen_height_mm;
526 gl_debug (DEBUG_VIEW, "Horizontal dot pitch: %g pixels/mm (%g dpi)",
527 x_pixels_per_mm, x_pixels_per_mm * 25.4);
528 gl_debug (DEBUG_VIEW, "Vertical dot pitch: %g pixels/mm (%g dpi)",
529 y_pixels_per_mm, y_pixels_per_mm * 25.4);
531 scale = (x_pixels_per_mm + y_pixels_per_mm) / 2.0;
533 gl_debug (DEBUG_VIEW, "Average dot pitch: %g pixels/mm (%g dpi)",
534 scale, scale * 25.4);
536 scale /= POINTS_PER_MM;
538 gl_debug (DEBUG_VIEW, "Scale = %g pixels/point", scale);
540 /* Make sure scale is somewhat sane. */
541 if ( (scale < 0.25) || (scale > 4.0) ) return 1.0;
546 /*---------------------------------------------------------------------------*/
547 /* Schedule canvas update. */
548 /*---------------------------------------------------------------------------*/
550 gl_view_update (glView *view)
555 gl_debug (DEBUG_VIEW, "START");
557 widget = GTK_WIDGET (view->canvas);
559 if (!widget->window) return;
561 if ( !view->update_scheduled_flag )
563 view->update_scheduled_flag = TRUE;
565 region = gdk_drawable_get_clip_region (widget->window);
566 /* redraw the cairo canvas completely by exposing it */
567 gdk_window_invalidate_region (widget->window, region, TRUE);
568 gdk_region_destroy (region);
571 gl_debug (DEBUG_VIEW, "END");
574 /*---------------------------------------------------------------------------*/
575 /* Schedule canvas region update. */
576 /*---------------------------------------------------------------------------*/
578 gl_view_update_region (glView *view,
580 glLabelRegion *region)
586 gl_debug (DEBUG_VIEW, "START");
588 widget = GTK_WIDGET (view->canvas);
590 if (!widget->window) return;
592 x = MIN (region->x1, region->x2);
593 y = MIN (region->y1, region->y2);
594 w = fabs (region->x2 - region->x1);
595 h = fabs (region->y2 - region->y1);
597 cairo_user_to_device (cr, &x, &y);
598 cairo_user_to_device_distance (cr, &w, &h);
605 gdk_window_invalidate_rect (widget->window, &rect, TRUE);
607 gl_debug (DEBUG_VIEW, "END");
610 /*---------------------------------------------------------------------------*/
611 /* PRIVATE. Expose handler. */
612 /*---------------------------------------------------------------------------*/
614 expose_cb (glView *view,
615 GdkEventExpose *event)
619 gl_debug (DEBUG_VIEW, "START");
621 view->update_scheduled_flag = FALSE;
624 cr = gdk_cairo_create (GTK_LAYOUT (view->canvas)->bin_window);
627 event->area.x, event->area.y,
628 event->area.width, event->area.height);
631 draw_layers (view, cr);
635 gl_debug (DEBUG_VIEW, "END");
640 /*---------------------------------------------------------------------------*/
641 /* PRIVATE. Realize handler. */
642 /*---------------------------------------------------------------------------*/
644 realize_cb (glView *view)
646 g_return_if_fail (view && GL_IS_VIEW (view));
648 gl_debug (DEBUG_VIEW, "START");
650 gl_debug (DEBUG_VIEW, "END");
653 /*---------------------------------------------------------------------------*/
654 /* PRIVATE. Size allocation changed callback. */
655 /*---------------------------------------------------------------------------*/
657 size_allocate_cb (glView *view,
658 GtkAllocation *allocation)
660 gl_debug (DEBUG_VIEW, "START");
662 GTK_LAYOUT (view->canvas)->hadjustment->page_size = allocation->width;
663 GTK_LAYOUT (view->canvas)->hadjustment->page_increment = allocation->width / 2;
665 GTK_LAYOUT (view->canvas)->vadjustment->page_size = allocation->height;
666 GTK_LAYOUT (view->canvas)->vadjustment->page_increment = allocation->height / 2;
668 g_signal_emit_by_name (GTK_LAYOUT (view->canvas)->hadjustment, "changed");
669 g_signal_emit_by_name (GTK_LAYOUT (view->canvas)->vadjustment, "changed");
671 if (view->zoom_to_fit_flag) {
672 /* Maintain best fit zoom */
673 gl_view_zoom_to_fit (view);
676 gl_debug (DEBUG_VIEW, "END");
681 /*---------------------------------------------------------------------------*/
682 /* PRIVATE. Screen changed callback. */
683 /*---------------------------------------------------------------------------*/
685 screen_changed_cb (glView *view)
687 gl_debug (DEBUG_VIEW, "START");
689 if (gtk_widget_has_screen (GTK_WIDGET (view->canvas))) {
691 view->home_scale = get_home_scale (view);
693 if (view->zoom_to_fit_flag) {
694 /* Maintain best fit zoom */
695 gl_view_zoom_to_fit (view);
699 gl_debug (DEBUG_VIEW, "END");
702 /*---------------------------------------------------------------------------*/
703 /* PRIVATE. Handle label changed event. */
704 /*---------------------------------------------------------------------------*/
706 label_changed_cb (glView *view)
708 g_return_if_fail (view && GL_IS_VIEW (view));
710 gl_debug (DEBUG_VIEW, "START");
712 gl_view_update (view);
714 gl_debug (DEBUG_VIEW, "END");
718 /*---------------------------------------------------------------------------*/
719 /* PRIVATE. Handle label resize event. */
720 /*---------------------------------------------------------------------------*/
722 label_resized_cb (glView *view)
724 g_return_if_fail (view && GL_IS_VIEW (view));
726 gl_debug (DEBUG_VIEW, "START");
728 g_signal_emit_by_name (GTK_LAYOUT (view->canvas)->hadjustment, "changed");
729 g_signal_emit_by_name (GTK_LAYOUT (view->canvas)->vadjustment, "changed");
731 gl_view_update (view);
733 gl_debug (DEBUG_VIEW, "END");
737 /*---------------------------------------------------------------------------*/
738 /* PRIVATE. Handle new label object. */
739 /*---------------------------------------------------------------------------*/
741 label_object_added_cb (glView *view,
742 glLabelObject *object)
744 glViewObject *view_object;
746 g_return_if_fail (view && GL_IS_VIEW (view));
747 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
749 if (GL_IS_LABEL_BOX (object)) {
750 view_object = gl_view_box_new (GL_LABEL_BOX(object), view);
751 } else if (GL_IS_LABEL_ELLIPSE (object)) {
752 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object), view);
753 } else if (GL_IS_LABEL_LINE (object)) {
754 view_object = gl_view_line_new (GL_LABEL_LINE(object), view);
755 } else if (GL_IS_LABEL_IMAGE (object)) {
756 view_object = gl_view_image_new (GL_LABEL_IMAGE(object), view);
757 } else if (GL_IS_LABEL_TEXT (object)) {
758 view_object = gl_view_text_new (GL_LABEL_TEXT(object), view);
759 } else if (GL_IS_LABEL_BARCODE (object)) {
760 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(object), view);
762 /* Should not happen! */
764 g_message ("Invalid label object type.");
767 gl_view_select_object (view, view_object);
770 /*---------------------------------------------------------------------------*/
771 /* PRIVATE. Create, draw and order layers. */
772 /*---------------------------------------------------------------------------*/
774 draw_layers (glView *view,
779 gint canvas_w, canvas_h;
781 g_return_if_fail (view && GL_IS_VIEW (view));
782 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
784 gl_debug (DEBUG_VIEW, "START");
786 scale = view->zoom * view->home_scale;
788 gl_label_get_size (view->label, &w, &h);
790 scale = view->home_scale * view->zoom;
791 gtk_layout_set_size (GTK_LAYOUT (view->canvas), w*scale+8, h*scale+8);
793 gdk_drawable_get_size (GTK_LAYOUT (view->canvas)->bin_window, &canvas_w, &canvas_h);
795 view->x0 = (canvas_w/scale - w) / 2.0;
796 view->y0 = (canvas_h/scale - h) / 2.0;
802 cairo_scale (cr, scale, scale);
803 cairo_translate (cr, view->x0, view->y0);
805 draw_bg_layer (view, cr);
806 draw_grid_layer (view, cr);
807 draw_markup_layer (view, cr);
808 draw_objects_layer (view, cr);
809 draw_fg_layer (view, cr);
810 draw_highlight_layer (view, cr);
811 draw_select_region_layer (view, cr);
815 gl_debug (DEBUG_VIEW, "END");
819 /*---------------------------------------------------------------------------*/
820 /* PRIVATE. Draw background */
821 /*---------------------------------------------------------------------------*/
823 draw_bg_layer (glView *view,
826 g_return_if_fail (view && GL_IS_VIEW (view));
827 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
829 gl_cairo_label_path (cr, view->label->template, view->label->rotate_flag, FALSE);
831 cairo_set_source_rgb (cr, PAPER_RGB_ARGS);
832 cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
836 /*---------------------------------------------------------------------------*/
837 /* PRIVATE. Draw grid lines. */
838 /*---------------------------------------------------------------------------*/
840 draw_grid_layer (glView *view,
846 const glTemplateLabelType *label_type;
848 gl_debug (DEBUG_VIEW, "START");
850 g_return_if_fail (view && GL_IS_VIEW (view));
851 g_return_if_fail (view->label && GL_IS_LABEL(view->label));
853 if (view->grid_visible)
856 label_type = gl_template_get_first_label_type (view->label->template);
858 gl_label_get_size (view->label, &w, &h);
860 if (label_type->shape == GL_TEMPLATE_SHAPE_RECT) {
864 /* round labels, adjust grid to line up with center of label. */
865 x0 = fmod (w/2.0, view->grid_spacing);
866 y0 = fmod (h/2.0, view->grid_spacing);
872 cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
873 cairo_set_line_width (cr, GRID_LINE_WIDTH_PIXELS/(view->home_scale * view->zoom));
874 cairo_set_source_rgb (cr, GRID_RGB_ARGS);
876 for ( x=x0+view->grid_spacing; x < w; x += view->grid_spacing )
878 cairo_move_to (cr, x, 0);
879 cairo_line_to (cr, x, h);
883 for ( y=y0+view->grid_spacing; y < h; y += view->grid_spacing )
885 cairo_move_to (cr, 0, y);
886 cairo_line_to (cr, w, y);
894 gl_debug (DEBUG_VIEW, "END");
897 /*---------------------------------------------------------------------------*/
898 /* PRIVATE. Draw markup layer. */
899 /*---------------------------------------------------------------------------*/
901 draw_markup_layer (glView *view,
905 const glTemplateLabelType *label_type;
907 glTemplateMarkup *markup;
909 g_return_if_fail (view && GL_IS_VIEW (view));
910 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
912 if (view->markup_visible)
916 label_type = gl_template_get_first_label_type (label->template);
920 cairo_set_line_width (cr, MARKUP_LINE_WIDTH_PIXELS/(view->home_scale * view->zoom));
921 cairo_set_source_rgb (cr, MARKUP_RGB_ARGS);
923 for ( p=label_type->markups; p != NULL; p=p->next )
925 markup = (glTemplateMarkup *)p->data;
927 gl_cairo_markup_path (cr, markup, label);
937 /*---------------------------------------------------------------------------*/
938 /* PRIVATE. Draw objects layer. */
939 /*---------------------------------------------------------------------------*/
941 draw_objects_layer (glView *view,
944 gl_label_draw (view->label, cr, TRUE, NULL);
947 /*---------------------------------------------------------------------------*/
948 /* PRIVATE. Draw foreground */
949 /*---------------------------------------------------------------------------*/
951 draw_fg_layer (glView *view,
954 g_return_if_fail (view && GL_IS_VIEW (view));
955 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
957 gl_cairo_label_path (cr, view->label->template, view->label->rotate_flag, FALSE);
959 cairo_set_line_width (cr, OUTLINE_WIDTH_PIXELS/(view->home_scale * view->zoom));
960 cairo_set_source_rgb (cr, OUTLINE_RGB_ARGS);
964 /*---------------------------------------------------------------------------*/
965 /* PRIVATE. Create highlight layer. */
966 /*---------------------------------------------------------------------------*/
968 draw_highlight_layer (glView *view,
972 glViewObject *view_object;
974 g_return_if_fail (view && GL_IS_VIEW (view));
978 cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
980 for (p_obj = view->selected_object_list; p_obj != NULL; p_obj = p_obj->next)
982 view_object = GL_VIEW_OBJECT (p_obj->data);
984 gl_view_object_draw_handles (view_object, cr);
990 /*---------------------------------------------------------------------------*/
991 /* PRIVATE. Draw select region layer. */
992 /*---------------------------------------------------------------------------*/
994 draw_select_region_layer (glView *view,
1000 g_return_if_fail (view && GL_IS_VIEW (view));
1002 if (view->select_region_visible)
1004 x1 = MIN (view->select_region.x1, view->select_region.x2);
1005 y1 = MIN (view->select_region.y1, view->select_region.y2);
1006 w = fabs (view->select_region.x2 - view->select_region.x1);
1007 h = fabs (view->select_region.y2 - view->select_region.y1);
1011 cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
1013 cairo_rectangle (cr, x1, y1, w, h);
1015 cairo_set_source_rgba (cr, SELECT_FILL_RGBA_ARGS);
1016 cairo_fill_preserve (cr);
1018 cairo_set_line_width (cr, SELECT_LINE_WIDTH_PIXELS/(view->home_scale * view->zoom));
1019 cairo_set_source_rgba (cr, SELECT_LINE_RGBA_ARGS);
1026 /*****************************************************************************/
1028 /*****************************************************************************/
1030 gl_view_show_grid (glView *view)
1032 g_return_if_fail (view && GL_IS_VIEW (view));
1034 view->grid_visible = TRUE;
1035 gl_view_update (view);
1038 /*****************************************************************************/
1040 /*****************************************************************************/
1042 gl_view_hide_grid (glView *view)
1044 g_return_if_fail (view && GL_IS_VIEW (view));
1046 view->grid_visible = FALSE;
1047 gl_view_update (view);
1050 /*****************************************************************************/
1051 /* Set grid spacing. */
1052 /*****************************************************************************/
1054 gl_view_set_grid_spacing (glView *view,
1057 g_return_if_fail (view && GL_IS_VIEW (view));
1059 view->grid_spacing = spacing;
1060 gl_view_update (view);
1063 /*****************************************************************************/
1065 /*****************************************************************************/
1067 gl_view_show_markup (glView *view)
1069 g_return_if_fail (view && GL_IS_VIEW (view));
1071 view->markup_visible = TRUE;
1072 gl_view_update (view);
1075 /*****************************************************************************/
1077 /*****************************************************************************/
1079 gl_view_hide_markup (glView *view)
1081 g_return_if_fail (view && GL_IS_VIEW (view));
1083 view->markup_visible = FALSE;
1084 gl_view_update (view);
1087 /*****************************************************************************/
1088 /* Set arrow mode. */
1089 /*****************************************************************************/
1091 gl_view_arrow_mode (glView *view)
1095 gl_debug (DEBUG_VIEW, "START");
1097 g_return_if_fail (view && GL_IS_VIEW (view));
1099 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1100 gdk_window_set_cursor (view->canvas->window, cursor);
1101 gdk_cursor_unref (cursor);
1103 view->mode = GL_VIEW_MODE_ARROW;
1104 view->state = GL_VIEW_IDLE;
1106 gl_debug (DEBUG_VIEW, "END");
1109 /*****************************************************************************/
1110 /* Set create text object mode. */
1111 /*****************************************************************************/
1113 gl_view_object_create_mode (glView *view,
1114 glLabelObjectType type)
1116 GdkCursor *cursor = NULL;
1118 gl_debug (DEBUG_VIEW, "START");
1120 g_return_if_fail (view && GL_IS_VIEW (view));
1124 case GL_LABEL_OBJECT_BOX:
1125 cursor = gl_view_box_get_create_cursor ();
1127 case GL_LABEL_OBJECT_ELLIPSE:
1128 cursor = gl_view_ellipse_get_create_cursor ();
1130 case GL_LABEL_OBJECT_LINE:
1131 cursor = gl_view_line_get_create_cursor ();
1133 case GL_LABEL_OBJECT_IMAGE:
1134 cursor = gl_view_image_get_create_cursor ();
1136 case GL_LABEL_OBJECT_TEXT:
1137 cursor = gl_view_text_get_create_cursor ();
1139 case GL_LABEL_OBJECT_BARCODE:
1140 cursor = gl_view_barcode_get_create_cursor ();
1143 g_message ("Invalid label object type.");/*Should not happen!*/
1147 gdk_window_set_cursor (view->canvas->window, cursor);
1148 gdk_cursor_unref (cursor);
1150 view->mode = GL_VIEW_MODE_OBJECT_CREATE;
1151 view->state = GL_VIEW_IDLE;
1152 view->create_type = type;
1154 gl_debug (DEBUG_VIEW, "END");
1157 /*****************************************************************************/
1158 /* Select given object (adding to current selection). */
1159 /*****************************************************************************/
1161 gl_view_select_object (glView *view,
1162 glViewObject *view_object)
1164 gl_debug (DEBUG_VIEW, "START");
1166 g_return_if_fail (view && GL_IS_VIEW (view));
1168 select_object_real (view, view_object);
1170 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1172 gl_debug (DEBUG_VIEW, "END");
1175 /*****************************************************************************/
1176 /* Unselect given object (removing from current selection). */
1177 /*****************************************************************************/
1179 gl_view_unselect_object (glView *view,
1180 glViewObject *view_object)
1182 gl_debug (DEBUG_VIEW, "START");
1184 g_return_if_fail (view && GL_IS_VIEW (view));
1186 unselect_object_real (view, view_object);
1188 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1190 gl_debug (DEBUG_VIEW, "END");
1193 /*****************************************************************************/
1194 /* Select all items. */
1195 /*****************************************************************************/
1197 gl_view_select_all (glView *view)
1201 gl_debug (DEBUG_VIEW, "START");
1203 g_return_if_fail (view && GL_IS_VIEW (view));
1205 /* 1st unselect anything already selected. */
1206 for (p = view->selected_object_list; p != NULL; p = p_next) {
1208 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1211 /* Finally select all objects. */
1212 for (p = view->object_list; p != NULL; p = p->next) {
1213 select_object_real (view, GL_VIEW_OBJECT (p->data));
1216 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1218 gl_debug (DEBUG_VIEW, "END");
1221 /*****************************************************************************/
1222 /* Remove all selections */
1223 /*****************************************************************************/
1225 gl_view_unselect_all (glView *view)
1230 gl_debug (DEBUG_VIEW, "START");
1232 g_return_if_fail (view && GL_IS_VIEW (view));
1234 for (p = view->selected_object_list; p != NULL; p = p_next) {
1236 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1239 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1241 gl_debug (DEBUG_VIEW, "END");
1244 /*****************************************************************************/
1245 /* Select all objects within given rectangular region (adding to selection). */
1246 /*****************************************************************************/
1248 gl_view_select_region (glView *view,
1249 glLabelRegion *region)
1252 glViewObject *view_object;
1253 glLabelObject *object;
1256 glLabelRegion obj_extent;
1258 gl_debug (DEBUG_VIEW, "START");
1260 g_return_if_fail (view && GL_IS_VIEW (view));
1262 r_x1 = MIN (region->x1, region->x2);
1263 r_y1 = MIN (region->y1, region->y2);
1264 r_x2 = MAX (region->x1, region->x2);
1265 r_y2 = MAX (region->y1, region->y2);
1267 for (p = view->object_list; p != NULL; p = p->next)
1269 view_object = GL_VIEW_OBJECT(p->data);
1270 if (!gl_view_is_object_selected (view, view_object))
1273 object = gl_view_object_get_object (view_object);
1275 gl_label_object_get_extent (object, &obj_extent);
1276 if ((obj_extent.x1 >= r_x1) &&
1277 (obj_extent.x2 <= r_x2) &&
1278 (obj_extent.y1 >= r_y1) &&
1279 (obj_extent.y2 <= r_y2))
1281 select_object_real (view, view_object);
1287 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1289 gl_debug (DEBUG_VIEW, "END");
1292 /*---------------------------------------------------------------------------*/
1293 /* PRIVATE. Select an object. */
1294 /*---------------------------------------------------------------------------*/
1296 select_object_real (glView *view,
1297 glViewObject *view_object)
1299 gl_debug (DEBUG_VIEW, "START");
1301 g_return_if_fail (view && GL_IS_VIEW (view));
1302 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1304 if (!gl_view_is_object_selected (view, view_object)) {
1305 view->selected_object_list =
1306 g_list_append (view->selected_object_list, view_object);
1308 gtk_widget_grab_focus (GTK_WIDGET (view->canvas));
1310 gl_view_update (view);
1312 gl_debug (DEBUG_VIEW, "END");
1315 /*---------------------------------------------------------------------------*/
1316 /* PRIVATE. Un-select object. */
1317 /*---------------------------------------------------------------------------*/
1319 unselect_object_real (glView *view,
1320 glViewObject *view_object)
1322 gl_debug (DEBUG_VIEW, "START");
1324 g_return_if_fail (view && GL_IS_VIEW (view));
1325 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1327 view->selected_object_list =
1328 g_list_remove (view->selected_object_list, view_object);
1330 gl_view_update (view);
1332 gl_debug (DEBUG_VIEW, "END");
1335 /*---------------------------------------------------------------------------*/
1336 /* PRIVATE. Return object at (x,y). */
1337 /*---------------------------------------------------------------------------*/
1338 static glViewObject *
1339 view_view_object_at (glView *view,
1345 glViewObject *view_object;
1347 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
1349 for (p_obj = g_list_last (view->object_list); p_obj != NULL; p_obj = p_obj->prev)
1352 view_object = GL_VIEW_OBJECT (p_obj->data);
1354 if (gl_view_object_at (view_object, cr, x, y))
1364 /*---------------------------------------------------------------------------*/
1365 /* PRIVATE. Return object handle at (x,y). */
1366 /*---------------------------------------------------------------------------*/
1367 static glViewObject *
1368 view_handle_at (glView *view,
1372 glViewObjectHandle *handle)
1375 glViewObject *view_object;
1377 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
1379 for (p_obj = g_list_last (view->selected_object_list); p_obj != NULL; p_obj = p_obj->prev)
1382 view_object = GL_VIEW_OBJECT (p_obj->data);
1384 if ((*handle = gl_view_object_handle_at (view_object, cr, x, y)))
1394 /*****************************************************************************/
1395 /* Is the object in our current selection? */
1396 /*****************************************************************************/
1398 gl_view_is_object_selected (glView *view,
1399 glViewObject *view_object)
1401 gl_debug (DEBUG_VIEW, "");
1403 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1404 g_return_val_if_fail (GL_IS_VIEW_OBJECT (view_object), FALSE);
1406 if (g_list_find (view->selected_object_list, view_object) == NULL) {
1412 /*****************************************************************************/
1413 /* Is our current selection empty? */
1414 /*****************************************************************************/
1416 gl_view_is_selection_empty (glView *view)
1418 gl_debug (DEBUG_VIEW, "");
1420 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1422 if (view->selected_object_list == NULL) {
1429 /*****************************************************************************/
1430 /* Is our current selection atomic? I.e. only one item selected. */
1431 /*****************************************************************************/
1433 gl_view_is_selection_atomic (glView *view)
1435 gl_debug (DEBUG_VIEW, "");
1437 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1439 if (view->selected_object_list == NULL)
1441 if (view->selected_object_list->next == NULL)
1446 /*****************************************************************************/
1447 /* Delete selected objects. (Bypass clipboard) */
1448 /*****************************************************************************/
1450 gl_view_delete_selection (glView *view)
1455 glViewObject *view_object;
1456 glLabelObject *object;
1458 gl_debug (DEBUG_VIEW, "START");
1460 g_return_if_fail (view && GL_IS_VIEW (view));
1462 object_list = view->selected_object_list;
1463 view->selected_object_list = NULL;
1464 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1466 for (p = object_list; p != NULL; p = p_next) {
1468 view_object = GL_VIEW_OBJECT (p->data);
1469 object = gl_view_object_get_object (view_object);
1470 gl_label_object_remove (object);
1473 g_list_free (object_list);
1475 gl_debug (DEBUG_VIEW, "END");
1478 /*****************************************************************************/
1479 /* Get object property editor of first selected object. */
1480 /*****************************************************************************/
1482 gl_view_get_editor (glView *view)
1484 glViewObject *view_object;
1485 GtkWidget *editor = NULL;
1487 gl_debug (DEBUG_VIEW, "START");
1489 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
1491 if (!gl_view_is_selection_empty (view)) {
1493 view_object = GL_VIEW_OBJECT(view->selected_object_list->data);
1494 editor = gl_view_object_get_editor (view_object);
1498 gl_debug (DEBUG_VIEW, "END");
1503 /*****************************************************************************/
1504 /* Raise selected items to top. */
1505 /*****************************************************************************/
1507 gl_view_raise_selection (glView *view)
1510 glViewObject *view_object;
1511 glLabelObject *object;
1513 gl_debug (DEBUG_VIEW, "START");
1515 g_return_if_fail (view && GL_IS_VIEW (view));
1517 for (p = view->selected_object_list; p != NULL; p = p->next) {
1518 view_object = GL_VIEW_OBJECT (p->data);
1519 object = gl_view_object_get_object (view_object);
1520 gl_label_object_raise_to_top (object);
1523 gl_debug (DEBUG_VIEW, "END");
1526 /*****************************************************************************/
1527 /* Lower selected items to bottom. */
1528 /*****************************************************************************/
1530 gl_view_lower_selection (glView *view)
1533 glViewObject *view_object;
1534 glLabelObject *object;
1536 gl_debug (DEBUG_VIEW, "START");
1538 g_return_if_fail (view && GL_IS_VIEW (view));
1540 for (p = view->selected_object_list; p != NULL; p = p->next) {
1541 view_object = GL_VIEW_OBJECT (p->data);
1542 object = gl_view_object_get_object (view_object);
1543 gl_label_object_lower_to_bottom (object);
1546 gl_debug (DEBUG_VIEW, "END");
1549 /*****************************************************************************/
1550 /* Rotate selected objects by given angle. */
1551 /*****************************************************************************/
1553 gl_view_rotate_selection (glView *view,
1557 glViewObject *view_object;
1558 glLabelObject *object;
1560 gl_debug (DEBUG_VIEW, "START");
1562 g_return_if_fail (view && GL_IS_VIEW (view));
1564 for (p = view->selected_object_list; p != NULL; p = p->next) {
1565 view_object = GL_VIEW_OBJECT (p->data);
1566 object = gl_view_object_get_object (view_object);
1567 gl_label_object_rotate (object, theta_degs);
1570 gl_debug (DEBUG_VIEW, "END");
1573 /*****************************************************************************/
1574 /* Rotate selected objects 90 degrees left. */
1575 /*****************************************************************************/
1577 gl_view_rotate_selection_left (glView *view)
1580 glViewObject *view_object;
1581 glLabelObject *object;
1583 gl_debug (DEBUG_VIEW, "START");
1585 g_return_if_fail (view && GL_IS_VIEW (view));
1587 for (p = view->selected_object_list; p != NULL; p = p->next) {
1588 view_object = GL_VIEW_OBJECT (p->data);
1589 object = gl_view_object_get_object (view_object);
1590 gl_label_object_rotate (object, -90.0);
1593 gl_debug (DEBUG_VIEW, "END");
1596 /*****************************************************************************/
1597 /* Rotate selected objects 90 degrees right. */
1598 /*****************************************************************************/
1600 gl_view_rotate_selection_right (glView *view)
1603 glViewObject *view_object;
1604 glLabelObject *object;
1606 gl_debug (DEBUG_VIEW, "START");
1608 g_return_if_fail (view && GL_IS_VIEW (view));
1610 for (p = view->selected_object_list; p != NULL; p = p->next) {
1611 view_object = GL_VIEW_OBJECT (p->data);
1612 object = gl_view_object_get_object (view_object);
1613 gl_label_object_rotate (object, 90.0);
1616 gl_debug (DEBUG_VIEW, "END");
1619 /*****************************************************************************/
1620 /* Flip selected objects horizontally. */
1621 /*****************************************************************************/
1623 gl_view_flip_selection_horiz (glView *view)
1626 glViewObject *view_object;
1627 glLabelObject *object;
1629 gl_debug (DEBUG_VIEW, "START");
1631 g_return_if_fail (view && GL_IS_VIEW (view));
1633 for (p = view->selected_object_list; p != NULL; p = p->next) {
1634 view_object = GL_VIEW_OBJECT (p->data);
1635 object = gl_view_object_get_object (view_object);
1636 gl_label_object_flip_horiz (object);
1639 gl_debug (DEBUG_VIEW, "END");
1642 /*****************************************************************************/
1643 /* Flip selected objects vertically. */
1644 /*****************************************************************************/
1646 gl_view_flip_selection_vert (glView *view)
1649 glViewObject *view_object;
1650 glLabelObject *object;
1652 gl_debug (DEBUG_VIEW, "START");
1654 g_return_if_fail (view && GL_IS_VIEW (view));
1656 for (p = view->selected_object_list; p != NULL; p = p->next) {
1657 view_object = GL_VIEW_OBJECT (p->data);
1658 object = gl_view_object_get_object (view_object);
1659 gl_label_object_flip_vert (object);
1662 gl_debug (DEBUG_VIEW, "END");
1665 /*****************************************************************************/
1666 /* Align selected objects to left most edge. */
1667 /*****************************************************************************/
1669 gl_view_align_selection_left (glView *view)
1672 glViewObject *view_object;
1673 glLabelObject *object;
1675 glLabelRegion obj_extent;
1677 gl_debug (DEBUG_VIEW, "START");
1679 g_return_if_fail (view && GL_IS_VIEW (view));
1681 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1682 !gl_view_is_selection_atomic (view));
1684 /* find left most edge */
1685 p = view->selected_object_list;
1686 view_object = GL_VIEW_OBJECT (p->data);
1687 object = gl_view_object_get_object (view_object);
1688 gl_label_object_get_extent (object, &obj_extent);
1689 x1_min = obj_extent.x1;
1690 for (p = p->next; p != NULL; p = p->next)
1692 view_object = GL_VIEW_OBJECT (p->data);
1693 object = gl_view_object_get_object (view_object);
1694 gl_label_object_get_extent (object, &obj_extent);
1695 if ( obj_extent.x1 < x1_min ) x1_min = obj_extent.x1;
1698 /* now adjust the object positions to line up the left edges */
1699 for (p = view->selected_object_list; p != NULL; p = p->next)
1701 view_object = GL_VIEW_OBJECT (p->data);
1702 object = gl_view_object_get_object (view_object);
1703 gl_label_object_get_extent (object, &obj_extent);
1704 dx = x1_min - obj_extent.x1;
1705 gl_label_object_set_position_relative (object, dx, 0.0);
1708 gl_debug (DEBUG_VIEW, "END");
1712 /*****************************************************************************/
1713 /* Align selected objects to right most edge. */
1714 /*****************************************************************************/
1716 gl_view_align_selection_right (glView *view)
1719 glViewObject *view_object;
1720 glLabelObject *object;
1722 glLabelRegion obj_extent;
1724 gl_debug (DEBUG_VIEW, "START");
1726 g_return_if_fail (view && GL_IS_VIEW (view));
1728 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1729 !gl_view_is_selection_atomic (view));
1731 /* find right most edge */
1732 p = view->selected_object_list;
1733 view_object = GL_VIEW_OBJECT (p->data);
1734 object = gl_view_object_get_object (view_object);
1735 gl_label_object_get_extent (object, &obj_extent);
1736 x2_max = obj_extent.x2;
1737 for (p = p->next; p != NULL; p = p->next)
1739 view_object = GL_VIEW_OBJECT (p->data);
1740 object = gl_view_object_get_object (view_object);
1741 gl_label_object_get_extent (object, &obj_extent);
1742 if ( obj_extent.x2 > x2_max ) x2_max = obj_extent.x2;
1745 /* now adjust the object positions to line up the right edges */
1746 for (p = view->selected_object_list; p != NULL; p = p->next)
1748 view_object = GL_VIEW_OBJECT (p->data);
1749 object = gl_view_object_get_object (view_object);
1750 gl_label_object_get_extent (object, &obj_extent);
1751 dx = x2_max - obj_extent.x2;
1752 gl_label_object_set_position_relative (object, dx, 0.0);
1755 gl_debug (DEBUG_VIEW, "END");
1758 /*****************************************************************************/
1759 /* Align selected objects to horizontal center of objects. */
1760 /*****************************************************************************/
1762 gl_view_align_selection_hcenter (glView *view)
1765 glViewObject *view_object;
1766 glLabelObject *object;
1770 glLabelRegion obj_extent;
1774 gl_debug (DEBUG_VIEW, "START");
1776 g_return_if_fail (view && GL_IS_VIEW (view));
1778 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1779 !gl_view_is_selection_atomic (view));
1781 /* find average center of objects */
1784 for (p = view->selected_object_list; p != NULL; p = p->next)
1786 view_object = GL_VIEW_OBJECT (p->data);
1787 object = gl_view_object_get_object (view_object);
1788 gl_label_object_get_extent (object, &obj_extent);
1789 xsum += (obj_extent.x1 + obj_extent.x2) / 2.0;
1794 /* find center of object closest to average center */
1795 p = view->selected_object_list;
1796 view_object = GL_VIEW_OBJECT (p->data);
1797 object = gl_view_object_get_object (view_object);
1798 gl_label_object_get_extent (object, &obj_extent);
1799 dxmin = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
1800 xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
1801 for (p = p->next; p != NULL; p = p->next)
1803 view_object = GL_VIEW_OBJECT (p->data);
1804 object = gl_view_object_get_object (view_object);
1805 gl_label_object_get_extent (object, &obj_extent);
1806 dx = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
1810 xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
1814 /* now adjust the object positions to line up this center */
1815 for (p = view->selected_object_list; p != NULL; p = p->next) {
1816 view_object = GL_VIEW_OBJECT (p->data);
1817 object = gl_view_object_get_object (view_object);
1818 gl_label_object_get_extent (object, &obj_extent);
1819 dx = xcenter - (obj_extent.x1 + obj_extent.x2)/2.0;
1820 gl_label_object_set_position_relative (object, dx, 0.0);
1823 gl_debug (DEBUG_VIEW, "END");
1826 /*****************************************************************************/
1827 /* Align selected objects to top most edge. */
1828 /*****************************************************************************/
1830 gl_view_align_selection_top (glView *view)
1833 glViewObject *view_object;
1834 glLabelObject *object;
1836 glLabelRegion obj_extent;
1838 gl_debug (DEBUG_VIEW, "START");
1840 g_return_if_fail (view && GL_IS_VIEW (view));
1842 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1843 !gl_view_is_selection_atomic (view));
1845 /* find top most edge */
1846 p = view->selected_object_list;
1847 view_object = GL_VIEW_OBJECT (p->data);
1848 object = gl_view_object_get_object (view_object);
1849 gl_label_object_get_extent (object, &obj_extent);
1850 y1_min = obj_extent.y1;
1851 for (p = p->next; p != NULL; p = p->next)
1853 view_object = GL_VIEW_OBJECT (p->data);
1854 object = gl_view_object_get_object (view_object);
1855 gl_label_object_get_extent (object, &obj_extent);
1856 if ( obj_extent.y1 < y1_min ) y1_min = obj_extent.y1;
1859 /* now adjust the object positions to line up the top edges */
1860 for (p = view->selected_object_list; p != NULL; p = p->next)
1862 view_object = GL_VIEW_OBJECT (p->data);
1863 object = gl_view_object_get_object (view_object);
1864 gl_label_object_get_extent (object, &obj_extent);
1865 dy = y1_min - obj_extent.y1;
1866 gl_label_object_set_position_relative (object, 0.0, dy);
1869 gl_debug (DEBUG_VIEW, "END");
1872 /*****************************************************************************/
1873 /* Align selected objects to bottom most edge. */
1874 /*****************************************************************************/
1876 gl_view_align_selection_bottom (glView *view)
1879 glViewObject *view_object;
1880 glLabelObject *object;
1882 glLabelRegion obj_extent;
1884 gl_debug (DEBUG_VIEW, "START");
1886 g_return_if_fail (view && GL_IS_VIEW (view));
1888 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1889 !gl_view_is_selection_atomic (view));
1891 /* find bottom most edge */
1892 p = view->selected_object_list;
1893 view_object = GL_VIEW_OBJECT (p->data);
1894 object = gl_view_object_get_object (view_object);
1895 gl_label_object_get_extent (object, &obj_extent);
1896 y2_max = obj_extent.y2;
1897 for (p = p->next; p != NULL; p = p->next)
1899 view_object = GL_VIEW_OBJECT (p->data);
1900 object = gl_view_object_get_object (view_object);
1901 gl_label_object_get_extent (object, &obj_extent);
1902 if ( obj_extent.y2 > y2_max ) y2_max = obj_extent.y2;
1905 /* now adjust the object positions to line up the bottom edges */
1906 for (p = view->selected_object_list; p != NULL; p = p->next)
1908 view_object = GL_VIEW_OBJECT (p->data);
1909 object = gl_view_object_get_object (view_object);
1910 gl_label_object_get_extent (object, &obj_extent);
1911 dy = y2_max - obj_extent.y2;
1912 gl_label_object_set_position_relative (object, 0.0, dy);
1915 gl_debug (DEBUG_VIEW, "END");
1918 /*****************************************************************************/
1919 /* Align selected objects to viertical center of objects. */
1920 /*****************************************************************************/
1922 gl_view_align_selection_vcenter (glView *view)
1925 glViewObject *view_object;
1926 glLabelObject *object;
1930 glLabelRegion obj_extent;
1934 gl_debug (DEBUG_VIEW, "START");
1936 g_return_if_fail (view && GL_IS_VIEW (view));
1938 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1939 !gl_view_is_selection_atomic (view));
1941 /* find average center of objects */
1944 for (p = view->selected_object_list; p != NULL; p = p->next)
1946 view_object = GL_VIEW_OBJECT (p->data);
1947 object = gl_view_object_get_object (view_object);
1948 gl_label_object_get_extent (object, &obj_extent);
1949 ysum += (obj_extent.y1 + obj_extent.y2) / 2.0;
1954 /* find center of object closest to average center */
1955 p = view->selected_object_list;
1956 view_object = GL_VIEW_OBJECT (p->data);
1957 object = gl_view_object_get_object (view_object);
1958 gl_label_object_get_extent (object, &obj_extent);
1959 dymin = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
1960 ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
1961 for (p = p->next; p != NULL; p = p->next)
1963 view_object = GL_VIEW_OBJECT (p->data);
1964 object = gl_view_object_get_object (view_object);
1965 gl_label_object_get_extent (object, &obj_extent);
1966 dy = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
1970 ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
1974 /* now adjust the object positions to line up this center */
1975 for (p = view->selected_object_list; p != NULL; p = p->next)
1977 view_object = GL_VIEW_OBJECT (p->data);
1978 object = gl_view_object_get_object (view_object);
1979 gl_label_object_get_extent (object, &obj_extent);
1980 dy = ycenter - (obj_extent.y1 + obj_extent.y2)/2.0;
1981 gl_label_object_set_position_relative (object, 0.0, dy);
1984 gl_debug (DEBUG_VIEW, "END");
1987 /*****************************************************************************/
1988 /* Center selected objects to in center of label. */
1989 /*****************************************************************************/
1991 gl_view_center_selection_horiz (glView *view)
1994 glViewObject *view_object;
1995 glLabelObject *object;
1997 gdouble x_label_center;
1998 gdouble x_obj_center;
1999 glLabelRegion obj_extent;
2002 gl_debug (DEBUG_VIEW, "START");
2004 g_return_if_fail (view && GL_IS_VIEW (view));
2006 g_return_if_fail (!gl_view_is_selection_empty (view));
2008 gl_label_get_size (view->label, &w, &h);
2009 x_label_center = w / 2.0;
2011 /* adjust the object positions */
2012 for (p = view->selected_object_list; p != NULL; p = p->next)
2014 view_object = GL_VIEW_OBJECT (p->data);
2015 object = gl_view_object_get_object (view_object);
2016 gl_label_object_get_extent (object, &obj_extent);
2017 x_obj_center = (obj_extent.x1 + obj_extent.x2) / 2.0;
2018 dx = x_label_center - x_obj_center;
2019 gl_label_object_set_position_relative (object, dx, 0.0);
2022 gl_debug (DEBUG_VIEW, "END");
2026 /*****************************************************************************/
2027 /* Center selected objects to in center of label. */
2028 /*****************************************************************************/
2030 gl_view_center_selection_vert (glView *view)
2033 glViewObject *view_object;
2034 glLabelObject *object;
2036 gdouble y_label_center;
2037 gdouble y_obj_center;
2038 glLabelRegion obj_extent;
2041 gl_debug (DEBUG_VIEW, "START");
2043 g_return_if_fail (view && GL_IS_VIEW (view));
2045 g_return_if_fail (!gl_view_is_selection_empty (view));
2047 gl_label_get_size (view->label, &w, &h);
2048 y_label_center = h / 2.0;
2050 /* adjust the object positions */
2051 for (p = view->selected_object_list; p != NULL; p = p->next)
2053 view_object = GL_VIEW_OBJECT (p->data);
2054 object = gl_view_object_get_object (view_object);
2055 gl_label_object_get_extent (object, &obj_extent);
2056 y_obj_center = (obj_extent.y1 + obj_extent.y2) / 2.0;
2057 dy = y_label_center - y_obj_center;
2058 gl_label_object_set_position_relative (object, 0.0, dy);
2061 gl_debug (DEBUG_VIEW, "END");
2065 /*****************************************************************************/
2066 /* Move selected objects */
2067 /*****************************************************************************/
2069 gl_view_move_selection (glView *view,
2074 glLabelObject *object;
2076 gl_debug (DEBUG_VIEW, "START");
2078 g_return_if_fail (view && GL_IS_VIEW (view));
2080 for (p = view->selected_object_list; p != NULL; p = p->next)
2083 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2084 gl_label_object_set_position_relative (object, dx, dy);
2088 gl_debug (DEBUG_VIEW, "END");
2091 /*****************************************************************************/
2092 /* Can text properties be set for selection? */
2093 /*****************************************************************************/
2095 gl_view_can_selection_text (glView *view)
2098 glLabelObject *object;
2100 gl_debug (DEBUG_VIEW, "");
2102 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2104 for (p = view->selected_object_list; p != NULL; p = p->next)
2107 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2108 if (gl_label_object_can_text (object))
2118 /*****************************************************************************/
2119 /* Set font family for all text contained in selected objects. */
2120 /*****************************************************************************/
2122 gl_view_set_selection_font_family (glView *view,
2123 const gchar *font_family)
2126 glLabelObject *object;
2128 gl_debug (DEBUG_VIEW, "START");
2130 g_return_if_fail (view && GL_IS_VIEW (view));
2132 for (p = view->selected_object_list; p != NULL; p = p->next) {
2134 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2135 gl_label_object_set_font_family (object, font_family);
2139 gl_debug (DEBUG_VIEW, "END");
2142 /*****************************************************************************/
2143 /* Set font size for all text contained in selected objects. */
2144 /*****************************************************************************/
2146 gl_view_set_selection_font_size (glView *view,
2150 glLabelObject *object;
2152 gl_debug (DEBUG_VIEW, "START");
2154 g_return_if_fail (view && GL_IS_VIEW (view));
2156 for (p = view->selected_object_list; p != NULL; p = p->next) {
2158 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2159 gl_label_object_set_font_size (object, font_size);
2163 gl_debug (DEBUG_VIEW, "END");
2166 /*****************************************************************************/
2167 /* Set font weight for all text contained in selected objects. */
2168 /*****************************************************************************/
2170 gl_view_set_selection_font_weight (glView *view,
2171 PangoWeight font_weight)
2174 glLabelObject *object;
2176 gl_debug (DEBUG_VIEW, "START");
2178 g_return_if_fail (view && GL_IS_VIEW (view));
2180 for (p = view->selected_object_list; p != NULL; p = p->next) {
2182 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2183 gl_label_object_set_font_weight (object, font_weight);
2187 gl_debug (DEBUG_VIEW, "END");
2190 /*****************************************************************************/
2191 /* Set font italic flag for all text contained in selected objects. */
2192 /*****************************************************************************/
2194 gl_view_set_selection_font_italic_flag (glView *view,
2195 gboolean font_italic_flag)
2198 glLabelObject *object;
2200 gl_debug (DEBUG_VIEW, "START");
2202 g_return_if_fail (view && GL_IS_VIEW (view));
2204 for (p = view->selected_object_list; p != NULL; p = p->next) {
2206 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2207 gl_label_object_set_font_italic_flag (object, font_italic_flag);
2211 gl_debug (DEBUG_VIEW, "END");
2214 /*****************************************************************************/
2215 /* Set text alignment for all text contained in selected objects. */
2216 /*****************************************************************************/
2218 gl_view_set_selection_text_alignment (glView *view,
2219 PangoAlignment text_alignment)
2222 glLabelObject *object;
2224 gl_debug (DEBUG_VIEW, "START");
2226 g_return_if_fail (view && GL_IS_VIEW (view));
2228 for (p = view->selected_object_list; p != NULL; p = p->next) {
2230 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2231 gl_label_object_set_text_alignment (object, text_alignment);
2235 gl_debug (DEBUG_VIEW, "END");
2238 /*****************************************************************************/
2239 /* Set text line spacing for all text contained in selected objects. */
2240 /*****************************************************************************/
2242 gl_view_set_selection_text_line_spacing (glView *view,
2243 gdouble text_line_spacing)
2246 glLabelObject *object;
2248 gl_debug (DEBUG_VIEW, "START");
2250 g_return_if_fail (view && GL_IS_VIEW (view));
2252 for (p = view->selected_object_list; p != NULL; p = p->next) {
2254 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2255 gl_label_object_set_text_line_spacing (object, text_line_spacing);
2259 gl_debug (DEBUG_VIEW, "END");
2261 /*****************************************************************************/
2262 /* Set text color for all text contained in selected objects. */
2263 /*****************************************************************************/
2265 gl_view_set_selection_text_color (glView *view,
2266 glColorNode *text_color_node)
2269 glLabelObject *object;
2271 gl_debug (DEBUG_VIEW, "START");
2273 g_return_if_fail (view && GL_IS_VIEW (view));
2275 for (p = view->selected_object_list; p != NULL; p = p->next) {
2277 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2278 gl_label_object_set_text_color (object, text_color_node);
2282 gl_debug (DEBUG_VIEW, "END");
2285 /*****************************************************************************/
2286 /* Can fill properties be set for selection? */
2287 /*****************************************************************************/
2289 gl_view_can_selection_fill (glView *view)
2292 glLabelObject *object;
2294 gl_debug (DEBUG_VIEW, "");
2296 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2298 for (p = view->selected_object_list; p != NULL; p = p->next) {
2300 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2301 if (gl_label_object_can_fill (object)) {
2310 /*****************************************************************************/
2311 /* Set fill color for all selected objects. */
2312 /*****************************************************************************/
2314 gl_view_set_selection_fill_color (glView *view,
2315 glColorNode *fill_color_node)
2318 glLabelObject *object;
2320 gl_debug (DEBUG_VIEW, "START");
2322 g_return_if_fail (view && GL_IS_VIEW (view));
2324 for (p = view->selected_object_list; p != NULL; p = p->next) {
2326 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2327 gl_label_object_set_fill_color (object, fill_color_node);
2331 gl_debug (DEBUG_VIEW, "END");
2334 /*****************************************************************************/
2335 /* Can line color properties be set for selection? */
2336 /*****************************************************************************/
2338 gl_view_can_selection_line_color (glView *view)
2341 glLabelObject *object;
2343 gl_debug (DEBUG_VIEW, "");
2345 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2347 for (p = view->selected_object_list; p != NULL; p = p->next) {
2349 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2350 if (gl_label_object_can_line_color (object)) {
2359 /*****************************************************************************/
2360 /* Set line color for all selected objects. */
2361 /*****************************************************************************/
2363 gl_view_set_selection_line_color (glView *view,
2364 glColorNode *line_color_node)
2367 glLabelObject *object;
2369 gl_debug (DEBUG_VIEW, "START");
2371 g_return_if_fail (view && GL_IS_VIEW (view));
2373 for (p = view->selected_object_list; p != NULL; p = p->next) {
2375 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2376 gl_label_object_set_line_color (object, line_color_node);
2380 gl_debug (DEBUG_VIEW, "END");
2383 /*****************************************************************************/
2384 /* Can line width properties be set for selection? */
2385 /*****************************************************************************/
2387 gl_view_can_selection_line_width (glView *view)
2390 glLabelObject *object;
2392 gl_debug (DEBUG_VIEW, "");
2394 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2396 for (p = view->selected_object_list; p != NULL; p = p->next) {
2398 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2399 if (gl_label_object_can_line_width (object)) {
2408 /*****************************************************************************/
2409 /* Set line width for all selected objects. */
2410 /*****************************************************************************/
2412 gl_view_set_selection_line_width (glView *view,
2416 glLabelObject *object;
2418 gl_debug (DEBUG_VIEW, "START");
2420 g_return_if_fail (view && GL_IS_VIEW (view));
2422 for (p = view->selected_object_list; p != NULL; p = p->next) {
2424 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2425 gl_label_object_set_line_width (object, line_width);
2429 gl_debug (DEBUG_VIEW, "END");
2432 /*****************************************************************************/
2433 /* "Cut" selected items and place in clipboard selections. */
2434 /*****************************************************************************/
2436 gl_view_cut (glView *view)
2438 gl_debug (DEBUG_VIEW, "START");
2440 g_return_if_fail (view && GL_IS_VIEW (view));
2442 gl_view_copy (view);
2443 gl_view_delete_selection (view);
2445 gl_debug (DEBUG_VIEW, "END");
2448 /*****************************************************************************/
2449 /* "Copy" selected items to clipboard selections. */
2450 /*****************************************************************************/
2452 gl_view_copy (glView *view)
2455 glViewObject *view_object;
2456 glLabelObject *object;
2458 gl_debug (DEBUG_VIEW, "START");
2460 g_return_if_fail (view && GL_IS_VIEW (view));
2462 if (view->selected_object_list) {
2464 if ( view->selection_data ) {
2465 g_object_unref (view->selection_data);
2467 view->selection_data = GL_LABEL(gl_label_new ());
2468 gl_label_set_template (view->selection_data, view->label->template);
2469 gl_label_set_rotate_flag (view->selection_data, view->label->rotate_flag);
2471 for (p = view->selected_object_list; p != NULL; p = p->next) {
2473 view_object = GL_VIEW_OBJECT (p->data);
2474 object = gl_view_object_get_object (view_object);
2476 gl_label_object_dup (object, view->selection_data);
2480 gtk_selection_owner_set (view->invisible,
2481 clipboard_atom, GDK_CURRENT_TIME);
2482 view->have_selection = TRUE;
2486 gl_debug (DEBUG_VIEW, "END");
2489 /*****************************************************************************/
2490 /* "Paste" from private clipboard selection. */
2491 /*****************************************************************************/
2493 gl_view_paste (glView *view)
2495 gl_debug (DEBUG_VIEW, "START");
2497 g_return_if_fail (view && GL_IS_VIEW (view));
2499 gtk_selection_convert (GTK_WIDGET (view->invisible),
2500 clipboard_atom, GDK_SELECTION_TYPE_STRING,
2503 gl_debug (DEBUG_VIEW, "END");
2506 /*****************************************************************************/
2507 /* Zoom in one "notch" */
2508 /*****************************************************************************/
2510 gl_view_zoom_in (glView *view)
2513 gdouble dist, dist_min;
2515 gl_debug (DEBUG_VIEW, "START");
2517 g_return_if_fail (view && GL_IS_VIEW (view));
2519 /* Find index of current scale (or best match) */
2520 i_min = 1; /* start with 2nd largest scale */
2521 dist_min = fabs (zooms[1] - view->zoom);
2522 for (i = 2; i < N_ZOOMS; i++) {
2523 dist = fabs (zooms[i] - view->zoom);
2524 if (dist < dist_min) {
2530 /* zoom in one "notch" */
2531 i = MAX (0, i_min - 1);
2532 gl_debug (DEBUG_VIEW, "zoom[%d] = %g", i, zooms[i]);
2533 set_zoom_real (view, zooms[i], FALSE);
2535 gl_debug (DEBUG_VIEW, "END");
2538 /*****************************************************************************/
2539 /* Zoom out one "notch" */
2540 /*****************************************************************************/
2542 gl_view_zoom_out (glView *view)
2545 gdouble dist, dist_min;
2547 gl_debug (DEBUG_VIEW, "START");
2549 g_return_if_fail (view && GL_IS_VIEW (view));
2551 /* Find index of current scale (or best match) */
2552 i_min = 0; /* start with largest scale */
2553 dist_min = fabs (zooms[0] - view->zoom);
2554 for (i = 1; i < N_ZOOMS; i++) {
2555 dist = fabs (zooms[i] - view->zoom);
2556 if (dist < dist_min) {
2562 /* zoom out one "notch" */
2563 if (i_min >= N_ZOOMS)
2568 set_zoom_real (view, zooms[i], FALSE);
2570 gl_debug (DEBUG_VIEW, "END");
2573 /*****************************************************************************/
2574 /* Set zoom to best fit. */
2575 /*****************************************************************************/
2577 gl_view_zoom_to_fit (glView *view)
2579 gint w_view, h_view;
2580 gdouble w_label, h_label;
2581 gdouble x_scale, y_scale, scale;
2583 gl_debug (DEBUG_VIEW, "");
2585 if ( ! GTK_WIDGET_VISIBLE(view)) {
2586 set_zoom_real (view, 1.0, TRUE);
2590 w_view = GTK_WIDGET(view)->allocation.width;
2591 h_view = GTK_WIDGET(view)->allocation.height;
2593 gl_label_get_size (GL_LABEL(view->label), &w_label, &h_label);
2595 gl_debug (DEBUG_VIEW, "View size: %d, %d", w_view, h_view);
2596 gl_debug (DEBUG_VIEW, "Label size: %g, %g", w_label, h_label);
2598 /* Calculate best scale */
2599 x_scale = (double)(w_view - ZOOMTOFIT_PAD) / w_label;
2600 y_scale = (double)(h_view - ZOOMTOFIT_PAD) / h_label;
2601 scale = MIN (x_scale, y_scale);
2602 gl_debug (DEBUG_VIEW, "Candidate zooms: %g, %g => %g", x_scale, y_scale, scale);
2605 gl_debug (DEBUG_VIEW, "Scale: %g", scale);
2606 scale = MIN (scale, zooms[0]*view->home_scale);
2607 scale = MAX (scale, zooms[N_ZOOMS-1]*view->home_scale);
2608 gl_debug (DEBUG_VIEW, "Limitted scale: %g", scale);
2610 set_zoom_real (view, scale/view->home_scale, TRUE);
2613 /*****************************************************************************/
2614 /* Set current zoom factor to explicit value. */
2615 /*****************************************************************************/
2617 gl_view_set_zoom (glView *view,
2620 gl_debug (DEBUG_VIEW, "START");
2622 set_zoom_real (view, zoom, FALSE);
2624 gl_debug (DEBUG_VIEW, "END");
2627 /*---------------------------------------------------------------------------*/
2628 /* PRIVATE. Set canvas scale. */
2629 /*---------------------------------------------------------------------------*/
2631 set_zoom_real (glView *view,
2633 gboolean zoom_to_fit_flag)
2635 gl_debug (DEBUG_VIEW, "START");
2637 g_return_if_fail (view && GL_IS_VIEW (view));
2638 g_return_if_fail (zoom > 0.0);
2640 /* Limit, if needed */
2641 gl_debug (DEBUG_VIEW, "Zoom requested: %g", zoom);
2642 zoom = MIN (zoom, zooms[0]);
2643 zoom = MAX (zoom, zooms[N_ZOOMS-1]);
2644 gl_debug (DEBUG_VIEW, "Limitted zoom: %g", zoom);
2646 if ( zoom != view->zoom ) {
2649 view->zoom_to_fit_flag = zoom_to_fit_flag;
2651 gl_view_update (view);
2653 g_signal_emit (G_OBJECT(view), signals[ZOOM_CHANGED], 0, zoom);
2657 gl_debug (DEBUG_VIEW, "END");
2662 /*****************************************************************************/
2663 /* Get current zoom factor. */
2664 /*****************************************************************************/
2666 gl_view_get_zoom (glView *view)
2668 gl_debug (DEBUG_VIEW, "");
2670 g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
2675 /*****************************************************************************/
2676 /* Is this the maximum zoom level. */
2677 /*****************************************************************************/
2679 gl_view_is_zoom_max (glView *view)
2681 gl_debug (DEBUG_VIEW, "");
2683 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
2685 return view->zoom >= zooms[0];
2688 /*****************************************************************************/
2689 /* Is this the minimum zoom level. */
2690 /*****************************************************************************/
2692 gl_view_is_zoom_min (glView *view)
2694 gl_debug (DEBUG_VIEW, "");
2696 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2698 return view->zoom <= zooms[N_ZOOMS-1];
2701 /*---------------------------------------------------------------------------*/
2702 /* PRIVATE. Handle "selection-clear" signal. */
2703 /*---------------------------------------------------------------------------*/
2705 selection_clear_cb (GtkWidget *widget,
2706 GdkEventSelection *event,
2709 gl_debug (DEBUG_VIEW, "START");
2711 g_return_if_fail (view && GL_IS_VIEW (view));
2713 view->have_selection = FALSE;
2714 g_object_unref (view->selection_data);
2715 view->selection_data = NULL;
2717 gl_debug (DEBUG_VIEW, "END");
2720 /*---------------------------------------------------------------------------*/
2721 /* PRIVATE. Handle "selection-get" signal. */
2722 /*---------------------------------------------------------------------------*/
2724 selection_get_cb (GtkWidget *widget,
2725 GtkSelectionData *selection_data,
2731 glXMLLabelStatus status;
2733 gl_debug (DEBUG_VIEW, "START");
2735 g_return_if_fail (view && GL_IS_VIEW (view));
2737 if (view->have_selection) {
2739 buffer = gl_xml_label_save_buffer (view->selection_data,
2741 gtk_selection_data_set (selection_data,
2742 GDK_SELECTION_TYPE_STRING, 8,
2743 (guchar *)buffer, strlen (buffer));
2747 gl_debug (DEBUG_VIEW, "END");
2750 /*---------------------------------------------------------------------------*/
2751 /* PRIVATE. Handle "selection-received" signal. (Result of Paste) */
2752 /*---------------------------------------------------------------------------*/
2754 selection_received_cb (GtkWidget *widget,
2755 GtkSelectionData *selection_data,
2759 glLabel *label = NULL;
2760 glXMLLabelStatus status;
2762 glLabelObject *object, *newobject;
2763 glViewObject *view_object;
2765 gl_debug (DEBUG_VIEW, "START");
2767 g_return_if_fail (view && GL_IS_VIEW (view));
2769 if (selection_data->length < 0) {
2772 if (selection_data->type != GDK_SELECTION_TYPE_STRING) {
2776 gl_view_unselect_all (view);
2778 label = gl_xml_label_open_buffer ((gchar *)selection_data->data, &status);
2779 for (p = label->objects; p != NULL; p = p_next) {
2782 object = (glLabelObject *) p->data;
2783 newobject = gl_label_object_dup (object, view->label);
2785 gl_debug (DEBUG_VIEW, "object pasted");
2787 if (GL_IS_LABEL_BOX (newobject)) {
2788 view_object = gl_view_box_new (GL_LABEL_BOX(newobject),
2790 } else if (GL_IS_LABEL_ELLIPSE (newobject)) {
2791 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(newobject),
2793 } else if (GL_IS_LABEL_LINE (newobject)) {
2794 view_object = gl_view_line_new (GL_LABEL_LINE(newobject),
2796 } else if (GL_IS_LABEL_IMAGE (newobject)) {
2797 view_object = gl_view_image_new (GL_LABEL_IMAGE(newobject),
2799 } else if (GL_IS_LABEL_TEXT (newobject)) {
2800 view_object = gl_view_text_new (GL_LABEL_TEXT(newobject),
2802 } else if (GL_IS_LABEL_BARCODE (newobject)) {
2803 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(newobject),
2806 /* Should not happen! */
2808 g_message ("Invalid label object type.");
2810 gl_view_select_object (view, view_object);
2812 g_object_unref (label);
2814 gl_debug (DEBUG_VIEW, "END");
2817 /****************************************************************************/
2818 /* Set default font family. */
2819 /****************************************************************************/
2821 gl_view_set_default_font_family (glView *view,
2822 const gchar *font_family)
2824 gl_debug (DEBUG_VIEW, "START");
2826 g_return_if_fail (view && GL_IS_VIEW (view));
2828 if (view->default_font_family) {
2829 g_free (view->default_font_family);
2831 view->default_font_family = g_strdup (font_family);
2833 gl_debug (DEBUG_VIEW, "END");
2837 /****************************************************************************/
2838 /* Set default font size. */
2839 /****************************************************************************/
2841 gl_view_set_default_font_size (glView *view,
2844 gl_debug (DEBUG_VIEW, "START");
2846 g_return_if_fail (view && GL_IS_VIEW (view));
2848 view->default_font_size = font_size;
2850 gl_debug (DEBUG_VIEW, "END");
2854 /****************************************************************************/
2855 /* Set default font weight. */
2856 /****************************************************************************/
2858 gl_view_set_default_font_weight (glView *view,
2859 PangoWeight font_weight)
2861 gl_debug (DEBUG_VIEW, "START");
2863 g_return_if_fail (view && GL_IS_VIEW (view));
2865 view->default_font_weight = font_weight;
2867 gl_debug (DEBUG_VIEW, "END");
2871 /****************************************************************************/
2872 /* Set default font italic flag. */
2873 /****************************************************************************/
2875 gl_view_set_default_font_italic_flag (glView *view,
2876 gboolean font_italic_flag)
2878 gl_debug (DEBUG_VIEW, "START");
2880 g_return_if_fail (view && GL_IS_VIEW (view));
2882 view->default_font_italic_flag = font_italic_flag;
2884 gl_debug (DEBUG_VIEW, "END");
2888 /****************************************************************************/
2889 /* Set default text color. */
2890 /****************************************************************************/
2892 gl_view_set_default_text_color (glView *view,
2895 gl_debug (DEBUG_VIEW, "START");
2897 g_return_if_fail (view && GL_IS_VIEW (view));
2899 view->default_text_color = text_color;
2901 gl_debug (DEBUG_VIEW, "END");
2905 /****************************************************************************/
2906 /* Set default text alignment. */
2907 /****************************************************************************/
2909 gl_view_set_default_text_alignment (glView *view,
2910 PangoAlignment text_alignment)
2912 gl_debug (DEBUG_VIEW, "START");
2914 g_return_if_fail (view && GL_IS_VIEW (view));
2916 view->default_text_alignment = text_alignment;
2917 gl_debug (DEBUG_VIEW, "END");
2920 /****************************************************************************/
2921 /* Set default text line spacing. */
2922 /****************************************************************************/
2924 gl_view_set_default_text_line_spacing (glView *view,
2925 gdouble text_line_spacing)
2927 gl_debug (DEBUG_VIEW, "START");
2929 g_return_if_fail (view && GL_IS_VIEW (view));
2931 view->default_text_line_spacing = text_line_spacing;
2933 gl_debug (DEBUG_VIEW, "END");
2937 /****************************************************************************/
2938 /* Set default line width. */
2939 /****************************************************************************/
2941 gl_view_set_default_line_width (glView *view,
2944 gl_debug (DEBUG_VIEW, "START");
2946 g_return_if_fail (view && GL_IS_VIEW (view));
2948 view->default_line_width = line_width;
2950 gl_debug (DEBUG_VIEW, "END");
2954 /****************************************************************************/
2955 /* Set default line color. */
2956 /****************************************************************************/
2958 gl_view_set_default_line_color (glView *view,
2961 gl_debug (DEBUG_VIEW, "START");
2963 g_return_if_fail (view && GL_IS_VIEW (view));
2965 view->default_line_color = line_color;
2967 gl_debug (DEBUG_VIEW, "END");
2971 /****************************************************************************/
2972 /* Set default fill color. */
2973 /****************************************************************************/
2975 gl_view_set_default_fill_color (glView *view,
2978 gl_debug (DEBUG_VIEW, "START");
2980 g_return_if_fail (view && GL_IS_VIEW (view));
2982 view->default_fill_color = fill_color;
2984 gl_debug (DEBUG_VIEW, "END");
2989 /****************************************************************************/
2990 /* Get default font family. */
2991 /****************************************************************************/
2993 gl_view_get_default_font_family (glView *view)
2995 gl_debug (DEBUG_VIEW, "START");
2997 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
2999 gl_debug (DEBUG_VIEW, "END");
3001 return g_strdup (view->default_font_family);
3005 /****************************************************************************/
3006 /* Get default font size. */
3007 /****************************************************************************/
3009 gl_view_get_default_font_size (glView *view)
3011 gl_debug (DEBUG_VIEW, "START");
3013 g_return_val_if_fail (view && GL_IS_VIEW (view), 12.0);
3015 gl_debug (DEBUG_VIEW, "END");
3017 return view->default_font_size;
3021 /****************************************************************************/
3022 /* Get default font weight. */
3023 /****************************************************************************/
3025 gl_view_get_default_font_weight (glView *view)
3027 gl_debug (DEBUG_VIEW, "START");
3029 g_return_val_if_fail (view && GL_IS_VIEW (view), PANGO_WEIGHT_NORMAL);
3031 gl_debug (DEBUG_VIEW, "END");
3033 return view->default_font_weight;
3037 /****************************************************************************/
3038 /* Get default font italic flag. */
3039 /****************************************************************************/
3041 gl_view_get_default_font_italic_flag (glView *view)
3043 gl_debug (DEBUG_VIEW, "START");
3045 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3047 gl_debug (DEBUG_VIEW, "END");
3049 return view->default_font_italic_flag;
3053 /****************************************************************************/
3054 /* Get default text color. */
3055 /****************************************************************************/
3057 gl_view_get_default_text_color (glView *view)
3059 gl_debug (DEBUG_VIEW, "START");
3061 g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
3063 gl_debug (DEBUG_VIEW, "END");
3065 return view->default_text_color;
3069 /****************************************************************************/
3070 /* Get default text alignment. */
3071 /****************************************************************************/
3073 gl_view_get_default_text_alignment (glView *view)
3075 gl_debug (DEBUG_VIEW, "START");
3077 g_return_val_if_fail (view && GL_IS_VIEW (view), PANGO_ALIGN_LEFT);
3079 gl_debug (DEBUG_VIEW, "END");
3081 return view->default_text_alignment;
3084 /****************************************************************************/
3085 /* Get default text line spacing. */
3086 /****************************************************************************/
3088 gl_view_get_default_text_line_spacing (glView *view)
3090 gl_debug (DEBUG_VIEW, "START");
3092 g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
3094 gl_debug (DEBUG_VIEW, "END");
3096 return view->default_text_line_spacing;
3101 /****************************************************************************/
3102 /* Get default line width. */
3103 /****************************************************************************/
3105 gl_view_get_default_line_width (glView *view)
3107 gl_debug (DEBUG_VIEW, "START");
3109 g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
3111 gl_debug (DEBUG_VIEW, "END");
3113 return view->default_line_width;
3117 /****************************************************************************/
3118 /* Get default line color. */
3119 /****************************************************************************/
3121 gl_view_get_default_line_color (glView *view)
3123 gl_debug (DEBUG_VIEW, "START");
3125 g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
3127 gl_debug (DEBUG_VIEW, "END");
3129 return view->default_line_color;
3133 /****************************************************************************/
3134 /* Get default fill color. */
3135 /****************************************************************************/
3137 gl_view_get_default_fill_color (glView *view)
3139 gl_debug (DEBUG_VIEW, "START");
3141 g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
3143 gl_debug (DEBUG_VIEW, "END");
3145 return view->default_fill_color;
3148 /*---------------------------------------------------------------------------*/
3149 /* PRIVATE. Focus in event handler. */
3150 /*---------------------------------------------------------------------------*/
3152 focus_in_event_cb (glView *view,
3153 GdkEventFocus *event)
3155 GTK_WIDGET_SET_FLAGS (GTK_WIDGET (view->canvas), GTK_HAS_FOCUS);
3160 /*---------------------------------------------------------------------------*/
3161 /* PRIVATE. Focus out event handler. */
3162 /*---------------------------------------------------------------------------*/
3164 focus_out_event_cb (glView *view,
3165 GdkEventFocus *event)
3167 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (view->canvas), GTK_HAS_FOCUS);
3172 /*---------------------------------------------------------------------------*/
3173 /* PRIVATE. Enter notify event handler. */
3174 /*---------------------------------------------------------------------------*/
3176 enter_notify_event_cb (glView *view,
3177 GdkEventCrossing *event)
3179 gtk_widget_grab_focus(GTK_WIDGET (view->canvas));
3184 /*---------------------------------------------------------------------------*/
3185 /* PRIVATE. Leave notify event handler. */
3186 /*---------------------------------------------------------------------------*/
3188 leave_notify_event_cb (glView *view,
3189 GdkEventCrossing *event)
3192 g_signal_emit (G_OBJECT(view), signals[POINTER_EXIT], 0);
3197 /*---------------------------------------------------------------------------*/
3198 /* PRIVATE. Motion notify event handler. */
3199 /*---------------------------------------------------------------------------*/
3201 motion_notify_event_cb (glView *view,
3202 GdkEventMotion *event)
3204 gboolean return_value = FALSE;
3209 glViewObjectHandle handle;
3211 cr = gdk_cairo_create (GTK_LAYOUT (view->canvas)->bin_window);
3214 * Translate to label coordinates
3216 scale = view->zoom * view->home_scale;
3217 cairo_scale (cr, scale, scale);
3218 cairo_translate (cr, view->x0, view->y0);
3222 cairo_device_to_user (cr, &x, &y);
3225 * Emit signal regardless of mode
3227 g_signal_emit (G_OBJECT(view), signals[POINTER_MOVED], 0, x, y);
3230 * Handle event as appropriate for mode
3235 case GL_VIEW_MODE_ARROW:
3236 switch (view->state)
3240 if (view_handle_at (view, cr, event->x, event->y, &handle))
3242 cursor = gdk_cursor_new (GDK_CROSSHAIR);
3244 else if (view_view_object_at (view, cr, event->x, event->y))
3246 cursor = gdk_cursor_new (GDK_FLEUR);
3250 cursor = gdk_cursor_new (GDK_LEFT_PTR);
3252 gdk_window_set_cursor (view->canvas->window, cursor);
3253 gdk_cursor_unref (cursor);
3256 case GL_VIEW_ARROW_SELECT_REGION:
3258 gl_view_update_region (view, cr, &view->select_region);
3260 view->select_region.x2 = x;
3261 view->select_region.y2 = y;
3263 gl_view_update_region (view, cr, &view->select_region);
3265 gl_view_update (view);
3269 case GL_VIEW_ARROW_MOVE:
3270 gl_view_move_selection (view,
3271 (x - view->move_last_x),
3272 (y - view->move_last_y));
3273 view->move_last_x = x;
3274 view->move_last_y = y;
3277 case GL_VIEW_ARROW_RESIZE:
3278 gl_view_object_resize_event (view->resize_object,
3279 view->resize_handle,
3280 view->resize_honor_aspect,
3287 g_message ("Invalid arrow state."); /*Should not happen!*/
3289 return_value = TRUE;
3293 case GL_VIEW_MODE_OBJECT_CREATE:
3294 if (view->state != GL_VIEW_IDLE)
3296 switch (view->create_type)
3298 case GL_LABEL_OBJECT_BOX:
3299 gl_view_box_create_motion_event (view, x, y);
3301 case GL_LABEL_OBJECT_ELLIPSE:
3302 gl_view_ellipse_create_motion_event (view, x, y);
3304 case GL_LABEL_OBJECT_LINE:
3305 gl_view_line_create_motion_event (view, x, y);
3307 case GL_LABEL_OBJECT_IMAGE:
3308 gl_view_image_create_motion_event (view, x, y);
3310 case GL_LABEL_OBJECT_TEXT:
3311 gl_view_text_create_motion_event (view, x, y);
3313 case GL_LABEL_OBJECT_BARCODE:
3314 gl_view_barcode_create_motion_event (view, x, y);
3317 g_message ("Invalid create type."); /*Should not happen!*/
3324 g_message ("Invalid view mode."); /*Should not happen!*/
3331 * FIXME: we re-establish grabs here if the grab has been lost. We seem to be
3332 * losing grabs when we emit signals that lead to the manipulation of
3333 * the GtkUIManager. Needs more investigation
3335 if (view->grabbed_flag && !gdk_pointer_is_grabbed ())
3337 gdk_pointer_grab (GTK_LAYOUT (view->canvas)->bin_window,
3339 (GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK),
3345 return return_value;
3348 /*---------------------------------------------------------------------------*/
3349 /* PRIVATE. Button press event handler. */
3350 /*---------------------------------------------------------------------------*/
3352 button_press_event_cb (glView *view,
3353 GdkEventButton *event)
3355 gboolean return_value = FALSE;
3359 glViewObject *view_object;
3360 glViewObjectHandle handle;
3362 cr = gdk_cairo_create (GTK_LAYOUT (view->canvas)->bin_window);
3365 * Translate to label coordinates
3367 scale = view->zoom * view->home_scale;
3368 cairo_scale (cr, scale, scale);
3369 cairo_translate (cr, view->x0, view->y0);
3373 cairo_device_to_user (cr, &x, &y);
3375 switch (event->button)
3380 * Handle event as appropriate for mode
3384 case GL_VIEW_MODE_ARROW:
3385 if ((view_object = view_handle_at (view, cr, event->x, event->y, &handle)))
3387 view->resize_object = view_object;
3388 view->resize_handle = handle;
3389 view->resize_honor_aspect = event->state & GDK_CONTROL_MASK;
3391 view->state = GL_VIEW_ARROW_RESIZE;
3393 else if ((view_object = view_view_object_at (view, cr, event->x, event->y)))
3395 if (event->state & GDK_CONTROL_MASK)
3397 if (gl_view_is_object_selected (view, view_object))
3399 /* Un-selecting a selected item */
3400 gl_view_unselect_object (view, view_object);
3402 /* Add to current selection */
3403 gl_view_select_object (view, view_object);
3408 if (!gl_view_is_object_selected (view, view_object))
3410 /* remove any selections before adding */
3411 gl_view_unselect_all (view);
3412 /* Add to current selection */
3413 gl_view_select_object (view, view_object);
3416 view->move_last_x = x;
3417 view->move_last_y = y;
3419 view->state = GL_VIEW_ARROW_MOVE;
3423 if (!(event->state & GDK_CONTROL_MASK))
3425 gl_view_unselect_all (view);
3428 view->select_region_visible = TRUE;
3429 view->select_region.x1 = x;
3430 view->select_region.y1 = y;
3431 view->select_region.x2 = x;
3432 view->select_region.y2 = y;
3434 view->state = GL_VIEW_ARROW_SELECT_REGION;
3438 return_value = TRUE;
3441 case GL_VIEW_MODE_OBJECT_CREATE:
3442 switch (view->create_type)
3444 case GL_LABEL_OBJECT_BOX:
3445 gl_view_box_create_button_press_event (view, x, y);
3447 case GL_LABEL_OBJECT_ELLIPSE:
3448 gl_view_ellipse_create_button_press_event (view, x, y);
3450 case GL_LABEL_OBJECT_LINE:
3451 gl_view_line_create_button_press_event (view, x, y);
3453 case GL_LABEL_OBJECT_IMAGE:
3454 gl_view_image_create_button_press_event (view, x, y);
3456 case GL_LABEL_OBJECT_TEXT:
3457 gl_view_text_create_button_press_event (view, x, y);
3459 case GL_LABEL_OBJECT_BARCODE:
3460 gl_view_barcode_create_button_press_event (view, x, y);
3463 g_message ("Invalid create type."); /*Should not happen!*/
3465 view->state = GL_VIEW_CREATE_DRAG;
3466 return_value = TRUE;
3470 g_message ("Invalid view mode."); /*Should not happen!*/
3473 view->grabbed_flag = TRUE;
3474 gdk_pointer_grab (GTK_LAYOUT (view->canvas)->bin_window,
3476 (GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK),
3483 g_signal_emit (G_OBJECT (view),
3484 signals[CONTEXT_MENU_ACTIVATE], 0,
3485 event->button, event->time);
3486 return_value = TRUE;
3493 return return_value;
3496 /*---------------------------------------------------------------------------*/
3497 /* PRIVATE. Button release event handler. */
3498 /*---------------------------------------------------------------------------*/
3500 button_release_event_cb (glView *view,
3501 GdkEventButton *event)
3503 gboolean return_value = FALSE;
3509 cr = gdk_cairo_create (GTK_LAYOUT (view->canvas)->bin_window);
3512 * Translate to label coordinates
3514 scale = view->zoom * view->home_scale;
3515 cairo_scale (cr, scale, scale);
3516 cairo_translate (cr, view->x0, view->y0);
3520 cairo_device_to_user (cr, &x, &y);
3522 switch (event->button)
3526 view->grabbed_flag = FALSE;
3527 gdk_pointer_ungrab (event->time);
3529 * Handle event as appropriate for mode
3533 case GL_VIEW_MODE_ARROW:
3534 switch (view->state)
3536 case GL_VIEW_ARROW_RESIZE:
3537 view->resize_object = NULL;
3539 view->state = GL_VIEW_IDLE;
3542 case GL_VIEW_ARROW_SELECT_REGION:
3544 gl_view_update_region (view, cr, &view->select_region);
3546 gl_view_update (view);
3549 view->select_region_visible = FALSE;
3550 view->select_region.x2 = x;
3551 view->select_region.y2 = y;
3553 gl_view_select_region (view, &view->select_region);
3555 view->state = GL_VIEW_IDLE;
3559 view->state = GL_VIEW_IDLE;
3564 return_value = TRUE;
3568 case GL_VIEW_MODE_OBJECT_CREATE:
3569 switch (view->create_type)
3571 case GL_LABEL_OBJECT_BOX:
3572 gl_view_box_create_button_release_event (view, x, y);
3574 case GL_LABEL_OBJECT_ELLIPSE:
3575 gl_view_ellipse_create_button_release_event (view, x, y);
3577 case GL_LABEL_OBJECT_LINE:
3578 gl_view_line_create_button_release_event (view, x, y);
3580 case GL_LABEL_OBJECT_IMAGE:
3581 gl_view_image_create_button_release_event (view, x, y);
3583 case GL_LABEL_OBJECT_TEXT:
3584 gl_view_text_create_button_release_event (view, x, y);
3586 case GL_LABEL_OBJECT_BARCODE:
3587 gl_view_barcode_create_button_release_event (view, x, y);
3590 g_message ("Invalid create type."); /*Should not happen!*/
3592 view->mode = GL_VIEW_MODE_ARROW;
3593 view->state = GL_VIEW_IDLE;
3594 cursor = gdk_cursor_new (GDK_LEFT_PTR);
3595 gdk_window_set_cursor (view->canvas->window, cursor);
3596 gdk_cursor_unref (cursor);
3601 g_message ("Invalid view mode."); /*Should not happen!*/
3608 return return_value;
3611 /*---------------------------------------------------------------------------*/
3612 /* PRIVATE. Key press event handler. */
3613 /*---------------------------------------------------------------------------*/
3615 key_press_event_cb (glView *view,
3620 gl_debug (DEBUG_VIEW, "");
3622 if ( (view->mode == GL_VIEW_MODE_ARROW) &&
3623 (view->state == GL_VIEW_IDLE) )
3625 switch (event->keyval) {
3629 gl_view_move_selection (view, -1.0 / (view->zoom), 0.0);
3633 gl_view_move_selection (view, 0.0, -1.0 / (view->zoom));
3637 gl_view_move_selection (view, 1.0 / (view->zoom), 0.0);
3641 gl_view_move_selection (view, 0.0, 1.0 / (view->zoom));
3645 gl_view_delete_selection (view);
3646 cursor = gdk_cursor_new (GDK_LEFT_PTR);
3647 gdk_window_set_cursor (GTK_WIDGET (view->canvas)->window
3649 gdk_cursor_unref (cursor);
3656 return TRUE; /* We handled this or we were dragging. */