Code

use rotation center in keyboard rotation and transform dialog
authorbuliabyak <buliabyak@users.sourceforge.net>
Wed, 22 Mar 2006 23:41:24 +0000 (23:41 +0000)
committerbuliabyak <buliabyak@users.sourceforge.net>
Wed, 22 Mar 2006 23:41:24 +0000 (23:41 +0000)
src/selection-chemistry.cpp
src/selection.cpp
src/selection.h
src/seltrans.cpp
src/sp-item-transform.cpp
src/ui/dialog/transformation.cpp

index e7e3ec4a35e25436ccbfc7001efc85d8d52909ec..851fc3a3bf9780828aceef86cafe852a00bcd538 100644 (file)
@@ -1450,7 +1450,7 @@ sp_selection_rotate(Inkscape::Selection *selection, gdouble const angle_degrees)
     if (selection->isEmpty())
         return;
 
-    NR::Point const center(selection->bounds().midpoint());
+    NR::Point center = selection->center();
 
     sp_selection_rotate_relative(selection, center, angle_degrees);
 
@@ -1470,7 +1470,8 @@ sp_selection_rotate_screen(Inkscape::Selection *selection, gdouble angle)
         return;
 
     NR::Rect const bbox(selection->bounds());
-    NR::Point const center(bbox.midpoint());
+
+    NR::Point center = selection->center();
 
     gdouble const zoom = selection->desktop()->current_zoom();
     gdouble const zmove = angle / zoom;
index 763713c9d86923e0242f6399429fb41f01d77313..473a7202e594e1eecabcac3e1b9067774d7a64c9 100644 (file)
@@ -339,6 +339,23 @@ NR::Rect Selection::boundsInDocument() const {
     return NR::Rect(*boundsInDocument(&r));
 }
 
+/** Extract the position of the center from the first selected object */
+NR::Point Selection::center() const {
+    GSList *items = (GSList *) const_cast<Selection *>(this)->itemList();
+    NR::Point center;
+    if (items) {
+        SPItem *first = reinterpret_cast<SPItem*>(g_slist_last(items)->data); // from the first item in selection
+        if (first->isCenterSet()) { // only if set explicitly
+            center = first->getCenter();
+        } else {
+            center = bounds().midpoint();
+        }
+    } else {
+        center = bounds().midpoint();
+    }
+    return center;
+}
+
 /**
  * Compute the list of points in the selection that are to be considered for snapping.
  */
index 6996e3ec8684f36e6b4ab7426cda65004e933859..6d403c426986c084be840f32dc751b237d3a16ff 100644 (file)
@@ -241,6 +241,11 @@ public:
      */
     ::NR::Rect boundsInDocument() const;
 
