]> git.sur5r.net Git - glabels/commitdiff
Added initial object rotation code.
authorJim Evins <evins@snaught.com>
Mon, 11 Nov 2002 20:10:14 +0000 (20:10 +0000)
committerJim Evins <evins@snaught.com>
Mon, 11 Nov 2002 20:10:14 +0000 (20:10 +0000)
git-svn-id: https://glabels.svn.sourceforge.net/svnroot/glabels/trunk@176 f5e0f49d-192f-0410-a22d-a8d8700d0965

glabels2/src/label-object.c
glabels2/src/label-object.h
glabels2/src/print.c
glabels2/src/tools.c
glabels2/src/tools.h
glabels2/src/ui.c
glabels2/src/view-highlight.c
glabels2/src/view-object.c
glabels2/src/view.c
glabels2/src/view.h
glabels2/src/xml-label.c

index 03eecf6a64cc6f87865f138c6e68f83b63aa5cc7..f3e4b49b6215e48ed2bb702098313dc73222df02 100644 (file)
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
+#include <config.h>
 
 #include <glib.h>
+#include <libart_lgpl/libart.h>
 
 #include "label-object.h"
 #include "marshal.h"
@@ -35,8 +37,7 @@ struct _glLabelObjectPrivate {
        gchar             *name;
        gdouble            x, y;
        gdouble            w, h;
-       glLabelObjectFlip  flip;
-       gdouble            rotate_degs;
+       gdouble            affine[6];
 };
 
 enum {
@@ -134,9 +135,9 @@ gl_label_object_class_init (glLabelObjectClass *klass)
                              G_SIGNAL_RUN_LAST,
                              G_STRUCT_OFFSET (glLabelObjectClass, flip_rotate),
                              NULL, NULL,
-                             gl_marshal_VOID__INT_DOUBLE,
+                             gl_marshal_VOID__VOID,
                              G_TYPE_NONE,
-                             2, G_TYPE_INT, G_TYPE_DOUBLE);
+                             0);
        signals[TOP] =
                g_signal_new ("top",
                              G_OBJECT_CLASS_TYPE (object_class),
@@ -169,6 +170,8 @@ gl_label_object_instance_init (glLabelObject *object)
 
        object->private->name = g_strdup_printf ("object%d", instance++);
 
+       art_affine_identity (object->private->affine);
+
        gl_debug (DEBUG_LABEL, "END");
 }
 
@@ -218,18 +221,18 @@ gl_label_object_copy_props (glLabelObject *dst_object,
                            glLabelObject *src_object)
 {
        gdouble           x, y, w, h;
-       glLabelObjectFlip flip;
+       gdouble           affine[6];
 
        g_return_if_fail (src_object && GL_IS_LABEL_OBJECT (src_object));
        g_return_if_fail (dst_object && GL_IS_LABEL_OBJECT (dst_object));
 
-       gl_label_object_get_position    (src_object, &x, &y);
-       gl_label_object_get_size        (src_object, &w, &h);
-       flip = gl_label_object_get_flip (src_object);
+       gl_label_object_get_position (src_object, &x, &y);
+       gl_label_object_get_size     (src_object, &w, &h);
+       gl_label_object_get_affine   (src_object, affine);
 
-       gl_label_object_set_position (dst_object,  x,  y);
-       gl_label_object_set_size     (dst_object,  w,  h);
-       gl_label_object_set_flip     (dst_object,  flip);
+       gl_label_object_set_position (dst_object, x, y);
+       gl_label_object_set_size     (dst_object, w, h);
+       gl_label_object_set_affine   (dst_object, affine);
 }
 
 /*****************************************************************************/
@@ -432,22 +435,46 @@ gl_label_object_get_size (glLabelObject *object,
        gl_debug (DEBUG_LABEL, "END");
 }
 
-/****************************************************************************/
-/* Set flip state of object.                                                */
-/****************************************************************************/
+/*****************************************************************************/
+/* Get extent of object.                                                     */
+/*****************************************************************************/
 void
-gl_label_object_set_flip (glLabelObject     *object,
-                         glLabelObjectFlip  flip)
+gl_label_object_get_extent (glLabelObject *object,
+                           gdouble       *x1,
+                           gdouble       *y1,
+                           gdouble       *x2,
+                           gdouble       *y2)
 {
+       ArtPoint a1, a2, a3, a4, b1, b2, b3, b4;
+       gdouble  affine[6];
+
        gl_debug (DEBUG_LABEL, "START");
 
        g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-       object->private->flip = flip;
-
-       g_signal_emit (G_OBJECT(object), signals[FLIP_ROTATE], 0,
-                      flip, object->private->rotate_degs);
-
+       /* setup untransformed corners of bounding box */
+       a1.x = 0.0;
+       a1.y = 0.0;
+       a2.x = object->private->w;
+       a2.y = 0.0;
+       a3.x = object->private->w;
+       a3.y = object->private->h;
+       a4.x = 0.0;
+       a4.y = object->private->h;
+
+       /* transform these points */
+       gl_label_object_get_applied_affine (object, affine);
+       art_affine_point (&b1, &a1, affine);
+       art_affine_point (&b2, &a2, affine);
+       art_affine_point (&b3, &a3, affine);
+       art_affine_point (&b4, &a4, affine);
+
+       /* now find the maximum extent of these points in x and y */
+       *x1 = MIN (b1.x, MIN (b2.x, MIN (b3.x, b4.x))) + object->private->x;
+       *y1 = MIN (b1.y, MIN (b2.y, MIN (b3.y, b4.y))) + object->private->y;
+       *x2 = MAX (b1.x, MAX (b2.x, MAX (b3.x, b4.x))) + object->private->x;
+       *y2 = MAX (b1.y, MAX (b2.y, MAX (b3.y, b4.y))) + object->private->y;
+       
        gl_debug (DEBUG_LABEL, "END");
 }
 
@@ -461,10 +488,9 @@ gl_label_object_flip_horiz (glLabelObject *object)
 
        g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-       object->private->flip ^= GL_LABEL_OBJECT_FLIP_HORIZ;
+       art_affine_flip (object->private->affine, object->private->affine, TRUE, FALSE);
 
-       g_signal_emit (G_OBJECT(object), signals[FLIP_ROTATE], 0,
-                      object->private->flip, object->private->rotate_degs);
+       g_signal_emit (G_OBJECT(object), signals[FLIP_ROTATE], 0);
 
        gl_debug (DEBUG_LABEL, "END");
 }
@@ -479,25 +505,90 @@ gl_label_object_flip_vert (glLabelObject *object)
 
        g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-       object->private->flip ^= GL_LABEL_OBJECT_FLIP_VERT;
+       art_affine_flip (object->private->affine, object->private->affine, FALSE, TRUE);
+
+       g_signal_emit (G_OBJECT(object), signals[FLIP_ROTATE], 0);
+
+       gl_debug (DEBUG_LABEL, "END");
+}
+
+/****************************************************************************/
+/* Rotate object.                                                           */
+/****************************************************************************/
+void
+gl_label_object_rotate (glLabelObject *object,
+                       gdouble        theta_degs)
+{
+       gdouble rotate_affine[6];
+
+       gl_debug (DEBUG_LABEL, "START");
+
+       g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
+
+       art_affine_rotate (rotate_affine, theta_degs);
+       art_affine_multiply (object->private->affine, object->private->affine, rotate_affine);
 
-       g_signal_emit (G_OBJECT(object), signals[FLIP_ROTATE], 0,
-                      object->private->flip, object->private->rotate_degs);
+       g_signal_emit (G_OBJECT(object), signals[FLIP_ROTATE], 0);
 
        gl_debug (DEBUG_LABEL, "END");
 }
 
 /****************************************************************************/
-/* Get flip state of object.                                                */
+/* Set raw affine                                                           */
+/****************************************************************************/
+void
+gl_label_object_set_affine (glLabelObject *object,
+                           gdouble        affine[6])
+{
+       gl_debug (DEBUG_LABEL, "");
+
+       g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
+
+       object->private->affine[0] = affine[0];
+       object->private->affine[1] = affine[1];
+       object->private->affine[2] = affine[2];
+       object->private->affine[3] = affine[3];
+       object->private->affine[4] = affine[4];
+       object->private->affine[5] = affine[5];
+}
+
+/****************************************************************************/
+/* Get raw affine                                                           */
 /****************************************************************************/
-glLabelObjectFlip
-gl_label_object_get_flip (glLabelObject      *object)
+void
+gl_label_object_get_affine (glLabelObject *object,
+                           gdouble        affine[6])
 {
        gl_debug (DEBUG_LABEL, "");
 
        g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
 
-       return object->private->flip;
+       affine[0] = object->private->affine[0];
+       affine[1] = object->private->affine[1];
+       affine[2] = object->private->affine[2];
+       affine[3] = object->private->affine[3];
+       affine[4] = object->private->affine[4];
+       affine[5] = object->private->affine[5];
+}
+
+/****************************************************************************/
+/* Get applied affine, i.e. translated to center of object and back         */
+/****************************************************************************/
+void
+gl_label_object_get_applied_affine (glLabelObject *object,
+                                   gdouble        affine[6])
+{
+       gdouble to_center[6], to_origin[6];
+
+       gl_debug (DEBUG_LABEL, "");
+
+       g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
+
+       /* setup transformation affine */
+       art_affine_translate (to_center, -object->private->w/2.0, -object->private->h/2.0);
+       art_affine_multiply (affine, to_center, object->private->affine);
+       art_affine_translate (to_origin, object->private->w/2.0, object->private->h/2.0);
+       art_affine_multiply (affine, affine, to_origin);
 }
 
 /****************************************************************************/
