summaryrefslogtreecommitdiffstats
path: root/src/ui/tool
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/tool')
-rw-r--r--src/ui/tool/control-point.cpp15
-rw-r--r--src/ui/tool/control-point.h6
-rw-r--r--src/ui/tool/curve-drag-point.cpp20
-rw-r--r--src/ui/tool/curve-drag-point.h6
-rw-r--r--src/ui/tool/multi-path-manipulator.cpp8
-rw-r--r--src/ui/tool/multi-path-manipulator.h1
-rw-r--r--src/ui/tool/path-manipulator.cpp36
-rw-r--r--src/ui/tool/path-manipulator.h6
-rw-r--r--src/ui/tool/selector.cpp4
-rw-r--r--src/ui/tool/selector.h1
10 files changed, 82 insertions, 21 deletions
diff --git a/src/ui/tool/control-point.cpp b/src/ui/tool/control-point.cpp
index bcf5c9fce..636595016 100644
--- a/src/ui/tool/control-point.cpp
+++ b/src/ui/tool/control-point.cpp
@@ -71,7 +71,8 @@ ControlPoint::ControlPoint(SPDesktop *d, Geom::Point const &initial_pos, SPAncho
_cset(cset),
_state(STATE_NORMAL),
_position(initial_pos),
- _lurking(false)
+ _lurking(false),
+ _double_clicked(false)
{
_canvas_item = sp_canvas_item_new(
group ? group : _desktop->getControls(), SP_TYPE_CTRL,
@@ -80,6 +81,7 @@ ControlPoint::ControlPoint(SPDesktop *d, Geom::Point const &initial_pos, SPAncho
"filled", TRUE, "fill_color", _cset.normal.fill,
"stroked", TRUE, "stroke_color", _cset.normal.stroke,
"mode", SP_CTRL_MODE_XOR, NULL);
+
_commonInit();
}
@@ -91,7 +93,8 @@ ControlPoint::ControlPoint(SPDesktop *d, Geom::Point const &initial_pos, SPAncho
_cset(cset),
_state(STATE_NORMAL),
_position(initial_pos),
- _lurking(false)
+ _lurking(false),
+ _double_clicked(false)
{
_canvas_item = ControlManager::getManager().createControl(group ? group : _desktop->getControls(), type);
g_object_set(_canvas_item,
@@ -245,7 +248,8 @@ bool ControlPoint::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, G
static Geom::Point pointer_offset;
// number of last doubleclicked button
static unsigned next_release_doubleclick = 0;
-
+ _double_clicked = false;
+
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int drag_tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
GdkEventMotion em;
@@ -278,6 +282,7 @@ bool ControlPoint::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, G
Ca = _desktop->canvas;
em = event->motion;
combine_motion_events(Ca, em, 0);
+
if (_event_grab && ! event_context->space_panning) {
_desktop->snapindicator->remove_snaptarget();
bool transferred = false;
@@ -298,6 +303,7 @@ bool ControlPoint::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, G
_drag_initiated = true;
}
}
+
if (!transferred) {
// dragging in progress
Geom::Point new_pos = _desktop->w2d(event_point(event->motion)) + pointer_offset;
@@ -305,7 +311,7 @@ bool ControlPoint::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, G
dragged(new_pos, &em);
move(new_pos);
_updateDragTip(&em); // update dragging tip after moving to new position
-
+
_desktop->scroll_to_point(new_pos);
_desktop->set_coordinate_status(_position);
sp_event_context_snap_delay_handler(event_context, NULL,
@@ -342,6 +348,7 @@ bool ControlPoint::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, G
} else {
// it is the end of a click
if (next_release_doubleclick) {
+ _double_clicked = true;
return doubleclicked(&event->button);
} else {
return clicked(&event->button);
diff --git a/src/ui/tool/control-point.h b/src/ui/tool/control-point.h
index b3ed9545e..4a01b9f21 100644
--- a/src/ui/tool/control-point.h
+++ b/src/ui/tool/control-point.h
@@ -193,6 +193,8 @@ public:
virtual bool _eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEvent *event);
SPDesktop *const _desktop; ///< The desktop this control point resides on.
+ bool doubleClicked() {return _double_clicked;}
+
protected:
struct ColorEntry {
@@ -361,6 +363,8 @@ protected:
/** Events which should be captured when a handle is being dragged. */
static int const _grab_event_mask;
+ static bool _drag_initiated;
+
private:
ControlPoint(ControlPoint const &other);
@@ -397,7 +401,7 @@ private:
static bool _event_grab;
- static bool _drag_initiated;
+ bool _double_clicked;
};
diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp
index 23640456e..d1756fa2c 100644
--- a/src/ui/tool/curve-drag-point.cpp
+++ b/src/ui/tool/curve-drag-point.cpp
@@ -15,6 +15,8 @@
#include "ui/tool/multi-path-manipulator.h"
#include "ui/tool/path-manipulator.h"
#include "ui/tool/node.h"
+#include "sp-namedview.h"
+#include "snap.h"
namespace Inkscape {
namespace UI {
@@ -77,6 +79,16 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event)
return;
}
+ if (_drag_initiated && !(event->state & GDK_SHIFT_MASK)) {
+ SnapManager &m = _desktop->namedview->snap_manager;
+ SPItem *path = static_cast<SPItem *>(_pm._path);
+ m.setup(_desktop, true, path); // We will not try to snap to "path" itself
+ Inkscape::SnapCandidatePoint scp(new_pos, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+ Inkscape::SnappedPoint sp = m.freeSnap(scp, Geom::OptRect(), false);
+ new_pos = sp.getPoint();
+ m.unSetup();
+ }
+
// Magic Bezier Drag Equations follow!
// "weight" describes how the influence of the drag should be distributed
// among the handles; 0 = front handle only, 1 = back handle only.
@@ -166,14 +178,8 @@ void CurveDragPoint::_insertNode(bool take_selection)
// Otherwise clicks on the new node would only work after the user moves the mouse a bit.
// PathManipulator will restore visibility when necessary.
setVisible(false);
- NodeList::iterator inserted = _pm.subdivideSegment(first, _t);
- if (take_selection) {
- _pm._selection.clear();
- }
- _pm._selection.insert(inserted.ptr());
- _pm.update(true);
- _pm._commit(_("Add node"));
+ _pm.insertNode(first, _t, take_selection);
}
Glib::ustring CurveDragPoint::_getTip(unsigned state) const
diff --git a/src/ui/tool/curve-drag-point.h b/src/ui/tool/curve-drag-point.h
index ea83978e0..c1d40575f 100644
--- a/src/ui/tool/curve-drag-point.h
+++ b/src/ui/tool/curve-drag-point.h
@@ -34,7 +34,9 @@ public:
CurveDragPoint(PathManipulator &pm);
void setSize(double sz) { _setSize(sz); }
void setTimeValue(double t) { _t = t; }
+ double getTimeValue() { return _t; }
void setIterator(NodeList::iterator i) { first = i; }
+ NodeList::iterator getIterator() { return first; }
virtual bool _eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEvent *event);
protected:
@@ -47,9 +49,6 @@ protected:
virtual bool doubleclicked(GdkEventButton *);
private:
-
- void _insertNode(bool take_selection);
-
double _t;
PathManipulator &_pm;
NodeList::iterator first;
@@ -57,6 +56,7 @@ private:
static bool _drags_stroke;
static bool _segment_was_degenerate;
static Geom::Point _stroke_drag_origin;
+ void _insertNode(bool take_selection);
};
} // namespace UI
diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp
index f53cef5f4..46c6246a1 100644
--- a/src/ui/tool/multi-path-manipulator.cpp
+++ b/src/ui/tool/multi-path-manipulator.cpp
@@ -339,6 +339,14 @@ void MultiPathManipulator::insertNodesAtExtrema(ExtremumType extremum)
_done(_("Add extremum nodes"));
}
+void MultiPathManipulator::insertNode(Geom::Point pt)
+{
+ // When double clicking to insert nodes, we might not have a selection of nodes (and we don't need one)
+ // so don't check for "_selection.empty()" here, contrary to the other methods above and below this one
+ invokeForAll(&PathManipulator::insertNode, pt);
+ _done(_("Add nodes"));
+}
+
void MultiPathManipulator::duplicateNodes()
{
if (_selection.empty()) return;
diff --git a/src/ui/tool/multi-path-manipulator.h b/src/ui/tool/multi-path-manipulator.h
index 1bbcdd7ec..c908cede2 100644
--- a/src/ui/tool/multi-path-manipulator.h
+++ b/src/ui/tool/multi-path-manipulator.h
@@ -53,6 +53,7 @@ public:
void insertNodesAtExtrema(ExtremumType extremum);
void insertNodes();
+ void insertNode(Geom::Point pt);
void alertLPE();
void duplicateNodes();
void joinNodes();
diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp
index 6b0c95f68..a772c07c2 100644
--- a/src/ui/tool/path-manipulator.cpp
+++ b/src/ui/tool/path-manipulator.cpp
@@ -174,7 +174,8 @@ bool PathManipulator::event(Inkscape::UI::Tools::ToolBase * /*event_context*/, G
case GDK_MOTION_NOTIFY:
_updateDragPoint(event_point(event->motion));
break;
- default: break;
+ default:
+ break;
}
return false;
}
@@ -275,6 +276,27 @@ void PathManipulator::insertNodes()
}
}
+void PathManipulator::insertNode(Geom::Point pt)
+{
+ Geom::Coord dist = _updateDragPoint(pt);
+ if (dist < 1e-5) { // 1e-6 is too small, as observed occasionally when inserting a node at a snapped intersection of paths
+ insertNode(_dragpoint->getIterator(), _dragpoint->getTimeValue(), true);
+ }
+}
+
+void PathManipulator::insertNode(NodeList::iterator first, double t, bool take_selection)
+{
+ NodeList::iterator inserted = subdivideSegment(first, t);
+ if (take_selection) {
+ _selection.clear();
+ }
+ _selection.insert(inserted.ptr());
+
+ update(true);
+ _commit(_("Add node"));
+}
+
+
static void
add_or_replace_if_extremum(std::vector< std::pair<NodeList::iterator, double> > &vec,
double & extrvalue, double testvalue, NodeList::iterator const& node, double t)
@@ -1643,13 +1665,15 @@ void PathManipulator::_commit(Glib::ustring const &annotation, gchar const *key)
/** 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)
+Geom::Coord PathManipulator::_updateDragPoint(Geom::Point const &evp)
{
+ Geom::Coord dist = 1e23;
+
Geom::Affine to_desktop = _edit_transform * _i2d_transform;
Geom::PathVector pv = _spcurve->get_pathvector();
boost::optional<Geom::PathVectorPosition> pvp
= Geom::nearestPoint(pv, _desktop->w2d(evp) * to_desktop.inverse());
- if (!pvp) return;
+ if (!pvp) return dist;
Geom::Point nearest_point = _desktop->d2w(pv.at(pvp->path_nr).pointAt(pvp->t) * to_desktop);
double fracpart;
@@ -1657,10 +1681,12 @@ void PathManipulator::_updateDragPoint(Geom::Point const &evp)
for (unsigned i = 0; i < pvp->path_nr; ++i, ++spi) {}
NodeList::iterator first = (*spi)->before(pvp->t, &fracpart);
+ dist = Geom::distance(evp, nearest_point);
+
double stroke_tolerance = _getStrokeTolerance();
if (first && first.next() &&
fracpart != 0.0 &&
- Geom::distance(evp, nearest_point) < stroke_tolerance)
+ dist < stroke_tolerance)
{
_dragpoint->setVisible(true);
_dragpoint->setPosition(_desktop->w2d(nearest_point));
@@ -1670,6 +1696,8 @@ void PathManipulator::_updateDragPoint(Geom::Point const &evp)
} else {
_dragpoint->setVisible(false);
}
+
+ return dist;
}
/// This is called on zoom change to update the direction arrows
diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h
index 2219af849..4c6f74ba4 100644
--- a/src/ui/tool/path-manipulator.h
+++ b/src/ui/tool/path-manipulator.h
@@ -70,6 +70,8 @@ public:
void insertNodeAtExtremum(ExtremumType extremum);
void insertNodes();
+ void insertNode(Geom::Point);
+ void insertNode(NodeList::iterator first, double t, bool take_selection);
void duplicateNodes();
void weldNodes(NodeList::iterator preserve_pos = NodeList::iterator());
void weldSegments();
@@ -133,7 +135,7 @@ private:
void _removeNodesFromSelection();
void _commit(Glib::ustring const &annotation);
void _commit(Glib::ustring const &annotation, gchar const *key);
- void _updateDragPoint(Geom::Point const &);
+ Geom::Coord _updateDragPoint(Geom::Point const &);
void _updateOutlineOnZoomChange();
double _getStrokeTolerance();
Handle *_chooseHandle(Node *n, int which);
@@ -143,7 +145,7 @@ private:
SPPath *_path; ///< can be an SPPath or an Inkscape::LivePathEffect::Effect !!!
SPCurve *_spcurve; // in item coordinates
SPCanvasItem *_outline;
- CurveDragPoint *_dragpoint; // an invisible control point hoverng over curve
+ CurveDragPoint *_dragpoint; // an invisible control point hovering over curve
PathManipulatorObserver *_observer;
Geom::Affine _d2i_transform; ///< desktop-to-item transform
Geom::Affine _i2d_transform; ///< item-to-desktop transform, inverse of _d2i_transform
diff --git a/src/ui/tool/selector.cpp b/src/ui/tool/selector.cpp
index e4e701785..051cb41ae 100644
--- a/src/ui/tool/selector.cpp
+++ b/src/ui/tool/selector.cpp
@@ -129,6 +129,10 @@ bool Selector::event(Inkscape::UI::Tools::ToolBase *event_context, GdkEvent *eve
return false;
}
+bool Selector::doubleClicked() {
+ return _dragger->doubleClicked();
+}
+
} // namespace UI
} // namespace Inkscape
diff --git a/src/ui/tool/selector.h b/src/ui/tool/selector.h
index dbe751ede..bd8d3e1aa 100644
--- a/src/ui/tool/selector.h
+++ b/src/ui/tool/selector.h
@@ -29,6 +29,7 @@ public:
Selector(SPDesktop *d);
virtual ~Selector();
virtual bool event(Inkscape::UI::Tools::ToolBase *, GdkEvent *);
+ virtual bool doubleClicked();
sigc::signal<void, Geom::Rect const &, GdkEventButton*> signal_area;
sigc::signal<void, Geom::Point const &, GdkEventButton*> signal_point;