summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 3fb170a)
raw | patch | inline | side by side (parent: 3fb170a)
author | Diederik van Lierop <mailat-signdiedenrezidotnl> | |
Sat, 24 Jul 2010 12:37:50 +0000 (14:37 +0200) | ||
committer | Diederik van Lierop <mailat-signdiedenrezidotnl> | |
Sat, 24 Jul 2010 12:37:50 +0000 (14:37 +0200) |
diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp
index ef5dcc7d0f3bb395ad33a075c0538c5dbf3a7e85..c1ed08f12f7610b7d0004001078ddcad98423f58 100644 (file)
--- a/src/object-snapper.cpp
+++ b/src/object-snapper.cpp
@@ -228,11 +228,17 @@ void Inkscape::ObjectSnapper::_collectNodes(Inkscape::SnapSourceType const &t,
_snapmanager->snapprefs.setSnapIntersectionCS(false);
}
+ bool old_pref2 = _snapmanager->snapprefs.getIncludeItemCenter();
+ if ((*i).item == _snapmanager->getRotationCenterSource()) {
+ // don't snap to this item's rotation center
+ _snapmanager->snapprefs.setIncludeItemCenter(false);
+ }
+
sp_item_snappoints(root_item, *_points_to_snap_to, &_snapmanager->snapprefs);
- if (_snapmanager->snapprefs.getSnapToItemPath()) {
- _snapmanager->snapprefs.setSnapIntersectionCS(old_pref);
- }
+ // restore the original snap preferences
+ _snapmanager->snapprefs.setSnapIntersectionCS(old_pref);
+ _snapmanager->snapprefs.setIncludeItemCenter(old_pref2);
}
//Collect the bounding box's corners so we can snap to them
diff --git a/src/selection.cpp b/src/selection.cpp
index 96c66e0c506496ec96ac1b8f99e425fb103a66e0..3f333e4e24e4569904b7dc90a41c42bc0c5c86fd 100644 (file)
--- a/src/selection.cpp
+++ b/src/selection.cpp
}
/** 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;
diff --git a/src/seltrans.cpp b/src/seltrans.cpp
index b9bf4c6ce8a9efc280fa1bfb35758e6a8dcae283..764c222a8fe67ba1ea04496e54dfd92002761a8f 100644 (file)
--- a/src/seltrans.cpp
+++ b/src/seltrans.cpp
@@ -883,7 +883,11 @@ gboolean Inkscape::SelTrans::handleRequest(SPKnot *knot, Geom::Point *position,
if (handle.request(this, handle, *position, state)) {
sp_knot_set_position(knot, *position, state);
SP_CTRL(_grip)->moveto(*position);
- SP_CTRL(_norm)->moveto(_origin);
+ if (&handle == &handle_center) {
+ SP_CTRL(_norm)->moveto(*position);
+ } else {
+ SP_CTRL(_norm)->moveto(_origin);
+ }
}
return TRUE;
{
SnapManager &m = _desktop->namedview->snap_manager;
m.setup(_desktop);
- m.freeSnapReturnByRef(pt, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+
+ // Center is being dragged for the first item in the selection only
+ // Find out which item is first ...
+ GSList *items = (GSList *) const_cast<Selection *>(_selection)->itemList();
+ SPItem *first = NULL;
+ if (items) {
+ first = reinterpret_cast<SPItem*>(g_slist_last(items)->data); // from the first item in selection
+ }
+ // ... and store that item because later on we need to make sure that
+ // this transformation center won't snap to itself
+ m.setRotationCenterSource(first);
+ m.freeSnapReturnByRef(pt, Inkscape::SNAPSOURCE_ROTATION_CENTER);
if (state & GDK_CONTROL_MASK) {
if ( fabs(_point[Geom::X] - pt[Geom::X]) > fabs(_point[Geom::Y] - pt[Geom::Y]) ) {
diff --git a/src/snap.cpp b/src/snap.cpp
index ccbd449bd4c461a5757a3323975f28b764d6baa2..fc8837c4315328c892a7b7c8e57a029d36b4e9d5 100644 (file)
--- a/src/snap.cpp
+++ b/src/snap.cpp
_snapindicator = snapindicator;
_unselected_nodes = unselected_nodes;
_guide_to_ignore = guide_to_ignore;
+ _rotation_center_source_item = NULL;
}
/**
_snapindicator = snapindicator;
_unselected_nodes = unselected_nodes;
_guide_to_ignore = guide_to_ignore;
+ _rotation_center_source_item = NULL;
}
/// Setup, taking the list of items to ignore from the desktop's selection.
_snapindicator = snapindicator;
_unselected_nodes = unselected_nodes;
_guide_to_ignore = guide_to_ignore;
+ _rotation_center_source_item = NULL;
_items_to_ignore.clear();
Inkscape::Selection *sel = _desktop->selection;
diff --git a/src/snap.h b/src/snap.h
index 26e599cc66773aae66edc20c39b6d8cb682a922b..f740f3c62b900d93a12f1194c3e31a8308e697e4 100644 (file)
--- a/src/snap.h
+++ b/src/snap.h
std::vector<SPItem const *> &items_to_ignore,
std::vector<Inkscape::SnapCandidatePoint> *unselected_nodes = NULL,
SPGuide *guide_to_ignore = NULL);
+
void setupIgnoreSelection(SPDesktop const *desktop,
bool snapindicator = true,
std::vector<Inkscape::SnapCandidatePoint> *unselected_nodes = NULL,
SPGuide *guide_to_ignore = NULL);
+ // If we're dragging a rotation center, then setRotationCenterSource() stores the parent item
+ // of this rotation center; this reference is used to make sure that we do not snap a rotation
+ // center to itself
+ // NOTE: Must be called after calling setup(), not before!
+ void setRotationCenterSource(SPItem *item) {_rotation_center_source_item = item;}
+ SPItem* getRotationCenterSource() {return _rotation_center_source_item;}
+
// freeSnapReturnByRef() is preferred over freeSnap(), because it only returns a
// point if snapping has occurred (by overwriting p); otherwise p is untouched
void freeSnapReturnByRef(Geom::Point &p,
private:
std::vector<SPItem const *> _items_to_ignore; ///< Items that should not be snapped to, for example the items that are currently being dragged. Set using the setup() method
+ SPItem *_rotation_center_source_item; // to avoid snapping a rotation center to itself
SPGuide *_guide_to_ignore; ///< A guide that should not be snapped to, e.g. the guide that is currently being dragged
SPDesktop const *_desktop;
bool _snapindicator; ///< When true, an indicator will be drawn at the position that was being snapped to
diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp
index 0038908bfd19f6bc869d0aad951a176c9f69761f..b64ad45e0773f5fafbfda24c5bf2b5efcc1304e7 100644 (file)
--- a/src/sp-shape.cpp
+++ b/src/sp-shape.cpp
@@ -1208,57 +1208,57 @@ static void sp_shape_snappoints(SPItem const *item, std::vector<Inkscape::SnapCa
for(Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) {
if (snapprefs->getSnapToItemNode()) {
- // Add the first point of the path
- p.push_back(Inkscape::SnapCandidatePoint(path_it->initialPoint() * i2d, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP));
+ // Add the first point of the path
+ p.push_back(Inkscape::SnapCandidatePoint(path_it->initialPoint() * i2d, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP));
}
Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve
Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve
while (curve_it1 != path_it->end_default())
{
- // For each path: consider midpoints of line segments for snapping
- if (snapprefs->getSnapLineMidpoints()) { // only do this when we're snapping nodes (enforces strict snapping)
- if (Geom::LineSegment const* line_segment = dynamic_cast<Geom::LineSegment const*>(&(*curve_it1))) {
- p.push_back(Inkscape::SnapCandidatePoint(Geom::middle_point(*line_segment) * i2d, Inkscape::SNAPSOURCE_LINE_MIDPOINT, Inkscape::SNAPTARGET_LINE_MIDPOINT));
- }
- }
-
- if (curve_it2 == path_it->end_default()) { // Test will only pass for the last iteration of the while loop
- if (snapprefs->getSnapToItemNode() && !path_it->closed()) {
- // Add the last point of the path, but only for open paths
- // (for closed paths the first and last point will coincide)
- p.push_back(Inkscape::SnapCandidatePoint((*curve_it1).finalPoint() * i2d, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP));
- }
- } else {
- /* Test whether to add the node between curve_it1 and curve_it2.
- * Loop to end_default (so only iterating through the stroked part); */
-
- Geom::NodeType nodetype = Geom::get_nodetype(*curve_it1, *curve_it2);
-
- bool c1 = snapprefs->getSnapToItemNode() && (nodetype == Geom::NODE_CUSP || nodetype == Geom::NODE_NONE);
- bool c2 = snapprefs->getSnapSmoothNodes() && (nodetype == Geom::NODE_SMOOTH || nodetype == Geom::NODE_SYMM);
-
- if (c1 || c2) {
- Inkscape::SnapSourceType sst;
- Inkscape::SnapTargetType stt;
- switch (nodetype) {
- case Geom::NODE_CUSP:
- sst = Inkscape::SNAPSOURCE_NODE_CUSP;
- stt = Inkscape::SNAPTARGET_NODE_CUSP;
- break;
- case Geom::NODE_SMOOTH:
- case Geom::NODE_SYMM:
- sst = Inkscape::SNAPSOURCE_NODE_SMOOTH;
- stt = Inkscape::SNAPTARGET_NODE_SMOOTH;
- break;
- default:
- sst = Inkscape::SNAPSOURCE_UNDEFINED;
- stt = Inkscape::SNAPTARGET_UNDEFINED;
- break;
- }
- p.push_back(Inkscape::SnapCandidatePoint(curve_it1->finalPoint() * i2d, sst, stt));
- }
- }
+ // For each path: consider midpoints of line segments for snapping
+ if (snapprefs->getSnapLineMidpoints()) { // only do this when we're snapping nodes (enforces strict snapping)
+ if (Geom::LineSegment const* line_segment = dynamic_cast<Geom::LineSegment const*>(&(*curve_it1))) {
+ p.push_back(Inkscape::SnapCandidatePoint(Geom::middle_point(*line_segment) * i2d, Inkscape::SNAPSOURCE_LINE_MIDPOINT, Inkscape::SNAPTARGET_LINE_MIDPOINT));
+ }
+ }
+
+ if (curve_it2 == path_it->end_default()) { // Test will only pass for the last iteration of the while loop
+ if (snapprefs->getSnapToItemNode() && !path_it->closed()) {
+ // Add the last point of the path, but only for open paths
+ // (for closed paths the first and last point will coincide)
+ p.push_back(Inkscape::SnapCandidatePoint((*curve_it1).finalPoint() * i2d, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP));
+ }
+ } else {
+ /* Test whether to add the node between curve_it1 and curve_it2.
+ * Loop to end_default (so only iterating through the stroked part); */
+
+ Geom::NodeType nodetype = Geom::get_nodetype(*curve_it1, *curve_it2);
+
+ bool c1 = snapprefs->getSnapToItemNode() && (nodetype == Geom::NODE_CUSP || nodetype == Geom::NODE_NONE);
+ bool c2 = snapprefs->getSnapSmoothNodes() && (nodetype == Geom::NODE_SMOOTH || nodetype == Geom::NODE_SYMM);
+
+ if (c1 || c2) {
+ Inkscape::SnapSourceType sst;
+ Inkscape::SnapTargetType stt;
+ switch (nodetype) {
+ case Geom::NODE_CUSP:
+ sst = Inkscape::SNAPSOURCE_NODE_CUSP;
+ stt = Inkscape::SNAPTARGET_NODE_CUSP;
+ break;
+ case Geom::NODE_SMOOTH:
+ case Geom::NODE_SYMM:
+ sst = Inkscape::SNAPSOURCE_NODE_SMOOTH;
+ stt = Inkscape::SNAPTARGET_NODE_SMOOTH;
+ break;
+ default:
+ sst = Inkscape::SNAPSOURCE_UNDEFINED;
+ stt = Inkscape::SNAPTARGET_UNDEFINED;
+ break;
+ }
+ p.push_back(Inkscape::SnapCandidatePoint(curve_it1->finalPoint() * i2d, sst, stt));
+ }
+ }
++curve_it1;
++curve_it2;