summaryrefslogtreecommitdiffstats
path: root/src/ui/tool
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2015-07-24 23:26:11 +0000
committerJabiertxof <jtx@jtx.marker.es>2015-07-24 23:26:11 +0000
commit7b6ffd82650ee1e20a53b0631d5c2dddef58e8d5 (patch)
tree48cae26bf789b11d79f72efc16a6676f960eaaa6 /src/ui/tool
parentupdate to trunk (diff)
parent3D box tool: the shift key must not prevent snapping of the vanishing point. ... (diff)
downloadinkscape-7b6ffd82650ee1e20a53b0631d5c2dddef58e8d5.tar.gz
inkscape-7b6ffd82650ee1e20a53b0631d5c2dddef58e8d5.zip
update to trunk
(bzr r12588.1.45)
Diffstat (limited to '')
-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.cpp29
-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/node.cpp16
-rw-r--r--src/ui/tool/node.h4
-rw-r--r--src/ui/tool/path-manipulator.cpp71
-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
-rw-r--r--src/ui/tools/box3d-tool.cpp2
-rw-r--r--src/ui/tools/calligraphic-tool.cpp3
-rw-r--r--src/ui/tools/connector-tool.cpp8
-rw-r--r--src/ui/tools/dropper-tool.cpp3
-rw-r--r--src/ui/tools/eraser-tool.cpp57
-rw-r--r--src/ui/tools/flood-tool.cpp2
-rw-r--r--src/ui/tools/gradient-tool.cpp39
-rw-r--r--src/ui/tools/lpe-tool.cpp8
-rw-r--r--src/ui/tools/measure-tool.cpp6
-rw-r--r--src/ui/tools/mesh-tool.cpp29
-rw-r--r--src/ui/tools/node-tool.cpp140
-rw-r--r--src/ui/tools/node-tool.h59
-rw-r--r--src/ui/tools/pen-tool.cpp55
-rw-r--r--src/ui/tools/pencil-tool.cpp16
-rw-r--r--src/ui/tools/rect-tool.cpp1
-rw-r--r--src/ui/tools/select-tool.cpp6
-rw-r--r--src/ui/tools/spray-tool.cpp86
-rw-r--r--src/ui/tools/spray-tool.h17
-rw-r--r--src/ui/tools/text-tool.cpp7
-rw-r--r--src/ui/tools/tool-base.cpp6
-rw-r--r--src/ui/tools/tool-base.h7
-rw-r--r--src/ui/tools/tweak-tool.cpp28
34 files changed, 431 insertions, 321 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..e460b0fb7 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
@@ -181,6 +187,10 @@ Glib::ustring CurveDragPoint::_getTip(unsigned state) const
if (_pm.empty()) return "";
if (!first || !first.next()) return "";
bool linear = first->front()->isDegenerate() && first.next()->back()->isDegenerate();
+ if(state_held_shift(state) && _pm._isBSpline()){
+ return C_("Path segment tip",
+ "<b>Shift</b>: drag to open or move BSpline handles");
+ }
if (state_held_shift(state)) {
return C_("Path segment tip",
"<b>Shift</b>: click to toggle segment selection");
@@ -189,6 +199,11 @@ Glib::ustring CurveDragPoint::_getTip(unsigned state) const
return C_("Path segment tip",
"<b>Ctrl+Alt</b>: click to insert a node");
}
+ if(_pm._isBSpline()){
+ return C_("Path segment tip",
+ "<b>BSpline segment</b>: drag to shape the segment, doubleclick to insert node, "
+ "click to select (more: Shift, Ctrl+Alt)");
+ }
if (linear) {
return C_("Path segment tip",
"<b>Linear segment</b>: drag to convert to a Bezier segment, "
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/node.cpp b/src/ui/tool/node.cpp
index aa5365265..ca6f5abb1 100644
--- a/src/ui/tool/node.cpp
+++ b/src/ui/tool/node.cpp
@@ -356,8 +356,8 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event)
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));
+ Geom::Point orig_pos = original_line.pointAt(original_line.nearestTime(new_pos));
+ Geom::Point perp_pos = perp_line.pointAt(perp_line.nearestTime(new_pos));
Geom::Point result = snap_pos;
ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - snap_pos);
@@ -1464,13 +1464,14 @@ Glib::ustring Node::_getTip(unsigned state) const
// No modifiers: assemble tip from node type
char const *nodetype = node_type_to_localized_string(_type);
+ double power = _pm()._bsplineHandlePosition(h,h2);
if (_selection.transformHandlesEnabled() && selected()) {
if (_selection.size() == 1 && !isBSpline) {
return format_tip(C_("Path node tip",
"<b>%s</b>: drag to shape the path (more: Shift, Ctrl, Alt)"), nodetype);
}else if(_selection.size() == 1){
return format_tip(C_("Path node tip",
- "<b>BSpline node</b>: drag to shape the path (more: Shift, Ctrl, Alt). %g power"),_pm()._bsplineHandlePosition(h,h2));
+ "<b>BSpline node</b>: drag to shape the path (more: Shift, Ctrl, Alt). %g power"), power);
}
return format_tip(C_("Path node tip",
"<b>%s</b>: drag to shape the path, click to toggle scale/rotation handles (more: Shift, Ctrl, Alt)"), nodetype);
@@ -1480,7 +1481,7 @@ Glib::ustring Node::_getTip(unsigned state) const
"<b>%s</b>: drag to shape the path, click to select only this node (more: Shift, Ctrl, Alt)"), nodetype);
}else{
return format_tip(C_("Path node tip",
- "<b>BSpline node</b>: drag to shape the path, click to select only this node (more: Shift, Ctrl, Alt). %g power"),_pm()._bsplineHandlePosition(h,h2));
+ "<b>BSpline node</b>: drag to shape the path, click to select only this node (more: Shift, Ctrl, Alt). %g power"), power);
}
}
@@ -1567,6 +1568,13 @@ NodeList::iterator NodeList::before(double t, double *fracpart)
return ret;
}
+NodeList::iterator NodeList::before(Geom::PathTime const &pvp)
+{
+ iterator ret = begin();
+ std::advance(ret, pvp.curve_index);
+ return ret;
+}
+
NodeList::iterator NodeList::insert(iterator pos, Node *x)
{
ListNode *ins = pos._node;
diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h
index 101af4817..025c460e2 100644
--- a/src/ui/tool/node.h
+++ b/src/ui/tool/node.h
@@ -406,9 +406,13 @@ public:
void setClosed(bool c) { _closed = c; }
iterator before(double t, double *fracpart = NULL);
+ iterator before(Geom::PathTime const &pvp);
const_iterator before(double t, double *fracpart = NULL) const {
return const_iterator(before(t, fracpart)._node);
}
+ const_iterator before(Geom::PathTime const &pvp) const {
+ return const_iterator(before(pvp)._node);
+ }
// list operations
diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp
index 6b0c95f68..848b10373 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)
@@ -996,7 +1018,7 @@ NodeList::iterator PathManipulator::subdivideSegment(NodeList::iterator first, d
Geom::CubicBezier temp(first->position(), first->front()->position(),
second->back()->position(), second->position());
std::pair<Geom::CubicBezier, Geom::CubicBezier> div = temp.subdivide(t);
- std::vector<Geom::Point> seg1 = div.first.points(), seg2 = div.second.points();
+ std::vector<Geom::Point> seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints();
// set new handle positions
Node *n = new Node(_multi_path_manipulator._path_data.node_data, seg2[0]);
@@ -1141,22 +1163,22 @@ void PathManipulator::_createControlPointsFromGeometry()
pathv *= (_edit_transform * _i2d_transform);
// in this loop, we know that there are no zero-segment subpaths
- for (Geom::PathVector::const_iterator pit = pathv.begin(); pit != pathv.end(); ++pit) {
+ for (Geom::PathVector::iterator pit = pathv.begin(); pit != pathv.end(); ++pit) {
// prepare new subpath
SubpathPtr subpath(new NodeList(_subpaths));
_subpaths.push_back(subpath);
Node *previous_node = new Node(_multi_path_manipulator._path_data.node_data, pit->initialPoint());
subpath->push_back(previous_node);
- Geom::Curve const &cseg = pit->back_closed();
- bool fuse_ends = pit->closed()
- && Geom::are_near(cseg.initialPoint(), cseg.finalPoint());
- for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_open(); ++cit) {
+
+ bool closed = pit->closed();
+
+ for (Geom::Path::iterator cit = pit->begin(); cit != pit->end(); ++cit) {
Geom::Point pos = cit->finalPoint();
Node *current_node;
// if the closing segment is degenerate and the path is closed, we need to move
// the handle of the first node instead of creating a new one
- if (fuse_ends && cit == --(pit->end_open())) {
+ if (closed && cit == --(pit->end())) {
current_node = subpath->begin().get_pointer();
} else {
/* regardless of segment type, create a new node at the end
@@ -1271,7 +1293,7 @@ double PathManipulator::_bsplineHandlePosition(Handle *h, Handle *h2)
line_inside_nodes->moveto(n->position());
line_inside_nodes->lineto(next_node->position());
if(!are_near(h->position(), n->position())){
- pos = Geom::nearest_point(Geom::Point(h->position()[X] - HANDLE_CUBIC_GAP, h->position()[Y] - HANDLE_CUBIC_GAP), *line_inside_nodes->first_segment());
+ pos = Geom::nearest_time(Geom::Point(h->position()[X] - HANDLE_CUBIC_GAP, h->position()[Y] - HANDLE_CUBIC_GAP), *line_inside_nodes->first_segment());
}
}
if (pos == NO_POWER && !h2){
@@ -1425,7 +1447,7 @@ void PathManipulator::_updateOutline()
Geom::PathVector arrows;
for (Geom::PathVector::iterator i = pv.begin(); i != pv.end(); ++i) {
Geom::Path &path = *i;
- for (Geom::Path::const_iterator j = path.begin(); j != path.end_default(); ++j) {
+ for (Geom::Path::iterator j = path.begin(); j != path.end_default(); ++j) {
Geom::Point at = j->pointAt(0.5);
Geom::Point ut = j->unitTangentAt(0.5);
// rotate the point
@@ -1643,33 +1665,40 @@ 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 = HUGE_VAL;
+
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;
- Geom::Point nearest_point = _desktop->d2w(pv.at(pvp->path_nr).pointAt(pvp->t) * to_desktop);
-
- double fracpart;
+
+ boost::optional<Geom::PathVectorTime> pvp =
+ pv.nearestTime(_desktop->w2d(evp) * to_desktop.inverse());
+ if (!pvp) return dist;
+ Geom::Point nearest_pt = _desktop->d2w(pv.pointAt(*pvp) * to_desktop);
+
+ double fracpart = pvp->t;
std::list<SubpathPtr>::iterator spi = _subpaths.begin();
- for (unsigned i = 0; i < pvp->path_nr; ++i, ++spi) {}
- NodeList::iterator first = (*spi)->before(pvp->t, &fracpart);
+ for (unsigned i = 0; i < pvp->path_index; ++i, ++spi) {}
+ NodeList::iterator first = (*spi)->before(pvp->asPathTime());
+ dist = Geom::distance(evp, nearest_pt);
+
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));
+ _dragpoint->setPosition(_desktop->w2d(nearest_pt));
_dragpoint->setSize(2 * stroke_tolerance);
_dragpoint->setTimeValue(fracpart);
_dragpoint->setIterator(first);
} 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;
diff --git a/src/ui/tools/box3d-tool.cpp b/src/ui/tools/box3d-tool.cpp
index 538e0c7e2..27e755add 100644
--- a/src/ui/tools/box3d-tool.cpp
+++ b/src/ui/tools/box3d-tool.cpp
@@ -165,7 +165,7 @@ bool Box3dTool::item_handler(SPItem* item, GdkEvent* event) {
case GDK_BUTTON_PRESS:
if ( event->button.button == 1 && !this->space_panning) {
Inkscape::setup_for_drag_start(desktop, this, event);
- ret = TRUE;
+ //ret = TRUE;
}
break;
// motion and release are always on root (why?)
diff --git a/src/ui/tools/calligraphic-tool.cpp b/src/ui/tools/calligraphic-tool.cpp
index 15e6527a3..28195eb75 100644
--- a/src/ui/tools/calligraphic-tool.cpp
+++ b/src/ui/tools/calligraphic-tool.cpp
@@ -140,8 +140,7 @@ void CalligraphicTool::setup() {
{
/* TODO: have a look at DropperTool::setup where the same is done.. generalize? */
- Geom::PathVector path;
- Geom::Circle(0, 0, 1).getPath(path);
+ Geom::PathVector path = Geom::Path(Geom::Circle(0,0,1));
SPCurve *c = new SPCurve(path);
diff --git a/src/ui/tools/connector-tool.cpp b/src/ui/tools/connector-tool.cpp
index c3ef19507..0a36877ff 100644
--- a/src/ui/tools/connector-tool.cpp
+++ b/src/ui/tools/connector-tool.cpp
@@ -1303,12 +1303,12 @@ void cc_selection_set_avoid(bool const set_avoid)
Inkscape::Selection *selection = desktop->getSelection();
- GSList *l = const_cast<GSList *>(selection->itemList());
int changes = 0;
- while (l) {
- SPItem *item = SP_ITEM(l->data);
+ std::vector<SPItem*> l = selection->itemList();
+ for(std::vector<SPItem*>::const_iterator i=l.begin();i!=l.end();i++) {
+ SPItem *item = *i;
char const *value = (set_avoid) ? "true" : NULL;
@@ -1317,8 +1317,6 @@ void cc_selection_set_avoid(bool const set_avoid)
item->avoidRef->handleSettingChange();
changes++;
}
-
- l = l->next;
}
if (changes == 0) {
diff --git a/src/ui/tools/dropper-tool.cpp b/src/ui/tools/dropper-tool.cpp
index bda9d8e8a..c838c27d5 100644
--- a/src/ui/tools/dropper-tool.cpp
+++ b/src/ui/tools/dropper-tool.cpp
@@ -84,8 +84,7 @@ void DropperTool::setup() {
ToolBase::setup();
/* TODO: have a look at CalligraphicTool::setup where the same is done.. generalize? */
- Geom::PathVector path;
- Geom::Circle(0, 0, 1).getPath(path);
+ Geom::PathVector path = Geom::Path(Geom::Circle(0,0,1));
SPCurve *c = new SPCurve(path);
diff --git a/src/ui/tools/eraser-tool.cpp b/src/ui/tools/eraser-tool.cpp
index af0cbcb78..e416fd7ef 100644
--- a/src/ui/tools/eraser-tool.cpp
+++ b/src/ui/tools/eraser-tool.cpp
@@ -666,8 +666,7 @@ void EraserTool::set_to_accumulated() {
Geom::OptRect eraserBbox = acid->visualBounds();
Geom::Rect bounds = (*eraserBbox) * desktop->doc2dt();
std::vector<SPItem*> remainingItems;
- GSList* toWorkOn = 0;
-
+ std::vector<SPItem*> toWorkOn;
if (selection->isEmpty()) {
if ( eraserMode ) {
toWorkOn = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, bounds);
@@ -675,17 +674,16 @@ void EraserTool::set_to_accumulated() {
Inkscape::Rubberband *r = Inkscape::Rubberband::get(desktop);
toWorkOn = desktop->getDocument()->getItemsAtPoints(desktop->dkey, r->getPoints());
}
-
- toWorkOn = g_slist_remove( toWorkOn, acid );
+ toWorkOn.erase(std::remove(toWorkOn.begin(), toWorkOn.end(), acid), toWorkOn.end());
} else {
- toWorkOn = g_slist_copy(const_cast<GSList*>(selection->itemList()));
+ toWorkOn= selection->itemList();
wasSelection = true;
}
- if ( g_slist_length(toWorkOn) > 0 ) {
+ if ( !toWorkOn.empty() ) {
if ( eraserMode ) {
- for (GSList *i = toWorkOn ; i ; i = i->next ) {
- SPItem *item = SP_ITEM(i->data);
+ for (std::vector<SPItem*>::const_iterator i = toWorkOn.begin(); i != toWorkOn.end(); i++){
+ SPItem *item = *i;
if ( eraserMode ) {
Geom::OptRect bbox = item->visualBounds();
@@ -702,13 +700,10 @@ void EraserTool::set_to_accumulated() {
if ( !selection->isEmpty() ) {
// If the item was not completely erased, track the new remainder.
- GSList *nowSel = g_slist_copy(const_cast<GSList *>(selection->itemList()));
-
- for (GSList const *i2 = nowSel ; i2 ; i2 = i2->next ) {
- remainingItems.push_back(SP_ITEM(i2->data));
+ std::vector<SPItem*> nowSel(selection->itemList());
+ for (std::vector<SPItem*>::const_iterator i2 = nowSel.begin();i2!=nowSel.end();i2++) {
+ remainingItems.push_back(*i2);
}
-
- g_slist_free(nowSel);
}
} else {
remainingItems.push_back(item);
@@ -716,20 +711,18 @@ void EraserTool::set_to_accumulated() {
}
}
} else {
- for (GSList *i = toWorkOn ; i ; i = i->next ) {
- sp_object_ref( SP_ITEM(i->data), 0 );
+ for (std::vector<SPItem*> ::const_iterator i = toWorkOn.begin();i!=toWorkOn.end();i++) {
+ sp_object_ref( *i, 0 );
}
- for (GSList *i = toWorkOn ; i ; i = i->next ) {
- SPItem *item = SP_ITEM(i->data);
+ for (std::vector<SPItem*>::const_iterator i = toWorkOn.begin();i!=toWorkOn.end();i++) {
+ SPItem *item = *i;
item->deleteObject(true);
sp_object_unref(item);
workDone = true;
}
}
- g_slist_free(toWorkOn);
-
if ( !eraserMode ) {
//sp_selection_delete(desktop);
remainingItems.clear();
@@ -796,6 +789,8 @@ add_cap(SPCurve *curve,
}
void EraserTool::accumulate() {
+ // construct a crude outline of the eraser's path.
+ // this desperately needs to be rewritten to use the path outliner...
if ( !this->cal1->is_empty() && !this->cal2->is_empty() ) {
this->accumulated->reset(); /* Is this required ?? */
SPCurve *rev_cal2 = this->cal2->create_reverse();
@@ -805,10 +800,10 @@ void EraserTool::accumulate() {
g_assert( ! this->cal1->first_path()->closed() );
g_assert( ! rev_cal2->first_path()->closed() );
- Geom::CubicBezier const * dc_cal1_firstseg = dynamic_cast<Geom::CubicBezier const *>( this->cal1->first_segment() );
- Geom::CubicBezier const * rev_cal2_firstseg = dynamic_cast<Geom::CubicBezier const *>( rev_cal2->first_segment() );
- Geom::CubicBezier const * dc_cal1_lastseg = dynamic_cast<Geom::CubicBezier const *>( this->cal1->last_segment() );
- Geom::CubicBezier const * rev_cal2_lastseg = dynamic_cast<Geom::CubicBezier const *>( rev_cal2->last_segment() );
+ Geom::BezierCurve const * dc_cal1_firstseg = dynamic_cast<Geom::BezierCurve const *>( this->cal1->first_segment() );
+ Geom::BezierCurve const * rev_cal2_firstseg = dynamic_cast<Geom::BezierCurve const *>( rev_cal2->first_segment() );
+ Geom::BezierCurve const * dc_cal1_lastseg = dynamic_cast<Geom::BezierCurve const *>( this->cal1->last_segment() );
+ Geom::BezierCurve const * rev_cal2_lastseg = dynamic_cast<Geom::BezierCurve const *>( rev_cal2->last_segment() );
g_assert( dc_cal1_firstseg );
g_assert( rev_cal2_firstseg );
@@ -817,11 +812,21 @@ void EraserTool::accumulate() {
this->accumulated->append(this->cal1, FALSE);
- add_cap(this->accumulated, (*dc_cal1_lastseg)[2], (*dc_cal1_lastseg)[3], (*rev_cal2_firstseg)[0], (*rev_cal2_firstseg)[1], this->cap_rounding);
+ add_cap(this->accumulated,
+ dc_cal1_lastseg->finalPoint() - dc_cal1_lastseg->unitTangentAt(1),
+ dc_cal1_lastseg->finalPoint(),
+ rev_cal2_firstseg->initialPoint(),
+ rev_cal2_firstseg->initialPoint() + rev_cal2_firstseg->unitTangentAt(0),
+ this->cap_rounding);
this->accumulated->append(rev_cal2, TRUE);
- add_cap(this->accumulated, (*rev_cal2_lastseg)[2], (*rev_cal2_lastseg)[3], (*dc_cal1_firstseg)[0], (*dc_cal1_firstseg)[1], this->cap_rounding);
+ add_cap(this->accumulated,
+ rev_cal2_lastseg->finalPoint() - rev_cal2_lastseg->unitTangentAt(1),
+ rev_cal2_lastseg->finalPoint(),
+ dc_cal1_firstseg->initialPoint(),
+ dc_cal1_firstseg->initialPoint() + dc_cal1_firstseg->unitTangentAt(0),
+ this->cap_rounding);
this->accumulated->closepath();
diff --git a/src/ui/tools/flood-tool.cpp b/src/ui/tools/flood-tool.cpp
index ffd41d97d..748c82717 100644
--- a/src/ui/tools/flood-tool.cpp
+++ b/src/ui/tools/flood-tool.cpp
@@ -932,7 +932,7 @@ static void sp_flood_do_flood_fill(ToolBase *event_context, GdkEvent *event, boo
std::deque<Geom::Point>::iterator start_sort = fill_queue.begin();
std::deque<Geom::Point>::iterator end_sort = fill_queue.begin();
unsigned int sort_y = (unsigned int)cp[Geom::Y];
- unsigned int current_y = sort_y;
+ unsigned int current_y;
for (std::deque<Geom::Point>::iterator i = fill_queue.begin(); i != fill_queue.end(); ++i) {
Geom::Point current = *i;
diff --git a/src/ui/tools/gradient-tool.cpp b/src/ui/tools/gradient-tool.cpp
index b27859ebb..603458983 100644
--- a/src/ui/tools/gradient-tool.cpp
+++ b/src/ui/tools/gradient-tool.cpp
@@ -106,7 +106,7 @@ void GradientTool::selection_changed(Inkscape::Selection*) {
if (selection == NULL) {
return;
}
- guint n_obj = g_slist_length((GSList *) selection->itemList());
+ guint n_obj = selection->itemList().size();
if (!drag->isNonEmpty() || selection->isEmpty())
return;
@@ -207,7 +207,7 @@ sp_gradient_context_is_over_line (GradientTool *rc, SPItem *item, Geom::Point ev
SPCtrlLine* line = SP_CTRLLINE(item);
Geom::LineSegment ls(line->s, line->e);
- Geom::Point nearest = ls.pointAt(ls.nearestPoint(rc->mousepoint_doc));
+ Geom::Point nearest = ls.pointAt(ls.nearestTime(rc->mousepoint_doc));
double dist_screen = Geom::L2 (rc->mousepoint_doc - nearest) * desktop->current_zoom();
double tolerance = (double) SP_EVENT_CONTEXT(rc)->tolerance;
@@ -492,10 +492,11 @@ bool GradientTool::root_handler(GdkEvent* event) {
if (over_line) {
// we take the first item in selection, because with doubleclick, the first click
// always resets selection to the single object under cursor
- sp_gradient_context_add_stop_near_point(this, SP_ITEM(selection->itemList()->data), this->mousepoint_doc, event->button.time);
+ sp_gradient_context_add_stop_near_point(this, SP_ITEM(selection->itemList().front()), this->mousepoint_doc, event->button.time);
} else {
- for (GSList const* i = selection->itemList(); i != NULL; i = i->next) {
- SPItem *item = SP_ITEM(i->data);
+ std::vector<SPItem*> items=selection->itemList();
+ for (std::vector<SPItem*>::const_iterator i = items.begin();i!=items.end();i++) {
+ SPItem *item = *i;
SPGradientType new_type = (SPGradientType) prefs->getInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR);
Inkscape::PaintTarget fsmode = (prefs->getInt("/tools/gradient/newfillorstroke", 1) != 0) ? Inkscape::FOR_FILL : Inkscape::FOR_STROKE;
@@ -898,32 +899,32 @@ static void sp_gradient_drag(GradientTool &rc, Geom::Point const pt, guint /*sta
} else {
// Starting from empty space:
// Sort items so that the topmost comes last
- GSList *items = g_slist_copy ((GSList *) selection->itemList());
- items = g_slist_sort(items, (GCompareFunc) sp_item_repr_compare_position);
+ std::vector<SPItem*> items(selection->itemList());
+ sort(items.begin(),items.end(),sp_item_repr_compare_position);
// take topmost
- vector = sp_gradient_vector_for_object(document, desktop, SP_ITEM(g_slist_last(items)->data), fill_or_stroke);
- g_slist_free (items);
+ vector = sp_gradient_vector_for_object(document, desktop, SP_ITEM(items.back()), fill_or_stroke);
}
// HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
SPCSSAttr *css = sp_repr_css_attr_new();
sp_repr_css_set_property(css, "fill-opacity", "1.0");
- for (GSList const *i = selection->itemList(); i != NULL; i = i->next) {
+ std::vector<SPItem*> itemlist = selection->itemList();
+ for (std::vector<SPItem*>::const_iterator i = itemlist.begin();i!=itemlist.end();i++) {
//FIXME: see above
- sp_repr_css_change_recursive(SP_OBJECT(i->data)->getRepr(), css, "style");
+ sp_repr_css_change_recursive((*i)->getRepr(), css, "style");
- sp_item_set_gradient(SP_ITEM(i->data), vector, (SPGradientType) type, fill_or_stroke);
+ sp_item_set_gradient(*i, vector, (SPGradientType) type, fill_or_stroke);
if (type == SP_GRADIENT_TYPE_LINEAR) {
- sp_item_gradient_set_coords (SP_ITEM(i->data), POINT_LG_BEGIN, 0, rc.origin, fill_or_stroke, true, false);
- sp_item_gradient_set_coords (SP_ITEM(i->data), POINT_LG_END, 0, pt, fill_or_stroke, true, false);
+ sp_item_gradient_set_coords (*i, POINT_LG_BEGIN, 0, rc.origin, fill_or_stroke, true, false);
+ sp_item_gradient_set_coords (*i, POINT_LG_END, 0, pt, fill_or_stroke, true, false);
} else if (type == SP_GRADIENT_TYPE_RADIAL) {
- sp_item_gradient_set_coords (SP_ITEM(i->data), POINT_RG_CENTER, 0, rc.origin, fill_or_stroke, true, false);
- sp_item_gradient_set_coords (SP_ITEM(i->data), POINT_RG_R1, 0, pt, fill_or_stroke, true, false);
+ sp_item_gradient_set_coords (*i, POINT_RG_CENTER, 0, rc.origin, fill_or_stroke, true, false);
+ sp_item_gradient_set_coords (*i, POINT_RG_R1, 0, pt, fill_or_stroke, true, false);
}
- SP_OBJECT(i->data)->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ (*i)->requestModified(SP_OBJECT_MODIFIED_FLAG);
}
if (ec->_grdrag) {
ec->_grdrag->updateDraggers();
@@ -932,7 +933,7 @@ static void sp_gradient_drag(GradientTool &rc, Geom::Point const pt, guint /*sta
ec->_grdrag->local_change = true;
// give the grab out-of-bounds values of xp/yp because we're already dragging
// and therefore are already out of tolerance
- ec->_grdrag->grabKnot (SP_ITEM(selection->itemList()->data),
+ ec->_grdrag->grabKnot (selection->itemList()[0],
type == SP_GRADIENT_TYPE_LINEAR? POINT_LG_END : POINT_RG_R1,
-1, // ignore number (though it is always 1)
fill_or_stroke, 99999, 99999, etime);
@@ -941,7 +942,7 @@ static void sp_gradient_drag(GradientTool &rc, Geom::Point const pt, guint /*sta
// status text; we do not track coords because this branch is run once, not all the time
// during drag
- int n_objects = g_slist_length((GSList *) selection->itemList());
+ int n_objects = selection->itemList().size();
rc.message_context->setF(Inkscape::NORMAL_MESSAGE,
ngettext("<b>Gradient</b> for %d object; with <b>Ctrl</b> to snap angle",
"<b>Gradient</b> for %d objects; with <b>Ctrl</b> to snap angle", n_objects),
diff --git a/src/ui/tools/lpe-tool.cpp b/src/ui/tools/lpe-tool.cpp
index c0517578d..13e47f3a6 100644
--- a/src/ui/tools/lpe-tool.cpp
+++ b/src/ui/tools/lpe-tool.cpp
@@ -396,10 +396,10 @@ lpetool_create_measuring_items(LpeTool *lc, Inkscape::Selection *selection)
SPCanvasGroup *tmpgrp = lc->desktop->getTempGroup();
gchar *arc_length;
double lengthval;
-
- for (GSList const *i = selection->itemList(); i != NULL; i = i->next) {
- if (SP_IS_PATH(i->data)) {
- path = SP_PATH(i->data);
+ std::vector<SPItem*> items=selection->itemList();
+ for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++){
+ if (SP_IS_PATH(*i)) {
+ path = SP_PATH(*i);
curve = path->getCurve();
Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = paths_to_pw(curve->get_pathvector());
canvas_text = (SPCanvasText *) sp_canvastext_new(tmpgrp, lc->desktop, Geom::Point(0,0), "");
diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp
index 0875c29e0..570f3e796 100644
--- a/src/ui/tools/measure-tool.cpp
+++ b/src/ui/tools/measure-tool.cpp
@@ -431,10 +431,10 @@ bool MeasureTool::root_handler(GdkEvent* event) {
// TODO switch to a different variable name. The single letter 'l' is easy to misread.
//select elements crossed by line segment:
- GSList *items = desktop->getDocument()->getItemsAtPoints(desktop->dkey, points);
+ std::vector<SPItem*> items = desktop->getDocument()->getItemsAtPoints(desktop->dkey, points);
std::vector<double> intersection_times;
- for (GSList *l = items; l != NULL; l = l->next) {
- SPItem *item = static_cast<SPItem*>(l->data);
+ for (std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++) {
+ SPItem *item = *i;
if (SP_IS_SHAPE(item)) {
calculate_intersections(desktop, item, lineseg, SP_SHAPE(item)->getCurve(), intersection_times);
diff --git a/src/ui/tools/mesh-tool.cpp b/src/ui/tools/mesh-tool.cpp
index 67ed7aef1..813d6ae5b 100644
--- a/src/ui/tools/mesh-tool.cpp
+++ b/src/ui/tools/mesh-tool.cpp
@@ -103,7 +103,7 @@ void MeshTool::selection_changed(Inkscape::Selection* /*sel*/) {
return;
}
- guint n_obj = g_slist_length((GSList *) selection->itemList());
+ guint n_obj = selection->itemList().size();
if (!drag->isNonEmpty() || selection->isEmpty()) {
return;
@@ -275,7 +275,7 @@ sp_mesh_context_is_over_line (MeshTool *rc, SPItem *item, Geom::Point event_p)
SPCtrlCurve *curve = SP_CTRLCURVE(item);
Geom::BezierCurveN<3> b( curve->p0, curve->p1, curve->p2, curve->p3 );
- Geom::Coord coord = b.nearestPoint( rc->mousepoint_doc ); // Coord == double
+ Geom::Coord coord = b.nearestTime( rc->mousepoint_doc ); // Coord == double
Geom::Point nearest = b( coord );
double dist_screen = Geom::L2 (rc->mousepoint_doc - nearest) * desktop->current_zoom();
@@ -467,11 +467,12 @@ bool MeshTool::root_handler(GdkEvent* event) {
if (over_line) {
// We take the first item in selection, because with doubleclick, the first click
// always resets selection to the single object under cursor
- sp_mesh_context_split_near_point(this, SP_ITEM(selection->itemList()->data), this->mousepoint_doc, event->button.time);
+ sp_mesh_context_split_near_point(this, selection->itemList()[0], this->mousepoint_doc, event->button.time);
} else {
// Create a new gradient with default coordinates.
- for (GSList const* i = selection->itemList(); i != NULL; i = i->next) {
- SPItem *item = SP_ITEM(i->data);
+ std::vector<SPItem*> items=selection->itemList();
+ for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++){
+ SPItem *item = *i;
SPGradientType new_type = SP_GRADIENT_TYPE_MESH;
Inkscape::PaintTarget fsmode = (prefs->getInt("/tools/gradient/newfillorstroke", 1) != 0) ? Inkscape::FOR_FILL : Inkscape::FOR_STROKE;
@@ -940,27 +941,27 @@ static void sp_mesh_drag(MeshTool &rc, Geom::Point const /*pt*/, guint /*state*/
} else {
// Starting from empty space:
// Sort items so that the topmost comes last
- GSList *items = g_slist_copy ((GSList *) selection->itemList());
- items = g_slist_sort(items, (GCompareFunc) sp_item_repr_compare_position);
+ std::vector<SPItem*> items(selection->itemList());
+ sort(items.begin(),items.end(),sp_item_repr_compare_position);
// take topmost
- vector = sp_gradient_vector_for_object(document, desktop, SP_ITEM(g_slist_last(items)->data), fill_or_stroke);
- g_slist_free (items);
+ vector = sp_gradient_vector_for_object(document, desktop, SP_ITEM(items.back()), fill_or_stroke);
}
// HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
SPCSSAttr *css = sp_repr_css_attr_new();
sp_repr_css_set_property(css, "fill-opacity", "1.0");
- for (GSList const *i = selection->itemList(); i != NULL; i = i->next) {
+ std::vector<SPItem*> items=selection->itemList();
+ for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++){
//FIXME: see above
- sp_repr_css_change_recursive(SP_OBJECT(i->data)->getRepr(), css, "style");
+ sp_repr_css_change_recursive((*i)->getRepr(), css, "style");
- sp_item_set_gradient(SP_ITEM(i->data), vector, (SPGradientType) type, fill_or_stroke);
+ sp_item_set_gradient(*i, vector, (SPGradientType) type, fill_or_stroke);
// We don't need to do anything. Mesh is already sized appropriately.
- SP_OBJECT(i->data)->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ (*i)->requestModified(SP_OBJECT_MODIFIED_FLAG);
}
// if (ec->_grdrag) {
// ec->_grdrag->updateDraggers();
@@ -978,7 +979,7 @@ static void sp_mesh_drag(MeshTool &rc, Geom::Point const /*pt*/, guint /*state*/
// status text; we do not track coords because this branch is run once, not all the time
// during drag
- int n_objects = g_slist_length((GSList *) selection->itemList());
+ int n_objects = selection->itemList().size();
rc.message_context->setF(Inkscape::NORMAL_MESSAGE,
ngettext("<b>Gradient</b> for %d object; with <b>Ctrl</b> to snap angle",
"<b>Gradient</b> for %d objects; with <b>Ctrl</b> to snap angle", n_objects),
diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp
index a4b903960..6a6ca0b26 100644
--- a/src/ui/tools/node-tool.cpp
+++ b/src/ui/tools/node-tool.cpp
@@ -26,6 +26,8 @@
#include "ui/shape-editor.h" // temporary!
#include "live_effects/effect.h"
#include "display/curve.h"
+#include "snap.h"
+#include "sp-namedview.h"
#include "sp-clippath.h"
#include "sp-item-group.h"
#include "sp-mask.h"
@@ -112,7 +114,7 @@ namespace UI {
namespace Tools {
const std::string& NodeTool::getPrefsPath() {
- return NodeTool::prefsPath;
+ return NodeTool::prefsPath;
}
const std::string NodeTool::prefsPath = "/tools/nodes";
@@ -216,7 +218,7 @@ void NodeTool::setup() {
Inkscape::UI::ControlPoint::signal_mouseover_change.connect(sigc::mem_fun(this, &NodeTool::mouseover_changed));
this->_sizeUpdatedConn = ControlManager::getManager().connectCtrlSizeChanged(
- sigc::mem_fun(this, &NodeTool::handleControlUiStyleChange)
+ sigc::mem_fun(this, &NodeTool::handleControlUiStyleChange)
);
this->_selected_nodes = new Inkscape::UI::ControlPointSelection(this->desktop, this->_transform_handle_group);
@@ -236,14 +238,14 @@ void NodeTool::setup() {
);
this->_selected_nodes->signal_selection_changed.connect(
- // Hide both signal parameters and bind the function parameter to 0
- // sigc::signal<void, SelectableControlPoint *, bool>
- // <=>
- // void update_tip(GdkEvent *event)
- sigc::hide(sigc::hide(sigc::bind(
- sigc::mem_fun(this, &NodeTool::update_tip),
- (GdkEvent*)NULL
- )))
+ // Hide both signal parameters and bind the function parameter to 0
+ // sigc::signal<void, SelectableControlPoint *, bool>
+ // <=>
+ // void update_tip(GdkEvent *event)
+ sigc::hide(sigc::hide(sigc::bind(
+ sigc::mem_fun(this, &NodeTool::update_tip),
+ (GdkEvent*)NULL
+ )))
);
this->helperpath_tmpitem = NULL;
@@ -359,7 +361,7 @@ void NodeTool::set(const Inkscape::Preferences::Entry& value) {
this->edit_masks = value.getBool();
this->selection_changed(this->desktop->selection);
} else {
- ToolBase::set(value);
+ ToolBase::set(value);
}
}
@@ -370,7 +372,7 @@ void gather_items(NodeTool *nt, SPItem *base, SPObject *obj, Inkscape::UI::Shape
using namespace Inkscape::UI;
if (!obj) {
- return;
+ return;
}
//XML Tree being used directly here while it shouldn't be.
@@ -410,10 +412,9 @@ void NodeTool::selection_changed(Inkscape::Selection *sel) {
std::set<ShapeRecord> shapes;
- GSList const *ilist = sel->itemList();
-
- for (GSList *i = const_cast<GSList*>(ilist); i; i = i->next) {
- SPObject *obj = static_cast<SPObject*>(i->data);
+ std::vector<SPItem*> items=sel->itemList();
+ for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++){
+ SPObject *obj = *i;
if (SP_IS_ITEM(obj)) {
gather_items(this, NULL, static_cast<SPItem*>(obj), SHAPE_ROLE_NORMAL, shapes);
@@ -447,6 +448,9 @@ void NodeTool::selection_changed(Inkscape::Selection *sel) {
}
}
+ _previous_selection = _current_selection;
+ _current_selection = sel->itemList();
+
this->_multipath->setItems(shapes);
this->update_tip(NULL);
this->desktop->updateNow();
@@ -459,31 +463,47 @@ bool NodeTool::root_handler(GdkEvent* event) {
* 3. some keybindings
*/
using namespace Inkscape::UI; // pull in event helpers
-
+
Inkscape::Selection *selection = desktop->selection;
static Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if (this->_multipath->event(this, event)) {
- return true;
+ return true;
}
if (this->_selector->event(this, event)) {
- return true;
+ return true;
}
if (this->_selected_nodes->event(this, event)) {
- return true;
+ return true;
}
switch (event->type)
{
case GDK_MOTION_NOTIFY: {
- this->update_helperpath();
+ this->update_helperpath();
combine_motion_events(desktop->canvas, event->motion, 0);
this->update_helperpath();
SPItem *over_item = sp_event_context_find_item (desktop, event_point(event->button),
FALSE, TRUE);
+ Geom::Point const motion_w(event->motion.x, event->motion.y);
+ Geom::Point const motion_dt(this->desktop->w2d(motion_w));
+
+ SnapManager &m = this->desktop->namedview->snap_manager;
+
+ // We will show a pre-snap indication for when the user adds a node through double-clicking
+ // Adding a node will only work when a path has been selected; if that's not the case then snapping is useless
+ if (not this->desktop->selection->isEmpty()) {
+ if (!(event->motion.state & GDK_SHIFT_MASK)) {
+ m.setup(this->desktop);
+ Inkscape::SnapCandidatePoint scp(motion_dt, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+ m.preSnap(scp, true);
+ m.unSetup();
+ }
+ }
+
if (over_item != this->_last_over) {
this->_last_over = over_item;
//ink_node_tool_update_tip(nt, event);
@@ -492,11 +512,11 @@ bool NodeTool::root_handler(GdkEvent* event) {
// create pathflash outline
if (prefs->getBool("/tools/nodes/pathflash_enabled")) {
if (over_item == this->flashed_item) {
- break;
+ break;
}
if (!prefs->getBool("/tools/nodes/pathflash_selected") && selection->includes(over_item)) {
- break;
+ break;
}
if (this->flash_tempitem) {
@@ -506,14 +526,14 @@ bool NodeTool::root_handler(GdkEvent* event) {
}
if (!SP_IS_SHAPE(over_item)) {
- break; // for now, handle only shapes
+ break; // for now, handle only shapes
}
this->flashed_item = over_item;
SPCurve *c = SP_SHAPE(over_item)->getCurveBeforeLPE();
if (!c) {
- break; // break out when curve doesn't exist
+ break; // break out when curve doesn't exist
}
c->transform(over_item->i2dt_affine());
@@ -576,11 +596,42 @@ bool NodeTool::root_handler(GdkEvent* event) {
case GDK_KEY_RELEASE:
//ink_node_tool_update_tip(nt, event);
- this->update_tip(event);
+ this->update_tip(event);
+ break;
+
+ case GDK_BUTTON_RELEASE:
+ if (this->_selector->doubleClicked()) {
+ // If the selector received the doubleclick event, then we're at some distance from
+ // the path; otherwise, the doubleclick event would have been received by
+ // CurveDragPoint; we will insert nodes into the path anyway but only if we can snap
+ // to the path. Otherwise the position would not be very well defined.
+ if (!(event->motion.state & GDK_SHIFT_MASK)) {
+ Geom::Point const motion_w(event->motion.x, event->motion.y);
+ Geom::Point const motion_dt(this->desktop->w2d(motion_w));
+
+ SnapManager &m = this->desktop->namedview->snap_manager;
+ m.setup(this->desktop);
+ Inkscape::SnapCandidatePoint scp(motion_dt, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+ Inkscape::SnappedPoint sp = m.freeSnap(scp, Geom::OptRect(), true);
+ m.unSetup();
+
+ if (sp.getSnapped()) {
+ // The first click of the double click will have cleared the path selection, because
+ // we clicked aside of the path. We need to undo this on double click
+ Inkscape::Selection *selection = desktop->getSelection();
+ selection->addList(_previous_selection);
+
+ // The selection has been restored, and the signal selection_changed has been emitted,
+ // which has again forced a restore of the _mmap variable of the MultiPathManipulator (this->_multipath)
+ // Now we can insert the new nodes as if nothing has happened!
+ this->_multipath->insertNode(this->desktop->d2w(sp.getPoint()));
+ }
+ }
+ }
break;
default:
- break;
+ break;
}
return ToolBase::root_handler(event);
@@ -593,7 +644,7 @@ void NodeTool::update_tip(GdkEvent *event) {
unsigned new_state = state_after_event(event);
if (new_state == event->key.state) {
- return;
+ return;
}
if (state_held_shift(new_state)) {
@@ -614,9 +665,27 @@ void NodeTool::update_tip(GdkEvent *event) {
unsigned total = this->_selected_nodes->allPoints().size();
if (sz != 0) {
- char *nodestring = g_strdup_printf(
- ngettext("<b>%u of %u</b> node selected.", "<b>%u of %u</b> nodes selected.", total),
- sz, total);
+ char *nodestring;
+ if (sz == 2) {
+ // if there are only two nodes selected, display the angle
+ // of a line going through them relative to the X axis.
+ Inkscape::UI::ControlPointSelection::Set &selection_nodes = this->_selected_nodes->allPoints();
+ std::vector<Geom::Point> positions;
+ for (Inkscape::UI::ControlPointSelection::Set::iterator i = selection_nodes.begin(); i != selection_nodes.end(); ++i) {
+ if ((*i)->selected()) {
+ Inkscape::UI::Node *n = dynamic_cast<Inkscape::UI::Node *>(*i);
+ positions.push_back(n->position());
+ }
+ }
+ g_assert(positions.size() == 2);
+ const double angle = Geom::rad_to_deg(Geom::Line(positions[0], positions[1]).angle());
+ nodestring = g_strdup_printf("<b>%u of %u</b> nodes selected, angle: %.2f°.", sz, total, angle);
+ }
+ else {
+ nodestring = g_strdup_printf(
+ ngettext("<b>%u of %u</b> node selected.", "<b>%u of %u</b> nodes selected.", total),
+ sz, total);
+ }
if (this->_last_over) {
// TRANSLATORS: The %s below is where the "%u of %u nodes selected" sentence gets put
@@ -658,12 +727,11 @@ void NodeTool::select_area(Geom::Rect const &sel, GdkEventButton *event) {
if (this->_multipath->empty()) {
// if multipath is empty, select rubberbanded items rather than nodes
Inkscape::Selection *selection = this->desktop->selection;
- GSList *items = this->desktop->getDocument()->getItemsInBox(this->desktop->dkey, sel);
+ std::vector<SPItem*> items = this->desktop->getDocument()->getItemsInBox(this->desktop->dkey, sel);
selection->setList(items);
- g_slist_free(items);
} else {
if (!held_shift(*event)) {
- this->_selected_nodes->clear();
+ this->_selected_nodes->clear();
}
this->_selected_nodes->selectArea(sel);
@@ -674,11 +742,11 @@ void NodeTool::select_point(Geom::Point const &/*sel*/, GdkEventButton *event) {
using namespace Inkscape::UI; // pull in event helpers
if (!event) {
- return;
+ return;
}
if (event->button != 1) {
- return;
+ return;
}
Inkscape::Selection *selection = this->desktop->selection;
diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h
index 20375e869..8342d66a6 100644
--- a/src/ui/tools/node-tool.h
+++ b/src/ui/tools/node-tool.h
@@ -19,18 +19,18 @@
#include "selection.h"
namespace Inkscape {
- namespace Display {
- class TemporaryItem;
- }
-
- namespace UI {
- class MultiPathManipulator;
- class ControlPointSelection;
- class Selector;
- class ControlPoint;
-
- struct PathSharedData;
- }
+ namespace Display {
+ class TemporaryItem;
+ }
+
+ namespace UI {
+ class MultiPathManipulator;
+ class ControlPointSelection;
+ class Selector;
+ class ControlPoint;
+
+ struct PathSharedData;
+ }
}
struct SPCanvasGroup;
@@ -44,26 +44,26 @@ namespace Tools {
class NodeTool : public ToolBase {
public:
- NodeTool();
- virtual ~NodeTool();
+ NodeTool();
+ virtual ~NodeTool();
- Inkscape::UI::ControlPointSelection* _selected_nodes;
+ Inkscape::UI::ControlPointSelection* _selected_nodes;
Inkscape::UI::MultiPathManipulator* _multipath;
bool edit_clipping_paths;
bool edit_masks;
- static const std::string prefsPath;
+ static const std::string prefsPath;
- virtual void setup();
- virtual void update_helperpath();
- virtual void set(const Inkscape::Preferences::Entry& val);
- virtual bool root_handler(GdkEvent* event);
+ virtual void setup();
+ virtual void update_helperpath();
+ virtual void set(const Inkscape::Preferences::Entry& val);
+ virtual bool root_handler(GdkEvent* event);
- virtual const std::string& getPrefsPath();
+ virtual const std::string& getPrefsPath();
private:
- sigc::connection _selection_changed_connection;
+ sigc::connection _selection_changed_connection;
sigc::connection _mouseover_changed_connection;
sigc::connection _sizeUpdatedConn;
@@ -85,13 +85,16 @@ private:
bool show_transform_handles;
bool single_node_transform_handles;
- void selection_changed(Inkscape::Selection *sel);
+ std::vector<SPItem*> _current_selection;
+ std::vector<SPItem*> _previous_selection;
- void select_area(Geom::Rect const &sel, GdkEventButton *event);
- void select_point(Geom::Point const &sel, GdkEventButton *event);
- void mouseover_changed(Inkscape::UI::ControlPoint *p);
- void update_tip(GdkEvent *event);
- void handleControlUiStyleChange();
+ void selection_changed(Inkscape::Selection *sel);
+
+ void select_area(Geom::Rect const &sel, GdkEventButton *event);
+ void select_point(Geom::Point const &sel, GdkEventButton *event);
+ void mouseover_changed(Inkscape::UI::ControlPoint *p);
+ void update_tip(GdkEvent *event);
+ void handleControlUiStyleChange();
};
}
diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp
index daffc7032..827dbf5c3 100644
--- a/src/ui/tools/pen-tool.cpp
+++ b/src/ui/tools/pen-tool.cpp
@@ -57,8 +57,7 @@
#include <typeinfo>
#include <2geom/pathvector.h>
#include <2geom/affine.h>
-#include <2geom/bezier-curve.h>
-#include <2geom/hvlinesegment.h>
+#include <2geom/curves.h>
#include "helper/geom-nodetype.h"
#include "helper/geom-curves.h"
@@ -71,7 +70,7 @@
#define INKSCAPE_LPE_BSPLINE_C
#include "live_effects/lpe-bspline.h"
-#include <2geom/nearest-point.h>
+#include <2geom/nearest-time.h>
#include "live_effects/effect.h"
@@ -762,14 +761,12 @@ bool PenTool::_handleButtonRelease(GdkEventButton const &revent) {
}
}
this->state = PenTool::CONTROL;
- ret = true;
break;
case PenTool::CONTROL:
// End current segment
this->_endpointSnap(p, revent.state);
this->_finishSegment(p, revent.state);
this->state = PenTool::POINT;
- ret = true;
break;
case PenTool::CLOSE:
// End current segment
@@ -783,12 +780,10 @@ bool PenTool::_handleButtonRelease(GdkEventButton const &revent) {
}
this->_finish(true);
this->state = PenTool::POINT;
- ret = true;
break;
case PenTool::STOP:
// This is allowed, if we just canceled curve
this->state = PenTool::POINT;
- ret = true;
break;
default:
break;
@@ -823,7 +818,6 @@ bool PenTool::_handleButtonRelease(GdkEventButton const &revent) {
break;
}
this->state = PenTool::POINT;
- ret = true;
break;
default:
break;
@@ -1357,8 +1351,9 @@ void PenTool::_bsplineSpiroColor()
void PenTool::_bsplineSpiro(bool shift)
{
- if(!this->spiro && !this->bspline)
+ if(!this->spiro && !this->bspline){
return;
+ }
shift?this->_bsplineSpiroOff():this->_bsplineSpiroOn();
this->_bsplineSpiroBuild();
@@ -1419,21 +1414,26 @@ void PenTool::_bsplineSpiroStartAnchor(bool shift)
}else{
this->spiro = false;
}
- if(!this->spiro && !this->bspline)
+ if(!this->spiro && !this->bspline){
+ SPCurve *tmp_curve = this->sa->curve->copy();
+ if (this->sa->start) {
+ tmp_curve = tmp_curve ->create_reverse();
+ }
+ this->overwrite_curve = tmp_curve ;
return;
-
- if(shift)
+ }
+ if(shift){
this->_bsplineSpiroStartAnchorOff();
- else
+ } else {
this->_bsplineSpiroStartAnchorOn();
+ }
}
void PenTool::_bsplineSpiroStartAnchorOn()
{
using Geom::X;
using Geom::Y;
- SPCurve *tmp_curve = new SPCurve();
- tmp_curve = this->sa->curve->copy();
+ SPCurve *tmp_curve = this->sa->curve->copy();
if(this->sa->start)
tmp_curve = tmp_curve ->create_reverse();
Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const*>(&*tmp_curve ->last_segment());
@@ -1465,8 +1465,7 @@ void PenTool::_bsplineSpiroStartAnchorOn()
void PenTool::_bsplineSpiroStartAnchorOff()
{
- SPCurve *tmp_curve = new SPCurve();
- tmp_curve = this->sa->curve->copy();
+ SPCurve *tmp_curve = this->sa->curve->copy();
if(this->sa->start)
tmp_curve = tmp_curve ->create_reverse();
Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const*>(&*tmp_curve ->last_segment());
@@ -1490,9 +1489,9 @@ void PenTool::_bsplineSpiroStartAnchorOff()
}
void PenTool::_bsplineSpiroMotion(bool shift){
- if(!this->spiro && !this->bspline)
+ if(!this->spiro && !this->bspline){
return;
-
+ }
using Geom::X;
using Geom::Y;
if(this->red_curve->is_empty()) return;
@@ -1522,7 +1521,7 @@ void PenTool::_bsplineSpiroMotion(bool shift){
Geom::D2< Geom::SBasis > SBasisweight_power;
weight_power->moveto(tmp_curve ->last_segment()->finalPoint());
weight_power->lineto(tmp_curve ->last_segment()->initialPoint());
- float WP = Geom::nearest_point((*cubic)[2],*weight_power->first_segment());
+ float WP = Geom::nearest_time((*cubic)[2],*weight_power->first_segment());
weight_power->reset();
weight_power->moveto(this->red_curve->last_segment()->initialPoint());
weight_power->lineto(this->red_curve->last_segment()->finalPoint());
@@ -1564,7 +1563,7 @@ void PenTool::_bsplineSpiroEndAnchorOn()
using Geom::Y;
this->p[2] = this->p[3] + (1./3)*(this->p[0] - this->p[3]);
this->p[2] = Geom::Point(this->p[2][X] + HANDLE_CUBIC_GAP,this->p[2][Y] + HANDLE_CUBIC_GAP);
- SPCurve *tmp_curve = new SPCurve();
+ SPCurve *tmp_curve;
SPCurve *last_segment = new SPCurve();
Geom::Point point_c(0,0);
bool reverse = false;
@@ -1621,7 +1620,7 @@ void PenTool::_bsplineSpiroEndAnchorOn()
void PenTool::_bsplineSpiroEndAnchorOff()
{
- SPCurve *tmp_curve = new SPCurve();
+ SPCurve *tmp_curve;
SPCurve *last_segment = new SPCurve();
bool reverse = false;
this->p[2] = this->p[3];
@@ -1744,7 +1743,7 @@ void PenTool::_bsplineSpiroBuild()
//from LPE BSPLINE:
void PenTool::_bsplineDoEffect(SPCurve * curve)
{
- const double NO_POWER = 0.0;
+ //const double NO_POWER = 0.0;
const double DEFAULT_START_POWER = 0.3334;
const double DEFAULT_END_POWER = 0.6667;
if (curve->get_segment_count() < 1) {
@@ -1798,12 +1797,12 @@ void PenTool::_bsplineDoEffect(SPCurve * curve)
if(are_near((*cubic)[1],(*cubic)[0]) && !are_near((*cubic)[2],(*cubic)[3])) {
point_at1 = sbasis_in.valueAt(DEFAULT_START_POWER);
} else {
- point_at1 = sbasis_in.valueAt(Geom::nearest_point((*cubic)[1], *in->first_segment()));
+ point_at1 = sbasis_in.valueAt(Geom::nearest_time((*cubic)[1], *in->first_segment()));
}
if(are_near((*cubic)[2],(*cubic)[3]) && !are_near((*cubic)[1],(*cubic)[0])) {
point_at2 = sbasis_in.valueAt(DEFAULT_END_POWER);
} else {
- point_at2 = sbasis_in.valueAt(Geom::nearest_point((*cubic)[2], *in->first_segment()));
+ point_at2 = sbasis_in.valueAt(Geom::nearest_time((*cubic)[2], *in->first_segment()));
}
} else {
point_at1 = in->first_segment()->initialPoint();
@@ -1821,7 +1820,7 @@ void PenTool::_bsplineDoEffect(SPCurve * curve)
if(are_near((*cubic)[1],(*cubic)[0]) && !are_near((*cubic)[2],(*cubic)[3])) {
next_point_at1 = sbasis_in.valueAt(DEFAULT_START_POWER);
} else {
- next_point_at1 = sbasis_out.valueAt(Geom::nearest_point((*cubic)[1], *out->first_segment()));
+ next_point_at1 = sbasis_out.valueAt(Geom::nearest_time((*cubic)[1], *out->first_segment()));
}
} else {
next_point_at1 = out->first_segment()->initialPoint();
@@ -1838,7 +1837,7 @@ void PenTool::_bsplineDoEffect(SPCurve * curve)
cubic = dynamic_cast<Geom::CubicBezier const *>(&*path_it->begin());
if (cubic) {
line_helper->moveto(sbasis_start.valueAt(
- Geom::nearest_point((*cubic)[1], *start->first_segment())));
+ Geom::nearest_time((*cubic)[1], *start->first_segment())));
} else {
line_helper->moveto(start->first_segment()->initialPoint());
}
@@ -1852,7 +1851,7 @@ void PenTool::_bsplineDoEffect(SPCurve * curve)
cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1);
if (cubic) {
line_helper->lineto(sbasis_end.valueAt(
- Geom::nearest_point((*cubic)[2], *end->first_segment())));
+ Geom::nearest_time((*cubic)[2], *end->first_segment())));
} else {
line_helper->lineto(end->first_segment()->finalPoint());
}
diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp
index 008804162..16c26546f 100644
--- a/src/ui/tools/pencil-tool.cpp
+++ b/src/ui/tools/pencil-tool.cpp
@@ -53,6 +53,7 @@ static Geom::Point pencil_drag_origin_w(0, 0);
static bool pencil_within_tolerance = false;
static bool in_svg_plane(Geom::Point const &p) { return Geom::LInfty(p) < 1e18; }
+const double HANDLE_CUBIC_GAP = 0.01;
const std::string& PencilTool::getPrefsPath() {
return PencilTool::prefsPath;
@@ -357,7 +358,6 @@ bool PencilTool::_handleButtonRelease(GdkEventButton const &revent) {
// Ctrl+click creates a single point so only set context in ADDLINE mode when Ctrl isn't pressed
this->state = SP_PENCIL_CONTEXT_ADDLINE;
}
- ret = true;
break;
case SP_PENCIL_CONTEXT_ADDLINE:
/* Finish segment now */
@@ -371,7 +371,6 @@ bool PencilTool::_handleButtonRelease(GdkEventButton const &revent) {
this->_finishEndpoint();
this->state = SP_PENCIL_CONTEXT_IDLE;
sp_event_context_discard_delayed_snap_event(this);
- ret = true;
break;
case SP_PENCIL_CONTEXT_FREEHAND:
if (revent.state & GDK_MOD1_MASK) {
@@ -413,7 +412,6 @@ bool PencilTool::_handleButtonRelease(GdkEventButton const &revent) {
// reset sketch mode too
this->sketch_n = 0;
}
- ret = true;
break;
case SP_PENCIL_CONTEXT_SKETCH:
default:
@@ -663,10 +661,10 @@ void PencilTool::_interpolate() {
for (int c = 0; c < n_segs; c++) {
// if we are in BSpline we modify the trace to create adhoc nodes
if(mode == 2){
- Geom::Point point_at1 = b[4*c+0] + (1./3)*(b[4*c+3] - b[4*c+0]);
- point_at1 = Geom::Point(point_at1[X] + 0.0001,point_at1[Y] + 0.0001);
- Geom::Point point_at2 = b[4*c+3] + (1./3)*(b[4*c+0] - b[4*c+3]);
- point_at2 = Geom::Point(point_at2[X] + 0.0001,point_at2[Y] + 0.0001);
+ Geom::Point point_at1 = b[4 * c + 0] + (1./3) * (b[4 * c + 3] - b[4 * c + 0]);
+ point_at1 = Geom::Point(point_at1[X] + HANDLE_CUBIC_GAP, point_at1[Y] + HANDLE_CUBIC_GAP);
+ Geom::Point point_at2 = b[4 * c + 3] + (1./3) * (b[4 * c + 0] - b[4 * c + 3]);
+ point_at2 = Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP);
this->green_curve->curveto(point_at1,point_at2,b[4*c+3]);
}else{
this->green_curve->curveto(b[4 * c + 1], b[4 * c + 2], b[4 * c + 3]);
@@ -811,9 +809,9 @@ void PencilTool::_fitAndSplit() {
guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0);
if(mode == 2){
Geom::Point point_at1 = b[0] + (1./3)*(b[3] - b[0]);
- point_at1 = Geom::Point(point_at1[X] + 0.0001,point_at1[Y] + 0.0001);
+ point_at1 = Geom::Point(point_at1[X] + HANDLE_CUBIC_GAP, point_at1[Y] + HANDLE_CUBIC_GAP);
Geom::Point point_at2 = b[3] + (1./3)*(b[0] - b[3]);
- point_at2 = Geom::Point(point_at2[X] + 0.0001,point_at2[Y] + 0.0001);
+ point_at2 = Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP);
this->red_curve->curveto(point_at1,point_at2,b[3]);
}else{
this->red_curve->curveto(b[1], b[2], b[3]);
diff --git a/src/ui/tools/rect-tool.cpp b/src/ui/tools/rect-tool.cpp
index 62a9006ea..844965c4d 100644
--- a/src/ui/tools/rect-tool.cpp
+++ b/src/ui/tools/rect-tool.cpp
@@ -143,7 +143,6 @@ bool RectTool::item_handler(SPItem* item, GdkEvent* event) {
case GDK_BUTTON_PRESS:
if ( event->button.button == 1 && !this->space_panning) {
Inkscape::setup_for_drag_start(desktop, this, event);
- ret = TRUE;
}
break;
// motion and release are always on root (why?)
diff --git a/src/ui/tools/select-tool.cpp b/src/ui/tools/select-tool.cpp
index 40b994968..f06b03d91 100644
--- a/src/ui/tools/select-tool.cpp
+++ b/src/ui/tools/select-tool.cpp
@@ -472,7 +472,7 @@ bool SelectTool::root_handler(GdkEvent* event) {
case GDK_2BUTTON_PRESS:
if (event->button.button == 1) {
if (!selection->isEmpty()) {
- SPItem *clicked_item = static_cast<SPItem *>(selection->itemList()->data);
+ SPItem *clicked_item = selection->itemList()[0];
if (dynamic_cast<SPGroup *>(clicked_item) && !dynamic_cast<SPBox3D *>(clicked_item)) { // enter group if it's not a 3D box
desktop->setCurrentLayer(clicked_item);
@@ -709,7 +709,7 @@ bool SelectTool::root_handler(GdkEvent* event) {
if (r->is_started() && !within_tolerance) {
// this was a rubberband drag
- GSList *items = NULL;
+ std::vector<SPItem*> items;
if (r->getMode() == RUBBERBAND_MODE_RECT) {
Geom::OptRect const b = r->getRectangle();
@@ -730,7 +730,6 @@ bool SelectTool::root_handler(GdkEvent* event) {
selection->setList (items);
}
- g_slist_free (items);
} else { // it was just a click, or a too small rubberband
r->stop();
@@ -778,7 +777,6 @@ bool SelectTool::root_handler(GdkEvent* event) {
}
rb_escaped = 0;
- ret = TRUE;
}
}
}
diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp
index 0399b1e55..e2be5ca4b 100644
--- a/src/ui/tools/spray-tool.cpp
+++ b/src/ui/tools/spray-tool.cpp
@@ -133,14 +133,13 @@ SprayTool::SprayTool()
: ToolBase(cursor_spray_xpm, 4, 4, false)
, pressure(TC_DEFAULT_PRESSURE)
, dragging(false)
- , usepressure(0)
- , usetilt(0)
+ , usepressure(false)
+ , usetilt(false)
, usetext(false)
, width(0.2)
, ratio(0)
, tilt(0)
, rotation_variation(0)
- , force(0.2)
, population(0)
, scale_variation(1)
, scale(1)
@@ -165,20 +164,12 @@ SprayTool::~SprayTool() {
}
}
-static bool is_transform_modes(gint mode)
-{
- return (mode == SPRAY_MODE_COPY ||
- mode == SPRAY_MODE_CLONE ||
- mode == SPRAY_MODE_SINGLE_PATH ||
- mode == SPRAY_OPTION);
-}
-
void SprayTool::update_cursor(bool /*with_shift*/) {
guint num = 0;
gchar *sel_message = NULL;
if (!desktop->selection->isEmpty()) {
- num = g_slist_length(const_cast<GSList *>(desktop->selection->itemList()));
+ num = desktop->selection->itemList().size();
sel_message = g_strdup_printf(ngettext("<b>%i</b> object selected","<b>%i</b> objects selected",num), num);
} else {
sel_message = g_strdup_printf("%s", _("<b>Nothing</b> selected"));
@@ -207,8 +198,7 @@ void SprayTool::setup() {
{
/* TODO: have a look at sp_dyna_draw_context_setup where the same is done.. generalize? at least make it an arcto! */
- Geom::PathVector path;
- Geom::Circle(0, 0, 1).getPath(path);
+ Geom::PathVector path = Geom::Path(Geom::Circle(0,0,1));
SPCurve *c = new SPCurve(path);
@@ -229,7 +219,6 @@ void SprayTool::setup() {
sp_event_context_read(this, "scale_variation");
sp_event_context_read(this, "mode");
sp_event_context_read(this, "population");
- sp_event_context_read(this, "force");
sp_event_context_read(this, "mean");
sp_event_context_read(this, "standard_deviation");
sp_event_context_read(this, "usepressure");
@@ -271,9 +260,7 @@ void SprayTool::set(const Inkscape::Preferences::Entry& val) {
this->tilt = CLAMP(val.getDouble(0.1), 0, 1000.0);
} else if (path == "ratio") {
this->ratio = CLAMP(val.getDouble(), 0.0, 0.9);
- } else if (path == "force") {
- this->force = CLAMP(val.getDouble(1.0), 0, 1.0);
- }
+ }
}
static void sp_spray_extinput(SprayTool *tc, GdkEvent *event)
@@ -290,16 +277,6 @@ static double get_dilate_radius(SprayTool *tc)
return 250 * tc->width/SP_EVENT_CONTEXT(tc)->desktop->current_zoom();
}
-static double get_path_force(SprayTool *tc)
-{
- double force = 8 * (tc->usepressure? tc->pressure : TC_DEFAULT_PRESSURE)
- /sqrt(SP_EVENT_CONTEXT(tc)->desktop->current_zoom());
- if (force > 3) {
- force += 4 * (force - 3);
- }
- return force * tc->force;
-}
-
static double get_path_mean(SprayTool *tc)
{
return tc->mean;
@@ -310,10 +287,11 @@ static double get_path_standard_deviation(SprayTool *tc)
return tc->standard_deviation;
}
-static double get_move_force(SprayTool *tc)
+static double get_population(SprayTool *tc)
{
- double force = (tc->usepressure? tc->pressure : TC_DEFAULT_PRESSURE);
- return force * tc->force;
+ double pressure = (tc->usepressure? tc->pressure / TC_DEFAULT_PRESSURE : 1);
+ //g_warning("Pressure, population: %f, %f", pressure, pressure * tc->population);
+ return pressure * tc->population;
}
static double get_move_mean(SprayTool *tc)
@@ -361,7 +339,6 @@ static bool sp_spray_recursive(SPDesktop *desktop,
Geom::Point /*vector*/,
gint mode,
double radius,
- double /*force*/,
double population,
double &scale,
double scale_variation,
@@ -426,11 +403,9 @@ static bool sp_spray_recursive(SPDesktop *desktop,
SPItem *unionResult = NULL; // Previous union
int i=1;
- for (GSList *items = g_slist_copy(const_cast<GSList *>(selection->itemList()));
- items != NULL;
- items = items->next) {
-
- SPItem *item1 = dynamic_cast<SPItem *>(static_cast<SPObject *>(items->data));
+ std::vector<SPItem*> items=selection->itemList();
+ for(std::vector<SPItem*>::const_iterator it=items.begin();it!=items.end();it++){
+ SPItem *item1 = *it;
if (i == 1) {
parent_item = item1;
}
@@ -527,8 +502,8 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point
bool did = false;
double radius = get_dilate_radius(tc);
- double path_force = get_path_force(tc);
- if (radius == 0 || path_force == 0) {
+ double population = get_population(tc);
+ if (radius == 0 || population == 0) {
return false;
}
double path_mean = get_path_mean(tc);
@@ -539,42 +514,29 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point
if (radius == 0 || path_standard_deviation == 0) {
return false;
}
- double move_force = get_move_force(tc);
double move_mean = get_move_mean(tc);
double move_standard_deviation = get_move_standard_deviation(tc);
{
- GSList *const original_selection = g_slist_copy(const_cast<GSList *>(selection->itemList()));
+ std::vector<SPItem*> const items(selection->itemList());
- for (GSList *items = original_selection;
- items != NULL;
- items = items->next) {
- SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(items->data));
+ for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++){
+ SPItem *item = *i;
g_assert(item != NULL);
sp_object_ref(item);
}
- for (GSList *items = original_selection;
- items != NULL;
- items = items->next) {
- SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(items->data));
+ for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++){
+ SPItem *item = *i;
g_assert(item != NULL);
- if (is_transform_modes(tc->mode)) {
- if (sp_spray_recursive(desktop, selection, item, p, vector, tc->mode, radius, move_force, tc->population, tc->scale, tc->scale_variation, reverse, move_mean, move_standard_deviation, tc->ratio, tc->tilt, tc->rotation_variation, tc->distrib)) {
- did = true;
- }
- } else {
- if (sp_spray_recursive(desktop, selection, item, p, vector, tc->mode, radius, path_force, tc->population, tc->scale, tc->scale_variation, reverse, path_mean, path_standard_deviation, tc->ratio, tc->tilt, tc->rotation_variation, tc->distrib)) {
- did = true;
- }
+ if (sp_spray_recursive(desktop, selection, item, p, vector, tc->mode, radius, population, tc->scale, tc->scale_variation, reverse, move_mean, move_standard_deviation, tc->ratio, tc->tilt, tc->rotation_variation, tc->distrib)) {
+ did = true;
}
}
- for (GSList *items = original_selection;
- items != NULL;
- items = items->next) {
- SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(items->data));
+ for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++){
+ SPItem *item = *i;
g_assert(item != NULL);
sp_object_unref(item);
}
@@ -650,7 +612,7 @@ bool SprayTool::root_handler(GdkEvent* event) {
guint num = 0;
if (!desktop->selection->isEmpty()) {
- num = g_slist_length(const_cast<GSList *>(desktop->selection->itemList()));
+ num = desktop->selection->itemList().size();
}
if (num == 0) {
this->message_context->flash(Inkscape::ERROR_MESSAGE, _("<b>Nothing selected!</b> Select objects to spray."));
diff --git a/src/ui/tools/spray-tool.h b/src/ui/tools/spray-tool.h
index 1a8f98006..8df730201 100644
--- a/src/ui/tools/spray-tool.h
+++ b/src/ui/tools/spray-tool.h
@@ -52,8 +52,8 @@ enum {
class SprayTool : public ToolBase {
public:
- SprayTool();
- virtual ~SprayTool();
+ SprayTool();
+ virtual ~SprayTool();
//ToolBase event_context;
//Inkscape::UI::Dialog::Dialog *dialog_option;//Attribut de type SprayOptionClass, localisé dans scr/ui/dialog
@@ -70,7 +70,6 @@ public:
double ratio;
double tilt;
double rotation_variation;
- double force;
double population;
double scale_variation;
double scale;
@@ -90,16 +89,16 @@ public:
sigc::connection style_set_connection;
- static const std::string prefsPath;
+ static const std::string prefsPath;
- virtual void setup();
- virtual void set(const Inkscape::Preferences::Entry& val);
- virtual bool root_handler(GdkEvent* event);
+ virtual void setup();
+ virtual void set(const Inkscape::Preferences::Entry& val);
+ virtual bool root_handler(GdkEvent* event);
- virtual const std::string& getPrefsPath();
+ virtual const std::string& getPrefsPath();
- void update_cursor(bool /*with_shift*/);
+ void update_cursor(bool /*with_shift*/);
};
}
diff --git a/src/ui/tools/text-tool.cpp b/src/ui/tools/text-tool.cpp
index a2c0c81ae..1888551cf 100644
--- a/src/ui/tools/text-tool.cpp
+++ b/src/ui/tools/text-tool.cpp
@@ -1461,7 +1461,7 @@ int TextTool::_styleQueried(SPStyle *style, int property)
}
sp_text_context_validate_cursor_iterators(this);
- GSList *styles_list = NULL;
+ std::vector<SPItem*> styles_list;
Inkscape::Text::Layout::iterator begin_it, end_it;
if (this->text_sel_start < this->text_sel_end) {
@@ -1477,7 +1477,7 @@ int TextTool::_styleQueried(SPStyle *style, int property)
}
}
for (Inkscape::Text::Layout::iterator it = begin_it ; it < end_it ; it.nextStartOfSpan()) {
- SPObject const *pos_obj = 0;
+ SPObject *pos_obj = 0;
void *rawptr = 0;
layout->getSourceOfCharacter(it, &rawptr);
if (!rawptr || !SP_IS_OBJECT(rawptr)) {
@@ -1487,12 +1487,11 @@ int TextTool::_styleQueried(SPStyle *style, int property)
while (SP_IS_STRING(pos_obj) && pos_obj->parent) {
pos_obj = pos_obj->parent; // SPStrings don't have style
}
- styles_list = g_slist_prepend(styles_list, (gpointer)pos_obj);
+ styles_list.insert(styles_list.begin(),(SPItem*)pos_obj);
}
int result = sp_desktop_query_style_from_list (styles_list, style, property);
- g_slist_free(styles_list);
return result;
}
diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp
index 2eb6d24d9..0f9b3ee7a 100644
--- a/src/ui/tools/tool-base.cpp
+++ b/src/ui/tools/tool-base.cpp
@@ -1174,11 +1174,9 @@ SPItem *sp_event_context_find_item(SPDesktop *desktop, Geom::Point const &p,
SPItem *
sp_event_context_over_item(SPDesktop *desktop, SPItem *item,
Geom::Point const &p) {
- GSList *temp = NULL;
- temp = g_slist_prepend(temp, item);
+ std::vector<SPItem*> temp;
+ temp.push_back(item);
SPItem *item_at_point = desktop->getItemFromListAtPointBottom(temp, p);
- g_slist_free(temp);
-
return item_at_point;
}
diff --git a/src/ui/tools/tool-base.h b/src/ui/tools/tool-base.h
index 7a6ab83e7..58eb6f88e 100644
--- a/src/ui/tools/tool-base.h
+++ b/src/ui/tools/tool-base.h
@@ -75,7 +75,12 @@ public:
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
double value = prefs->getDoubleLimited("/options/snapdelay/value", 0, 0, 1000);
- _timer_id = g_timeout_add(value, &sp_event_context_snap_watchdog_callback, this);
+ // We used to have this specified in milliseconds; this has changed to seconds now for consistency's sake
+ if (value > 1) { // Apparently we have an old preference file, this value must have been in milliseconds;
+ value = value / 1000.0; // now convert this value to seconds
+ }
+
+ _timer_id = g_timeout_add(value*1000.0, &sp_event_context_snap_watchdog_callback, this);
_event = gdk_event_copy((GdkEvent*) event);
((GdkEventMotion *)_event)->time = GDK_CURRENT_TIME;
diff --git a/src/ui/tools/tweak-tool.cpp b/src/ui/tools/tweak-tool.cpp
index 80b52fba6..94f7aa135 100644
--- a/src/ui/tools/tweak-tool.cpp
+++ b/src/ui/tools/tweak-tool.cpp
@@ -153,7 +153,7 @@ void TweakTool::update_cursor (bool with_shift) {
gchar *sel_message = NULL;
if (!desktop->selection->isEmpty()) {
- num = g_slist_length(const_cast<GSList *>(desktop->selection->itemList()));
+ num = desktop->selection->itemList().size();
sel_message = g_strdup_printf(ngettext("<b>%i</b> object selected","<b>%i</b> objects selected",num), num);
} else {
sel_message = g_strdup_printf("%s", _("<b>Nothing</b> selected"));
@@ -259,8 +259,7 @@ void TweakTool::setup() {
{
/* TODO: have a look at sp_dyna_draw_context_setup where the same is done.. generalize? at least make it an arcto! */
- Geom::PathVector path;
- Geom::Circle(0, 0, 1).getPath(path);
+ Geom::PathVector path = Geom::Path(Geom::Circle(0,0,1));
SPCurve *c = new SPCurve(path);
@@ -372,14 +371,13 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P
}
if (dynamic_cast<SPText *>(item) || dynamic_cast<SPFlowtext *>(item)) {
- GSList *items = g_slist_prepend (NULL, item);
- GSList *selected = NULL;
- GSList *to_select = NULL;
+ std::vector<SPItem*> items;
+ items.push_back(item);
+ std::vector<SPItem*> selected;
+ std::vector<Inkscape::XML::Node*> to_select;
SPDocument *doc = item->document;
- sp_item_list_to_curves (items, &selected, &to_select);
- g_slist_free (items);
- SPObject* newObj = doc->getObjectByRepr(static_cast<Inkscape::XML::Node *>(to_select->data));
- g_slist_free (to_select);
+ sp_item_list_to_curves (items, selected, to_select);
+ SPObject* newObj = doc->getObjectByRepr(to_select[0]);
item = dynamic_cast<SPItem *>(newObj);
g_assert(item != NULL);
selection->add(item);
@@ -1078,11 +1076,9 @@ sp_tweak_dilate (TweakTool *tc, Geom::Point event_p, Geom::Point p, Geom::Point
double move_force = get_move_force(tc);
double color_force = MIN(sqrt(path_force)/20.0, 1);
- for (GSList *items = g_slist_copy(const_cast<GSList *>(selection->itemList()));
- items != NULL;
- items = items->next) {
-
- SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(items->data));
+ std::vector<SPItem*> items=selection->itemList();
+ for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++){
+ SPItem *item = *i;
if (is_color_mode (tc->mode)) {
if (do_fill || do_stroke || do_opacity) {
@@ -1189,7 +1185,7 @@ bool TweakTool::root_handler(GdkEvent* event) {
guint num = 0;
if (!desktop->selection->isEmpty()) {
- num = g_slist_length(const_cast<GSList *>(desktop->selection->itemList()));
+ num = desktop->selection->itemList().size();
}
if (num == 0) {
this->message_context->flash(Inkscape::ERROR_MESSAGE, _("<b>Nothing selected!</b> Select objects to tweak."));