summaryrefslogtreecommitdiffstats
path: root/src/ui/tool
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2010-11-25 20:51:17 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2010-11-25 20:51:17 +0000
commit0bd9f7e209d522dbcebe0449a91397fdd9e38977 (patch)
tree834c7d02456658b57625ab68cc28f7854a5a85dc /src/ui/tool
parentFix handling of x and y attributes of patterns (diff)
parentFix ruler redraw issue on GTK 2.22 (diff)
downloadinkscape-0bd9f7e209d522dbcebe0449a91397fdd9e38977.tar.gz
inkscape-0bd9f7e209d522dbcebe0449a91397fdd9e38977.zip
Merge from trunk
(bzr r9508.1.70)
Diffstat (limited to 'src/ui/tool')
-rw-r--r--src/ui/tool/commit-events.h2
-rw-r--r--src/ui/tool/control-point-selection.cpp2
-rw-r--r--src/ui/tool/control-point-selection.h2
-rw-r--r--src/ui/tool/control-point.cpp9
-rw-r--r--src/ui/tool/control-point.h2
-rw-r--r--src/ui/tool/curve-drag-point.cpp2
-rw-r--r--src/ui/tool/curve-drag-point.h2
-rw-r--r--src/ui/tool/event-utils.cpp2
-rw-r--r--src/ui/tool/event-utils.h2
-rw-r--r--src/ui/tool/manipulator.cpp2
-rw-r--r--src/ui/tool/manipulator.h2
-rw-r--r--src/ui/tool/modifier-tracker.cpp2
-rw-r--r--src/ui/tool/modifier-tracker.h2
-rw-r--r--src/ui/tool/multi-path-manipulator.cpp50
-rw-r--r--src/ui/tool/multi-path-manipulator.h3
-rw-r--r--src/ui/tool/node-tool.cpp52
-rw-r--r--src/ui/tool/node-tool.h5
-rw-r--r--src/ui/tool/node-types.h2
-rw-r--r--src/ui/tool/node.cpp59
-rw-r--r--src/ui/tool/node.h2
-rw-r--r--src/ui/tool/path-manipulator.cpp52
-rw-r--r--src/ui/tool/path-manipulator.h3
-rw-r--r--src/ui/tool/selectable-control-point.cpp2
-rw-r--r--src/ui/tool/selectable-control-point.h2
-rw-r--r--src/ui/tool/selector.cpp2
-rw-r--r--src/ui/tool/selector.h2
-rw-r--r--src/ui/tool/shape-record.h2
-rw-r--r--src/ui/tool/transform-handle-set.cpp2
-rw-r--r--src/ui/tool/transform-handle-set.h2
29 files changed, 197 insertions, 78 deletions
diff --git a/src/ui/tool/commit-events.h b/src/ui/tool/commit-events.h
index d99872766..110564ba3 100644
--- a/src/ui/tool/commit-events.h
+++ b/src/ui/tool/commit-events.h
@@ -48,4 +48,4 @@ enum CommitEvent {
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/control-point-selection.cpp b/src/ui/tool/control-point-selection.cpp
index 615587eeb..91e0bc2c2 100644
--- a/src/ui/tool/control-point-selection.cpp
+++ b/src/ui/tool/control-point-selection.cpp
@@ -654,4 +654,4 @@ bool ControlPointSelection::event(GdkEvent *event)
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/control-point-selection.h b/src/ui/tool/control-point-selection.h
index 8023c3e28..3aed6ae93 100644
--- a/src/ui/tool/control-point-selection.h
+++ b/src/ui/tool/control-point-selection.h
@@ -159,4 +159,4 @@ private:
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/control-point.cpp b/src/ui/tool/control-point.cpp
index b74e3bc9c..d5e5b7dfe 100644
--- a/src/ui/tool/control-point.cpp
+++ b/src/ui/tool/control-point.cpp
@@ -329,7 +329,7 @@ bool ControlPoint::_eventHandler(GdkEvent *event)
_setState(STATE_CLICKED);
return true;
}
- return false;
+ return _event_grab;
case GDK_2BUTTON_PRESS:
// store the button number for next release
@@ -452,8 +452,9 @@ bool ControlPoint::_eventHandler(GdkEvent *event)
default: break;
}
-
- return false;
+
+ // do not propagate events during grab - it might cause problems
+ return _event_grab;
}
void ControlPoint::_setMouseover(ControlPoint *p, unsigned state)
@@ -578,4 +579,4 @@ bool ControlPoint::doubleclicked(GdkEventButton *) { return false; }
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/control-point.h b/src/ui/tool/control-point.h
index 48c70748b..4de5e5847 100644
--- a/src/ui/tool/control-point.h
+++ b/src/ui/tool/control-point.h
@@ -199,4 +199,4 @@ extern ControlPoint::ColorSet invisible_cset;
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp
index 0e5805dda..a3fb5aa6e 100644
--- a/src/ui/tool/curve-drag-point.cpp
+++ b/src/ui/tool/curve-drag-point.cpp
@@ -193,4 +193,4 @@ Glib::ustring CurveDragPoint::_getTip(unsigned state)
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/curve-drag-point.h b/src/ui/tool/curve-drag-point.h
index 288ae6a8e..42a4930c8 100644
--- a/src/ui/tool/curve-drag-point.h
+++ b/src/ui/tool/curve-drag-point.h
@@ -59,4 +59,4 @@ private:
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/event-utils.cpp b/src/ui/tool/event-utils.cpp
index 91b2cdb04..ef2d27653 100644
--- a/src/ui/tool/event-utils.cpp
+++ b/src/ui/tool/event-utils.cpp
@@ -153,4 +153,4 @@ unsigned state_after_event(GdkEvent *event)
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/event-utils.h b/src/ui/tool/event-utils.h
index 784855f56..de29c3dda 100644
--- a/src/ui/tool/event-utils.h
+++ b/src/ui/tool/event-utils.h
@@ -129,4 +129,4 @@ unsigned state_after_event(GdkEvent *event);
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/manipulator.cpp b/src/ui/tool/manipulator.cpp
index b532fcab4..49e601797 100644
--- a/src/ui/tool/manipulator.cpp
+++ b/src/ui/tool/manipulator.cpp
@@ -86,4 +86,4 @@ bool ManipulatorGroup::event(GdkEvent *event)
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/manipulator.h b/src/ui/tool/manipulator.h
index 799dad0d3..fd24e7b61 100644
--- a/src/ui/tool/manipulator.h
+++ b/src/ui/tool/manipulator.h
@@ -162,4 +162,4 @@ protected:
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/modifier-tracker.cpp b/src/ui/tool/modifier-tracker.cpp
index 8c6033bc7..bbef0d469 100644
--- a/src/ui/tool/modifier-tracker.cpp
+++ b/src/ui/tool/modifier-tracker.cpp
@@ -90,4 +90,4 @@ bool ModifierTracker::event(GdkEvent *event)
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/modifier-tracker.h b/src/ui/tool/modifier-tracker.h
index 55538ead6..8c8787e87 100644
--- a/src/ui/tool/modifier-tracker.h
+++ b/src/ui/tool/modifier-tracker.h
@@ -51,4 +51,4 @@ private:
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp
index 2025a12d7..82446b7b4 100644
--- a/src/ui/tool/multi-path-manipulator.cpp
+++ b/src/ui/tool/multi-path-manipulator.cpp
@@ -220,11 +220,29 @@ void MultiPathManipulator::invertSelectionInSubpaths()
void MultiPathManipulator::setNodeType(NodeType type)
{
if (_selection.empty()) return;
+
+ // When all selected nodes are already cusp, retract their handles
+ bool retract_handles = (type == NODE_CUSP);
+
for (ControlPointSelection::iterator i = _selection.begin(); i != _selection.end(); ++i) {
Node *node = dynamic_cast<Node*>(*i);
- if (node) node->setType(type);
+ if (node) {
+ retract_handles &= (node->type() == NODE_CUSP);
+ node->setType(type);
+ }
+ }
+
+ if (retract_handles) {
+ for (ControlPointSelection::iterator i = _selection.begin(); i != _selection.end(); ++i) {
+ Node *node = dynamic_cast<Node*>(*i);
+ if (node) {
+ node->front()->retract();
+ node->back()->retract();
+ }
+ }
}
- _done(_("Change node type"));
+
+ _done(retract_handles ? _("Retract handles") : _("Change node type"));
}
void MultiPathManipulator::setSegmentType(SegmentType type)
@@ -244,6 +262,12 @@ void MultiPathManipulator::insertNodes()
_done(_("Add nodes"));
}
+void MultiPathManipulator::duplicateNodes()
+{
+ invokeForAll(&PathManipulator::duplicateNodes);
+ _done(_("Duplicate nodes"));
+}
+
void MultiPathManipulator::joinNodes()
{
invokeForAll(&PathManipulator::hideDragPoint);
@@ -513,6 +537,12 @@ bool MultiPathManipulator::event(GdkEvent *event)
return true;
}
break;
+ case GDK_d:
+ case GDK_D:
+ if (held_only_shift(event->key)) {
+ duplicateNodes();
+ return true;
+ }
case GDK_j:
case GDK_J:
if (held_only_shift(event->key)) {
@@ -591,6 +621,20 @@ bool MultiPathManipulator::event(GdkEvent *event)
return true;
}
break;
+ case GDK_l:
+ case GDK_L:
+ if (held_only_shift(event->key)) {
+ // Shift+L - make segments linear
+ setSegmentType(SEGMENT_STRAIGHT);
+ return true;
+ }
+ case GDK_u:
+ case GDK_U:
+ if (held_only_shift(event->key)) {
+ // Shift+L - make segments curves
+ setSegmentType(SEGMENT_CUBIC_BEZIER);
+ return true;
+ }
default:
break;
}
@@ -714,4 +758,4 @@ guint32 MultiPathManipulator::_getOutlineColor(ShapeRole role)
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/multi-path-manipulator.h b/src/ui/tool/multi-path-manipulator.h
index 181ae6d1d..ddb74c1bc 100644
--- a/src/ui/tool/multi-path-manipulator.h
+++ b/src/ui/tool/multi-path-manipulator.h
@@ -53,6 +53,7 @@ public:
void setSegmentType(SegmentType t);
void insertNodes();
+ void duplicateNodes();
void joinNodes();
void breakNodes();
void deleteNodes(bool keep_shape = true);
@@ -135,4 +136,4 @@ private:
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/node-tool.cpp b/src/ui/tool/node-tool.cpp
index 450ca96f0..8008d79eb 100644
--- a/src/ui/tool/node-tool.cpp
+++ b/src/ui/tool/node-tool.cpp
@@ -25,6 +25,7 @@
#include "sp-mask.h"
#include "sp-object-group.h"
#include "sp-path.h"
+#include "sp-text.h"
#include "ui/tool/node-tool.h"
#include "ui/tool/control-point-selection.h"
#include "ui/tool/curve-drag-point.h"
@@ -164,6 +165,7 @@ void ink_node_tool_init(InkNodeTool *nt)
new (&nt->_multipath) MultiPathPtr();
new (&nt->_selector) SelectorPtr();
new (&nt->_path_data) PathSharedDataPtr();
+ new (&nt->_shape_editors) ShapeEditors();
}
void ink_node_tool_dispose(GObject *object)
@@ -178,6 +180,7 @@ void ink_node_tool_dispose(GObject *object)
nt->_multipath.~MultiPathPtr();
nt->_selected_nodes.~CSelPtr();
nt->_selector.~SelectorPtr();
+ nt->_shape_editors.~ShapeEditors();
Inkscape::UI::PathSharedData &data = *nt->_path_data;
destroy_group(data.node_data.node_group);
@@ -195,10 +198,6 @@ void ink_node_tool_dispose(GObject *object)
if (nt->_node_message_context) {
delete nt->_node_message_context;
}
- if (nt->shape_editor) {
- nt->shape_editor->unset_item(SH_KNOTHOLDER);
- delete nt->shape_editor;
- }
G_OBJECT_CLASS(g_type_class_peek(g_type_parent(INK_TYPE_NODE_TOOL)))->dispose(object);
}
@@ -281,9 +280,6 @@ void ink_node_tool_setup(SPEventContext *ec)
nt->flash_tempitem = NULL;
nt->flashed_item = NULL;
nt->_last_over = NULL;
- // TODO long term, fold ShapeEditor into MultiPathManipulator and rename MPM
- // to something better
- nt->shape_editor = new ShapeEditor(nt->desktop);
// read prefs before adding items to selection to prevent momentarily showing the outline
sp_event_context_read(nt, "show_handles");
@@ -403,22 +399,30 @@ void ink_node_tool_selection_changed(InkNodeTool *nt, Inkscape::Selection *sel)
}
}
- // ugly hack: set the first editable non-path item for knotholder
- // maybe use multiple ShapeEditors for now, to allow editing many shapes at once?
- bool something_set = false;
+ // use multiple ShapeEditors for now, to allow editing many shapes at once
+ // needs to be rethought
+ for (ShapeEditors::iterator i = nt->_shape_editors.begin();
+ i != nt->_shape_editors.end(); )
+ {
+ ShapeRecord s;
+ s.item = i->first;
+ if (shapes.find(s) == shapes.end()) {
+ nt->_shape_editors.erase(i++);
+ } else {
+ ++i;
+ }
+ }
+
for (std::set<ShapeRecord>::iterator i = shapes.begin(); i != shapes.end(); ++i) {
ShapeRecord const &r = *i;
- if (SP_IS_SHAPE(r.item) ||
- (SP_IS_PATH(r.item) && r.item->repr->attribute("inkscape:original-d") != NULL))
+ if ((SP_IS_SHAPE(r.item) || SP_IS_TEXT(r.item)) &&
+ nt->_shape_editors.find(r.item) == nt->_shape_editors.end())
{
- nt->shape_editor->set_item(r.item, SH_KNOTHOLDER);
- something_set = true;
- break;
+ ShapeEditor *si = new ShapeEditor(nt->desktop);
+ si->set_item(r.item, SH_KNOTHOLDER);
+ nt->_shape_editors.insert(const_cast<SPItem*&>(r.item), si);
}
}
- if (!something_set) {
- nt->shape_editor->unset_item(SH_KNOTHOLDER);
- }
nt->_multipath->setItems(shapes);
ink_node_tool_update_tip(nt, NULL);
@@ -615,8 +619,14 @@ void ink_node_tool_select_point(InkNodeTool *nt, Geom::Point const &/*sel*/, Gdk
if (item_clicked == NULL) { // nothing under cursor
// if no Shift, deselect
- if (!(event->state & GDK_SHIFT_MASK)) {
- selection->clear();
+ // if there are nodes selected, the first click should deselect the nodes
+ // and the second should deselect the items
+ if (!state_held_shift(event->state)) {
+ if (nt->_selected_nodes->empty()) {
+ selection->clear();
+ } else {
+ nt->_selected_nodes->clear();
+ }
}
} else {
if (held_shift(*event)) {
@@ -658,4 +668,4 @@ void ink_node_tool_mouseover_changed(InkNodeTool *nt, Inkscape::UI::ControlPoint
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/node-tool.h b/src/ui/tool/node-tool.h
index 641d064c1..4d38e69e2 100644
--- a/src/ui/tool/node-tool.h
+++ b/src/ui/tool/node-tool.h
@@ -12,6 +12,7 @@
#define SEEN_UI_TOOL_NODE_TOOL_H
#include <memory>
+#include <boost/ptr_container/ptr_map.hpp>
#include <glib.h>
#include <sigc++/sigc++.h>
#include "event-context.h"
@@ -41,6 +42,7 @@ typedef std::auto_ptr<Inkscape::UI::MultiPathManipulator> MultiPathPtr;
typedef std::auto_ptr<Inkscape::UI::ControlPointSelection> CSelPtr;
typedef std::auto_ptr<Inkscape::UI::Selector> SelectorPtr;
typedef std::auto_ptr<Inkscape::UI::PathSharedData> PathSharedDataPtr;
+typedef boost::ptr_map<SPItem*, ShapeEditor> ShapeEditors;
struct InkNodeTool : public SPEventContext
{
@@ -56,6 +58,7 @@ struct InkNodeTool : public SPEventContext
PathSharedDataPtr _path_data;
SPCanvasGroup *_transform_handle_group;
SPItem *_last_over;
+ ShapeEditors _shape_editors;
unsigned cursor_drag : 1;
unsigned show_handles : 1;
@@ -86,4 +89,4 @@ GType ink_node_tool_get_type (void);
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/node-types.h b/src/ui/tool/node-types.h
index 80eaf4fa7..e4921fa8d 100644
--- a/src/ui/tool/node-types.h
+++ b/src/ui/tool/node-types.h
@@ -45,4 +45,4 @@ enum SegmentType {
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp
index a8582ccc5..12d04dd2b 100644
--- a/src/ui/tool/node.cpp
+++ b/src/ui/tool/node.cpp
@@ -274,8 +274,10 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event)
} else {
sm.freeSnapReturnByRef(new_pos, SNAPSOURCE_NODE_HANDLE);
}
+ sm.unSetup();
}
+
// with Shift, if the node is cusp, rotate the other handle as well
if (_parent->type() == NODE_CUSP && !_drag_out) {
if (held_shift(*event)) {
@@ -566,11 +568,7 @@ void Node::setType(NodeType type, bool update_handles)
if (update_handles) {
switch (type) {
case NODE_CUSP:
- // if the existing type is also NODE_CUSP, retract handles
- if (_type == NODE_CUSP) {
- _front.retract();
- _back.retract();
- }
+ // nothing to do
break;
case NODE_AUTO:
// auto handles make no sense for endnodes
@@ -578,13 +576,15 @@ void Node::setType(NodeType type, bool update_handles)
_updateAutoHandles();
break;
case NODE_SMOOTH: {
+ // ignore attempts to make smooth endnodes.
+ if (isEndNode()) return;
// rotate handles to be colinear
// for degenerate nodes set positions like auto handles
bool prev_line = _is_line_segment(_prev(), this);
bool next_line = _is_line_segment(this, _next());
if (_type == NODE_SMOOTH) {
- // for a node that is already smooth and has a degenerate handle,
- // drag out the second handle to 1/3 the length of the linear segment
+ // For a node that is already smooth and has a degenerate handle,
+ // drag out the second handle without changing the direction of the first one.
if (_front.isDegenerate()) {
double dist = Geom::distance(_next()->position(), position());
_front.setRelativePos(Geom::unit_vector(-_back.relativePos()) * dist / 3);
@@ -728,8 +728,7 @@ NodeType Node::parse_nodetype(char x)
/** Customized event handler to catch scroll events needed for selection grow/shrink. */
bool Node::_eventHandler(GdkEvent *event)
{
- static NodeList::iterator origin;
- static int dir;
+ int dir = 0;
switch (event->type)
{
@@ -740,14 +739,34 @@ bool Node::_eventHandler(GdkEvent *event)
dir = -1;
} else break;
if (held_control(event->scroll)) {
- _selection.spatialGrow(this, dir);
+ _linearGrow(dir);
} else {
+ _selection.spatialGrow(this, dir);
+ }
+ return true;
+ case GDK_KEY_PRESS:
+ switch (shortcut_key(event->key))
+ {
+ case GDK_Page_Up:
+ dir = 1;
+ break;
+ case GDK_Page_Down:
+ dir = -1;
+ break;
+ default: goto bail_out;
+ }
+
+ if (held_control(event->key)) {
_linearGrow(dir);
+ } else {
+ _selection.spatialGrow(this, dir);
}
return true;
default:
break;
}
+
+ bail_out:
return ControlPoint::_eventHandler(event);
}
@@ -942,8 +961,16 @@ 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();
+ // even if we won't really snap, we might still call the one of the
+ // constrainedSnap() methods to enforce the constraints, so we need
+ // to setup the snapmanager anyway; this is also required for someSnapperMightSnap()
+ sm.setup(_desktop);
+
+ // do not snap when Shift is pressed
+ bool snap = !held_shift(*event) && sm.someSnapperMightSnap();
+
Inkscape::SnappedPoint sp;
+ std::vector<Inkscape::SnapCandidatePoint> unselected;
if (snap) {
/* setup
* TODO We are doing this every time a snap happens. It should once be done only once
@@ -953,7 +980,6 @@ 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) {
@@ -963,6 +989,7 @@ void Node::dragged(Geom::Point &new_pos, GdkEventMotion *event)
unselected.push_back(p);
}
}
+ sm.unSetup();
sm.setupIgnoreSelection(_desktop, true, &unselected);
}
@@ -1014,12 +1041,12 @@ void Node::dragged(Geom::Point &new_pos, GdkEventMotion *event)
constraints.push_back(Inkscape::Snapper::SnapConstraint(origin, *bperp_point));
}
- sp = sm.multipleConstrainedSnaps(Inkscape::SnapCandidatePoint(new_pos, _snapSourceType()), constraints);
+ sp = sm.multipleConstrainedSnaps(Inkscape::SnapCandidatePoint(new_pos, _snapSourceType()), constraints, held_shift(*event));
} else {
// with Ctrl, constrain to axes
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);
+ sp = sm.multipleConstrainedSnaps(Inkscape::SnapCandidatePoint(new_pos, _snapSourceType()), constraints, held_shift(*event));
}
new_pos = sp.getPoint();
} else if (snap) {
@@ -1027,6 +1054,8 @@ void Node::dragged(Geom::Point &new_pos, GdkEventMotion *event)
new_pos = sp.getPoint();
}
+ sm.unSetup();
+
SelectableControlPoint::dragged(new_pos, event);
}
@@ -1374,4 +1403,4 @@ NodeList &NodeList::get(iterator const &i) {
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h
index af4cd7e3a..0194f5053 100644
--- a/src/ui/tool/node.h
+++ b/src/ui/tool/node.h
@@ -408,4 +408,4 @@ NodeIterator<N> &NodeIterator<N>::retreat() {
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp
index 66f72f379..956f48a7d 100644
--- a/src/ui/tool/path-manipulator.cpp
+++ b/src/ui/tool/path-manipulator.cpp
@@ -319,6 +319,39 @@ void PathManipulator::insertNodes()
}
}
+/** Insert new nodes exactly at the positions of selected nodes while preserving shape.
+ * This is equivalent to breaking, except that it doesn't split into subpaths. */
+void PathManipulator::duplicateNodes()
+{
+ if (_num_selected == 0) return;
+
+ for (SubpathList::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) {
+ for (NodeList::iterator j = (*i)->begin(); j != (*i)->end(); ++j) {
+ if (j->selected()) {
+ 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();
+
+ 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);
+ }
+ }
+ }
+}
+
/** Replace contiguous selections of nodes in each subpath with one node. */
void PathManipulator::weldNodes(NodeList::iterator preserve_pos)
{
@@ -1292,17 +1325,11 @@ bool PathManipulator::_nodeClicked(Node *n, GdkEventButton *event)
return true;
} else if (held_control(*event)) {
// Ctrl+click: cycle between node types
- if (n->isEndNode()) {
- if (n->type() == NODE_CUSP) {
- n->setType(NODE_SMOOTH);
- } else {
- n->setType(NODE_CUSP);
- }
- } else {
+ if (!n->isEndNode()) {
n->setType(static_cast<NodeType>((n->type() + 1) % NODE_LAST_REAL_TYPE));
+ update();
+ _commit(_("Cycle node type"));
}
- update();
- _commit(_("Cycle node type"));
return true;
}
return false;
@@ -1414,7 +1441,10 @@ void PathManipulator::_updateDragPoint(Geom::Point const &evp)
NodeList::iterator first = (*spi)->before(pvp->t, &fracpart);
double stroke_tolerance = _getStrokeTolerance();
- if (Geom::distance(evp, nearest_point) < stroke_tolerance) {
+ if (first && first.next() &&
+ fracpart != 0.0 &&
+ Geom::distance(evp, nearest_point) < stroke_tolerance)
+ {
_dragpoint->setVisible(true);
_dragpoint->setPosition(_desktop->w2d(nearest_point));
_dragpoint->setSize(2 * stroke_tolerance);
@@ -1459,4 +1489,4 @@ double PathManipulator::_getStrokeTolerance()
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h
index a8f1c957e..87b88fc77 100644
--- a/src/ui/tool/path-manipulator.h
+++ b/src/ui/tool/path-manipulator.h
@@ -69,6 +69,7 @@ public:
void invertSelectionInSubpaths();
void insertNodes();
+ void duplicateNodes();
void weldNodes(NodeList::iterator preserve_pos = NodeList::iterator());
void weldSegments();
void breakNodes();
@@ -162,4 +163,4 @@ private:
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/selectable-control-point.cpp b/src/ui/tool/selectable-control-point.cpp
index 76028dd82..e9a8bcbd6 100644
--- a/src/ui/tool/selectable-control-point.cpp
+++ b/src/ui/tool/selectable-control-point.cpp
@@ -136,4 +136,4 @@ void SelectableControlPoint::_setState(State state)
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/selectable-control-point.h b/src/ui/tool/selectable-control-point.h
index 2fde16ea9..1b8bd46cc 100644
--- a/src/ui/tool/selectable-control-point.h
+++ b/src/ui/tool/selectable-control-point.h
@@ -69,4 +69,4 @@ private:
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/selector.cpp b/src/ui/tool/selector.cpp
index d766d5be3..fdd0fc51f 100644
--- a/src/ui/tool/selector.cpp
+++ b/src/ui/tool/selector.cpp
@@ -130,4 +130,4 @@ bool Selector::event(GdkEvent *event)
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/selector.h b/src/ui/tool/selector.h
index f7c00ea71..e61668d9e 100644
--- a/src/ui/tool/selector.h
+++ b/src/ui/tool/selector.h
@@ -56,4 +56,4 @@ private:
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/shape-record.h b/src/ui/tool/shape-record.h
index edfad1401..893231404 100644
--- a/src/ui/tool/shape-record.h
+++ b/src/ui/tool/shape-record.h
@@ -58,4 +58,4 @@ struct ShapeRecord :
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/transform-handle-set.cpp b/src/ui/tool/transform-handle-set.cpp
index 6b8fb4c11..ef93a3767 100644
--- a/src/ui/tool/transform-handle-set.cpp
+++ b/src/ui/tool/transform-handle-set.cpp
@@ -654,4 +654,4 @@ void TransformHandleSet::_updateVisibility(bool v)
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/tool/transform-handle-set.h b/src/ui/tool/transform-handle-set.h
index 48ad3af51..2a4df8751 100644
--- a/src/ui/tool/transform-handle-set.h
+++ b/src/ui/tool/transform-handle-set.h
@@ -93,4 +93,4 @@ private:
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :