summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 2f616c2)
raw | patch | inline | side by side (parent: 2f616c2)
author | dvlierop2 <dvlierop2@users.sourceforge.net> | |
Fri, 20 Feb 2009 21:49:07 +0000 (21:49 +0000) | ||
committer | dvlierop2 <dvlierop2@users.sourceforge.net> | |
Fri, 20 Feb 2009 21:49:07 +0000 (21:49 +0000) |
56 files changed:
diff --git a/src/arc-context.cpp b/src/arc-context.cpp
index da236ae8730672f7b1278afed563edd3a4538b39..115b5534c16137279b291f87c39aaae24e450262 100644 (file)
--- a/src/arc-context.cpp
+++ b/src/arc-context.cpp
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
Geom::Point pt2g = to_2geom(ac->center);
- m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g);
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE);
ac->center = from_2geom(pt2g);
sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
diff --git a/src/box3d-context.cpp b/src/box3d-context.cpp
index 2b76233f5c5cdf3d88a1eb62ec01bfef760081d4..e8cee44b05f1ab4b90da783c64c8b913ae36e964 100644 (file)
--- a/src/box3d-context.cpp
+++ b/src/box3d-context.cpp
@@ -294,7 +294,7 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
/* Snap center */
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop, true, bc->item);
- m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, button_dt);
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, button_dt, Inkscape::SNAPSOURCE_HANDLE);
bc->center = from_2geom(button_dt);
sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
@@ -326,7 +326,7 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop, true, bc->item);
- m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, motion_dt);
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, motion_dt, Inkscape::SNAPSOURCE_HANDLE);
bc->ctrl_dragged = event->motion.state & GDK_CONTROL_MASK;
@@ -360,7 +360,7 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
bc->drag_ptC_proj = cur_persp->tmat.preimage (from_2geom(motion_dt), bc->drag_ptB_proj[Proj::X], Proj::X);
}
Geom::Point pt2g = to_2geom(bc->drag_ptC);
- m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g);
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE);
bc->drag_ptC = from_2geom(pt2g);
}
index 6fa709b18915437322ef9827a8daacbb0e2786d9..a3bb19de6d6131c397c66669f171f2ca53fb69bb 100644 (file)
@@ -537,7 +537,7 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const
// as there's no other points to go off.
SnapManager &m = cc->desktop->namedview->snap_manager;
m.setup(cc->desktop);
- m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g);
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE);
}
spcc_connector_set_initial_point(cc, from_2geom(pt2g));
diff --git a/src/context-fns.cpp b/src/context-fns.cpp
index 54b07a02a76f05287b7a8b2fce27a78b85902344..30062504cfd03d81f91f01b4bd7e2d74026eca51 100644 (file)
--- a/src/context-fns.cpp
+++ b/src/context-fns.cpp
@@ -132,11 +132,11 @@ Geom::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item
Inkscape::SnappedPoint s[2];
/* Try to snap p[0] (the opposite corner) along the constraint vector */
- s[0] = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[0]),
+ s[0] = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[0]), Inkscape::SNAPSOURCE_HANDLE,
Inkscape::Snapper::ConstraintLine(p[0] - p[1]));
/* Try to snap p[1] (the dragged corner) along the constraint vector */
- s[1] = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[1]),
+ s[1] = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[1]), Inkscape::SNAPSOURCE_HANDLE,
Inkscape::Snapper::ConstraintLine(p[1] - p[0]));
/* Choose the best snap and update points accordingly */
@@ -157,7 +157,7 @@ Geom::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item
/* Our origin is the opposite corner. Snap the drag point along the constraint vector */
p[0] = center;
- snappoint = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[1]),
+ snappoint = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[1]), Inkscape::SNAPSOURCE_HANDLE,
Inkscape::Snapper::ConstraintLine(p[1] - p[0]));
if (snappoint.getSnapped()) {
p[1] = snappoint.getPoint();
@@ -175,8 +175,8 @@ Geom::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item
Inkscape::SnappedPoint s[2];
- s[0] = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[0]));
- s[1] = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[1]));
+ s[0] = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[0]), Inkscape::SNAPSOURCE_HANDLE);
+ s[1] = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p[1]), Inkscape::SNAPSOURCE_HANDLE);
if (s[0].getSnapDistance() < s[1].getSnapDistance()) {
if (s[0].getSnapped()) {
@@ -197,7 +197,7 @@ Geom::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item
/* There's no constraint on the corner point, so just snap it to anything */
p[0] = center;
p[1] = pt;
- snappoint = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(pt));
+ snappoint = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(pt), Inkscape::SNAPSOURCE_HANDLE);
if (snappoint.getSnapped()) {
p[1] = snappoint.getPoint();
}
@@ -209,7 +209,7 @@ Geom::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item
p[0] = sp_desktop_dt2doc_xy_point(desktop, p[0]);
p[1] = sp_desktop_dt2doc_xy_point(desktop, p[1]);
-
+
return Geom::Rect(Geom::Point(MIN(p[0][Geom::X], p[1][Geom::X]), MIN(p[0][Geom::Y], p[1][Geom::Y])),
Geom::Point(MAX(p[0][Geom::X], p[1][Geom::X]), MAX(p[0][Geom::Y], p[1][Geom::Y])));
}
index 076dcdd332613e346f8f2c002ce7b090c33f8f6f..ea5393d393f3b090229e5b20a07332b928120f25 100644 (file)
return s;
}
-void CanvasAxonomGridSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, Geom::Point const normal_to_line, Geom::Point const point_on_line) const
+void CanvasAxonomGridSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Point const normal_to_line, Geom::Point const point_on_line) const
{
- SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line);
+ SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, source, target, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line);
sc.grid_lines.push_back(dummy);
}
index 4849f08ad50d025cda018d1840a42134d0f6aec7..ecbd846a18e58549bea477ef4e165d9b8a7015fc 100644 (file)
private:
LineList _getSnapLines(Geom::Point const &p) const;
- void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, Geom::Point const normal_to_line, const Geom::Point point_on_line) const;
+ void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Point const normal_to_line, const Geom::Point point_on_line) const;
CanvasAxonomGrid *grid;
};
index 49a1211eb9eb45f266489a4847483b48f5b8a72a..3e7295b90aea83cf2ac2b7656ead1d0495e667ca 100644 (file)
return s;
}
-void CanvasXYGridSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, Geom::Point const normal_to_line, Geom::Point const point_on_line) const
+void CanvasXYGridSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Point const normal_to_line, Geom::Point const point_on_line) const
{
- SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line);
+ SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, source, target, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line);
sc.grid_lines.push_back(dummy);
}
index 85e890feff84d5bc93d760967c011b2b13bc668a..37e30fab0fcfcaff83cebbae166aa2015c535f27 100644 (file)
private:
LineList _getSnapLines(Geom::Point const &p) const;
- void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, Geom::Point const normal_to_line, const Geom::Point point_on_line) const;
+ void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Point const normal_to_line, const Geom::Point point_on_line) const;
CanvasXYGrid *grid;
};
index 1785da7b91896d9a1ab60de6c874fb63c3852fe2..e55c8faac2d88dca24e15c3c08da99ca52e3ff0f 100644 (file)
case SNAPTARGET_GRID_GUIDE_INTERSECTION:
target_name = _("grid-guide intersection");
break;
- case SNAPTARGET_NODE:
- target_name = _("node");
+ case SNAPTARGET_NODE_CUSP:
+ target_name = _("cusp node");
+ break;
+ case SNAPTARGET_NODE_SMOOTH:
+ target_name = _("smooth node");
break;
case SNAPTARGET_PATH:
target_name = _("path");
case SNAPTARGET_PAGE_BORDER:
target_name = _("page border");
break;
+ case SNAPTARGET_LINE_MIDPOINT:
+ target_name = _("line midpoint");
+ break;
+ case SNAPTARGET_OBJECT_MIDPOINT:
+ target_name = _("object midpoint");
+ break;
+ case SNAPTARGET_ROTATION_CENTER:
+ target_name = _("object rotation center");
+ break;
+ case SNAPTARGET_HANDLE:
+ target_name = _("handle");
+ break;
+ case SNAPTARGET_BBOX_EDGE_MIDPOINT:
+ target_name = _("bounding box side midpoint");
+ break;
+ case SNAPTARGET_BBOX_MIDPOINT:
+ target_name = _("bounding box midpoint");
+ break;
+ case SNAPTARGET_PAGE_CORNER:
+ target_name = _("page corner");
+ break;
+ case SNAPTARGET_CONVEX_HULL_CORNER:
+ target_name = _("convex hull corner");
+ break;
+ case SNAPTARGET_ELLIPSE_QUADRANT_POINT:
+ target_name = _("quadrant point");
+ break;
default:
g_warning("Snap target has not yet been defined!");
break;
}
- // std::cout << "Snapped to: " << target_name << std::endl;
+
+ gchar *source_name = _("UNDEFINED");
+ switch (p.getSource()) {
+ case SNAPSOURCE_UNDEFINED:
+ source_name = _("UNDEFINED");
+ break;
+ case SNAPSOURCE_BBOX_CORNER:
+ source_name = _("Bounding box corner");
+ break;
+ case SNAPSOURCE_BBOX_MIDPOINT:
+ source_name = _("Bounding box midpoint");
+ break;
+ case SNAPSOURCE_BBOX_EDGE_MIDPOINT:
+ source_name = _("Bounding box side midpoint");
+ break;
+ case SNAPSOURCE_NODE_SMOOTH:
+ source_name = _("Smooth node");
+ break;
+ case SNAPSOURCE_NODE_CUSP:
+ source_name = _("Cusp node");
+ break;
+ case SNAPSOURCE_LINE_MIDPOINT:
+ source_name = _("Line midpoint");
+ break;
+ case SNAPSOURCE_OBJECT_MIDPOINT:
+ source_name = _("Object midpoint");
+ break;
+ case SNAPSOURCE_ROTATION_CENTER:
+ source_name = _("Object rotation center");
+ break;
+ case SNAPSOURCE_HANDLE:
+ source_name = _("Handle");
+ break;
+ case SNAPSOURCE_PATH_INTERSECTION:
+ source_name = _("Path intersection");
+ break;
+ case SNAPSOURCE_GUIDE:
+ source_name = _("Guide");
+ break;
+ case SNAPSOURCE_CONVEX_HULL_CORNER:
+ source_name = _("Convex hull corner");
+ break;
+ case SNAPSOURCE_ELLIPSE_QUADRANT_POINT:
+ source_name = _("Quadrant point");
+ break;
+ default:
+ g_warning("Snap source has not yet been defined!");
+ break;
+ }
+ //std::cout << "Snapped " << source_name << " to " << target_name << std::endl;
// Display the snap indicator (i.e. the cross)
SPCanvasItem * canvasitem = NULL;
- if (p.getTarget() == SNAPTARGET_NODE) {
+ if (p.getTarget() == SNAPTARGET_NODE_SMOOTH || p.getTarget() == SNAPTARGET_NODE_CUSP) {
canvasitem = sp_canvas_item_new(sp_desktop_tempgroup (_desktop),
SP_TYPE_CTRL,
"anchor", GTK_ANCHOR_CENTER,
GtkSettings *settings = gtk_widget_get_settings (&(_desktop->canvas->widget));
// If we set the timeout too short, then the tooltip might not show at all (most noticeable when a long snap delay is active)
g_object_set(settings, "gtk-tooltip-timeout", 200, NULL); // tooltip will be shown after x msec.
- gtk_widget_set_tooltip_text(&(_desktop->canvas->widget), target_name);
+ gchar *tooltip_text = g_strconcat(source_name, _(" to "), target_name, NULL);
+ gtk_widget_set_tooltip_text(&(_desktop->canvas->widget), tooltip_text);
// has_tooltip will be true by now because gtk_widget_set_has_tooltip() has been called implicitly
update_tooltip();
// The snap indicator will be removed automatically because it's a temporary canvas item; the tooltip
}
void
-SnapIndicator::set_new_snapsource(Geom::Point const p)
+SnapIndicator::set_new_snapsource(std::pair<Geom::Point, int> const p)
{
remove_snapsource();
"shape", SP_KNOT_SHAPE_CIRCLE,
NULL );
- SP_CTRL(canvasitem)->moveto(p);
+ SP_CTRL(canvasitem)->moveto(p.first);
_snapsource = _desktop->add_temporary_canvasitem(canvasitem, 1000);
}
}
index 672d2e78c6f2331309ae46511901a666efd7eb58..ae0963b4f93ad0ac5d5e6a4c681d686768abeca5 100644 (file)
void set_new_snaptarget(Inkscape::SnappedPoint const p);
void remove_snaptarget();
- void set_new_snapsource(Geom::Point const p);
+ void set_new_snapsource(std::pair<Geom::Point, int> const p);
void remove_snapsource();
protected:
diff --git a/src/draw-context.cpp b/src/draw-context.cpp
index a8d6187f6917908e747b7e87f28afa75cdfc361f..b860c457d32a97838fe56e6b3ece410bc6bd4a59 100644 (file)
--- a/src/draw-context.cpp
+++ b/src/draw-context.cpp
@@ -513,7 +513,7 @@ void spdc_endpoint_snap_rotation(SPEventContext const *const ec, Geom::Point &p,
SnapManager &m = SP_EVENT_CONTEXT_DESKTOP(ec)->namedview->snap_manager;
m.setup(SP_EVENT_CONTEXT_DESKTOP(ec));
Geom::Point pt2g = to_2geom(p);
- m.constrainedSnapReturnByRef( Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::Snapper::ConstraintLine(best));
+ m.constrainedSnapReturnByRef( Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE, Inkscape::Snapper::ConstraintLine(best));
p = from_2geom(pt2g);
}
}
@@ -525,7 +525,7 @@ void spdc_endpoint_snap_free(SPEventContext const * const ec, Geom::Point& p, gu
SnapManager &m = SP_EVENT_CONTEXT_DESKTOP(ec)->namedview->snap_manager;
m.setup(SP_EVENT_CONTEXT_DESKTOP(ec));
Geom::Point pt2g = to_2geom(p);
- m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g);
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE);
p = from_2geom(pt2g);
}
index e9b46a2c29df5e3275d09c8a3d0af12665c68f79..16df41f7a82f6aa418ea38e8879214b59000defd 100644 (file)
--- a/src/gradient-context.cpp
+++ b/src/gradient-context.cpp
@@ -560,7 +560,7 @@ sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event)
/* Snap center to nearest magnetic point */
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
- m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, button_dt);
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, button_dt, Inkscape::SNAPSOURCE_HANDLE);
rc->origin = from_2geom(button_dt);
}
diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp
index a24f45c849c5b90bf444a39d96bc2c9b6ef2c7f1..76bed32cf5c1e3a953489a030e2f68e9958ad347 100644 (file)
--- a/src/gradient-drag.cpp
+++ b/src/gradient-drag.cpp
@@ -598,7 +598,7 @@ gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, guint state, gp
SPDesktop *desktop = dragger->parent->desktop;
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
- Inkscape::SnappedPoint s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p));
+ Inkscape::SnappedPoint s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(p), Inkscape::SNAPSOURCE_HANDLE);
if (s.getSnapped()) {
p = s.getPoint();
sp_knot_moveto (knot, p);
@@ -610,7 +610,7 @@ gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, guint state, gp
dist = fabs(p[Geom::Y] - dragger->parent->hor_levels[i]);
if (dist < snap_dist) {
p[Geom::Y] = dragger->parent->hor_levels[i];
- s = Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_GRADIENT, dist, snap_dist, false, false);
+ s = Inkscape::SnappedPoint(p, Inkscape::SNAPSOURCE_HANDLE, Inkscape::SNAPTARGET_GRADIENT, dist, snap_dist, false, false);
was_snapped = true;
sp_knot_moveto (knot, p);
}
@@ -619,7 +619,7 @@ gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, guint state, gp
dist = fabs(p[Geom::X] - dragger->parent->vert_levels[i]);
if (dist < snap_dist) {
p[Geom::X] = dragger->parent->vert_levels[i];
- s = Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_GRADIENT, dist, snap_dist, false, false);
+ s = Inkscape::SnappedPoint(p, Inkscape::SNAPSOURCE_HANDLE, Inkscape::SNAPTARGET_GRADIENT, dist, snap_dist, false, false);
was_snapped = true;
sp_knot_moveto (knot, p);
}
diff --git a/src/guide-snapper.cpp b/src/guide-snapper.cpp
index f344d891ff800d0f33fee390c20bf0e3d7f5bb1c..6df066cbbf3d2ad7f65f9fd0b615a8f1f56c5665 100644 (file)
--- a/src/guide-snapper.cpp
+++ b/src/guide-snapper.cpp
return (_snap_enabled && _snapmanager->snapprefs.getSnapToGuides() && _snapmanager->snapprefs.getSnapModeBBoxOrNodes() && _snapmanager->getNamedView()->showguides);
}
-void Inkscape::GuideSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, Geom::Point const normal_to_line, Geom::Point const point_on_line) const
+void Inkscape::GuideSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Point const normal_to_line, Geom::Point const point_on_line) const
{
- SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line);
+ SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, source, target, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line);
sc.guide_lines.push_back(dummy);
}
diff --git a/src/guide-snapper.h b/src/guide-snapper.h
index dd55816541a3c773da49ff0b5a8f2eb6a59323a0..8b59194e8f2db39d9aea393ca9e93bf6a1a2611d 100644 (file)
--- a/src/guide-snapper.h
+++ b/src/guide-snapper.h
private:
LineList _getSnapLines(Geom::Point const &p) const;
- void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, Geom::Point const normal_to_line, Geom::Point const point_on_line) const;
+ void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Point const normal_to_line, Geom::Point const point_on_line) const;
};
}
index 36a072c444b92d2767c611b5845dcd3ce1d05057..df58d356a1f20cbce3a9ba4064e02a39d5e6426d 100644 (file)
#define __KNOT_HOLDER_ENTITY_C__
-/** \file
- * KnotHolderEntity definition.
- *
+/** \file
+ * KnotHolderEntity definition.
+ *
* Authors:
* Mitsuru Oka <oka326@parkcity.ne.jp>
* Maximilian Albert <maximilian.albert@gmail.com>
Geom::Point dp(knot_get() * i2d);
_moved_connection.block();
- sp_knot_set_position(knot, dp, SP_KNOT_STATE_NORMAL);
+ sp_knot_set_position(knot, dp, SP_KNOT_STATE_NORMAL);
_moved_connection.unblock();
}
Geom::Point s = p * i2d;
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop, true, item);
- m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, s);
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, s, Inkscape::SNAPSOURCE_HANDLE);
return s * i2d.inverse();
}
diff --git a/src/line-snapper.cpp b/src/line-snapper.cpp
index bc43d640b0d9c6a327c26fe2e8a2609b2b1f69eb..d751993dda940d8c9d84a4b560d36495470f1277 100644 (file)
--- a/src/line-snapper.cpp
+++ b/src/line-snapper.cpp
@@ -26,10 +26,11 @@ Inkscape::LineSnapper::LineSnapper(SnapManager *sm, Geom::Coord const d) : Snapp
void Inkscape::LineSnapper::freeSnap(SnappedConstraints &sc,
Inkscape::SnapPreferences::PointType const &t,
Geom::Point const &p,
+ SnapSourceType const &source_type,
bool const &/*f*/,
Geom::OptRect const &/*bbox_to_snap*/,
std::vector<SPItem const *> const */*it*/,
- std::vector<Geom::Point> */*unselected_nodes*/) const
+ std::vector<std::pair<Geom::Point, int> > */*unselected_nodes*/) const
{
if (!(_snap_enabled && _snapmanager->snapprefs.getSnapFrom(t)) ) {
return;
Geom::Coord const dist = Geom::L2(p_proj - p);
//Store any line that's within snapping range
if (dist < getSnapperTolerance()) {
- _addSnappedLine(sc, p_proj, dist, i->first, i->second);
+ _addSnappedLine(sc, p_proj, dist, source_type, Inkscape::SNAPTARGET_UNDEFINED, i->first, i->second);
+ // We don't know if we're snapping to grids or guides here; therefore the snap target type will be set in findBestSnap()
// std::cout << " -> distance = " << dist;
}
// std::cout << std::endl;
void Inkscape::LineSnapper::constrainedSnap(SnappedConstraints &sc,
Inkscape::SnapPreferences::PointType const &t,
Geom::Point const &p,
+ SnapSourceType const &source_type,
bool const &/*f*/,
Geom::OptRect const &/*bbox_to_snap*/,
ConstraintLine const &c,
// This snappoint is therefore fully constrained, so there's no need
// to look for additional intersections; just return the snapped point
// and forget about the line
- sc.points.push_back(SnappedPoint(t, Inkscape::SNAPTARGET_UNDEFINED, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true));
- // The type of the snap target is yet undefined, as we cannot tell whether
- // we're snapping to grid or the guide lines; must be set by on a higher level
+ sc.points.push_back(SnappedPoint(t, source_type, Inkscape::SNAPTARGET_UNDEFINED, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true));
}
}
}
diff --git a/src/line-snapper.h b/src/line-snapper.h
index 91e8ca596d8e2d2188d0b36c795c603eb19fad0b..3a7ed6aae23b59331858b494b950e51bfc4531d9 100644 (file)
--- a/src/line-snapper.h
+++ b/src/line-snapper.h
void freeSnap(SnappedConstraints &sc,
Inkscape::SnapPreferences::PointType const &t,
Geom::Point const &p,
+ SnapSourceType const &source_type,
bool const &first_point,
Geom::OptRect const &bbox_to_snap,
std::vector<SPItem const *> const *it,
- std::vector<Geom::Point> *unselected_nodes) const;
+ std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const;
void constrainedSnap(SnappedConstraints &sc,
Inkscape::SnapPreferences::PointType const &t,
Geom::Point const &p,
+ SnapSourceType const &source_type,
bool const &first_point,
Geom::OptRect const &bbox_to_snap,
ConstraintLine const &c,
*/
virtual LineList _getSnapLines(Geom::Point const &p) const = 0;
- virtual void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, Geom::Point const normal_to_line, Geom::Point const point_on_line) const = 0;
+ virtual void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Point const normal_to_line, Geom::Point const point_on_line) const = 0;
};
}
diff --git a/src/nodepath.cpp b/src/nodepath.cpp
index cc38acbe5183210d5bb599b2a182625523b6ddcc..845d47b3b23d781166dbeab68ac56bd36ca94d67 100644 (file)
--- a/src/nodepath.cpp
+++ b/src/nodepath.cpp
@@ -1350,13 +1350,13 @@ static void sp_nodepath_selected_nodes_move(Inkscape::NodePath::Path *nodepath,
* must provide that information. */
// Build a list of the unselected nodes to which the snapper should snap
- std::vector<Geom::Point> unselected_nodes;
+ std::vector<std::pair<Geom::Point, int> > unselected_nodes;
for (GList *spl = nodepath->subpaths; spl != NULL; spl = spl->next) {
Inkscape::NodePath::SubPath *subpath = (Inkscape::NodePath::SubPath *) spl->data;
for (GList *nl = subpath->nodes; nl != NULL; nl = nl->next) {
Inkscape::NodePath::Node *node = (Inkscape::NodePath::Node *) nl->data;
if (!node->selected) {
- unselected_nodes.push_back(to_2geom(node->pos));
+ unselected_nodes.push_back(std::make_pair(to_2geom(node->pos), node->type == Inkscape::NodePath::NODE_SMOOTH ? Inkscape::SNAPTARGET_NODE_SMOOTH : Inkscape::SNAPTARGET_NODE_CUSP));
}
}
}
@@ -1388,12 +1388,13 @@ static void sp_nodepath_selected_nodes_move(Inkscape::NodePath::Path *nodepath,
Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data;
if (!closest_only || n == closest_node) { //try to snap either all selected nodes or only the closest one
Inkscape::SnappedPoint s;
+ Inkscape::SnapSourceType source_type = (n->type == Inkscape::NodePath::NODE_SMOOTH ? Inkscape::SNAPSOURCE_NODE_SMOOTH : Inkscape::SNAPSOURCE_NODE_CUSP);
if (constrained) {
Inkscape::Snapper::ConstraintLine dedicated_constraint = constraint;
dedicated_constraint.setPoint(n->pos);
- s = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(n->pos + delta), dedicated_constraint);
+ s = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(n->pos + delta), source_type, dedicated_constraint);
} else {
- s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(n->pos + delta));
+ s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(n->pos + delta), source_type);
}
if (s.getSnapped()) {
@@ -3945,6 +3946,7 @@ static gboolean node_handle_request(SPKnot *knot, Geom::Point &p, guint state, g
}
Inkscape::NodePath::Node *othernode = opposite->other;
+ Inkscape::SnapSourceType source_type = (n->type == Inkscape::NodePath::NODE_SMOOTH ? Inkscape::SNAPSOURCE_NODE_SMOOTH : Inkscape::SNAPSOURCE_NODE_CUSP);
if (othernode) {
if ((n->type != Inkscape::NodePath::NODE_CUSP) && sp_node_side_is_line(n, opposite)) {
/* We are smooth node adjacent with line */
@@ -3958,16 +3960,16 @@ static gboolean node_handle_request(SPKnot *knot, Geom::Point &p, guint state, g
p = n->pos + (scal / linelen) * ndelta;
}
if ((state & GDK_SHIFT_MASK) == 0) {
- s = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::Snapper::ConstraintLine(p, ndelta));
+ s = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, source_type, Inkscape::Snapper::ConstraintLine(p, ndelta));
}
} else {
if ((state & GDK_SHIFT_MASK) == 0) {
- s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p);
+ s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, source_type);
}
}
} else {
if ((state & GDK_SHIFT_MASK) == 0) {
- s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p);
+ s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, source_type);
}
}
diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp
index 515008964e2864432beda0c36ceb10edce3f9ea1..e2ca05408700299b1520009acb32d864bc7aa009 100644 (file)
--- a/src/object-snapper.cpp
+++ b/src/object-snapper.cpp
: Snapper(sm, d)
{
_candidates = new std::vector<SnapCandidate>;
- _points_to_snap_to = new std::vector<Geom::Point>;
+ _points_to_snap_to = new std::vector<std::pair<Geom::Point, int> >;
_paths_to_snap_to = new std::vector<std::pair<Geom::PathVector*, SnapTargetType> >;
}
@@ -196,7 +196,7 @@ void Inkscape::ObjectSnapper::_collectNodes(Inkscape::SnapPreferences::PointType
SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX;
}
- // Consider the page border for snapping
+ // Consider the page border for snapping to
if (_snapmanager->snapprefs.getSnapToPageBorder()) {
_getBorderNodes(_points_to_snap_to);
}
@@ -235,7 +235,7 @@ void Inkscape::ObjectSnapper::_collectNodes(Inkscape::SnapPreferences::PointType
_snapmanager->snapprefs.setSnapIntersectionCS(false);
}
- sp_item_snappoints(root_item, SnapPointsIter(*_points_to_snap_to), &_snapmanager->snapprefs);
+ sp_item_snappoints(root_item, true, *_points_to_snap_to, &_snapmanager->snapprefs);
if (_snapmanager->snapprefs.getSnapToItemPath()) {
_snapmanager->snapprefs.setSnapIntersectionCS(old_pref);
@@ -248,7 +248,7 @@ void Inkscape::ObjectSnapper::_collectNodes(Inkscape::SnapPreferences::PointType
// of the item AND the bbox of the clipping path at the same time
if (!(*i).clip_or_mask) {
Geom::OptRect b = sp_item_bbox_desktop(root_item, bbox_type);
- getBBoxPoints(b, _points_to_snap_to, _snapmanager->snapprefs.getSnapToBBoxNode(), _snapmanager->snapprefs.getSnapBBoxEdgeMidpoints(), _snapmanager->snapprefs.getSnapBBoxMidpoints());
+ getBBoxPoints(b, _points_to_snap_to, true, _snapmanager->snapprefs.getSnapToBBoxNode(), _snapmanager->snapprefs.getSnapBBoxEdgeMidpoints(), _snapmanager->snapprefs.getSnapBBoxMidpoints());
}
}
}
@@ -258,8 +258,9 @@ void Inkscape::ObjectSnapper::_collectNodes(Inkscape::SnapPreferences::PointType
void Inkscape::ObjectSnapper::_snapNodes(SnappedConstraints &sc,
Inkscape::SnapPreferences::PointType const &t,
Geom::Point const &p,
+ SnapSourceType const &source_type,
bool const &first_point,
- std::vector<Geom::Point> *unselected_nodes) const
+ std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const
{
// Iterate through all nodes, find out which one is the closest to p, and snap to it!
SnappedPoint s;
bool success = false;
- for (std::vector<Geom::Point>::const_iterator k = _points_to_snap_to->begin(); k != _points_to_snap_to->end(); k++) {
- Geom::Coord dist = Geom::L2(*k - p);
+ for (std::vector<std::pair<Geom::Point, int> >::const_iterator k = _points_to_snap_to->begin(); k != _points_to_snap_to->end(); k++) {
+ Geom::Coord dist = Geom::L2((*k).first - p);
if (dist < getSnapperTolerance() && dist < s.getSnapDistance()) {
- s = SnappedPoint(*k, SNAPTARGET_NODE, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true);
+ s = SnappedPoint((*k).first, source_type, static_cast<Inkscape::SnapTargetType>((*k).second), dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true);
success = true;
}
}
@@ -298,13 +299,13 @@ void Inkscape::ObjectSnapper::_snapTranslatingGuideToNodes(SnappedConstraints &s
Geom::Coord tol = getSnapperTolerance();
- for (std::vector<Geom::Point>::const_iterator k = _points_to_snap_to->begin(); k != _points_to_snap_to->end(); k++) {
+ for (std::vector<std::pair<Geom::Point, int> >::const_iterator k = _points_to_snap_to->begin(); k != _points_to_snap_to->end(); k++) {
// Project each node (*k) on the guide line (running through point p)
- Geom::Point p_proj = project_on_linesegment(*k, p, p + Geom::rot90(guide_normal));
- Geom::Coord dist = Geom::L2(*k - p_proj); // distance from node to the guide
+ Geom::Point p_proj = project_on_linesegment((*k).first, p, p + Geom::rot90(guide_normal));
+ Geom::Coord dist = Geom::L2((*k).first - p_proj); // distance from node to the guide
Geom::Coord dist2 = Geom::L2(p - p_proj); // distance from projection of node on the guide, to the mouse location
if ((dist < tol && dist2 < tol) || (getSnapperAlwaysSnap() && dist < s.getSnapDistance())) {
- s = SnappedPoint(*k, SNAPTARGET_NODE, dist, tol, getSnapperAlwaysSnap(), true);
+ s = SnappedPoint((*k).first, SNAPSOURCE_GUIDE, static_cast<Inkscape::SnapTargetType>((*k).second), dist, tol, getSnapperAlwaysSnap(), true);
success = true;
}
}
@@ -344,7 +345,7 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType
if (_snapmanager->snapprefs.getSnapToPageBorder()) {
Geom::PathVector *border_path = _getBorderPathv();
if (border_path != NULL) {
- _paths_to_snap_to->push_back(std::make_pair<Geom::PathVector*, SnapTargetType>(border_path, SNAPTARGET_PAGE_BORDER));
+ _paths_to_snap_to->push_back(std::make_pair(border_path, SNAPTARGET_PAGE_BORDER));
}
}
@@ -392,7 +393,7 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType
if (curve) {
// We will get our own copy of the path, which must be freed at some point
Geom::PathVector *borderpathv = pathvector_for_curve(root_item, curve, true, true, Geom::identity(), (*i).additional_affine);
- _paths_to_snap_to->push_back(std::make_pair<Geom::PathVector*, SnapTargetType>(borderpathv, SNAPTARGET_PATH)); // Perhaps for speed, get a reference to the Geom::pathvector, and store the transformation besides it.
+ _paths_to_snap_to->push_back(std::make_pair(borderpathv, SNAPTARGET_PATH)); // Perhaps for speed, get a reference to the Geom::pathvector, and store the transformation besides it.
curve->unref();
}
}
@@ -409,7 +410,7 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType
sp_item_invoke_bbox(root_item, rect, i2doc, TRUE, bbox_type);
if (rect) {
Geom::PathVector *path = _getPathvFromRect(*rect);
- _paths_to_snap_to->push_back(std::make_pair<Geom::PathVector*, SnapTargetType>(path, SNAPTARGET_BBOX_EDGE));
+ _paths_to_snap_to->push_back(std::make_pair(path, SNAPTARGET_BBOX_EDGE));
}
}
}
@@ -421,8 +422,9 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType
void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc,
Inkscape::SnapPreferences::PointType const &t,
Geom::Point const &p,
+ SnapSourceType const &source_type,
bool const &first_point,
- std::vector<Geom::Point> *unselected_nodes,
+ std::vector<std::pair<Geom::Point, int> > *unselected_nodes,
SPPath const *selected_path) const
{
_collectPaths(t, first_point);
SPCurve *curve = curve_for_item(SP_ITEM(selected_path));
if (curve) {
Geom::PathVector *pathv = pathvector_for_curve(SP_ITEM(selected_path), curve, true, true, Geom::identity(), Geom::identity()); // We will get our own copy of the path, which must be freed at some point
- _paths_to_snap_to->push_back(std::make_pair<Geom::PathVector*, SnapTargetType>(pathv, SNAPTARGET_PATH));
+ _paths_to_snap_to->push_back(std::make_pair(pathv, SNAPTARGET_PATH));
curve->unref();
}
}
if (!being_edited || (c1 && c2)) {
Geom::Coord const dist = Geom::distance(sp_doc, p_doc);
if (dist < getSnapperTolerance()) {
- sc.curves.push_back(Inkscape::SnappedCurve(sp_dt, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), false, curve, it_p->second));
+ sc.curves.push_back(Inkscape::SnappedCurve(sp_dt, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), false, curve, source_type, it_p->second));
}
}
}
}
/* Returns true if point is coincident with one of the unselected nodes */
-bool Inkscape::ObjectSnapper::isUnselectedNode(Geom::Point const &point, std::vector<Geom::Point> const *unselected_nodes) const
+bool Inkscape::ObjectSnapper::isUnselectedNode(Geom::Point const &point, std::vector<std::pair<Geom::Point, int> > const *unselected_nodes) const
{
if (unselected_nodes == NULL) {
return false;
@@ -515,8 +517,8 @@ bool Inkscape::ObjectSnapper::isUnselectedNode(Geom::Point const &point, std::ve
return false;
}
- for (std::vector<Geom::Point>::const_iterator i = unselected_nodes->begin(); i != unselected_nodes->end(); i++) {
- if (Geom::L2(point - *i) < 1e-4) {
+ for (std::vector<std::pair<Geom::Point, int> >::const_iterator i = unselected_nodes->begin(); i != unselected_nodes->end(); i++) {
+ if (Geom::L2(point - (*i).first) < 1e-4) {
return true;
}
}
@@ -527,6 +529,7 @@ bool Inkscape::ObjectSnapper::isUnselectedNode(Geom::Point const &point, std::ve
void Inkscape::ObjectSnapper::_snapPathsConstrained(SnappedConstraints &sc,
Inkscape::SnapPreferences::PointType const &t,
Geom::Point const &p,
+ SnapSourceType const source_type,
bool const &first_point,
ConstraintLine const &c) const
{
// When it's within snapping range, then return it
// (within snapping range == between p_min_on_cl and p_max_on_cl == 0 < ta < 1)
Geom::Coord dist = Geom::L2(_snapmanager->getDesktop()->dt2doc(p_proj_on_cl) - p_inters);
- SnappedPoint s(_snapmanager->getDesktop()->doc2dt(p_inters), k->second, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true);
+ SnappedPoint s(_snapmanager->getDesktop()->doc2dt(p_inters), source_type, k->second, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true);
sc.points.push_back(s);
}
}
void Inkscape::ObjectSnapper::freeSnap(SnappedConstraints &sc,
Inkscape::SnapPreferences::PointType const &t,
Geom::Point const &p,
+ SnapSourceType const &source_type,
bool const &first_point,
Geom::OptRect const &bbox_to_snap,
std::vector<SPItem const *> const *it,
- std::vector<Geom::Point> *unselected_nodes) const
+ std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const
{
if (_snap_enabled == false || _snapmanager->snapprefs.getSnapFrom(t) == false ) {
return;
|| _snapmanager->snapprefs.getSnapLineMidpoints() || _snapmanager->snapprefs.getSnapObjectMidpoints()
|| _snapmanager->snapprefs.getSnapBBoxEdgeMidpoints() || _snapmanager->snapprefs.getSnapBBoxMidpoints()
|| _snapmanager->snapprefs.getIncludeItemCenter()) {
- _snapNodes(sc, t, p, first_point, unselected_nodes);
+ _snapNodes(sc, t, p, source_type, first_point, unselected_nodes);
}
if (_snapmanager->snapprefs.getSnapToItemPath() || _snapmanager->snapprefs.getSnapToBBoxPath() || _snapmanager->snapprefs.getSnapToPageBorder()) {
g_assert(it->size() == 1);
path = SP_PATH(*it->begin());
}
- _snapPaths(sc, t, p, first_point, unselected_nodes, path);
+ _snapPaths(sc, t, p, source_type, first_point, unselected_nodes, path);
} else {
- _snapPaths(sc, t, p, first_point, NULL, NULL);
+ _snapPaths(sc, t, p, source_type, first_point, NULL, NULL);
}
}
}
void Inkscape::ObjectSnapper::constrainedSnap( SnappedConstraints &sc,
Inkscape::SnapPreferences::PointType const &t,
Geom::Point const &p,
+ SnapSourceType const &source_type,
bool const &first_point,
Geom::OptRect const &bbox_to_snap,
ConstraintLine const &c,
}
// A constrained snap, is a snap in only one degree of freedom (specified by the constraint line).
- // This is usefull for example when scaling an object while maintaining a fixed aspect ratio. It's
+ // This is useful for example when scaling an object while maintaining a fixed aspect ratio. It's
// nodes are only allowed to move in one direction (i.e. in one degree of freedom).
// When snapping to objects, we either snap to their nodes or their paths. It is however very
// so we will more or less snap to them anyhow.
if (_snapmanager->snapprefs.getSnapToItemPath() || _snapmanager->snapprefs.getSnapToBBoxPath() || _snapmanager->snapprefs.getSnapToPageBorder()) {
- _snapPathsConstrained(sc, t, p, first_point, c);
+ _snapPathsConstrained(sc, t, p, source_type, first_point, c);
}
}
@@ -743,31 +748,31 @@ Geom::PathVector* Inkscape::ObjectSnapper::_getPathvFromRect(Geom::Rect const re
}
}
-void Inkscape::ObjectSnapper::_getBorderNodes(std::vector<Geom::Point> *points) const
+void Inkscape::ObjectSnapper::_getBorderNodes(std::vector<std::pair<Geom::Point, int> > *points) const
{
Geom::Coord w = sp_document_width(_snapmanager->getDocument());
Geom::Coord h = sp_document_height(_snapmanager->getDocument());
- points->push_back(Geom::Point(0,0));
- points->push_back(Geom::Point(0,h));
- points->push_back(Geom::Point(w,h));
- points->push_back(Geom::Point(w,0));
+ points->push_back(std::make_pair(Geom::Point(0,0), SNAPTARGET_PAGE_CORNER));
+ points->push_back(std::make_pair(Geom::Point(0,h), SNAPTARGET_PAGE_CORNER));
+ points->push_back(std::make_pair(Geom::Point(w,h), SNAPTARGET_PAGE_CORNER));
+ points->push_back(std::make_pair(Geom::Point(w,0), SNAPTARGET_PAGE_CORNER));
}
-void Inkscape::getBBoxPoints(Geom::OptRect const bbox, std::vector<Geom::Point> *points, bool const includeCorners, bool const includeLineMidpoints, bool const includeObjectMidpoints)
+void Inkscape::getBBoxPoints(Geom::OptRect const bbox, std::vector<std::pair<Geom::Point, int> > *points, bool const isTarget, bool const includeCorners, bool const includeLineMidpoints, bool const includeObjectMidpoints)
{
if (bbox) {
// collect the corners of the bounding box
for ( unsigned k = 0 ; k < 4 ; k++ ) {
if (includeCorners) {
- points->push_back(bbox->corner(k));
+ points->push_back(std::make_pair((bbox->corner(k)), isTarget ? int(Inkscape::SNAPTARGET_BBOX_CORNER) : int(Inkscape::SNAPSOURCE_BBOX_CORNER)));
}
// optionally, collect the midpoints of the bounding box's edges too
if (includeLineMidpoints) {
- points->push_back((bbox->corner(k) + bbox->corner((k+1) % 4))/2);
+ points->push_back(std::make_pair((bbox->corner(k) + bbox->corner((k+1) % 4))/2, isTarget ? int(Inkscape::SNAPTARGET_BBOX_EDGE_MIDPOINT) : int(Inkscape::SNAPSOURCE_BBOX_EDGE_MIDPOINT)));
}
}
if (includeObjectMidpoints) {
- points->push_back(bbox->midpoint());
+ points->push_back(std::make_pair(bbox->midpoint(), isTarget ? int(Inkscape::SNAPTARGET_BBOX_MIDPOINT) : int(Inkscape::SNAPSOURCE_BBOX_MIDPOINT)));
}
}
}
diff --git a/src/object-snapper.h b/src/object-snapper.h
index 9a6978d4705e5c305d2b8f99ea4e1aeabaae7217..f220106e389a73fc97a409322db5aaf6c834e908 100644 (file)
--- a/src/object-snapper.h
+++ b/src/object-snapper.h
void freeSnap(SnappedConstraints &sc,
Inkscape::SnapPreferences::PointType const &t,
Geom::Point const &p,
+ SnapSourceType const &source_type,
bool const &first_point,
Geom::OptRect const &bbox_to_snap,
std::vector<SPItem const *> const *it,
- std::vector<Geom::Point> *unselected_nodes) const;
+ std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const;
void constrainedSnap(SnappedConstraints &sc,
Inkscape::SnapPreferences::PointType const &t,
Geom::Point const &p,
+ SnapSourceType const &source_type,
bool const &first_point,
Geom::OptRect const &bbox_to_snap,
ConstraintLine const &c,
private:
//store some lists of candidates, points and paths, so we don't have to rebuild them for each point we want to snap
std::vector<SnapCandidate> *_candidates;
- std::vector<Geom::Point> *_points_to_snap_to;
+ std::vector<std::pair<Geom::Point, int> > *_points_to_snap_to;
std::vector<std::pair<Geom::PathVector*, SnapTargetType> > *_paths_to_snap_to;
void _findCandidates(SPObject* parent,
void _snapNodes(SnappedConstraints &sc,
Inkscape::SnapPreferences::PointType const &t,
Geom::Point const &p, // in desktop coordinates
+ SnapSourceType const &source_type,
bool const &first_point,
- std::vector<Geom::Point> *unselected_nodes) const; // in desktop coordinates
+ std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const; // in desktop coordinates
void _snapTranslatingGuideToNodes(SnappedConstraints &sc,
Inkscape::SnapPreferences::PointType const &t,
void _snapPaths(SnappedConstraints &sc,
Inkscape::SnapPreferences::PointType const &t,
Geom::Point const &p, // in desktop coordinates
+ SnapSourceType const &source_type,
bool const &first_point,
- std::vector<Geom::Point> *unselected_nodes, // in desktop coordinates
+ std::vector<std::pair<Geom::Point, int> > *unselected_nodes, // in desktop coordinates
SPPath const *selected_path) const;
void _snapPathsConstrained(SnappedConstraints &sc,
Inkscape::SnapPreferences::PointType const &t,
Geom::Point const &p, // in desktop coordinates
- bool const &first_point,
+ SnapSourceType const source_type,
+ bool const &first_point,
ConstraintLine const &c) const;
- bool isUnselectedNode(Geom::Point const &point, std::vector<Geom::Point> const *unselected_nodes) const;
+ bool isUnselectedNode(Geom::Point const &point, std::vector<std::pair<Geom::Point, int> > const *unselected_nodes) const;
void _collectPaths(Inkscape::SnapPreferences::PointType const &t,
bool const &first_point) const;
void _clear_paths() const;
Geom::PathVector* _getBorderPathv() const;
Geom::PathVector* _getPathvFromRect(Geom::Rect const rect) const;
- void _getBorderNodes(std::vector<Geom::Point> *points) const;
+ void _getBorderNodes(std::vector<std::pair<Geom::Point, int> > *points) const;
}; // end of ObjectSnapper class
-void getBBoxPoints(Geom::OptRect const bbox, std::vector<Geom::Point> *points, bool const includeCorners, bool const includeLineMidpoints, bool const includeObjectMidpoints);
+void getBBoxPoints(Geom::OptRect const bbox, std::vector<std::pair<Geom::Point, int> > *points, bool const isTarget, bool const includeCorners, bool const includeLineMidpoints, bool const includeObjectMidpoints);
} // end of namespace Inkscape
diff --git a/src/pen-context.cpp b/src/pen-context.cpp
index 804c736bee91c1af5b30dbf913674810eefa6d43..7ff3de9e1de7c7a8900940a2210833890ffc76d2 100644 (file)
--- a/src/pen-context.cpp
+++ b/src/pen-context.cpp
@@ -477,7 +477,7 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const
if (!(bevent.state & GDK_SHIFT_MASK)) {
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
- m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p);
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE);
}
spdc_create_single_dot(event_context, p, "/tools/freehand/pen", bevent.state);
ret = TRUE;
diff --git a/src/pencil-context.cpp b/src/pencil-context.cpp
index de286ea5afba91416a7e11843e6ce30fe629633f..3e3a95c24922eabbfebfcc9df048cfc2077da460 100644 (file)
--- a/src/pencil-context.cpp
+++ b/src/pencil-context.cpp
@@ -259,7 +259,7 @@ pencil_handle_button_press(SPPencilContext *const pc, GdkEventButton const &beve
if (bevent.state & GDK_CONTROL_MASK) {
if (!(bevent.state & GDK_SHIFT_MASK)) {
- m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p);
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE);
}
spdc_create_single_dot(event_context, p, "/tools/freehand/pencil", bevent.state);
sp_canvas_set_snap_delay_active(desktop->canvas, false);
@@ -277,10 +277,10 @@ pencil_handle_button_press(SPPencilContext *const pc, GdkEventButton const &beve
// anchor, which is handled by the sibling branch above)
selection->clear();
desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Creating new path"));
- m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p);
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE);
} else if (selection->singleItem() && SP_IS_PATH(selection->singleItem())) {
desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Appending to selected path"));
- m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p);
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, p, Inkscape::SNAPSOURCE_HANDLE);
}
}
pc->sa = anchor;
diff --git a/src/rect-context.cpp b/src/rect-context.cpp
index c63e1dc2ab5505db9f10a90b3a58ff35f2461545..3650e05b1115d5da06d6fb4097f09802dc9dc76d 100644 (file)
--- a/src/rect-context.cpp
+++ b/src/rect-context.cpp
@@ -266,7 +266,7 @@ static gint sp_rect_context_root_handler(SPEventContext *event_context, GdkEvent
/* Snap center */
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
- m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, button_dt);
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, button_dt, Inkscape::SNAPSOURCE_HANDLE);
rc->center = from_2geom(button_dt);
sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
index 3ffebeb065a081acee6349675f0427be79cfeb45..505e18675779c6e46bf4ea2dc2add7b7308542fc 100644 (file)
#include <approx-equal.h>
void satisfied_guide_cns(SPDesktop const &desktop,
- std::vector<Geom::Point> const &snappoints,
+ SnapPointsWithType const &snappoints,
std::vector<SPGuideConstraint> &cns)
{
SPNamedView const &nv = *sp_desktop_namedview(&desktop);
for (GSList const *l = nv.guides; l != NULL; l = l->next) {
SPGuide &g = *SP_GUIDE(l->data);
for (unsigned int i = 0; i < snappoints.size(); ++i) {
- if (approx_equal( sp_guide_distance_from_pt(&g, snappoints[i]), 0) ) {
+ if (approx_equal( sp_guide_distance_from_pt(&g, snappoints[i].first), 0) ) {
cns.push_back(SPGuideConstraint(&g, i));
}
}
index 1952bef448402906bfa0eddd2002a5c1d12a3f25..99229f64c9aafc084c39d888b62ac2ecd0dc7725 100644 (file)
#include <forward.h>
#include <2geom/forward.h>
#include <vector>
+#include <sp-item.h>
+
class SPGuideConstraint;
void satisfied_guide_cns(SPDesktop const &desktop,
- std::vector<Geom::Point> const &snappoints,
+ SnapPointsWithType const &snappoints,
std::vector<SPGuideConstraint> &cns);
diff --git a/src/selection.cpp b/src/selection.cpp
index ea1c0053fa6be419f3c4178cf9e36f17d36f396c..4d92a18df77948f7de0620a8609566eb9e33075e 100644 (file)
--- a/src/selection.cpp
+++ b/src/selection.cpp
/**
* Compute the list of points in the selection that are to be considered for snapping.
*/
-std::vector<Geom::Point> Selection::getSnapPoints(SnapPreferences const *snapprefs) const {
+std::vector<std::pair<Geom::Point, int> > Selection::getSnapPoints(SnapPreferences const *snapprefs) const {
GSList const *items = const_cast<Selection *>(this)->itemList();
-
+
SnapPreferences snapprefs_dummy = *snapprefs; // create a local copy of the snapping prefs
snapprefs_dummy.setIncludeItemCenter(false); // locally disable snapping to the item center
-
- std::vector<Geom::Point> p;
+
+ std::vector<std::pair<Geom::Point, int> > p;
for (GSList const *iter = items; iter != NULL; iter = iter->next) {
SPItem *this_item = SP_ITEM(iter->data);
- sp_item_snappoints(this_item, SnapPointsIter(p), &snapprefs_dummy);
-
+ sp_item_snappoints(this_item, false, p, &snapprefs_dummy);
+
//Include the transformation origin for snapping
//For a selection or group only the overall origin is considered
if (snapprefs != NULL && snapprefs->getIncludeItemCenter()) {
- p.push_back(this_item->getCenter());
- }
+ p.push_back(std::make_pair(this_item->getCenter(), SNAPSOURCE_ROTATION_CENTER));
+ }
}
return p;
}
-std::vector<Geom::Point> Selection::getSnapPointsConvexHull(SnapPreferences const *snapprefs) const {
+std::vector<std::pair<Geom::Point, int> > Selection::getSnapPointsConvexHull(SnapPreferences const *snapprefs) const {
GSList const *items = const_cast<Selection *>(this)->itemList();
- std::vector<Geom::Point> p;
+ std::vector<std::pair<Geom::Point, int> > p;
for (GSList const *iter = items; iter != NULL; iter = iter->next) {
- sp_item_snappoints(SP_ITEM(iter->data), SnapPointsIter(p), snapprefs);
+ sp_item_snappoints(SP_ITEM(iter->data), false, p, snapprefs);
}
- std::vector<Geom::Point> pHull;
+ std::vector<std::pair<Geom::Point, int> > pHull;
if (!p.empty()) {
- std::vector<Geom::Point>::iterator i;
- Geom::RectHull cvh(p.front());
+ std::vector<std::pair<Geom::Point, int> >::iterator i;
+ Geom::RectHull cvh((p.front()).first);
for (i = p.begin(); i != p.end(); i++) {
// these are the points we get back
- cvh.add(*i);
+ cvh.add((*i).first);
}
Geom::OptRect rHull = cvh.bounds();
if (rHull) {
for ( unsigned i = 0 ; i < 4 ; ++i ) {
- pHull.push_back(rHull->corner(i));
+ pHull.push_back(std::make_pair(rHull->corner(i), SNAPSOURCE_CONVEX_HULL_CORNER));
}
}
}
diff --git a/src/selection.h b/src/selection.h
index f3ab8e1c1a07ed48954bea58d97a020dd9823af9..ecb1ef45e5399780cbe4812bf52a1bb18b6517ce 100644 (file)
--- a/src/selection.h
+++ b/src/selection.h
#include "gc-soft-ptr.h"
#include "util/list.h"
#include "sp-item.h"
+#include "snapped-point.h"
class SPItem;
class SPBox3D;
* at the given desktop. Both SPItem and SPRepr lists can be retrieved
* from the selection. Many actions operate on the selection, so it is
* widely used throughout the code.
- * It also implements its own asynchronous notification signals that
+ * It also implements its own asynchronous notification signals that
* UI elements can listen to.
*/
class Selection : public Inkscape::GC::Managed<>,
* @brief Returns the bounding rectangle of the selection
*
* \todo how is this different from bounds()?
- */
+ */
NRRect *boundsInDocument(NRRect *dest, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const;
/**
* @brief Gets the selection's snap points.
* @return Selection's snap points
*/
- std::vector<Geom::Point> getSnapPoints(SnapPreferences const *snapprefs) const;
+ std::vector<std::pair<Geom::Point, int> > getSnapPoints(SnapPreferences const *snapprefs) const;
/**
* @brief Gets the snap points of a selection that form a convex hull.
* @return Selection's convex hull points
*/
- std::vector<Geom::Point> getSnapPointsConvexHull(SnapPreferences const *snapprefs) const;
+ std::vector<std::pair<Geom::Point, int> > getSnapPointsConvexHull(SnapPreferences const *snapprefs) const;
/**
* @brief Connects a slot to be notified of selection changes
}
/**
- * @brief Connects a slot to be notified of selected
- * object modifications
+ * @brief Connects a slot to be notified of selected
+ * object modifications
*
* This method connects the given slot such that it will
* receive notifications whenever any selected item is
diff --git a/src/seltrans.cpp b/src/seltrans.cpp
index 4614adb87c9dea7f1e7111f32ff983da0f4b6441..f3ad2849c4ed802d04397b9f2cd2254b9fe98c37 100644 (file)
--- a/src/seltrans.cpp
+++ b/src/seltrans.cpp
@@ -291,7 +291,7 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s
// but as a snap source we still need some nodes though!
_snap_points.clear();
_snap_points = selection->getSnapPoints(&local_snapprefs);
- std::vector<Geom::Point> snap_points_hull = selection->getSnapPointsConvexHull(&local_snapprefs);
+ std::vector<std::pair<Geom::Point, int> > snap_points_hull = selection->getSnapPointsConvexHull(&local_snapprefs);
if (_snap_points.size() > 100) {
/* Snapping a huge number of nodes will take way too long, so limit the number of snappable nodes
An average user would rarely ever try to snap such a large number of nodes anyway, because
@@ -305,11 +305,11 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s
// any other special points
Geom::Rect snap_points_bbox;
if ( snap_points_hull.empty() == false ) {
- std::vector<Geom::Point>::iterator i = snap_points_hull.begin();
- snap_points_bbox = Geom::Rect(*i, *i);
+ std::vector<std::pair<Geom::Point, int> >::iterator i = snap_points_hull.begin();
+ snap_points_bbox = Geom::Rect((*i).first, (*i).first);
i++;
while (i != snap_points_hull.end()) {
- snap_points_bbox.expandTo(*i);
+ snap_points_bbox.expandTo((*i).first);
i++;
}
}
@@ -317,7 +317,7 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s
_bbox_points.clear();
if (_bbox) {
if (m.snapprefs.getSnapModeBBox()) {
- getBBoxPoints(_bbox, &_bbox_points, true, m.snapprefs.getSnapBBoxEdgeMidpoints(), m.snapprefs.getSnapBBoxMidpoints());
+ getBBoxPoints(_bbox, &_bbox_points, false, true, m.snapprefs.getSnapBBoxEdgeMidpoints(), m.snapprefs.getSnapBBoxMidpoints());
}
// There are two separate "opposites" (i.e. opposite w.r.t. the handle being dragged):
// - one for snapping the boundingbox, which can be either visual or geometric
@@ -350,7 +350,7 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s
g_assert(_bbox_points.size() < 2 && _snap_points.size() < 2);
if (_snap_points.size() == 1 && _bbox_points.size() == 1) { //both vectors can only have either one or zero elements
// So we have exactly one bbox corner and one node left; now find out which is closest and delete the other one
- if (Geom::L2(_snap_points.at(0) - p) < Geom::L2(_bbox_points.at(0) - p)) {
+ if (Geom::L2((_snap_points.at(0)).first - p) < Geom::L2((_bbox_points.at(0)).first - p)) {
_bbox_points.clear();
} else {
_snap_points.clear();
@@ -370,20 +370,6 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s
sp_canvas_set_snap_delay_active(_desktop->canvas, true);
- // The lines below are useful for debugging any snapping issues, as they'll spit out all points that are considered for snapping
-
- /*std::cout << "Number of snap points: " << _snap_points.size() << std::endl;
- for (std::vector<Geom::Point>::const_iterator i = _snap_points.begin(); i != _snap_points.end(); i++)
- {
- std::cout << " " << *i << std::endl;
- }
-
- std::cout << "Number of bbox points: " << _bbox_points.size() << std::endl;
- for (std::vector<Geom::Point>::const_iterator i = _bbox_points.begin(); i != _bbox_points.end(); i++)
- {
- std::cout << " " << *i << std::endl;
- }*/
-
if ((x != -1) && (y != -1)) {
sp_canvas_item_show(_norm);
sp_canvas_item_show(_grip);
return TRUE;
}
+// Move the item's transformation center
gboolean Inkscape::SelTrans::centerRequest(Geom::Point &pt, guint state)
{
SnapManager &m = _desktop->namedview->snap_manager;
m.setup(_desktop);
- m.freeSnapReturnByRef(SnapPreferences::SNAPPOINT_NODE, pt);
+ m.freeSnapReturnByRef(SnapPreferences::SNAPPOINT_NODE, pt, Inkscape::SNAPSOURCE_HANDLE);
if (state & GDK_CONTROL_MASK) {
if ( fabs(_point[Geom::X] - pt[Geom::X]) > fabs(_point[Geom::Y] - pt[Geom::Y]) ) {
*/
m.setup(_desktop, true, _items_const);
- m.freeSnapReturnByRef(SnapPreferences::SNAPPOINT_NODE, dxy);
+ m.freeSnapReturnByRef(SnapPreferences::SNAPPOINT_NODE, dxy, Inkscape::SNAPSOURCE_UNDEFINED);
} else if (!shift) {
@@ -1593,15 +1580,15 @@ Geom::Point Inkscape::SelTrans::_calcAbsAffineGeom(Geom::Scale const geom_scale)
return visual_bbox.min() + visual_bbox.dimensions() * Geom::Scale(_handle_x, _handle_y);
}
-void Inkscape::SelTrans::_keepClosestPointOnly(std::vector<Geom::Point> &points, const Geom::Point &reference)
+void Inkscape::SelTrans::_keepClosestPointOnly(std::vector<std::pair<Geom::Point, int> > &points, const Geom::Point &reference)
{
if (points.size() < 2) return;
- Geom::Point closest_point = Geom::Point(NR_HUGE, NR_HUGE);
+ std::pair<Geom::Point, int> closest_point = std::make_pair(Geom::Point(NR_HUGE, NR_HUGE), SNAPSOURCE_UNDEFINED);
Geom::Coord closest_dist = NR_HUGE;
- for(std::vector<Geom::Point>::const_iterator i = points.begin(); i != points.end(); i++) {
- Geom::Coord dist = Geom::L2(*i - reference);
+ for(std::vector<std::pair<Geom::Point, int> >::const_iterator i = points.begin(); i != points.end(); i++) {
+ Geom::Coord dist = Geom::L2((*i).first - reference);
if (i == points.begin() || dist < closest_dist) {
closest_point = *i;
closest_dist = dist;
diff --git a/src/seltrans.h b/src/seltrans.h
index 42effff7c03dfb4e2eff255362ba5bb44884fe5a..4f47d8e2072d7311f537adbe6b787845ee29d881 100644 (file)
--- a/src/seltrans.h
+++ b/src/seltrans.h
return _empty;
}
bool isGrabbed() {
- return _grabbed;
+ return _grabbed;
}
bool centerIsVisible() {
return ( _chandle && SP_KNOT_IS_VISIBLE (_chandle) );
Geom::Point _getGeomHandlePos(Geom::Point const &visual_handle_pos);
Geom::Point _calcAbsAffineDefault(Geom::Scale const default_scale);
Geom::Point _calcAbsAffineGeom(Geom::Scale const geom_scale);
- void _keepClosestPointOnly(std::vector<Geom::Point> &points, const Geom::Point &reference);
+ void _keepClosestPointOnly(std::vector<std::pair<Geom::Point, int> > &points, const Geom::Point &reference);
void _display_snapsource();
enum State {
STATE_SCALE, //scale or stretch
STATE_ROTATE //rotate or skew
};
-
+
SPDesktop *_desktop;
std::vector<SPItem *> _items;
std::vector<SPItem const *> _items_const;
std::vector<Geom::Matrix> _items_affines;
std::vector<Geom::Point> _items_centers;
-
- std::vector<Geom::Point> _snap_points;
- std::vector<Geom::Point> _bbox_points;
-
+
+ std::vector<std::pair<Geom::Point, int> > _snap_points;
+ std::vector<std::pair<Geom::Point, int> > _bbox_points;
+
Inkscape::SelCue _selcue;
Inkscape::Selection *_selection;
bool _changed;
SPItem::BBoxType _snap_bbox_type;
-
+
Geom::OptRect _bbox;
Geom::OptRect _approximate_bbox;
Geom::OptRect _geometric_bbox;
gdouble _strokewidth;
-
+
Geom::Matrix _current_relative_affine;
Geom::Matrix _absolute_affine;
Geom::Matrix _relative_affine;
* lines into straight lines and parallel lines into parallel lines but may alter distance between points
* and angles between lines <affine geometry>
*/
-
- Geom::Point _opposite; ///< opposite point to where a scale is taking place
+
+ Geom::Point _opposite; ///< opposite point to where a scale is taking place
Geom::Point _opposite_for_specpoints;
Geom::Point _opposite_for_bboxpoints;
Geom::Point _origin_for_specpoints;
diff --git a/src/snap.cpp b/src/snap.cpp
index 548741455704b51b510b052b2d9df4a608d0dd9f..a170046c23c4a70232e82819e25f3d03d6e4affc 100644 (file)
--- a/src/snap.cpp
+++ b/src/snap.cpp
*/
void SnapManager::freeSnapReturnByRef(Inkscape::SnapPreferences::PointType point_type,
- Geom::Point &p,
- bool first_point,
+ Geom::Point &p,
+ Inkscape::SnapSourceType const source_type,
+ bool first_point,
Geom::OptRect const &bbox_to_snap) const
{
- Inkscape::SnappedPoint const s = freeSnap(point_type, p, first_point, bbox_to_snap);
+ Inkscape::SnappedPoint const s = freeSnap(point_type, p, source_type, first_point, bbox_to_snap);
s.getPoint(p);
}
+
/**
* Try to snap a point to any of the specified snappers.
*
@@ -157,8 +159,9 @@ void SnapManager::freeSnapReturnByRef(Inkscape::SnapPreferences::PointType point
*/
Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::SnapPreferences::PointType point_type,
- Geom::Point const &p,
- bool first_point,
+ Geom::Point const &p,
+ Inkscape::SnapSourceType const &source_type,
+ bool first_point,
Geom::OptRect const &bbox_to_snap) const
{
if (_desktop->canvas->context_snap_delay_active == false) {
@@ -167,7 +170,7 @@ Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::SnapPreferences::PointTyp
}
if (!someSnapperMightSnap()) {
- return Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
+ return Inkscape::SnappedPoint(p, source_type, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
}
std::vector<SPItem const *> *items_to_ignore;
@@ -184,14 +187,14 @@ Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::SnapPreferences::PointTyp
SnapperList const snappers = getSnappers();
for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) {
- (*i)->freeSnap(sc, point_type, p, first_point, bbox_to_snap, items_to_ignore, _unselected_nodes);
+ (*i)->freeSnap(sc, point_type, p, source_type, first_point, bbox_to_snap, items_to_ignore, _unselected_nodes);
}
if (_item_to_ignore) {
delete items_to_ignore;
}
- return findBestSnap(p, sc, false);
+ return findBestSnap(p, source_type, sc, false);
}
// When pasting, we would like to snap to the grid. Problem is that we don't know which nodes were
@@ -199,7 +202,7 @@ Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::SnapPreferences::PointTyp
// unaligned node to the grid, previously aligned nodes would become unaligned. That's undesirable.
// Instead we will make sure that the offset between the source and the copy is a multiple of the grid
// pitch. If the source was aligned, then the copy will therefore also be aligned
-// PS: Wether we really find a multiple also depends on the snapping range!
+// PS: Whether we really find a multiple also depends on the snapping range!
Geom::Point SnapManager::multipleOfGridPitch(Geom::Point const &t) const
{
if (!snapprefs.getSnapEnabledGlobally()) // No need to check for snapprefs.getSnapPostponedGlobally() here
Geom::Point const t_offset = t + grid->origin;
SnappedConstraints sc;
// Only the first three parameters are being used for grid snappers
- snapper->freeSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_NODE, t_offset, TRUE, Geom::OptRect(), NULL, NULL);
+ snapper->freeSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_NODE, t_offset, Inkscape::SNAPSOURCE_UNDEFINED, TRUE, Geom::OptRect(), NULL, NULL);
// Find the best snap for this grid, including intersections of the grid-lines
- Inkscape::SnappedPoint s = findBestSnap(t_offset, sc, false);
+ Inkscape::SnappedPoint s = findBestSnap(t_offset, Inkscape::SNAPSOURCE_UNDEFINED, sc, false);
if (s.getSnapped() && (s.getSnapDistance() < nearest_distance)) {
// use getSnapDistance() instead of getWeightedDistance() here because the pointer's position
// doesn't tell us anything about which node to snap
*/
void SnapManager::constrainedSnapReturnByRef(Inkscape::SnapPreferences::PointType point_type,
- Geom::Point &p,
+ Geom::Point &p,
+ Inkscape::SnapSourceType const source_type,
Inkscape::Snapper::ConstraintLine const &constraint,
bool first_point,
Geom::OptRect const &bbox_to_snap) const
{
- Inkscape::SnappedPoint const s = constrainedSnap(point_type, p, constraint, first_point, bbox_to_snap);
+ Inkscape::SnappedPoint const s = constrainedSnap(point_type, p, source_type, constraint, first_point, bbox_to_snap);
s.getPoint(p);
}
+
/**
* Try to snap a point to any interested snappers. A snap will only occur along
* a line described by a Inkscape::Snapper::ConstraintLine.
@@ -284,7 +289,8 @@ void SnapManager::constrainedSnapReturnByRef(Inkscape::SnapPreferences::PointTyp
*/
Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapPreferences::PointType point_type,
- Geom::Point const &p,
+ Geom::Point const &p,
+ Inkscape::SnapSourceType const &source_type,
Inkscape::Snapper::ConstraintLine const &constraint,
bool first_point,
Geom::OptRect const &bbox_to_snap) const
@@ -295,7 +301,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapPreferences::P
}
if (!someSnapperMightSnap()) {
- return Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
+ return Inkscape::SnappedPoint(p, source_type, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
}
std::vector<SPItem const *> *items_to_ignore;
@@ -311,14 +317,14 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapPreferences::P
SnappedConstraints sc;
SnapperList const snappers = getSnappers();
for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) {
- (*i)->constrainedSnap(sc, point_type, p, first_point, bbox_to_snap, constraint, items_to_ignore);
+ (*i)->constrainedSnap(sc, point_type, p, source_type, first_point, bbox_to_snap, constraint, items_to_ignore);
}
if (_item_to_ignore) {
delete items_to_ignore;
}
- return findBestSnap(p, sc, true);
+ return findBestSnap(p, source_type, sc, true);
}
void SnapManager::guideSnap(Geom::Point &p, Geom::Point const &guide_normal) const
@@ -337,7 +343,7 @@ void SnapManager::guideSnap(Geom::Point &p, Geom::Point const &guide_normal) con
SnappedConstraints sc;
object.guideSnap(sc, p, guide_normal);
- Inkscape::SnappedPoint const s = findBestSnap(p, sc, false);
+ Inkscape::SnappedPoint const s = findBestSnap(p, Inkscape::SNAPSOURCE_GUIDE, sc, false);
s.getPoint(p);
}
@@ -361,7 +367,7 @@ void SnapManager::guideSnap(Geom::Point &p, Geom::Point const &guide_normal) con
Inkscape::SnappedPoint SnapManager::_snapTransformed(
Inkscape::SnapPreferences::PointType type,
- std::vector<Geom::Point> const &points,
+ std::vector<std::pair<Geom::Point, int> > const &points,
Geom::Point const &pointer,
bool constrained,
Inkscape::Snapper::ConstraintLine const &constraint,
return Inkscape::SnappedPoint();
}
- std::vector<Geom::Point> transformed_points;
+ std::vector<std::pair<Geom::Point, int> > transformed_points;
Geom::Rect bbox;
- for (std::vector<Geom::Point>::const_iterator i = points.begin(); i != points.end(); i++) {
+ for (std::vector<std::pair<Geom::Point, int> >::const_iterator i = points.begin(); i != points.end(); i++) {
/* Work out the transformed version of this point */
Geom::Point transformed = _transformPoint(*i, transformation_type, transformation, origin, dim, uniform);
bbox.expandTo(transformed);
}
- transformed_points.push_back(transformed);
+ transformed_points.push_back(std::make_pair(transformed, (*i).second));
}
/* The current best transformation */
g_assert(best_snapped_point.getAlwaysSnap() == false); // Check initialization of snapped point
g_assert(best_snapped_point.getAtIntersection() == false);
- std::vector<Geom::Point>::const_iterator j = transformed_points.begin();
+ std::vector<std::pair<Geom::Point, int> >::const_iterator j = transformed_points.begin();
// std::cout << std::endl;
- for (std::vector<Geom::Point>::const_iterator i = points.begin(); i != points.end(); i++) {
+ for (std::vector<std::pair<Geom::Point, int> >::const_iterator i = points.begin(); i != points.end(); i++) {
/* Snap it */
Inkscape::SnappedPoint snapped_point;
Inkscape::Snapper::ConstraintLine dedicated_constraint = constraint;
- Geom::Point const b = (*i - origin); // vector to original point
+ Geom::Point const b = ((*i).first - origin); // vector to original point
if (constrained) {
if ((transformation_type == SCALE || transformation_type == STRETCH) && uniform) {
// calculate that line here
dedicated_constraint = Inkscape::Snapper::ConstraintLine(origin, b);
} else if (transformation_type == STRETCH) { // when non-uniform stretching {
- dedicated_constraint = Inkscape::Snapper::ConstraintLine((*i), component_vectors[dim]);
+ dedicated_constraint = Inkscape::Snapper::ConstraintLine((*i).first, component_vectors[dim]);
} else if (transformation_type == TRANSLATION) {
// When doing a constrained translation, all points will move in the same direction, i.e.
// either horizontally or vertically. The lines along which they move are therefore all
// parallel, but might not be colinear. Therefore we will have to set the point through
// which the constraint-line runs here, for each point individually.
- dedicated_constraint.setPoint(*i);
+ dedicated_constraint.setPoint((*i).first);
} // else: leave the original constraint, e.g. for skewing
if (transformation_type == SCALE && !uniform) {
g_warning("Non-uniform constrained scaling is not supported!");
}
- snapped_point = constrainedSnap(type, *j, dedicated_constraint, i == points.begin(), bbox);
+ snapped_point = constrainedSnap(type, (*j).first, static_cast<Inkscape::SnapSourceType>((*j).second), dedicated_constraint, i == points.begin(), bbox);
} else {
bool const c1 = fabs(b[Geom::X]) < 1e-6;
bool const c2 = fabs(b[Geom::Y]) < 1e-6;
// move in that specific direction; therefore it should only snap in that direction, otherwise
// we will get snapped points with an invalid transformation
dedicated_constraint = Inkscape::Snapper::ConstraintLine(origin, component_vectors[c1]);
- snapped_point = constrainedSnap(type, *j, dedicated_constraint, i == points.begin(), bbox);
+ snapped_point = constrainedSnap(type, (*j).first, static_cast<Inkscape::SnapSourceType>((*j).second), dedicated_constraint, i == points.begin(), bbox);
} else {
- snapped_point = freeSnap(type, *j, i == points.begin(), bbox);
+ snapped_point = freeSnap(type, (*j).first, static_cast<Inkscape::SnapSourceType>((*j).second), i == points.begin(), bbox);
}
}
// std::cout << "dist = " << snapped_point.getSnapDistance() << std::endl;
- snapped_point.setPointerDistance(Geom::L2(pointer - *i));
+ snapped_point.setPointerDistance(Geom::L2(pointer - (*i).first));
Geom::Point result;
Geom::Point scale_metric(NR_HUGE, NR_HUGE);
switch (transformation_type) {
case TRANSLATION:
- result = snapped_point.getPoint() - *i;
+ result = snapped_point.getPoint() - (*i).first;
/* Consider the case in which a box is almost aligned with a grid in both
* horizontal and vertical directions. The distance to the intersection of
* the grid lines will always be larger then the distance to a single grid
snapped_point.setSecondSnapDistance(NR_HUGE);
break;
case SKEW:
- result[0] = (snapped_point.getPoint()[dim] - (*i)[dim]) / ((*i)[1 - dim] - origin[1 - dim]); // skew factor
+ result[0] = (snapped_point.getPoint()[dim] - ((*i).first)[dim]) / (((*i).first)[1 - dim] - origin[1 - dim]); // skew factor
result[1] = transformation[1]; // scale factor
// Store the metric for this transformation as a virtual distance
snapped_point.setSnapDistance(std::abs(result[0] - transformation[0]));
*/
Inkscape::SnappedPoint SnapManager::freeSnapTranslation(Inkscape::SnapPreferences::PointType point_type,
- std::vector<Geom::Point> const &p,
+ std::vector<std::pair<Geom::Point, int> > const &p,
Geom::Point const &pointer,
Geom::Point const &tr) const
{
if (p.size() == 1) {
- _displaySnapsource(point_type, _transformPoint(p.at(0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false));
+ _displaySnapsource(point_type, std::make_pair(_transformPoint(p.at(0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false), (p.at(0)).second));
}
return _snapTransformed(point_type, p, pointer, false, Geom::Point(0,0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false);
@@ -625,13 +631,13 @@ Inkscape::SnappedPoint SnapManager::freeSnapTranslation(Inkscape::SnapPreference
*/
Inkscape::SnappedPoint SnapManager::constrainedSnapTranslation(Inkscape::SnapPreferences::PointType point_type,
- std::vector<Geom::Point> const &p,
+ std::vector<std::pair<Geom::Point, int> > const &p,
Geom::Point const &pointer,
Inkscape::Snapper::ConstraintLine const &constraint,
Geom::Point const &tr) const
{
if (p.size() == 1) {
- _displaySnapsource(point_type, _transformPoint(p.at(0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false));
+ _displaySnapsource(point_type, std::make_pair(_transformPoint(p.at(0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false), (p.at(0)).second));
}
return _snapTransformed(point_type, p, pointer, true, constraint, TRANSLATION, tr, Geom::Point(0,0), Geom::X, false);
@@ -650,13 +656,13 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapTranslation(Inkscape::SnapPre
*/
Inkscape::SnappedPoint SnapManager::freeSnapScale(Inkscape::SnapPreferences::PointType point_type,
- std::vector<Geom::Point> const &p,
+ std::vector<std::pair<Geom::Point, int> > const &p,
Geom::Point const &pointer,
Geom::Scale const &s,
Geom::Point const &o) const
{
if (p.size() == 1) {
- _displaySnapsource(point_type, _transformPoint(p.at(0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, false));
+ _displaySnapsource(point_type, std::make_pair(_transformPoint(p.at(0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, false), (p.at(0)).second));
}
return _snapTransformed(point_type, p, pointer, false, Geom::Point(0,0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, false);
@@ -676,14 +682,14 @@ Inkscape::SnappedPoint SnapManager::freeSnapScale(Inkscape::SnapPreferences::Poi
*/
Inkscape::SnappedPoint SnapManager::constrainedSnapScale(Inkscape::SnapPreferences::PointType point_type,
- std::vector<Geom::Point> const &p,
+ std::vector<std::pair<Geom::Point, int> > const &p,
Geom::Point const &pointer,
Geom::Scale const &s,
Geom::Point const &o) const
{
// When constrained scaling, only uniform scaling is supported.
if (p.size() == 1) {
- _displaySnapsource(point_type, _transformPoint(p.at(0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, true));
+ _displaySnapsource(point_type, std::make_pair(_transformPoint(p.at(0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, true), (p.at(0)).second));
}
return _snapTransformed(point_type, p, pointer, true, Geom::Point(0,0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, true);
@@ -704,7 +710,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapScale(Inkscape::SnapPreferenc
*/
Inkscape::SnappedPoint SnapManager::constrainedSnapStretch(Inkscape::SnapPreferences::PointType point_type,
- std::vector<Geom::Point> const &p,
+ std::vector<std::pair<Geom::Point, int> > const &p,
Geom::Point const &pointer,
Geom::Coord const &s,
Geom::Point const &o,
@@ -712,7 +718,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapStretch(Inkscape::SnapPrefere
bool u) const
{
if (p.size() == 1) {
- _displaySnapsource(point_type, _transformPoint(p.at(0), STRETCH, Geom::Point(s, s), o, d, u));
+ _displaySnapsource(point_type, std::make_pair(_transformPoint(p.at(0), STRETCH, Geom::Point(s, s), o, d, u), (p.at(0)).second));
}
return _snapTransformed(point_type, p, pointer, true, Geom::Point(0,0), STRETCH, Geom::Point(s, s), o, d, u);
@@ -732,7 +738,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapStretch(Inkscape::SnapPrefere
*/
Inkscape::SnappedPoint SnapManager::constrainedSnapSkew(Inkscape::SnapPreferences::PointType point_type,
- std::vector<Geom::Point> const &p,
+ std::vector<std::pair<Geom::Point, int> > const &p,
Geom::Point const &pointer,
Inkscape::Snapper::ConstraintLine const &constraint,
Geom::Point const &s,
@@ -749,13 +755,13 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapSkew(Inkscape::SnapPreference
g_assert(!(point_type & Inkscape::SnapPreferences::SNAPPOINT_BBOX));
if (p.size() == 1) {
- _displaySnapsource(point_type, _transformPoint(p.at(0), SKEW, s, o, d, false));
+ _displaySnapsource(point_type, std::make_pair(_transformPoint(p.at(0), SKEW, s, o, d, false), (p.at(0)).second));
}
return _snapTransformed(point_type, p, pointer, true, constraint, SKEW, s, o, d, false);
}
-Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, SnappedConstraints &sc, bool constrained) const
+Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, Inkscape::SnapSourceType const source_type, SnappedConstraints &sc, bool constrained) const
{
/*
@@ -786,7 +792,8 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, SnappedCo
// search for the closest snapped intersection of curves
Inkscape::SnappedPoint closestCurvesIntersection;
if (getClosestIntersectionCS(sc.curves, p, closestCurvesIntersection, _desktop->dt2doc())) {
- sp_list.push_back(closestCurvesIntersection);
+ closestCurvesIntersection.setSource(source_type);
+ sp_list.push_back(closestCurvesIntersection);
}
}
@@ -814,14 +821,16 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, SnappedCo
// search for the closest snapped intersection of grid lines
Inkscape::SnappedPoint closestGridPoint;
if (getClosestIntersectionSL(sc.grid_lines, closestGridPoint)) {
- closestGridPoint.setTarget(Inkscape::SNAPTARGET_GRID_INTERSECTION);
+ closestGridPoint.setSource(source_type);
+ closestGridPoint.setTarget(Inkscape::SNAPTARGET_GRID_INTERSECTION);
sp_list.push_back(closestGridPoint);
}
// search for the closest snapped intersection of guide lines
Inkscape::SnappedPoint closestGuidePoint;
if (getClosestIntersectionSL(sc.guide_lines, closestGuidePoint)) {
- closestGuidePoint.setTarget(Inkscape::SNAPTARGET_GUIDE_INTERSECTION);
+ closestGuidePoint.setSource(source_type);
+ closestGuidePoint.setTarget(Inkscape::SNAPTARGET_GUIDE_INTERSECTION);
sp_list.push_back(closestGuidePoint);
}
@@ -829,14 +838,15 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, SnappedCo
if (snapprefs.getSnapIntersectionGG()) {
Inkscape::SnappedPoint closestGridGuidePoint;
if (getClosestIntersectionSL(sc.grid_lines, sc.guide_lines, closestGridGuidePoint)) {
- closestGridGuidePoint.setTarget(Inkscape::SNAPTARGET_GRID_GUIDE_INTERSECTION);
+ closestGridGuidePoint.setSource(source_type);
+ closestGridGuidePoint.setTarget(Inkscape::SNAPTARGET_GRID_GUIDE_INTERSECTION);
sp_list.push_back(closestGridGuidePoint);
}
}
}
// now let's see which snapped point gets a thumbs up
- Inkscape::SnappedPoint bestSnappedPoint = Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
+ Inkscape::SnappedPoint bestSnappedPoint = Inkscape::SnappedPoint(p, Inkscape::SNAPSOURCE_UNDEFINED, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false);
// std::cout << "Finding the best snap..." << std::endl;
for (std::list<Inkscape::SnappedPoint>::const_iterator i = sp_list.begin(); i != sp_list.end(); i++) {
// first find out if this snapped point is within snapping range
@@ -864,7 +874,7 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, SnappedCo
return bestSnappedPoint;
}
-void SnapManager::setup(SPDesktop const *desktop, bool snapindicator, SPItem const *item_to_ignore, std::vector<Geom::Point> *unselected_nodes)
+void SnapManager::setup(SPDesktop const *desktop, bool snapindicator, SPItem const *item_to_ignore, std::vector<std::pair<Geom::Point, int> > *unselected_nodes)
{
g_assert(desktop != NULL);
_item_to_ignore = item_to_ignore;
@@ -874,7 +884,7 @@ void SnapManager::setup(SPDesktop const *desktop, bool snapindicator, SPItem con
_unselected_nodes = unselected_nodes;
}
-void SnapManager::setup(SPDesktop const *desktop, bool snapindicator, std::vector<SPItem const *> &items_to_ignore, std::vector<Geom::Point> *unselected_nodes)
+void SnapManager::setup(SPDesktop const *desktop, bool snapindicator, std::vector<SPItem const *> &items_to_ignore, std::vector<std::pair<Geom::Point, int> > *unselected_nodes)
{
g_assert(desktop != NULL);
_item_to_ignore = NULL;
return _named_view->document;
}
-Geom::Point SnapManager::_transformPoint(Geom::Point const &p,
+Geom::Point SnapManager::_transformPoint(std::pair<Geom::Point, int> const &p,
Transformation const transformation_type,
Geom::Point const &transformation,
Geom::Point const &origin,
Geom::Point transformed;
switch (transformation_type) {
case TRANSLATION:
- transformed = p + transformation;
+ transformed = p.first + transformation;
break;
case SCALE:
- transformed = (p - origin) * Geom::Scale(transformation[Geom::X], transformation[Geom::Y]) + origin;
+ transformed = (p.first - origin) * Geom::Scale(transformation[Geom::X], transformation[Geom::Y]) + origin;
break;
case STRETCH:
{
s[dim] = transformation[dim];
s[1 - dim] = 1;
}
- transformed = ((p - origin) * s) + origin;
+ transformed = ((p.first - origin) * s) + origin;
break;
}
case SKEW:
// Apply the skew factor
- transformed[dim] = p[dim] + transformation[0] * (p[1 - dim] - origin[1 - dim]);
+ transformed[dim] = (p.first)[dim] + transformation[0] * ((p.first)[1 - dim] - origin[1 - dim]);
// While skewing, mirroring and scaling (by integer multiples) in the opposite direction is also allowed.
// Apply that scale factor here
- transformed[1-dim] = (p - origin)[1 - dim] * transformation[1] + origin[1 - dim];
+ transformed[1-dim] = (p.first - origin)[1 - dim] * transformation[1] + origin[1 - dim];
break;
default:
g_assert_not_reached();
return transformed;
}
-void SnapManager::_displaySnapsource(Inkscape::SnapPreferences::PointType point_type, Geom::Point const &p) const {
+void SnapManager::_displaySnapsource(Inkscape::SnapPreferences::PointType point_type, std::pair<Geom::Point, int> const &p) const {
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if (prefs->getBool("/options/snapclosestonly/value")) {
diff --git a/src/snap.h b/src/snap.h
index b86ceb8b0e7f3fdc5e5351c8098013f828395e62..b6ec3a5d74d64629cb70a3a220bf55e848905e46 100644 (file)
--- a/src/snap.h
+++ b/src/snap.h
bool someSnapperMightSnap() const;
bool gridSnapperMightSnap() const;
- void setup(SPDesktop const *desktop, bool snapindicator = true, SPItem const *item_to_ignore = NULL, std::vector<Geom::Point> *unselected_nodes = NULL);
- void setup(SPDesktop const *desktop, bool snapindicator, std::vector<SPItem const *> &items_to_ignore, std::vector<Geom::Point> *unselected_nodes = NULL);
+ void setup(SPDesktop const *desktop, bool snapindicator = true, SPItem const *item_to_ignore = NULL, std::vector<std::pair<Geom::Point, int> > *unselected_nodes = NULL);
+ void setup(SPDesktop const *desktop, bool snapindicator, std::vector<SPItem const *> &items_to_ignore, std::vector<std::pair<Geom::Point, int> > *unselected_nodes = NULL);
// freeSnapReturnByRef() is preferred over freeSnap(), because it only returns a
- // point if snapping has occured (by overwriting p); otherwise p is untouched
+ // point if snapping has occurred (by overwriting p); otherwise p is untouched
void freeSnapReturnByRef(Inkscape::SnapPreferences::PointType point_type,
- Geom::Point &p,
- bool first_point = true,
- Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const;
+ Geom::Point &p,
+ Inkscape::SnapSourceType const source_type,
+ bool first_point = true,
+ Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const;
+
Inkscape::SnappedPoint freeSnap(Inkscape::SnapPreferences::PointType point_type,
- Geom::Point const &p,
- bool first_point = true,
+ Geom::Point const &p,
+ Inkscape::SnapSourceType const &source_type,
+ bool first_point = true,
Geom::OptRect const &bbox_to_snap = Geom::OptRect() ) const;
Geom::Point multipleOfGridPitch(Geom::Point const &t) const;
// constrainedSnapReturnByRef() is preferred over constrainedSnap(), because it only returns a
- // point, by overwriting p, if snapping has occured; otherwise p is untouched
+ // point, by overwriting p, if snapping has occurred; otherwise p is untouched
void constrainedSnapReturnByRef(Inkscape::SnapPreferences::PointType point_type,
- Geom::Point &p,
- Inkscape::Snapper::ConstraintLine const &constraint,
- bool first_point = true,
- Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const;
+ Geom::Point &p,
+ Inkscape::SnapSourceType const source_type,
+ Inkscape::Snapper::ConstraintLine const &constraint,
+ bool first_point = true,
+ Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const;
Inkscape::SnappedPoint constrainedSnap(Inkscape::SnapPreferences::PointType point_type,
- Geom::Point const &p,
- Inkscape::Snapper::ConstraintLine const &constraint,
+ Geom::Point const &p,
+ Inkscape::SnapSourceType const &source_type,
+ Inkscape::Snapper::ConstraintLine const &constraint,
bool first_point = true,
Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const;
void guideSnap(Geom::Point &p, Geom::Point const &guide_normal) const;
Inkscape::SnappedPoint freeSnapTranslation(Inkscape::SnapPreferences::PointType point_type,
- std::vector<Geom::Point> const &p,
+ std::vector<std::pair<Geom::Point, int> > const &p,
Geom::Point const &pointer,
Geom::Point const &tr) const;
Inkscape::SnappedPoint constrainedSnapTranslation(Inkscape::SnapPreferences::PointType point_type,
- std::vector<Geom::Point> const &p,
+ std::vector<std::pair<Geom::Point, int> > const &p,
Geom::Point const &pointer,
Inkscape::Snapper::ConstraintLine const &constraint,
Geom::Point const &tr) const;
Inkscape::SnappedPoint freeSnapScale(Inkscape::SnapPreferences::PointType point_type,
- std::vector<Geom::Point> const &p,
+ std::vector<std::pair<Geom::Point, int> > const &p,
Geom::Point const &pointer,
Geom::Scale const &s,
Geom::Point const &o) const;
Inkscape::SnappedPoint constrainedSnapScale(Inkscape::SnapPreferences::PointType point_type,
- std::vector<Geom::Point> const &p,
+ std::vector<std::pair<Geom::Point, int> > const &p,
Geom::Point const &pointer,
Geom::Scale const &s,
Geom::Point const &o) const;
Inkscape::SnappedPoint constrainedSnapStretch(Inkscape::SnapPreferences::PointType point_type,
- std::vector<Geom::Point> const &p,
+ std::vector<std::pair<Geom::Point, int> > const &p,
Geom::Point const &pointer,
Geom::Coord const &s,
Geom::Point const &o,
bool uniform) const;
Inkscape::SnappedPoint constrainedSnapSkew(Inkscape::SnapPreferences::PointType point_type,
- std::vector<Geom::Point> const &p,
+ std::vector<std::pair<Geom::Point, int> > const &p,
Geom::Point const &pointer,
Inkscape::Snapper::ConstraintLine const &constraint,
Geom::Point const &s, // s[0] = skew factor, s[1] = scale factor
SPItem const *_item_to_ignore;
SPDesktop const *_desktop;
bool _snapindicator;
- std::vector<Geom::Point> *_unselected_nodes;
+ std::vector<std::pair<Geom::Point, int> > *_unselected_nodes;
Inkscape::SnappedPoint _snapTransformed(Inkscape::SnapPreferences::PointType type,
- std::vector<Geom::Point> const &points,
+ std::vector<std::pair<Geom::Point, int> > const &points,
Geom::Point const &pointer,
bool constrained,
Inkscape::Snapper::ConstraintLine const &constraint,
Geom::Dim2 dim,
bool uniform) const;
- Geom::Point _transformPoint(Geom::Point const &p,
+ Geom::Point _transformPoint(std::pair<Geom::Point, int> const &p,
Transformation const transformation_type,
Geom::Point const &transformation,
Geom::Point const &origin,
Geom::Dim2 const dim,
bool const uniform) const;
- void _displaySnapsource(Inkscape::SnapPreferences::PointType point_type, Geom::Point const &p) const;
+ void _displaySnapsource(Inkscape::SnapPreferences::PointType point_type, std::pair<Geom::Point, int> const &p) const;
- Inkscape::SnappedPoint findBestSnap(Geom::Point const &p, SnappedConstraints &sc, bool constrained) const;
+ Inkscape::SnappedPoint findBestSnap(Geom::Point const &p, Inkscape::SnapSourceType const source_type, SnappedConstraints &sc, bool constrained) const;
};
#endif /* !SEEN_SNAP_H */
diff --git a/src/snapped-curve.cpp b/src/snapped-curve.cpp
index 34cc4dad2a15a0c45d6896bba7a0368c0174406e..e66b44401fca7d8717d61d4e0e1e3a68077e17e6 100644 (file)
--- a/src/snapped-curve.cpp
+++ b/src/snapped-curve.cpp
#include <2geom/path-intersection.h>
#include <libnr/nr-convert2geom.h>
-Inkscape::SnappedCurve::SnappedCurve(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve, SnapTargetType target)
+Inkscape::SnappedCurve::SnappedCurve(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve, SnapSourceType source, SnapTargetType target)
{
_distance = snapped_distance;
_tolerance = std::max(snapped_tolerance, 1.0);
_point = snapped_point;
_at_intersection = false;
_fully_constrained = fully_constrained;
+ _source = source;
_target = target;
}
_point = Geom::Point(0,0);
_at_intersection = false;
_fully_constrained = false;
+ _source = SNAPSOURCE_UNDEFINED;
_target = SNAPTARGET_UNDEFINED;
}
@@ -83,12 +85,12 @@ Inkscape::SnappedPoint Inkscape::SnappedCurve::intersect(SnappedCurve const &cur
// TODO: Investigate whether it is possible to use document coordinates everywhere
// in the snapper code. Only the mouse position should be in desktop coordinates, I guess.
// All paths are already in document coords and we are certainly not going to change THAT.
- return SnappedPoint(best_p, Inkscape::SNAPTARGET_PATH_INTERSECTION, primaryDist, primaryC->getTolerance(), primaryC->getAlwaysSnap(), true, true,
+ return SnappedPoint(best_p, Inkscape::SNAPSOURCE_UNDEFINED, Inkscape::SNAPTARGET_PATH_INTERSECTION, primaryDist, primaryC->getTolerance(), primaryC->getAlwaysSnap(), true, true,
secondaryDist, secondaryC->getTolerance(), secondaryC->getAlwaysSnap());
}
// No intersection
- return SnappedPoint(Geom::Point(NR_HUGE, NR_HUGE), SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false);
+ return SnappedPoint(Geom::Point(NR_HUGE, NR_HUGE), SNAPSOURCE_UNDEFINED, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false);
}
// search for the closest snapped line
diff --git a/src/snapped-curve.h b/src/snapped-curve.h
index d3dcd023813b16e4ddfaba69e953b34e65da92da..60f5fa0d98329fdad3566616425bb57df310bc4e 100644 (file)
--- a/src/snapped-curve.h
+++ b/src/snapped-curve.h
{
public:
SnappedCurve();
- SnappedCurve(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve, SnapTargetType target);
+ SnappedCurve(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve, SnapSourceType source, SnapTargetType target);
~SnappedCurve();
Inkscape::SnappedPoint intersect(SnappedCurve const &curve, Geom::Point const &p, Geom::Matrix dt2doc) const; //intersect with another SnappedCurve
diff --git a/src/snapped-line.cpp b/src/snapped-line.cpp
index 5f7d5407b5e9e8f2afdcecb77b6de4d245087380..70689367339c4e141e846fd65a1349a1ab7f89b0 100644 (file)
--- a/src/snapped-line.cpp
+++ b/src/snapped-line.cpp
#include <2geom/geom.h>
#include "libnr/nr-values.h"
-Inkscape::SnappedLineSegment::SnappedLineSegment(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &start_point_of_line, Geom::Point const &end_point_of_line)
+Inkscape::SnappedLineSegment::SnappedLineSegment(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &start_point_of_line, Geom::Point const &end_point_of_line)
: _start_point_of_line(start_point_of_line), _end_point_of_line(end_point_of_line)
{
_point = snapped_point;
+ _source = source;
+ _target = target;
_distance = snapped_distance;
_tolerance = std::max(snapped_tolerance, 1.0);
_always_snap = always_snap;
_start_point_of_line = Geom::Point(0,0);
_end_point_of_line = Geom::Point(0,0);
_point = Geom::Point(0,0);
+ _source = SNAPSOURCE_UNDEFINED;
+ _target = SNAPTARGET_UNDEFINED;
_distance = NR_HUGE;
_tolerance = 1;
_always_snap = false;
@@ -69,20 +73,22 @@ Inkscape::SnappedPoint Inkscape::SnappedLineSegment::intersect(SnappedLineSegmen
Inkscape::SnappedLineSegment const *secondarySLS = use_this_as_primary ? &line : this;
Geom::Coord primaryDist = use_this_as_primary ? Geom::L2(intersection_2geom - this->getPoint()) : Geom::L2(intersection_2geom - line.getPoint());
Geom::Coord secondaryDist = use_this_as_primary ? Geom::L2(intersection_2geom - line.getPoint()) : Geom::L2(intersection_2geom - this->getPoint());
- return SnappedPoint(intersection, SNAPTARGET_PATH_INTERSECTION, primaryDist, primarySLS->getTolerance(), primarySLS->getAlwaysSnap(), true, true,
+ return SnappedPoint(intersection, SNAPSOURCE_UNDEFINED, SNAPTARGET_PATH_INTERSECTION, primaryDist, primarySLS->getTolerance(), primarySLS->getAlwaysSnap(), true, true,
secondaryDist, secondarySLS->getTolerance(), secondarySLS->getAlwaysSnap());
}
// No intersection
- return SnappedPoint(intersection, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false);
+ return SnappedPoint(intersection, SNAPSOURCE_UNDEFINED, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false);
};
-Inkscape::SnappedLine::SnappedLine(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &normal_to_line, Geom::Point const &point_on_line)
+Inkscape::SnappedLine::SnappedLine(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &normal_to_line, Geom::Point const &point_on_line)
: _normal_to_line(normal_to_line), _point_on_line(point_on_line)
{
- _distance = snapped_distance;
+ _source = source;
+ _target = target;
+ _distance = snapped_distance;
_tolerance = std::max(snapped_tolerance, 1.0);
_always_snap = always_snap;
_second_distance = NR_HUGE;
{
_normal_to_line = Geom::Point(0,0);
_point_on_line = Geom::Point(0,0);
+ _source = SNAPSOURCE_UNDEFINED;
+ _target = SNAPTARGET_UNDEFINED;
_distance = NR_HUGE;
_tolerance = 1;
_always_snap = false;
@@ -137,14 +145,14 @@ Inkscape::SnappedPoint Inkscape::SnappedLine::intersect(SnappedLine const &line)
Inkscape::SnappedLine const *secondarySL = use_this_as_primary ? &line : this;
Geom::Coord primaryDist = use_this_as_primary ? Geom::L2(intersection_2geom - this->getPoint()) : Geom::L2(intersection_2geom - line.getPoint());
Geom::Coord secondaryDist = use_this_as_primary ? Geom::L2(intersection_2geom - line.getPoint()) : Geom::L2(intersection_2geom - this->getPoint());
- return SnappedPoint(intersection, Inkscape::SNAPTARGET_UNDEFINED, primaryDist, primarySL->getTolerance(), primarySL->getAlwaysSnap(), true, true,
+ return SnappedPoint(intersection, Inkscape::SNAPSOURCE_UNDEFINED, Inkscape::SNAPTARGET_UNDEFINED, primaryDist, primarySL->getTolerance(), primarySL->getAlwaysSnap(), true, true,
secondaryDist, secondarySL->getTolerance(), secondarySL->getAlwaysSnap());
// The type of the snap target is yet undefined, as we cannot tell whether
// we're snapping to grid or the guide lines; must be set by on a higher level
}
// No intersection
- return SnappedPoint(intersection, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false);
+ return SnappedPoint(intersection, SNAPSOURCE_UNDEFINED, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false);
}
// search for the closest snapped line segment
diff --git a/src/snapped-line.h b/src/snapped-line.h
index ea18baefc5e98201cfa22216efdcbdc84c1a579b..3d666831107f311e9367aa47e1989bed2c809fb9 100644 (file)
--- a/src/snapped-line.h
+++ b/src/snapped-line.h
{
public:
SnappedLineSegment();
- SnappedLineSegment(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &start_point_of_line, Geom::Point const &end_point_of_line);
+ SnappedLineSegment(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &snapped_tolerance,bool const &always_snap, Geom::Point const &start_point_of_line, Geom::Point const &end_point_of_line);
~SnappedLineSegment();
Inkscape::SnappedPoint intersect(SnappedLineSegment const &line) const; //intersect with another SnappedLineSegment
-
+
private:
Geom::Point _start_point_of_line;
- Geom::Point _end_point_of_line;
+ Geom::Point _end_point_of_line;
};
{
public:
SnappedLine();
- SnappedLine(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &normal_to_line, Geom::Point const &point_on_line);
+ SnappedLine(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &normal_to_line, Geom::Point const &point_on_line);
~SnappedLine();
Inkscape::SnappedPoint intersect(SnappedLine const &line) const; //intersect with another SnappedLine
// This line is described by this equation:
Geom::Point getNormal() const {return _normal_to_line;} // n = (nx, ny)
Geom::Point getPointOnLine() const {return _point_on_line;} // p = (px, py)
Geom::Coord getConstTerm() const {return dot(_normal_to_line, _point_on_line);} // c = n.p = nx*px + ny*py;
-
+
private:
Geom::Point _normal_to_line;
- Geom::Point _point_on_line;
+ Geom::Point _point_on_line;
};
}
bool getClosestSL(std::list<Inkscape::SnappedLine> const &list, Inkscape::SnappedLine &result);
bool getClosestIntersectionSL(std::list<Inkscape::SnappedLine> const &list, Inkscape::SnappedPoint &result);
bool getClosestIntersectionSL(std::list<Inkscape::SnappedLine> const &list1, std::list<Inkscape::SnappedLine> const &list2, Inkscape::SnappedPoint &result);
-
+
#endif /* !SEEN_SNAPPEDLINE_H */
diff --git a/src/snapped-point.cpp b/src/snapped-point.cpp
index 44b69050ff99a2ab7739e6599c950969380a0706..d7f13d82fa298ae6fa0d91b75a34bb7edbc4229d 100644 (file)
--- a/src/snapped-point.cpp
+++ b/src/snapped-point.cpp
#include "preferences.h"
// overloaded constructor
-Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained)
- : _point(p), _target(target), _distance(d), _tolerance(std::max(t,1.0)), _always_snap(a)
+Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained)
+ : _point(p), _source(source), _target(target), _distance(d), _tolerance(std::max(t,1.0)), _always_snap(a)
{
// tolerance should never be smaller than 1 px, as it is used for normalization in isOtherSnapBetter. We don't want a division by zero.
_at_intersection = false;
_pointer_distance = NR_HUGE;
}
-Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &at_intersection, bool const &fully_constrained, Geom::Coord const &d2, Geom::Coord const &t2, bool const &a2)
- : _point(p), _target(target), _at_intersection(at_intersection), _fully_constrained(fully_constrained), _distance(d), _tolerance(std::max(t,1.0)), _always_snap(a),
+Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &at_intersection, bool const &fully_constrained, Geom::Coord const &d2, Geom::Coord const &t2, bool const &a2)
+ : _point(p), _source(source), _target(target), _at_intersection(at_intersection), _fully_constrained(fully_constrained), _distance(d), _tolerance(std::max(t,1.0)), _always_snap(a),
_second_distance(d2), _second_tolerance(std::max(t2,1.0)), _second_always_snap(a2)
{
// tolerance should never be smaller than 1 px, as it is used for normalization in
Inkscape::SnappedPoint::SnappedPoint()
{
_point = Geom::Point(0,0);
+ _source = SNAPSOURCE_UNDEFINED,
_target = SNAPTARGET_UNDEFINED,
_at_intersection = false;
_fully_constrained = false;
diff --git a/src/snapped-point.h b/src/snapped-point.h
index 7085ccae8f6d0d09c12d5ab6dc118577ec3b242e..f8ef50ff361f873f92c44c6f2ef7986bba62a985 100644 (file)
--- a/src/snapped-point.h
+++ b/src/snapped-point.h
{
enum SnapTargetType {
- SNAPTARGET_UNDEFINED,
+ SNAPTARGET_UNDEFINED = 0,
SNAPTARGET_GRID,
SNAPTARGET_GRID_INTERSECTION,
SNAPTARGET_GUIDE,
SNAPTARGET_GUIDE_INTERSECTION,
SNAPTARGET_GRID_GUIDE_INTERSECTION,
- SNAPTARGET_NODE,
+ SNAPTARGET_NODE_SMOOTH,
+ SNAPTARGET_NODE_CUSP,
+ SNAPTARGET_LINE_MIDPOINT,
+ SNAPTARGET_OBJECT_MIDPOINT,
+ SNAPTARGET_ROTATION_CENTER,
+ SNAPTARGET_HANDLE, //e.g. center of ellipse, corner of rectangle
SNAPTARGET_PATH,
SNAPTARGET_PATH_INTERSECTION,
SNAPTARGET_BBOX_CORNER,
SNAPTARGET_BBOX_EDGE,
+ SNAPTARGET_BBOX_EDGE_MIDPOINT,
+ SNAPTARGET_BBOX_MIDPOINT,
SNAPTARGET_GRADIENT,
- SNAPTARGET_PAGE_BORDER
+ SNAPTARGET_PAGE_BORDER,
+ SNAPTARGET_PAGE_CORNER,
+ SNAPTARGET_CONVEX_HULL_CORNER,
+ SNAPTARGET_ELLIPSE_QUADRANT_POINT,
};
+enum SnapSourceType {
+ SNAPSOURCE_UNDEFINED = 0,
+ SNAPSOURCE_BBOX_CORNER,
+ SNAPSOURCE_BBOX_MIDPOINT,
+ SNAPSOURCE_BBOX_EDGE_MIDPOINT,
+ SNAPSOURCE_NODE_SMOOTH,
+ SNAPSOURCE_NODE_CUSP,
+ SNAPSOURCE_LINE_MIDPOINT,
+ SNAPSOURCE_OBJECT_MIDPOINT,
+ SNAPSOURCE_ROTATION_CENTER,
+ SNAPSOURCE_HANDLE,
+ SNAPSOURCE_PATH_INTERSECTION,
+ SNAPSOURCE_GUIDE,
+ SNAPSOURCE_CONVEX_HULL_CORNER,
+ SNAPSOURCE_ELLIPSE_QUADRANT_POINT
+};
+
+
/// Class describing the result of an attempt to snap.
class SnappedPoint
{
public:
SnappedPoint();
- SnappedPoint(Geom::Point const &p, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &at_intersection, bool const &fully_constrained, Geom::Coord const &d2, Geom::Coord const &t2, bool const &a2);
- SnappedPoint(Geom::Point const &p, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained);
+ SnappedPoint(Geom::Point const &p, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &at_intersection, bool const &fully_constrained, Geom::Coord const &d2, Geom::Coord const &t2, bool const &a2);
+ SnappedPoint(Geom::Point const &p, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained);
~SnappedPoint();
Geom::Coord getSnapDistance() const {return _distance;}
void setTransformation(Geom::Point const t) {_transformation = t;}
void setTarget(SnapTargetType const target) {_target = target;}
SnapTargetType getTarget() const {return _target;}
+ void setSource(SnapSourceType const source) {_source = source;}
+ SnapSourceType getSource() const {return _source;}
bool isOtherSnapBetter(SnappedPoint const &other_one, bool weighted) const;
/*void dump() const {
std::cout << "_point = " << _point << std::endl;
+ std::cout << "_source = " << _source << std::endl;
std::cout << "_target = " << _target << std::endl;
std::cout << "_at_intersection = " << _at_intersection << std::endl;
std::cout << "_fully_constrained = " << _fully_constrained << std::endl;
protected:
Geom::Point _point; // Location of the snapped point
+ SnapSourceType _source; // Describes what snapped
SnapTargetType _target; // Describes to what we've snapped to
bool _at_intersection; // If true, the snapped point is at an intersection
bool _fully_constrained; // When snapping for example to a node, then the snap will be "fully constrained".
diff --git a/src/snapper.h b/src/snapper.h
index 49f2774113d8062ee5afe6942e3f38d6fc8b2847..08b10e41b30676f6ca390bd57ae898cab09902e6 100644 (file)
--- a/src/snapper.h
+++ b/src/snapper.h
virtual void freeSnap(SnappedConstraints &/*sc*/,
SnapPreferences::PointType const &/*t*/,
Geom::Point const &/*p*/,
+ SnapSourceType const &/*source_type*/,
bool const &/*first_point*/,
Geom::OptRect const &/*bbox_to_snap*/,
std::vector<SPItem const *> const */*it*/,
- std::vector<Geom::Point> */*unselected_nodes*/) const {};
+ std::vector<std::pair<Geom::Point, int> > */*unselected_nodes*/) const {};
class ConstraintLine
{
virtual void constrainedSnap(SnappedConstraints &/*sc*/,
SnapPreferences::PointType const &/*t*/,
Geom::Point const &/*p*/,
+ SnapSourceType const &/*source_type*/,
bool const &/*first_point*/,
Geom::OptRect const &/*bbox_to_snap*/,
ConstraintLine const &/*c*/,
diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp
index ce1343272f9612da961c4b25c1f7ae26998521c7..97656375428a9f4eef0251254888b93cc9f322c9 100644 (file)
--- a/src/sp-ellipse.cpp
+++ b/src/sp-ellipse.cpp
static void sp_genericellipse_update(SPObject *object, SPCtx *ctx, guint flags);
-static void sp_genericellipse_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_genericellipse_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
static void sp_genericellipse_set_shape(SPShape *shape);
static void sp_genericellipse_update_patheffect (SPLPEItem *lpeitem, bool write);
curve->unref();
}
-static void sp_genericellipse_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_genericellipse_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
{
g_assert(item != NULL);
g_assert(SP_IS_GENERICELLIPSE(item));
@@ -290,31 +290,37 @@ static void sp_genericellipse_snappoints(SPItem const *item, SnapPointsIter p, I
double cx = ellipse->cx.computed;
double cy = ellipse->cy.computed;
+ Geom::Point pt;
+
// Snap to the 4 quadrant points of the ellipse, but only if the arc
// spans far enough to include them
if (snapprefs->getSnapToItemNode()) { //TODO: Make a separate snap option toggle for this?
double angle = 0;
for (angle = 0; angle < SP_2PI; angle += M_PI_2) {
if (angle >= ellipse->start && angle <= ellipse->end) {
- *p = Geom::Point(cx + cos(angle)*rx, cy + sin(angle)*ry) * i2d;
+ pt = Geom::Point(cx + cos(angle)*rx, cy + sin(angle)*ry) * i2d;
+ p.push_back(std::make_pair(pt, target ? int(Inkscape::SNAPTARGET_ELLIPSE_QUADRANT_POINT) : int(Inkscape::SNAPSOURCE_ELLIPSE_QUADRANT_POINT)));
}
}
}
// Add the centre, if we have a closed slice or when explicitly asked for
if ((snapprefs->getSnapToItemNode() && slice && ellipse->closed) || snapprefs->getSnapObjectMidpoints()) {
- *p = Geom::Point(cx, cy) * i2d;
+ pt = Geom::Point(cx, cy) * i2d;
+ p.push_back(std::make_pair(pt, target ? int(Inkscape::SNAPTARGET_HANDLE) : int(Inkscape::SNAPSOURCE_HANDLE)));
}
// And if we have a slice, also snap to the endpoints
if (snapprefs->getSnapToItemNode() && slice) {
// Add the start point, if it's not coincident with a quadrant point
if (fmod(ellipse->start, M_PI_2) != 0.0 ) {
- *p = Geom::Point(cx + cos(ellipse->start)*rx, cy + sin(ellipse->start)*ry) * i2d;
+ pt = Geom::Point(cx + cos(ellipse->start)*rx, cy + sin(ellipse->start)*ry) * i2d;
+ p.push_back(std::make_pair(pt, target ? int(Inkscape::SNAPTARGET_NODE_CUSP) : int(Inkscape::SNAPSOURCE_NODE_CUSP)));
}
// Add the end point, if it's not coincident with a quadrant point
if (fmod(ellipse->end, M_PI_2) != 0.0 ) {
- *p = Geom::Point(cx + cos(ellipse->end)*rx, cy + sin(ellipse->end)*ry) * i2d;
+ pt = Geom::Point(cx + cos(ellipse->end)*rx, cy + sin(ellipse->end)*ry) * i2d;
+ p.push_back(std::make_pair(pt, target ? int(Inkscape::SNAPTARGET_NODE_CUSP) : int(Inkscape::SNAPSOURCE_NODE_CUSP)));
}
}
}
diff --git a/src/sp-image.cpp b/src/sp-image.cpp
index 75be3bea2cb951f3c9702d69b5590ef631ebf7ad..e23dddaf629b25ff348b1ed5b37d77db0e3ead14 100644 (file)
--- a/src/sp-image.cpp
+++ b/src/sp-image.cpp
static void sp_image_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags);
static void sp_image_print (SPItem * item, SPPrintContext *ctx);
static gchar * sp_image_description (SPItem * item);
-static void sp_image_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_image_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
static NRArenaItem *sp_image_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
static Geom::Matrix sp_image_set_transform (SPItem *item, Geom::Matrix const &xform);
static void sp_image_set_curve(SPImage *image);
}
}
-static void sp_image_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const */*snapprefs*/)
+static void sp_image_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const */*snapprefs*/)
{
/* An image doesn't have any nodes to snap, but still we want to be able snap one image
to another. Therefore we will create some snappoints at the corner, similar to a rect. If
@@ -1327,10 +1327,12 @@ static void sp_image_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::
double const x1 = x0 + image.width.computed;
double const y1 = y0 + image.height.computed;
Geom::Matrix const i2d (sp_item_i2d_affine (item));
- *p = Geom::Point(x0, y0) * i2d;
- *p = Geom::Point(x0, y1) * i2d;
- *p = Geom::Point(x1, y1) * i2d;
- *p = Geom::Point(x1, y0) * i2d;
+ Geom::Point pt;
+ int type = target ? int(Inkscape::SNAPTARGET_HANDLE) : int(Inkscape::SNAPSOURCE_HANDLE);
+ p.push_back(std::make_pair(Geom::Point(x0, y0) * i2d, type));
+ p.push_back(std::make_pair(Geom::Point(x0, y1) * i2d, type));
+ p.push_back(std::make_pair(Geom::Point(x1, y1) * i2d, type));
+ p.push_back(std::make_pair(Geom::Point(x1, y0) * i2d, type));
}
}
diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp
index 862a36cb065888c7ba178fe561be9375ebf2e459..ed5382fae3cc9389ac5366984d90968442ab098b 100644 (file)
--- a/src/sp-item-group.cpp
+++ b/src/sp-item-group.cpp
static Geom::Matrix sp_group_set_transform(SPItem *item, Geom::Matrix const &xform);
static NRArenaItem *sp_group_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
static void sp_group_hide (SPItem * item, unsigned int key);
-static void sp_group_snappoints (SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_group_snappoints (SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
static void sp_group_update_patheffect(SPLPEItem *lpeitem, bool write);
static void sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup);
SP_GROUP(item)->group->hide(key);
}
-static void sp_group_snappoints (SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_group_snappoints (SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
{
for (SPObject const *o = sp_object_first_child(SP_OBJECT(item));
o != NULL;
o = SP_OBJECT_NEXT(o))
{
if (SP_IS_ITEM(o)) {
- sp_item_snappoints(SP_ITEM(o), p, snapprefs);
+ sp_item_snappoints(SP_ITEM(o), target, p, snapprefs);
}
}
}
index 5cc1692216de354f596a490c686bbe9a20a96420..0bc08a2355d84f9ad0fb5143b3b0ce8fb7ddd226 100644 (file)
@@ -24,11 +24,11 @@ void sp_item_notify_moveto(SPItem &item, SPGuide const &mv_g, int const snappoin
double const dir_lensq(dot(dir, dir));
g_return_if_fail( dir_lensq != 0 );
- std::vector<Geom::Point> snappoints;
- sp_item_snappoints(&item, SnapPointsIter(snappoints), NULL);
+ SnapPointsWithType snappoints;
+ sp_item_snappoints(&item, false, snappoints, NULL);
g_return_if_fail( snappoint_ix < int(snappoints.size()) );
- double const pos0 = dot(dir, snappoints[snappoint_ix]);
+ double const pos0 = dot(dir, snappoints[snappoint_ix].first);
/// \todo effic: skip if mv_g is already satisfied.
/* Translate along dir to make dot(dir, snappoints(item)[snappoint_ix]) == position. */
index 6d7ab2fda8937880b8e013ce5071450fcddc5c7d..2464532413d2a32cf687267fe0471d53b4df05f4 100644 (file)
if (item.constraints.empty()) {
return;
}
- std::vector<Geom::Point> snappoints;
- sp_item_snappoints(&item, SnapPointsIter(snappoints), NULL);
+ SnapPointsWithType snappoints;
+ sp_item_snappoints(&item, false, snappoints, NULL);
for (unsigned i = item.constraints.size(); i--;) {
g_assert( i < item.constraints.size() );
SPGuideConstraint const &cn = item.constraints[i];
int const snappoint_ix = cn.snappoint_ix;
g_assert( snappoint_ix < int(snappoints.size()) );
- if (!approx_equal( sp_guide_distance_from_pt(cn.g, snappoints[snappoint_ix]), 0) ) {
+ if (!approx_equal( sp_guide_distance_from_pt(cn.g, snappoints[snappoint_ix].first), 0) ) {
remove_last(cn.g->attached_items, SPGuideAttachment(&item, cn.snappoint_ix));
g_assert( i < item.constraints.size() );
vector<SPGuideConstraint>::iterator const ei(&item.constraints[i]);
index f7329bd45a2096907bba6349b653cbb92e1c734f..bebd6502199dab5b9939e014c976d9191a079875 100644 (file)
void sp_item_update_cns(SPItem &item, SPDesktop const &desktop)
{
- std::vector<Geom::Point> snappoints;
- sp_item_snappoints(&item, SnapPointsIter(snappoints), NULL);
+ SnapPointsWithType snappoints;
+ sp_item_snappoints(&item, false, snappoints, NULL);
/* TODO: Implement the ordering. */
vector<SPGuideConstraint> found_cns;
satisfied_guide_cns(desktop, snappoints, found_cns);
diff --git a/src/sp-item.cpp b/src/sp-item.cpp
index 2ac480341a4ef469a9194ed439bff6f249a517ea..996804cd3a5c4001c1df381da035fb8ce686f194 100644 (file)
--- a/src/sp-item.cpp
+++ b/src/sp-item.cpp
static Inkscape::XML::Node *sp_item_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
static gchar *sp_item_private_description(SPItem *item);
-static void sp_item_private_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_item_private_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
static SPItemView *sp_item_view_new_prepend(SPItemView *list, SPItem *item, unsigned flags, unsigned key, NRArenaItem *arenaitem);
static SPItemView *sp_item_view_list_remove(SPItemView *list, SPItemView *view);
return rect;
}
-static void sp_item_private_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const */*snapprefs*/)
+static void sp_item_private_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const */*snapprefs*/)
{
/* This will only be called if the derived class doesn't override this.
* see for example sp_genericellipse_snappoints in sp-ellipse.cpp
@@ -952,15 +952,16 @@ static void sp_item_private_snappoints(SPItem const *item, SnapPointsIter p, Ink
Geom::Point p1, p2;
p1 = bbox->min();
p2 = bbox->max();
- *p = p1;
- *p = Geom::Point(p1[Geom::X], p2[Geom::Y]);
- *p = p2;
- *p = Geom::Point(p1[Geom::Y], p2[Geom::X]);
+ int type = target ? int(Inkscape::SNAPSOURCE_CONVEX_HULL_CORNER) : int(Inkscape::SNAPSOURCE_CONVEX_HULL_CORNER);
+ p.push_back(std::make_pair(p1, type));
+ p.push_back(std::make_pair(Geom::Point(p1[Geom::X], p2[Geom::Y]), type));
+ p.push_back(std::make_pair(p2, type));
+ p.push_back(std::make_pair(Geom::Point(p1[Geom::Y], p2[Geom::X]), type));
}
}
-void sp_item_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
+void sp_item_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
{
g_assert (item != NULL);
g_assert (SP_IS_ITEM(item));
@@ -968,12 +969,12 @@ void sp_item_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPref
// Get the snappoints of the item
SPItemClass const &item_class = *(SPItemClass const *) G_OBJECT_GET_CLASS(item);
if (item_class.snappoints) {
- item_class.snappoints(item, p, snapprefs);
+ item_class.snappoints(item, target, p, snapprefs);
}
// Get the snappoints at the item's center
if (snapprefs != NULL && snapprefs->getIncludeItemCenter()) {
- *p = item->getCenter();
+ p.push_back(std::make_pair(item->getCenter(), target ? int(Inkscape::SNAPTARGET_OBJECT_MIDPOINT) : int(Inkscape::SNAPSOURCE_OBJECT_MIDPOINT)));
}
// Get the snappoints of clipping paths and mask, if any
@@ -988,14 +989,15 @@ void sp_item_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPref
// obj is a group object, the children are the actual clippers
for (SPObject *child = (*o)->children ; child ; child = child->next) {
if (SP_IS_ITEM(child)) {
- std::vector<Geom::Point> p_clip_or_mask;
+ SnapPointsWithType p_clip_or_mask;
// Please note the recursive call here!
- sp_item_snappoints(SP_ITEM(child), SnapPointsIter(p_clip_or_mask), snapprefs);
+ sp_item_snappoints(SP_ITEM(child), target, p_clip_or_mask, snapprefs);
// Take into account the transformation of the item being clipped or masked
- for (std::vector<Geom::Point>::const_iterator p_orig = p_clip_or_mask.begin(); p_orig != p_clip_or_mask.end(); p_orig++) {
+ for (SnapPointsWithType::const_iterator p_orig = p_clip_or_mask.begin(); p_orig != p_clip_or_mask.end(); p_orig++) {
// All snappoints are in desktop coordinates, but the item's transformation is
// in document coordinates. Hence the awkward construction below
- *p = desktop->dt2doc(*p_orig) * sp_item_i2d_affine(item);
+ Geom::Point pt = desktop->dt2doc((*p_orig).first) * sp_item_i2d_affine(item);
+ p.push_back(std::make_pair(pt, (*p_orig).second));
}
}
}
diff --git a/src/sp-item.h b/src/sp-item.h
index d95fc2486f1b28ce9cce49c54e3fab5e66ef6e1c..639a1b4a2a18d1d0c601cc41706281ce25d9a04d 100644 (file)
--- a/src/sp-item.h
+++ b/src/sp-item.h
#include <2geom/forward.h>
#include <libnr/nr-convert2geom.h>
#include <snap-preferences.h>
+#include <snapped-point.h>
class SPGuideConstraint;
struct SPClipPathReference;
struct SPAvoidRef;
struct SPPrintContext;
namespace Inkscape { class URIReference; }
-
+
enum {
SP_EVENT_INVALID,
SP_EVENT_NONE,
#define SP_ITEM_SHOW_DISPLAY (1 << 0)
/**
- * Flag for referenced views (i.e. markers, clippaths, masks and patterns);
+ * Flag for referenced views (i.e. markers, clippaths, masks and patterns);
currently unused, does the same as DISPLAY
*/
#define SP_ITEM_REFERENCE_FLAGS (1 << 1)
struct SPItem : public SPObject {
enum BBoxType {
// legacy behavior: includes crude stroke, markers; excludes long miters, blur margin; is known to be wrong for caps
- APPROXIMATE_BBOX,
+ APPROXIMATE_BBOX,
// includes only the bare path bbox, no stroke, no nothing
GEOMETRIC_BBOX,
// includes everything: correctly done stroke (with proper miters and caps), markers, filter margins (e.g. blur)
double transform_center_y;
Geom::Matrix transform;
-
+
SPClipPathReference *clip_ref;
SPMaskReference *mask_ref;
-
+
// Used for object-avoiding connectors
SPAvoidRef *avoidRef;
-
+
SPItemView *display;
-
+
std::vector<SPGuideConstraint> constraints;
-
+
sigc::signal<void, Geom::Matrix const *, SPItem *> _transformed_signal;
- void init();
+ void init();
bool isLocked() const;
void setLocked(bool lock);
-
+
bool isHidden() const;
void setHidden(bool hidden);
bool isEvaluated() const;
void setEvaluated(bool visible);
void resetEvaluated();
-
+
bool isHidden(unsigned display_key) const;
-
+
bool isExplicitlyHidden() const;
-
+
void setExplicitlyHidden(bool val);
void setCenter(Geom::Point object_centre);
Geom::Point getCenter() const;
bool isVisibleAndUnlocked() const;
-
+
bool isVisibleAndUnlocked(unsigned display_key) const;
-
+
Geom::Matrix getRelativeTransform(SPObject const *obj) const;
-
+
void raiseOne();
void lowerOne();
void raiseToTop();
mutable EvaluatedStatus _evaluated_status;
};
-typedef std::back_insert_iterator<std::vector<Geom::Point> > SnapPointsIter;
+typedef std::vector<std::pair<Geom::Point, int> > SnapPointsWithType; // int is either of these enums: Inkscape::SnapTargetType or Inkscape::SnapSourceType
/// The SPItem vtable.
struct SPItemClass {
/** BBox union in given coordinate system */
void (* bbox) (SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags);
-
+
/** Printing method. Assumes ctm is set to item affine matrix */
/* \todo Think about it, and maybe implement generic export method instead (Lauris) */
void (* print) (SPItem *item, SPPrintContext *ctx);
-
+
/** Give short description of item (for status display) */
gchar * (* description) (SPItem * item);
-
+
NRArenaItem * (* show) (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
void (* hide) (SPItem *item, unsigned int key);
-
+
/** Write to an iterator the points that should be considered for snapping
* as the item's `nodes'.
*/
- void (* snappoints) (SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
-
+ void (* snappoints) (SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
+
/** Apply the transform optimally, and return any residual transformation */
Geom::Matrix (* set_transform)(SPItem *item, Geom::Matrix const &transform);
/** Convert the item to guidelines */
void (* convert_to_guides)(SPItem *item);
-
+
/** Emit event, if applicable */
gint (* event) (SPItem *item, SPEvent *event);
};
NRArenaItem *sp_item_invoke_show(SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
void sp_item_invoke_hide(SPItem *item, unsigned int key);
-void sp_item_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+void sp_item_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
void sp_item_adjust_pattern(SPItem *item, /* Geom::Matrix const &premul, */ Geom::Matrix const &postmul, bool set = false);
void sp_item_adjust_gradient(SPItem *item, /* Geom::Matrix const &premul, */ Geom::Matrix const &postmul, bool set = false);
diff --git a/src/sp-offset.cpp b/src/sp-offset.cpp
index 39b8227a4384cb68cab7508135de9263b97c66bc..ae0f7bf19ea48bebe09cc7ccf91f12f6958aff74 100644 (file)
--- a/src/sp-offset.cpp
+++ b/src/sp-offset.cpp
static void sp_offset_release (SPObject * object);
static gchar *sp_offset_description (SPItem * item);
-static void sp_offset_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_offset_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
static void sp_offset_set_shape (SPShape * shape);
static void refresh_offset_source(SPOffset* offset);
/**
* Virtual snappoints function.
*/
-static void sp_offset_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_offset_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
{
if (((SPItemClass *) parent_class)->snappoints) {
- ((SPItemClass *) parent_class)->snappoints (item, p, snapprefs);
+ ((SPItemClass *) parent_class)->snappoints (item, target, p, snapprefs);
}
}
diff --git a/src/sp-rect.cpp b/src/sp-rect.cpp
index c88b9eb38df0899f11d88a972de5f35f64e53f3a..4f8dbbbce6ad733923b56a90490dae8d2530948e 100644 (file)
--- a/src/sp-rect.cpp
+++ b/src/sp-rect.cpp
static void sp_rect_convert_to_guides(SPItem *item);
static void sp_rect_set_shape(SPShape *shape);
-static void sp_rect_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_rect_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
static SPShapeClass *parent_class;
/**
* Sets the snappoint p to the unrounded corners of the rectangle
*/
-static void sp_rect_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_rect_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
{
/* This method overrides sp_shape_snappoints, which is the default for any shape. The default method
returns all eight points along the path of a rounded rectangle, but not the real corners. Snapping
@@ -569,22 +569,27 @@ static void sp_rect_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::S
Geom::Point p2 = Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed) * i2d;
Geom::Point p3 = Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed) * i2d;
+ int type;
+
if (snapprefs->getSnapToItemNode()) {
- *p = p0;
- *p = p1;
- *p = p2;
- *p = p3;
+ type = target ? int(Inkscape::SNAPTARGET_HANDLE) : int(Inkscape::SNAPSOURCE_HANDLE);
+ p.push_back(std::make_pair(p0, type));
+ p.push_back(std::make_pair(p1, type));
+ p.push_back(std::make_pair(p2, type));
+ p.push_back(std::make_pair(p3, type));
}
if (snapprefs->getSnapLineMidpoints()) { // only do this when we're snapping nodes (enforce strict snapping)
- *p = (p0 + p1)/2;
- *p = (p1 + p2)/2;
- *p = (p2 + p3)/2;
- *p = (p3 + p0)/2;
+ type = target ? int(Inkscape::SNAPTARGET_LINE_MIDPOINT) : int(Inkscape::SNAPSOURCE_LINE_MIDPOINT);
+ p.push_back(std::make_pair((p0 + p1)/2, type));
+ p.push_back(std::make_pair((p1 + p2)/2, type));
+ p.push_back(std::make_pair((p2 + p3)/2, type));
+ p.push_back(std::make_pair((p3 + p0)/2, type));
}
if (snapprefs->getSnapObjectMidpoints()) { // only do this when we're snapping nodes (enforce strict snapping)
- *p = (p0 + p2)/2;
+ type = target ? int(Inkscape::SNAPTARGET_OBJECT_MIDPOINT) : int(Inkscape::SNAPSOURCE_OBJECT_MIDPOINT);
+ p.push_back(std::make_pair((p0 + p2)/2, type));
}
}
diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp
index 178ca89a8b210c93a529f8a75720e4170109a745..7b4663908e84cf532ffc6a9fd07167ed4f769e8a 100644 (file)
--- a/src/sp-shape.cpp
+++ b/src/sp-shape.cpp
void sp_shape_print (SPItem * item, SPPrintContext * ctx);
static NRArenaItem *sp_shape_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
static void sp_shape_hide (SPItem *item, unsigned int key);
-static void sp_shape_snappoints (SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_shape_snappoints (SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
static void sp_shape_update_marker_view (SPShape *shape, NRArenaItem *ai);
@@ -1057,7 +1057,7 @@ sp_shape_set_curve_insync (SPShape *shape, SPCurve *curve, unsigned int owner)
/**
* Return all nodes in a path that are to be considered for snapping
*/
-static void sp_shape_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_shape_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
{
g_assert(item != NULL);
g_assert(SP_IS_SHAPE(item));
@@ -1078,16 +1078,20 @@ static void sp_shape_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::
Geom::Matrix const i2d (sp_item_i2d_affine (item));
+ int type;
+
if (snapprefs->getSnapObjectMidpoints()) {
Geom::OptRect bbox = item->getBounds(sp_item_i2d_affine(item));
if (bbox) {
- *p = bbox->midpoint();
+ type = target ? int(Inkscape::SNAPTARGET_OBJECT_MIDPOINT) : int(Inkscape::SNAPSOURCE_OBJECT_MIDPOINT);
+ p.push_back(std::make_pair(bbox->midpoint(), type));
}
}
for(Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) {
if (snapprefs->getSnapToItemNode()) {
- *p = path_it->initialPoint() * i2d;
+ type = target ? int(Inkscape::SNAPTARGET_NODE_CUSP) : int(Inkscape::SNAPSOURCE_NODE_CUSP);
+ p.push_back(std::make_pair(path_it->initialPoint() * i2d, type));
}
Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve
@@ -1106,13 +1110,15 @@ static void sp_shape_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::
bool c2 = snapprefs->getSnapSmoothNodes() && (nodetype == Geom::NODE_SMOOTH || nodetype == Geom::NODE_SYMM);
if (c1 || c2) {
- *p = curve_it1->finalPoint() * i2d;
+ type = target ? int(Inkscape::SNAPTARGET_NODE_CUSP) : int(Inkscape::SNAPSOURCE_NODE_CUSP);
+ p.push_back(std::make_pair(curve_it1->finalPoint() * i2d, type));
}
// Consider midpoints of line segments for snapping
if (snapprefs->getSnapLineMidpoints()) { // only do this when we're snapping nodes (enforce strict snapping)
if (Geom::LineSegment const* line_segment = dynamic_cast<Geom::LineSegment const*>(&(*curve_it1))) {
- *p = Geom::middle_point(*line_segment) * i2d;
+ type = target ? int(Inkscape::SNAPTARGET_LINE_MIDPOINT) : int(Inkscape::SNAPSOURCE_LINE_MIDPOINT);
+ p.push_back(std::make_pair(Geom::middle_point(*line_segment) * i2d, type));
}
}
@@ -1128,7 +1134,8 @@ static void sp_shape_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::
if (cs.size() > 0) { // There might be multiple intersections...
for (Geom::Crossings::const_iterator i = cs.begin(); i != cs.end(); i++) {
Geom::Point p_ix = (*path_it).pointAt((*i).ta);
- *p = p_ix * i2d;
+ type = target ? int(Inkscape::SNAPTARGET_PATH_INTERSECTION) : int(Inkscape::SNAPSOURCE_PATH_INTERSECTION);
+ p.push_back(std::make_pair(p_ix * i2d, type));
}
}
}
diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp
index 624c5ae181ad7513a2200cac5e1c79373270043a..872607c275da938770a17b1521edb441899737eb 100644 (file)
--- a/src/sp-spiral.cpp
+++ b/src/sp-spiral.cpp
static void sp_spiral_update (SPObject *object, SPCtx *ctx, guint flags);
static gchar * sp_spiral_description (SPItem * item);
-static void sp_spiral_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_spiral_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
static void sp_spiral_set_shape (SPShape *shape);
static void sp_spiral_update_patheffect (SPLPEItem *lpeitem, bool write);
/**
* Virtual snappoints callback.
*/
-static void sp_spiral_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_spiral_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
{
// We will determine the spiral's midpoint ourselves, instead of trusting on the base class
// Therefore setSnapObjectMidpoints() is set to false temporarily
@@ -511,7 +511,7 @@ static void sp_spiral_snappoints(SPItem const *item, SnapPointsIter p, Inkscape:
local_snapprefs.setSnapObjectMidpoints(false);
if (((SPItemClass *) parent_class)->snappoints) {
- ((SPItemClass *) parent_class)->snappoints (item, p, &local_snapprefs);
+ ((SPItemClass *) parent_class)->snappoints (item, target, p, &local_snapprefs);
}
// Help enforcing strict snapping, i.e. only return nodes when we're snapping nodes to nodes or a guide to nodes
@@ -522,7 +522,8 @@ static void sp_spiral_snappoints(SPItem const *item, SnapPointsIter p, Inkscape:
if (snapprefs->getSnapObjectMidpoints()) {
Geom::Matrix const i2d (sp_item_i2d_affine (item));
SPSpiral *spiral = SP_SPIRAL(item);
- *p = Geom::Point(spiral->cx, spiral->cy) * i2d;
+ int type = target ? int(Inkscape::SNAPTARGET_OBJECT_MIDPOINT) : int(Inkscape::SNAPSOURCE_OBJECT_MIDPOINT);
+ p.push_back(std::make_pair(Geom::Point(spiral->cx, spiral->cy) * i2d, type));
// This point is the start-point of the spiral, which is also returned when _snap_to_itemnode has been set
// in the object snapper. In that case we will get a duplicate!
}
diff --git a/src/sp-star.cpp b/src/sp-star.cpp
index c1581a6d6d7bc3baa131f52680b1bde2f0d31b00..3c8754a1147ebd148b99fbb6e34c3198ab891edf 100644 (file)
--- a/src/sp-star.cpp
+++ b/src/sp-star.cpp
static void sp_star_update (SPObject *object, SPCtx *ctx, guint flags);
static gchar * sp_star_description (SPItem * item);
-static void sp_star_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_star_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
static void sp_star_set_shape (SPShape *shape);
static void sp_star_update_patheffect (SPLPEItem *lpeitem, bool write);
SP_OBJECT(star)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
-static void sp_star_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_star_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
{
// We will determine the star's midpoint ourselves, instead of trusting on the base class
// Therefore setSnapObjectMidpoints() is set to false temporarily
@@ -536,7 +536,7 @@ static void sp_star_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::S
local_snapprefs.setSnapObjectMidpoints(false);
if (((SPItemClass *) parent_class)->snappoints) {
- ((SPItemClass *) parent_class)->snappoints (item, p, &local_snapprefs);
+ ((SPItemClass *) parent_class)->snappoints (item, target, p, &local_snapprefs);
}
// Help enforcing strict snapping, i.e. only return nodes when we're snapping nodes to nodes or a guide to nodes
@@ -546,7 +546,8 @@ static void sp_star_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::S
if (snapprefs->getSnapObjectMidpoints()) {
Geom::Matrix const i2d (sp_item_i2d_affine (item));
- *p = SP_STAR(item)->center * i2d;
+ int type = target ? int(Inkscape::SNAPTARGET_OBJECT_MIDPOINT) : int(Inkscape::SNAPSOURCE_OBJECT_MIDPOINT);
+ p.push_back(std::make_pair(SP_STAR(item)->center * i2d, type));
}
}
diff --git a/src/sp-text.cpp b/src/sp-text.cpp
index 8627e179ffbc88dc0fc7d4eb29e2dd98c8429dd6..abfb9ca6582c5b3841ff94c652c8a2fa8bc9a0b8 100644 (file)
--- a/src/sp-text.cpp
+++ b/src/sp-text.cpp
static NRArenaItem *sp_text_show (SPItem *item, NRArena *arena, unsigned key, unsigned flags);
static void sp_text_hide (SPItem *item, unsigned key);
static char *sp_text_description (SPItem *item);
-static void sp_text_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_text_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
static Geom::Matrix sp_text_set_transform(SPItem *item, Geom::Matrix const &xform);
static void sp_text_print (SPItem *item, SPPrintContext *gpc);
return ret;
}
-static void sp_text_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const */*snapprefs*/)
+static void sp_text_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const */*snapprefs*/)
{
// the baseline anchor of the first char
Inkscape::Text::Layout const *layout = te_get_layout((SPItem *) item);
if(layout != NULL) {
- *p = layout->characterAnchorPoint(layout->begin()) * sp_item_i2d_affine(item);
+ int type = target ? int(Inkscape::SNAPTARGET_HANDLE) : int(Inkscape::SNAPSOURCE_HANDLE);
+ p.push_back(std::make_pair(layout->characterAnchorPoint(layout->begin()) * sp_item_i2d_affine(item), type));
}
}
diff --git a/src/sp-use.cpp b/src/sp-use.cpp
index 36372e67b4f3f8a5a0c7fadb0d98a6e994cb93b9..990407f95deb85b7004b4e8dcaf142a58c107e4e 100644 (file)
--- a/src/sp-use.cpp
+++ b/src/sp-use.cpp
static void sp_use_modified(SPObject *object, guint flags);
static void sp_use_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags);
-static void sp_use_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_use_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
static void sp_use_print(SPItem *item, SPPrintContext *ctx);
static gchar *sp_use_description(SPItem *item);
static NRArenaItem *sp_use_show(SPItem *item, NRArena *arena, unsigned key, unsigned flags);
}
static void
-sp_use_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
+sp_use_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
{
g_assert (item != NULL);
g_assert (SP_IS_ITEM(item));
g_assert (SP_IS_USE(item));
-
+
SPUse *use = SP_USE(item);
SPItem *root = sp_use_root(use);
g_return_if_fail(root);
-
+
SPItemClass const &item_class = *(SPItemClass const *) G_OBJECT_GET_CLASS(root);
if (item_class.snappoints) {
- item_class.snappoints(root, p, snapprefs);
+ item_class.snappoints(root, target, p, snapprefs);
}
}
diff --git a/src/spiral-context.cpp b/src/spiral-context.cpp
index 35d5144a7881d58f8b67f87321bd848fc10b6fa6..3689ae4af3fbbe9bea974c9b5306786e08fe7d6c 100644 (file)
--- a/src/spiral-context.cpp
+++ b/src/spiral-context.cpp
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
Geom::Point pt2g = to_2geom(sc->center);
- m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g);
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE);
sc->center = from_2geom(pt2g);
sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop, true, sc->item);
- m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, motion_dt);
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, motion_dt, Inkscape::SNAPSOURCE_HANDLE);
sp_spiral_drag(sc, from_2geom(motion_dt), event->motion.state);
gobble_motion_events(GDK_BUTTON1_MASK);
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop, true, sc->item);
Geom::Point pt2g = to_2geom(p);
- m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g);
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE);
Geom::Point const p0 = to_2geom(sp_desktop_dt2doc_xy_point(desktop, sc->center));
Geom::Point const p1 = to_2geom(sp_desktop_dt2doc_xy_point(desktop, from_2geom(pt2g)));
diff --git a/src/star-context.cpp b/src/star-context.cpp
index da79d4719a9852ce62e294b91516ac7e919f9750..54c431e2cadc656c1818f62bd3a9b4cfeb297de6 100644 (file)
--- a/src/star-context.cpp
+++ b/src/star-context.cpp
@@ -243,7 +243,7 @@ static gint sp_star_context_root_handler(SPEventContext *event_context, GdkEvent
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop, true);
Geom::Point pt2g = to_2geom(sc->center);
- m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g);
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE);
sc->center = from_2geom(pt2g);
sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop, true, sc->item);
Geom::Point pt2g = to_2geom(p);
- m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g);
+ m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE);
Geom::Point const p0 = to_2geom(sp_desktop_dt2doc_xy_point(desktop, sc->center));
Geom::Point const p1 = to_2geom(sp_desktop_dt2doc_xy_point(desktop, from_2geom(pt2g)));