summaryrefslogtreecommitdiffstats
path: root/src/ui/tool/node.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/tool/node.cpp')
-rw-r--r--src/ui/tool/node.cpp117
1 files changed, 16 insertions, 101 deletions
diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp
index 69c09602e..a8582ccc5 100644
--- a/src/ui/tool/node.cpp
+++ b/src/ui/tool/node.cpp
@@ -270,9 +270,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event)
_parent->position() - node_away->position());
Inkscape::SnappedPoint p;
p = sm.constrainedSnap(Inkscape::SnapCandidatePoint(new_pos, SNAPSOURCE_NODE_HANDLE), cl);
- if (p.getSnapped()) {
- p.getPoint(new_pos);
- }
+ new_pos = p.getPoint();
} else {
sm.freeSnapReturnByRef(new_pos, SNAPSOURCE_NODE_HANDLE);
}
@@ -945,7 +943,7 @@ void Node::dragged(Geom::Point &new_pos, GdkEventMotion *event)
// For a note on how snapping is implemented in Inkscape, see snap.h.
SnapManager &sm = _desktop->namedview->snap_manager;
bool snap = sm.someSnapperMightSnap();
- std::vector<Inkscape::SnapCandidatePoint> unselected;
+ Inkscape::SnappedPoint sp;
if (snap) {
/* setup
* TODO We are doing this every time a snap happens. It should once be done only once
@@ -955,6 +953,7 @@ void Node::dragged(Geom::Point &new_pos, GdkEventMotion *event)
* TODO Snapping to unselected segments of selected paths doesn't work yet. */
// Build the list of unselected nodes.
+ std::vector<Inkscape::SnapCandidatePoint> unselected;
typedef ControlPointSelection::Set Set;
Set &nodes = _selection.allPoints();
for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) {
@@ -964,32 +963,22 @@ void Node::dragged(Geom::Point &new_pos, GdkEventMotion *event)
unselected.push_back(p);
}
}
- sm.setupIgnoreSelection(_desktop, false, &unselected);
+ sm.setupIgnoreSelection(_desktop, true, &unselected);
}
if (held_control(*event)) {
Geom::Point origin = _last_drag_origin();
- Inkscape::SnappedPoint fp, bp, fpp, bpp;
+ std::vector<Inkscape::Snapper::SnapConstraint> constraints;
if (held_alt(*event)) {
// with Ctrl+Alt, constrain to handle lines
// project the new position onto a handle line that is closer;
// also snap to perpendiculars of handle lines
- // TODO: this code is repetitive to the point of sillyness. Find a way
- // to express this concisely by modifying the semantics of snapping calls.
- // During a non-snap invocation, we should call constrainedSnap()
- // anyway, but it should just return the closest point matching the constraint
- // rather than snapping to an object. There should be comparison
- // operators defined for snap results, to simplify determining the best one,
- // or the snapping calls should take a reference to a snapping result and
- // replace it with the current result if it's better.
-
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int snaps = prefs->getIntLimited("/options/rotationsnapsperpi/value", 12, 1, 1000);
double min_angle = M_PI / snaps;
boost::optional<Geom::Point> front_point, back_point, fperp_point, bperp_point;
- boost::optional<Inkscape::Snapper::SnapConstraint> line_front, line_back, line_fperp, line_bperp;
if (_front.isDegenerate()) {
if (_is_line_segment(this, _next()))
front_point = _next()->position() - origin;
@@ -1003,11 +992,11 @@ void Node::dragged(Geom::Point &new_pos, GdkEventMotion *event)
back_point = _back.relativePos();
}
if (front_point) {
- line_front = Inkscape::Snapper::SnapConstraint(origin, *front_point);
+ constraints.push_back(Inkscape::Snapper::SnapConstraint(origin, *front_point));
fperp_point = Geom::rot90(*front_point);
}
if (back_point) {
- line_back = Inkscape::Snapper::SnapConstraint(origin, *back_point);
+ constraints.push_back(Inkscape::Snapper::SnapConstraint(origin, *back_point));
bperp_point = Geom::rot90(*back_point);
}
// perpendiculars only snap when they are further than snap increment away
@@ -1016,100 +1005,26 @@ void Node::dragged(Geom::Point &new_pos, GdkEventMotion *event)
(fabs(Geom::angle_between(*fperp_point, *back_point)) > min_angle &&
fabs(Geom::angle_between(*fperp_point, *back_point)) < M_PI - min_angle)))
{
- line_fperp = Inkscape::Snapper::SnapConstraint(origin, *fperp_point);
+ constraints.push_back(Inkscape::Snapper::SnapConstraint(origin, *fperp_point));
}
if (bperp_point && (!front_point ||
(fabs(Geom::angle_between(*bperp_point, *front_point)) > min_angle &&
fabs(Geom::angle_between(*bperp_point, *front_point)) < M_PI - min_angle)))
{
- line_bperp = Inkscape::Snapper::SnapConstraint(origin, *bperp_point);
+ constraints.push_back(Inkscape::Snapper::SnapConstraint(origin, *bperp_point));
}
- // TODO: combine the snap and non-snap branches by modifying snap.h / snap.cpp
- if (snap) {
- if (line_front) {
- fp = sm.constrainedSnap(Inkscape::SnapCandidatePoint(new_pos,
- _snapSourceType()), *line_front);
- }
- if (line_back) {
- bp = sm.constrainedSnap(Inkscape::SnapCandidatePoint(new_pos,
- _snapSourceType()), *line_back);
- }
- if (line_fperp) {
- fpp = sm.constrainedSnap(Inkscape::SnapCandidatePoint(new_pos,
- _snapSourceType()), *line_fperp);
- }
- if (line_bperp) {
- bpp = sm.constrainedSnap(Inkscape::SnapCandidatePoint(new_pos,
- _snapSourceType()), *line_bperp);
- }
- }
- if (fp.getSnapped() || bp.getSnapped() || fpp.getSnapped() || bpp.getSnapped()) {
- if (fp.isOtherSnapBetter(bp, false)) {
- fp = bp;
- }
- if (fp.isOtherSnapBetter(fpp, false)) {
- fp = fpp;
- }
- if (fp.isOtherSnapBetter(bpp, false)) {
- fp = bpp;
- }
- fp.getPoint(new_pos);
- _desktop->snapindicator->set_new_snaptarget(fp);
- } else {
- boost::optional<Geom::Point> pos;
- if (line_front) {
- pos = line_front->projection(new_pos);
- }
- if (line_back) {
- Geom::Point pos2 = line_back->projection(new_pos);
- if (!pos || (pos && Geom::distance(new_pos, *pos) > Geom::distance(new_pos, pos2)))
- pos = pos2;
- }
- if (line_fperp) {
- Geom::Point pos2 = line_fperp->projection(new_pos);
- if (!pos || (pos && Geom::distance(new_pos, *pos) > Geom::distance(new_pos, pos2)))
- pos = pos2;
- }
- if (line_bperp) {
- Geom::Point pos2 = line_bperp->projection(new_pos);
- if (!pos || (pos && Geom::distance(new_pos, *pos) > Geom::distance(new_pos, pos2)))
- pos = pos2;
- }
- if (pos) {
- new_pos = *pos;
- } else {
- new_pos = origin;
- }
- }
+ sp = sm.multipleConstrainedSnaps(Inkscape::SnapCandidatePoint(new_pos, _snapSourceType()), constraints);
} else {
// with Ctrl, constrain to axes
- // TODO combine the two branches
- if (snap) {
- Inkscape::Snapper::SnapConstraint line_x(origin, Geom::Point(1, 0));
- Inkscape::Snapper::SnapConstraint line_y(origin, Geom::Point(0, 1));
- fp = sm.constrainedSnap(Inkscape::SnapCandidatePoint(new_pos, _snapSourceType()), line_x);
- bp = sm.constrainedSnap(Inkscape::SnapCandidatePoint(new_pos, _snapSourceType()), line_y);
- }
- if (fp.getSnapped() || bp.getSnapped()) {
- if (fp.isOtherSnapBetter(bp, false)) {
- fp = bp;
- }
- fp.getPoint(new_pos);
- _desktop->snapindicator->set_new_snaptarget(fp);
- } else {
- Geom::Point origin = _last_drag_origin();
- Geom::Point delta = new_pos - origin;
- Geom::Dim2 d = (fabs(delta[Geom::X]) < fabs(delta[Geom::Y])) ? Geom::X : Geom::Y;
- new_pos[d] = origin[d];
- }
+ constraints.push_back(Inkscape::Snapper::SnapConstraint(origin, Geom::Point(1, 0)));
+ constraints.push_back(Inkscape::Snapper::SnapConstraint(origin, Geom::Point(0, 1)));
+ sp = sm.multipleConstrainedSnaps(Inkscape::SnapCandidatePoint(new_pos, _snapSourceType()), constraints);
}
+ new_pos = sp.getPoint();
} else if (snap) {
- Inkscape::SnappedPoint p = sm.freeSnap(Inkscape::SnapCandidatePoint(new_pos, _snapSourceType()));
- if (p.getSnapped()) {
- p.getPoint(new_pos);
- _desktop->snapindicator->set_new_snaptarget(p);
- }
+ sp = sm.freeSnap(Inkscape::SnapCandidatePoint(new_pos, _snapSourceType()));
+ new_pos = sp.getPoint();
}
SelectableControlPoint::dragged(new_pos, event);