diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2011-04-07 23:42:04 +0000 |
|---|---|---|
| committer | Krzysztof KosiĆski <tweenk.pl@gmail.com> | 2011-04-07 23:42:04 +0000 |
| commit | 945ce419c806c73d70203dec33ececafbe108a92 (patch) | |
| tree | cfcdb59bf47e9db7f9e01f7eebb59924bdeaea94 /src/snap.cpp | |
| parent | Merge from trunk (again) (diff) | |
| parent | Extensions. SVG+media fix (see Bug #400356). (diff) | |
| download | inkscape-945ce419c806c73d70203dec33ececafbe108a92.tar.gz inkscape-945ce419c806c73d70203dec33ececafbe108a92.zip | |
Merge from trunk
(bzr r9508.1.73)
Diffstat (limited to 'src/snap.cpp')
| -rw-r--r-- | src/snap.cpp | 94 |
1 files changed, 68 insertions, 26 deletions
diff --git a/src/snap.cpp b/src/snap.cpp index 7b0b4ce48..f8fe8e3fa 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -22,6 +22,7 @@ #include "sp-namedview.h" #include "snap.h" +#include "snap-enums.h" #include "snapped-line.h" #include "snapped-curve.h" @@ -682,7 +683,7 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( Geom::Point const &transformation, Geom::Point const &origin, Geom::Dim2 dim, - bool uniform) const + bool uniform) { /* We have a list of points, which we are proposing to transform in some way. We need to see ** if any of these points, when transformed, snap to anything. If they do, we return the @@ -734,6 +735,12 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( g_warning("Unconstrained rotation is not supported!"); } + // We will try to snap a set of points, but we don't want to have a snap indicator displayed + // for each of them. That's why it's temporarily disabled here, and re-enabled again after we + // have finished calling the freeSnap() and constrainedSnap() methods + bool _orig_snapindicator_status = _snapindicator; + _snapindicator = false; + std::vector<Inkscape::SnapCandidatePoint>::iterator j = transformed_points.begin(); // std::cout << std::endl; @@ -753,16 +760,6 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( dedicated_constraint = Inkscape::Snapper::SnapConstraint(origin, b); } else if (transformation_type == ROTATE) { Geom::Coord r = Geom::L2(b); // the radius of the circular constraint - if (r < 1e-9) { // points too close to the rotation center will not move. Don't try to snap these - // as they will always yield a perfect snap result if they're already snapped beforehand (e.g. - // when the transformation center has been snapped to a grid intersection in the selector tool) - continue; // skip this SnapCandidate and continue with the next one - // PS1: Apparently we don't have to do this for skewing, but why? - // PS2: We cannot easily filter these points upstream, e.g. in the grab() method (seltrans.cpp) - // because the rotation center will change when pressing shift, and grab() won't be recalled. - // Filtering could be done in handleRequest() (again in seltrans.cpp), by iterating through - // the snap candidates. But hey, we're iterating here anyway. - } dedicated_constraint = Inkscape::Snapper::SnapConstraint(origin, b, r); } else if (transformation_type == STRETCH) { // when non-uniform stretching { dedicated_constraint = Inkscape::Snapper::SnapConstraint((*i).getPoint(), component_vectors[dim]); @@ -802,6 +799,9 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( // std::cout << "dist = " << snapped_point.getSnapDistance() << std::endl; snapped_point.setPointerDistance(Geom::L2(pointer - (*i).getPoint())); + // Allow the snapindicator to be displayed again + _snapindicator = _orig_snapindicator_status; + Geom::Point result; /*Find the transformation that describes where the snapped point has @@ -816,11 +816,11 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( /* Consider the case in which a box is almost aligned with a grid in both * horizontal and vertical directions. The distance to the intersection of * the grid lines will always be larger then the distance to a single grid - * line. If we prefer snapping to an intersection instead of to a single + * line. If we prefer snapping to an intersection over to a single * grid line, then we cannot use "metric = Geom::L2(result)". Therefore the * snapped distance will be used as a metric. Please note that the snapped - * distance is defined as the distance to the nearest line of the intersection, - * and not to the intersection itself! + * distance to an intersection is defined as the distance to the nearest line + * of the intersection, and not to the intersection itself! */ // Only for translations, the relevant metric will be the real snapped distance, // so we don't have to do anything special here @@ -838,7 +838,7 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( if (fabs(fabs(a[index]/b[index]) - fabs(transformation[index])) > 1e-12) { // if SNAPPING DID occur in this direction result[index] = a[index] / b[index]; // then calculate it! } - // we might leave result[1-index] = NR_HUGE + // we might have left result[1-index] = NR_HUGE // if scaling didn't occur in the other direction } } @@ -851,8 +851,12 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( } // Compare the resulting scaling with the desired scaling Geom::Point scale_metric = Geom::abs(result - transformation); // One or both of its components might be NR_HUGE - snapped_point.setSnapDistance(std::min(scale_metric[0], scale_metric[1])); - snapped_point.setSecondSnapDistance(std::max(scale_metric[0], scale_metric[1])); + if (scale_metric[0] == NR_HUGE || scale_metric[1] == NR_HUGE) { + snapped_point.setSnapDistance(std::min(scale_metric[0], scale_metric[1])); + } else { + snapped_point.setSnapDistance(Geom::L2(scale_metric)); + } + snapped_point.setSecondSnapDistance(NR_HUGE); break; } case STRETCH: @@ -881,8 +885,18 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( // a is vector to snapped point; b is vector to original point; now lets calculate angle between a and b result[0] = atan2(Geom::dot(Geom::rot90(b), a), Geom::dot(b, a)); result[1] = result[1]; // how else should we store an angle in a point ;-) - // Store the metric for this transformation as a virtual distance (we're storing an angle) - snapped_point.setSnapDistance(std::abs(result[0] - transformation[0])); + if (Geom::L2(b) < 1e-9) { // points too close to the rotation center will not move. Don't try to snap these + // as they will always yield a perfect snap result if they're already snapped beforehand (e.g. + // when the transformation center has been snapped to a grid intersection in the selector tool) + snapped_point.setSnapDistance(NR_HUGE); + // PS1: Apparently we don't have to do this for skewing, but why? + // PS2: We cannot easily filter these points upstream, e.g. in the grab() method (seltrans.cpp) + // because the rotation center will change when pressing shift, and grab() won't be recalled. + // Filtering could be done in handleRequest() (again in seltrans.cpp), by iterating through + // the snap candidates. But hey, we're iterating here anyway. + } else { + snapped_point.setSnapDistance(std::abs(result[0] - transformation[0])); + } snapped_point.setSecondSnapDistance(NR_HUGE); break; default: @@ -932,6 +946,14 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( // Using " < 1e6" instead of " < Geom::infinity()" for catching some rounding errors // These rounding errors might be caused by NRRects, see bug #1584301 best_snapped_point.setSnapDistance(best_metric < 1e6 ? best_metric : Geom::infinity()); + + if (_snapindicator) { + if (best_snapped_point.getSnapped()) { + _desktop->snapindicator->set_new_snaptarget(best_snapped_point); + } else { + _desktop->snapindicator->remove_snaptarget(); + } + } return best_snapped_point; } @@ -947,7 +969,7 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( Inkscape::SnappedPoint SnapManager::freeSnapTranslate(std::vector<Inkscape::SnapCandidatePoint> const &p, Geom::Point const &pointer, - Geom::Point const &tr) const + Geom::Point const &tr) { Inkscape::SnappedPoint result = _snapTransformed(p, pointer, false, Geom::Point(0,0), TRANSLATE, tr, Geom::Point(0,0), Geom::X, false); @@ -971,7 +993,7 @@ Inkscape::SnappedPoint SnapManager::freeSnapTranslate(std::vector<Inkscape::Snap Inkscape::SnappedPoint SnapManager::constrainedSnapTranslate(std::vector<Inkscape::SnapCandidatePoint> const &p, Geom::Point const &pointer, Inkscape::Snapper::SnapConstraint const &constraint, - Geom::Point const &tr) const + Geom::Point const &tr) { Inkscape::SnappedPoint result = _snapTransformed(p, pointer, true, constraint, TRANSLATE, tr, Geom::Point(0,0), Geom::X, false); @@ -996,7 +1018,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapTranslate(std::vector<Inkscap Inkscape::SnappedPoint SnapManager::freeSnapScale(std::vector<Inkscape::SnapCandidatePoint> const &p, Geom::Point const &pointer, Geom::Scale const &s, - Geom::Point const &o) const + Geom::Point const &o) { Inkscape::SnappedPoint result = _snapTransformed(p, pointer, false, Geom::Point(0,0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, false); @@ -1021,7 +1043,7 @@ Inkscape::SnappedPoint SnapManager::freeSnapScale(std::vector<Inkscape::SnapCand Inkscape::SnappedPoint SnapManager::constrainedSnapScale(std::vector<Inkscape::SnapCandidatePoint> const &p, Geom::Point const &pointer, Geom::Scale const &s, - Geom::Point const &o) const + Geom::Point const &o) { // When constrained scaling, only uniform scaling is supported. Inkscape::SnappedPoint result = _snapTransformed(p, pointer, true, Geom::Point(0,0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, true); @@ -1050,7 +1072,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapStretch(std::vector<Inkscape: Geom::Coord const &s, Geom::Point const &o, Geom::Dim2 d, - bool u) const + bool u) { Inkscape::SnappedPoint result = _snapTransformed(p, pointer, true, Geom::Point(0,0), STRETCH, Geom::Point(s, s), o, d, u); @@ -1078,7 +1100,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapSkew(std::vector<Inkscape::Sn Inkscape::Snapper::SnapConstraint const &constraint, Geom::Point const &s, Geom::Point const &o, - Geom::Dim2 d) const + Geom::Dim2 d) { // "s" contains skew factor in s[0], and scale factor in s[1] @@ -1113,7 +1135,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapSkew(std::vector<Inkscape::Sn Inkscape::SnappedPoint SnapManager::constrainedSnapRotate(std::vector<Inkscape::SnapCandidatePoint> const &p, Geom::Point const &pointer, Geom::Coord const &angle, - Geom::Point const &o) const + Geom::Point const &o) { // Snapping the nodes of the bounding box of a selection that is being transformed, will only work if // the transformation of the bounding box is equal to the transformation of the individual nodes. This is @@ -1429,6 +1451,26 @@ void SnapManager::_displaySnapsource(Inkscape::SnapCandidatePoint const &p) cons } } +void SnapManager::keepClosestPointOnly(std::vector<Inkscape::SnapCandidatePoint> &points, const Geom::Point &reference) const +{ + if (points.size() < 2) return; + + Inkscape::SnapCandidatePoint closest_point = Inkscape::SnapCandidatePoint(Geom::Point(NR_HUGE, NR_HUGE), Inkscape::SNAPSOURCE_UNDEFINED, Inkscape::SNAPTARGET_UNDEFINED); + Geom::Coord closest_dist = NR_HUGE; + + for(std::vector<Inkscape::SnapCandidatePoint>::const_iterator i = points.begin(); i != points.end(); i++) { + Geom::Coord dist = Geom::L2((*i).getPoint() - reference); + if (i == points.begin() || dist < closest_dist) { + closest_point = *i; + closest_dist = dist; + } + } + + closest_point.setSourceNum(-1); + points.clear(); + points.push_back(closest_point); +} + /* Local Variables: mode:c++ |