+    /**
+     * @brief Returns the rotation/skew center of the selection
+     */
+    ::NR::Point center() const;
+
     /**
      * @brief Gets the selection's snap points.
      * @return Selection's snap points
index 1d4557b903fa60e7bad1e0b7780ce3ba0a9a5cb7..b41ee1d5c6374399c4552c7c69ac600d4a131b19 100644 (file)
@@ -480,18 +480,7 @@ void Inkscape::SelTrans::_updateHandles()
     }
 
     if (!_center_is_set) {
-        // Extract the position of the center from the first selected object
-        GSList *items = (GSList *) _desktop->selection->itemList();
-        if (items) {
-            SPItem *first = reinterpret_cast<SPItem*>(g_slist_last(items)->data); // from the first item in selection
-            if (first->isCenterSet()) { // only if set explicitly
-                _center =  first->getCenter();
-            } else {
-                _center = _box.midpoint();
-            }
-        } else {
-            _center = _box.midpoint();
-        }
+        _center = _desktop->selection->center();
         _center_is_set = true;
     }
 
index beefc7640d98659fe292272062f24778d369b390..c2b1a2648f288d8ec4d5f230e3dfd4638157ca4c 100644 (file)
@@ -28,20 +28,25 @@ static NR::translate inverse(NR::translate const m)
 void
 sp_item_rotate_rel(SPItem *item, NR::rotate const &rotation)
 {
-       NR::translate const s(sp_item_bbox_desktop(item).midpoint());
-
-       // Rotate item.
-       sp_item_set_i2d_affine(item,
-                              sp_item_i2d_affine(item) * inverse(s) * rotation * s);
-
-       // Use each item's own transform writer, consistent with sp_selection_apply_affine()
-       sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform);
+    NR::Point center = item->getCenter();
+    NR::translate const s(item->getCenter());
+    NR::Matrix affine = NR::Matrix(inverse(s)) * NR::Matrix(rotation) * NR::Matrix(s);
+
+    // Rotate item.
+    sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * affine);
+    // Use each item's own transform writer, consistent with sp_selection_apply_affine()
+    sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform);
+
+    // Restore the center position (it's changed because the bbox center changed)
+    if (item->isCenterSet()) {
+        item->setCenter(center * affine);
+    }
 }
 
 void
 sp_item_scale_rel (SPItem *item, NR::scale const &scale)
 {
-       NR::translate const s(sp_item_bbox_desktop(item).midpoint());
+    NR::translate const s(sp_item_bbox_desktop(item).midpoint()); // use getCenter?
 
        sp_item_set_i2d_affine(item,
                               sp_item_i2d_affine(item) * inverse(s) * scale * s);
@@ -51,15 +56,19 @@ sp_item_scale_rel (SPItem *item, NR::scale const &scale)
 void
 sp_item_skew_rel (SPItem *item, double skewX, double skewY)
 {
-       NR::Rect bbox(sp_item_bbox_desktop(item));
+    NR::Point center = item->getCenter();
+    NR::translate const s(item->getCenter());
 
-       NR::translate const s(bbox.midpoint());
+    NR::Matrix const skew(1, skewY, skewX, 1, 0, 0);
+    NR::Matrix affine = NR::Matrix(inverse(s)) * skew * NR::Matrix(s);
 
-       NR::Matrix const skew(1, skewY, skewX, 1, 0, 0);
+    sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * affine);
+    sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform);
 
-       sp_item_set_i2d_affine(item,
-                              sp_item_i2d_affine(item) * inverse(s) * skew * s);
-       sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform);
+    // Restore the center position (it's changed because the bbox center changed)
+    if (item->isCenterSet()) {
+        item->setCenter(center * affine);
+    }
 }
 
 void sp_item_move_rel(SPItem *item, NR::translate const &tr)
index 6056e4a2e3043853692d50402f0513d3726ec4dc..92baa7b810ee028c923508948bf40e8386b4ff0b 100644 (file)
@@ -613,7 +613,7 @@ Transformation::applyPageScale(Inkscape::Selection *selection)
         }
     } else {
         NR::Rect  bbox(selection->bounds());
-        NR::Point center(bbox.midpoint());
+        NR::Point center(bbox.midpoint()); // use rotation center?
         NR::scale scale (0,0);
         // the values are increments!
         if (_units_scale.isAbsolute()) {
@@ -646,13 +646,11 @@ Transformation::applyPageRotate(Inkscape::Selection *selection)
             sp_item_rotate_rel(item, NR::rotate (angle*M_PI/180.0));
         }
     } else {
-        NR::Rect  bbox   = selection->bounds();
-        NR::Point center = bbox.midpoint();
+        NR::Point center = selection->center();
         sp_selection_rotate_relative(selection, center, angle);
     }
 
     sp_document_done(SP_DT_DOCUMENT(selection->desktop()));
-
 }
 
 void
@@ -685,7 +683,7 @@ Transformation::applyPageSkew(Inkscape::Selection *selection)
         NR::Rect bbox = selection->bounds();
         double width  = bbox.max()[NR::X] - bbox.min()[NR::X];
         double height = bbox.max()[NR::Y] - bbox.min()[NR::Y];
-        NR::Point center = bbox.midpoint();
+        NR::Point center = selection->center();
 
         if (!_units_skew.isAbsolute()) { // percentage
             double skewX = _scalar_skew_horizontal.getValue("%");