3 * Copyright (C) 2001-2009 Jim Evins <evins@snaught.com>.
5 * This file is part of gLabels.
7 * gLabels is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * gLabels is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
25 #include <glib/gi18n.h>
27 #include <gdk/gdkkeysyms.h>
32 #include "cairo-label-path.h"
33 #include "cairo-markup-path.h"
34 #include "view-object.h"
36 #include "view-ellipse.h"
37 #include "view-line.h"
38 #include "view-image.h"
39 #include "view-text.h"
40 #include "view-barcode.h"
41 #include "xml-label.h"
49 /*==========================================================================*/
50 /* Private macros and constants. */
51 /*==========================================================================*/
53 #define BG_COLOR GL_COLOR (192, 192, 192)
55 #define PAPER_RGB_ARGS 1.0, 1.0, 1.0
56 #define GRID_RGB_ARGS 0.753, 0.753, 0.753
57 #define MARKUP_RGB_ARGS 0.94, 0.39, 0.39
58 #define OUTLINE_RGB_ARGS 0.68, 0.85, 0.90
59 #define SELECT_LINE_RGBA_ARGS 0.0, 0.0, 1.0, 0.5
60 #define SELECT_FILL_RGBA_ARGS 0.75, 0.75, 1.0, 0.5
62 #define GRID_LINE_WIDTH_PIXELS 1.0
63 #define MARKUP_LINE_WIDTH_PIXELS 1.0
64 #define OUTLINE_WIDTH_PIXELS 3.0
65 #define SELECT_LINE_WIDTH_PIXELS 3.0
67 #define ZOOMTOFIT_PAD 16
69 #define POINTS_PER_MM 2.83464566929
72 /*==========================================================================*/
74 /*==========================================================================*/
78 CONTEXT_MENU_ACTIVATE,
87 /*==========================================================================*/
89 /*==========================================================================*/
91 static guint signals[LAST_SIGNAL] = {0};
93 /* "CLIPBOARD" selection */
94 static GdkAtom clipboard_atom = GDK_NONE;
96 static gdouble zooms[] = {
113 #define N_ZOOMS G_N_ELEMENTS(zooms)
116 /*==========================================================================*/
117 /* Local function prototypes */
118 /*==========================================================================*/
120 static void gl_view_finalize (GObject *object);
122 static void gl_view_construct (glView *view,
125 static gdouble get_home_scale (glView *view);
127 static gboolean expose_cb (glView *view,
128 GdkEventExpose *event);
130 static void realize_cb (glView *view);
132 static void size_allocate_cb (glView *view,
133 GtkAllocation *allocation);
135 static void screen_changed_cb (glView *view);
137 static void label_changed_cb (glView *view);
139 static void label_resized_cb (glView *view);
141 static void label_object_added_cb (glView *view,
142 glLabelObject *object);
144 static void draw_layers (glView *view,
147 static void draw_bg_layer (glView *view,
149 static void draw_grid_layer (glView *view,
151 static void draw_markup_layer (glView *view,
153 static void draw_objects_layer (glView *view,
155 static void draw_fg_layer (glView *view,
157 static void draw_highlight_layer (glView *view,
159 static void draw_select_region_layer (glView *view,
162 static void select_object_real (glView *view,
163 glViewObject *view_object);
164 static void unselect_object_real (glView *view,
165 glViewObject *view_object);
167 static glViewObject *view_view_object_at (glView *view,
172 static void set_zoom_real (glView *view,
174 gboolean scale_to_fit_flag);
176 static void selection_clear_cb (GtkWidget *widget,
177 GdkEventSelection *event,
180 static void selection_get_cb (GtkWidget *widget,
181 GtkSelectionData *selection_data,
186 static void selection_received_cb (GtkWidget *widget,
187 GtkSelectionData *selection_data,
191 static gboolean focus_in_event_cb (glView *view,
192 GdkEventFocus *event);
194 static gboolean focus_out_event_cb (glView *view,
195 GdkEventFocus *event);
197 static gboolean enter_notify_event_cb (glView *view,
198 GdkEventCrossing *event);
200 static gboolean leave_notify_event_cb (glView *view,
201 GdkEventCrossing *event);
203 static gboolean motion_notify_event_cb (glView *view,
204 GdkEventMotion *event);
206 static gboolean button_press_event_cb (glView *view,
207 GdkEventButton *event);
209 static gboolean button_release_event_cb (glView *view,
210 GdkEventButton *event);
212 static gboolean key_press_event_cb (glView *view,
216 /****************************************************************************/
217 /* Boilerplate Object stuff. */
218 /****************************************************************************/
219 G_DEFINE_TYPE (glView, gl_view, GTK_TYPE_VBOX);
223 gl_view_class_init (glViewClass *class)
225 GObjectClass *object_class = G_OBJECT_CLASS (class);
227 gl_debug (DEBUG_VIEW, "START");
229 gl_view_parent_class = g_type_class_peek_parent (class);
231 object_class->finalize = gl_view_finalize;
233 signals[SELECTION_CHANGED] =
234 g_signal_new ("selection_changed",
235 G_OBJECT_CLASS_TYPE (object_class),
237 G_STRUCT_OFFSET (glViewClass, selection_changed),
239 gl_marshal_VOID__VOID,
243 signals[CONTEXT_MENU_ACTIVATE] =
244 g_signal_new ("context_menu_activate",
245 G_OBJECT_CLASS_TYPE (object_class),
247 G_STRUCT_OFFSET (glViewClass, context_menu_activate),
249 gl_marshal_VOID__INT_UINT,
251 2, G_TYPE_INT, G_TYPE_UINT);
253 signals[ZOOM_CHANGED] =
254 g_signal_new ("zoom_changed",
255 G_OBJECT_CLASS_TYPE (object_class),
257 G_STRUCT_OFFSET (glViewClass, zoom_changed),
259 gl_marshal_VOID__DOUBLE,
263 signals[POINTER_MOVED] =
264 g_signal_new ("pointer_moved",
265 G_OBJECT_CLASS_TYPE (object_class),
267 G_STRUCT_OFFSET (glViewClass, pointer_moved),
269 gl_marshal_VOID__DOUBLE_DOUBLE,
271 2, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
273 signals[POINTER_EXIT] =
274 g_signal_new ("pointer_exit",
275 G_OBJECT_CLASS_TYPE (object_class),
277 G_STRUCT_OFFSET (glViewClass, pointer_exit),
279 gl_marshal_VOID__VOID,
283 signals[MODE_CHANGED] =
284 g_signal_new ("mode_changed",
285 G_OBJECT_CLASS_TYPE (object_class),
287 G_STRUCT_OFFSET (glViewClass, mode_changed),
289 gl_marshal_VOID__VOID,
293 gl_debug (DEBUG_VIEW, "END");
298 gl_view_init (glView *view)
303 gl_debug (DEBUG_VIEW, "START");
306 view->grid_visible = TRUE;
307 view->grid_spacing = 9;
308 view->markup_visible = TRUE;
309 view->default_font_family = NULL;
310 view->mode = GL_VIEW_MODE_ARROW;
311 view->object_list = NULL;
312 view->selected_object_list = NULL;
314 view->home_scale = get_home_scale (view);
319 view->canvas = gtk_layout_new (NULL, NULL);
320 wscroll = gtk_scrolled_window_new (NULL, NULL);
321 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (wscroll),
322 GTK_POLICY_AUTOMATIC,
323 GTK_POLICY_AUTOMATIC);
324 gtk_box_pack_start (GTK_BOX (view), wscroll, TRUE, TRUE, 0);
325 gtk_container_add (GTK_CONTAINER (wscroll), view->canvas);
327 bg_color = gl_color_to_gdk_color (BG_COLOR);
328 gtk_widget_modify_bg (GTK_WIDGET (view->canvas), GTK_STATE_NORMAL, bg_color);
331 gtk_widget_set_can_focus (GTK_WIDGET (view->canvas), TRUE);
333 gtk_widget_add_events (GTK_WIDGET (view->canvas),
334 (GDK_FOCUS_CHANGE_MASK |
335 GDK_ENTER_NOTIFY_MASK |
336 GDK_LEAVE_NOTIFY_MASK |
337 GDK_POINTER_MOTION_MASK |
338 GDK_BUTTON_PRESS_MASK |
339 GDK_BUTTON_RELEASE_MASK |
340 GDK_KEY_PRESS_MASK));
342 g_signal_connect_swapped (G_OBJECT (view->canvas), "expose-event",
343 G_CALLBACK (expose_cb), view);
344 g_signal_connect_swapped (G_OBJECT (view->canvas), "realize",
345 G_CALLBACK (realize_cb), view);
346 g_signal_connect_swapped (G_OBJECT (view->canvas), "size-allocate",
347 G_CALLBACK (size_allocate_cb), view);
348 g_signal_connect_swapped (G_OBJECT (view->canvas), "screen-changed",
349 G_CALLBACK (screen_changed_cb), view);
350 g_signal_connect_swapped (G_OBJECT (view->canvas), "focus-in-event",
351 G_CALLBACK (focus_in_event_cb), view);
352 g_signal_connect_swapped (G_OBJECT (view->canvas), "focus-out-event",
353 G_CALLBACK (focus_out_event_cb), view);
354 g_signal_connect_swapped (G_OBJECT (view->canvas), "enter-notify-event",
355 G_CALLBACK (enter_notify_event_cb), view);
356 g_signal_connect_swapped (G_OBJECT (view->canvas), "leave-notify-event",
357 G_CALLBACK (leave_notify_event_cb), view);
358 g_signal_connect_swapped (G_OBJECT (view->canvas), "motion-notify-event",
359 G_CALLBACK (motion_notify_event_cb), view);
360 g_signal_connect_swapped (G_OBJECT (view->canvas), "button-press-event",
361 G_CALLBACK (button_press_event_cb), view);
362 g_signal_connect_swapped (G_OBJECT (view->canvas), "button-release-event",
363 G_CALLBACK (button_release_event_cb), view);
364 g_signal_connect_swapped (G_OBJECT (view->canvas), "key-press-event",
365 G_CALLBACK (key_press_event_cb), view);
370 view->have_selection = FALSE;
371 view->selection_data = NULL;
372 view->invisible = gtk_invisible_new ();
373 if (!clipboard_atom) {
374 clipboard_atom = gdk_atom_intern ("GLABELS_CLIPBOARD", FALSE);
376 gtk_selection_add_target (view->invisible,
377 clipboard_atom, GDK_SELECTION_TYPE_STRING, 1);
378 g_signal_connect (G_OBJECT (view->invisible),
379 "selection_clear_event",
380 G_CALLBACK (selection_clear_cb), view);
381 g_signal_connect (G_OBJECT (view->invisible), "selection_get",
382 G_CALLBACK (selection_get_cb), view);
383 g_signal_connect (G_OBJECT (view->invisible),
384 "selection_received",
385 G_CALLBACK (selection_received_cb), view);
388 * Defaults from preferences
390 gl_view_set_default_font_family (view, gl_prefs_model_get_default_font_family (gl_prefs));
391 gl_view_set_default_font_size (view, gl_prefs_model_get_default_font_size (gl_prefs));
392 gl_view_set_default_font_weight (view, gl_prefs_model_get_default_font_weight (gl_prefs));
393 gl_view_set_default_font_italic_flag (view, gl_prefs_model_get_default_font_italic_flag (gl_prefs));
394 gl_view_set_default_text_color (view, gl_prefs_model_get_default_text_color (gl_prefs));
395 gl_view_set_default_text_alignment (view, gl_prefs_model_get_default_text_alignment (gl_prefs));
396 gl_view_set_default_text_line_spacing (view, gl_prefs_model_get_default_text_line_spacing (gl_prefs));
397 gl_view_set_default_line_width (view, gl_prefs_model_get_default_line_width (gl_prefs));
398 gl_view_set_default_line_color (view, gl_prefs_model_get_default_line_color (gl_prefs));
399 gl_view_set_default_fill_color (view, gl_prefs_model_get_default_fill_color (gl_prefs));
401 gl_debug (DEBUG_VIEW, "END");
406 gl_view_finalize (GObject *object)
408 glView *view = GL_VIEW (object);
410 gl_debug (DEBUG_VIEW, "START");
412 g_return_if_fail (object != NULL);
413 g_return_if_fail (GL_IS_VIEW (object));
415 if (view->default_font_family) {
416 g_free (view->default_font_family);
419 G_OBJECT_CLASS (gl_view_parent_class)->finalize (object);
421 gl_debug (DEBUG_VIEW, "END");
425 /****************************************************************************/
426 /* NEW view object. */
427 /****************************************************************************/
429 gl_view_new (glLabel *label)
433 gl_debug (DEBUG_VIEW, "START");
435 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
437 view = g_object_new (GL_TYPE_VIEW, NULL);
439 gl_view_construct (view, label);
441 gl_debug (DEBUG_VIEW, "END");
443 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");
496 /*---------------------------------------------------------------------------*/
497 /* PRIAVTE. Calculate 1:1 scale for screen. */
498 /*---------------------------------------------------------------------------*/
500 get_home_scale (glView *view)
503 gdouble screen_width_pixels;
504 gdouble screen_width_mm;
505 gdouble screen_height_pixels;
506 gdouble screen_height_mm;
507 gdouble x_pixels_per_mm;
508 gdouble y_pixels_per_mm;
511 if (view->canvas == NULL) return 1.0;
513 if (!gtk_widget_has_screen (GTK_WIDGET (view->canvas))) return 1.0;
515 screen = gtk_widget_get_screen (GTK_WIDGET (view->canvas));
517 gl_debug (DEBUG_VIEW, "Screen = %p", screen);
519 screen_width_pixels = gdk_screen_get_width (screen);
520 screen_width_mm = gdk_screen_get_width_mm (screen);
521 screen_height_pixels = gdk_screen_get_height (screen);
522 screen_height_mm = gdk_screen_get_height_mm (screen);
524 x_pixels_per_mm = screen_width_pixels / screen_width_mm;
525 y_pixels_per_mm = screen_height_pixels / screen_height_mm;
527 gl_debug (DEBUG_VIEW, "Horizontal dot pitch: %g pixels/mm (%g dpi)",
528 x_pixels_per_mm, x_pixels_per_mm * 25.4);
529 gl_debug (DEBUG_VIEW, "Vertical dot pitch: %g pixels/mm (%g dpi)",
530 y_pixels_per_mm, y_pixels_per_mm * 25.4);
532 scale = (x_pixels_per_mm + y_pixels_per_mm) / 2.0;
534 gl_debug (DEBUG_VIEW, "Average dot pitch: %g pixels/mm (%g dpi)",
535 scale, scale * 25.4);
537 scale /= POINTS_PER_MM;
539 gl_debug (DEBUG_VIEW, "Scale = %g pixels/point", scale);
541 /* Make sure scale is somewhat sane. */
542 if ( (scale < 0.25) || (scale > 4.0) ) return 1.0;
548 /*---------------------------------------------------------------------------*/
549 /* Schedule canvas update. */
550 /*---------------------------------------------------------------------------*/
552 gl_view_update (glView *view)
557 gl_debug (DEBUG_VIEW, "START");
559 window = gtk_widget_get_window (GTK_WIDGET (view->canvas));
563 if ( !view->update_scheduled_flag )
565 view->update_scheduled_flag = TRUE;
567 region = gdk_drawable_get_clip_region (window);
568 /* redraw the cairo canvas completely by exposing it */
569 gdk_window_invalidate_region (window, region, TRUE);
570 gdk_region_destroy (region);
573 gl_debug (DEBUG_VIEW, "END");
577 /*---------------------------------------------------------------------------*/
578 /* Schedule canvas region update. */
579 /*---------------------------------------------------------------------------*/
581 gl_view_update_region (glView *view,
583 glLabelRegion *region)
589 gl_debug (DEBUG_VIEW, "START");
591 window = gtk_widget_get_window (GTK_WIDGET (view->canvas));
595 x = MIN (region->x1, region->x2);
596 y = MIN (region->y1, region->y2);
597 w = fabs (region->x2 - region->x1);
598 h = fabs (region->y2 - region->y1);
600 cairo_user_to_device (cr, &x, &y);
601 cairo_user_to_device_distance (cr, &w, &h);
608 gdk_window_invalidate_rect (window, &rect, TRUE);
610 gl_debug (DEBUG_VIEW, "END");
614 /*---------------------------------------------------------------------------*/
615 /* PRIVATE. Expose handler. */
616 /*---------------------------------------------------------------------------*/
618 expose_cb (glView *view,
619 GdkEventExpose *event)
621 GdkWindow *bin_window;
624 gl_debug (DEBUG_VIEW, "START");
626 view->update_scheduled_flag = FALSE;
628 bin_window = gtk_layout_get_bin_window (GTK_LAYOUT (view->canvas));
629 cr = gdk_cairo_create (bin_window);
632 event->area.x, event->area.y,
633 event->area.width, event->area.height);
636 draw_layers (view, cr);
640 gl_debug (DEBUG_VIEW, "END");
646 /*---------------------------------------------------------------------------*/
647 /* PRIVATE. Realize handler. */
648 /*---------------------------------------------------------------------------*/
650 realize_cb (glView *view)
652 g_return_if_fail (view && GL_IS_VIEW (view));
654 gl_debug (DEBUG_VIEW, "START");
656 gl_debug (DEBUG_VIEW, "END");
660 /*---------------------------------------------------------------------------*/
661 /* PRIVATE. Size allocation changed callback. */
662 /*---------------------------------------------------------------------------*/
664 size_allocate_cb (glView *view,
665 GtkAllocation *allocation)
667 GtkAdjustment *hadjustment;
668 GtkAdjustment *vadjustment;
670 gl_debug (DEBUG_VIEW, "START");
672 hadjustment = gtk_layout_get_hadjustment(GTK_LAYOUT (view->canvas));
673 vadjustment = gtk_layout_get_vadjustment(GTK_LAYOUT (view->canvas));
675 gtk_adjustment_set_page_size( hadjustment, allocation->width);
676 gtk_adjustment_set_page_increment( hadjustment, allocation->width / 2);
678 gtk_adjustment_set_page_size( vadjustment, allocation->height);
679 gtk_adjustment_set_page_increment( vadjustment, allocation->height / 2);
681 g_signal_emit_by_name (hadjustment, "changed");
682 g_signal_emit_by_name (vadjustment, "changed");
684 if (view->zoom_to_fit_flag) {
685 /* Maintain best fit zoom */
686 gl_view_zoom_to_fit (view);
689 gl_debug (DEBUG_VIEW, "END");
693 /*---------------------------------------------------------------------------*/
694 /* PRIVATE. Screen changed callback. */
695 /*---------------------------------------------------------------------------*/
697 screen_changed_cb (glView *view)
699 gl_debug (DEBUG_VIEW, "START");
701 if (gtk_widget_has_screen (GTK_WIDGET (view->canvas))) {
703 view->home_scale = get_home_scale (view);
705 if (view->zoom_to_fit_flag) {
706 /* Maintain best fit zoom */
707 gl_view_zoom_to_fit (view);
711 gl_debug (DEBUG_VIEW, "END");
715 /*---------------------------------------------------------------------------*/
716 /* PRIVATE. Handle label changed event. */
717 /*---------------------------------------------------------------------------*/
719 label_changed_cb (glView *view)
721 g_return_if_fail (view && GL_IS_VIEW (view));
723 gl_debug (DEBUG_VIEW, "START");
725 gl_view_update (view);
727 gl_debug (DEBUG_VIEW, "END");
731 /*---------------------------------------------------------------------------*/
732 /* PRIVATE. Handle label resize event. */
733 /*---------------------------------------------------------------------------*/
735 label_resized_cb (glView *view)
737 GtkAdjustment *hadjustment;
738 GtkAdjustment *vadjustment;
740 g_return_if_fail (view && GL_IS_VIEW (view));
742 gl_debug (DEBUG_VIEW, "START");
744 hadjustment = gtk_layout_get_hadjustment(GTK_LAYOUT (view->canvas));
745 vadjustment = gtk_layout_get_vadjustment(GTK_LAYOUT (view->canvas));
747 g_signal_emit_by_name (hadjustment, "changed");
748 g_signal_emit_by_name (vadjustment, "changed");
750 gl_view_update (view);
752 gl_debug (DEBUG_VIEW, "END");
756 /*---------------------------------------------------------------------------*/
757 /* PRIVATE. Handle new label object. */
758 /*---------------------------------------------------------------------------*/
760 label_object_added_cb (glView *view,
761 glLabelObject *object)
763 glViewObject *view_object;
765 g_return_if_fail (view && GL_IS_VIEW (view));
766 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
768 if (GL_IS_LABEL_BOX (object)) {
769 view_object = gl_view_box_new (GL_LABEL_BOX(object), view);
770 } else if (GL_IS_LABEL_ELLIPSE (object)) {
771 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object), view);
772 } else if (GL_IS_LABEL_LINE (object)) {
773 view_object = gl_view_line_new (GL_LABEL_LINE(object), view);
774 } else if (GL_IS_LABEL_IMAGE (object)) {
775 view_object = gl_view_image_new (GL_LABEL_IMAGE(object), view);
776 } else if (GL_IS_LABEL_TEXT (object)) {
777 view_object = gl_view_text_new (GL_LABEL_TEXT(object), view);
778 } else if (GL_IS_LABEL_BARCODE (object)) {
779 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(object), view);
781 /* Should not happen! */
783 g_message ("Invalid label object type.");
786 gl_view_select_object (view, view_object);
790 /*---------------------------------------------------------------------------*/
791 /* PRIVATE. Create, draw and order layers. */
792 /*---------------------------------------------------------------------------*/
794 draw_layers (glView *view,
797 GdkWindow *bin_window;
800 gint canvas_w, canvas_h;
802 g_return_if_fail (view && GL_IS_VIEW (view));
803 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
805 gl_debug (DEBUG_VIEW, "START");
807 bin_window = gtk_layout_get_bin_window (GTK_LAYOUT (view->canvas));
809 scale = view->zoom * view->home_scale;
811 gl_label_get_size (view->label, &w, &h);
813 scale = view->home_scale * view->zoom;
814 gtk_layout_set_size (GTK_LAYOUT (view->canvas), w*scale+8, h*scale+8);
816 gdk_drawable_get_size (bin_window, &canvas_w, &canvas_h);
818 view->x0 = (canvas_w/scale - w) / 2.0;
819 view->y0 = (canvas_h/scale - h) / 2.0;
825 cairo_scale (cr, scale, scale);
826 cairo_translate (cr, view->x0, view->y0);
828 draw_bg_layer (view, cr);
829 draw_grid_layer (view, cr);
830 draw_markup_layer (view, cr);
831 draw_objects_layer (view, cr);
832 draw_fg_layer (view, cr);
833 draw_highlight_layer (view, cr);
834 draw_select_region_layer (view, cr);
838 gl_debug (DEBUG_VIEW, "END");
843 /*---------------------------------------------------------------------------*/
844 /* PRIVATE. Draw background */
845 /*---------------------------------------------------------------------------*/
847 draw_bg_layer (glView *view,
850 g_return_if_fail (view && GL_IS_VIEW (view));
851 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
853 gl_cairo_label_path (cr, view->label->template, view->label->rotate_flag, FALSE);
855 cairo_set_source_rgb (cr, PAPER_RGB_ARGS);
856 cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
861 /*---------------------------------------------------------------------------*/
862 /* PRIVATE. Draw grid lines. */
863 /*---------------------------------------------------------------------------*/
865 draw_grid_layer (glView *view,
871 const lglTemplateFrame *frame;
873 gl_debug (DEBUG_VIEW, "START");
875 g_return_if_fail (view && GL_IS_VIEW (view));
876 g_return_if_fail (view->label && GL_IS_LABEL(view->label));
878 if (view->grid_visible)
881 frame = (lglTemplateFrame *)view->label->template->frames->data;
883 gl_label_get_size (view->label, &w, &h);
885 if (frame->shape == LGL_TEMPLATE_FRAME_SHAPE_RECT) {
889 /* round labels, adjust grid to line up with center of label. */
890 x0 = fmod (w/2.0, view->grid_spacing);
891 y0 = fmod (h/2.0, view->grid_spacing);
897 cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
898 cairo_set_line_width (cr, GRID_LINE_WIDTH_PIXELS/(view->home_scale * view->zoom));
899 cairo_set_source_rgb (cr, GRID_RGB_ARGS);
901 for ( x=x0+view->grid_spacing; x < w; x += view->grid_spacing )
903 cairo_move_to (cr, x, 0);
904 cairo_line_to (cr, x, h);
908 for ( y=y0+view->grid_spacing; y < h; y += view->grid_spacing )
910 cairo_move_to (cr, 0, y);
911 cairo_line_to (cr, w, y);
919 gl_debug (DEBUG_VIEW, "END");
923 /*---------------------------------------------------------------------------*/
924 /* PRIVATE. Draw markup layer. */
925 /*---------------------------------------------------------------------------*/
927 draw_markup_layer (glView *view,
931 const lglTemplateFrame *frame;
933 lglTemplateMarkup *markup;
934 gdouble width, height;
936 g_return_if_fail (view && GL_IS_VIEW (view));
937 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
939 if (view->markup_visible)
943 frame = (lglTemplateFrame *)view->label->template->frames->data;
947 if (label->rotate_flag)
949 lgl_template_frame_get_size (frame, &width, &height);
950 cairo_rotate (cr, -M_PI/2.0);
951 cairo_translate (cr, -width, 0.0);
954 cairo_set_line_width (cr, MARKUP_LINE_WIDTH_PIXELS/(view->home_scale * view->zoom));
955 cairo_set_source_rgb (cr, MARKUP_RGB_ARGS);
957 for ( p=frame->all.markups; p != NULL; p=p->next )
959 markup = (lglTemplateMarkup *)p->data;
961 gl_cairo_markup_path (cr, markup, label);
972 /*---------------------------------------------------------------------------*/
973 /* PRIVATE. Draw objects layer. */
974 /*---------------------------------------------------------------------------*/
976 draw_objects_layer (glView *view,
979 gl_label_draw (view->label, cr, TRUE, NULL);
983 /*---------------------------------------------------------------------------*/
984 /* PRIVATE. Draw foreground */
985 /*---------------------------------------------------------------------------*/
987 draw_fg_layer (glView *view,
990 g_return_if_fail (view && GL_IS_VIEW (view));
991 g_return_if_fail (view->label && GL_IS_LABEL (view->label));
993 gl_cairo_label_path (cr, view->label->template, view->label->rotate_flag, FALSE);
995 cairo_set_line_width (cr, OUTLINE_WIDTH_PIXELS/(view->home_scale * view->zoom));
996 cairo_set_source_rgb (cr, OUTLINE_RGB_ARGS);
1001 /*---------------------------------------------------------------------------*/
1002 /* PRIVATE. Create highlight layer. */
1003 /*---------------------------------------------------------------------------*/
1005 draw_highlight_layer (glView *view,
1009 glViewObject *view_object;
1011 g_return_if_fail (view && GL_IS_VIEW (view));
1015 cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
1017 for (p_obj = view->selected_object_list; p_obj != NULL; p_obj = p_obj->next)
1019 view_object = GL_VIEW_OBJECT (p_obj->data);
1021 gl_view_object_draw_handles (view_object, cr);
1028 /*---------------------------------------------------------------------------*/
1029 /* PRIVATE. Draw select region layer. */
1030 /*---------------------------------------------------------------------------*/
1032 draw_select_region_layer (glView *view,
1038 g_return_if_fail (view && GL_IS_VIEW (view));
1040 if (view->select_region_visible)
1042 x1 = MIN (view->select_region.x1, view->select_region.x2);
1043 y1 = MIN (view->select_region.y1, view->select_region.y2);
1044 w = fabs (view->select_region.x2 - view->select_region.x1);
1045 h = fabs (view->select_region.y2 - view->select_region.y1);
1049 cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
1051 cairo_rectangle (cr, x1, y1, w, h);
1053 cairo_set_source_rgba (cr, SELECT_FILL_RGBA_ARGS);
1054 cairo_fill_preserve (cr);
1056 cairo_set_line_width (cr, SELECT_LINE_WIDTH_PIXELS/(view->home_scale * view->zoom));
1057 cairo_set_source_rgba (cr, SELECT_LINE_RGBA_ARGS);
1065 /*****************************************************************************/
1067 /*****************************************************************************/
1069 gl_view_show_grid (glView *view)
1071 g_return_if_fail (view && GL_IS_VIEW (view));
1073 view->grid_visible = TRUE;
1074 gl_view_update (view);
1078 /*****************************************************************************/
1080 /*****************************************************************************/
1082 gl_view_hide_grid (glView *view)
1084 g_return_if_fail (view && GL_IS_VIEW (view));
1086 view->grid_visible = FALSE;
1087 gl_view_update (view);
1091 /*****************************************************************************/
1092 /* Set grid spacing. */
1093 /*****************************************************************************/
1095 gl_view_set_grid_spacing (glView *view,
1098 g_return_if_fail (view && GL_IS_VIEW (view));
1100 view->grid_spacing = spacing;
1101 gl_view_update (view);
1105 /*****************************************************************************/
1107 /*****************************************************************************/
1109 gl_view_show_markup (glView *view)
1111 g_return_if_fail (view && GL_IS_VIEW (view));
1113 view->markup_visible = TRUE;
1114 gl_view_update (view);
1118 /*****************************************************************************/
1120 /*****************************************************************************/
1122 gl_view_hide_markup (glView *view)
1124 g_return_if_fail (view && GL_IS_VIEW (view));
1126 view->markup_visible = FALSE;
1127 gl_view_update (view);
1131 /*****************************************************************************/
1132 /* Set arrow mode. */
1133 /*****************************************************************************/
1135 gl_view_arrow_mode (glView *view)
1140 gl_debug (DEBUG_VIEW, "START");
1142 g_return_if_fail (view && GL_IS_VIEW (view));
1144 window = gtk_widget_get_window (view->canvas);
1146 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1147 gdk_window_set_cursor (window, cursor);
1148 gdk_cursor_unref (cursor);
1150 view->mode = GL_VIEW_MODE_ARROW;
1151 view->state = GL_VIEW_IDLE;
1153 gl_debug (DEBUG_VIEW, "END");
1157 /*****************************************************************************/
1158 /* Set create text object mode. */
1159 /*****************************************************************************/
1161 gl_view_object_create_mode (glView *view,
1162 glLabelObjectType type)
1165 GdkCursor *cursor = NULL;
1167 gl_debug (DEBUG_VIEW, "START");
1169 g_return_if_fail (view && GL_IS_VIEW (view));
1171 window = gtk_widget_get_window (view->canvas);
1175 case GL_LABEL_OBJECT_BOX:
1176 cursor = gl_view_box_get_create_cursor ();
1178 case GL_LABEL_OBJECT_ELLIPSE:
1179 cursor = gl_view_ellipse_get_create_cursor ();
1181 case GL_LABEL_OBJECT_LINE:
1182 cursor = gl_view_line_get_create_cursor ();
1184 case GL_LABEL_OBJECT_IMAGE:
1185 cursor = gl_view_image_get_create_cursor ();
1187 case GL_LABEL_OBJECT_TEXT:
1188 cursor = gl_view_text_get_create_cursor ();
1190 case GL_LABEL_OBJECT_BARCODE:
1191 cursor = gl_view_barcode_get_create_cursor ();
1194 g_message ("Invalid label object type.");/*Should not happen!*/
1198 gdk_window_set_cursor (window, cursor);
1199 gdk_cursor_unref (cursor);
1201 view->mode = GL_VIEW_MODE_OBJECT_CREATE;
1202 view->state = GL_VIEW_IDLE;
1203 view->create_type = type;
1205 gl_debug (DEBUG_VIEW, "END");
1209 /*****************************************************************************/
1210 /* Select given object (adding to current selection). */
1211 /*****************************************************************************/
1213 gl_view_select_object (glView *view,
1214 glViewObject *view_object)
1216 gl_debug (DEBUG_VIEW, "START");
1218 g_return_if_fail (view && GL_IS_VIEW (view));
1220 select_object_real (view, view_object);
1222 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1224 gl_debug (DEBUG_VIEW, "END");
1228 /*****************************************************************************/
1229 /* Unselect given object (removing from current selection). */
1230 /*****************************************************************************/
1232 gl_view_unselect_object (glView *view,
1233 glViewObject *view_object)
1235 gl_debug (DEBUG_VIEW, "START");
1237 g_return_if_fail (view && GL_IS_VIEW (view));
1239 unselect_object_real (view, view_object);
1241 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1243 gl_debug (DEBUG_VIEW, "END");
1247 /*****************************************************************************/
1248 /* Select all items. */
1249 /*****************************************************************************/
1251 gl_view_select_all (glView *view)
1255 gl_debug (DEBUG_VIEW, "START");
1257 g_return_if_fail (view && GL_IS_VIEW (view));
1259 /* 1st unselect anything already selected. */
1260 for (p = view->selected_object_list; p != NULL; p = p_next) {
1262 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1265 /* Finally select all objects. */
1266 for (p = view->object_list; p != NULL; p = p->next) {
1267 select_object_real (view, GL_VIEW_OBJECT (p->data));
1270 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1272 gl_debug (DEBUG_VIEW, "END");
1276 /*****************************************************************************/
1277 /* Remove all selections */
1278 /*****************************************************************************/
1280 gl_view_unselect_all (glView *view)
1285 gl_debug (DEBUG_VIEW, "START");
1287 g_return_if_fail (view && GL_IS_VIEW (view));
1289 for (p = view->selected_object_list; p != NULL; p = p_next) {
1291 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1294 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1296 gl_debug (DEBUG_VIEW, "END");
1300 /*****************************************************************************/
1301 /* Select all objects within given rectangular region (adding to selection). */
1302 /*****************************************************************************/
1304 gl_view_select_region (glView *view,
1305 glLabelRegion *region)
1308 glViewObject *view_object;
1309 glLabelObject *object;
1312 glLabelRegion obj_extent;
1314 gl_debug (DEBUG_VIEW, "START");
1316 g_return_if_fail (view && GL_IS_VIEW (view));
1318 r_x1 = MIN (region->x1, region->x2);
1319 r_y1 = MIN (region->y1, region->y2);
1320 r_x2 = MAX (region->x1, region->x2);
1321 r_y2 = MAX (region->y1, region->y2);
1323 for (p = view->object_list; p != NULL; p = p->next)
1325 view_object = GL_VIEW_OBJECT(p->data);
1326 if (!gl_view_is_object_selected (view, view_object))
1329 object = gl_view_object_get_object (view_object);
1331 gl_label_object_get_extent (object, &obj_extent);
1332 if ((obj_extent.x1 >= r_x1) &&
1333 (obj_extent.x2 <= r_x2) &&
1334 (obj_extent.y1 >= r_y1) &&
1335 (obj_extent.y2 <= r_y2))
1337 select_object_real (view, view_object);
1343 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1345 gl_debug (DEBUG_VIEW, "END");
1349 /*---------------------------------------------------------------------------*/
1350 /* PRIVATE. Select an object. */
1351 /*---------------------------------------------------------------------------*/
1353 select_object_real (glView *view,
1354 glViewObject *view_object)
1356 gl_debug (DEBUG_VIEW, "START");
1358 g_return_if_fail (view && GL_IS_VIEW (view));
1359 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1361 if (!gl_view_is_object_selected (view, view_object)) {
1362 view->selected_object_list =
1363 g_list_append (view->selected_object_list, view_object);
1365 gtk_widget_grab_focus (GTK_WIDGET (view->canvas));
1367 gl_view_update (view);
1369 gl_debug (DEBUG_VIEW, "END");
1373 /*---------------------------------------------------------------------------*/
1374 /* PRIVATE. Un-select object. */
1375 /*---------------------------------------------------------------------------*/
1377 unselect_object_real (glView *view,
1378 glViewObject *view_object)
1380 gl_debug (DEBUG_VIEW, "START");
1382 g_return_if_fail (view && GL_IS_VIEW (view));
1383 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1385 view->selected_object_list =
1386 g_list_remove (view->selected_object_list, view_object);
1388 gl_view_update (view);
1390 gl_debug (DEBUG_VIEW, "END");
1394 /*---------------------------------------------------------------------------*/
1395 /* PRIVATE. Return object at (x,y). */
1396 /*---------------------------------------------------------------------------*/
1397 static glViewObject *
1398 view_view_object_at (glView *view,
1404 glViewObject *view_object;
1406 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
1408 for (p_obj = g_list_last (view->object_list); p_obj != NULL; p_obj = p_obj->prev)
1411 view_object = GL_VIEW_OBJECT (p_obj->data);
1413 if (gl_view_object_at (view_object, cr, x, y))
1424 /*---------------------------------------------------------------------------*/
1425 /* PRIVATE. Return object handle at (x,y). */
1426 /*---------------------------------------------------------------------------*/
1427 static glViewObject *
1428 view_handle_at (glView *view,
1432 glViewObjectHandle *handle)
1435 glViewObject *view_object;
1437 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
1439 for (p_obj = g_list_last (view->selected_object_list); p_obj != NULL; p_obj = p_obj->prev)
1442 view_object = GL_VIEW_OBJECT (p_obj->data);
1444 if ((*handle = gl_view_object_handle_at (view_object, cr, x, y)))
1455 /*****************************************************************************/
1456 /* Is the object in our current selection? */
1457 /*****************************************************************************/
1459 gl_view_is_object_selected (glView *view,
1460 glViewObject *view_object)
1462 gl_debug (DEBUG_VIEW, "");
1464 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1465 g_return_val_if_fail (GL_IS_VIEW_OBJECT (view_object), FALSE);
1467 if (g_list_find (view->selected_object_list, view_object) == NULL) {
1474 /*****************************************************************************/
1475 /* Is our current selection empty? */
1476 /*****************************************************************************/
1478 gl_view_is_selection_empty (glView *view)
1480 gl_debug (DEBUG_VIEW, "");
1482 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1484 if (view->selected_object_list == NULL) {
1492 /*****************************************************************************/
1493 /* Is our current selection atomic? I.e. only one item selected. */
1494 /*****************************************************************************/
1496 gl_view_is_selection_atomic (glView *view)
1498 gl_debug (DEBUG_VIEW, "");
1500 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1502 if (view->selected_object_list == NULL)
1504 if (view->selected_object_list->next == NULL)
1510 /*****************************************************************************/
1511 /* Delete selected objects. (Bypass clipboard) */
1512 /*****************************************************************************/
1514 gl_view_delete_selection (glView *view)
1519 glViewObject *view_object;
1520 glLabelObject *object;
1522 gl_debug (DEBUG_VIEW, "START");
1524 g_return_if_fail (view && GL_IS_VIEW (view));
1526 object_list = view->selected_object_list;
1527 view->selected_object_list = NULL;
1528 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1530 for (p = object_list; p != NULL; p = p_next) {
1532 view_object = GL_VIEW_OBJECT (p->data);
1533 object = gl_view_object_get_object (view_object);
1534 gl_label_object_remove (object);
1537 g_list_free (object_list);
1539 gl_debug (DEBUG_VIEW, "END");
1543 /*****************************************************************************/
1544 /* Get object property editor of first selected object. */
1545 /*****************************************************************************/
1547 gl_view_get_editor (glView *view)
1549 glViewObject *view_object;
1550 GtkWidget *editor = NULL;
1552 gl_debug (DEBUG_VIEW, "START");
1554 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
1556 if (!gl_view_is_selection_empty (view)) {
1558 view_object = GL_VIEW_OBJECT(view->selected_object_list->data);
1559 editor = gl_view_object_get_editor (view_object);
1563 gl_debug (DEBUG_VIEW, "END");
1569 /*****************************************************************************/
1570 /* Raise selected items to top. */
1571 /*****************************************************************************/
1573 gl_view_raise_selection (glView *view)
1576 glViewObject *view_object;
1577 glLabelObject *object;
1579 gl_debug (DEBUG_VIEW, "START");
1581 g_return_if_fail (view && GL_IS_VIEW (view));
1583 for (p = view->selected_object_list; p != NULL; p = p->next) {
1584 view_object = GL_VIEW_OBJECT (p->data);
1585 object = gl_view_object_get_object (view_object);
1586 gl_label_object_raise_to_top (object);
1589 gl_debug (DEBUG_VIEW, "END");
1593 /*****************************************************************************/
1594 /* Lower selected items to bottom. */
1595 /*****************************************************************************/
1597 gl_view_lower_selection (glView *view)
1600 glViewObject *view_object;
1601 glLabelObject *object;
1603 gl_debug (DEBUG_VIEW, "START");
1605 g_return_if_fail (view && GL_IS_VIEW (view));
1607 for (p = view->selected_object_list; p != NULL; p = p->next) {
1608 view_object = GL_VIEW_OBJECT (p->data);
1609 object = gl_view_object_get_object (view_object);
1610 gl_label_object_lower_to_bottom (object);
1613 gl_debug (DEBUG_VIEW, "END");
1617 /*****************************************************************************/
1618 /* Rotate selected objects by given angle. */
1619 /*****************************************************************************/
1621 gl_view_rotate_selection (glView *view,
1625 glViewObject *view_object;
1626 glLabelObject *object;
1628 gl_debug (DEBUG_VIEW, "START");
1630 g_return_if_fail (view && GL_IS_VIEW (view));
1632 for (p = view->selected_object_list; p != NULL; p = p->next) {
1633 view_object = GL_VIEW_OBJECT (p->data);
1634 object = gl_view_object_get_object (view_object);
1635 gl_label_object_rotate (object, theta_degs);
1638 gl_debug (DEBUG_VIEW, "END");
1642 /*****************************************************************************/
1643 /* Rotate selected objects 90 degrees left. */
1644 /*****************************************************************************/
1646 gl_view_rotate_selection_left (glView *view)
1649 glViewObject *view_object;
1650 glLabelObject *object;
1652 gl_debug (DEBUG_VIEW, "START");
1654 g_return_if_fail (view && GL_IS_VIEW (view));
1656 for (p = view->selected_object_list; p != NULL; p = p->next) {
1657 view_object = GL_VIEW_OBJECT (p->data);
1658 object = gl_view_object_get_object (view_object);
1659 gl_label_object_rotate (object, -90.0);
1662 gl_debug (DEBUG_VIEW, "END");
1666 /*****************************************************************************/
1667 /* Rotate selected objects 90 degrees right. */
1668 /*****************************************************************************/
1670 gl_view_rotate_selection_right (glView *view)
1673 glViewObject *view_object;
1674 glLabelObject *object;
1676 gl_debug (DEBUG_VIEW, "START");
1678 g_return_if_fail (view && GL_IS_VIEW (view));
1680 for (p = view->selected_object_list; p != NULL; p = p->next) {
1681 view_object = GL_VIEW_OBJECT (p->data);
1682 object = gl_view_object_get_object (view_object);
1683 gl_label_object_rotate (object, 90.0);
1686 gl_debug (DEBUG_VIEW, "END");
1690 /*****************************************************************************/
1691 /* Flip selected objects horizontally. */
1692 /*****************************************************************************/
1694 gl_view_flip_selection_horiz (glView *view)
1697 glViewObject *view_object;
1698 glLabelObject *object;
1700 gl_debug (DEBUG_VIEW, "START");
1702 g_return_if_fail (view && GL_IS_VIEW (view));
1704 for (p = view->selected_object_list; p != NULL; p = p->next) {
1705 view_object = GL_VIEW_OBJECT (p->data);
1706 object = gl_view_object_get_object (view_object);
1707 gl_label_object_flip_horiz (object);
1710 gl_debug (DEBUG_VIEW, "END");
1714 /*****************************************************************************/
1715 /* Flip selected objects vertically. */
1716 /*****************************************************************************/
1718 gl_view_flip_selection_vert (glView *view)
1721 glViewObject *view_object;
1722 glLabelObject *object;
1724 gl_debug (DEBUG_VIEW, "START");
1726 g_return_if_fail (view && GL_IS_VIEW (view));
1728 for (p = view->selected_object_list; p != NULL; p = p->next) {
1729 view_object = GL_VIEW_OBJECT (p->data);
1730 object = gl_view_object_get_object (view_object);
1731 gl_label_object_flip_vert (object);
1734 gl_debug (DEBUG_VIEW, "END");
1738 /*****************************************************************************/
1739 /* Align selected objects to left most edge. */
1740 /*****************************************************************************/
1742 gl_view_align_selection_left (glView *view)
1745 glViewObject *view_object;
1746 glLabelObject *object;
1748 glLabelRegion obj_extent;
1750 gl_debug (DEBUG_VIEW, "START");
1752 g_return_if_fail (view && GL_IS_VIEW (view));
1754 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1755 !gl_view_is_selection_atomic (view));
1757 /* find left most edge */
1758 p = view->selected_object_list;
1759 view_object = GL_VIEW_OBJECT (p->data);
1760 object = gl_view_object_get_object (view_object);
1761 gl_label_object_get_extent (object, &obj_extent);
1762 x1_min = obj_extent.x1;
1763 for (p = p->next; p != NULL; p = p->next)
1765 view_object = GL_VIEW_OBJECT (p->data);
1766 object = gl_view_object_get_object (view_object);
1767 gl_label_object_get_extent (object, &obj_extent);
1768 if ( obj_extent.x1 < x1_min ) x1_min = obj_extent.x1;
1771 /* now adjust the object positions to line up the left edges */
1772 for (p = view->selected_object_list; p != NULL; p = p->next)
1774 view_object = GL_VIEW_OBJECT (p->data);
1775 object = gl_view_object_get_object (view_object);
1776 gl_label_object_get_extent (object, &obj_extent);
1777 dx = x1_min - obj_extent.x1;
1778 gl_label_object_set_position_relative (object, dx, 0.0);
1781 gl_debug (DEBUG_VIEW, "END");
1785 /*****************************************************************************/
1786 /* Align selected objects to right most edge. */
1787 /*****************************************************************************/
1789 gl_view_align_selection_right (glView *view)
1792 glViewObject *view_object;
1793 glLabelObject *object;
1795 glLabelRegion obj_extent;
1797 gl_debug (DEBUG_VIEW, "START");
1799 g_return_if_fail (view && GL_IS_VIEW (view));
1801 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1802 !gl_view_is_selection_atomic (view));
1804 /* find right most edge */
1805 p = view->selected_object_list;
1806 view_object = GL_VIEW_OBJECT (p->data);
1807 object = gl_view_object_get_object (view_object);
1808 gl_label_object_get_extent (object, &obj_extent);
1809 x2_max = obj_extent.x2;
1810 for (p = p->next; p != NULL; p = p->next)
1812 view_object = GL_VIEW_OBJECT (p->data);
1813 object = gl_view_object_get_object (view_object);
1814 gl_label_object_get_extent (object, &obj_extent);
1815 if ( obj_extent.x2 > x2_max ) x2_max = obj_extent.x2;
1818 /* now adjust the object positions to line up the right edges */
1819 for (p = view->selected_object_list; p != NULL; p = p->next)
1821 view_object = GL_VIEW_OBJECT (p->data);
1822 object = gl_view_object_get_object (view_object);
1823 gl_label_object_get_extent (object, &obj_extent);
1824 dx = x2_max - obj_extent.x2;
1825 gl_label_object_set_position_relative (object, dx, 0.0);
1828 gl_debug (DEBUG_VIEW, "END");
1832 /*****************************************************************************/
1833 /* Align selected objects to horizontal center of objects. */
1834 /*****************************************************************************/
1836 gl_view_align_selection_hcenter (glView *view)
1839 glViewObject *view_object;
1840 glLabelObject *object;
1844 glLabelRegion obj_extent;
1848 gl_debug (DEBUG_VIEW, "START");
1850 g_return_if_fail (view && GL_IS_VIEW (view));
1852 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1853 !gl_view_is_selection_atomic (view));
1855 /* find average center of objects */
1858 for (p = view->selected_object_list; p != NULL; p = p->next)
1860 view_object = GL_VIEW_OBJECT (p->data);
1861 object = gl_view_object_get_object (view_object);
1862 gl_label_object_get_extent (object, &obj_extent);
1863 xsum += (obj_extent.x1 + obj_extent.x2) / 2.0;
1868 /* find center of object closest to average center */
1869 p = view->selected_object_list;
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 dxmin = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
1874 xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
1875 for (p = p->next; p != NULL; p = p->next)
1877 view_object = GL_VIEW_OBJECT (p->data);
1878 object = gl_view_object_get_object (view_object);
1879 gl_label_object_get_extent (object, &obj_extent);
1880 dx = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
1884 xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
1888 /* now adjust the object positions to line up this center */
1889 for (p = view->selected_object_list; p != NULL; p = p->next) {
1890 view_object = GL_VIEW_OBJECT (p->data);
1891 object = gl_view_object_get_object (view_object);
1892 gl_label_object_get_extent (object, &obj_extent);
1893 dx = xcenter - (obj_extent.x1 + obj_extent.x2)/2.0;
1894 gl_label_object_set_position_relative (object, dx, 0.0);
1897 gl_debug (DEBUG_VIEW, "END");
1901 /*****************************************************************************/
1902 /* Align selected objects to top most edge. */
1903 /*****************************************************************************/
1905 gl_view_align_selection_top (glView *view)
1908 glViewObject *view_object;
1909 glLabelObject *object;
1911 glLabelRegion obj_extent;
1913 gl_debug (DEBUG_VIEW, "START");
1915 g_return_if_fail (view && GL_IS_VIEW (view));
1917 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1918 !gl_view_is_selection_atomic (view));
1920 /* find top most edge */
1921 p = view->selected_object_list;
1922 view_object = GL_VIEW_OBJECT (p->data);
1923 object = gl_view_object_get_object (view_object);
1924 gl_label_object_get_extent (object, &obj_extent);
1925 y1_min = obj_extent.y1;
1926 for (p = p->next; p != NULL; p = p->next)
1928 view_object = GL_VIEW_OBJECT (p->data);
1929 object = gl_view_object_get_object (view_object);
1930 gl_label_object_get_extent (object, &obj_extent);
1931 if ( obj_extent.y1 < y1_min ) y1_min = obj_extent.y1;
1934 /* now adjust the object positions to line up the top edges */
1935 for (p = view->selected_object_list; p != NULL; p = p->next)
1937 view_object = GL_VIEW_OBJECT (p->data);
1938 object = gl_view_object_get_object (view_object);
1939 gl_label_object_get_extent (object, &obj_extent);
1940 dy = y1_min - obj_extent.y1;
1941 gl_label_object_set_position_relative (object, 0.0, dy);
1944 gl_debug (DEBUG_VIEW, "END");
1948 /*****************************************************************************/
1949 /* Align selected objects to bottom most edge. */
1950 /*****************************************************************************/
1952 gl_view_align_selection_bottom (glView *view)
1955 glViewObject *view_object;
1956 glLabelObject *object;
1958 glLabelRegion obj_extent;
1960 gl_debug (DEBUG_VIEW, "START");
1962 g_return_if_fail (view && GL_IS_VIEW (view));
1964 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1965 !gl_view_is_selection_atomic (view));
1967 /* find bottom most edge */
1968 p = view->selected_object_list;
1969 view_object = GL_VIEW_OBJECT (p->data);
1970 object = gl_view_object_get_object (view_object);
1971 gl_label_object_get_extent (object, &obj_extent);
1972 y2_max = obj_extent.y2;
1973 for (p = p->next; p != NULL; p = p->next)
1975 view_object = GL_VIEW_OBJECT (p->data);
1976 object = gl_view_object_get_object (view_object);
1977 gl_label_object_get_extent (object, &obj_extent);
1978 if ( obj_extent.y2 > y2_max ) y2_max = obj_extent.y2;
1981 /* now adjust the object positions to line up the bottom edges */
1982 for (p = view->selected_object_list; p != NULL; p = p->next)
1984 view_object = GL_VIEW_OBJECT (p->data);
1985 object = gl_view_object_get_object (view_object);
1986 gl_label_object_get_extent (object, &obj_extent);
1987 dy = y2_max - obj_extent.y2;
1988 gl_label_object_set_position_relative (object, 0.0, dy);
1991 gl_debug (DEBUG_VIEW, "END");
1995 /*****************************************************************************/
1996 /* Align selected objects to viertical center of objects. */
1997 /*****************************************************************************/
1999 gl_view_align_selection_vcenter (glView *view)
2002 glViewObject *view_object;
2003 glLabelObject *object;
2007 glLabelRegion obj_extent;
2011 gl_debug (DEBUG_VIEW, "START");
2013 g_return_if_fail (view && GL_IS_VIEW (view));
2015 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2016 !gl_view_is_selection_atomic (view));
2018 /* find average center of objects */
2021 for (p = view->selected_object_list; p != NULL; p = p->next)
2023 view_object = GL_VIEW_OBJECT (p->data);
2024 object = gl_view_object_get_object (view_object);
2025 gl_label_object_get_extent (object, &obj_extent);
2026 ysum += (obj_extent.y1 + obj_extent.y2) / 2.0;
2031 /* find center of object closest to average center */
2032 p = view->selected_object_list;
2033 view_object = GL_VIEW_OBJECT (p->data);
2034 object = gl_view_object_get_object (view_object);
2035 gl_label_object_get_extent (object, &obj_extent);
2036 dymin = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
2037 ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
2038 for (p = p->next; p != NULL; p = p->next)
2040 view_object = GL_VIEW_OBJECT (p->data);
2041 object = gl_view_object_get_object (view_object);
2042 gl_label_object_get_extent (object, &obj_extent);
2043 dy = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
2047 ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
2051 /* now adjust the object positions to line up this center */
2052 for (p = view->selected_object_list; p != NULL; p = p->next)
2054 view_object = GL_VIEW_OBJECT (p->data);
2055 object = gl_view_object_get_object (view_object);
2056 gl_label_object_get_extent (object, &obj_extent);
2057 dy = ycenter - (obj_extent.y1 + obj_extent.y2)/2.0;
2058 gl_label_object_set_position_relative (object, 0.0, dy);
2061 gl_debug (DEBUG_VIEW, "END");
2065 /*****************************************************************************/
2066 /* Center selected objects to in center of label. */
2067 /*****************************************************************************/
2069 gl_view_center_selection_horiz (glView *view)
2072 glViewObject *view_object;
2073 glLabelObject *object;
2075 gdouble x_label_center;
2076 gdouble x_obj_center;
2077 glLabelRegion obj_extent;
2080 gl_debug (DEBUG_VIEW, "START");
2082 g_return_if_fail (view && GL_IS_VIEW (view));
2084 g_return_if_fail (!gl_view_is_selection_empty (view));
2086 gl_label_get_size (view->label, &w, &h);
2087 x_label_center = w / 2.0;
2089 /* adjust the object positions */
2090 for (p = view->selected_object_list; p != NULL; p = p->next)
2092 view_object = GL_VIEW_OBJECT (p->data);
2093 object = gl_view_object_get_object (view_object);
2094 gl_label_object_get_extent (object, &obj_extent);
2095 x_obj_center = (obj_extent.x1 + obj_extent.x2) / 2.0;
2096 dx = x_label_center - x_obj_center;
2097 gl_label_object_set_position_relative (object, dx, 0.0);
2100 gl_debug (DEBUG_VIEW, "END");
2104 /*****************************************************************************/
2105 /* Center selected objects to in center of label. */
2106 /*****************************************************************************/
2108 gl_view_center_selection_vert (glView *view)
2111 glViewObject *view_object;
2112 glLabelObject *object;
2114 gdouble y_label_center;
2115 gdouble y_obj_center;
2116 glLabelRegion obj_extent;
2119 gl_debug (DEBUG_VIEW, "START");
2121 g_return_if_fail (view && GL_IS_VIEW (view));
2123 g_return_if_fail (!gl_view_is_selection_empty (view));
2125 gl_label_get_size (view->label, &w, &h);
2126 y_label_center = h / 2.0;
2128 /* adjust the object positions */
2129 for (p = view->selected_object_list; p != NULL; p = p->next)
2131 view_object = GL_VIEW_OBJECT (p->data);
2132 object = gl_view_object_get_object (view_object);
2133 gl_label_object_get_extent (object, &obj_extent);
2134 y_obj_center = (obj_extent.y1 + obj_extent.y2) / 2.0;
2135 dy = y_label_center - y_obj_center;
2136 gl_label_object_set_position_relative (object, 0.0, dy);
2139 gl_debug (DEBUG_VIEW, "END");
2143 /*****************************************************************************/
2144 /* Move selected objects */
2145 /*****************************************************************************/
2147 gl_view_move_selection (glView *view,
2152 glLabelObject *object;
2154 gl_debug (DEBUG_VIEW, "START");
2156 g_return_if_fail (view && GL_IS_VIEW (view));
2158 for (p = view->selected_object_list; p != NULL; p = p->next)
2161 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2162 gl_label_object_set_position_relative (object, dx, dy);
2166 gl_debug (DEBUG_VIEW, "END");
2170 /*****************************************************************************/
2171 /* Can text properties be set for selection? */
2172 /*****************************************************************************/
2174 gl_view_can_selection_text (glView *view)
2177 glLabelObject *object;
2179 gl_debug (DEBUG_VIEW, "");
2181 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2183 for (p = view->selected_object_list; p != NULL; p = p->next)
2186 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2187 if (gl_label_object_can_text (object))
2198 /*****************************************************************************/
2199 /* Set font family for all text contained in selected objects. */
2200 /*****************************************************************************/
2202 gl_view_set_selection_font_family (glView *view,
2203 const gchar *font_family)
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_family (object, font_family);
2219 gl_debug (DEBUG_VIEW, "END");
2223 /*****************************************************************************/
2224 /* Set font size for all text contained in selected objects. */
2225 /*****************************************************************************/
2227 gl_view_set_selection_font_size (glView *view,
2231 glLabelObject *object;
2233 gl_debug (DEBUG_VIEW, "START");
2235 g_return_if_fail (view && GL_IS_VIEW (view));
2237 for (p = view->selected_object_list; p != NULL; p = p->next) {
2239 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2240 gl_label_object_set_font_size (object, font_size);
2244 gl_debug (DEBUG_VIEW, "END");
2248 /*****************************************************************************/
2249 /* Set font weight for all text contained in selected objects. */
2250 /*****************************************************************************/
2252 gl_view_set_selection_font_weight (glView *view,
2253 PangoWeight font_weight)
2256 glLabelObject *object;
2258 gl_debug (DEBUG_VIEW, "START");
2260 g_return_if_fail (view && GL_IS_VIEW (view));
2262 for (p = view->selected_object_list; p != NULL; p = p->next) {
2264 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2265 gl_label_object_set_font_weight (object, font_weight);
2269 gl_debug (DEBUG_VIEW, "END");
2273 /*****************************************************************************/
2274 /* Set font italic flag for all text contained in selected objects. */
2275 /*****************************************************************************/
2277 gl_view_set_selection_font_italic_flag (glView *view,
2278 gboolean font_italic_flag)
2281 glLabelObject *object;
2283 gl_debug (DEBUG_VIEW, "START");
2285 g_return_if_fail (view && GL_IS_VIEW (view));
2287 for (p = view->selected_object_list; p != NULL; p = p->next) {
2289 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2290 gl_label_object_set_font_italic_flag (object, font_italic_flag);
2294 gl_debug (DEBUG_VIEW, "END");
2298 /*****************************************************************************/
2299 /* Set text alignment for all text contained in selected objects. */
2300 /*****************************************************************************/
2302 gl_view_set_selection_text_alignment (glView *view,
2303 PangoAlignment text_alignment)
2306 glLabelObject *object;
2308 gl_debug (DEBUG_VIEW, "START");
2310 g_return_if_fail (view && GL_IS_VIEW (view));
2312 for (p = view->selected_object_list; p != NULL; p = p->next) {
2314 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2315 gl_label_object_set_text_alignment (object, text_alignment);
2319 gl_debug (DEBUG_VIEW, "END");
2323 /*****************************************************************************/
2324 /* Set text line spacing for all text contained in selected objects. */
2325 /*****************************************************************************/
2327 gl_view_set_selection_text_line_spacing (glView *view,
2328 gdouble text_line_spacing)
2331 glLabelObject *object;
2333 gl_debug (DEBUG_VIEW, "START");
2335 g_return_if_fail (view && GL_IS_VIEW (view));
2337 for (p = view->selected_object_list; p != NULL; p = p->next) {
2339 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2340 gl_label_object_set_text_line_spacing (object, text_line_spacing);
2344 gl_debug (DEBUG_VIEW, "END");
2348 /*****************************************************************************/
2349 /* Set text color for all text contained in selected objects. */
2350 /*****************************************************************************/
2352 gl_view_set_selection_text_color (glView *view,
2353 glColorNode *text_color_node)
2356 glLabelObject *object;
2358 gl_debug (DEBUG_VIEW, "START");
2360 g_return_if_fail (view && GL_IS_VIEW (view));
2362 for (p = view->selected_object_list; p != NULL; p = p->next) {
2364 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2365 gl_label_object_set_text_color (object, text_color_node);
2369 gl_debug (DEBUG_VIEW, "END");
2373 /*****************************************************************************/
2374 /* Can fill properties be set for selection? */
2375 /*****************************************************************************/
2377 gl_view_can_selection_fill (glView *view)
2380 glLabelObject *object;
2382 gl_debug (DEBUG_VIEW, "");
2384 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2386 for (p = view->selected_object_list; p != NULL; p = p->next) {
2388 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2389 if (gl_label_object_can_fill (object)) {
2399 /*****************************************************************************/
2400 /* Set fill color for all selected objects. */
2401 /*****************************************************************************/
2403 gl_view_set_selection_fill_color (glView *view,
2404 glColorNode *fill_color_node)
2407 glLabelObject *object;
2409 gl_debug (DEBUG_VIEW, "START");
2411 g_return_if_fail (view && GL_IS_VIEW (view));
2413 for (p = view->selected_object_list; p != NULL; p = p->next) {
2415 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2416 gl_label_object_set_fill_color (object, fill_color_node);
2420 gl_debug (DEBUG_VIEW, "END");
2424 /*****************************************************************************/
2425 /* Can line color properties be set for selection? */
2426 /*****************************************************************************/
2428 gl_view_can_selection_line_color (glView *view)
2431 glLabelObject *object;
2433 gl_debug (DEBUG_VIEW, "");
2435 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2437 for (p = view->selected_object_list; p != NULL; p = p->next) {
2439 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2440 if (gl_label_object_can_line_color (object)) {
2450 /*****************************************************************************/
2451 /* Set line color for all selected objects. */
2452 /*****************************************************************************/
2454 gl_view_set_selection_line_color (glView *view,
2455 glColorNode *line_color_node)
2458 glLabelObject *object;
2460 gl_debug (DEBUG_VIEW, "START");
2462 g_return_if_fail (view && GL_IS_VIEW (view));
2464 for (p = view->selected_object_list; p != NULL; p = p->next) {
2466 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2467 gl_label_object_set_line_color (object, line_color_node);
2471 gl_debug (DEBUG_VIEW, "END");
2475 /*****************************************************************************/
2476 /* Can line width properties be set for selection? */
2477 /*****************************************************************************/
2479 gl_view_can_selection_line_width (glView *view)
2482 glLabelObject *object;
2484 gl_debug (DEBUG_VIEW, "");
2486 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2488 for (p = view->selected_object_list; p != NULL; p = p->next) {
2490 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2491 if (gl_label_object_can_line_width (object)) {
2501 /*****************************************************************************/
2502 /* Set line width for all selected objects. */
2503 /*****************************************************************************/
2505 gl_view_set_selection_line_width (glView *view,
2509 glLabelObject *object;
2511 gl_debug (DEBUG_VIEW, "START");
2513 g_return_if_fail (view && GL_IS_VIEW (view));
2515 for (p = view->selected_object_list; p != NULL; p = p->next) {
2517 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2518 gl_label_object_set_line_width (object, line_width);
2522 gl_debug (DEBUG_VIEW, "END");
2526 /*****************************************************************************/
2527 /* "Cut" selected items and place in clipboard selections. */
2528 /*****************************************************************************/
2530 gl_view_cut (glView *view)
2532 gl_debug (DEBUG_VIEW, "START");
2534 g_return_if_fail (view && GL_IS_VIEW (view));
2536 gl_view_copy (view);
2537 gl_view_delete_selection (view);
2539 gl_debug (DEBUG_VIEW, "END");
2543 /*****************************************************************************/
2544 /* "Copy" selected items to clipboard selections. */
2545 /*****************************************************************************/
2547 gl_view_copy (glView *view)
2550 glViewObject *view_object;
2551 glLabelObject *object;
2553 gl_debug (DEBUG_VIEW, "START");
2555 g_return_if_fail (view && GL_IS_VIEW (view));
2557 if (view->selected_object_list) {
2559 if ( view->selection_data ) {
2560 g_object_unref (view->selection_data);
2562 view->selection_data = GL_LABEL(gl_label_new ());
2563 gl_label_set_template (view->selection_data, view->label->template);
2564 gl_label_set_rotate_flag (view->selection_data, view->label->rotate_flag);
2566 for (p = view->selected_object_list; p != NULL; p = p->next) {
2568 view_object = GL_VIEW_OBJECT (p->data);
2569 object = gl_view_object_get_object (view_object);
2571 gl_label_object_dup (object, view->selection_data);
2575 gtk_selection_owner_set (view->invisible,
2576 clipboard_atom, GDK_CURRENT_TIME);
2577 view->have_selection = TRUE;
2581 gl_debug (DEBUG_VIEW, "END");
2585 /*****************************************************************************/
2586 /* "Paste" from private clipboard selection. */
2587 /*****************************************************************************/
2589 gl_view_paste (glView *view)
2591 gl_debug (DEBUG_VIEW, "START");
2593 g_return_if_fail (view && GL_IS_VIEW (view));
2595 gtk_selection_convert (GTK_WIDGET (view->invisible),
2596 clipboard_atom, GDK_SELECTION_TYPE_STRING,
2599 gl_debug (DEBUG_VIEW, "END");
2603 /*****************************************************************************/
2604 /* Zoom in one "notch" */
2605 /*****************************************************************************/
2607 gl_view_zoom_in (glView *view)
2610 gdouble dist, dist_min;
2612 gl_debug (DEBUG_VIEW, "START");
2614 g_return_if_fail (view && GL_IS_VIEW (view));
2616 /* Find index of current scale (or best match) */
2617 i_min = 1; /* start with 2nd largest scale */
2618 dist_min = fabs (zooms[1] - view->zoom);
2619 for (i = 2; i < N_ZOOMS; i++) {
2620 dist = fabs (zooms[i] - view->zoom);
2621 if (dist < dist_min) {
2627 /* zoom in one "notch" */
2628 i = MAX (0, i_min - 1);
2629 gl_debug (DEBUG_VIEW, "zoom[%d] = %g", i, zooms[i]);
2630 set_zoom_real (view, zooms[i], FALSE);
2632 gl_debug (DEBUG_VIEW, "END");
2636 /*****************************************************************************/
2637 /* Zoom out one "notch" */
2638 /*****************************************************************************/
2640 gl_view_zoom_out (glView *view)
2643 gdouble dist, dist_min;
2645 gl_debug (DEBUG_VIEW, "START");
2647 g_return_if_fail (view && GL_IS_VIEW (view));
2649 /* Find index of current scale (or best match) */
2650 i_min = 0; /* start with largest scale */
2651 dist_min = fabs (zooms[0] - view->zoom);
2652 for (i = 1; i < N_ZOOMS; i++) {
2653 dist = fabs (zooms[i] - view->zoom);
2654 if (dist < dist_min) {
2660 /* zoom out one "notch" */
2661 if (i_min >= N_ZOOMS)
2666 set_zoom_real (view, zooms[i], FALSE);
2668 gl_debug (DEBUG_VIEW, "END");
2672 /*****************************************************************************/
2673 /* Set zoom to best fit. */
2674 /*****************************************************************************/
2676 gl_view_zoom_to_fit (glView *view)
2678 GtkAllocation allocation;
2679 gint w_view, h_view;
2680 gdouble w_label, h_label;
2681 gdouble x_scale, y_scale, scale;
2683 gl_debug (DEBUG_VIEW, "");
2685 if ( ! gtk_widget_get_window (GTK_WIDGET (view)) ) {
2686 set_zoom_real (view, 1.0, TRUE);
2690 gtk_widget_get_allocation (GTK_WIDGET (view), &allocation);
2691 w_view = allocation.width;
2692 h_view = allocation.height;
2694 gl_label_get_size (GL_LABEL(view->label), &w_label, &h_label);
2696 gl_debug (DEBUG_VIEW, "View size: %d, %d", w_view, h_view);
2697 gl_debug (DEBUG_VIEW, "Label size: %g, %g", w_label, h_label);
2699 /* Calculate best scale */
2700 x_scale = (double)(w_view - ZOOMTOFIT_PAD) / w_label;
2701 y_scale = (double)(h_view - ZOOMTOFIT_PAD) / h_label;
2702 scale = MIN (x_scale, y_scale);
2703 gl_debug (DEBUG_VIEW, "Candidate zooms: %g, %g => %g", x_scale, y_scale, scale);
2706 gl_debug (DEBUG_VIEW, "Scale: %g", scale);
2707 scale = MIN (scale, zooms[0]*view->home_scale);
2708 scale = MAX (scale, zooms[N_ZOOMS-1]*view->home_scale);
2709 gl_debug (DEBUG_VIEW, "Limitted scale: %g", scale);
2711 set_zoom_real (view, scale/view->home_scale, TRUE);
2715 /*****************************************************************************/
2716 /* Set current zoom factor to explicit value. */
2717 /*****************************************************************************/
2719 gl_view_set_zoom (glView *view,
2722 gl_debug (DEBUG_VIEW, "START");
2724 set_zoom_real (view, zoom, FALSE);
2726 gl_debug (DEBUG_VIEW, "END");
2730 /*---------------------------------------------------------------------------*/
2731 /* PRIVATE. Set canvas scale. */
2732 /*---------------------------------------------------------------------------*/
2734 set_zoom_real (glView *view,
2736 gboolean zoom_to_fit_flag)
2738 gl_debug (DEBUG_VIEW, "START");
2740 g_return_if_fail (view && GL_IS_VIEW (view));
2741 g_return_if_fail (zoom > 0.0);
2743 /* Limit, if needed */
2744 gl_debug (DEBUG_VIEW, "Zoom requested: %g", zoom);
2745 zoom = MIN (zoom, zooms[0]);
2746 zoom = MAX (zoom, zooms[N_ZOOMS-1]);
2747 gl_debug (DEBUG_VIEW, "Limitted zoom: %g", zoom);
2749 if ( zoom != view->zoom ) {
2752 view->zoom_to_fit_flag = zoom_to_fit_flag;
2754 gl_view_update (view);
2756 g_signal_emit (G_OBJECT(view), signals[ZOOM_CHANGED], 0, zoom);
2760 gl_debug (DEBUG_VIEW, "END");
2765 /*****************************************************************************/
2766 /* Get current zoom factor. */
2767 /*****************************************************************************/
2769 gl_view_get_zoom (glView *view)
2771 gl_debug (DEBUG_VIEW, "");
2773 g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
2779 /*****************************************************************************/
2780 /* Is this the maximum zoom level. */
2781 /*****************************************************************************/
2783 gl_view_is_zoom_max (glView *view)
2785 gl_debug (DEBUG_VIEW, "");
2787 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
2789 return view->zoom >= zooms[0];
2793 /*****************************************************************************/
2794 /* Is this the minimum zoom level. */
2795 /*****************************************************************************/
2797 gl_view_is_zoom_min (glView *view)
2799 gl_debug (DEBUG_VIEW, "");
2801 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2803 return view->zoom <= zooms[N_ZOOMS-1];
2807 /*---------------------------------------------------------------------------*/
2808 /* PRIVATE. Handle "selection-clear" signal. */
2809 /*---------------------------------------------------------------------------*/
2811 selection_clear_cb (GtkWidget *widget,
2812 GdkEventSelection *event,
2815 gl_debug (DEBUG_VIEW, "START");
2817 g_return_if_fail (view && GL_IS_VIEW (view));
2819 view->have_selection = FALSE;
2820 g_object_unref (view->selection_data);
2821 view->selection_data = NULL;
2823 gl_debug (DEBUG_VIEW, "END");
2827 /*---------------------------------------------------------------------------*/
2828 /* PRIVATE. Handle "selection-get" signal. */
2829 /*---------------------------------------------------------------------------*/
2831 selection_get_cb (GtkWidget *widget,
2832 GtkSelectionData *sd,
2838 glXMLLabelStatus status;
2840 gl_debug (DEBUG_VIEW, "START");
2842 g_return_if_fail (view && GL_IS_VIEW (view));
2844 if (view->have_selection) {
2846 buffer = gl_xml_label_save_buffer (view->selection_data,
2848 gtk_selection_data_set (sd,
2849 GDK_SELECTION_TYPE_STRING, 8,
2850 (guchar *)buffer, strlen (buffer));
2854 gl_debug (DEBUG_VIEW, "END");
2858 /*---------------------------------------------------------------------------*/
2859 /* PRIVATE. Handle "selection-received" signal. (Result of Paste) */
2860 /*---------------------------------------------------------------------------*/
2862 selection_received_cb (GtkWidget *widget,
2863 GtkSelectionData *sd,
2867 glLabel *label = NULL;
2868 glXMLLabelStatus status;
2870 glLabelObject *object, *newobject;
2872 gl_debug (DEBUG_VIEW, "START");
2874 g_return_if_fail (view && GL_IS_VIEW (view));
2876 if (gtk_selection_data_get_length (sd) < 0)
2880 if (gtk_selection_data_get_data_type (sd) != GDK_SELECTION_TYPE_STRING)
2885 gl_view_unselect_all (view);
2887 label = gl_xml_label_open_buffer ((gchar *)gtk_selection_data_get_data (sd), &status);
2888 for (p = label->objects; p != NULL; p = p_next)
2892 object = (glLabelObject *) p->data;
2893 newobject = gl_label_object_dup (object, view->label);
2895 gl_debug (DEBUG_VIEW, "object pasted");
2897 g_object_unref (label);
2899 gl_debug (DEBUG_VIEW, "END");
2903 /****************************************************************************/
2904 /* Set default font family. */
2905 /****************************************************************************/
2907 gl_view_set_default_font_family (glView *view,
2908 const gchar *font_family)
2910 gl_debug (DEBUG_VIEW, "START");
2912 g_return_if_fail (view && GL_IS_VIEW (view));
2914 if (view->default_font_family) {
2915 g_free (view->default_font_family);
2917 view->default_font_family = g_strdup (font_family);
2919 gl_debug (DEBUG_VIEW, "END");
2923 /****************************************************************************/
2924 /* Set default font size. */
2925 /****************************************************************************/
2927 gl_view_set_default_font_size (glView *view,
2930 gl_debug (DEBUG_VIEW, "START");
2932 g_return_if_fail (view && GL_IS_VIEW (view));
2934 view->default_font_size = font_size;
2936 gl_debug (DEBUG_VIEW, "END");
2940 /****************************************************************************/
2941 /* Set default font weight. */
2942 /****************************************************************************/
2944 gl_view_set_default_font_weight (glView *view,
2945 PangoWeight font_weight)
2947 gl_debug (DEBUG_VIEW, "START");
2949 g_return_if_fail (view && GL_IS_VIEW (view));
2951 view->default_font_weight = font_weight;
2953 gl_debug (DEBUG_VIEW, "END");
2957 /****************************************************************************/
2958 /* Set default font italic flag. */
2959 /****************************************************************************/
2961 gl_view_set_default_font_italic_flag (glView *view,
2962 gboolean font_italic_flag)
2964 gl_debug (DEBUG_VIEW, "START");
2966 g_return_if_fail (view && GL_IS_VIEW (view));
2968 view->default_font_italic_flag = font_italic_flag;
2970 gl_debug (DEBUG_VIEW, "END");
2974 /****************************************************************************/
2975 /* Set default text color. */
2976 /****************************************************************************/
2978 gl_view_set_default_text_color (glView *view,
2981 gl_debug (DEBUG_VIEW, "START");
2983 g_return_if_fail (view && GL_IS_VIEW (view));
2985 view->default_text_color = text_color;
2987 gl_debug (DEBUG_VIEW, "END");
2991 /****************************************************************************/
2992 /* Set default text alignment. */
2993 /****************************************************************************/
2995 gl_view_set_default_text_alignment (glView *view,
2996 PangoAlignment text_alignment)
2998 gl_debug (DEBUG_VIEW, "START");
3000 g_return_if_fail (view && GL_IS_VIEW (view));
3002 view->default_text_alignment = text_alignment;
3003 gl_debug (DEBUG_VIEW, "END");
3007 /****************************************************************************/
3008 /* Set default text line spacing. */
3009 /****************************************************************************/
3011 gl_view_set_default_text_line_spacing (glView *view,
3012 gdouble text_line_spacing)
3014 gl_debug (DEBUG_VIEW, "START");
3016 g_return_if_fail (view && GL_IS_VIEW (view));
3018 view->default_text_line_spacing = text_line_spacing;
3020 gl_debug (DEBUG_VIEW, "END");
3024 /****************************************************************************/
3025 /* Set default line width. */
3026 /****************************************************************************/
3028 gl_view_set_default_line_width (glView *view,
3031 gl_debug (DEBUG_VIEW, "START");
3033 g_return_if_fail (view && GL_IS_VIEW (view));
3035 view->default_line_width = line_width;
3037 gl_debug (DEBUG_VIEW, "END");
3041 /****************************************************************************/
3042 /* Set default line color. */
3043 /****************************************************************************/
3045 gl_view_set_default_line_color (glView *view,
3048 gl_debug (DEBUG_VIEW, "START");
3050 g_return_if_fail (view && GL_IS_VIEW (view));
3052 view->default_line_color = line_color;
3054 gl_debug (DEBUG_VIEW, "END");
3058 /****************************************************************************/
3059 /* Set default fill color. */
3060 /****************************************************************************/
3062 gl_view_set_default_fill_color (glView *view,
3065 gl_debug (DEBUG_VIEW, "START");
3067 g_return_if_fail (view && GL_IS_VIEW (view));
3069 view->default_fill_color = fill_color;
3071 gl_debug (DEBUG_VIEW, "END");
3075 /****************************************************************************/
3076 /* Get default font family. */
3077 /****************************************************************************/
3079 gl_view_get_default_font_family (glView *view)
3081 gl_debug (DEBUG_VIEW, "START");
3083 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
3085 gl_debug (DEBUG_VIEW, "END");
3087 return g_strdup (view->default_font_family);
3091 /****************************************************************************/
3092 /* Get default font size. */
3093 /****************************************************************************/
3095 gl_view_get_default_font_size (glView *view)
3097 gl_debug (DEBUG_VIEW, "START");
3099 g_return_val_if_fail (view && GL_IS_VIEW (view), 12.0);
3101 gl_debug (DEBUG_VIEW, "END");
3103 return view->default_font_size;
3107 /****************************************************************************/
3108 /* Get default font weight. */
3109 /****************************************************************************/
3111 gl_view_get_default_font_weight (glView *view)
3113 gl_debug (DEBUG_VIEW, "START");
3115 g_return_val_if_fail (view && GL_IS_VIEW (view), PANGO_WEIGHT_NORMAL);
3117 gl_debug (DEBUG_VIEW, "END");
3119 return view->default_font_weight;
3123 /****************************************************************************/
3124 /* Get default font italic flag. */
3125 /****************************************************************************/
3127 gl_view_get_default_font_italic_flag (glView *view)
3129 gl_debug (DEBUG_VIEW, "START");
3131 g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3133 gl_debug (DEBUG_VIEW, "END");
3135 return view->default_font_italic_flag;
3139 /****************************************************************************/
3140 /* Get default text color. */
3141 /****************************************************************************/
3143 gl_view_get_default_text_color (glView *view)
3145 gl_debug (DEBUG_VIEW, "START");
3147 g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
3149 gl_debug (DEBUG_VIEW, "END");
3151 return view->default_text_color;
3155 /****************************************************************************/
3156 /* Get default text alignment. */
3157 /****************************************************************************/
3159 gl_view_get_default_text_alignment (glView *view)
3161 gl_debug (DEBUG_VIEW, "START");
3163 g_return_val_if_fail (view && GL_IS_VIEW (view), PANGO_ALIGN_LEFT);
3165 gl_debug (DEBUG_VIEW, "END");
3167 return view->default_text_alignment;
3171 /****************************************************************************/
3172 /* Get default text line spacing. */
3173 /****************************************************************************/
3175 gl_view_get_default_text_line_spacing (glView *view)
3177 gl_debug (DEBUG_VIEW, "START");
3179 g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
3181 gl_debug (DEBUG_VIEW, "END");
3183 return view->default_text_line_spacing;
3187 /****************************************************************************/
3188 /* Get default line width. */
3189 /****************************************************************************/
3191 gl_view_get_default_line_width (glView *view)
3193 gl_debug (DEBUG_VIEW, "START");
3195 g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
3197 gl_debug (DEBUG_VIEW, "END");
3199 return view->default_line_width;
3203 /****************************************************************************/
3204 /* Get default line color. */
3205 /****************************************************************************/
3207 gl_view_get_default_line_color (glView *view)
3209 gl_debug (DEBUG_VIEW, "START");
3211 g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
3213 gl_debug (DEBUG_VIEW, "END");
3215 return view->default_line_color;
3219 /****************************************************************************/
3220 /* Get default fill color. */
3221 /****************************************************************************/
3223 gl_view_get_default_fill_color (glView *view)
3225 gl_debug (DEBUG_VIEW, "START");
3227 g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
3229 gl_debug (DEBUG_VIEW, "END");
3231 return view->default_fill_color;
3235 /*---------------------------------------------------------------------------*/
3236 /* PRIVATE. Focus in event handler. */
3237 /*---------------------------------------------------------------------------*/
3239 focus_in_event_cb (glView *view,
3240 GdkEventFocus *event)
3246 /*---------------------------------------------------------------------------*/
3247 /* PRIVATE. Focus out event handler. */
3248 /*---------------------------------------------------------------------------*/
3250 focus_out_event_cb (glView *view,
3251 GdkEventFocus *event)
3257 /*---------------------------------------------------------------------------*/
3258 /* PRIVATE. Enter notify event handler. */
3259 /*---------------------------------------------------------------------------*/
3261 enter_notify_event_cb (glView *view,
3262 GdkEventCrossing *event)
3268 /*---------------------------------------------------------------------------*/
3269 /* PRIVATE. Leave notify event handler. */
3270 /*---------------------------------------------------------------------------*/
3272 leave_notify_event_cb (glView *view,
3273 GdkEventCrossing *event)
3276 g_signal_emit (G_OBJECT(view), signals[POINTER_EXIT], 0);
3282 /*---------------------------------------------------------------------------*/
3283 /* PRIVATE. Motion notify event handler. */
3284 /*---------------------------------------------------------------------------*/
3286 motion_notify_event_cb (glView *view,
3287 GdkEventMotion *event)
3289 gboolean return_value = FALSE;
3290 GdkWindow *bin_window;
3296 glViewObjectHandle handle;
3298 bin_window = gtk_layout_get_bin_window (GTK_LAYOUT (view->canvas));
3299 window = gtk_widget_get_window (view->canvas);
3301 cr = gdk_cairo_create (bin_window);
3304 * Translate to label coordinates
3306 scale = view->zoom * view->home_scale;
3307 cairo_scale (cr, scale, scale);
3308 cairo_translate (cr, view->x0, view->y0);
3312 cairo_device_to_user (cr, &x, &y);
3315 * Emit signal regardless of mode
3317 g_signal_emit (G_OBJECT(view), signals[POINTER_MOVED], 0, x, y);
3320 * Handle event as appropriate for mode
3325 case GL_VIEW_MODE_ARROW:
3326 switch (view->state)
3330 if ( gl_view_is_selection_atomic (view) &&
3331 view_handle_at (view, cr, event->x, event->y, &handle) )
3333 cursor = gdk_cursor_new (GDK_CROSSHAIR);
3335 else if (view_view_object_at (view, cr, event->x, event->y))
3337 cursor = gdk_cursor_new (GDK_FLEUR);
3341 cursor = gdk_cursor_new (GDK_LEFT_PTR);
3343 gdk_window_set_cursor (window, cursor);
3344 gdk_cursor_unref (cursor);
3347 case GL_VIEW_ARROW_SELECT_REGION:
3349 gl_view_update_region (view, cr, &view->select_region);
3351 view->select_region.x2 = x;
3352 view->select_region.y2 = y;
3354 gl_view_update_region (view, cr, &view->select_region);
3356 gl_view_update (view);
3360 case GL_VIEW_ARROW_MOVE:
3361 gl_view_move_selection (view,
3362 (x - view->move_last_x),
3363 (y - view->move_last_y));
3364 view->move_last_x = x;
3365 view->move_last_y = y;
3368 case GL_VIEW_ARROW_RESIZE:
3369 gl_view_object_resize_event (view->resize_object,
3370 view->resize_handle,
3371 view->resize_honor_aspect,
3378 g_message ("Invalid arrow state."); /*Should not happen!*/
3380 return_value = TRUE;
3384 case GL_VIEW_MODE_OBJECT_CREATE:
3385 if (view->state != GL_VIEW_IDLE)
3387 switch (view->create_type)
3389 case GL_LABEL_OBJECT_BOX:
3390 gl_view_box_create_motion_event (view, x, y);
3392 case GL_LABEL_OBJECT_ELLIPSE:
3393 gl_view_ellipse_create_motion_event (view, x, y);
3395 case GL_LABEL_OBJECT_LINE:
3396 gl_view_line_create_motion_event (view, x, y);
3398 case GL_LABEL_OBJECT_IMAGE:
3399 gl_view_image_create_motion_event (view, x, y);
3401 case GL_LABEL_OBJECT_TEXT:
3402 gl_view_text_create_motion_event (view, x, y);
3404 case GL_LABEL_OBJECT_BARCODE:
3405 gl_view_barcode_create_motion_event (view, x, y);
3408 g_message ("Invalid create type."); /*Should not happen!*/
3415 g_message ("Invalid view mode."); /*Should not happen!*/
3422 * FIXME: we re-establish grabs here if the grab has been lost. We seem to be
3423 * losing grabs when we emit signals that lead to the manipulation of
3424 * the GtkUIManager. Needs more investigation
3426 if (view->grabbed_flag && !gdk_pointer_is_grabbed ())
3428 gdk_pointer_grab (bin_window,
3430 (GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK),
3436 return return_value;
3440 /*---------------------------------------------------------------------------*/
3441 /* PRIVATE. Button press event handler. */
3442 /*---------------------------------------------------------------------------*/
3444 button_press_event_cb (glView *view,
3445 GdkEventButton *event)
3447 gboolean return_value = FALSE;
3448 GdkWindow *bin_window;
3452 glViewObject *view_object;
3453 glViewObjectHandle handle;
3455 gtk_widget_grab_focus(GTK_WIDGET (view->canvas));
3457 bin_window = gtk_layout_get_bin_window (GTK_LAYOUT (view->canvas));
3459 cr = gdk_cairo_create (bin_window);
3462 * Translate to label coordinates
3464 scale = view->zoom * view->home_scale;
3465 cairo_scale (cr, scale, scale);
3466 cairo_translate (cr, view->x0, view->y0);
3470 cairo_device_to_user (cr, &x, &y);
3472 switch (event->button)
3477 * Handle event as appropriate for mode
3481 case GL_VIEW_MODE_ARROW:
3482 if ( gl_view_is_selection_atomic (view) &&
3483 (view_object = view_handle_at (view, cr, event->x, event->y, &handle)) )
3485 view->resize_object = view_object;
3486 view->resize_handle = handle;
3487 view->resize_honor_aspect = event->state & GDK_CONTROL_MASK;
3489 view->state = GL_VIEW_ARROW_RESIZE;
3491 else if ((view_object = view_view_object_at (view, cr, event->x, event->y)))
3493 if (event->state & GDK_CONTROL_MASK)
3495 if (gl_view_is_object_selected (view, view_object))
3497 /* Un-selecting a selected item */
3498 gl_view_unselect_object (view, view_object);
3500 /* Add to current selection */
3501 gl_view_select_object (view, view_object);
3506 if (!gl_view_is_object_selected (view, view_object))
3508 /* remove any selections before adding */
3509 gl_view_unselect_all (view);
3510 /* Add to current selection */
3511 gl_view_select_object (view, view_object);
3514 view->move_last_x = x;
3515 view->move_last_y = y;
3517 view->state = GL_VIEW_ARROW_MOVE;
3521 if (!(event->state & GDK_CONTROL_MASK))
3523 gl_view_unselect_all (view);
3526 view->select_region_visible = TRUE;
3527 view->select_region.x1 = x;
3528 view->select_region.y1 = y;
3529 view->select_region.x2 = x;
3530 view->select_region.y2 = y;
3532 view->state = GL_VIEW_ARROW_SELECT_REGION;
3536 return_value = TRUE;
3539 case GL_VIEW_MODE_OBJECT_CREATE:
3540 switch (view->create_type)
3542 case GL_LABEL_OBJECT_BOX:
3543 gl_view_box_create_button_press_event (view, x, y);
3545 case GL_LABEL_OBJECT_ELLIPSE:
3546 gl_view_ellipse_create_button_press_event (view, x, y);
3548 case GL_LABEL_OBJECT_LINE:
3549 gl_view_line_create_button_press_event (view, x, y);
3551 case GL_LABEL_OBJECT_IMAGE:
3552 gl_view_image_create_button_press_event (view, x, y);
3554 case GL_LABEL_OBJECT_TEXT:
3555 gl_view_text_create_button_press_event (view, x, y);
3557 case GL_LABEL_OBJECT_BARCODE:
3558 gl_view_barcode_create_button_press_event (view, x, y);
3561 g_message ("Invalid create type."); /*Should not happen!*/
3563 view->state = GL_VIEW_CREATE_DRAG;
3564 return_value = TRUE;
3568 g_message ("Invalid view mode."); /*Should not happen!*/
3571 view->grabbed_flag = TRUE;
3572 gdk_pointer_grab (bin_window,
3574 (GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK),
3581 g_signal_emit (G_OBJECT (view),
3582 signals[CONTEXT_MENU_ACTIVATE], 0,
3583 event->button, event->time);
3584 return_value = TRUE;
3591 return return_value;
3595 /*---------------------------------------------------------------------------*/
3596 /* PRIVATE. Button release event handler. */
3597 /*---------------------------------------------------------------------------*/
3599 button_release_event_cb (glView *view,
3600 GdkEventButton *event)
3602 gboolean return_value = FALSE;
3603 GdkWindow *bin_window;
3610 bin_window = gtk_layout_get_bin_window (GTK_LAYOUT (view->canvas));
3611 window = gtk_widget_get_window (view->canvas);
3613 cr = gdk_cairo_create (bin_window);
3616 * Translate to label coordinates
3618 scale = view->zoom * view->home_scale;
3619 cairo_scale (cr, scale, scale);
3620 cairo_translate (cr, view->x0, view->y0);
3624 cairo_device_to_user (cr, &x, &y);
3626 switch (event->button)
3630 view->grabbed_flag = FALSE;
3631 gdk_pointer_ungrab (event->time);
3633 * Handle event as appropriate for mode
3637 case GL_VIEW_MODE_ARROW:
3638 switch (view->state)
3640 case GL_VIEW_ARROW_RESIZE:
3641 view->resize_object = NULL;
3643 view->state = GL_VIEW_IDLE;
3646 case GL_VIEW_ARROW_SELECT_REGION:
3648 gl_view_update_region (view, cr, &view->select_region);
3650 gl_view_update (view);
3653 view->select_region_visible = FALSE;
3654 view->select_region.x2 = x;
3655 view->select_region.y2 = y;
3657 gl_view_select_region (view, &view->select_region);
3659 view->state = GL_VIEW_IDLE;
3663 view->state = GL_VIEW_IDLE;
3668 return_value = TRUE;
3672 case GL_VIEW_MODE_OBJECT_CREATE:
3673 switch (view->create_type)
3675 case GL_LABEL_OBJECT_BOX:
3676 gl_view_box_create_button_release_event (view, x, y);
3678 case GL_LABEL_OBJECT_ELLIPSE:
3679 gl_view_ellipse_create_button_release_event (view, x, y);
3681 case GL_LABEL_OBJECT_LINE:
3682 gl_view_line_create_button_release_event (view, x, y);
3684 case GL_LABEL_OBJECT_IMAGE:
3685 gl_view_image_create_button_release_event (view, x, y);
3687 case GL_LABEL_OBJECT_TEXT:
3688 gl_view_text_create_button_release_event (view, x, y);
3690 case GL_LABEL_OBJECT_BARCODE:
3691 gl_view_barcode_create_button_release_event (view, x, y);
3694 g_message ("Invalid create type."); /*Should not happen!*/
3696 view->mode = GL_VIEW_MODE_ARROW;
3697 view->state = GL_VIEW_IDLE;
3698 cursor = gdk_cursor_new (GDK_LEFT_PTR);
3699 gdk_window_set_cursor (window, cursor);
3700 gdk_cursor_unref (cursor);
3705 g_message ("Invalid view mode."); /*Should not happen!*/
3712 return return_value;
3716 /*---------------------------------------------------------------------------*/
3717 /* PRIVATE. Key press event handler. */
3718 /*---------------------------------------------------------------------------*/
3720 key_press_event_cb (glView *view,
3726 gl_debug (DEBUG_VIEW, "");
3728 window = gtk_widget_get_window (view->canvas);
3730 if ( (view->mode == GL_VIEW_MODE_ARROW) &&
3731 (view->state == GL_VIEW_IDLE) )
3733 switch (event->keyval) {
3737 gl_view_move_selection (view, -1.0 / (view->zoom), 0.0);
3741 gl_view_move_selection (view, 0.0, -1.0 / (view->zoom));
3745 gl_view_move_selection (view, 1.0 / (view->zoom), 0.0);
3749 gl_view_move_selection (view, 0.0, 1.0 / (view->zoom));
3753 gl_view_delete_selection (view);
3754 cursor = gdk_cursor_new (GDK_LEFT_PTR);
3755 gdk_window_set_cursor (window, cursor);
3756 gdk_cursor_unref (cursor);
3763 return TRUE; /* We handled this or we were dragging. */
3769 * Local Variables: -- emacs
3771 * c-basic-offset: 8 -- emacs
3772 * tab-width: 8 -- emacs
3773 * indent-tabs-mode: nil -- emacs