From 89363253b6fc2e0f1d01136fb91f039599236be2 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Thu, 16 Dec 2010 20:27:26 +0100 Subject: Node tool: correctly save node skewing to undo history Fixed bugs: - https://launchpad.net/bugs/590259 (bzr r9956) --- src/ui/tool/multi-path-manipulator.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/ui/tool') diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index ef1c764bb..5f60f117a 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -695,6 +695,14 @@ void MultiPathManipulator::_commit(CommitEvent cps) reason = _("Scale nodes vertically"); key = "node:scale:y"; break; + case COMMIT_MOUSE_SKEW_X: + reason = _("Skew nodes horizontally"); + key = "node:skew:x"; + break; + case COMMIT_MOUSE_SKEW_Y: + reason = _("Skew nodes vertically"); + key = "node:skew:y"; + break; case COMMIT_FLIP_X: reason = _("Flip nodes horizontally"); break; -- cgit v1.2.3 From cb1e5c9cd7b8d9c44f728433d9300e04209d8585 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Thu, 16 Dec 2010 20:28:30 +0100 Subject: Node tool: fix moving multiple nodes along handles (Ctrl+Alt) Fixed bugs: - https://launchpad.net/bugs/642536 (bzr r9957) --- src/ui/tool/control-point-selection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui/tool') diff --git a/src/ui/tool/control-point-selection.cpp b/src/ui/tool/control-point-selection.cpp index 91e0bc2c2..baa53f76e 100644 --- a/src/ui/tool/control-point-selection.cpp +++ b/src/ui/tool/control-point-selection.cpp @@ -290,7 +290,7 @@ void ControlPointSelection::_pointDragged(Geom::Point &new_pos, GdkEventMotion * { Geom::Point abs_delta = new_pos - _original_positions[_grabbed_point]; double fdist = Geom::distance(_original_positions[_grabbed_point], _original_positions[_farthest_point]); - if (held_alt(*event) && fdist > 0) { + if (held_only_alt(*event) && fdist > 0) { // Sculpting for (iterator i = _points.begin(); i != _points.end(); ++i) { SelectableControlPoint *cur = (*i); -- cgit v1.2.3 From 981c5891a7cf64021d724f4b33d133f66427e18c Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Thu, 16 Dec 2010 21:11:16 +0100 Subject: Node tool: fix handle retraction with non-cusp nodes Fixed bugs: - https://launchpad.net/bugs/610817 (bzr r9958) --- src/ui/tool/node.cpp | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'src/ui/tool') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 12d04dd2b..1ea994bb9 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -113,12 +113,29 @@ void Handle::move(Geom::Point const &new_pos) Handle *towards_second = node_towards ? node_towards->handleToward(_parent) : NULL; if (Geom::are_near(new_pos, _parent->position())) { - // The handle becomes degenerate. If the segment between it and the node + // The handle becomes degenerate. + // Adjust node type as necessary. + if (other->isDegenerate()) { + // If both handles become degenerate, convert to parent cusp node + _parent->setType(NODE_CUSP, false); + } else { + // Only 1 handle becomes degenerate + switch (_parent->type()) { + case NODE_AUTO: + case NODE_SYMMETRIC: + _parent->setType(NODE_SMOOTH, false); + break; + default: + // do nothing for other node types + break; + } + } + // If the segment between the handle and the node // in its direction becomes linear and there are smooth nodes // at its ends, make their handles colinear with the segment - if (towards && towards->isDegenerate()) { + if (towards && towards_second->isDegenerate()) { if (node_towards->type() == NODE_SMOOTH) { - towards_second->setDirection(*_parent, *node_towards); + towards->setDirection(*_parent, *node_towards); } if (_parent->type() == NODE_SMOOTH) { other->setDirection(*node_towards, *_parent); @@ -160,6 +177,7 @@ void Handle::move(Geom::Point const &new_pos) void Handle::setPosition(Geom::Point const &p) { + Geom::Point old_pos = position(); ControlPoint::setPosition(p); sp_ctrlline_set_coords(SP_CTRLLINE(_handle_line), _parent->position(), position()); @@ -167,15 +185,12 @@ void Handle::setPosition(Geom::Point const &p) if (Geom::are_near(position(), _parent->position())) _degenerate = true; else _degenerate = false; + if (_parent->_handles_shown && _parent->visible() && !_degenerate) { setVisible(true); } else { setVisible(false); } - // If both handles become degenerate, convert to parent cusp node - if (_parent->isDegenerate()) { - _parent->setType(NODE_CUSP, false); - } } void Handle::setLength(double len) @@ -187,7 +202,7 @@ void Handle::setLength(double len) void Handle::retract() { - setPosition(_parent->position()); + move(_parent->position()); } void Handle::setDirection(Geom::Point const &from, Geom::Point const &to) -- cgit v1.2.3 From d7f88cb16397d88cd5839bd71c1091f3332bec8a Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Thu, 16 Dec 2010 21:56:43 +0100 Subject: Node tool: fix snapping during constrained rotation of handles (bzr r9959) --- src/ui/tool/node.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'src/ui/tool') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 1ea994bb9..a79a5c409 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -241,6 +241,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) Geom::Point origin = _last_drag_origin(); SnapManager &sm = _desktop->namedview->snap_manager; bool snap = sm.someSnapperMightSnap(); + boost::optional ctrl_constraint; // with Alt, preserve length if (held_alt(*event)) { @@ -256,16 +257,23 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) // note: if snapping to the original position is only desired in the original // direction of the handle, change to Ray instead of Line Geom::Line original_line(parent_pos, origin); + Geom::Line perp_line(parent_pos, parent_pos + Geom::rot90(origin - parent_pos)); Geom::Point snap_pos = parent_pos + Geom::constrain_angle( Geom::Point(0,0), new_pos - parent_pos, snaps, Geom::Point(1,0)); Geom::Point orig_pos = original_line.pointAt(original_line.nearestPoint(new_pos)); + Geom::Point perp_pos = perp_line.pointAt(perp_line.nearestPoint(new_pos)); - if (Geom::distance(snap_pos, new_pos) < Geom::distance(orig_pos, new_pos)) { - new_pos = snap_pos; - } else { - new_pos = orig_pos; + Geom::Point result = snap_pos; + ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - snap_pos); + if (Geom::distance(orig_pos, new_pos) < Geom::distance(result, new_pos)) { + result = orig_pos; + ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - orig_pos); } - snap = false; + if (Geom::distance(perp_pos, new_pos) < Geom::distance(result, new_pos)) { + result = perp_pos; + ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - perp_pos); + } + new_pos = result; } std::vector unselected; @@ -279,13 +287,20 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) } sm.setupIgnoreSelection(_desktop, true, &unselected); - Node *node_away = (this == &_parent->_front ? _parent->_prev() : _parent->_next()); + Node *node_away = _parent->nodeAwayFrom(this); if (_parent->type() == NODE_SMOOTH && Node::_is_line_segment(_parent, node_away)) { Inkscape::Snapper::SnapConstraint cl(_parent->position(), _parent->position() - node_away->position()); Inkscape::SnappedPoint p; p = sm.constrainedSnap(Inkscape::SnapCandidatePoint(new_pos, SNAPSOURCE_NODE_HANDLE), cl); new_pos = p.getPoint(); + } else if (ctrl_constraint) { + // NOTE: this is subtly wrong. + // We should get all possible constraints and snap along them using + // multipleConstrainedSnaps, instead of first snapping to angle and the to objects + Inkscape::SnappedPoint p; + p = sm.constrainedSnap(Inkscape::SnapCandidatePoint(new_pos, SNAPSOURCE_NODE_HANDLE), *ctrl_constraint); + new_pos = p.getPoint(); } else { sm.freeSnapReturnByRef(new_pos, SNAPSOURCE_NODE_HANDLE); } -- cgit v1.2.3 From d18ee1bd701f1e78a42fc4253f7a5c4e7ece714a Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Thu, 16 Dec 2010 23:07:52 +0100 Subject: Node tool: fix snapping of node rotation center Fixed bugs: - https://launchpad.net/bugs/667072 (bzr r9960) --- src/ui/tool/node.cpp | 29 +++++++++++++++++++++++++++++ src/ui/tool/node.h | 1 + src/ui/tool/transform-handle-set.cpp | 20 +++++++++++++++++++- 3 files changed, 49 insertions(+), 1 deletion(-) (limited to 'src/ui/tool') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index a79a5c409..fea02d399 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -227,6 +227,35 @@ char const *Handle::handle_type_to_localized_string(NodeType type) } } +bool Handle::_eventHandler(GdkEvent *event) +{ + switch (event->type) + { + case GDK_KEY_PRESS: + switch (shortcut_key(event->key)) + { + case GDK_s: + case GDK_S: + if (held_only_shift(event->key) && _parent->_type == NODE_CUSP) { + // when Shift+S is pressed when hovering over a handle belonging to a cusp node, + // hold this handle in place; otherwise process normally + // this handle is guaranteed not to be degenerate + other()->move(_parent->position() - (position() - _parent->position())); + _parent->setType(NODE_SMOOTH, false); + _parent->_pm().update(); // magic triple combo to add undo event + _parent->_pm().writeXML(); + _parent->_pm()._commit(_("Change node type")); + return true; + } + break; + default: break; + } + default: break; + } + + return ControlPoint::_eventHandler(event); +} + bool Handle::grabbed(GdkEventMotion *) { _saved_other_pos = other()->position(); diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 0194f5053..b5d4d88f2 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -102,6 +102,7 @@ public: protected: Handle(NodeSharedData const &data, Geom::Point const &initial_pos, Node *parent); + virtual bool _eventHandler(GdkEvent *event); virtual void dragged(Geom::Point &, GdkEventMotion *); virtual bool grabbed(GdkEventMotion *); virtual void ungrabbed(GdkEventButton *); diff --git a/src/ui/tool/transform-handle-set.cpp b/src/ui/tool/transform-handle-set.cpp index ef93a3767..cafd592a3 100644 --- a/src/ui/tool/transform-handle-set.cpp +++ b/src/ui/tool/transform-handle-set.cpp @@ -18,6 +18,8 @@ #include "desktop-handles.h" #include "display/sodipodi-ctrlrect.h" #include "preferences.h" +#include "snap.h" +#include "sp-namedview.h" #include "ui/tool/commit-events.h" #include "ui/tool/control-point.h" #include "ui/tool/event-utils.h" @@ -473,7 +475,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 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", "Rotation center: drag to change the origin of transforms"); -- cgit v1.2.3 From 3a38979f6034517961c09e0af5a3028f0d6d7a52 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Fri, 17 Dec 2010 00:01:36 +0100 Subject: Node tool: fix Tab and Shift+Tab (bzr r9961) --- src/ui/tool/multi-path-manipulator.cpp | 73 +++++++++++++++++++++++++++++++++- src/ui/tool/path-manipulator.cpp | 59 +-------------------------- src/ui/tool/path-manipulator.h | 4 +- 3 files changed, 76 insertions(+), 60 deletions(-) (limited to 'src/ui/tool') diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index 5f60f117a..082ac194b 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -210,7 +210,78 @@ void MultiPathManipulator::selectSubpaths() void MultiPathManipulator::shiftSelection(int dir) { - invokeForAll(&PathManipulator::shiftSelection, dir); + if (empty()) return; + + // 1. find last selected node + // 2. select the next node; if the last node or nothing is selected, + // select first node + MapType::iterator last_i; + SubpathList::iterator last_j; + NodeList::iterator last_k; + bool anything_found = false; + + for (MapType::iterator i = _mmap.begin(); i != _mmap.end(); ++i) { + SubpathList &sp = i->second->subpathList(); + for (SubpathList::iterator j = sp.begin(); j != sp.end(); ++j) { + for (NodeList::iterator k = (*j)->begin(); k != (*j)->end(); ++k) { + if (k->selected()) { + last_i = i; + last_j = j; + last_k = k; + anything_found = true; + // when tabbing backwards, we want the first node + if (dir == -1) goto exit_loop; + } + } + } + } + exit_loop: + + // NOTE: we should not assume the _selection contains only nodes + // in future it might also contain handles and other types of control points + // this is why we use a flag instead in the loop above, instead of calling + // selection.empty() + if (!anything_found) { + // select first / last node + // this should never fail because there must be at least 1 non-empty manipulator + if (dir == 1) { + _selection.insert((*_mmap.begin()->second->subpathList().begin())->begin().ptr()); + } else { + _selection.insert((--(*--(--_mmap.end())->second->subpathList().end())->end()).ptr()); + } + return; + } + + // three levels deep - w00t! + if (dir == 1) { + if (++last_k == (*last_j)->end()) { + // here, last_k points to the node to be selected + ++last_j; + if (last_j == last_i->second->subpathList().end()) { + ++last_i; + if (last_i == _mmap.end()) { + last_i = _mmap.begin(); + } + last_j = last_i->second->subpathList().begin(); + } + last_k = (*last_j)->begin(); + } + } else { + if (!last_k || last_k == (*last_j)->begin()) { + if (last_j == last_i->second->subpathList().begin()) { + if (last_i == _mmap.begin()) { + last_i = _mmap.end(); + } + --last_i; + last_j = last_i->second->subpathList().end(); + } + --last_j; + last_k = (*last_j)->end(); + } + --last_k; + } + _selection.clear(); + _selection.insert(last_k.ptr()); } void MultiPathManipulator::invertSelectionInSubpaths() diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 5ae9c4137..7c60efbab 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -215,7 +215,7 @@ void PathManipulator::clear() /** Select all nodes in subpaths that have something selected. */ void PathManipulator::selectSubpaths() { - for (std::list::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) { + for (SubpathList::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) { NodeList::iterator sp_start = (*i)->begin(), sp_end = (*i)->end(); for (NodeList::iterator j = sp_start; j != sp_end; ++j) { if (j->selected()) { @@ -229,63 +229,6 @@ void PathManipulator::selectSubpaths() } } -/** Move the selection forward or backward by one node in each subpath, based on the sign - * of the parameter. */ -void PathManipulator::shiftSelection(int dir) -{ - if (dir == 0) return; - if (_num_selected == 0) { - // select the first node of the path. - SubpathList::iterator s = _subpaths.begin(); - if (s == _subpaths.end()) return; - NodeList::iterator n = (*s)->begin(); - if (n != (*s)->end()) - _selection.insert(n.ptr()); - return; - } - // We cannot do any tricks here, like iterating in different directions based on - // the sign and only setting the selection of nodes behind us, because it would break - // for closed paths. - for (SubpathList::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) { - std::deque sels; // I hope this is specialized for bools! - unsigned num = 0; - - for (NodeList::iterator j = (*i)->begin(); j != (*i)->end(); ++j) { - sels.push_back(j->selected()); - _selection.erase(j.ptr()); - ++num; - } - if (num == 0) continue; // should never happen! zero-node subpaths are not allowed - - num = 0; - // In closed subpath, shift the selection cyclically. In an open one, - // let the selection 'slide into nothing' at ends. - if (dir > 0) { - if ((*i)->closed()) { - bool last = sels.back(); - sels.pop_back(); - sels.push_front(last); - } else { - sels.push_front(false); - } - } else { - if ((*i)->closed()) { - bool first = sels.front(); - sels.pop_front(); - sels.push_back(first); - } else { - sels.push_back(false); - num = 1; - } - } - - for (NodeList::iterator j = (*i)->begin(); j != (*i)->end(); ++j) { - if (sels[num]) _selection.insert(j.ptr()); - ++num; - } - } -} - /** Invert selection in the selected subpaths. */ void PathManipulator::invertSelectionInSubpaths() { diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 87b88fc77..8a0167e59 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -65,7 +65,6 @@ public: SPPath *item() { return _path; } void selectSubpaths(); - void shiftSelection(int dir); void invertSelectionInSubpaths(); void insertNodes(); @@ -94,6 +93,9 @@ public: NodeList::iterator extremeNode(NodeList::iterator origin, bool search_selected, bool search_unselected, bool closest); + // this is necessary for Tab-selection in MultiPathManipulator + SubpathList &subpathList() { return _subpaths; } + static bool is_item_type(void *item); private: typedef NodeList Subpath; -- cgit v1.2.3 From 69059080428adb8b6258a6d5de15f0028c4444f8 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Fri, 17 Dec 2010 00:16:33 +0100 Subject: Node tool: special case node duplication for endnodes - select new endnode (bzr r9962) --- src/ui/tool/path-manipulator.cpp | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'src/ui/tool') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 7c60efbab..ea7f3412d 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -275,22 +275,31 @@ void PathManipulator::duplicateNodes() NodeList::iterator k = j.next(); Node *n = new Node(_multi_path_manipulator._path_data.node_data, *j); - // Move the new node to the bottom of the Z-order. This way you can drag all - // nodes that were selected before this operation without deselecting - // everything because there is a new node above. - n->sink(); + if (k) { + // Move the new node to the bottom of the Z-order. This way you can drag all + // nodes that were selected before this operation without deselecting + // everything because there is a new node above. + n->sink(); + } n->front()->setPosition(*j->front()); j->front()->retract(); j->setType(NODE_CUSP, false); (*i)->insert(k, n); - // We need to manually call the selection change callback to refresh - // the handle display correctly. - // This call changes num_selected, but we call this once for a selected node - // and once for an unselected node, so in the end the number stays correct. - _selectionChanged(j.ptr(), true); - _selectionChanged(n, false); + if (k) { + // We need to manually call the selection change callback to refresh + // the handle display correctly. + // This call changes num_selected, but we call this once for a selected node + // and once for an unselected node, so in the end the number stays correct. + _selectionChanged(j.ptr(), true); + _selectionChanged(n, false); + } else { + // select the new end node instead of the node just before it + _selection.erase(j.ptr()); + _selection.insert(n); + break; // this was the end node, nothing more to do + } } } } -- cgit v1.2.3 From 3cc158ecff4f2420590ab102d7f3a84d7ca2a711 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Thu, 23 Dec 2010 00:10:28 -0800 Subject: Split SPCanvasItem and SPCanvasGroup to individual .h files. Removed forward header. (bzr r9978.1.1) --- src/ui/tool/control-point-selection.h | 2 +- src/ui/tool/control-point.cpp | 1 + src/ui/tool/control-point.h | 1 - src/ui/tool/multi-path-manipulator.h | 1 - src/ui/tool/node-tool.cpp | 1 + src/ui/tool/node-tool.h | 9 ++++++--- src/ui/tool/path-manipulator.h | 2 +- src/ui/tool/selector.h | 1 - src/ui/tool/transform-handle-set.h | 3 +-- 9 files changed, 11 insertions(+), 10 deletions(-) (limited to 'src/ui/tool') diff --git a/src/ui/tool/control-point-selection.h b/src/ui/tool/control-point-selection.h index 3aed6ae93..6a5b05e85 100644 --- a/src/ui/tool/control-point-selection.h +++ b/src/ui/tool/control-point-selection.h @@ -18,13 +18,13 @@ #include <2geom/forward.h> #include <2geom/point.h> #include <2geom/rect.h> -#include "display/display-forward.h" #include "util/accumulators.h" #include "util/unordered-containers.h" #include "ui/tool/commit-events.h" #include "ui/tool/manipulator.h" class SPDesktop; +struct SPCanvasGroup; namespace Inkscape { namespace UI { diff --git a/src/ui/tool/control-point.cpp b/src/ui/tool/control-point.cpp index d5e5b7dfe..38b421553 100644 --- a/src/ui/tool/control-point.cpp +++ b/src/ui/tool/control-point.cpp @@ -14,6 +14,7 @@ #include <2geom/point.h> #include "desktop.h" #include "desktop-handles.h" +#include "display/sp-canvas.h" #include "display/snap-indicator.h" #include "event-context.h" #include "message-context.h" diff --git a/src/ui/tool/control-point.h b/src/ui/tool/control-point.h index 4de5e5847..3f5fe668d 100644 --- a/src/ui/tool/control-point.h +++ b/src/ui/tool/control-point.h @@ -17,7 +17,6 @@ #include #include <2geom/point.h> -#include "display/display-forward.h" #include "forward.h" #include "util/accumulators.h" #include "display/sodipodi-ctrl.h" diff --git a/src/ui/tool/multi-path-manipulator.h b/src/ui/tool/multi-path-manipulator.h index ddb74c1bc..aef9c1ac9 100644 --- a/src/ui/tool/multi-path-manipulator.h +++ b/src/ui/tool/multi-path-manipulator.h @@ -12,7 +12,6 @@ #define SEEN_UI_TOOL_MULTI_PATH_MANIPULATOR_H #include -#include "display/display-forward.h" #include "forward.h" #include "ui/tool/commit-events.h" #include "ui/tool/manipulator.h" diff --git a/src/ui/tool/node-tool.cpp b/src/ui/tool/node-tool.cpp index 8661e7946..e75f31370 100644 --- a/src/ui/tool/node-tool.cpp +++ b/src/ui/tool/node-tool.cpp @@ -13,6 +13,7 @@ #include #include "desktop.h" #include "desktop-handles.h" +#include "display/sp-canvas-group.h" #include "display/canvas-bpath.h" #include "display/curve.h" #include "display/sp-canvas.h" diff --git a/src/ui/tool/node-tool.h b/src/ui/tool/node-tool.h index 4d38e69e2..bcf6a8d5e 100644 --- a/src/ui/tool/node-tool.h +++ b/src/ui/tool/node-tool.h @@ -17,7 +17,6 @@ #include #include "event-context.h" #include "forward.h" -#include "display/display-forward.h" #include "ui/tool/node-types.h" #define INK_TYPE_NODE_TOOL (ink_node_tool_get_type ()) @@ -30,13 +29,17 @@ class InkNodeTool; class InkNodeToolClass; namespace Inkscape { + +namespace Display { +class TemporaryItem; +} // namespace Display namespace UI { class MultiPathManipulator; class ControlPointSelection; class Selector; struct PathSharedData; -} -} +} // namespace UI +} // namespace Inkscape typedef std::auto_ptr MultiPathPtr; typedef std::auto_ptr CSelPtr; diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 8a0167e59..58907ea96 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -17,12 +17,12 @@ #include <2geom/matrix.h> #include #include -#include "display/display-forward.h" #include "forward.h" #include "ui/tool/node.h" #include "ui/tool/manipulator.h" struct SPCanvasItem; +struct SPCurve; namespace Inkscape { namespace XML { class Node; } diff --git a/src/ui/tool/selector.h b/src/ui/tool/selector.h index e61668d9e..05d72c208 100644 --- a/src/ui/tool/selector.h +++ b/src/ui/tool/selector.h @@ -14,7 +14,6 @@ #include #include #include <2geom/rect.h> -#include "display/display-forward.h" #include "ui/tool/manipulator.h" class SPDesktop; diff --git a/src/ui/tool/transform-handle-set.h b/src/ui/tool/transform-handle-set.h index 2a4df8751..b18c598ee 100644 --- a/src/ui/tool/transform-handle-set.h +++ b/src/ui/tool/transform-handle-set.h @@ -14,12 +14,11 @@ #include #include #include <2geom/forward.h> -#include "display/display-forward.h" #include "ui/tool/commit-events.h" #include "ui/tool/manipulator.h" class SPDesktop; -class CtrlRect; // this is not present in display-forward.h! +class CtrlRect; namespace Inkscape { namespace UI { -- cgit v1.2.3 From c210fd393e9423898f9c745fe081da3d90e9b605 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Mon, 27 Dec 2010 22:18:34 +0100 Subject: Node tool: snap while scaling a selection of nodes. Consider this as experimental; needs cleanup! (bzr r9985) --- src/ui/tool/control-point-selection.cpp | 18 +++++++++ src/ui/tool/control-point-selection.h | 5 +++ src/ui/tool/transform-handle-set.cpp | 66 ++++++++++++++++++++++++++++++++- 3 files changed, 87 insertions(+), 2 deletions(-) (limited to 'src/ui/tool') diff --git a/src/ui/tool/control-point-selection.cpp b/src/ui/tool/control-point-selection.cpp index baa53f76e..517e90da2 100644 --- a/src/ui/tool/control-point-selection.cpp +++ b/src/ui/tool/control-point-selection.cpp @@ -642,6 +642,24 @@ bool ControlPointSelection::event(GdkEvent *event) return false; } +std::vector ControlPointSelection::getOriginalPoints() +{ + std::vector points; + for (iterator i = _points.begin(); i != _points.end(); ++i) { + points.push_back(Inkscape::SnapCandidatePoint(_original_positions[*i], SNAPSOURCE_NODE_HANDLE)); + } + return points; +} + +void ControlPointSelection::setOriginalPoints() +{ + _original_positions.clear(); + for (iterator i = _points.begin(); i != _points.end(); ++i) { + _original_positions.insert(std::make_pair(*i, (*i)->position())); + } +} + + } // namespace UI } // namespace Inkscape diff --git a/src/ui/tool/control-point-selection.h b/src/ui/tool/control-point-selection.h index 6a5b05e85..0e5acf6c5 100644 --- a/src/ui/tool/control-point-selection.h +++ b/src/ui/tool/control-point-selection.h @@ -22,6 +22,7 @@ #include "util/unordered-containers.h" #include "ui/tool/commit-events.h" #include "ui/tool/manipulator.h" +#include "snap-candidate.h" class SPDesktop; struct SPCanvasGroup; @@ -108,6 +109,10 @@ public: sigc::signal signal_update; sigc::signal signal_point_changed; sigc::signal signal_commit; + + std::vector getOriginalPoints(); + void setOriginalPoints(); + private: // The functions below are invoked from SelectableControlPoint. // Previously they were connected to handlers when selecting, but this diff --git a/src/ui/tool/transform-handle-set.cpp b/src/ui/tool/transform-handle-set.cpp index cafd592a3..209b7fe98 100644 --- a/src/ui/tool/transform-handle-set.cpp +++ b/src/ui/tool/transform-handle-set.cpp @@ -19,11 +19,15 @@ #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 @@ -96,6 +100,8 @@ protected: Geom::Matrix _last_transform; Geom::Point _origin; TransformHandleSet &_th; + std::vector _snap_points; + private: virtual bool grabbed(GdkEventMotion *) { _origin = position(); @@ -105,6 +111,20 @@ 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) @@ -118,6 +138,7 @@ private: _last_transform = t; } virtual void ungrabbed(GdkEventButton *) { + _snap_points.clear(); _th._clearActiveHandle(); _cset = &thandle_cset; _setState(_state); @@ -177,23 +198,64 @@ 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(); + std::cout << "startTransform()" << std::endl; + selection->setOriginalPoints(); } virtual Geom::Matrix 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 unselected; + typedef ControlPointSelection::Set Set; + Set &nodes = _parent->_selection.allPoints(); + for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { + Node *n = static_cast(*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) -- cgit v1.2.3 From e2fe5c8411dcbd514f1df51de0925c0719019dc9 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Mon, 27 Dec 2010 23:03:25 +0100 Subject: Snapping: improve calculation of metrics for scaling, modify some comments, and remove a line of obsolete debugging output (bzr r9986) --- src/ui/tool/transform-handle-set.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/ui/tool') diff --git a/src/ui/tool/transform-handle-set.cpp b/src/ui/tool/transform-handle-set.cpp index 209b7fe98..5c3b494ce 100644 --- a/src/ui/tool/transform-handle-set.cpp +++ b/src/ui/tool/transform-handle-set.cpp @@ -200,7 +200,6 @@ protected: _last_scale_x = _last_scale_y = 1.0; InkNodeTool *nt = INK_NODE_TOOL(_desktop->event_context); ControlPointSelection *selection = nt->_selected_nodes.get(); - std::cout << "startTransform()" << std::endl; selection->setOriginalPoints(); } virtual Geom::Matrix computeTransform(Geom::Point const &new_pos, GdkEventMotion *event) { -- cgit v1.2.3 From 53933f5fea9d07d1ba6304b88439fba257ee8c34 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Wed, 2 Feb 2011 22:24:36 +0100 Subject: update to latest 2geom ! (bzr r10025) --- src/ui/tool/control-point-selection.cpp | 14 +++++++------- src/ui/tool/control-point-selection.h | 6 +++--- src/ui/tool/control-point.cpp | 2 +- src/ui/tool/control-point.h | 2 +- src/ui/tool/node.cpp | 34 +++++++-------------------------- src/ui/tool/node.h | 2 +- src/ui/tool/path-manipulator.cpp | 12 ++++++------ src/ui/tool/path-manipulator.h | 12 ++++++------ src/ui/tool/shape-record.h | 4 ++-- src/ui/tool/transform-handle-set.cpp | 28 +++++++++++++-------------- src/ui/tool/transform-handle-set.h | 4 ++-- 11 files changed, 50 insertions(+), 70 deletions(-) (limited to 'src/ui/tool') diff --git a/src/ui/tool/control-point-selection.cpp b/src/ui/tool/control-point-selection.cpp index 517e90da2..1fb98d78f 100644 --- a/src/ui/tool/control-point-selection.cpp +++ b/src/ui/tool/control-point-selection.cpp @@ -166,7 +166,7 @@ void ControlPointSelection::spatialGrow(SelectableControlPoint *origin, int dir) } /** Transform all selected control points by the given affine transformation. */ -void ControlPointSelection::transform(Geom::Matrix const &m) +void ControlPointSelection::transform(Geom::Affine const &m) { for (iterator i = _points.begin(); i != _points.end(); ++i) { SelectableControlPoint *cur = *i; @@ -273,7 +273,7 @@ void ControlPointSelection::_pointGrabbed(SelectableControlPoint *point) _grabbed_point = point; _farthest_point = point; double maxdist = 0; - Geom::Matrix m; + Geom::Affine m; m.setIdentity(); for (iterator i = _points.begin(); i != _points.end(); ++i) { _original_positions.insert(std::make_pair(*i, (*i)->position())); @@ -294,7 +294,7 @@ void ControlPointSelection::_pointDragged(Geom::Point &new_pos, GdkEventMotion * // Sculpting for (iterator i = _points.begin(); i != _points.end(); ++i) { SelectableControlPoint *cur = (*i); - Geom::Matrix trans; + Geom::Affine trans; trans.setIdentity(); double dist = Geom::distance(_original_positions[cur], _original_positions[_grabbed_point]); double deltafrac = 0.5 + 0.5 * cos(M_PI * dist/fdist); @@ -323,7 +323,7 @@ void ControlPointSelection::_pointDragged(Geom::Point &new_pos, GdkEventMotion * Geom::Point newdx = (newpx - newp) / Geom::EPSILON; Geom::Point newdy = (newpy - newp) / Geom::EPSILON; - Geom::Matrix itrans(newdx[Geom::X], newdx[Geom::Y], newdy[Geom::X], newdy[Geom::Y], 0, 0); + Geom::Affine itrans(newdx[Geom::X], newdx[Geom::Y], newdy[Geom::X], newdy[Geom::Y], 0, 0); if (itrans.isSingular()) itrans.setIdentity(); @@ -502,7 +502,7 @@ bool ControlPointSelection::_keyboardRotate(GdkEventKey const &event, int dir) } // translate to origin, rotate, translate back to original position - Geom::Matrix m = Geom::Translate(-rc) + Geom::Affine m = Geom::Translate(-rc) * Geom::Rotate(angle) * Geom::Translate(rc); transform(m); signal_commit.emit(COMMIT_KEYBOARD_ROTATE); @@ -538,7 +538,7 @@ bool ControlPointSelection::_keyboardScale(GdkEventKey const &event, int dir) } double scale = (maxext + length_change) / maxext; - Geom::Matrix m = Geom::Translate(-center) * Geom::Scale(scale) * Geom::Translate(center); + Geom::Affine m = Geom::Translate(-center) * Geom::Scale(scale) * Geom::Translate(center); transform(m); signal_commit.emit(COMMIT_KEYBOARD_SCALE_UNIFORM); return true; @@ -559,7 +559,7 @@ bool ControlPointSelection::_keyboardFlip(Geom::Dim2 d) dynamic_cast(ControlPoint::mouseovered_point); Geom::Point center = scp ? scp->position() : _handles->rotationCenter().position(); - Geom::Matrix m = Geom::Translate(-center) * scale_transform * Geom::Translate(center); + Geom::Affine m = Geom::Translate(-center) * scale_transform * Geom::Translate(center); transform(m); signal_commit.emit(d == Geom::X ? COMMIT_FLIP_X : COMMIT_FLIP_Y); return true; diff --git a/src/ui/tool/control-point-selection.h b/src/ui/tool/control-point-selection.h index 0e5acf6c5..a9c929cb1 100644 --- a/src/ui/tool/control-point-selection.h +++ b/src/ui/tool/control-point-selection.h @@ -91,7 +91,7 @@ public: virtual bool event(GdkEvent *); - void transform(Geom::Matrix const &m); + void transform(Geom::Affine const &m); void align(Geom::Dim2 d); void distribute(Geom::Dim2 d); @@ -130,14 +130,14 @@ private: bool _keyboardRotate(GdkEventKey const &, int); bool _keyboardScale(GdkEventKey const &, int); bool _keyboardFlip(Geom::Dim2); - void _keyboardTransform(Geom::Matrix const &); + void _keyboardTransform(Geom::Affine const &); void _commitHandlesTransform(CommitEvent ce); double _rotationRadius(Geom::Point const &); set_type _points; set_type _all_points; INK_UNORDERED_MAP _original_positions; - INK_UNORDERED_MAP _last_trans; + INK_UNORDERED_MAP _last_trans; boost::optional _rot_radius; boost::optional _mouseover_rot_radius; Geom::OptRect _bounds; diff --git a/src/ui/tool/control-point.cpp b/src/ui/tool/control-point.cpp index 38b421553..bece1324b 100644 --- a/src/ui/tool/control-point.cpp +++ b/src/ui/tool/control-point.cpp @@ -214,7 +214,7 @@ void ControlPoint::move(Geom::Point const &pos) /** Apply an arbitrary affine transformation to a control point. This is used * by ControlPointSelection, and is important for things like nodes with handles. * The default implementation simply moves the point according to the transform. */ -void ControlPoint::transform(Geom::Matrix const &m) { +void ControlPoint::transform(Geom::Affine const &m) { move(position() * m); } diff --git a/src/ui/tool/control-point.h b/src/ui/tool/control-point.h index 3f5fe668d..0b88786e5 100644 --- a/src/ui/tool/control-point.h +++ b/src/ui/tool/control-point.h @@ -56,7 +56,7 @@ public: operator Geom::Point const &() { return _position; } virtual void move(Geom::Point const &pos); virtual void setPosition(Geom::Point const &pos); - virtual void transform(Geom::Matrix const &m); + virtual void transform(Geom::Affine const &m); /// @} /// @name Toggle the point's visibility diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index fea02d399..8e3da266b 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -514,7 +514,7 @@ void Node::move(Geom::Point const &new_pos) _fixNeighbors(old_pos, new_pos); } -void Node::transform(Geom::Matrix const &m) +void Node::transform(Geom::Affine const &m) { Geom::Point old_pos = position(); setPosition(position() * m); @@ -829,26 +829,6 @@ bool Node::_eventHandler(GdkEvent *event) return ControlPoint::_eventHandler(event); } -// TODO Move this to 2Geom! -static double bezier_length (Geom::Point a0, Geom::Point a1, Geom::Point a2, Geom::Point a3) -{ - double lower = Geom::distance(a0, a3); - double upper = Geom::distance(a0, a1) + Geom::distance(a1, a2) + Geom::distance(a2, a3); - - if (upper - lower < Geom::EPSILON) return (lower + upper)/2; - - Geom::Point // Casteljau subdivision - b0 = a0, - c0 = a3, - b1 = 0.5*(a0 + a1), - t0 = 0.5*(a1 + a2), - c1 = 0.5*(a2 + a3), - b2 = 0.5*(b1 + t0), - c2 = 0.5*(t0 + c1), - b3 = 0.5*(b2 + c2); // == c3 - return bezier_length(b0, b1, b2, b3) + bezier_length(b3, c2, c1, c0); -} - /** Select or deselect a node in this node's subpath based on its path distance from this node. * @param dir If negative, shrink selection by one node; if positive, grow by one node */ void Node::_linearGrow(int dir) @@ -875,7 +855,7 @@ void Node::_linearGrow(int dir) // find first unselected nodes on both sides while (fwd && fwd->selected()) { NodeList::iterator n = fwd.next(); - distance_front += bezier_length(*fwd, fwd->_front, n->_back, *n); + distance_front += Geom::bezier_length(*fwd, fwd->_front, n->_back, *n); fwd = n; if (fwd == this_iter) // there is no unselected node in this cyclic subpath @@ -886,7 +866,7 @@ void Node::_linearGrow(int dir) // so we are guaranteed to stop. while (rev && rev->selected()) { NodeList::iterator p = rev.prev(); - distance_back += bezier_length(*rev, rev->_back, p->_front, *p); + distance_back += Geom::bezier_length(*rev, rev->_back, p->_front, *p); rev = p; } @@ -917,7 +897,7 @@ void Node::_linearGrow(int dir) last_distance_front = distance_front; } NodeList::iterator n = fwd.next(); - if (n) distance_front += bezier_length(*fwd, fwd->_front, n->_back, *n); + if (n) distance_front += Geom::bezier_length(*fwd, fwd->_front, n->_back, *n); fwd = n; } else if (rev && (!fwd || distance_front > distance_back)) { if (rev->selected()) { @@ -925,7 +905,7 @@ void Node::_linearGrow(int dir) last_distance_back = distance_back; } NodeList::iterator p = rev.prev(); - if (p) distance_back += bezier_length(*rev, rev->_back, p->_front, *p); + if (p) distance_back += Geom::bezier_length(*rev, rev->_back, p->_front, *p); rev = p; } // Check whether we walked the entire cyclic subpath. @@ -935,8 +915,8 @@ void Node::_linearGrow(int dir) if (fwd && fwd == rev) { if (!fwd->selected()) break; NodeList::iterator fwdp = fwd.prev(), revn = rev.next(); - double df = distance_front + bezier_length(*fwdp, fwdp->_front, fwd->_back, *fwd); - double db = distance_back + bezier_length(*revn, revn->_back, rev->_front, *rev); + double df = distance_front + Geom::bezier_length(*fwdp, fwdp->_front, fwd->_back, *fwd); + double db = distance_back + Geom::bezier_length(*revn, revn->_back, rev->_front, *rev); if (df > db) { last_fwd = fwd; last_distance_front = df; diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index b5d4d88f2..451915dbe 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -128,7 +128,7 @@ class Node : ListNode, public SelectableControlPoint { public: Node(NodeSharedData const &data, Geom::Point const &pos); virtual void move(Geom::Point const &p); - virtual void transform(Geom::Matrix const &m); + virtual void transform(Geom::Affine const &m); virtual Geom::Rect bounds(); NodeType type() { return _type; } diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index ea7f3412d..47e28a788 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -102,7 +102,7 @@ private: void build_segment(Geom::PathBuilder &, Node *, Node *); PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, - Geom::Matrix const &et, guint32 outline_color, Glib::ustring lpe_key) + Geom::Affine const &et, guint32 outline_color, Glib::ustring lpe_key) : PointManipulator(mpm._path_data.node_data.desktop, *mpm._path_data.node_data.selection) , _subpaths(*this) , _multi_path_manipulator(mpm) @@ -847,9 +847,9 @@ void PathManipulator::setLiveObjects(bool set) _live_objects = set; } -void PathManipulator::setControlsTransform(Geom::Matrix const &tnew) +void PathManipulator::setControlsTransform(Geom::Affine const &tnew) { - Geom::Matrix delta = _i2d_transform.inverse() * _edit_transform.inverse() * tnew * _i2d_transform; + Geom::Affine delta = _i2d_transform.inverse() * _edit_transform.inverse() * tnew * _i2d_transform; _edit_transform = tnew; for (SubpathList::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) { for (NodeList::iterator j = (*i)->begin(); j != (*i)->end(); ++j) { @@ -894,7 +894,7 @@ NodeList::iterator PathManipulator::subdivideSegment(NodeList::iterator first, d // build bezier curve and subdivide Geom::CubicBezier temp(first->position(), first->front()->position(), second->back()->position(), second->position()); - std::pair div = temp.subdivide(t); + std::pair div = temp.subdivide(t); std::vector seg1 = div.first.points(), seg2 = div.second.points(); // set new handle positions @@ -975,7 +975,7 @@ void PathManipulator::_externalChange(unsigned type) _updateOutline(); } break; case PATH_CHANGE_TRANSFORM: { - Geom::Matrix i2d_change = _d2i_transform; + Geom::Affine i2d_change = _d2i_transform; _i2d_transform = SP_ITEM(_path)->i2d_affine(); _d2i_transform = _i2d_transform.inverse(); i2d_change *= _i2d_transform; @@ -1388,7 +1388,7 @@ void PathManipulator::_commit(Glib::ustring const &annotation, gchar const *key) * point of the path. */ void PathManipulator::_updateDragPoint(Geom::Point const &evp) { - Geom::Matrix to_desktop = _edit_transform * _i2d_transform; + Geom::Affine to_desktop = _edit_transform * _i2d_transform; Geom::PathVector pv = _spcurve->get_pathvector(); boost::optional pvp = Geom::nearestPoint(pv, _desktop->w2d(evp) * to_desktop.inverse()); diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 58907ea96..27a83f06b 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -14,7 +14,7 @@ #include #include #include <2geom/pathvector.h> -#include <2geom/matrix.h> +#include <2geom/affine.h> #include #include #include "forward.h" @@ -53,7 +53,7 @@ class PathManipulator : public PointManipulator { public: typedef SPPath *ItemType; - PathManipulator(MultiPathManipulator &mpm, SPPath *path, Geom::Matrix const &edit_trans, + PathManipulator(MultiPathManipulator &mpm, SPPath *path, Geom::Affine const &edit_trans, guint32 outline_color, Glib::ustring lpe_key); ~PathManipulator(); virtual bool event(GdkEvent *); @@ -85,7 +85,7 @@ public: void showPathDirection(bool show); void setLiveOutline(bool set); void setLiveObjects(bool set); - void setControlsTransform(Geom::Matrix const &); + void setControlsTransform(Geom::Affine const &); void hideDragPoint(); MultiPathManipulator &mpm() { return _multi_path_manipulator; } @@ -134,9 +134,9 @@ private: SPCanvasItem *_outline; CurveDragPoint *_dragpoint; // an invisible control point hoverng over curve PathManipulatorObserver *_observer; - Geom::Matrix _d2i_transform; ///< desktop-to-item transform - Geom::Matrix _i2d_transform; ///< item-to-desktop transform, inverse of _d2i_transform - Geom::Matrix _edit_transform; ///< additional transform to apply to editing controls + Geom::Affine _d2i_transform; ///< desktop-to-item transform + Geom::Affine _i2d_transform; ///< item-to-desktop transform, inverse of _d2i_transform + Geom::Affine _edit_transform; ///< additional transform to apply to editing controls unsigned _num_selected; ///< number of selected nodes bool _show_handles; bool _show_outline; diff --git a/src/ui/tool/shape-record.h b/src/ui/tool/shape-record.h index 893231404..646e6f4f6 100644 --- a/src/ui/tool/shape-record.h +++ b/src/ui/tool/shape-record.h @@ -14,7 +14,7 @@ #include #include -#include <2geom/matrix.h> +#include <2geom/affine.h> class SPItem; namespace Inkscape { @@ -32,7 +32,7 @@ struct ShapeRecord : public boost::totally_ordered { SPItem *item; // SP node for the edited shape - Geom::Matrix edit_transform; // how to transform controls - used for clipping paths and masks + Geom::Affine edit_transform; // how to transform controls - used for clipping paths and masks ShapeRole role; Glib::ustring lpe_key; // name of LPE shape param being edited diff --git a/src/ui/tool/transform-handle-set.cpp b/src/ui/tool/transform-handle-set.cpp index 5c3b494ce..26263c26b 100644 --- a/src/ui/tool/transform-handle-set.cpp +++ b/src/ui/tool/transform-handle-set.cpp @@ -94,10 +94,10 @@ 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 _snap_points; @@ -129,10 +129,10 @@ private: } 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; @@ -202,7 +202,7 @@ protected: 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; @@ -257,7 +257,7 @@ protected: _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; @@ -294,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((_side + 1) % 2); @@ -313,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; @@ -351,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); @@ -359,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; @@ -425,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 @@ -458,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; @@ -645,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); diff --git a/src/ui/tool/transform-handle-set.h b/src/ui/tool/transform-handle-set.h index b18c598ee..0557b1278 100644 --- a/src/ui/tool/transform-handle-set.h +++ b/src/ui/tool/transform-handle-set.h @@ -50,10 +50,10 @@ public: bool transforming() { return _in_transform; } ControlPoint &rotationCenter(); - sigc::signal signal_transform; + sigc::signal signal_transform; sigc::signal signal_commit; private: - void _emitTransform(Geom::Matrix const &); + void _emitTransform(Geom::Affine const &); void _setActiveHandle(ControlPoint *h); void _clearActiveHandle(); void _updateVisibility(bool v); -- cgit v1.2.3 From fb749ad5edae38b062e00d1593ec0d306bac4ada Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sat, 5 Feb 2011 03:04:47 +0100 Subject: Fix node tool brokenness resulting from a switch to runtime order in 2Geom's BezierCurve (bzr r10035) --- src/ui/tool/path-manipulator.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/ui/tool') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 47e28a788..0e5705ee4 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1039,13 +1039,14 @@ void PathManipulator::_createControlPointsFromGeometry() subpath->push_back(current_node); } // if this is a bezier segment, move handles appropriately - if (Geom::CubicBezier const *cubic_bezier = - dynamic_cast(&*cit)) + // TODO: I don't know why the dynamic cast below doesn't want to work + // when I replace BezierCurve with CubicBezier. Might be a bug + // somewhere in pathv_to_linear_and_cubic_beziers + Geom::BezierCurve const *bezier = dynamic_cast(&*cit); + if (bezier && bezier->order() == 3) { - std::vector points = cubic_bezier->points(); - - previous_node->front()->setPosition(points[1]); - current_node ->back() ->setPosition(points[2]); + previous_node->front()->setPosition((*bezier)[1]); + current_node ->back() ->setPosition((*bezier)[2]); } previous_node = current_node; } -- cgit v1.2.3 From c8ec8ac8c5a3665adf39b1a939404027395ace0e Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 13 Feb 2011 21:06:36 +0100 Subject: update to latest 2geom. fixes bezier curve casts. (bzr r10050) --- src/ui/tool/path-manipulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui/tool') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 0e5705ee4..1e0dc85a4 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -894,7 +894,7 @@ NodeList::iterator PathManipulator::subdivideSegment(NodeList::iterator first, d // build bezier curve and subdivide Geom::CubicBezier temp(first->position(), first->front()->position(), second->back()->position(), second->position()); - std::pair div = temp.subdivide(t); + std::pair div = temp.subdivide(t); std::vector seg1 = div.first.points(), seg2 = div.second.points(); // set new handle positions -- cgit v1.2.3 From b7c5598b9c8dcb471747713503e21a09bb0a5ca0 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Mon, 21 Feb 2011 16:01:57 -0800 Subject: Finished cleanup of outdated SP_OBJECT_STYLE C macro. (bzr r10066) --- src/ui/tool/path-manipulator.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/ui/tool') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 1e0dc85a4..7c2013872 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -109,7 +109,7 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, , _path(path) , _spcurve(new SPCurve()) , _dragpoint(new CurveDragPoint(*this)) - , /* XML Tree being used here directly while it shouldn't be*/_observer(new PathManipulatorObserver(this, SP_OBJECT(path)->getRepr())) + , /* XML Tree being used here directly while it shouldn't be*/_observer(new PathManipulatorObserver(this, path->getRepr())) , _edit_transform(et) , _num_selected(0) , _show_handles(true) @@ -191,7 +191,7 @@ void PathManipulator::writeXML() if (!_path) return; _observer->block(); if (!empty()) { - SP_OBJECT(_path)->updateRepr(); + _path->updateRepr(); _getXMLNode()->setAttribute(_nodetypesKey().data(), _createTypeString().data()); } else { // this manipulator will have to be destroyed right after this call @@ -1430,8 +1430,8 @@ double PathManipulator::_getStrokeTolerance() * drag tolerance setting. */ Inkscape::Preferences *prefs = Inkscape::Preferences::get(); double ret = prefs->getIntLimited("/options/dragtolerance/value", 2, 0, 100); - if (_path && SP_OBJECT_STYLE(_path) && !SP_OBJECT_STYLE(_path)->stroke.isNone()) { - ret += SP_OBJECT_STYLE(_path)->stroke_width.computed * 0.5 + if (_path && _path->style && !_path->style->stroke.isNone()) { + ret += _path->style->stroke_width.computed * 0.5 * (_edit_transform * _i2d_transform).descrim() // scale to desktop coords * _desktop->current_zoom(); // == _d2w.descrim() - scale to window coords } -- cgit v1.2.3 From 76ad5cbf7bbdd4272b2d49387fdc10ca808767d7 Mon Sep 17 00:00:00 2001 From: Adib Taraben Date: Sun, 27 Feb 2011 21:48:16 +0100 Subject: compatibility patch to compile using gcc 4.6 Fixed bugs: - https://launchpad.net/bugs/707205 (bzr r10070.1.1) --- src/ui/tool/control-point-selection.h | 1 + src/ui/tool/control-point.h | 1 + src/ui/tool/manipulator.h | 1 + src/ui/tool/multi-path-manipulator.h | 1 + src/ui/tool/node-tool.h | 1 + src/ui/tool/node.h | 1 + 6 files changed, 6 insertions(+) (limited to 'src/ui/tool') diff --git a/src/ui/tool/control-point-selection.h b/src/ui/tool/control-point-selection.h index a9c929cb1..7e09d50f5 100644 --- a/src/ui/tool/control-point-selection.h +++ b/src/ui/tool/control-point-selection.h @@ -14,6 +14,7 @@ #include #include +#include #include #include <2geom/forward.h> #include <2geom/point.h> diff --git a/src/ui/tool/control-point.h b/src/ui/tool/control-point.h index 0b88786e5..9f62fca42 100644 --- a/src/ui/tool/control-point.h +++ b/src/ui/tool/control-point.h @@ -12,6 +12,7 @@ #define SEEN_UI_TOOL_CONTROL_POINT_H #include +#include #include #include #include diff --git a/src/ui/tool/manipulator.h b/src/ui/tool/manipulator.h index fd24e7b61..6866ec9dd 100644 --- a/src/ui/tool/manipulator.h +++ b/src/ui/tool/manipulator.h @@ -13,6 +13,7 @@ #include #include +#include #include #include #include diff --git a/src/ui/tool/multi-path-manipulator.h b/src/ui/tool/multi-path-manipulator.h index aef9c1ac9..c25719790 100644 --- a/src/ui/tool/multi-path-manipulator.h +++ b/src/ui/tool/multi-path-manipulator.h @@ -11,6 +11,7 @@ #ifndef SEEN_UI_TOOL_MULTI_PATH_MANIPULATOR_H #define SEEN_UI_TOOL_MULTI_PATH_MANIPULATOR_H +#include #include #include "forward.h" #include "ui/tool/commit-events.h" diff --git a/src/ui/tool/node-tool.h b/src/ui/tool/node-tool.h index bcf6a8d5e..d005a0bdf 100644 --- a/src/ui/tool/node-tool.h +++ b/src/ui/tool/node-tool.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "event-context.h" #include "forward.h" diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 451915dbe..b7145790b 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From 434ac15158aec9c65c8d61c936788d8358ed3157 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 2 Apr 2011 01:02:33 +0200 Subject: use shape's curve before LPE as flash path in node tool. so now, you should see a flashing path for all shapes now (bzr r10143) --- src/ui/tool/node-tool.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/ui/tool') diff --git a/src/ui/tool/node-tool.cpp b/src/ui/tool/node-tool.cpp index e75f31370..f83f8c473 100644 --- a/src/ui/tool/node-tool.cpp +++ b/src/ui/tool/node-tool.cpp @@ -480,10 +480,11 @@ gint ink_node_tool_root_handler(SPEventContext *event_context, GdkEvent *event) nt->flash_tempitem = NULL; nt->flashed_item = NULL; } - if (!SP_IS_PATH(over_item)) break; // for now, handle only paths + if (!SP_IS_SHAPE(over_item)) break; // for now, handle only shapes nt->flashed_item = over_item; - SPCurve *c = sp_path_get_curve_for_edit(SP_PATH(over_item)); + SPCurve *c = SP_SHAPE(over_item)->getCurveBeforeLPE(); + if (!c) break; // break out when curve doesn't exist c->transform(over_item->i2d_affine()); SPCanvasItem *flash = sp_canvas_bpath_new(sp_desktop_tempgroup(desktop), c); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(flash), -- cgit v1.2.3