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 lglTemplateFrame *frame;
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 frame = (lglTemplateFrame *)view->label->template->frames->data;
858 gl_label_get_size (view->label, &w, &h);
860 if (frame->shape == LGL_TEMPLATE_FRAME_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 lglTemplateFrame *frame;
907 lglTemplateMarkup *markup;
908 gdouble width, height;
910 g_return_if_fail (view && GL_IS_VIEW (view));
911 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
913 if (view->markup_visible)
917 frame = (lglTemplateFrame *)view->label->template->frames->data;
921 if (label->rotate_flag)
923 lgl_template_frame_get_size (frame, &width, &height);
924 cairo_rotate (cr, -M_PI/2.0);
925 cairo_translate (cr, -width, 0.0);
928 cairo_set_line_width (cr, MARKUP_LINE_WIDTH_PIXELS/(view->home_scale * view->zoom));
929 cairo_set_source_rgb (cr, MARKUP_RGB_ARGS);
931 for ( p=frame->all.markups; p != NULL; p=p->next )
933 markup = (lglTemplateMarkup *)p->data;
935 gl_cairo_markup_path (cr, markup, label);
945 /*---------------------------------------------------------------------------*/
946 /* PRIVATE. Draw objects layer. */
947 /*---------------------------------------------------------------------------*/
949 draw_objects_layer (glView *view,
952 gl_label_draw (view->label, cr, TRUE, NULL);
955 /*---------------------------------------------------------------------------*/
956 /* PRIVATE. Draw foreground */
957 /*---------------------------------------------------------------------------*/
959 draw_fg_layer (glView *view,
962 g_return_if_fail (view && GL_IS_VIEW (view));
963 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
965 gl_cairo_label_path (cr, view->label->template, view->label->rotate_flag, FALSE);
967 cairo_set_line_width (cr, OUTLINE_WIDTH_PIXELS/(view->home_scale * view->zoom));
968 cairo_set_source_rgb (cr, OUTLINE_RGB_ARGS);
972 /*---------------------------------------------------------------------------*/
973 /* PRIVATE. Create highlight layer. */
974 /*---------------------------------------------------------------------------*/
976 draw_highlight_layer (glView *view,
980 glViewObject *view_object;
982 g_return_if_fail (view && GL_IS_VIEW (view));
986 cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
988 for (p_obj = view->selected_object_list; p_obj != NULL; p_obj = p_obj->next)
990 view_object = GL_VIEW_OBJECT (p_obj->data);
992 gl_view_object_draw_handles (view_object, cr);
998 /*---------------------------------------------------------------------------*/
999 /* PRIVATE. Draw select region layer. */
1000 /*---------------------------------------------------------------------------*/
1002 draw_select_region_layer (glView *view,
1008 g_return_if_fail (view && GL_IS_VIEW (view));
1010 if (view->select_region_visible)
1012 x1 = MIN (view->select_region.x1, view->select_region.x2);
1013 y1 = MIN (view->select_region.y1, view->select_region.y2);
1014 w = fabs (view->select_region.x2 - view->select_region.x1);
1015 h = fabs (view->select_region.y2 - view->select_region.y1);
1019 cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
1021 cairo_rectangle (cr, x1, y1, w, h);
1023 cairo_set_source_rgba (cr, SELECT_FILL_RGBA_ARGS);
1024 cairo_fill_preserve (cr);
1026 cairo_set_line_width (cr, SELECT_LINE_WIDTH_PIXELS/(view->home_scale * view->zoom));
1027 cairo_set_source_rgba (cr, SELECT_LINE_RGBA_ARGS);
1034 /*****************************************************************************/
1036 /*****************************************************************************/
1038 gl_view_show_grid (glView *view)
1040 g_return_if_fail (view && GL_IS_VIEW (view));
1042 view->grid_visible = TRUE;
1043 gl_view_update (view);
1046 /*****************************************************************************/
1048 /*****************************************************************************/
1050 gl_view_hide_grid (glView *view)
1052 g_return_if_fail (view && GL_IS_VIEW (view));
1054 view->grid_visible = FALSE;
1055 gl_view_update (view);
1058 /*****************************************************************************/
1059 /* Set grid spacing. */
1060 /*****************************************************************************/
1062 gl_view_set_grid_spacing (glView *view,
1065 g_return_if_fail (view && GL_IS_VIEW (view));
1067 view->grid_spacing = spacing;
1068 gl_view_update (view);
1071 /*****************************************************************************/
1073 /*****************************************************************************/
1075 gl_view_show_markup (glView *view)
1077 g_return_if_fail (view && GL_IS_VIEW (view));
1079 view->markup_visible = TRUE;
1080 gl_view_update (view);
1083 /*****************************************************************************/
1085 /*****************************************************************************/
1087 gl_view_hide_markup (glView *view)
1089 g_return_if_fail (view && GL_IS_VIEW (view));
1091 view->markup_visible = FALSE;
1092 gl_view_update (view);
1095 /*****************************************************************************/
1096 /* Set arrow mode. */
1097 /*****************************************************************************/
1099 gl_view_arrow_mode (glView *view)
1103 gl_debug (DEBUG_VIEW, "START");
1105 g_return_if_fail (view && GL_IS_VIEW (view));
1107 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1108 gdk_window_set_cursor (view->canvas->window, cursor);
1109 gdk_cursor_unref (cursor);
1111 view->mode = GL_VIEW_MODE_ARROW;
1112 view->state = GL_VIEW_IDLE;
1114 gl_debug (DEBUG_VIEW, "END");
1117 /*****************************************************************************/
1118 /* Set create text object mode. */
1119 /*****************************************************************************/
1121 gl_view_object_create_mode (glView *view,
1122 glLabelObjectType type)
1124 GdkCursor *cursor = NULL;
1126 gl_debug (DEBUG_VIEW, "START");
1128 g_return_if_fail (view && GL_IS_VIEW (view));
1132 case GL_LABEL_OBJECT_BOX:
1133 cursor = gl_view_box_get_create_cursor ();
1135 case GL_LABEL_OBJECT_ELLIPSE:
1136 cursor = gl_view_ellipse_get_create_cursor ();
1138 case GL_LABEL_OBJECT_LINE:
1139 cursor = gl_view_line_get_create_cursor ();
1141 case GL_LABEL_OBJECT_IMAGE:
1142 cursor = gl_view_image_get_create_cursor ();
1144 case GL_LABEL_OBJECT_TEXT:
1145 cursor = gl_view_text_get_create_cursor ();
1147 case GL_LABEL_OBJECT_BARCODE:
1148 cursor = gl_view_barcode_get_create_cursor ();
1151 g_message ("Invalid label object type.");/*Should not happen!*/
1155 gdk_window_set_cursor (view->canvas->window, cursor);
1156 gdk_cursor_unref (cursor);
1158 view->mode = GL_VIEW_MODE_OBJECT_CREATE;
1159 view->state = GL_VIEW_IDLE;
1160 view->create_type = type;
1162 gl_debug (DEBUG_VIEW, "END");
1165 /*****************************************************************************/
1166 /* Select given object (adding to current selection). */
1167 /*****************************************************************************/
1169 gl_view_select_object (glView *view,
1170 glViewObject *view_object)
1172 gl_debug (DEBUG_VIEW, "START");
1174 g_return_if_fail (view && GL_IS_VIEW (view));
1176 select_object_real (view, view_object);
1178 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1180 gl_debug (DEBUG_VIEW, "END");
1183 /*****************************************************************************/
1184 /* Unselect given object (removing from current selection). */
1185 /*****************************************************************************/
1187 gl_view_unselect_object (glView *view,
1188 glViewObject *view_object)
1190 gl_debug (DEBUG_VIEW, "START");
1192 g_return_if_fail (view && GL_IS_VIEW (view));
1194 unselect_object_real (view, view_object);
1196 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1198 gl_debug (DEBUG_VIEW, "END");
1201 /*****************************************************************************/
1202 /* Select all items. */
1203 /*****************************************************************************/
1205 gl_view_select_all (glView *view)
1209 gl_debug (DEBUG_VIEW, "START");
1211 g_return_if_fail (view && GL_IS_VIEW (view));
1213 /* 1st unselect anything already selected. */
1214 for (p = view->selected_object_list; p != NULL; p = p_next) {
1216 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1219 /* Finally select all objects. */
1220 for (p = view->object_list; p != NULL; p = p->next) {
1221 select_object_real (view, GL_VIEW_OBJECT (p->data));
1224 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1226 gl_debug (DEBUG_VIEW, "END");
1229 /*****************************************************************************/
1230 /* Remove all selections */
1231 /*****************************************************************************/
1233 gl_view_unselect_all (glView *view)
1238 gl_debug (DEBUG_VIEW, "START");
1240 g_return_if_fail (view && GL_IS_VIEW (view));
1242 for (p = view->selected_object_list; p != NULL; p = p_next) {
1244 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1247 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1249 gl_debug (DEBUG_VIEW, "END");
1252 /*****************************************************************************/
1253 /* Select all objects within given rectangular region (adding to selection). */
1254 /*****************************************************************************/
1256 gl_view_select_region (glView *view,
1257 glLabelRegion *region)
1260 glViewObject *view_object;
1261 glLabelObject *object;
1264 glLabelRegion obj_extent;
1266 gl_debug (DEBUG_VIEW, "START");
1268 g_return_if_fail (view && GL_IS_VIEW (view));
1270 r_x1 = MIN (region->x1, region->x2);
1271 r_y1 = MIN (region->y1, region->y2);
1272 r_x2 = MAX (region->x1, region->x2);
1273 r_y2 = MAX (region->y1, region->y2);
1275 for (p = view->object_list; p != NULL; p = p->next)
1277 view_object = GL_VIEW_OBJECT(p->data);
1278 if (!gl_view_is_object_selected (view, view_object))
1281 object = gl_view_object_get_object (view_object);
1283 gl_label_object_get_extent (object, &obj_extent);
1284 if ((obj_extent.x1 >= r_x1) &&
1285 (obj_extent.x2 <= r_x2) &&
1286 (obj_extent.y1 >= r_y1) &&
1287 (obj_extent.y2 <= r_y2))
1289 select_object_real (view, view_object);
1295 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1297 gl_debug (DEBUG_VIEW, "END");
1300 /*---------------------------------------------------------------------------*/
1301 /* PRIVATE. Select an object. */
1302 /*---------------------------------------------------------------------------*/
1304 select_object_real (glView *view,
1305 glViewObject *view_object)
1307 gl_debug (DEBUG_VIEW, "START");
1309 g_return_if_fail (view && GL_IS_VIEW (view));
1310 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1312 if (!gl_view_is_object_selected (view, view_object)) {
1313 view->selected_object_list =
1314 g_list_append (view->selected_object_list, view_object);
1316 gtk_widget_grab_focus (GTK_WIDGET (view->canvas));
1318 gl_view_update (view);
1320 gl_debug (DEBUG_VIEW, "END");
1323 /*---------------------------------------------------------------------------*/
1324 /* PRIVATE. Un-select object. */
1325 /*---------------------------------------------------------------------------*/
1327 unselect_object_real (glView *view,
1328 glViewObject *view_object)
1330 gl_debug (DEBUG_VIEW, "START");
1332 g_return_if_fail (view && GL_IS_VIEW (view));
1333 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1335 view->selected_object_list =
1336 g_list_remove (view->selected_object_list, view_object);
1338 gl_view_update (view);
1340 gl_debug (DEBUG_VIEW, "END");
1343 /*---------------------------------------------------------------------------*/
1344 /* PRIVATE. Return object at (x,y). */
1345 /*---------------------------------------------------------------------------*/
1346 static glViewObject *
1347 view_view_object_at (glView *view,
1353 glViewObject *view_object;
1355 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
1357 for (p_obj = g_list_last (view->object_list); p_obj != NULL; p_obj = p_obj->prev)
1360 view_object = GL_VIEW_OBJECT (p_obj->data);
1362 if (gl_view_object_at (view_object, cr, x, y))
1372 /*---------------------------------------------------------------------------*/
1373 /* PRIVATE. Return object handle at (x,y). */
1374 /*---------------------------------------------------------------------------*/
1375 static glViewObject *
1376 view_handle_at (glView *view,
1380 glViewObjectHandle *handle)
1383 glViewObject *view_object;
1385 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
1387 for (p_obj = g_list_last (view->selected_object_list); p_obj != NULL; p_obj = p_obj->prev)
1390 view_object = GL_VIEW_OBJECT (p_obj->data);
1392 if ((*handle = gl_view_object_handle_at (view_object, cr, x, y)))
1402 /*****************************************************************************/
1403 /* Is the object in our current selection? */
1404 /*****************************************************************************/
1406 gl_view_is_object_selected (glView *view,
1407 glViewObject *view_object)
1409 gl_debug (DEBUG_VIEW, "");
1411 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1412 g_return_val_if_fail (GL_IS_VIEW_OBJECT (view_object), FALSE);
1414 if (g_list_find (view->selected_object_list, view_object) == NULL) {
1420 /*****************************************************************************/
1421 /* Is our current selection empty? */
1422 /*****************************************************************************/
1424 gl_view_is_selection_empty (glView *view)
1426 gl_debug (DEBUG_VIEW, "");
1428 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1430 if (view->selected_object_list == NULL) {
1437 /*****************************************************************************/
1438 /* Is our current selection atomic? I.e. only one item selected. */
1439 /*****************************************************************************/
1441 gl_view_is_selection_atomic (glView *view)
1443 gl_debug (DEBUG_VIEW, "");
1445 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1447 if (view->selected_object_list == NULL)
1449 if (view->selected_object_list->next == NULL)
1454 /*****************************************************************************/
1455 /* Delete selected objects. (Bypass clipboard) */
1456 /*****************************************************************************/
1458 gl_view_delete_selection (glView *view)
1463 glViewObject *view_object;
1464 glLabelObject *object;
1466 gl_debug (DEBUG_VIEW, "START");
1468 g_return_if_fail (view && GL_IS_VIEW (view));
1470 object_list = view->selected_object_list;
1471 view->selected_object_list = NULL;
1472 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1474 for (p = object_list; p != NULL; p = p_next) {
1476 view_object = GL_VIEW_OBJECT (p->data);
1477 object = gl_view_object_get_object (view_object);
1478 gl_label_object_remove (object);
1481 g_list_free (object_list);
1483 gl_debug (DEBUG_VIEW, "END");
1486 /*****************************************************************************/
1487 /* Get object property editor of first selected object. */
1488 /*****************************************************************************/
1490 gl_view_get_editor (glView *view)
1492 glViewObject *view_object;
1493 GtkWidget *editor = NULL;
1495 gl_debug (DEBUG_VIEW, "START");
1497 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
1499 if (!gl_view_is_selection_empty (view)) {
1501 view_object = GL_VIEW_OBJECT(view->selected_object_list->data);
1502 editor = gl_view_object_get_editor (view_object);
1506 gl_debug (DEBUG_VIEW, "END");
1511 /*****************************************************************************/
1512 /* Raise selected items to top. */
1513 /*****************************************************************************/
1515 gl_view_raise_selection (glView *view)
1518 glViewObject *view_object;
1519 glLabelObject *object;
1521 gl_debug (DEBUG_VIEW, "START");
1523 g_return_if_fail (view && GL_IS_VIEW (view));
1525 for (p = view->selected_object_list; p != NULL; p = p->next) {
1526 view_object = GL_VIEW_OBJECT (p->data);
1527 object = gl_view_object_get_object (view_object);
1528 gl_label_object_raise_to_top (object);
1531 gl_debug (DEBUG_VIEW, "END");
1534 /*****************************************************************************/
1535 /* Lower selected items to bottom. */
1536 /*****************************************************************************/
1538 gl_view_lower_selection (glView *view)
1541 glViewObject *view_object;
1542 glLabelObject *object;
1544 gl_debug (DEBUG_VIEW, "START");
1546 g_return_if_fail (view && GL_IS_VIEW (view));
1548 for (p = view->selected_object_list; p != NULL; p = p->next) {
1549 view_object = GL_VIEW_OBJECT (p->data);
1550 object = gl_view_object_get_object (view_object);
1551 gl_label_object_lower_to_bottom (object);
1554 gl_debug (DEBUG_VIEW, "END");
1557 /*****************************************************************************/
1558 /* Rotate selected objects by given angle. */
1559 /*****************************************************************************/
1561 gl_view_rotate_selection (glView *view,
1565 glViewObject *view_object;
1566 glLabelObject *object;
1568 gl_debug (DEBUG_VIEW, "START");
1570 g_return_if_fail (view && GL_IS_VIEW (view));
1572 for (p = view->selected_object_list; p != NULL; p = p->next) {
1573 view_object = GL_VIEW_OBJECT (p->data);
1574 object = gl_view_object_get_object (view_object);
1575 gl_label_object_rotate (object, theta_degs);
1578 gl_debug (DEBUG_VIEW, "END");
1581 /*****************************************************************************/
1582 /* Rotate selected objects 90 degrees left. */
1583 /*****************************************************************************/
1585 gl_view_rotate_selection_left (glView *view)
1588 glViewObject *view_object;
1589 glLabelObject *object;
1591 gl_debug (DEBUG_VIEW, "START");
1593 g_return_if_fail (view && GL_IS_VIEW (view));
1595 for (p = view->selected_object_list; p != NULL; p = p->next) {
1596 view_object = GL_VIEW_OBJECT (p->data);
1597 object = gl_view_object_get_object (view_object);
1598 gl_label_object_rotate (object, -90.0);
1601 gl_debug (DEBUG_VIEW, "END");
1604 /*****************************************************************************/
1605 /* Rotate selected objects 90 degrees right. */
1606 /*****************************************************************************/
1608 gl_view_rotate_selection_right (glView *view)
1611 glViewObject *view_object;
1612 glLabelObject *object;
1614 gl_debug (DEBUG_VIEW, "START");
1616 g_return_if_fail (view && GL_IS_VIEW (view));
1618 for (p = view->selected_object_list; p != NULL; p = p->next) {
1619 view_object = GL_VIEW_OBJECT (p->data);
1620 object = gl_view_object_get_object (view_object);
1621 gl_label_object_rotate (object, 90.0);
1624 gl_debug (DEBUG_VIEW, "END");
1627 /*****************************************************************************/
1628 /* Flip selected objects horizontally. */
1629 /*****************************************************************************/
1631 gl_view_flip_selection_horiz (glView *view)
1634 glViewObject *view_object;
1635 glLabelObject *object;
1637 gl_debug (DEBUG_VIEW, "START");
1639 g_return_if_fail (view && GL_IS_VIEW (view));
1641 for (p = view->selected_object_list; p != NULL; p = p->next) {
1642 view_object = GL_VIEW_OBJECT (p->data);
1643 object = gl_view_object_get_object (view_object);
1644 gl_label_object_flip_horiz (object);
1647 gl_debug (DEBUG_VIEW, "END");
1650 /*****************************************************************************/
1651 /* Flip selected objects vertically. */
1652 /*****************************************************************************/
1654 gl_view_flip_selection_vert (glView *view)
1657 glViewObject *view_object;
1658 glLabelObject *object;
1660 gl_debug (DEBUG_VIEW, "START");
1662 g_return_if_fail (view && GL_IS_VIEW (view));
1664 for (p = view->selected_object_list; p != NULL; p = p->next) {
1665 view_object = GL_VIEW_OBJECT (p->data);
1666 object = gl_view_object_get_object (view_object);
1667 gl_label_object_flip_vert (object);
1670 gl_debug (DEBUG_VIEW, "END");
1673 /*****************************************************************************/
1674 /* Align selected objects to left most edge. */
1675 /*****************************************************************************/
1677 gl_view_align_selection_left (glView *view)
1680 glViewObject *view_object;
1681 glLabelObject *object;
1683 glLabelRegion obj_extent;
1685 gl_debug (DEBUG_VIEW, "START");
1687 g_return_if_fail (view && GL_IS_VIEW (view));
1689 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1690 !gl_view_is_selection_atomic (view));
1692 /* find left most edge */
1693 p = view->selected_object_list;
1694 view_object = GL_VIEW_OBJECT (p->data);
1695 object = gl_view_object_get_object (view_object);
1696 gl_label_object_get_extent (object, &obj_extent);
1697 x1_min = obj_extent.x1;
1698 for (p = p->next; p != NULL; p = p->next)
1700 view_object = GL_VIEW_OBJECT (p->data);
1701 object = gl_view_object_get_object (view_object);
1702 gl_label_object_get_extent (object, &obj_extent);
1703 if ( obj_extent.x1 < x1_min ) x1_min = obj_extent.x1;
1706 /* now adjust the object positions to line up the left edges */
1707 for (p = view->selected_object_list; p != NULL; p = p->next)
1709 view_object = GL_VIEW_OBJECT (p->data);
1710 object = gl_view_object_get_object (view_object);
1711 gl_label_object_get_extent (object, &obj_extent);
1712 dx = x1_min - obj_extent.x1;
1713 gl_label_object_set_position_relative (object, dx, 0.0);
1716 gl_debug (DEBUG_VIEW, "END");
1720 /*****************************************************************************/
1721 /* Align selected objects to right most edge. */
1722 /*****************************************************************************/
1724 gl_view_align_selection_right (glView *view)
1727 glViewObject *view_object;
1728 glLabelObject *object;
1730 glLabelRegion obj_extent;
1732 gl_debug (DEBUG_VIEW, "START");
1734 g_return_if_fail (view && GL_IS_VIEW (view));
1736 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1737 !gl_view_is_selection_atomic (view));
1739 /* find right most edge */
1740 p = view->selected_object_list;
1741 view_object = GL_VIEW_OBJECT (p->data);
1742 object = gl_view_object_get_object (view_object);
1743 gl_label_object_get_extent (object, &obj_extent);
1744 x2_max = obj_extent.x2;
1745 for (p = p->next; p != NULL; p = p->next)
1747 view_object = GL_VIEW_OBJECT (p->data);
1748 object = gl_view_object_get_object (view_object);
1749 gl_label_object_get_extent (object, &obj_extent);
1750 if ( obj_extent.x2 > x2_max ) x2_max = obj_extent.x2;
1753 /* now adjust the object positions to line up the right edges */
1754 for (p = view->selected_object_list; p != NULL; p = p->next)
1756 view_object = GL_VIEW_OBJECT (p->data);
1757 object = gl_view_object_get_object (view_object);
1758 gl_label_object_get_extent (object, &obj_extent);
1759 dx = x2_max - obj_extent.x2;
1760 gl_label_object_set_position_relative (object, dx, 0.0);
1763 gl_debug (DEBUG_VIEW, "END");
1766 /*****************************************************************************/
1767 /* Align selected objects to horizontal center of objects. */
1768 /*****************************************************************************/
1770 gl_view_align_selection_hcenter (glView *view)
1773 glViewObject *view_object;
1774 glLabelObject *object;
1778 glLabelRegion obj_extent;
1782 gl_debug (DEBUG_VIEW, "START");
1784 g_return_if_fail (view && GL_IS_VIEW (view));
1786 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1787 !gl_view_is_selection_atomic (view));
1789 /* find average center of objects */
1792 for (p = view->selected_object_list; p != NULL; p = p->next)
1794 view_object = GL_VIEW_OBJECT (p->data);
1795 object = gl_view_object_get_object (view_object);
1796 gl_label_object_get_extent (object, &obj_extent);
1797 xsum += (obj_extent.x1 + obj_extent.x2) / 2.0;
1802 /* find center of object closest to average center */
1803 p = view->selected_object_list;
1804 view_object = GL_VIEW_OBJECT (p->data);
1805 object = gl_view_object_get_object (view_object);
1806 gl_label_object_get_extent (object, &obj_extent);
1807 dxmin = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
1808 xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
1809 for (p = p->next; p != NULL; p = p->next)
1811 view_object = GL_VIEW_OBJECT (p->data);
1812 object = gl_view_object_get_object (view_object);
1813 gl_label_object_get_extent (object, &obj_extent);
1814 dx = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
1818 xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
1822 /* now adjust the object positions to line up this center */
1823 for (p = view->selected_object_list; p != NULL; p = p->next) {
1824 view_object = GL_VIEW_OBJECT (p->data);
1825 object = gl_view_object_get_object (view_object);
1826 gl_label_object_get_extent (object, &obj_extent);
1827 dx = xcenter - (obj_extent.x1 + obj_extent.x2)/2.0;
1828 gl_label_object_set_position_relative (object, dx, 0.0);
1831 gl_debug (DEBUG_VIEW, "END");
1834 /*****************************************************************************/
1835 /* Align selected objects to top most edge. */
1836 /*****************************************************************************/
1838 gl_view_align_selection_top (glView *view)
1841 glViewObject *view_object;
1842 glLabelObject *object;
1844 glLabelRegion obj_extent;
1846 gl_debug (DEBUG_VIEW, "START");
1848 g_return_if_fail (view && GL_IS_VIEW (view));
1850 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1851 !gl_view_is_selection_atomic (view));
1853 /* find top most edge */
1854 p = view->selected_object_list;
1855 view_object = GL_VIEW_OBJECT (p->data);
1856 object = gl_view_object_get_object (view_object);
1857 gl_label_object_get_extent (object, &obj_extent);
1858 y1_min = obj_extent.y1;
1859 for (p = p->next; p != NULL; p = p->next)
1861 view_object = GL_VIEW_OBJECT (p->data);
1862 object = gl_view_object_get_object (view_object);
1863 gl_label_object_get_extent (object, &obj_extent);
1864 if ( obj_extent.y1 < y1_min ) y1_min = obj_extent.y1;
1867 /* now adjust the object positions to line up the top edges */
1868 for (p = view->selected_object_list; p != NULL; p = p->next)
1870 view_object = GL_VIEW_OBJECT (p->data);
1871 object = gl_view_object_get_object (view_object);
1872 gl_label_object_get_extent (object, &obj_extent);
1873 dy = y1_min - obj_extent.y1;
1874 gl_label_object_set_position_relative (object, 0.0, dy);
1877 gl_debug (DEBUG_VIEW, "END");
1880 /*****************************************************************************/
1881 /* Align selected objects to bottom most edge. */
1882 /*****************************************************************************/
1884 gl_view_align_selection_bottom (glView *view)
1887 glViewObject *view_object;
1888 glLabelObject *object;
1890 glLabelRegion obj_extent;
1892 gl_debug (DEBUG_VIEW, "START");
1894 g_return_if_fail (view && GL_IS_VIEW (view));
1896 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1897 !gl_view_is_selection_atomic (view));
1899 /* find bottom most edge */
1900 p = view->selected_object_list;
1901 view_object = GL_VIEW_OBJECT (p->data);
1902 object = gl_view_object_get_object (view_object);
1903 gl_label_object_get_extent (object, &obj_extent);
1904 y2_max = obj_extent.y2;
1905 for (p = p->next; p != NULL; p = p->next)
1907 view_object = GL_VIEW_OBJECT (p->data);
1908 object = gl_view_object_get_object (view_object);
1909 gl_label_object_get_extent (object, &obj_extent);
1910 if ( obj_extent.y2 > y2_max ) y2_max = obj_extent.y2;
1913 /* now adjust the object positions to line up the bottom edges */
1914 for (p = view->selected_object_list; p != NULL; p = p->next)
1916 view_object = GL_VIEW_OBJECT (p->data);
1917 object = gl_view_object_get_object (view_object);
1918 gl_label_object_get_extent (object, &obj_extent);
1919 dy = y2_max - obj_extent.y2;
1920 gl_label_object_set_position_relative (object, 0.0, dy);
1923 gl_debug (DEBUG_VIEW, "END");
1926 /*****************************************************************************/
1927 /* Align selected objects to viertical center of objects. */
1928 /*****************************************************************************/
1930 gl_view_align_selection_vcenter (glView *view)
1933 glViewObject *view_object;
1934 glLabelObject *object;
1938 glLabelRegion obj_extent;
1942 gl_debug (DEBUG_VIEW, "START");
1944 g_return_if_fail (view && GL_IS_VIEW (view));
1946 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1947 !gl_view_is_selection_atomic (view));
1949 /* find average center of objects */
1952 for (p = view->selected_object_list; p != NULL; p = p->next)
1954 view_object = GL_VIEW_OBJECT (p->data);
1955 object = gl_view_object_get_object (view_object);
1956 gl_label_object_get_extent (object, &obj_extent);
1957 ysum += (obj_extent.y1 + obj_extent.y2) / 2.0;
1962 /* find center of object closest to average center */
1963 p = view->selected_object_list;
1964 view_object = GL_VIEW_OBJECT (p->data);
1965 object = gl_view_object_get_object (view_object);
1966 gl_label_object_get_extent (object, &obj_extent);
1967 dymin = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
1968 ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
1969 for (p = p->next; p != NULL; p = p->next)
1971 view_object = GL_VIEW_OBJECT (p->data);
1972 object = gl_view_object_get_object (view_object);
1973 gl_label_object_get_extent (object, &obj_extent);
1974 dy = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
1978 ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
1982 /* now adjust the object positions to line up this center */
1983 for (p = view->selected_object_list; p != NULL; p = p->next)
1985 view_object = GL_VIEW_OBJECT (p->data);
1986 object = gl_view_object_get_object (view_object);
1987 gl_label_object_get_extent (object, &obj_extent);
1988 dy = ycenter - (obj_extent.y1 + obj_extent.y2)/2.0;
1989 gl_label_object_set_position_relative (object, 0.0, dy);
1992 gl_debug (DEBUG_VIEW, "END");
1995 /*****************************************************************************/
1996 /* Center selected objects to in center of label. */
1997 /*****************************************************************************/
1999 gl_view_center_selection_horiz (glView *view)
2002 glViewObject *view_object;
2003 glLabelObject *object;
2005 gdouble x_label_center;
2006 gdouble x_obj_center;
2007 glLabelRegion obj_extent;
2010 gl_debug (DEBUG_VIEW, "START");
2012 g_return_if_fail (view && GL_IS_VIEW (view));
2014 g_return_if_fail (!gl_view_is_selection_empty (view));
2016 gl_label_get_size (view->label, &w, &h);
2017 x_label_center = w / 2.0;
2019 /* adjust the object positions */
2020 for (p = view->selected_object_list; p != NULL; p = p->next)
2022 view_object = GL_VIEW_OBJECT (p->data);
2023 object = gl_view_object_get_object (view_object);
2024 gl_label_object_get_extent (object, &obj_extent);
2025 x_obj_center = (obj_extent.x1 + obj_extent.x2) / 2.0;
2026 dx = x_label_center - x_obj_center;
2027 gl_label_object_set_position_relative (object, dx, 0.0);
2030 gl_debug (DEBUG_VIEW, "END");
2034 /*****************************************************************************/
2035 /* Center selected objects to in center of label. */
2036 /*****************************************************************************/
2038 gl_view_center_selection_vert (glView *view)
2041 glViewObject *view_object;
2042 glLabelObject *object;
2044 gdouble y_label_center;
2045 gdouble y_obj_center;
2046 glLabelRegion obj_extent;
2049 gl_debug (DEBUG_VIEW, "START");
2051 g_return_if_fail (view && GL_IS_VIEW (view));
2053 g_return_if_fail (!gl_view_is_selection_empty (view));
2055 gl_label_get_size (view->label, &w, &h);
2056 y_label_center = h / 2.0;
2058 /* adjust the object positions */
2059 for (p = view->selected_object_list; p != NULL; p = p->next)
2061 view_object = GL_VIEW_OBJECT (p->data);
2062 object = gl_view_object_get_object (view_object);
2063 gl_label_object_get_extent (object, &obj_extent);
2064 y_obj_center = (obj_extent.y1 + obj_extent.y2) / 2.0;
2065 dy = y_label_center - y_obj_center;
2066 gl_label_object_set_position_relative (object, 0.0, dy);
2069 gl_debug (DEBUG_VIEW, "END");
2073 /*****************************************************************************/
2074 /* Move selected objects */
2075 /*****************************************************************************/
2077 gl_view_move_selection (glView *view,
2082 glLabelObject *object;
2084 gl_debug (DEBUG_VIEW, "START");
2086 g_return_if_fail (view && GL_IS_VIEW (view));
2088 for (p = view->selected_object_list; p != NULL; p = p->next)
2091 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2092 gl_label_object_set_position_relative (object, dx, dy);
2096 gl_debug (DEBUG_VIEW, "END");
2099 /*****************************************************************************/
2100 /* Can text properties be set for selection? */
2101 /*****************************************************************************/
2103 gl_view_can_selection_text (glView *view)
2106 glLabelObject *object;
2108 gl_debug (DEBUG_VIEW, "");
2110 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2112 for (p = view->selected_object_list; p != NULL; p = p->next)
2115 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2116 if (gl_label_object_can_text (object))
2126 /*****************************************************************************/
2127 /* Set font family for all text contained in selected objects. */
2128 /*****************************************************************************/
2130 gl_view_set_selection_font_family (glView *view,
2131 const gchar *font_family)
2134 glLabelObject *object;
2136 gl_debug (DEBUG_VIEW, "START");
2138 g_return_if_fail (view && GL_IS_VIEW (view));
2140 for (p = view->selected_object_list; p != NULL; p = p->next) {
2142 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2143 gl_label_object_set_font_family (object, font_family);
2147 gl_debug (DEBUG_VIEW, "END");
2150 /*****************************************************************************/
2151 /* Set font size for all text contained in selected objects. */
2152 /*****************************************************************************/
2154 gl_view_set_selection_font_size (glView *view,
2158 glLabelObject *object;
2160 gl_debug (DEBUG_VIEW, "START");
2162 g_return_if_fail (view && GL_IS_VIEW (view));
2164 for (p = view->selected_object_list; p != NULL; p = p->next) {
2166 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2167 gl_label_object_set_font_size (object, font_size);
2171 gl_debug (DEBUG_VIEW, "END");
2174 /*****************************************************************************/
2175 /* Set font weight for all text contained in selected objects. */
2176 /*****************************************************************************/
2178 gl_view_set_selection_font_weight (glView *view,
2179 PangoWeight font_weight)
2182 glLabelObject *object;
2184 gl_debug (DEBUG_VIEW, "START");
2186 g_return_if_fail (view && GL_IS_VIEW (view));
2188 for (p = view->selected_object_list; p != NULL; p = p->next) {
2190 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2191 gl_label_object_set_font_weight (object, font_weight);
2195 gl_debug (DEBUG_VIEW, "END");
2198 /*****************************************************************************/
2199 /* Set font italic flag for all text contained in selected objects. */
2200 /*****************************************************************************/
2202 gl_view_set_selection_font_italic_flag (glView *view,
2203 gboolean font_italic_flag)
2206 glLabelObject *object;
2208 gl_debug (DEBUG_VIEW, "START");
2210 g_return_if_fail (view && GL_IS_VIEW (view));
2212 for (p = view->selected_object_list; p != NULL; p = p->next) {
2214 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2215 gl_label_object_set_font_italic_flag (object, font_italic_flag);
2219 gl_debug (DEBUG_VIEW, "END");
2222 /*****************************************************************************/
2223 /* Set text alignment for all text contained in selected objects. */
2224 /*****************************************************************************/
2226 gl_view_set_selection_text_alignment (glView *view,
2227 PangoAlignment text_alignment)
2230 glLabelObject *object;
2232 gl_debug (DEBUG_VIEW, "START");
2234 g_return_if_fail (view && GL_IS_VIEW (view));
2236 for (p = view->selected_object_list; p != NULL; p = p->next) {
2238 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2239 gl_label_object_set_text_alignment (object, text_alignment);
2243 gl_debug (DEBUG_VIEW, "END");
2246 /*****************************************************************************/
2247 /* Set text line spacing for all text contained in selected objects. */
2248 /*****************************************************************************/
2250 gl_view_set_selection_text_line_spacing (glView *view,
2251 gdouble text_line_spacing)
2254 glLabelObject *object;
2256 gl_debug (DEBUG_VIEW, "START");
2258 g_return_if_fail (view && GL_IS_VIEW (view));
2260 for (p = view->selected_object_list; p != NULL; p = p->next) {
2262 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2263 gl_label_object_set_text_line_spacing (object, text_line_spacing);
2267 gl_debug (DEBUG_VIEW, "END");
2269 /*****************************************************************************/
2270 /* Set text color for all text contained in selected objects. */
2271 /*****************************************************************************/
2273 gl_view_set_selection_text_color (glView *view,
2274 glColorNode *text_color_node)
2277 glLabelObject *object;
2279 gl_debug (DEBUG_VIEW, "START");
2281 g_return_if_fail (view && GL_IS_VIEW (view));
2283 for (p = view->selected_object_list; p != NULL; p = p->next) {
2285 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2286 gl_label_object_set_text_color (object, text_color_node);
2290 gl_debug (DEBUG_VIEW, "END");
2293 /*****************************************************************************/
2294 /* Can fill properties be set for selection? */
2295 /*****************************************************************************/
2297 gl_view_can_selection_fill (glView *view)
2300 glLabelObject *object;
2302 gl_debug (DEBUG_VIEW, "");
2304 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2306 for (p = view->selected_object_list; p != NULL; p = p->next) {
2308 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2309 if (gl_label_object_can_fill (object)) {
2318 /*****************************************************************************/
2319 /* Set fill color for all selected objects. */
2320 /*****************************************************************************/
2322 gl_view_set_selection_fill_color (glView *view,
2323 glColorNode *fill_color_node)
2326 glLabelObject *object;
2328 gl_debug (DEBUG_VIEW, "START");
2330 g_return_if_fail (view && GL_IS_VIEW (view));
2332 for (p = view->selected_object_list; p != NULL; p = p->next) {
2334 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2335 gl_label_object_set_fill_color (object, fill_color_node);
2339 gl_debug (DEBUG_VIEW, "END");
2342 /*****************************************************************************/
2343 /* Can line color properties be set for selection? */
2344 /*****************************************************************************/
2346 gl_view_can_selection_line_color (glView *view)
2349 glLabelObject *object;
2351 gl_debug (DEBUG_VIEW, "");
2353 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2355 for (p = view->selected_object_list; p != NULL; p = p->next) {
2357 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2358 if (gl_label_object_can_line_color (object)) {
2367 /*****************************************************************************/
2368 /* Set line color for all selected objects. */
2369 /*****************************************************************************/
2371 gl_view_set_selection_line_color (glView *view,
2372 glColorNode *line_color_node)
2375 glLabelObject *object;
2377 gl_debug (DEBUG_VIEW, "START");
2379 g_return_if_fail (view && GL_IS_VIEW (view));
2381 for (p = view->selected_object_list; p != NULL; p = p->next) {
2383 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2384 gl_label_object_set_line_color (object, line_color_node);
2388 gl_debug (DEBUG_VIEW, "END");
2391 /*****************************************************************************/
2392 /* Can line width properties be set for selection? */
2393 /*****************************************************************************/
2395 gl_view_can_selection_line_width (glView *view)
2398 glLabelObject *object;
2400 gl_debug (DEBUG_VIEW, "");
2402 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2404 for (p = view->selected_object_list; p != NULL; p = p->next) {
2406 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2407 if (gl_label_object_can_line_width (object)) {
2416 /*****************************************************************************/
2417 /* Set line width for all selected objects. */
2418 /*****************************************************************************/
2420 gl_view_set_selection_line_width (glView *view,
2424 glLabelObject *object;
2426 gl_debug (DEBUG_VIEW, "START");
2428 g_return_if_fail (view && GL_IS_VIEW (view));
2430 for (p = view->selected_object_list; p != NULL; p = p->next) {
2432 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2433 gl_label_object_set_line_width (object, line_width);
2437 gl_debug (DEBUG_VIEW, "END");
2440 /*****************************************************************************/
2441 /* "Cut" selected items and place in clipboard selections. */
2442 /*****************************************************************************/
2444 gl_view_cut (glView *view)
2446 gl_debug (DEBUG_VIEW, "START");
2448 g_return_if_fail (view && GL_IS_VIEW (view));
2450 gl_view_copy (view);
2451 gl_view_delete_selection (view);
2453 gl_debug (DEBUG_VIEW, "END");
2456 /*****************************************************************************/
2457 /* "Copy" selected items to clipboard selections. */
2458 /*****************************************************************************/
2460 gl_view_copy (glView *view)
2463 glViewObject *view_object;
2464 glLabelObject *object;
2466 gl_debug (DEBUG_VIEW, "START");
2468 g_return_if_fail (view && GL_IS_VIEW (view));
2470 if (view->selected_object_list) {
2472 if ( view->selection_data ) {
2473 g_object_unref (view->selection_data);
2475 view->selection_data = GL_LABEL(gl_label_new ());
2476 gl_label_set_template (view->selection_data, view->label->template);
2477 gl_label_set_rotate_flag (view->selection_data, view->label->rotate_flag);
2479 for (p = view->selected_object_list; p != NULL; p = p->next) {
2481 view_object = GL_VIEW_OBJECT (p->data);
2482 object = gl_view_object_get_object (view_object);
2484 gl_label_object_dup (object, view->selection_data);
2488 gtk_selection_owner_set (view->invisible,
2489 clipboard_atom, GDK_CURRENT_TIME);
2490 view->have_selection = TRUE;
2494 gl_debug (DEBUG_VIEW, "END");
2497 /*****************************************************************************/
2498 /* "Paste" from private clipboard selection. */
2499 /*****************************************************************************/
2501 gl_view_paste (glView *view)
2503 gl_debug (DEBUG_VIEW, "START");
2505 g_return_if_fail (view && GL_IS_VIEW (view));
2507 gtk_selection_convert (GTK_WIDGET (view->invisible),
2508 clipboard_atom, GDK_SELECTION_TYPE_STRING,
2511 gl_debug (DEBUG_VIEW, "END");
2514 /*****************************************************************************/
2515 /* Zoom in one "notch" */
2516 /*****************************************************************************/
2518 gl_view_zoom_in (glView *view)
2521 gdouble dist, dist_min;
2523 gl_debug (DEBUG_VIEW, "START");
2525 g_return_if_fail (view && GL_IS_VIEW (view));
2527 /* Find index of current scale (or best match) */
2528 i_min = 1; /* start with 2nd largest scale */
2529 dist_min = fabs (zooms[1] - view->zoom);
2530 for (i = 2; i < N_ZOOMS; i++) {
2531 dist = fabs (zooms[i] - view->zoom);
2532 if (dist < dist_min) {
2538 /* zoom in one "notch" */
2539 i = MAX (0, i_min - 1);
2540 gl_debug (DEBUG_VIEW, "zoom[%d] = %g", i, zooms[i]);
2541 set_zoom_real (view, zooms[i], FALSE);
2543 gl_debug (DEBUG_VIEW, "END");
2546 /*****************************************************************************/
2547 /* Zoom out one "notch" */
2548 /*****************************************************************************/
2550 gl_view_zoom_out (glView *view)
2553 gdouble dist, dist_min;
2555 gl_debug (DEBUG_VIEW, "START");
2557 g_return_if_fail (view && GL_IS_VIEW (view));
2559 /* Find index of current scale (or best match) */
2560 i_min = 0; /* start with largest scale */
2561 dist_min = fabs (zooms[0] - view->zoom);
2562 for (i = 1; i < N_ZOOMS; i++) {
2563 dist = fabs (zooms[i] - view->zoom);
2564 if (dist < dist_min) {
2570 /* zoom out one "notch" */
2571 if (i_min >= N_ZOOMS)
2576 set_zoom_real (view, zooms[i], FALSE);
2578 gl_debug (DEBUG_VIEW, "END");
2581 /*****************************************************************************/
2582 /* Set zoom to best fit. */
2583 /*****************************************************************************/
2585 gl_view_zoom_to_fit (glView *view)
2587 gint w_view, h_view;
2588 gdouble w_label, h_label;
2589 gdouble x_scale, y_scale, scale;
2591 gl_debug (DEBUG_VIEW, "");
2593 if ( ! GTK_WIDGET_VISIBLE(view)) {
2594 set_zoom_real (view, 1.0, TRUE);
2598 w_view = GTK_WIDGET(view)->allocation.width;
2599 h_view = GTK_WIDGET(view)->allocation.height;
2601 gl_label_get_size (GL_LABEL(view->label), &w_label, &h_label);
2603 gl_debug (DEBUG_VIEW, "View size: %d, %d", w_view, h_view);
2604 gl_debug (DEBUG_VIEW, "Label size: %g, %g", w_label, h_label);
2606 /* Calculate best scale */
2607 x_scale = (double)(w_view - ZOOMTOFIT_PAD) / w_label;
2608 y_scale = (double)(h_view - ZOOMTOFIT_PAD) / h_label;
2609 scale = MIN (x_scale, y_scale);
2610 gl_debug (DEBUG_VIEW, "Candidate zooms: %g, %g => %g", x_scale, y_scale, scale);
2613 gl_debug (DEBUG_VIEW, "Scale: %g", scale);
2614 scale = MIN (scale, zooms[0]*view->home_scale);
2615 scale = MAX (scale, zooms[N_ZOOMS-1]*view->home_scale);
2616 gl_debug (DEBUG_VIEW, "Limitted scale: %g", scale);
2618 set_zoom_real (view, scale/view->home_scale, TRUE);
2621 /*****************************************************************************/
2622 /* Set current zoom factor to explicit value. */
2623 /*****************************************************************************/
2625 gl_view_set_zoom (glView *view,
2628 gl_debug (DEBUG_VIEW, "START");
2630 set_zoom_real (view, zoom, FALSE);
2632 gl_debug (DEBUG_VIEW, "END");
2635 /*---------------------------------------------------------------------------*/
2636 /* PRIVATE. Set canvas scale. */
2637 /*---------------------------------------------------------------------------*/
2639 set_zoom_real (glView *view,
2641 gboolean zoom_to_fit_flag)
2643 gl_debug (DEBUG_VIEW, "START");
2645 g_return_if_fail (view && GL_IS_VIEW (view));
2646 g_return_if_fail (zoom > 0.0);
2648 /* Limit, if needed */
2649 gl_debug (DEBUG_VIEW, "Zoom requested: %g", zoom);
2650 zoom = MIN (zoom, zooms[0]);
2651 zoom = MAX (zoom, zooms[N_ZOOMS-1]);
2652 gl_debug (DEBUG_VIEW, "Limitted zoom: %g", zoom);
2654 if ( zoom != view->zoom ) {
2657 view->zoom_to_fit_flag = zoom_to_fit_flag;
2659 gl_view_update (view);
2661 g_signal_emit (G_OBJECT(view), signals[ZOOM_CHANGED], 0, zoom);
2665 gl_debug (DEBUG_VIEW, "END");
2670 /*****************************************************************************/
2671 /* Get current zoom factor. */
2672 /*****************************************************************************/
2674 gl_view_get_zoom (glView *view)
2676 gl_debug (DEBUG_VIEW, "");
2678 g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
2683 /*****************************************************************************/
2684 /* Is this the maximum zoom level. */
2685 /*****************************************************************************/
2687 gl_view_is_zoom_max (glView *view)
2689 gl_debug (DEBUG_VIEW, "");
2691 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
2693 return view->zoom >= zooms[0];
2696 /*****************************************************************************/
2697 /* Is this the minimum zoom level. */
2698 /*****************************************************************************/
2700 gl_view_is_zoom_min (glView *view)
2702 gl_debug (DEBUG_VIEW, "");
2704 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2706 return view->zoom <= zooms[N_ZOOMS-1];
2709 /*---------------------------------------------------------------------------*/
2710 /* PRIVATE. Handle "selection-clear" signal. */
2711 /*---------------------------------------------------------------------------*/
2713 selection_clear_cb (GtkWidget *widget,
2714 GdkEventSelection *event,
2717 gl_debug (DEBUG_VIEW, "START");
2719 g_return_if_fail (view && GL_IS_VIEW (view));
2721 view->have_selection = FALSE;
2722 g_object_unref (view->selection_data);
2723 view->selection_data = NULL;
2725 gl_debug (DEBUG_VIEW, "END");
2728 /*---------------------------------------------------------------------------*/
2729 /* PRIVATE. Handle "selection-get" signal. */
2730 /*---------------------------------------------------------------------------*/
2732 selection_get_cb (GtkWidget *widget,
2733 GtkSelectionData *selection_data,
2739 glXMLLabelStatus status;
2741 gl_debug (DEBUG_VIEW, "START");
2743 g_return_if_fail (view && GL_IS_VIEW (view));
2745 if (view->have_selection) {
2747 buffer = gl_xml_label_save_buffer (view->selection_data,
2749 gtk_selection_data_set (selection_data,
2750 GDK_SELECTION_TYPE_STRING, 8,
2751 (guchar *)buffer, strlen (buffer));
2755 gl_debug (DEBUG_VIEW, "END");
2758 /*---------------------------------------------------------------------------*/
2759 /* PRIVATE. Handle "selection-received" signal. (Result of Paste) */
2760 /*---------------------------------------------------------------------------*/
2762 selection_received_cb (GtkWidget *widget,
2763 GtkSelectionData *selection_data,
2767 glLabel *label = NULL;
2768 glXMLLabelStatus status;
2770 glLabelObject *object, *newobject;
2771 glViewObject *view_object;
2773 gl_debug (DEBUG_VIEW, "START");
2775 g_return_if_fail (view && GL_IS_VIEW (view));
2777 if (selection_data->length < 0) {
2780 if (selection_data->type != GDK_SELECTION_TYPE_STRING) {
2784 gl_view_unselect_all (view);
2786 label = gl_xml_label_open_buffer ((gchar *)selection_data->data, &status);
2787 for (p = label->objects; p != NULL; p = p_next) {
2790 object = (glLabelObject *) p->data;
2791 newobject = gl_label_object_dup (object, view->label);
2793 gl_debug (DEBUG_VIEW, "object pasted");
2795 if (GL_IS_LABEL_BOX (newobject)) {
2796 view_object = gl_view_box_new (GL_LABEL_BOX(newobject),
2798 } else if (GL_IS_LABEL_ELLIPSE (newobject)) {
2799 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(newobject),
2801 } else if (GL_IS_LABEL_LINE (newobject)) {
2802 view_object = gl_view_line_new (GL_LABEL_LINE(newobject),
2804 } else if (GL_IS_LABEL_IMAGE (newobject)) {
2805 view_object = gl_view_image_new (GL_LABEL_IMAGE(newobject),
2807 } else if (GL_IS_LABEL_TEXT (newobject)) {
2808 view_object = gl_view_text_new (GL_LABEL_TEXT(newobject),
2810 } else if (GL_IS_LABEL_BARCODE (newobject)) {
2811 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(newobject),
2814 /* Should not happen! */
2816 g_message ("Invalid label object type.");
2818 gl_view_select_object (view, view_object);
2820 g_object_unref (label);
2822 gl_debug (DEBUG_VIEW, "END");
2825 /****************************************************************************/
2826 /* Set default font family. */
2827 /****************************************************************************/
2829 gl_view_set_default_font_family (glView *view,
2830 const gchar *font_family)
2832 gl_debug (DEBUG_VIEW, "START");
2834 g_return_if_fail (view && GL_IS_VIEW (view));
2836 if (view->default_font_family) {
2837 g_free (view->default_font_family);
2839 view->default_font_family = g_strdup (font_family);
2841 gl_debug (DEBUG_VIEW, "END");
2845 /****************************************************************************/
2846 /* Set default font size. */
2847 /****************************************************************************/
2849 gl_view_set_default_font_size (glView *view,
2852 gl_debug (DEBUG_VIEW, "START");
2854 g_return_if_fail (view && GL_IS_VIEW (view));
2856 view->default_font_size = font_size;
2858 gl_debug (DEBUG_VIEW, "END");
2862 /****************************************************************************/
2863 /* Set default font weight. */
2864 /****************************************************************************/
2866 gl_view_set_default_font_weight (glView *view,
2867 PangoWeight font_weight)
2869 gl_debug (DEBUG_VIEW, "START");
2871 g_return_if_fail (view && GL_IS_VIEW (view));
2873 view->default_font_weight = font_weight;
2875 gl_debug (DEBUG_VIEW, "END");
2879 /****************************************************************************/
2880 /* Set default font italic flag. */
2881 /****************************************************************************/
2883 gl_view_set_default_font_italic_flag (glView *view,
2884 gboolean font_italic_flag)
2886 gl_debug (DEBUG_VIEW, "START");
2888 g_return_if_fail (view && GL_IS_VIEW (view));
2890 view->default_font_italic_flag = font_italic_flag;
2892 gl_debug (DEBUG_VIEW, "END");
2896 /****************************************************************************/
2897 /* Set default text color. */
2898 /****************************************************************************/
2900 gl_view_set_default_text_color (glView *view,
2903 gl_debug (DEBUG_VIEW, "START");
2905 g_return_if_fail (view && GL_IS_VIEW (view));
2907 view->default_text_color = text_color;
2909 gl_debug (DEBUG_VIEW, "END");
2913 /****************************************************************************/
2914 /* Set default text alignment. */
2915 /****************************************************************************/
2917 gl_view_set_default_text_alignment (glView *view,
2918 PangoAlignment text_alignment)
2920 gl_debug (DEBUG_VIEW, "START");
2922 g_return_if_fail (view && GL_IS_VIEW (view));
2924 view->default_text_alignment = text_alignment;
2925 gl_debug (DEBUG_VIEW, "END");
2928 /****************************************************************************/
2929 /* Set default text line spacing. */
2930 /****************************************************************************/
2932 gl_view_set_default_text_line_spacing (glView *view,
2933 gdouble text_line_spacing)
2935 gl_debug (DEBUG_VIEW, "START");
2937 g_return_if_fail (view && GL_IS_VIEW (view));
2939 view->default_text_line_spacing = text_line_spacing;
2941 gl_debug (DEBUG_VIEW, "END");
2945 /****************************************************************************/
2946 /* Set default line width. */
2947 /****************************************************************************/
2949 gl_view_set_default_line_width (glView *view,
2952 gl_debug (DEBUG_VIEW, "START");
2954 g_return_if_fail (view && GL_IS_VIEW (view));
2956 view->default_line_width = line_width;
2958 gl_debug (DEBUG_VIEW, "END");
2962 /****************************************************************************/
2963 /* Set default line color. */
2964 /****************************************************************************/
2966 gl_view_set_default_line_color (glView *view,
2969 gl_debug (DEBUG_VIEW, "START");
2971 g_return_if_fail (view && GL_IS_VIEW (view));
2973 view->default_line_color = line_color;
2975 gl_debug (DEBUG_VIEW, "END");
2979 /****************************************************************************/
2980 /* Set default fill color. */
2981 /****************************************************************************/
2983 gl_view_set_default_fill_color (glView *view,
2986 gl_debug (DEBUG_VIEW, "START");
2988 g_return_if_fail (view && GL_IS_VIEW (view));
2990 view->default_fill_color = fill_color;
2992 gl_debug (DEBUG_VIEW, "END");
2997 /****************************************************************************/
2998 /* Get default font family. */
2999 /****************************************************************************/
3001 gl_view_get_default_font_family (glView *view)
3003 gl_debug (DEBUG_VIEW, "START");
3005 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
3007 gl_debug (DEBUG_VIEW, "END");
3009 return g_strdup (view->default_font_family);
3013 /****************************************************************************/
3014 /* Get default font size. */
3015 /****************************************************************************/
3017 gl_view_get_default_font_size (glView *view)
3019 gl_debug (DEBUG_VIEW, "START");
3021 g_return_val_if_fail (view && GL_IS_VIEW (view), 12.0);
3023 gl_debug (DEBUG_VIEW, "END");
3025 return view->default_font_size;
3029 /****************************************************************************/
3030 /* Get default font weight. */
3031 /****************************************************************************/
3033 gl_view_get_default_font_weight (glView *view)
3035 gl_debug (DEBUG_VIEW, "START");
3037 g_return_val_if_fail (view && GL_IS_VIEW (view), PANGO_WEIGHT_NORMAL);
3039 gl_debug (DEBUG_VIEW, "END");
3041 return view->default_font_weight;
3045 /****************************************************************************/
3046 /* Get default font italic flag. */
3047 /****************************************************************************/
3049 gl_view_get_default_font_italic_flag (glView *view)
3051 gl_debug (DEBUG_VIEW, "START");
3053 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3055 gl_debug (DEBUG_VIEW, "END");
3057 return view->default_font_italic_flag;
3061 /****************************************************************************/
3062 /* Get default text color. */
3063 /****************************************************************************/
3065 gl_view_get_default_text_color (glView *view)
3067 gl_debug (DEBUG_VIEW, "START");
3069 g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
3071 gl_debug (DEBUG_VIEW, "END");
3073 return view->default_text_color;
3077 /****************************************************************************/
3078 /* Get default text alignment. */
3079 /****************************************************************************/
3081 gl_view_get_default_text_alignment (glView *view)
3083 gl_debug (DEBUG_VIEW, "START");
3085 g_return_val_if_fail (view && GL_IS_VIEW (view), PANGO_ALIGN_LEFT);
3087 gl_debug (DEBUG_VIEW, "END");
3089 return view->default_text_alignment;
3092 /****************************************************************************/
3093 /* Get default text line spacing. */
3094 /****************************************************************************/
3096 gl_view_get_default_text_line_spacing (glView *view)
3098 gl_debug (DEBUG_VIEW, "START");
3100 g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
3102 gl_debug (DEBUG_VIEW, "END");
3104 return view->default_text_line_spacing;
3109 /****************************************************************************/
3110 /* Get default line width. */
3111 /****************************************************************************/
3113 gl_view_get_default_line_width (glView *view)
3115 gl_debug (DEBUG_VIEW, "START");
3117 g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
3119 gl_debug (DEBUG_VIEW, "END");
3121 return view->default_line_width;
3125 /****************************************************************************/
3126 /* Get default line color. */
3127 /****************************************************************************/
3129 gl_view_get_default_line_color (glView *view)
3131 gl_debug (DEBUG_VIEW, "START");
3133 g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
3135 gl_debug (DEBUG_VIEW, "END");
3137 return view->default_line_color;
3141 /****************************************************************************/
3142 /* Get default fill color. */
3143 /****************************************************************************/
3145 gl_view_get_default_fill_color (glView *view)
3147 gl_debug (DEBUG_VIEW, "START");
3149 g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
3151 gl_debug (DEBUG_VIEW, "END");
3153 return view->default_fill_color;
3156 /*---------------------------------------------------------------------------*/
3157 /* PRIVATE. Focus in event handler. */
3158 /*---------------------------------------------------------------------------*/
3160 focus_in_event_cb (glView *view,
3161 GdkEventFocus *event)
3163 GTK_WIDGET_SET_FLAGS (GTK_WIDGET (view->canvas), GTK_HAS_FOCUS);
3168 /*---------------------------------------------------------------------------*/
3169 /* PRIVATE. Focus out event handler. */
3170 /*---------------------------------------------------------------------------*/
3172 focus_out_event_cb (glView *view,
3173 GdkEventFocus *event)
3175 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (view->canvas), GTK_HAS_FOCUS);
3180 /*---------------------------------------------------------------------------*/
3181 /* PRIVATE. Enter notify event handler. */
3182 /*---------------------------------------------------------------------------*/
3184 enter_notify_event_cb (glView *view,
3185 GdkEventCrossing *event)
3187 gtk_widget_grab_focus(GTK_WIDGET (view->canvas));
3192 /*---------------------------------------------------------------------------*/
3193 /* PRIVATE. Leave notify event handler. */
3194 /*---------------------------------------------------------------------------*/
3196 leave_notify_event_cb (glView *view,
3197 GdkEventCrossing *event)
3200 g_signal_emit (G_OBJECT(view), signals[POINTER_EXIT], 0);
3205 /*---------------------------------------------------------------------------*/
3206 /* PRIVATE. Motion notify event handler. */
3207 /*---------------------------------------------------------------------------*/
3209 motion_notify_event_cb (glView *view,
3210 GdkEventMotion *event)
3212 gboolean return_value = FALSE;
3217 glViewObjectHandle handle;
3219 cr = gdk_cairo_create (GTK_LAYOUT (view->canvas)->bin_window);
3222 * Translate to label coordinates
3224 scale = view->zoom * view->home_scale;
3225 cairo_scale (cr, scale, scale);
3226 cairo_translate (cr, view->x0, view->y0);
3230 cairo_device_to_user (cr, &x, &y);
3233 * Emit signal regardless of mode
3235 g_signal_emit (G_OBJECT(view), signals[POINTER_MOVED], 0, x, y);
3238 * Handle event as appropriate for mode
3243 case GL_VIEW_MODE_ARROW:
3244 switch (view->state)
3248 if (view_handle_at (view, cr, event->x, event->y, &handle))
3250 cursor = gdk_cursor_new (GDK_CROSSHAIR);
3252 else if (view_view_object_at (view, cr, event->x, event->y))
3254 cursor = gdk_cursor_new (GDK_FLEUR);
3258 cursor = gdk_cursor_new (GDK_LEFT_PTR);
3260 gdk_window_set_cursor (view->canvas->window, cursor);
3261 gdk_cursor_unref (cursor);
3264 case GL_VIEW_ARROW_SELECT_REGION:
3266 gl_view_update_region (view, cr, &view->select_region);
3268 view->select_region.x2 = x;
3269 view->select_region.y2 = y;
3271 gl_view_update_region (view, cr, &view->select_region);
3273 gl_view_update (view);
3277 case GL_VIEW_ARROW_MOVE:
3278 gl_view_move_selection (view,
3279 (x - view->move_last_x),
3280 (y - view->move_last_y));
3281 view->move_last_x = x;
3282 view->move_last_y = y;
3285 case GL_VIEW_ARROW_RESIZE:
3286 gl_view_object_resize_event (view->resize_object,
3287 view->resize_handle,
3288 view->resize_honor_aspect,
3295 g_message ("Invalid arrow state."); /*Should not happen!*/
3297 return_value = TRUE;
3301 case GL_VIEW_MODE_OBJECT_CREATE:
3302 if (view->state != GL_VIEW_IDLE)
3304 switch (view->create_type)
3306 case GL_LABEL_OBJECT_BOX:
3307 gl_view_box_create_motion_event (view, x, y);
3309 case GL_LABEL_OBJECT_ELLIPSE:
3310 gl_view_ellipse_create_motion_event (view, x, y);
3312 case GL_LABEL_OBJECT_LINE:
3313 gl_view_line_create_motion_event (view, x, y);
3315 case GL_LABEL_OBJECT_IMAGE:
3316 gl_view_image_create_motion_event (view, x, y);
3318 case GL_LABEL_OBJECT_TEXT:
3319 gl_view_text_create_motion_event (view, x, y);
3321 case GL_LABEL_OBJECT_BARCODE:
3322 gl_view_barcode_create_motion_event (view, x, y);
3325 g_message ("Invalid create type."); /*Should not happen!*/
3332 g_message ("Invalid view mode."); /*Should not happen!*/
3339 * FIXME: we re-establish grabs here if the grab has been lost. We seem to be
3340 * losing grabs when we emit signals that lead to the manipulation of
3341 * the GtkUIManager. Needs more investigation
3343 if (view->grabbed_flag && !gdk_pointer_is_grabbed ())
3345 gdk_pointer_grab (GTK_LAYOUT (view->canvas)->bin_window,
3347 (GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK),
3353 return return_value;
3356 /*---------------------------------------------------------------------------*/
3357 /* PRIVATE. Button press event handler. */
3358 /*---------------------------------------------------------------------------*/
3360 button_press_event_cb (glView *view,
3361 GdkEventButton *event)
3363 gboolean return_value = FALSE;
3367 glViewObject *view_object;
3368 glViewObjectHandle handle;
3370 cr = gdk_cairo_create (GTK_LAYOUT (view->canvas)->bin_window);
3373 * Translate to label coordinates
3375 scale = view->zoom * view->home_scale;
3376 cairo_scale (cr, scale, scale);
3377 cairo_translate (cr, view->x0, view->y0);
3381 cairo_device_to_user (cr, &x, &y);
3383 switch (event->button)
3388 * Handle event as appropriate for mode
3392 case GL_VIEW_MODE_ARROW:
3393 if ((view_object = view_handle_at (view, cr, event->x, event->y, &handle)))
3395 view->resize_object = view_object;
3396 view->resize_handle = handle;
3397 view->resize_honor_aspect = event->state & GDK_CONTROL_MASK;
3399 view->state = GL_VIEW_ARROW_RESIZE;
3401 else if ((view_object = view_view_object_at (view, cr, event->x, event->y)))
3403 if (event->state & GDK_CONTROL_MASK)
3405 if (gl_view_is_object_selected (view, view_object))
3407 /* Un-selecting a selected item */
3408 gl_view_unselect_object (view, view_object);
3410 /* Add to current selection */
3411 gl_view_select_object (view, view_object);
3416 if (!gl_view_is_object_selected (view, view_object))
3418 /* remove any selections before adding */
3419 gl_view_unselect_all (view);
3420 /* Add to current selection */
3421 gl_view_select_object (view, view_object);
3424 view->move_last_x = x;
3425 view->move_last_y = y;
3427 view->state = GL_VIEW_ARROW_MOVE;
3431 if (!(event->state & GDK_CONTROL_MASK))
3433 gl_view_unselect_all (view);
3436 view->select_region_visible = TRUE;
3437 view->select_region.x1 = x;
3438 view->select_region.y1 = y;
3439 view->select_region.x2 = x;
3440 view->select_region.y2 = y;
3442 view->state = GL_VIEW_ARROW_SELECT_REGION;
3446 return_value = TRUE;
3449 case GL_VIEW_MODE_OBJECT_CREATE:
3450 switch (view->create_type)
3452 case GL_LABEL_OBJECT_BOX:
3453 gl_view_box_create_button_press_event (view, x, y);
3455 case GL_LABEL_OBJECT_ELLIPSE:
3456 gl_view_ellipse_create_button_press_event (view, x, y);
3458 case GL_LABEL_OBJECT_LINE:
3459 gl_view_line_create_button_press_event (view, x, y);
3461 case GL_LABEL_OBJECT_IMAGE:
3462 gl_view_image_create_button_press_event (view, x, y);
3464 case GL_LABEL_OBJECT_TEXT:
3465 gl_view_text_create_button_press_event (view, x, y);
3467 case GL_LABEL_OBJECT_BARCODE:
3468 gl_view_barcode_create_button_press_event (view, x, y);
3471 g_message ("Invalid create type."); /*Should not happen!*/
3473 view->state = GL_VIEW_CREATE_DRAG;
3474 return_value = TRUE;
3478 g_message ("Invalid view mode."); /*Should not happen!*/
3481 view->grabbed_flag = TRUE;
3482 gdk_pointer_grab (GTK_LAYOUT (view->canvas)->bin_window,
3484 (GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK),
3491 g_signal_emit (G_OBJECT (view),
3492 signals[CONTEXT_MENU_ACTIVATE], 0,
3493 event->button, event->time);
3494 return_value = TRUE;
3501 return return_value;
3504 /*---------------------------------------------------------------------------*/
3505 /* PRIVATE. Button release event handler. */
3506 /*---------------------------------------------------------------------------*/
3508 button_release_event_cb (glView *view,
3509 GdkEventButton *event)
3511 gboolean return_value = FALSE;
3517 cr = gdk_cairo_create (GTK_LAYOUT (view->canvas)->bin_window);
3520 * Translate to label coordinates
3522 scale = view->zoom * view->home_scale;
3523 cairo_scale (cr, scale, scale);
3524 cairo_translate (cr, view->x0, view->y0);
3528 cairo_device_to_user (cr, &x, &y);
3530 switch (event->button)
3534 view->grabbed_flag = FALSE;
3535 gdk_pointer_ungrab (event->time);
3537 * Handle event as appropriate for mode
3541 case GL_VIEW_MODE_ARROW:
3542 switch (view->state)
3544 case GL_VIEW_ARROW_RESIZE:
3545 view->resize_object = NULL;
3547 view->state = GL_VIEW_IDLE;
3550 case GL_VIEW_ARROW_SELECT_REGION:
3552 gl_view_update_region (view, cr, &view->select_region);
3554 gl_view_update (view);
3557 view->select_region_visible = FALSE;
3558 view->select_region.x2 = x;
3559 view->select_region.y2 = y;
3561 gl_view_select_region (view, &view->select_region);
3563 view->state = GL_VIEW_IDLE;
3567 view->state = GL_VIEW_IDLE;
3572 return_value = TRUE;
3576 case GL_VIEW_MODE_OBJECT_CREATE:
3577 switch (view->create_type)
3579 case GL_LABEL_OBJECT_BOX:
3580 gl_view_box_create_button_release_event (view, x, y);
3582 case GL_LABEL_OBJECT_ELLIPSE:
3583 gl_view_ellipse_create_button_release_event (view, x, y);
3585 case GL_LABEL_OBJECT_LINE:
3586 gl_view_line_create_button_release_event (view, x, y);
3588 case GL_LABEL_OBJECT_IMAGE:
3589 gl_view_image_create_button_release_event (view, x, y);
3591 case GL_LABEL_OBJECT_TEXT:
3592 gl_view_text_create_button_release_event (view, x, y);
3594 case GL_LABEL_OBJECT_BARCODE:
3595 gl_view_barcode_create_button_release_event (view, x, y);
3598 g_message ("Invalid create type."); /*Should not happen!*/
3600 view->mode = GL_VIEW_MODE_ARROW;
3601 view->state = GL_VIEW_IDLE;
3602 cursor = gdk_cursor_new (GDK_LEFT_PTR);
3603 gdk_window_set_cursor (view->canvas->window, cursor);
3604 gdk_cursor_unref (cursor);
3609 g_message ("Invalid view mode."); /*Should not happen!*/
3616 return return_value;
3619 /*---------------------------------------------------------------------------*/
3620 /* PRIVATE. Key press event handler. */
3621 /*---------------------------------------------------------------------------*/
3623 key_press_event_cb (glView *view,
3628 gl_debug (DEBUG_VIEW, "");
3630 if ( (view->mode == GL_VIEW_MODE_ARROW) &&
3631 (view->state == GL_VIEW_IDLE) )
3633 switch (event->keyval) {
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_move_selection (view, 1.0 / (view->zoom), 0.0);
3649 gl_view_move_selection (view, 0.0, 1.0 / (view->zoom));
3653 gl_view_delete_selection (view);
3654 cursor = gdk_cursor_new (GDK_LEFT_PTR);
3655 gdk_window_set_cursor (GTK_WIDGET (view->canvas)->window
3657 gdk_cursor_unref (cursor);
3664 return TRUE; /* We handled this or we were dragging. */