Code

Fix self-snapping when dragging the transformation center of a selection containing...
[inkscape.git] / src / selection.cpp
index 7b936587c343513760684927f30be54e7179f00b..3f333e4e24e4569904b7dc90a41c42bc0c5c86fd 100644 (file)
@@ -406,6 +406,8 @@ Geom::OptRect Selection::boundsInDocument(SPItem::BBoxType type) const {
 }
 
 /** Extract the position of the center from the first selected object */
+// If we have a selection of multiple items, then the center of the first item
+// will be returned; this is also the case in SelTrans::centerRequest()
 boost::optional<Geom::Point> Selection::center() const {
     GSList *items = (GSList *) const_cast<Selection *>(this)->itemList();
     Geom::Point center;
@@ -424,50 +426,56 @@ boost::optional<Geom::Point> Selection::center() const {
 }
 
 /**
- * Compute the list of points in the selection that are to be considered for snapping.
+ * Compute the list of points in the selection that are to be considered for snapping from.
  */
-std::vector<std::pair<Geom::Point, int> > Selection::getSnapPoints(SnapPreferences const *snapprefs) const {
+std::vector<Inkscape::SnapCandidatePoint> Selection::getSnapPoints(SnapPreferences const *snapprefs) const {
     GSList const *items = const_cast<Selection *>(this)->itemList();
 
     SnapPreferences snapprefs_dummy = *snapprefs; // create a local copy of the snapping prefs
     snapprefs_dummy.setIncludeItemCenter(false); // locally disable snapping to the item center
-
-    std::vector<std::pair<Geom::Point, int> > p;
+    snapprefs_dummy.setSnapToItemNode(true); // consider any type of nodes as a snap source
+    snapprefs_dummy.setSnapSmoothNodes(true); // i.e. disregard the smooth / cusp node preference
+    std::vector<Inkscape::SnapCandidatePoint> p;
     for (GSList const *iter = items; iter != NULL; iter = iter->next) {
         SPItem *this_item = SP_ITEM(iter->data);
-        sp_item_snappoints(this_item, false, p, &snapprefs_dummy);
+        sp_item_snappoints(this_item, p, &snapprefs_dummy);
 
         //Include the transformation origin for snapping
         //For a selection or group only the overall origin is considered
         if (snapprefs != NULL && snapprefs->getIncludeItemCenter()) {
-            p.push_back(std::make_pair(this_item->getCenter(), SNAPSOURCE_ROTATION_CENTER));
+            p.push_back(Inkscape::SnapCandidatePoint(this_item->getCenter(), SNAPSOURCE_ROTATION_CENTER));
         }
     }
 
     return p;
 }
-
-std::vector<std::pair<Geom::Point, int> > Selection::getSnapPointsConvexHull(SnapPreferences const *snapprefs) const {
+// TODO: both getSnapPoints and getSnapPointsConvexHull are called, subsequently. Can we do this more efficient?
+// Why do we need to include the transformation center in one case and not the other?
+std::vector<Inkscape::SnapCandidatePoint> Selection::getSnapPointsConvexHull(SnapPreferences const *snapprefs) const {
     GSList const *items = const_cast<Selection *>(this)->itemList();
 
-    std::vector<std::pair<Geom::Point, int> > p;
+    SnapPreferences snapprefs_dummy = *snapprefs; // create a local copy of the snapping prefs
+    snapprefs_dummy.setSnapToItemNode(true); // consider any type of nodes as a snap source
+    snapprefs_dummy.setSnapSmoothNodes(true); // i.e. disregard the smooth / cusp node preference
+
+    std::vector<Inkscape::SnapCandidatePoint> p;
     for (GSList const *iter = items; iter != NULL; iter = iter->next) {
-        sp_item_snappoints(SP_ITEM(iter->data), false, p, snapprefs);
+        sp_item_snappoints(SP_ITEM(iter->data), p, &snapprefs_dummy);
     }
 
-    std::vector<std::pair<Geom::Point, int> > pHull;
+    std::vector<Inkscape::SnapCandidatePoint> pHull;
     if (!p.empty()) {
-        std::vector<std::pair<Geom::Point, int> >::iterator i;
-        Geom::RectHull cvh((p.front()).first);
+        std::vector<Inkscape::SnapCandidatePoint>::iterator i;
+        Geom::RectHull cvh((p.front()).getPoint());
         for (i = p.begin(); i != p.end(); i++) {
             // these are the points we get back
-            cvh.add((*i).first);
+            cvh.add((*i).getPoint());
         }
 
         Geom::OptRect rHull = cvh.bounds();
         if (rHull) {
             for ( unsigned i = 0 ; i < 4 ; ++i ) {
-                pHull.push_back(std::make_pair(rHull->corner(i), SNAPSOURCE_CONVEX_HULL_CORNER));
+                pHull.push_back(Inkscape::SnapCandidatePoint(rHull->corner(i), SNAPSOURCE_CONVEX_HULL_CORNER));
             }
         }
     }