index 0e7d4df872c2463022e33d76b0f5e81e214abf1c..fc008d9ec4e124db8344ac029169909d886fbf91 100644 (file)
@@ -38,13 +38,6 @@ typedef enum {
         GL_LABEL_OBJECT_N_TYPES
 } glLabelObjectType;
 
-typedef enum {
-       GL_LABEL_OBJECT_FLIP_NONE  = 0,
-       GL_LABEL_OBJECT_FLIP_HORIZ = 1,
-       GL_LABEL_OBJECT_FLIP_VERT  = 2,
-       GL_LABEL_OBJECT_FLIP_BOTH  = (GL_LABEL_OBJECT_FLIP_HORIZ|GL_LABEL_OBJECT_FLIP_VERT)
-} glLabelObjectFlip;
-
 
 #define GL_TYPE_LABEL_OBJECT            (gl_label_object_get_type ())
 #define GL_LABEL_OBJECT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GL_TYPE_LABEL_OBJECT, glLabelObject))
@@ -79,8 +72,6 @@ struct _glLabelObjectClass {
                             gpointer           user_data);
 
        void (*flip_rotate) (glLabelObject     *object,
-                            glLabelObjectFlip  flip,
-                            gdouble            rotate,
                             gpointer           user_data);
 
        void (*top)         (glLabelObject     *object,
@@ -92,48 +83,74 @@ struct _glLabelObjectClass {
 
 GType     gl_label_object_get_type              (void);
 
-GObject  *gl_label_object_new                   (glLabel       *label);
+GObject  *gl_label_object_new                   (glLabel           *label);
+
+
+void      gl_label_object_copy_props            (glLabelObject     *dst_object,
+                                                glLabelObject     *src_object);
+
+void      gl_label_object_emit_changed          (glLabelObject     *object);
+
+
+void      gl_label_object_set_parent            (glLabelObject     *object,
+                                                glLabel           *label);
+
+glLabel  *gl_label_object_get_parent            (glLabelObject     *object);
+
+
+void      gl_label_object_set_name              (glLabelObject     *object,
+                                                gchar             *name);
+
+gchar    *gl_label_object_get_name              (glLabelObject     *object);
+
+
+void      gl_label_object_set_position          (glLabelObject     *object,
+                                                gdouble            x,
+                                                gdouble            y);
+
+void      gl_label_object_set_position_relative (glLabelObject     *object,
+                                                gdouble            dx,
+                                                gdouble            dy);
+
+void      gl_label_object_get_position          (glLabelObject     *object,
+                                                gdouble           *x,
+                                                gdouble           *y);
+
+void      gl_label_object_set_size              (glLabelObject     *object,
+                                                gdouble            w,
+                                                gdouble            h);
+
+void      gl_label_object_get_size              (glLabelObject     *object,
+                                                gdouble           *w,
+                                                gdouble           *h);
+
+void      gl_label_object_get_extent            (glLabelObject     *object,
+                                                gdouble           *x1,
+                                                gdouble           *y1,
+                                                gdouble           *x2,
+                                                gdouble           *y2);
 
-void      gl_label_object_copy_props            (glLabelObject *dst_object,
-                                                glLabelObject *src_object);
 
-void      gl_label_object_emit_changed          (glLabelObject *object);
+void      gl_label_object_raise_to_top          (glLabelObject     *object);
 
-void      gl_label_object_set_parent            (glLabelObject *object,
-                                                glLabel       *label);
-glLabel  *gl_label_object_get_parent            (glLabelObject *object);
+void      gl_label_object_lower_to_bottom       (glLabelObject     *object);
 
-void      gl_label_object_set_name              (glLabelObject *object,
-                                                gchar         *name);
-gchar    *gl_label_object_get_name              (glLabelObject *object);
 
-void      gl_label_object_set_position          (glLabelObject *object,
-                                                gdouble         x,
-                                                gdouble         y);
-void      gl_label_object_set_position_relative (glLabelObject *object,
-                                                gdouble        dx,
-                                                gdouble        dy);
-void      gl_label_object_get_position          (glLabelObject *object,
-                                                gdouble       *x,
-                                                gdouble       *y);
-void      gl_label_object_set_size              (glLabelObject *object,
-                                                gdouble        w,
-                                                gdouble        h);
-void      gl_label_object_get_size              (glLabelObject *object,
-                                                gdouble       *w,
-                                                gdouble       *h);
+void      gl_label_object_flip_horiz            (glLabelObject     *object);
 
-void      gl_label_object_raise_to_top          (glLabelObject *object);
-void      gl_label_object_lower_to_bottom       (glLabelObject *object);
+void      gl_label_object_flip_vert             (glLabelObject     *object);
 
-void              gl_label_object_set_flip      (glLabelObject     *object,
-                                                glLabelObjectFlip  flip);
+void      gl_label_object_rotate                (glLabelObject     *object,
+                                                gdouble            theta_degs);
 
-void              gl_label_object_flip_horiz    (glLabelObject     *object);
+void      gl_label_object_set_affine            (glLabelObject     *object,
+                                                gdouble           affine[6]);
 
-void              gl_label_object_flip_vert     (glLabelObject     *object);
+void      gl_label_object_get_affine            (glLabelObject     *object,
+                                                gdouble           affine[6]);
 
-glLabelObjectFlip gl_label_object_get_flip      (glLabelObject     *object);
+void      gl_label_object_get_applied_affine    (glLabelObject     *object,
+                                                gdouble           affine[6]);
 
 G_END_DECLS
 
index b248b841717a568c91b0a677127770678a4a5712..fb7f36ee7f96104c54b4661dfdbb3e811ee8561b 100644 (file)
@@ -550,27 +550,18 @@ draw_object (PrintInfo     *pi,
             glLabelObject *object,
             glMergeRecord *record)
 {
-       gdouble x0, y0, w, h;
-       glLabelObjectFlip flip;
+       gdouble x0, y0;
+       gdouble affine[6];
 
        gl_debug (DEBUG_PRINT, "START");
 
        gl_label_object_get_position (object, &x0, &y0);
-       gl_label_object_get_size (object, &w, &h);
-       flip = gl_label_object_get_flip (object);
+       gl_label_object_get_applied_affine (object, affine);
 
        gnome_print_gsave (pi->pc);
 
        gnome_print_translate (pi->pc, x0, y0);
-
-       if ( flip & GL_LABEL_OBJECT_FLIP_HORIZ ) {
-               gnome_print_translate (pi->pc, w, 0.0);
-               gnome_print_scale (pi->pc, -1.0, 1.0);
-       }
-       if ( flip & GL_LABEL_OBJECT_FLIP_VERT ) {
-               gnome_print_translate (pi->pc, 0.0, h);
-               gnome_print_scale (pi->pc, 1.0, -1.0);
-       }
+       gnome_print_concat (pi->pc, affine);
 
        if (GL_IS_LABEL_TEXT(object)) {
                draw_text_object (pi, GL_LABEL_TEXT(object), record);
index e61f4db4ba9d94830067c7628793ba55d13050a9..4744f867500e7452bfdebda3a6a9742fe49a1429 100644 (file)
@@ -297,6 +297,42 @@ gl_tools_lower_objects (BonoboUIComponent *uic,
        }
 }
 
+/*****************************************************************************/
+/* Rotate objects left 90 degrees.                                           */
+/*****************************************************************************/
+void
+gl_tools_rotate_objects_left (BonoboUIComponent *uic,
+                             gpointer           user_data,
+                             const gchar       *verbname)
+
+{
+       glWindow *window;
+
+       window = GL_WINDOW (user_data);
+
+       if (window->view != NULL) {
+               gl_view_rotate_selection (GL_VIEW(window->view), -90.0);
+       }
+}
+
+/*****************************************************************************/
+/* Rotate objects right 90 degrees.                                          */
+/*****************************************************************************/
+void
+gl_tools_rotate_objects_right (BonoboUIComponent *uic,
+                              gpointer           user_data,
+                              const gchar       *verbname)
+
+{
+       glWindow *window;
+
+       window = GL_WINDOW (user_data);
+
+       if (window->view != NULL) {
+               gl_view_rotate_selection (GL_VIEW(window->view), 90.0);
+       }
+}
+
 /*****************************************************************************/
 /* Flip objects horizontally callback.                                       */
 /*****************************************************************************/
index 1794541745345195adcadac8a049cd5f4861fbb9..2c205cf4e26fc180331f1f26dc2e56df46eba654 100644 (file)
@@ -82,6 +82,14 @@ void gl_tools_lower_objects            (BonoboUIComponent *uic,
                                        gpointer           user_data,
                                        const gchar       *verbname);
 
+void gl_tools_rotate_objects_left      (BonoboUIComponent *uic,
+                                       gpointer           user_data,
+                                       const gchar       *verbname);
+
+void gl_tools_rotate_objects_right     (BonoboUIComponent *uic,
+                                       gpointer           user_data,
+                                       const gchar       *verbname);
+
 void gl_tools_flip_objects_horiz       (BonoboUIComponent *uic,
                                        gpointer           user_data,
                                        const gchar       *verbname);
index 831060ac9a954662d2096a584c975eeaf623c8bc..68e414ca2772e43a3397e965dd52b36095977925 100644 (file)
@@ -75,6 +75,8 @@ static BonoboUIVerb gl_ui_verbs [] = {
        BONOBO_UI_VERB ("ToolsObjectProperties", gl_tools_object_properties),
        BONOBO_UI_VERB ("ToolsRaiseObjects", gl_tools_raise_objects),
        BONOBO_UI_VERB ("ToolsLowerObjects", gl_tools_lower_objects),
+       BONOBO_UI_VERB ("ToolsRotateLeft", gl_tools_rotate_objects_left),
+       BONOBO_UI_VERB ("ToolsRotateRight", gl_tools_rotate_objects_right),
        BONOBO_UI_VERB ("ToolsFlipHorizontal", gl_tools_flip_objects_horiz),
        BONOBO_UI_VERB ("ToolsFlipVertical", gl_tools_flip_objects_vert),
        BONOBO_UI_VERB ("SettingsPreferences", gl_cmd_settings_preferences),
index 240ff60bc717571fe8527e95f4ce3e80f8ad459e..0bf05f15aa5291e3eb08c78b8ecccb8dadf8f6ed 100644 (file)
@@ -197,6 +197,7 @@ gl_view_highlight_new (glViewObject         *view_object,
                       glViewHighlightStyle  style)
 {
        glViewHighlight *view_highlight;
+       gdouble          affine[6];
 
        gl_debug (DEBUG_VIEW, "START");
 
@@ -226,6 +227,10 @@ gl_view_highlight_new (glViewObject         *view_object,
 
        }
 
+
+       gl_label_object_get_applied_affine (view_highlight->private->object, affine);
+       gnome_canvas_item_affine_absolute (view_highlight->private->group, affine);
+
        g_signal_connect (G_OBJECT (view_highlight->private->object), "changed",
                          G_CALLBACK (object_changed_cb), view_highlight);
 
@@ -783,8 +788,8 @@ tl_resize_event_handler (GnomeCanvasItem *handle_item,
                         GdkEvent        *event,
                         glViewHighlight *view_highlight)
 {
-       gdouble x, y, w, h;
-       static gdouble x2, y2;
+       gdouble x0, y0, w, h;
+       gdouble x1, y1, x2, y2;
        static gboolean dragging = FALSE;
        glLabelObject *object;
        GdkCursor *cursor;
@@ -795,8 +800,18 @@ tl_resize_event_handler (GnomeCanvasItem *handle_item,
        }
 
        object = view_highlight->private->object;;
-       gl_label_object_get_position (object, &x, &y);
-       gl_label_object_get_size (object, &w, &h);
+
+       /* origin, relative to item */
+       gl_label_object_get_position (object, &x0, &y0);
+       gnome_canvas_item_w2i (view_highlight->private->group, &x0, &y0);
+
+       /* Top left corner, relative to item */
+       x1 = 0.0;
+       y1 = 0.0;
+
+       /* Bottom right corner, relative to item */
+       gl_label_object_get_size (object, &x2, &y2);
+
 
        switch (event->type) {
 
@@ -809,9 +824,6 @@ tl_resize_event_handler (GnomeCanvasItem *handle_item,
                                                GDK_BUTTON_RELEASE_MASK |
                                                GDK_BUTTON_PRESS_MASK,
                                                NULL, event->button.time);
-                       /* Anchor to bottom-right corner */
-                       x2 = x + w;
-                       y2 = y + h;
                        return TRUE;
 
                default:
@@ -824,11 +836,16 @@ tl_resize_event_handler (GnomeCanvasItem *handle_item,
                        dragging = FALSE;
                        gnome_canvas_item_ungrab (handle_item,
                                                  event->button.time);
-                       x = MIN (event->button.x, x2 - MIN_ITEM_SIZE);
-                       y = MIN (event->button.y, y2 - MIN_ITEM_SIZE);
+                       gnome_canvas_item_w2i (view_highlight->private->group,
+                                              &event->button.x, &event->button.y);
+                       x1 = MIN (event->button.x, x2 - MIN_ITEM_SIZE);
+                       y1 = MIN (event->button.y, y2 - MIN_ITEM_SIZE);
                        w = MAX (x2 - event->button.x, MIN_ITEM_SIZE);
                        h = MAX (y2 - event->button.y, MIN_ITEM_SIZE);
-                       gl_label_object_set_position (object, x, y);
+                       x0 = x0 + x1;
+                       y0 = y0 + y1;
+                       gnome_canvas_item_i2w (view_highlight->private->group, &x0, &y0);
+                       gl_label_object_set_position (object, x0, y0);
                        gl_label_object_set_size (object, w, h);
                        return TRUE;
 
@@ -838,11 +855,16 @@ tl_resize_event_handler (GnomeCanvasItem *handle_item,
 
        case GDK_MOTION_NOTIFY:
                if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
-                       x = MIN (event->motion.x, x2 - MIN_ITEM_SIZE);
-                       y = MIN (event->motion.y, y2 - MIN_ITEM_SIZE);
+                       gnome_canvas_item_w2i (view_highlight->private->group,
+                                              &event->button.x, &event->button.y);
+                       x1 = MIN (event->motion.x, x2 - MIN_ITEM_SIZE);
+                       y1 = MIN (event->motion.y, y2 - MIN_ITEM_SIZE);
                        w = MAX (x2 - event->motion.x, MIN_ITEM_SIZE);
                        h = MAX (y2 - event->motion.y, MIN_ITEM_SIZE);
-                       gl_label_object_set_position (object, x, y);
+                       x0 = x0 + x1;
+                       y0 = y0 + y1;
+                       gnome_canvas_item_i2w (view_highlight->private->group, &x0, &y0);
+                       gl_label_object_set_position (object, x0, y0);
                        gl_label_object_set_size (object, w, h);
                        return TRUE;
                } else {
@@ -877,8 +899,8 @@ tr_resize_event_handler (GnomeCanvasItem *handle_item,
                         GdkEvent        *event,
                         glViewHighlight *view_highlight)
 {
-       gdouble x, y, w, h;
-       static gdouble x1, y2;
+       gdouble x0, y0, w, h;
+       gdouble x1, y1, x2, y2;
        static gboolean dragging = FALSE;
        glLabelObject *object;
        GdkCursor *cursor;
@@ -889,8 +911,18 @@ tr_resize_event_handler (GnomeCanvasItem *handle_item,
        }
 
        object = view_highlight->private->object;;
-       gl_label_object_get_position (object, &x, &y);
-       gl_label_object_get_size (object, &w, &h);
+
+       /* origin, relative to item */
+       gl_label_object_get_position (object, &x0, &y0);
+       gnome_canvas_item_w2i (view_highlight->private->group, &x0, &y0);
+
+       /* Top left corner, relative to item */
+       x1 = 0.0;
+       y1 = 0.0;
+
+       /* Bottom right corner, relative to item */
+       gl_label_object_get_size (object, &x2, &y2);
+
 
        switch (event->type) {
 
@@ -903,9 +935,6 @@ tr_resize_event_handler (GnomeCanvasItem *handle_item,
                                                GDK_BUTTON_RELEASE_MASK |
                                                GDK_BUTTON_PRESS_MASK,
                                                NULL, event->button.time);
-                       /* Anchor to bottom-left corner */
-                       x1 = x;
-                       y2 = y + h;
                        return TRUE;
 
                default:
@@ -918,11 +947,16 @@ tr_resize_event_handler (GnomeCanvasItem *handle_item,
                        dragging = FALSE;
                        gnome_canvas_item_ungrab (handle_item,
                                                  event->button.time);
-                       x = x1;
-                       y = MIN (event->button.y, y2 - MIN_ITEM_SIZE);
+                       gnome_canvas_item_w2i (view_highlight->private->group,
+                                              &event->button.x, &event->button.y);
+                       /* x1 unchanged */
+                       y1 = MIN (event->button.y, y2 - MIN_ITEM_SIZE);
                        w = MAX (event->button.x - x1, MIN_ITEM_SIZE);
                        h = MAX (y2 - event->button.y, MIN_ITEM_SIZE);
-                       gl_label_object_set_position (object, x, y);
+                       x0 = x0 + x1;
+                       y0 = y0 + y1;
+                       gnome_canvas_item_i2w (view_highlight->private->group, &x0, &y0);
+                       gl_label_object_set_position (object, x0, y0);
                        gl_label_object_set_size (object, w, h);
                        return TRUE;
 
@@ -932,11 +966,16 @@ tr_resize_event_handler (GnomeCanvasItem *handle_item,
 
        case GDK_MOTION_NOTIFY:
                if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
-                       x = x1;
-                       y = MIN (event->motion.y, y2 - MIN_ITEM_SIZE);
-                       w = MAX (event->motion.x - x1, MIN_ITEM_SIZE);
-                       h = MAX (y2 - event->motion.y, MIN_ITEM_SIZE);
-                       gl_label_object_set_position (object, x, y);
+                       gnome_canvas_item_w2i (view_highlight->private->group,
+                                              &event->button.x, &event->button.y);
+                       /* x1 unchanged */
+                       y1 = MIN (event->button.y, y2 - MIN_ITEM_SIZE);
+                       w = MAX (event->button.x - x1, MIN_ITEM_SIZE);
+                       h = MAX (y2 - event->button.y, MIN_ITEM_SIZE);
+                       x0 = x0 + x1;
+                       y0 = y0 + y1;
+                       gnome_canvas_item_i2w (view_highlight->private->group, &x0, &y0);
+                       gl_label_object_set_position (object, x0, y0);
                        gl_label_object_set_size (object, w, h);
                        return TRUE;
                } else {
@@ -971,8 +1010,8 @@ bl_resize_event_handler (GnomeCanvasItem *handle_item,
                         GdkEvent        *event,
                         glViewHighlight *view_highlight)
 {
-       gdouble x, y, w, h;
-       static gdouble x2, y1;
+       gdouble x0, y0, w, h;
+       gdouble x1, y1, x2, y2;
        static gboolean dragging = FALSE;
        glLabelObject *object;
        GdkCursor *cursor;
@@ -983,8 +1022,18 @@ bl_resize_event_handler (GnomeCanvasItem *handle_item,
        }
 
        object = view_highlight->private->object;;
-       gl_label_object_get_position (object, &x, &y);
-       gl_label_object_get_size (object, &w, &h);
+
+       /* origin, relative to item */
+       gl_label_object_get_position (object, &x0, &y0);
+       gnome_canvas_item_w2i (view_highlight->private->group, &x0, &y0);
+
+       /* Top left corner, relative to item */
+       x1 = 0.0;
+       y1 = 0.0;
+
+       /* Bottom right corner, relative to item */
+       gl_label_object_get_size (object, &x2, &y2);
+
 
        switch (event->type) {
 
@@ -997,9 +1046,6 @@ bl_resize_event_handler (GnomeCanvasItem *handle_item,
                                                GDK_BUTTON_RELEASE_MASK |
                                                GDK_BUTTON_PRESS_MASK,
                                                NULL, event->button.time);
-                       /* Anchor to top-right corner */
-                       x2 = x + w;
-                       y1 = y;
                        return TRUE;
 
                default:
@@ -1012,11 +1058,16 @@ bl_resize_event_handler (GnomeCanvasItem *handle_item,
                        dragging = FALSE;
                        gnome_canvas_item_ungrab (handle_item,
                                                  event->button.time);
-                       x = MIN (event->button.x, x2 - MIN_ITEM_SIZE);
-                       y = y1;
+                       gnome_canvas_item_w2i (view_highlight->private->group,
+                                              &event->button.x, &event->button.y);
+                       x1 = MIN (event->button.x, x2 - MIN_ITEM_SIZE);
+                       /* y1 unchanged */
                        w = MAX (x2 - event->button.x, MIN_ITEM_SIZE);
-                       h = MAX (event->button.y - y1, MIN_ITEM_SIZE);
-                       gl_label_object_set_position (object, x, y);
+                       h = MAX (event->button.y - x1, MIN_ITEM_SIZE);
+                       x0 = x0 + x1;
+                       y0 = y0 + y1;
+                       gnome_canvas_item_i2w (view_highlight->private->group, &x0, &y0);
+                       gl_label_object_set_position (object, x0, y0);
                        gl_label_object_set_size (object, w, h);
                        return TRUE;
 
@@ -1026,11 +1077,16 @@ bl_resize_event_handler (GnomeCanvasItem *handle_item,
 
        case GDK_MOTION_NOTIFY:
                if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
-                       x = MIN (event->motion.x, x2 - MIN_ITEM_SIZE);
-                       y = y1;
-                       w = MAX (x2 - event->motion.x, MIN_ITEM_SIZE);
-                       h = MAX (event->motion.y - y1, MIN_ITEM_SIZE);
-                       gl_label_object_set_position (object, x, y);
+                       gnome_canvas_item_w2i (view_highlight->private->group,
+                                              &event->button.x, &event->button.y);
+                       x1 = MIN (event->button.x, x2 - MIN_ITEM_SIZE);
+                       /* y1 unchanged */
+                       w = MAX (x2 - event->button.x, MIN_ITEM_SIZE);
+                       h = MAX (event->button.y - x1, MIN_ITEM_SIZE);
+                       x0 = x0 + x1;
+                       y0 = y0 + y1;
+                       gnome_canvas_item_i2w (view_highlight->private->group, &x0, &y0);
+                       gl_label_object_set_position (object, x0, y0);
                        gl_label_object_set_size (object, w, h);
                        return TRUE;
                } else {
@@ -1065,8 +1121,8 @@ br_resize_event_handler (GnomeCanvasItem *handle_item,
                         GdkEvent        *event,
                         glViewHighlight *view_highlight)
 {
-       gdouble x, y, w, h;
-       static gdouble x1, y1;
+       gdouble x0, y0, w, h;
+       gdouble x1, y1, x2, y2;
        static gboolean dragging = FALSE;
        glLabelObject *object;
        GdkCursor *cursor;
@@ -1077,8 +1133,18 @@ br_resize_event_handler (GnomeCanvasItem *handle_item,
        }
 
        object = view_highlight->private->object;;
-       gl_label_object_get_position (object, &x, &y);
-       gl_label_object_get_size (object, &w, &h);
+
+       /* origin, relative to item */
+       gl_label_object_get_position (object, &x0, &y0);
+       gnome_canvas_item_w2i (view_highlight->private->group, &x0, &y0);
+
+       /* Top left corner, relative to item */
+       x1 = 0.0;
+       y1 = 0.0;
+
+       /* Bottom right corner, relative to item */
+       gl_label_object_get_size (object, &x2, &y2);
+
 
        switch (event->type) {
 
@@ -1092,9 +1158,6 @@ br_resize_event_handler (GnomeCanvasItem *handle_item,
                                                GDK_BUTTON_RELEASE_MASK |
                                                GDK_BUTTON_PRESS_MASK,
                                                NULL, event->button.time);
-                       /* Anchor to top-left corner */
-                       x1 = x;
-                       y1 = y;
                        return TRUE;
 
                default:
@@ -1108,11 +1171,16 @@ br_resize_event_handler (GnomeCanvasItem *handle_item,
                        dragging = FALSE;
                        gnome_canvas_item_ungrab (handle_item,
                                                  event->button.time);
-                       x = x1;
-                       y = y1;
+                       gnome_canvas_item_w2i (view_highlight->private->group,
+                                              &event->button.x, &event->button.y);
+                       /* x1 unchanged */
+                       /* y1 unchanged */
                        w = MAX (event->button.x - x1, MIN_ITEM_SIZE);
-                       h = MAX (event->button.y - y1, MIN_ITEM_SIZE);
-                       gl_label_object_set_position (object, x, y);
+                       h = MAX (event->button.y - x1, MIN_ITEM_SIZE);
+                       x0 = x0 + x1;
+                       y0 = y0 + y1;
+                       gnome_canvas_item_i2w (view_highlight->private->group, &x0, &y0);
+                       gl_label_object_set_position (object, x0, y0);
                        gl_label_object_set_size (object, w, h);
                        return TRUE;
 
@@ -1123,11 +1191,16 @@ br_resize_event_handler (GnomeCanvasItem *handle_item,
        case GDK_MOTION_NOTIFY:
                gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
                if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
-                       x = x1;
-                       y = y1;
-                       w = MAX (event->motion.x - x1, MIN_ITEM_SIZE);
-                       h = MAX (event->motion.y - y1, MIN_ITEM_SIZE);
-                       gl_label_object_set_position (object, x, y);
+                       gnome_canvas_item_w2i (view_highlight->private->group,
+                                              &event->button.x, &event->button.y);
+                       /* x1 unchanged */
+                       /* y1 unchanged */
+                       w = MAX (event->button.x - x1, MIN_ITEM_SIZE);
+                       h = MAX (event->button.y - x1, MIN_ITEM_SIZE);
+                       x0 = x0 + x1;
+                       y0 = y0 + y1;
+                       gnome_canvas_item_i2w (view_highlight->private->group, &x0, &y0);
+                       gl_label_object_set_position (object, x0, y0);
                        gl_label_object_set_size (object, w, h);
                        return TRUE;
                } else {
@@ -1165,8 +1238,8 @@ sl_resize_event_handler (GnomeCanvasItem *handle_item,
                         GdkEvent        *event,
                         glViewHighlight *view_highlight)
 {
-       gdouble x, y, w, h;
-       static gdouble x2;
+       gdouble x0, y0, w, h;
+       gdouble x1, y1, x2, y2;
        static gboolean dragging = FALSE;
        glLabelObject *object;
        GdkCursor *cursor;
@@ -1177,8 +1250,18 @@ sl_resize_event_handler (GnomeCanvasItem *handle_item,
        }
 
        object = view_highlight->private->object;;
-       gl_label_object_get_position (object, &x, &y);
-       gl_label_object_get_size (object, &w, &h);
+
+       /* origin, relative to item */
+       gl_label_object_get_position (object, &x0, &y0);
+       gnome_canvas_item_w2i (view_highlight->private->group, &x0, &y0);
+
+       /* Top left corner, relative to item */
+       x1 = 0.0;
+       y1 = 0.0;
+
+       /* Bottom right corner, relative to item */
+       gl_label_object_get_size (object, &x2, &y2);
+
 
        switch (event->type) {
 
@@ -1191,8 +1274,6 @@ sl_resize_event_handler (GnomeCanvasItem *handle_item,
                                                GDK_BUTTON_RELEASE_MASK |
                                                GDK_BUTTON_PRESS_MASK,
                                                NULL, event->button.time);
-                       /* Anchor to right side */
-                       x2 = x + w;
                        return TRUE;
 
                default:
@@ -1205,9 +1286,16 @@ sl_resize_event_handler (GnomeCanvasItem *handle_item,
                        dragging = FALSE;
                        gnome_canvas_item_ungrab (handle_item,
                                                  event->button.time);
-                       x = MIN (event->button.x, x2 - MIN_ITEM_SIZE);
+                       gnome_canvas_item_w2i (view_highlight->private->group,
+                                              &event->button.x, &event->button.y);
+                       x1 = MIN (event->button.x, x2 - MIN_ITEM_SIZE);
+                       /* y1 unchanged */
                        w = MAX (x2 - event->button.x, MIN_ITEM_SIZE);
-                       gl_label_object_set_position (object, x, y);
+                       h = y2 - y1;
+                       x0 = x0 + x1;
+                       y0 = y0 + y1;
+                       gnome_canvas_item_i2w (view_highlight->private->group, &x0, &y0);
+                       gl_label_object_set_position (object, x0, y0);
                        gl_label_object_set_size (object, w, h);
                        return TRUE;
 
@@ -1217,9 +1305,16 @@ sl_resize_event_handler (GnomeCanvasItem *handle_item,
 
        case GDK_MOTION_NOTIFY:
                if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
-                       x = MIN (event->motion.x, x2 - MIN_ITEM_SIZE);
-                       w = MAX (x2 - event->motion.x, MIN_ITEM_SIZE);
-                       gl_label_object_set_position (object, x, y);
+                       gnome_canvas_item_w2i (view_highlight->private->group,
+                                              &event->button.x, &event->button.y);
+                       x1 = MIN (event->button.x, x2 - MIN_ITEM_SIZE);
+                       /* y1 unchanged */
+                       w = MAX (x2 - event->button.x, MIN_ITEM_SIZE);
+                       h = y2 - y1;
+                       x0 = x0 + x1;
+                       y0 = y0 + y1;
+                       gnome_canvas_item_i2w (view_highlight->private->group, &x0, &y0);
+                       gl_label_object_set_position (object, x0, y0);
                        gl_label_object_set_size (object, w, h);
                        return TRUE;
                } else {
@@ -1254,8 +1349,8 @@ sr_resize_event_handler (GnomeCanvasItem *handle_item,
                         GdkEvent        *event,
                         glViewHighlight *view_highlight)
 {
-       gdouble x, y, w, h;
-       static gdouble x1;
+       gdouble x0, y0, w, h;
+       gdouble x1, y1, x2, y2;
        static gboolean dragging = FALSE;
        glLabelObject *object;
        GdkCursor *cursor;
@@ -1266,8 +1361,18 @@ sr_resize_event_handler (GnomeCanvasItem *handle_item,
        }
 
        object = view_highlight->private->object;;
-       gl_label_object_get_position (object, &x, &y);
-       gl_label_object_get_size (object, &w, &h);
+
+       /* origin, relative to item */
+       gl_label_object_get_position (object, &x0, &y0);
+       gnome_canvas_item_w2i (view_highlight->private->group, &x0, &y0);
+
+       /* Top left corner, relative to item */
+       x1 = 0.0;
+       y1 = 0.0;
+
+       /* Bottom right corner, relative to item */
+       gl_label_object_get_size (object, &x2, &y2);
+
 
        switch (event->type) {
 
@@ -1280,8 +1385,6 @@ sr_resize_event_handler (GnomeCanvasItem *handle_item,
                                                GDK_BUTTON_RELEASE_MASK |
                                                GDK_BUTTON_PRESS_MASK,
                                                NULL, event->button.time);
-                       /* Anchor to left side */
-                       x1 = x;
                        return TRUE;
 
                default:
@@ -1294,9 +1397,16 @@ sr_resize_event_handler (GnomeCanvasItem *handle_item,
                        dragging = FALSE;
                        gnome_canvas_item_ungrab (handle_item,
                                                  event->button.time);
-                       x = x1;
+                       gnome_canvas_item_w2i (view_highlight->private->group,
+                                              &event->button.x, &event->button.y);
+                       /* x1 unchanged */
+                       /* y1 unchanged */
                        w = MAX (event->button.x - x1, MIN_ITEM_SIZE);
-                       gl_label_object_set_position (object, x, y);
+                       h = y2 - y1;
+                       x0 = x0 + x1;
+                       y0 = y0 + y1;
+                       gnome_canvas_item_i2w (view_highlight->private->group, &x0, &y0);
+                       gl_label_object_set_position (object, x0, y0);
                        gl_label_object_set_size (object, w, h);
                        return TRUE;
 
@@ -1306,9 +1416,16 @@ sr_resize_event_handler (GnomeCanvasItem *handle_item,
 
        case GDK_MOTION_NOTIFY:
                if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
-                       x = x1;
-                       w = MAX (event->motion.x - x1, MIN_ITEM_SIZE);
-                       gl_label_object_set_position (object, x, y);
+                       gnome_canvas_item_w2i (view_highlight->private->group,
+                                              &event->button.x, &event->button.y);
+                       /* x1 unchanged */
+                       /* y1 unchanged */
+                       w = MAX (event->button.x - x1, MIN_ITEM_SIZE);
+                       h = y2 - y1;
+                       x0 = x0 + x1;
+                       y0 = y0 + y1;
+                       gnome_canvas_item_i2w (view_highlight->private->group, &x0, &y0);
+                       gl_label_object_set_position (object, x0, y0);
                        gl_label_object_set_size (object, w, h);
                        return TRUE;
                } else {
@@ -1343,8 +1460,8 @@ st_resize_event_handler (GnomeCanvasItem *handle_item,
                         GdkEvent        *event,
                         glViewHighlight *view_highlight)
 {
-       gdouble x, y, w, h;
-       static gdouble y2;
+       gdouble x0, y0, w, h;
+       gdouble x1, y1, x2, y2;
        static gboolean dragging = FALSE;
        glLabelObject *object;
        GdkCursor *cursor;
@@ -1355,8 +1472,18 @@ st_resize_event_handler (GnomeCanvasItem *handle_item,
        }
 
        object = view_highlight->private->object;;
-       gl_label_object_get_position (object, &x, &y);
-       gl_label_object_get_size (object, &w, &h);
+
+       /* origin, relative to item */
+       gl_label_object_get_position (object, &x0, &y0);
+       gnome_canvas_item_w2i (view_highlight->private->group, &x0, &y0);
+
+       /* Top left corner, relative to item */
+       x1 = 0.0;
+       y1 = 0.0;
+
+       /* Bottom right corner, relative to item */
+       gl_label_object_get_size (object, &x2, &y2);
+
 
        switch (event->type) {
 
@@ -1369,8 +1496,6 @@ st_resize_event_handler (GnomeCanvasItem *handle_item,
                                                GDK_BUTTON_RELEASE_MASK |
                                                GDK_BUTTON_PRESS_MASK,
                                                NULL, event->button.time);
-                       /* Anchor to bottom-right corner */
-                       y2 = y + h;
                        return TRUE;
 
                default:
@@ -1383,9 +1508,16 @@ st_resize_event_handler (GnomeCanvasItem *handle_item,
                        dragging = FALSE;
                        gnome_canvas_item_ungrab (handle_item,
                                                  event->button.time);
-                       y = MIN (event->button.y, y2 - MIN_ITEM_SIZE);
+                       gnome_canvas_item_w2i (view_highlight->private->group,
+                                              &event->button.x, &event->button.y);
+                       /* x1 unchanged */
+                       y1 = MIN (event->button.y, y2 - MIN_ITEM_SIZE);
+                       w = x2 - x1;
                        h = MAX (y2 - event->button.y, MIN_ITEM_SIZE);
-                       gl_label_object_set_position (object, x, y);
+                       x0 = x0 + x1;
+                       y0 = y0 + y1;
+                       gnome_canvas_item_i2w (view_highlight->private->group, &x0, &y0);
+                       gl_label_object_set_position (object, x0, y0);
                        gl_label_object_set_size (object, w, h);
                        return TRUE;
 
@@ -1395,9 +1527,16 @@ st_resize_event_handler (GnomeCanvasItem *handle_item,
 
        case GDK_MOTION_NOTIFY:
                if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
-                       y = MIN (event->motion.y, y2 - MIN_ITEM_SIZE);
-                       h = MAX (y2 - event->motion.y, MIN_ITEM_SIZE);
-                       gl_label_object_set_position (object, x, y);
+                       gnome_canvas_item_w2i (view_highlight->private->group,
+                                              &event->button.x, &event->button.y);
+                       /* x1 unchanged */
+                       y1 = MIN (event->button.y, y2 - MIN_ITEM_SIZE);
+                       w = x2 - x1;
+                       h = MAX (y2 - event->button.y, MIN_ITEM_SIZE);
+                       x0 = x0 + x1;
+                       y0 = y0 + y1;
+                       gnome_canvas_item_i2w (view_highlight->private->group, &x0, &y0);
+                       gl_label_object_set_position (object, x0, y0);
                        gl_label_object_set_size (object, w, h);
                        return TRUE;
                } else {
@@ -1432,8 +1571,8 @@ sb_resize_event_handler (GnomeCanvasItem *handle_item,
                         GdkEvent        *event,
                         glViewHighlight *view_highlight)
 {
-       gdouble x, y, w, h;
-       static gdouble y1;
+       gdouble x0, y0, w, h;
+       gdouble x1, y1, x2, y2;
        static gboolean dragging = FALSE;
        glLabelObject *object;
        GdkCursor *cursor;
@@ -1444,8 +1583,18 @@ sb_resize_event_handler (GnomeCanvasItem *handle_item,
        }
 
        object = view_highlight->private->object;;
-       gl_label_object_get_position (object, &x, &y);
-       gl_label_object_get_size (object, &w, &h);
+
+       /* origin, relative to item */
+       gl_label_object_get_position (object, &x0, &y0);
+       gnome_canvas_item_w2i (view_highlight->private->group, &x0, &y0);
+
+       /* Top left corner, relative to item */
+       x1 = 0.0;
+       y1 = 0.0;
+
+       /* Bottom right corner, relative to item */
+       gl_label_object_get_size (object, &x2, &y2);
+
 
        switch (event->type) {
 
@@ -1458,8 +1607,6 @@ sb_resize_event_handler (GnomeCanvasItem *handle_item,
                                                GDK_BUTTON_RELEASE_MASK |
                                                GDK_BUTTON_PRESS_MASK,
                                                NULL, event->button.time);
-                       /* Anchor to top side */
-                       y1 = y;
                        return TRUE;
 
                default:
@@ -1472,9 +1619,16 @@ sb_resize_event_handler (GnomeCanvasItem *handle_item,
                        dragging = FALSE;
                        gnome_canvas_item_ungrab (handle_item,
                                                  event->button.time);
-                       y = y1;
-                       h = MAX (event->button.y - y1, MIN_ITEM_SIZE);
-                       gl_label_object_set_position (object, x, y);
+                       gnome_canvas_item_w2i (view_highlight->private->group,
+                                              &event->button.x, &event->button.y);
+                       /* x1 unchanged */
+                       /* y1 unchanged */
+                       w = x2 - x1;
+                       h = MAX (event->button.y - x1, MIN_ITEM_SIZE);
+                       x0 = x0 + x1;
+                       y0 = y0 + y1;
+                       gnome_canvas_item_i2w (view_highlight->private->group, &x0, &y0);
+                       gl_label_object_set_position (object, x0, y0);
                        gl_label_object_set_size (object, w, h);
                        return TRUE;
 
@@ -1484,9 +1638,16 @@ sb_resize_event_handler (GnomeCanvasItem *handle_item,
 
        case GDK_MOTION_NOTIFY:
                if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
-                       y = y1;
-                       h = MAX (event->motion.y - y1, MIN_ITEM_SIZE);
-                       gl_label_object_set_position (object, x, y);
+                       gnome_canvas_item_w2i (view_highlight->private->group,
+                                              &event->button.x, &event->button.y);
+                       /* x1 unchanged */
+                       /* y1 unchanged */
+                       w = x2 - x1;
+                       h = MAX (event->button.y - x1, MIN_ITEM_SIZE);
+                       x0 = x0 + x1;
+                       y0 = y0 + y1;
+                       gnome_canvas_item_i2w (view_highlight->private->group, &x0, &y0);
+                       gl_label_object_set_position (object, x0, y0);
                        gl_label_object_set_size (object, w, h);
                        return TRUE;
                } else {
@@ -1521,8 +1682,8 @@ p1_resize_event_handler (GnomeCanvasItem *handle_item,
                         GdkEvent        *event,
                         glViewHighlight *view_highlight)
 {
-       gdouble x, y, dx, dy;
-       static gdouble x0, y0;
+       gdouble x0, y0, dx, dy;
+       gdouble x1, y1, x2, y2;
        static gboolean dragging = FALSE;
        glLabelObject *object;
        GdkCursor *cursor;
@@ -1533,8 +1694,18 @@ p1_resize_event_handler (GnomeCanvasItem *handle_item,
        }
 
        object = view_highlight->private->object;;
-       gl_label_object_get_position (object, &x, &y);
-       gl_label_object_get_size (object, &dx, &dy);
+
+       /* origin, relative to item */
+       gl_label_object_get_position (object, &x0, &y0);
+       gnome_canvas_item_w2i (view_highlight->private->group, &x0, &y0);
+
+       /* Top left corner, relative to item */
+       x1 = 0.0;
+       y1 = 0.0;
+
+       /* Bottom right corner, relative to item */
+       gl_label_object_get_size (object, &x2, &y2);
+
 
        switch (event->type) {
 
@@ -1547,9 +1718,6 @@ p1_resize_event_handler (GnomeCanvasItem *handle_item,
                                                GDK_BUTTON_RELEASE_MASK |
                                                GDK_BUTTON_PRESS_MASK,
                                                NULL, event->button.time);
-                       /* Anchor to P2 */
-                       x0 = x + dx;
-                       y0 = y + dy;
                        return TRUE;
 
                default:
@@ -1562,11 +1730,16 @@ p1_resize_event_handler (GnomeCanvasItem *handle_item,
                        dragging = FALSE;
                        gnome_canvas_item_ungrab (handle_item,
                                                  event->button.time);
-                       x = x0;
-                       y = y0;
-                       dx = (event->button.x - x0);
-                       dy = (event->button.y - y0);
-                       gl_label_object_set_position (object, x, y);
+                       gnome_canvas_item_w2i (view_highlight->private->group,
+                                              &event->button.x, &event->button.y);
+                       x1 = event->button.x;
+                       y1 = event->button.y;
+                       dx = (x2 - event->button.x);
+                       dy = (y2 - event->button.y);
+                       x0 = x0 + x1;
+                       y0 = y0 + y1;
+                       gnome_canvas_item_i2w (view_highlight->private->group, &x0, &y0);
+                       gl_label_object_set_position (object, x0, y0);
                        gl_label_object_set_size (object, dx, dy);
                        return TRUE;
 
@@ -1576,11 +1749,16 @@ p1_resize_event_handler (GnomeCanvasItem *handle_item,
 
        case GDK_MOTION_NOTIFY:
                if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
-                       x = x0;
-                       y = y0;
-                       dx = (event->motion.x - x0);
-                       dy = (event->motion.y - y0);
-                       gl_label_object_set_position (object, x, y);
+                       gnome_canvas_item_w2i (view_highlight->private->group,
+                                              &event->button.x, &event->button.y);
+                       x1 = event->button.x;
+                       y1 = event->button.y;
+                       dx = (x2 - event->button.x);
+                       dy = (y2 - event->button.y);
+                       x0 = x0 + x1;
+                       y0 = y0 + y1;
+                       gnome_canvas_item_i2w (view_highlight->private->group, &x0, &y0);
+                       gl_label_object_set_position (object, x0, y0);
                        gl_label_object_set_size (object, dx, dy);
                        return TRUE;
                } else {
@@ -1615,8 +1793,8 @@ p2_resize_event_handler (GnomeCanvasItem *handle_item,
                         GdkEvent        *event,
                         glViewHighlight *view_highlight)
 {
-       gdouble x, y, dx, dy;
-       static gdouble x0, y0;
+       gdouble x0, y0, dx, dy;
+       gdouble x1, y1, x2, y2;
        static gboolean dragging = FALSE;
        glLabelObject *object;
        GdkCursor *cursor;
@@ -1627,8 +1805,18 @@ p2_resize_event_handler (GnomeCanvasItem *handle_item,
        }
 
        object = view_highlight->private->object;;
-       gl_label_object_get_position (object, &x, &y);
-       gl_label_object_get_size (object, &dx, &dy);
+
+       /* origin, relative to item */
+       gl_label_object_get_position (object, &x0, &y0);
+       gnome_canvas_item_w2i (view_highlight->private->group, &x0, &y0);
+
+       /* Top left corner, relative to item */
+       x1 = 0.0;
+       y1 = 0.0;
+
+       /* Bottom right corner, relative to item */
+       gl_label_object_get_size (object, &x2, &y2);
+
 
        switch (event->type) {
 
@@ -1641,9 +1829,6 @@ p2_resize_event_handler (GnomeCanvasItem *handle_item,
                                                GDK_BUTTON_RELEASE_MASK |
                                                GDK_BUTTON_PRESS_MASK,
                                                NULL, event->button.time);
-                       /* Anchor to P1 */
-                       x0 = x;
-                       y0 = y;
                        return TRUE;
 
                default:
@@ -1656,11 +1841,16 @@ p2_resize_event_handler (GnomeCanvasItem *handle_item,
                        dragging = FALSE;
                        gnome_canvas_item_ungrab (handle_item,
                                                  event->button.time);
-                       x = x0;
-                       y = y0;
-                       dx = (event->button.x - x0);
-                       dy = (event->button.y - y0);
-                       gl_label_object_set_position (object, x, y);
+                       gnome_canvas_item_w2i (view_highlight->private->group,
+                                              &event->button.x, &event->button.y);
+                       /* x1 unchanged */
+                       /* y1 unchanged */
+                       dx = (event->button.x - x1);
+                       dy = (event->button.y - x1);
+                       x0 = x0 + x1;
+                       y0 = y0 + y1;
+                       gnome_canvas_item_i2w (view_highlight->private->group, &x0, &y0);
+                       gl_label_object_set_position (object, x0, y0);
                        gl_label_object_set_size (object, dx, dy);
                        return TRUE;
 
@@ -1670,11 +1860,16 @@ p2_resize_event_handler (GnomeCanvasItem *handle_item,
 
        case GDK_MOTION_NOTIFY:
                if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
-                       x = x0;
-                       y = y0;
-                       dx = (event->motion.x - x0);
-                       dy = (event->motion.y - y0);
-                       gl_label_object_set_position (object, x, y);
+                       gnome_canvas_item_w2i (view_highlight->private->group,
+                                              &event->button.x, &event->button.y);
+                       /* x1 unchanged */
+                       /* y1 unchanged */
+                       dx = (event->button.x - x1);
+                       dy = (event->button.y - x1);
+                       x0 = x0 + x1;
+                       y0 = y0 + y1;
+                       gnome_canvas_item_i2w (view_highlight->private->group, &x0, &y0);
+                       gl_label_object_set_position (object, x0, y0);
                        gl_label_object_set_size (object, dx, dy);
                        return TRUE;
                } else {
index 3e0ab89d79d53e3b6bf62b691284355b61958334..1317b73a3db275ec9aa445968d917c070c4f55b2 100644 (file)
@@ -39,8 +39,6 @@ struct _glViewObjectPrivate {
        GnomeCanvasItem            *group;
        glViewHighlight            *highlight;
 
-       gdouble                    affine[6];
-
        GtkWidget                  *menu;
        GtkWidget                  *property_dialog;
 
@@ -69,15 +67,13 @@ static void     object_moved_cb              (glLabelObject       *object,
                                              gdouble              y,
                                              glViewObject        *view_object);
 
-static void     raise_object_cb              (GtkWidget           *widget,
+static void     raise_object_cb              (glLabelObject       *object,
                                              glViewObject        *view_object);
 
-static void     lower_object_cb              (GtkWidget           *widget,
+static void     lower_object_cb              (glLabelObject       *object,
                                              glViewObject        *view_object);
 
-static void     flip_rotate_object_cb        (GtkWidget           *widget,
-                                             glLabelObjectFlip    flip,
-                                             gdouble              rotate_degs,
+static void     flip_rotate_object_cb        (glLabelObject       *object,
                                              glViewObject        *view_object);
 
 
@@ -209,8 +205,6 @@ gl_view_object_set_object     (glViewObject         *view_object,
        GnomeCanvas        *canvas;
        GnomeCanvasGroup   *root;
        gdouble            x, y, w, h;
-       glLabelObjectFlip  flip;
-       gdouble            a[6];
 
        gl_debug (DEBUG_VIEW, "START");
 
@@ -230,30 +224,6 @@ gl_view_object_set_object     (glViewObject         *view_object,
                                       "y", y,
                                       NULL);
 
-       /* create affine to handle flipping and rotation transformations */
-       art_affine_identity (view_object->private->affine);
-#if 1
-       /* Apply appropriate flipping */
-       flip = gl_label_object_get_flip (object);
-       g_print ("Flip = %d\n", flip);
-       if ( flip & GL_LABEL_OBJECT_FLIP_HORIZ ) {
-               art_affine_translate (a, -w, 0.0);
-               art_affine_multiply (view_object->private->affine,
-                                    view_object->private->affine, a);
-               art_affine_scale (a, -1.0, 1.0);
-               art_affine_multiply (view_object->private->affine,
-                                    view_object->private->affine, a);
-       }
-       if ( flip & GL_LABEL_OBJECT_FLIP_VERT ) {
-               art_affine_translate (a, 0.0, -h);
-               art_affine_multiply (view_object->private->affine,
-                                    view_object->private->affine, a);
-               art_affine_scale (a, 1.0, -1.0);
-               art_affine_multiply (view_object->private->affine,
-                                    view_object->private->affine, a);
-       }
-#endif
-
        /* Create appropriate selection highlight canvas item. */
        view_object->private->highlight =
                GL_VIEW_HIGHLIGHT (gl_view_highlight_new (view_object, style));
@@ -358,6 +328,7 @@ gl_view_object_item_new (glViewObject *view_object,
 {
        GnomeCanvasItem *item;
        va_list          args;
+       gdouble          affine[6];
 
        gl_debug (DEBUG_VIEW, "START");
 
@@ -370,17 +341,8 @@ gl_view_object_item_new (glViewObject *view_object,
         gnome_canvas_item_set_valist (item, first_arg_name, args);
         va_end (args);
 
-       g_print ("Affine = {%f, %f, %f, %f, %f, %f}\n",
-                view_object->private->affine[0],
-                view_object->private->affine[1],
-                view_object->private->affine[2],
-                view_object->private->affine[3],
-                view_object->private->affine[4],
-                view_object->private->affine[5]);
-
-#if 1
-       gnome_canvas_item_affine_absolute (item, view_object->private->affine);
-#endif
+       gl_label_object_get_applied_affine (view_object->private->object, affine);
+       gnome_canvas_item_affine_absolute (item, affine);
 
        gl_debug (DEBUG_VIEW, "END");
 
@@ -557,11 +519,9 @@ object_moved_cb (glLabelObject *object,
 /* PRIVATE.  raise item to front callback.                                   */
 /*---------------------------------------------------------------------------*/
 static void
-raise_object_cb (GtkWidget    *widget,
-                glViewObject *view_object)
+raise_object_cb (glLabelObject *object,
+                glViewObject  *view_object)
 {
-       glLabelObject *object;
-
        gl_debug (DEBUG_VIEW, "START");
 
        /* send to top */
@@ -577,11 +537,9 @@ raise_object_cb (GtkWidget    *widget,
 /* PRIVATE.  lower item to back callback.                                    */
 /*---------------------------------------------------------------------------*/
 static void
-lower_object_cb (GtkWidget    *widget,
-                glViewObject *view_object)
+lower_object_cb (glLabelObject *object,
+                glViewObject  *view_object)
 {
-       glLabelObject *object;
-
        gl_debug (DEBUG_VIEW, "START");
 
        /* Send to bottom */
@@ -599,49 +557,22 @@ lower_object_cb (GtkWidget    *widget,
 /* PRIVATE.  Flip/rotate object callback.                                    */
 /*---------------------------------------------------------------------------*/
 static void
-flip_rotate_object_cb (GtkWidget         *widget,
-                      glLabelObjectFlip  flip,
-                      gdouble            rotate_degs,
-                      glViewObject      *view_object)
+flip_rotate_object_cb (glLabelObject *object,
+                      glViewObject  *view_object)
 {
-       glLabelObject   *object;
-       gdouble          a[6];
+       gdouble          affine[6];
        gdouble          w, h;
        GList           *p, *item_list;
        GnomeCanvasItem *item;
 
        gl_debug (DEBUG_VIEW, "START");
 
-       gl_label_object_get_size (view_object->private->object, &w, &h);
-
-       /* Reset to identity affine */
-       art_affine_identity (view_object->private->affine);
-
-       /* Apply appropriate flipping */
-       if ( flip & GL_LABEL_OBJECT_FLIP_HORIZ ) {
-               art_affine_translate (a, -w, 0.0);
-               art_affine_multiply (view_object->private->affine, view_object->private->affine, a);
-               art_affine_scale (a, -1.0, 1.0);
-               art_affine_multiply (view_object->private->affine,
-                                    view_object->private->affine, a);
-       }
-       if ( flip & GL_LABEL_OBJECT_FLIP_VERT ) {
-               art_affine_translate (a, 0.0, -h);
-               art_affine_multiply (view_object->private->affine,
-                                    view_object->private->affine, a);
-               art_affine_scale (a, 1.0, -1.0);
-               art_affine_multiply (view_object->private->affine,
-                                    view_object->private->affine, a);
-       }
-
-#if 1
-       /* Apply newly constructed affine */
+       gl_label_object_get_applied_affine (object, affine);
        item_list = GNOME_CANVAS_GROUP(view_object->private->group)->item_list;
-       for ( p=item_list; p != NULL; p=p->next) {
+       for ( p=item_list; p != NULL; p=p->next ) {
                item = GNOME_CANVAS_ITEM(p->data);
-               gnome_canvas_item_affine_absolute (item, view_object->private->affine);
+               gnome_canvas_item_affine_absolute (item, affine);
        }
-#endif
 
        gl_debug (DEBUG_VIEW, "END");
 }
index fc24a7d8df829d27d2d07cf7b9f8448a73a652ad..846706cb3a1c90ae589a265b407fc11deb07409f 100644 (file)
@@ -1401,7 +1401,7 @@ gl_view_select_region (glView  *view,
        GList *p;
        glViewObject *view_object;
        glLabelObject *object;
-       gdouble i_x1, i_y1, i_x2, i_y2, w, h;
+       gdouble i_x1, i_y1, i_x2, i_y2;
 
        gl_debug (DEBUG_VIEW, "START");
 
@@ -1414,10 +1414,7 @@ gl_view_select_region (glView  *view,
 
                        object = gl_view_object_get_object (view_object);
 
-                       gl_label_object_get_position (object, &i_x1, &i_y1);
-                       gl_label_object_get_size (object, &w, &h);
-                       i_x2 = i_x1 + w;
-                       i_y2 = i_y1 + h;
+                       gl_label_object_get_extent (object, &i_x1, &i_y1, &i_x2, &i_y2);
                        if ((i_x1 >= x1) && (i_x2 <= x2) && (i_y1 >= y1)
                            && (i_y2 <= y2)) {
                                select_object_real (view, view_object);
@@ -1662,6 +1659,30 @@ gl_view_lower_selection (glView *view)
        gl_debug (DEBUG_VIEW, "END");
 }
 
+/*****************************************************************************/
+/* Rotate selected objects by given angle.                                   */
+/*****************************************************************************/
+void
+gl_view_rotate_selection (glView *view,
+                         gdouble theta_degs)
+{
+       GList *p;
+       glViewObject *view_object;
+       glLabelObject *label_object;
+
+       gl_debug (DEBUG_VIEW, "START");
+
+       g_return_if_fail (GL_IS_VIEW (view));
+
+       for (p = view->selected_object_list; p != NULL; p = p->next) {
+               view_object = GL_VIEW_OBJECT (p->data);
+               label_object = gl_view_object_get_object (view_object);
+               gl_label_object_rotate (label_object, theta_degs);
+       }
+
+       gl_debug (DEBUG_VIEW, "END");
+}
+
 /*****************************************************************************/
 /* Flip selected objects horizontally.                                       */
 /*****************************************************************************/
@@ -2077,12 +2098,11 @@ canvas_event_arrow_mode (GnomeCanvas *canvas,
                                }
 
                                dragging = TRUE;
-                               gdk_pointer_grab (GTK_WIDGET (view->canvas)->
-                                                 window, FALSE,
-                                                 GDK_POINTER_MOTION_MASK |
-                                                 GDK_BUTTON_RELEASE_MASK |
-                                                 GDK_BUTTON_PRESS_MASK, NULL,
-                                                 NULL, event->button.time);
+                               gnome_canvas_item_grab (canvas->root,
+                                                       GDK_POINTER_MOTION_MASK |
+                                                       GDK_BUTTON_RELEASE_MASK |
+                                                       GDK_BUTTON_PRESS_MASK,
+                                                       NULL, event->button.time);
                                group =
                                    gnome_canvas_root (GNOME_CANVAS
                                                       (view->canvas));
@@ -2113,7 +2133,8 @@ canvas_event_arrow_mode (GnomeCanvas *canvas,
                case 1:
                        if (dragging) {
                                dragging = FALSE;
-                               gdk_pointer_ungrab (event->button.time);
+                               gnome_canvas_item_ungrab (canvas->root,
+                                                         event->button.time);
                                gnome_canvas_window_to_world (canvas,
                                                              event->button.x,
                                                              event->button.y,
index 812e651ab7520f84b7c56eb0fc02a5b87bd036cf..45778d382cf8e7e6460c05a9f29859ee8c370d06 100644 (file)
@@ -150,6 +150,9 @@ void       gl_view_raise_selection         (glView            *view);
 
 void       gl_view_lower_selection         (glView            *view);
 
+void       gl_view_rotate_selection        (glView            *view,
+                                           gdouble            theta_degs);
+
 void       gl_view_flip_selection_horiz    (glView            *view);
 
 void       gl_view_flip_selection_vert     (glView            *view);
index 16c23732e60962c26b98c372f6e4d2862554b8eb..a9472e218a52cb4205a45fca8506c3a1030ba77b 100644 (file)
@@ -294,9 +294,9 @@ xml_parse_object (xmlNodePtr object_node,
                  glLabel * label)
 {
        glLabelObject *object;
-       gdouble x, y;
-       gchar *type_string;
-       gchar *flip_string;
+       gdouble        x, y;
+       gchar         *type_string;
+       gdouble        affine[6];
 
        gl_debug (DEBUG_XML, "START");
 
@@ -324,19 +324,14 @@ xml_parse_object (xmlNodePtr object_node,
 
        gl_label_object_set_position (object, x, y);
 
-       flip_string = xmlGetProp (object_node, "flip");
-       if ( g_strcasecmp (flip_string, "None") == 0 ) {
-               gl_label_object_set_flip (object, GL_LABEL_OBJECT_FLIP_NONE);
-       } else if ( g_strcasecmp (flip_string, "Horiz") == 0 ) {
-               gl_label_object_set_flip (object, GL_LABEL_OBJECT_FLIP_HORIZ);
-       } else if ( g_strcasecmp (flip_string, "Vert") == 0 ) {
-               gl_label_object_set_flip (object, GL_LABEL_OBJECT_FLIP_VERT);
-       } else if ( g_strcasecmp (flip_string, "Both") == 0 ) {
-               gl_label_object_set_flip (object, GL_LABEL_OBJECT_FLIP_BOTH);
-       } else {
-               g_warning ("Unknown flip type \"%s\"", flip_string);
-               return;
-       }
+       affine[0] = g_strtod (xmlGetProp (object_node, "a0"), NULL);
+       affine[1] = g_strtod (xmlGetProp (object_node, "a1"), NULL);
+       affine[2] = g_strtod (xmlGetProp (object_node, "a2"), NULL);
+       affine[3] = g_strtod (xmlGetProp (object_node, "a3"), NULL);
+       affine[4] = g_strtod (xmlGetProp (object_node, "a4"), NULL);
+       affine[5] = g_strtod (xmlGetProp (object_node, "a5"), NULL);
+
+       gl_label_object_set_affine (object, affine);
 
        gl_debug (DEBUG_XML, "END");
 }
@@ -782,9 +777,10 @@ xml_create_object (xmlNodePtr root,
                   xmlNsPtr ns,
                   glLabelObject * object)
 {
-       xmlNodePtr object_node;
-       gdouble x, y;
-       gchar *string;
+       xmlNodePtr  object_node;
+       gdouble     x, y;
+       gchar      *string;
+       gdouble     affine[6];
 
        gl_debug (DEBUG_XML, "START");
 
@@ -798,24 +794,25 @@ xml_create_object (xmlNodePtr root,
        xmlSetProp (object_node, "y", string);
        g_free (string);
 
-       xmlSetProp (object_node, "rotate", "0");
-
-       switch (gl_label_object_get_flip (object)) {
-       case GL_LABEL_OBJECT_FLIP_NONE:
-               xmlSetProp (object_node, "flip",   "None");
-               break;
-       case GL_LABEL_OBJECT_FLIP_HORIZ:
-               xmlSetProp (object_node, "flip",   "Horiz");
-               break;
-       case GL_LABEL_OBJECT_FLIP_VERT:
-               xmlSetProp (object_node, "flip",   "Vert");
-               break;
-       case GL_LABEL_OBJECT_FLIP_BOTH:
-               xmlSetProp (object_node, "flip",   "Both");
-               break;
-       default:
-               g_assert_not_reached ();
-       }
+       gl_label_object_get_affine (object, affine);
+       string = g_strdup_printf ("%g", affine[0]);
+       xmlSetProp (object_node, "a0", string);
+       g_free (string);
+       string = g_strdup_printf ("%g", affine[1]);
+       xmlSetProp (object_node, "a1", string);
+       g_free (string);
+       string = g_strdup_printf ("%g", affine[2]);
+       xmlSetProp (object_node, "a2", string);
+       g_free (string);
+       string = g_strdup_printf ("%g", affine[3]);
+       xmlSetProp (object_node, "a3", string);
+       g_free (string);
+       string = g_strdup_printf ("%g", affine[4]);
+       xmlSetProp (object_node, "a4", string);
+       g_free (string);
+       string = g_strdup_printf ("%g", affine[5]);
+       xmlSetProp (object_node, "a5", string);
+       g_free (string);
 
        if ( GL_IS_LABEL_TEXT(object) ) {
                xml_create_text_props (object_node, ns, object);