diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2010-03-14 17:38:50 +0000 |
|---|---|---|
| committer | Krzysztof KosiĆski <tweenk.pl@gmail.com> | 2010-03-14 17:38:50 +0000 |
| commit | 90e813701a7865bc36755fb0f35ab74c4b6963a2 (patch) | |
| tree | 460a5260664b3e83e736918f5d2594445c3761c7 /src/ui/tool/path-manipulator.cpp | |
| parent | disable console output on windows per default, as this probably annoys many b... (diff) | |
| download | inkscape-90e813701a7865bc36755fb0f35ab74c4b6963a2.tar.gz inkscape-90e813701a7865bc36755fb0f35ab74c4b6963a2.zip | |
Implement keyboard shortcuts for single handle adjustments.
Minor disambiguating cleanup in node.h.
(bzr r9190)
Diffstat (limited to 'src/ui/tool/path-manipulator.cpp')
| -rw-r--r-- | src/ui/tool/path-manipulator.cpp | 79 |
1 files changed, 74 insertions, 5 deletions
diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 0b0254108..d395d0e0a 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -598,10 +598,10 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite // We can't use nl->erase(start, end), because it would break when the stretch // crosses the beginning of a closed subpath - NodeList *nl = start->list(); + NodeList &nl = start->nodeList(); while (start != end) { NodeList::iterator next = start.next(); - nl->erase(start); + nl.erase(start); start = next; } @@ -728,6 +728,68 @@ void PathManipulator::setSegmentType(SegmentType type) } } +void PathManipulator::scaleHandle(Node *n, int which, int dir, bool pixel) +{ + if (n->type() == NODE_SYMMETRIC || n->type() == NODE_AUTO) { + n->setType(NODE_SMOOTH); + } + Handle *h = _chooseHandle(n, which); + double length_change; + + if (pixel) { + length_change = 1.0 / _desktop->current_zoom() * dir; + } else { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + length_change = prefs->getDoubleLimited("/options/defaultscale/value", 2, 1, 1000); + length_change *= dir; + } + + Geom::Point relpos = h->relativePos(); + double rellen = relpos.length(); + h->setRelativePos(relpos * ((rellen + length_change) / rellen)); + update(); + + gchar const *key = which < 0 ? "handle:scale:left" : "handle:scale:right"; + _commit(_("Scale handle"), key); +} + +void PathManipulator::rotateHandle(Node *n, int which, int dir, bool pixel) +{ + if (n->type() != NODE_CUSP) { + n->setType(NODE_CUSP); + } + Handle *h = _chooseHandle(n, which); + double angle; + + if (pixel) { + // Rotate by "one pixel" + angle = atan2(1.0 / _desktop->current_zoom(), h->length()) * dir; + } else { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int snaps = prefs->getIntLimited("/options/rotationsnapsperpi/value", 12, 1, 1000); + angle = M_PI * dir / snaps; + } + h->setRelativePos(h->relativePos() * Geom::Rotate(angle)); + update(); + gchar const *key = which < 0 ? "handle:rotate:left" : "handle:rotate:right"; + _commit(_("Rotate handle"), key); +} + +Handle *PathManipulator::_chooseHandle(Node *n, int which) +{ + Geom::Point f = n->front()->position(), b = n->back()->position(); + if (which < 0) { + // pick left handle. + // we just swap the handles and pick the right handle below. + std::swap(f, b); + } + if (f[Geom::X] >= b[Geom::X]) { + return n->front(); + } else { + return n->back(); + } +} + /** Set the visibility of handles. */ void PathManipulator::showHandles(bool show) { @@ -1187,11 +1249,11 @@ bool PathManipulator::_nodeClicked(Node *n, GdkEventButton *event) // Ctrl+Alt+click: delete nodes hideDragPoint(); NodeList::iterator iter = NodeList::get_iterator(n); - NodeList *nl = iter->list(); + NodeList &nl = iter->nodeList(); - if (nl->size() <= 1 || (nl->size() <= 2 && !nl->closed())) { + if (nl.size() <= 1 || (nl.size() <= 2 && !nl.closed())) { // Removing last node of closed path - delete it - nl->kill(); + nl.kill(); } else { // In other cases, delete the node under cursor _deleteStretch(iter, iter.next(), true); @@ -1304,6 +1366,13 @@ void PathManipulator::_commit(Glib::ustring const &annotation) sp_document_done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_NODE, annotation.data()); } +void PathManipulator::_commit(Glib::ustring const &annotation, gchar const *key) +{ + writeXML(); + sp_document_maybe_done(sp_desktop_document(_desktop), key, SP_VERB_CONTEXT_NODE, + annotation.data()); +} + /** Update the position of the curve drag point such that it is over the nearest * point of the path. */ void PathManipulator::_updateDragPoint(Geom::Point const &evp) |
