summaryrefslogtreecommitdiffstats
path: root/src/ui/tool/transform-handle-set.cpp
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2011-04-07 23:42:04 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2011-04-07 23:42:04 +0000
commit945ce419c806c73d70203dec33ececafbe108a92 (patch)
treecfcdb59bf47e9db7f9e01f7eebb59924bdeaea94 /src/ui/tool/transform-handle-set.cpp
parentMerge from trunk (again) (diff)
parentExtensions. SVG+media fix (see Bug #400356). (diff)
downloadinkscape-945ce419c806c73d70203dec33ececafbe108a92.tar.gz
inkscape-945ce419c806c73d70203dec33ececafbe108a92.zip
Merge from trunk
(bzr r9508.1.73)
Diffstat (limited to 'src/ui/tool/transform-handle-set.cpp')
-rw-r--r--src/ui/tool/transform-handle-set.cpp113
1 files changed, 96 insertions, 17 deletions
diff --git a/src/ui/tool/transform-handle-set.cpp b/src/ui/tool/transform-handle-set.cpp
index ef93a3767..26263c26b 100644
--- a/src/ui/tool/transform-handle-set.cpp
+++ b/src/ui/tool/transform-handle-set.cpp
@@ -18,10 +18,16 @@
#include "desktop-handles.h"
#include "display/sodipodi-ctrlrect.h"
#include "preferences.h"
+#include "snap.h"
+#include "snap-candidate.h"
+#include "sp-namedview.h"
#include "ui/tool/commit-events.h"
#include "ui/tool/control-point.h"
+#include "ui/tool/control-point-selection.h"
+#include "ui/tool/selectable-control-point.h"
#include "ui/tool/event-utils.h"
#include "ui/tool/transform-handle-set.h"
+#include "ui/tool/node-tool.h"
// FIXME BRAIN DAMAGE WARNING: this is a global variable in select-context.cpp
// It should be moved to a header
@@ -88,12 +94,14 @@ public:
protected:
virtual void startTransform() {}
virtual void endTransform() {}
- virtual Geom::Matrix computeTransform(Geom::Point const &pos, GdkEventMotion *event) = 0;
+ virtual Geom::Affine computeTransform(Geom::Point const &pos, GdkEventMotion *event) = 0;
virtual CommitEvent getCommitEvent() = 0;
- Geom::Matrix _last_transform;
+ Geom::Affine _last_transform;
Geom::Point _origin;
TransformHandleSet &_th;
+ std::vector<Inkscape::SnapCandidatePoint> _snap_points;
+
private:
virtual bool grabbed(GdkEventMotion *) {
_origin = position();
@@ -103,19 +111,34 @@ private:
_th._setActiveHandle(this);
_cset = &invisible_cset;
_setState(_state);
+
+ // Collect the snap-candidates, one for each selected node. These will be stored in the _snap_points vector.
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ SnapManager &m = desktop->namedview->snap_manager;
+ InkNodeTool *nt = INK_NODE_TOOL(_desktop->event_context);
+ ControlPointSelection *selection = nt->_selected_nodes.get();
+
+ _snap_points = selection->getOriginalPoints();
+
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ if (prefs->getBool("/options/snapclosestonly/value", false)) {
+ m.keepClosestPointOnly(_snap_points, _origin);
+ }
+
return false;
}
virtual void dragged(Geom::Point &new_pos, GdkEventMotion *event)
{
- Geom::Matrix t = computeTransform(new_pos, event);
+ Geom::Affine t = computeTransform(new_pos, event);
// protect against degeneracies
if (t.isSingular()) return;
- Geom::Matrix incr = _last_transform.inverse() * t;
+ Geom::Affine incr = _last_transform.inverse() * t;
if (incr.isSingular()) return;
_th.signal_transform.emit(incr);
_last_transform = t;
}
virtual void ungrabbed(GdkEventButton *) {
+ _snap_points.clear();
_th._clearActiveHandle();
_cset = &thandle_cset;
_setState(_state);
@@ -175,26 +198,66 @@ protected:
_sc_center = _th.rotationCenter();
_sc_opposite = _th.bounds().corner(_corner + 2);
_last_scale_x = _last_scale_y = 1.0;
+ InkNodeTool *nt = INK_NODE_TOOL(_desktop->event_context);
+ ControlPointSelection *selection = nt->_selected_nodes.get();
+ selection->setOriginalPoints();
}
- virtual Geom::Matrix computeTransform(Geom::Point const &new_pos, GdkEventMotion *event) {
+ virtual Geom::Affine computeTransform(Geom::Point const &new_pos, GdkEventMotion *event) {
Geom::Point scc = held_shift(*event) ? _sc_center : _sc_opposite;
Geom::Point vold = _origin - scc, vnew = new_pos - scc;
+
// avoid exploding the selection
if (Geom::are_near(vold[Geom::X], 0) || Geom::are_near(vold[Geom::Y], 0))
return Geom::identity();
double scale[2] = { vnew[Geom::X] / vold[Geom::X], vnew[Geom::Y] / vold[Geom::Y] };
+
if (held_alt(*event)) {
for (unsigned i = 0; i < 2; ++i) {
if (scale[i] >= 1.0) scale[i] = round(scale[i]);
else scale[i] = 1.0 / round(1.0 / scale[i]);
}
- } else if (held_control(*event)) {
- scale[0] = scale[1] = std::min(scale[0], scale[1]);
+ } else {
+ //SPDesktop *desktop = _th._desktop; // Won't work as _desktop is protected
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ SnapManager &m = desktop->namedview->snap_manager;
+
+ // The lines below have been copied from Handle::dragged() in node.cpp, and need to be
+ // activated if we want to snap to unselected (i.e. stationary) nodes and stationary pieces of paths of the
+ // path that's currently being edited
+ /*
+ std::vector<Inkscape::SnapCandidatePoint> unselected;
+ typedef ControlPointSelection::Set Set;
+ Set &nodes = _parent->_selection.allPoints();
+ for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) {
+ Node *n = static_cast<Node*>(*i);
+ Inkscape::SnapCandidatePoint p(n->position(), n->_snapSourceType(), n->_snapTargetType());
+ unselected.push_back(p);
+ }
+ m.setupIgnoreSelection(_desktop, true, &unselected);
+ */
+
+ m.setupIgnoreSelection(_desktop);
+
+ Inkscape::SnappedPoint sp;
+ if (held_control(*event)) {
+ scale[0] = scale[1] = std::min(scale[0], scale[1]);
+ sp = m.constrainedSnapScale(_snap_points, _origin, Geom::Scale(scale[0], scale[1]), scc);
+ } else {
+ sp = m.freeSnapScale(_snap_points, _origin, Geom::Scale(scale[0], scale[1]), scc);
+ }
+ m.unSetup();
+
+ if (sp.getSnapped()) {
+ Geom::Point result = sp.getTransformation();
+ scale[0] = result[0];
+ scale[1] = result[1];
+ }
}
+
_last_scale_x = scale[0];
_last_scale_y = scale[1];
- Geom::Matrix t = Geom::Translate(-scc)
+ Geom::Affine t = Geom::Translate(-scc)
* Geom::Scale(scale[0], scale[1])
* Geom::Translate(scc);
return t;
@@ -231,7 +294,7 @@ protected:
_sc_opposite = Geom::middle_point(b.corner(_side + 2), b.corner(_side + 3));
_last_scale_x = _last_scale_y = 1.0;
}
- virtual Geom::Matrix computeTransform(Geom::Point const &new_pos, GdkEventMotion *event) {
+ virtual Geom::Affine computeTransform(Geom::Point const &new_pos, GdkEventMotion *event) {
Geom::Point scc = held_shift(*event) ? _sc_center : _sc_opposite;
Geom::Point vs;
Geom::Dim2 d1 = static_cast<Geom::Dim2>((_side + 1) % 2);
@@ -250,7 +313,7 @@ protected:
_last_scale_x = vs[Geom::X];
_last_scale_y = vs[Geom::Y];
- Geom::Matrix t = Geom::Translate(-scc)
+ Geom::Affine t = Geom::Translate(-scc)
* Geom::Scale(vs)
* Geom::Translate(scc);
return t;
@@ -288,7 +351,7 @@ protected:
_last_angle = 0;
}
- virtual Geom::Matrix computeTransform(Geom::Point const &new_pos, GdkEventMotion *event)
+ virtual Geom::Affine computeTransform(Geom::Point const &new_pos, GdkEventMotion *event)
{
Geom::Point rotc = held_shift(*event) ? _rot_opposite : _rot_center;
double angle = Geom::angle_between(_origin - rotc, new_pos - rotc);
@@ -296,7 +359,7 @@ protected:
angle = snap_angle(angle);
}
_last_angle = angle;
- Geom::Matrix t = Geom::Translate(-rotc)
+ Geom::Affine t = Geom::Translate(-rotc)
* Geom::Rotate(angle)
* Geom::Translate(rotc);
return t;
@@ -362,7 +425,7 @@ protected:
_last_horizontal = _side % 2;
}
- virtual Geom::Matrix computeTransform(Geom::Point const &new_pos, GdkEventMotion *event)
+ virtual Geom::Affine computeTransform(Geom::Point const &new_pos, GdkEventMotion *event)
{
Geom::Point scc = held_shift(*event) ? _skew_center : _skew_opposite;
// d1 and d2 are reversed with respect to ScaleSideHandle
@@ -395,12 +458,12 @@ protected:
// skew matrix has the from [[1, k],[0, 1]] for horizontal skew
// and [[1,0],[k,1]] for vertical skew.
- Geom::Matrix skew = Geom::identity();
+ Geom::Affine skew = Geom::identity();
// correct the sign of the tangent
skew[d2 + 1] = (d1 == Geom::X ? -1.0 : 1.0) * tan(angle);
_last_angle = angle;
- Geom::Matrix t = Geom::Translate(-scc)
+ Geom::Affine t = Geom::Translate(-scc)
* Geom::Scale(scale) * skew
* Geom::Translate(scc);
return t;
@@ -473,7 +536,23 @@ public:
}
protected:
-
+ virtual void dragged(Geom::Point &new_pos, GdkEventMotion *event) {
+ SnapManager &sm = _desktop->namedview->snap_manager;
+ sm.setup(_desktop);
+ bool snap = !held_shift(*event) && sm.someSnapperMightSnap();
+ if (held_control(*event)) {
+ // constrain to axes
+ Geom::Point origin = _last_drag_origin();
+ std::vector<Inkscape::Snapper::SnapConstraint> constraints;
+ constraints.push_back(Inkscape::Snapper::SnapConstraint(origin, Geom::Point(1, 0)));
+ constraints.push_back(Inkscape::Snapper::SnapConstraint(origin, Geom::Point(0, 1)));
+ new_pos = sm.multipleConstrainedSnaps(Inkscape::SnapCandidatePoint(new_pos,
+ SNAPSOURCE_ROTATION_CENTER), constraints, held_shift(*event)).getPoint();
+ } else if (snap) {
+ sm.freeSnapReturnByRef(new_pos, SNAPSOURCE_ROTATION_CENTER);
+ }
+ sm.unSetup();
+ }
virtual Glib::ustring _getTip(unsigned /*state*/) {
return C_("Transform handle tip",
"<b>Rotation center</b>: drag to change the origin of transforms");
@@ -566,7 +645,7 @@ bool TransformHandleSet::event(GdkEvent*)
return false;
}
-void TransformHandleSet::_emitTransform(Geom::Matrix const &t)
+void TransformHandleSet::_emitTransform(Geom::Affine const &t)
{
signal_transform.emit(t);
_center->transform(t);