From: dvlierop2 Date: Wed, 30 Apr 2008 07:32:12 +0000 (+0000) Subject: - Major refactoring of snapping related code... X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=c3d71eeb981927093e5a6284277181d1d6b83985;p=inkscape.git - Major refactoring of snapping related code... - Enabling snap indicator for all remaining tools --- diff --git a/src/arc-context.cpp b/src/arc-context.cpp index 82c00fd05..07f5f4826 100644 --- a/src/arc-context.cpp +++ b/src/arc-context.cpp @@ -263,8 +263,9 @@ static gint sp_arc_context_root_handler(SPEventContext *event_context, GdkEvent dragging = true; ac->center = Inkscape::setup_for_drag_start(desktop, event_context, event); - SnapManager const &m = desktop->namedview->snap_manager; - ac->center = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, ac->center, ac->item).getPoint(); + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop, ac->item); + ac->center = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, ac->center).getPoint(); sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate), GDK_KEY_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | @@ -289,8 +290,9 @@ static gint sp_arc_context_root_handler(SPEventContext *event_context, GdkEvent NR::Point const motion_w(event->motion.x, event->motion.y); NR::Point motion_dt(desktop->w2d(motion_w)); - SnapManager const &m = desktop->namedview->snap_manager; - motion_dt = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, motion_dt, ac->item).getPoint(); + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop, ac->item); + motion_dt = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, motion_dt).getPoint(); sp_arc_drag(ac, motion_dt, event->motion.state); diff --git a/src/box3d-context.cpp b/src/box3d-context.cpp index 7414fcd77..ca6822dda 100644 --- a/src/box3d-context.cpp +++ b/src/box3d-context.cpp @@ -330,9 +330,9 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven bc->drag_ptC_proj[Proj::Z] = 0.25; /* Snap center */ - SnapManager const &m = desktop->namedview->snap_manager; - bc->center = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, - button_dt, bc->item).getPoint(); + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop, bc->item); + bc->center = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, button_dt).getPoint(); sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate), ( GDK_KEY_PRESS_MASK | @@ -361,8 +361,9 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven event->motion.y); NR::Point motion_dt(desktop->w2d(motion_w)); - SnapManager const &m = desktop->namedview->snap_manager; - motion_dt = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, motion_dt, bc->item).getPoint(); + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop, bc->item); + motion_dt = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, motion_dt).getPoint(); bc->ctrl_dragged = event->motion.state & GDK_CONTROL_MASK; @@ -395,7 +396,7 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven bc->drag_ptB_proj.normalize(); bc->drag_ptC_proj = cur_persp->tmat.preimage (motion_dt, bc->drag_ptB_proj[Proj::X], Proj::X); } - bc->drag_ptC = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, bc->drag_ptC, bc->item).getPoint(); + bc->drag_ptC = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, bc->drag_ptC).getPoint(); } sp_box3d_drag(*bc, event->motion.state); diff --git a/src/connector-context.cpp b/src/connector-context.cpp index 6da465f2a..d311cfabd 100644 --- a/src/connector-context.cpp +++ b/src/connector-context.cpp @@ -530,9 +530,9 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const if (!cc->sid) { // This is the first point, so just snap it to the grid // as there's no other points to go off. - SnapManager const &m = cc->desktop->namedview->snap_manager; - p = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, - p, NULL).getPoint(); + SnapManager &m = cc->desktop->namedview->snap_manager; + m.setup(cc->desktop); + p = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, p).getPoint(); } spcc_connector_set_initial_point(cc, p); diff --git a/src/context-fns.cpp b/src/context-fns.cpp index d7333adbe..83048af40 100644 --- a/src/context-fns.cpp +++ b/src/context-fns.cpp @@ -85,7 +85,8 @@ NR::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item, bool const shift = state & GDK_SHIFT_MASK; bool const control = state & GDK_CONTROL_MASK; - SnapManager const &m = desktop->namedview->snap_manager; + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop, item); Inkscape::SnappedPoint snappoint; if (control) { @@ -132,11 +133,11 @@ NR::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item, /* Try to snap p[0] (the opposite corner) along the constraint vector */ s[0] = m.constrainedSnap(Inkscape::Snapper::SNAPPOINT_NODE, p[0], - Inkscape::Snapper::ConstraintLine(p[0] - p[1]), item); + Inkscape::Snapper::ConstraintLine(p[0] - p[1])); /* Try to snap p[1] (the dragged corner) along the constraint vector */ s[1] = m.constrainedSnap(Inkscape::Snapper::SNAPPOINT_NODE, p[1], - Inkscape::Snapper::ConstraintLine(p[1] - p[0]), item); + Inkscape::Snapper::ConstraintLine(p[1] - p[0])); /* Choose the best snap and update points accordingly */ if (s[0].getDistance() < s[1].getDistance()) { @@ -148,13 +149,14 @@ NR::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item, p[1] = s[1].getPoint(); snappoint = s[1]; } + desktop->snapindicator->set_new_snappoint(snappoint); } else { /* Our origin is the opposite corner. Snap the drag point along the constraint vector */ p[0] = center; snappoint = m.constrainedSnap(Inkscape::Snapper::SNAPPOINT_NODE, p[1], - Inkscape::Snapper::ConstraintLine(p[1] - p[0]), item); + Inkscape::Snapper::ConstraintLine(p[1] - p[0])); p[1] = snappoint.getPoint(); } @@ -169,8 +171,8 @@ NR::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item, Inkscape::SnappedPoint s[2]; - s[0] = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, p[0], item); - s[1] = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, p[1], item); + s[0] = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, p[0]); + s[1] = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, p[1]); if (s[0].getDistance() < s[1].getDistance()) { p[0] = s[0].getPoint(); @@ -186,7 +188,7 @@ NR::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; - snappoint = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, pt, item); + snappoint = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, pt); p[1] = snappoint.getPoint(); } diff --git a/src/desktop-events.cpp b/src/desktop-events.cpp index d2b21294c..29734f459 100644 --- a/src/desktop-events.cpp +++ b/src/desktop-events.cpp @@ -142,19 +142,14 @@ static gint sp_dt_ruler_event(GtkWidget *widget, GdkEvent *event, SPDesktopWidge NR::Point const event_w(sp_canvas_window_to_world(dtw->canvas, event_win)); NR::Point event_dt(desktop->w2d(event_w)); - SnapManager const &m = desktop->namedview->snap_manager; + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop); Inkscape::SnappedPoint snappoint = m.guideSnap(event_dt, normal); event_dt = snappoint.getPoint(); sp_guideline_set_position(SP_GUIDELINE(guide), event_dt.to_2geom()); desktop->set_coordinate_status(event_dt); - desktop->setPosition (event_dt); - - if (snappoint.getSnapped()) { - desktop->snapindicator->set_new_snappoint(snappoint); - } else { - desktop->snapindicator->remove_snappoint(); - } + desktop->setPosition (event_dt); } break; case GDK_BUTTON_RELEASE: @@ -163,7 +158,8 @@ static gint sp_dt_ruler_event(GtkWidget *widget, GdkEvent *event, SPDesktopWidge NR::Point const event_w(sp_canvas_window_to_world(dtw->canvas, event_win)); NR::Point event_dt(desktop->w2d(event_w)); - SnapManager const &m = desktop->namedview->snap_manager; + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop); event_dt = m.guideSnap(event_dt, normal).getPoint(); dragging = false; @@ -245,7 +241,8 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) // This is for snapping while dragging existing guidelines. New guidelines, // which are dragged off the ruler, are being snapped in sp_dt_ruler_event - SnapManager const &m = desktop->namedview->snap_manager; + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop); Inkscape::SnappedPoint snappoint = m.guideSnap(motion_dt, guide->normal_to_line); motion_dt = snappoint.getPoint(); @@ -254,12 +251,6 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) desktop->set_coordinate_status(motion_dt); desktop->setPosition (motion_dt); - if (snappoint.getSnapped()) { - desktop->snapindicator->set_new_snappoint(snappoint); - } else { - desktop->snapindicator->remove_snappoint(); - } - ret = TRUE; } break; @@ -270,7 +261,8 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) event->button.y); NR::Point event_dt(desktop->w2d(event_w)); - SnapManager const &m = desktop->namedview->snap_manager; + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop); event_dt = m.guideSnap(event_dt, guide->normal_to_line).getPoint(); if (sp_canvas_world_pt_inside_window(item->canvas, event_w)) { diff --git a/src/desktop.h b/src/desktop.h index 7653f0857..df9848282 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -36,6 +36,7 @@ #include "ui/view/edit-widget-interface.h" #include "display/rendermode.h" +#include "display/snap-indicator.h" class NRRect; class SPCSSAttr; @@ -77,7 +78,7 @@ namespace Inkscape { namespace Display { class TemporaryItemList; class TemporaryItem; - class SnapIndicator; + //class SnapIndicator; } } diff --git a/src/display/snap-indicator.cpp b/src/display/snap-indicator.cpp index 03fcad484..3ee00c9d1 100644 --- a/src/display/snap-indicator.cpp +++ b/src/display/snap-indicator.cpp @@ -3,8 +3,10 @@ * * Authors: * Johan Engelen + * Diederik van Lierop * * Copyright (C) Johan Engelen 2008 + * Copyright (C) Diederik van Lierop 2008 * * Released under GNU GPL, read the file 'COPYING' for more information */ diff --git a/src/display/snap-indicator.h b/src/display/snap-indicator.h index c17de0494..1e93e36df 100644 --- a/src/display/snap-indicator.h +++ b/src/display/snap-indicator.h @@ -6,8 +6,10 @@ * * Authors: * Johan Engelen + * Diederik van Lierop * * Copyright (C) Johan Engelen 2008 + * Copyright (C) Diederik van Lierop 2008 * * Released under GNU GPL, read the file 'COPYING' for more information */ diff --git a/src/draw-context.cpp b/src/draw-context.cpp index 42555f8d2..05045e969 100644 --- a/src/draw-context.cpp +++ b/src/draw-context.cpp @@ -40,7 +40,6 @@ #include "snap.h" #include "sp-path.h" #include "sp-namedview.h" -#include "display/snap-indicator.h" static void sp_draw_context_class_init(SPDrawContextClass *klass); static void sp_draw_context_init(SPDrawContext *dc); @@ -354,13 +353,11 @@ void spdc_endpoint_snap_rotation(SPEventContext const *const ec, NR::Point &p, N p = o + bdot * best; /* Snap it along best vector */ - SnapManager const &m = SP_EVENT_CONTEXT_DESKTOP(ec)->namedview->snap_manager; + SnapManager &m = SP_EVENT_CONTEXT_DESKTOP(ec)->namedview->snap_manager; + m.setup(SP_EVENT_CONTEXT_DESKTOP(ec), NULL); Inkscape::SnappedPoint const s = m.constrainedSnap( Inkscape::Snapper::SNAPPOINT_NODE, - p, Inkscape::Snapper::ConstraintLine(best), NULL ); + p, Inkscape::Snapper::ConstraintLine(best)); p = s.getPoint(); - if (s.getSnapped()) { - SP_EVENT_CONTEXT_DESKTOP(ec)->snapindicator->set_new_snappoint(s); - } } } @@ -372,12 +369,10 @@ void spdc_endpoint_snap_free(SPEventContext const * const ec, NR::Point& p, guin return; } - SnapManager const &m = SP_EVENT_CONTEXT_DESKTOP(ec)->namedview->snap_manager; - Inkscape::SnappedPoint const s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, p, NULL); + SnapManager &m = SP_EVENT_CONTEXT_DESKTOP(ec)->namedview->snap_manager; + m.setup(SP_EVENT_CONTEXT_DESKTOP(ec), NULL); + Inkscape::SnappedPoint const s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, p); p = s.getPoint(); - if (s.getSnapped()) { - SP_EVENT_CONTEXT_DESKTOP(ec)->snapindicator->set_new_snappoint(s); - } } static SPCurve * diff --git a/src/gradient-context.cpp b/src/gradient-context.cpp index 230072e64..86bce50b9 100644 --- a/src/gradient-context.cpp +++ b/src/gradient-context.cpp @@ -552,8 +552,9 @@ sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event) event_context->item_to_select = sp_event_context_find_item (desktop, button_w, event->button.state & GDK_MOD1_MASK, TRUE); /* Snap center to nearest magnetic point */ - SnapManager const &m = desktop->namedview->snap_manager; - rc->origin = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, button_dt, NULL).getPoint(); + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop); + rc->origin = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, button_dt).getPoint(); } ret = TRUE; diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp index 7a7957856..ee9ff657b 100644 --- a/src/gradient-drag.cpp +++ b/src/gradient-drag.cpp @@ -43,8 +43,6 @@ #include "snap.h" #include "sp-namedview.h" #include "selection-chemistry.h" -#include "display/snap-indicator.h" - #define GR_KNOT_COLOR_NORMAL 0xffffff00 #define GR_KNOT_COLOR_MOUSEOVER 0xff000000 @@ -529,8 +527,6 @@ gr_knot_moved_handler(SPKnot *knot, NR::Point const *ppointer, guint state, gpoi // FIXME: take from prefs double snap_dist = SNAP_DIST / dragger->parent->desktop->current_zoom(); - dragger->parent->desktop->snapindicator->remove_snappoint(); - if (state & GDK_SHIFT_MASK) { // with Shift; unsnap if we carry more than one draggable if (dragger->draggables && dragger->draggables->next) { @@ -582,12 +578,13 @@ gr_knot_moved_handler(SPKnot *knot, NR::Point const *ppointer, guint state, gpoi if (!((state & GDK_SHIFT_MASK) || ((state & GDK_CONTROL_MASK) && (state & GDK_MOD1_MASK)))) { // Try snapping to the grid or guides - SnapManager const &m = dragger->parent->desktop->namedview->snap_manager; - Inkscape::SnappedPoint s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, p, NULL); + SPDesktop *desktop = dragger->parent->desktop; + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop); + Inkscape::SnappedPoint s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, p); if (s.getSnapped()) { p = s.getPoint(); sp_knot_moveto (knot, &p); - dragger->parent->desktop->snapindicator->set_new_snappoint(s); } else { bool was_snapped = false; double dist = NR_HUGE; @@ -611,7 +608,7 @@ gr_knot_moved_handler(SPKnot *knot, NR::Point const *ppointer, guint state, gpoi } } if (was_snapped) { - dragger->parent->desktop->snapindicator->set_new_snappoint(s); + desktop->snapindicator->set_new_snappoint(s); } } } diff --git a/src/line-snapper.cpp b/src/line-snapper.cpp index b9974c2c0..efa6762b2 100644 --- a/src/line-snapper.cpp +++ b/src/line-snapper.cpp @@ -23,14 +23,18 @@ Inkscape::LineSnapper::LineSnapper(SPNamedView const *nv, NR::Coord const d) : S } -void Inkscape::LineSnapper::_doFreeSnap(SnappedConstraints &sc, +void Inkscape::LineSnapper::freeSnap(SnappedConstraints &sc, Inkscape::Snapper::PointType const &t, NR::Point const &p, - bool const &f, - std::vector &points_to_snap, - std::vector const &it, - std::vector *unselected_nodes) const + bool const &/*f*/, + NR::Maybe const &/*bbox_to_snap*/, + std::vector const */*it*/, + std::vector */*unselected_nodes*/) const { + if (_snap_enabled == false || getSnapFrom(t) == false) { + return; + } + /* Get the lines that we will try to snap to */ const LineList lines = _getSnapLines(p); @@ -53,15 +57,19 @@ void Inkscape::LineSnapper::_doFreeSnap(SnappedConstraints &sc, } } -void Inkscape::LineSnapper::_doConstrainedSnap(SnappedConstraints &sc, - Inkscape::Snapper::PointType const &/*t*/, +void Inkscape::LineSnapper::constrainedSnap(SnappedConstraints &sc, + Inkscape::Snapper::PointType const &t, NR::Point const &p, bool const &/*f*/, - std::vector &/*points_to_snap*/, + NR::Maybe const &/*bbox_to_snap*/, ConstraintLine const &c, - std::vector const &/*it*/) const + std::vector const */*it*/) const { + if (_snap_enabled == false || getSnapFrom(t) == false) { + return; + } + /* Get the lines that we will try to snap to */ const LineList lines = _getSnapLines(p); diff --git a/src/line-snapper.h b/src/line-snapper.h index 39df82057..e5fc95dcb 100644 --- a/src/line-snapper.h +++ b/src/line-snapper.h @@ -21,28 +21,28 @@ class LineSnapper : public Snapper public: LineSnapper(SPNamedView const *nv, NR::Coord const d); -protected: - typedef std::list > LineList; - //first point is a vector normal to the line - //second point is a point on the line - -private: - void _doFreeSnap(SnappedConstraints &sc, + void freeSnap(SnappedConstraints &sc, Inkscape::Snapper::PointType const &t, NR::Point const &p, bool const &first_point, - std::vector &points_to_snap, - std::vector const &it, + NR::Maybe const &bbox_to_snap, + std::vector const *it, std::vector *unselected_nodes) const; - void _doConstrainedSnap(SnappedConstraints &sc, + void constrainedSnap(SnappedConstraints &sc, Inkscape::Snapper::PointType const &t, NR::Point const &p, bool const &first_point, - std::vector &points_to_snap, + NR::Maybe const &bbox_to_snap, ConstraintLine const &c, - std::vector const &it) const; - + std::vector const *it) const; + +protected: + typedef std::list > LineList; + //first point is a vector normal to the line + //second point is a point on the line + +private: /** * \param p Point that we are trying to snap. * \return List of lines that we should try snapping to. diff --git a/src/nodepath.cpp b/src/nodepath.cpp index a9886046c..6b1c54057 100644 --- a/src/nodepath.cpp +++ b/src/nodepath.cpp @@ -1233,7 +1233,8 @@ static void sp_nodepath_selected_nodes_move(Inkscape::NodePath::Path *nodepath, for (GList *l = nodepath->selected; l != NULL; l = l->next) { Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data; - Inkscape::SnappedPoint s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, n->pos + delta, SP_PATH(n->subpath->nodepath->item), &unselected_nodes); + m.setup(nodepath->desktop, SP_PATH(n->subpath->nodepath->item), &unselected_nodes); + Inkscape::SnappedPoint s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, n->pos + delta); if (s.getDistance() < best) { best = s.getDistance(); best_abs = s; @@ -3659,7 +3660,9 @@ static gboolean node_handle_request(SPKnot *knot, NR::Point *p, guint /*state*/, g_assert_not_reached(); } - SnapManager const &m = n->subpath->nodepath->desktop->namedview->snap_manager; + SPDesktop *desktop = n->subpath->nodepath->desktop; + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop, n->subpath->nodepath->item); Inkscape::SnappedPoint s ; Inkscape::NodePath::Node *othernode = opposite->other; @@ -3675,18 +3678,13 @@ static gboolean node_handle_request(SPKnot *knot, NR::Point *p, guint /*state*/, NR::Coord const scal = dot(delta, ndelta) / linelen; (*p) = n->pos + (scal / linelen) * ndelta; } - s = m.constrainedSnap(Inkscape::Snapper::SNAPPOINT_NODE, *p, Inkscape::Snapper::ConstraintLine(*p, ndelta), n->subpath->nodepath->item); + s = m.constrainedSnap(Inkscape::Snapper::SNAPPOINT_NODE, *p, Inkscape::Snapper::ConstraintLine(*p, ndelta)); } else { - s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, *p, n->subpath->nodepath->item); + s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, *p); } - } else { - s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, *p, n->subpath->nodepath->item); } - + *p = s.getPoint(); - if (s.getSnapped()) { - n->subpath->nodepath->desktop->snapindicator->set_new_snappoint(s); - } sp_node_adjust_handle(n, -which); diff --git a/src/object-edit.cpp b/src/object-edit.cpp index b3d661586..3d4aaae39 100644 --- a/src/object-edit.cpp +++ b/src/object-edit.cpp @@ -222,8 +222,9 @@ static NR::Point snap_knot_position(SPItem *item, NR::Point const &p) SPDesktop const *desktop = inkscape_active_desktop(); NR::Matrix const i2d (sp_item_i2d_affine (item)); NR::Point s = p * i2d; - SnapManager const &m = desktop->namedview->snap_manager; - s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, s, item).getPoint(); + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop, item); + s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, s).getPoint(); return s * i2d.inverse(); } diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp index a91014158..57ec1b347 100644 --- a/src/object-snapper.cpp +++ b/src/object-snapper.cpp @@ -60,21 +60,20 @@ Inkscape::ObjectSnapper::~ObjectSnapper() * \param r Pointer to the current document * \param it List of items to ignore * \param first_point If true then this point is the first one from a whole bunch of points - * \param points_to_snap The whole bunch of points, all from the same selection and having the same transformation + * \param bbox_to_snap Bounding box hulling the whole bunch of points, all from the same selection and having the same transformation * \param DimensionToSnap Snap in X, Y, or both directions. */ void Inkscape::ObjectSnapper::_findCandidates(SPObject* r, - std::vector const &it, + std::vector const *it, bool const &first_point, - std::vector &points_to_snap, + NR::Rect const &bbox_to_snap, DimensionToSnap const snap_dim) const { bool const c1 = (snap_dim == TRANSL_SNAP_XY) && ThisSnapperMightSnap(); bool const c2 = (snap_dim != TRANSL_SNAP_XY) && GuidesMightSnap(); - bool const c3 = points_to_snap.size() == 0; - if (!(c1 || c2) || c3) { + if (!(c1 || c2)) { return; } @@ -84,49 +83,32 @@ void Inkscape::ObjectSnapper::_findCandidates(SPObject* r, _candidates->clear(); } - NR::Maybe bbox = NR::Rect(); // a default NR::Rect is infinitely large - NR::Coord t = getSnapperTolerance(); + NR::Maybe bbox_of_item = NR::Rect(); // a default NR::Rect is infinitely large + NR::Rect bbox_to_snap_incl = bbox_to_snap; // _incl means: will include the snapper tolerance + bbox_to_snap_incl.growBy(getSnapperTolerance()); // see? - // When dragging a guide... - NR::Point p_guide = points_to_snap[0]; - if (!getSnapperAlwaysSnap()) { - bbox = NR::Rect(p_guide, p_guide); // bbox is now just a single point: p_guide - bbox->growBy(t); // bbox width and height now measure 2x snapper tolerance - // for angled guidelines the bbox is now larger than really needed - // (up to sqrt(2) for 45 deg. guidelines) but we'll leave it like that - } // else: use an infinitely large bbox to find candidates - for (SPObject* o = sp_object_first_child(r); o != NULL; o = SP_OBJECT_NEXT(o)) { if (SP_IS_ITEM(o) && !SP_ITEM(o)->isLocked() && !desktop->itemIsHidden(SP_ITEM(o))) { /* See if this item is on the ignore list */ - std::vector::const_iterator i = it.begin(); - while (i != it.end() && *i != o) { - i++; + std::vector::const_iterator i; + if (it != NULL) { + i = it->begin(); + while (i != it->end() && *i != o) { + i++; + } } - if (i == it.end()) { + if (it == NULL || i == it->end()) { /* See if the item is within range */ if (SP_IS_GROUP(o)) { - _findCandidates(o, it, false, points_to_snap, snap_dim); + _findCandidates(o, it, false, bbox_to_snap, snap_dim); } else { - // Now let's see if any of the snapping points is within snapping range of this object - if (snap_dim == TRANSL_SNAP_XY) { - bbox = sp_item_bbox_desktop(SP_ITEM(o)); - } // else: we're snapping a guide to an object and we will use the bbox as defined above - - if (bbox) { - for (std::vector::const_iterator i = points_to_snap.begin(); i != points_to_snap.end(); i++) { - NR::Point b_min = bbox->min(); - NR::Point b_max = bbox->max(); - bool withinX = ((*i)[NR::X] >= b_min[NR::X] - t) && ((*i)[NR::X] <= b_max[NR::X] + t); - bool withinY = ((*i)[NR::Y] >= b_min[NR::Y] - t) && ((*i)[NR::Y] <= b_max[NR::Y] + t); - if (withinX && withinY) { - //We've found a point that is within snapping range - //of this object, so record it as a candidate - _candidates->push_back(SP_ITEM(o)); - break; - } + bbox_of_item = sp_item_bbox_desktop(SP_ITEM(o)); + if (bbox_of_item) { + if (bbox_to_snap_incl.intersects(*bbox_of_item)) { + //This item is within snapping range, so record it as a candidate + _candidates->push_back(SP_ITEM(o)); } } } @@ -396,7 +378,8 @@ void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc, bool const being_edited = (node_tool_active && (*k) == _paths_to_snap_to->back()); //if true then this path k is currently being edited in the node tool - for (unsigned i = 1 ; i < (*k)->pts.size() ; i++) { + for (unsigned i = 1 ; i < (*k)->pts.size() ; i++) { + //pts describes a polyline approximation, which might consist of 1000s of points! NR::Point start_point; NR::Point end_point; NR::Maybe o = NR::Nothing(); @@ -435,6 +418,13 @@ void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc, if (o && o->t >= 0 && o->t <= 1) { /* Convert the nearest point back to desktop coordinates */ NR::Point const o_it = get_point_on_Path(*k, o->piece, o->t); + + /* IF YOU'RE BUG HUNTING: IT LOOKS LIKE get_point_on_Path SOMETIMES + * RETURNS THE WRONG POINT (WITH AN OFFSET, BUT STILL ON THE PATH. + * THIS BUG WILL NO LONGER BE ENCOUNTERED ONCE WE'VE SWITCHED TO + * 2GEOM FOR THE OBJECT SNAPPER + */ + NR::Point const o_dt = desktop->doc2dt(o_it); NR::Coord const dist = NR::L2(o_dt - p); @@ -549,21 +539,22 @@ void Inkscape::ObjectSnapper::_snapPathsConstrained(SnappedConstraints &sc, } -void Inkscape::ObjectSnapper::_doFreeSnap(SnappedConstraints &sc, +void Inkscape::ObjectSnapper::freeSnap(SnappedConstraints &sc, Inkscape::Snapper::PointType const &t, NR::Point const &p, bool const &first_point, - std::vector &points_to_snap, - std::vector const &it, + NR::Maybe const &bbox_to_snap, + std::vector const *it, std::vector *unselected_nodes) const { - if ( NULL == _named_view ) { + if (_snap_enabled == false || getSnapFrom(t) == false || _named_view == NULL) { return; } /* Get a list of all the SPItems that we will try to snap to */ if (first_point) { - _findCandidates(sp_document_root(_named_view->document), it, first_point, points_to_snap, TRANSL_SNAP_XY); + NR::Rect const local_bbox_to_snap = bbox_to_snap ? *bbox_to_snap : NR::Rect(p, p); + _findCandidates(sp_document_root(_named_view->document), it, first_point, local_bbox_to_snap, TRANSL_SNAP_XY); } if (_snap_to_itemnode || _snap_to_bboxnode) { @@ -580,31 +571,36 @@ void Inkscape::ObjectSnapper::_doFreeSnap(SnappedConstraints &sc, * of the node snapping requirements (i.e. only unselected nodes must be snapable). * That path must not be ignored however when snapping to the paths, so we add it here * manually when applicable - */ - g_assert(it.size() == 1); - g_assert(SP_IS_PATH(*it.begin())); - _snapPaths(sc, t, p, first_point, unselected_nodes, SP_PATH(*it.begin()), border_bpath); + */ + SPPath *path = NULL; + if (it != NULL) { + g_assert(SP_IS_PATH(*it->begin())); + g_assert(it->size() == 1); + path = SP_PATH(*it->begin()); + } + _snapPaths(sc, t, p, first_point, unselected_nodes, path, border_bpath); } else { _snapPaths(sc, t, p, first_point, NULL, NULL, border_bpath); } } } -void Inkscape::ObjectSnapper::_doConstrainedSnap( SnappedConstraints &sc, +void Inkscape::ObjectSnapper::constrainedSnap( SnappedConstraints &sc, Inkscape::Snapper::PointType const &t, NR::Point const &p, bool const &first_point, - std::vector &points_to_snap, + NR::Maybe const &bbox_to_snap, ConstraintLine const &c, - std::vector const &it) const + std::vector const *it) const { - if ( NULL == _named_view ) { + if (_snap_enabled == false || getSnapFrom(t) == false || _named_view == NULL) { return; } /* Get a list of all the SPItems that we will try to snap to */ if (first_point) { - _findCandidates(sp_document_root(_named_view->document), it, first_point, points_to_snap, TRANSL_SNAP_XY); + NR::Rect const local_bbox_to_snap = bbox_to_snap ? *bbox_to_snap : NR::Rect(p, p); + _findCandidates(sp_document_root(_named_view->document), it, first_point, local_bbox_to_snap, TRANSL_SNAP_XY); } // A constrained snap, is a snap in only one degree of freedom (specified by the constraint line). @@ -634,10 +630,7 @@ void Inkscape::ObjectSnapper::guideSnap(SnappedConstraints &sc, /* Get a list of all the SPItems that we will try to snap to */ std::vector cand; std::vector const it; //just an empty list - - std::vector points_to_snap; - points_to_snap.push_back(p); - + DimensionToSnap snap_dim; if (guide_normal == component_vectors[NR::Y]) { snap_dim = GUIDE_TRANSL_SNAP_Y; @@ -646,6 +639,7 @@ void Inkscape::ObjectSnapper::guideSnap(SnappedConstraints &sc, } else { snap_dim = ANGLED_GUIDE_TRANSL_SNAP; } + // We don't support ANGLED_GUIDE_ROT_SNAP yet. // It would be cool to allow the user to rotate a guide by dragging it, instead of @@ -655,8 +649,8 @@ void Inkscape::ObjectSnapper::guideSnap(SnappedConstraints &sc, // or a transformation center (which can be moved after clicking for the // second time on an object; but should this point then be constrained to the // line, or can it be located anywhere?) - - _findCandidates(sp_document_root(_named_view->document), it, true, points_to_snap, snap_dim); + + _findCandidates(sp_document_root(_named_view->document), &it, true, NR::Rect(p, p), snap_dim); _snapTranslatingGuideToNodes(sc, Inkscape::Snapper::SNAPPOINT_GUIDE, p, guide_normal); // _snapRotatingGuideToNodes has not been implemented yet. diff --git a/src/object-snapper.h b/src/object-snapper.h index 29f595424..94c9e5a1c 100644 --- a/src/object-snapper.h +++ b/src/object-snapper.h @@ -40,57 +40,19 @@ public: ANGLED_GUIDE_ROT_SNAP, // For snapping an angled guide, while rotating it around some pivot point TRANSL_SNAP_XY}; // All other cases; for snapping to objects, other than guides - void setSnapToItemNode(bool s) { - _snap_to_itemnode = s; - } - - bool getSnapToItemNode() const { - return _snap_to_itemnode; - } - - void setSnapToItemPath(bool s) { - _snap_to_itempath = s; - } - - bool getSnapToItemPath() const { - return _snap_to_itempath; - } - - void setSnapToBBoxNode(bool s) { - _snap_to_bboxnode = s; - } - - bool getSnapToBBoxNode() const { - return _snap_to_bboxnode; - } - - void setSnapToBBoxPath(bool s) { - _snap_to_bboxpath = s; - } - - bool getSnapToBBoxPath() const { - return _snap_to_bboxpath; - } - - void setSnapToPageBorder(bool s) { - _snap_to_page_border = s; - } - - bool getSnapToPageBorder() const { - return _snap_to_page_border; - } - - void setIncludeItemCenter(bool s) { - _include_item_center = s; - } - - bool getIncludeItemCenter() const { - return _include_item_center; - } - - void setStrictSnapping(bool enabled) { - _strict_snapping = enabled; - } + void setSnapToItemNode(bool s) {_snap_to_itemnode = s;} + bool getSnapToItemNode() const {return _snap_to_itemnode;} + void setSnapToItemPath(bool s) {_snap_to_itempath = s;} + bool getSnapToItemPath() const {return _snap_to_itempath;} + void setSnapToBBoxNode(bool s) {_snap_to_bboxnode = s;} + bool getSnapToBBoxNode() const {return _snap_to_bboxnode;} + void setSnapToBBoxPath(bool s) {_snap_to_bboxpath = s;} + bool getSnapToBBoxPath() const {return _snap_to_bboxpath;} + void setSnapToPageBorder(bool s) {_snap_to_page_border = s;} + bool getSnapToPageBorder() const {return _snap_to_page_border;} + void setIncludeItemCenter(bool s) {_include_item_center = s;} + bool getIncludeItemCenter() const {return _include_item_center;} + void setStrictSnapping(bool enabled) {_strict_snapping = enabled;} void guideSnap(SnappedConstraints &sc, NR::Point const &p, @@ -99,33 +61,33 @@ public: bool ThisSnapperMightSnap() const; bool GuidesMightSnap() const; -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 *_candidates; - std::vector *_points_to_snap_to; - std::vector *_bpaths_to_snap_to; - std::vector *_paths_to_snap_to; - - void _doFreeSnap(SnappedConstraints &sc, + void freeSnap(SnappedConstraints &sc, Inkscape::Snapper::PointType const &t, NR::Point const &p, bool const &first_point, - std::vector &points_to_snap, - std::vector const &it, + NR::Maybe const &bbox_to_snap, + std::vector const *it, std::vector *unselected_nodes) const; - void _doConstrainedSnap(SnappedConstraints &sc, + void constrainedSnap(SnappedConstraints &sc, Inkscape::Snapper::PointType const &t, NR::Point const &p, bool const &first_point, - std::vector &points_to_snap, + NR::Maybe const &bbox_to_snap, ConstraintLine const &c, - std::vector const &it) const; - + std::vector const *it) const; + +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 *_candidates; + std::vector *_points_to_snap_to; + std::vector *_bpaths_to_snap_to; + std::vector *_paths_to_snap_to; + void _findCandidates(SPObject* r, - std::vector const &it, + std::vector const *it, bool const &first_point, - std::vector &points_to_snap, + NR::Rect const &bbox_to_snap, DimensionToSnap snap_dim) const; void _snapNodes(SnappedConstraints &sc, @@ -155,6 +117,7 @@ private: NR::Point const &p, bool const &first_point, ConstraintLine const &c) const; + bool isUnselectedNode(NR::Point const &point, std::vector const *unselected_nodes) const; void _collectPaths(Inkscape::Snapper::PointType const &t, diff --git a/src/pencil-context.cpp b/src/pencil-context.cpp index 878651ade..3d397b180 100644 --- a/src/pencil-context.cpp +++ b/src/pencil-context.cpp @@ -32,7 +32,6 @@ #include "pixmaps/cursor-pencil.xpm" #include "display/bezier-utils.h" #include "display/canvas-bpath.h" -#include "display/snap-indicator.h" #include #include "libnr/in-svg-plane.h" #include "libnr/n-art-bpath.h" @@ -246,8 +245,9 @@ 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")); - SnapManager const &m = desktop->namedview->snap_manager; - p = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, p, NULL).getPoint(); + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop); + p = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, p).getPoint(); } else if (selection->singleItem() && SP_IS_PATH(selection->singleItem())) { desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Appending to selected path")); } @@ -275,8 +275,6 @@ pencil_handle_motion_notify(SPPencilContext *const pc, GdkEventMotion const &mev gint ret = FALSE; SPDesktop *const dt = pc->desktop; - dt->snapindicator->remove_snappoint(); - SPEventContext *event_context = SP_EVENT_CONTEXT(pc); if (event_context->space_panning || mevent.state & GDK_BUTTON2_MASK || mevent.state & GDK_BUTTON3_MASK) { // allow scrolling @@ -324,12 +322,10 @@ pencil_handle_motion_notify(SPPencilContext *const pc, GdkEventMotion const &mev if (anchor) { p = anchor->dp; } else if ((mevent.state & GDK_SHIFT_MASK) == 0) { - SnapManager const &m = dt->namedview->snap_manager; - Inkscape::SnappedPoint const s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, p, NULL); + SnapManager &m = dt->namedview->snap_manager; + m.setup(dt, NULL); + Inkscape::SnappedPoint const s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, p); p = s.getPoint(); - if (s.getSnapped()) { - dt->snapindicator->set_new_snappoint(s); - } } if ( pc->npoints != 0 ) { // buttonpress may have happened before we entered draw context! spdc_add_freehand_point(pc, p, mevent.state); diff --git a/src/rect-context.cpp b/src/rect-context.cpp index 1054a2c55..ad383b014 100644 --- a/src/rect-context.cpp +++ b/src/rect-context.cpp @@ -23,7 +23,6 @@ #include "macros.h" #include "display/sp-canvas.h" -#include "display/snap-indicator.h" #include "sp-rect.h" #include "document.h" #include "sp-namedview.h" @@ -284,8 +283,6 @@ static gint sp_rect_context_root_handler(SPEventContext *event_context, GdkEvent event_context->tolerance = prefs_get_int_attribute_limited("options.dragtolerance", "value", 0, 0, 100); - desktop->snapindicator->remove_snappoint(); - gint ret = FALSE; switch (event->type) { case GDK_BUTTON_PRESS: @@ -307,13 +304,11 @@ static gint sp_rect_context_root_handler(SPEventContext *event_context, GdkEvent NR::Point const button_dt(desktop->w2d(button_w)); /* Snap center */ - SnapManager const &m = desktop->namedview->snap_manager; - Inkscape::SnappedPoint s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, button_dt, rc->item); + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop, rc->item); + Inkscape::SnappedPoint s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, button_dt); rc->center = s.getPoint(); - if (s.getSnapped()) { - desktop->snapindicator->set_new_snappoint(s); - } - + sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate), ( GDK_KEY_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | @@ -341,13 +336,11 @@ static gint sp_rect_context_root_handler(SPEventContext *event_context, GdkEvent event->motion.y); NR::Point motion_dt(desktop->w2d(motion_w)); - SnapManager const &m = desktop->namedview->snap_manager; - Inkscape::SnappedPoint s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, motion_dt, rc->item); + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop, rc->item); + Inkscape::SnappedPoint s = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, motion_dt); motion_dt = s.getPoint(); - if (s.getSnapped()) { - desktop->snapindicator->set_new_snappoint(s); - } - + sp_rect_drag(*rc, motion_dt, event->motion.state); gobble_motion_events(GDK_BUTTON1_MASK); ret = TRUE; diff --git a/src/seltrans.cpp b/src/seltrans.cpp index c90ac31cf..b7dc2e767 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -917,7 +917,8 @@ gboolean Inkscape::SelTrans::scaleRequest(NR::Point &pt, guint state) // When scaling by an integer, snapping is not needed } else { // In all other cases we should try to snap now - SnapManager const &m = _desktop->namedview->snap_manager; + SnapManager &m = _desktop->namedview->snap_manager; + m.setup(NULL, _items_const); Inkscape::SnappedPoint bb, sn; NR::Coord bd(NR_HUGE); @@ -936,8 +937,8 @@ gboolean Inkscape::SelTrans::scaleRequest(NR::Point &pt, guint state) } // Snap along a suitable constraint vector from the origin. - bb = m.constrainedSnapScale(Snapper::SNAPPOINT_BBOX, _bbox_points, _items_const, default_scale, _origin_for_bboxpoints); - sn = m.constrainedSnapScale(Snapper::SNAPPOINT_NODE, _snap_points, _items_const, geom_scale, _origin_for_specpoints); + bb = m.constrainedSnapScale(Snapper::SNAPPOINT_BBOX, _bbox_points, default_scale, _origin_for_bboxpoints); + sn = m.constrainedSnapScale(Snapper::SNAPPOINT_NODE, _snap_points, geom_scale, _origin_for_specpoints); /* Choose the smaller difference in scale. Since s[X] == s[Y] we can ** just compare difference in s[X]. @@ -946,8 +947,8 @@ gboolean Inkscape::SelTrans::scaleRequest(NR::Point &pt, guint state) sd = sn.getSnapped() ? fabs(sn.getTransformation()[NR::X] - geom_scale[NR::X]) : NR_HUGE; } else { /* Scale aspect ratio is unlocked */ - bb = m.freeSnapScale(Snapper::SNAPPOINT_BBOX, _bbox_points, _items_const, default_scale, _origin_for_bboxpoints); - sn = m.freeSnapScale(Snapper::SNAPPOINT_NODE, _snap_points, _items_const, geom_scale, _origin_for_specpoints); + bb = m.freeSnapScale(Snapper::SNAPPOINT_BBOX, _bbox_points, default_scale, _origin_for_bboxpoints); + sn = m.freeSnapScale(Snapper::SNAPPOINT_NODE, _snap_points, geom_scale, _origin_for_specpoints); /* Pick the snap that puts us closest to the original scale */ bd = bb.getSnapped() ? fabs(NR::L2(bb.getTransformation()) - NR::L2(default_scale.point())) : NR_HUGE; @@ -957,6 +958,7 @@ gboolean Inkscape::SelTrans::scaleRequest(NR::Point &pt, guint state) if (!(bb.getSnapped() || sn.getSnapped())) { // We didn't snap at all! Don't update the handle position, just calculate the new transformation _calcAbsAffineDefault(default_scale); + _desktop->snapindicator->remove_snappoint(); } else if (bd < sd) { // We snapped the bbox (which is either visual or geometric) _desktop->snapindicator->set_new_snappoint(bb); @@ -1024,7 +1026,8 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, NR:: } else { // In all other cases we should try to snap now - SnapManager const &m = _desktop->namedview->snap_manager; + SnapManager &m = _desktop->namedview->snap_manager; + m.setup(NULL, _items_const); Inkscape::SnappedPoint bb, sn; g_assert(bb.getSnapped() == false); // Check initialization to catch any regression @@ -1033,8 +1036,8 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, NR:: bool symmetrical = state & GDK_CONTROL_MASK; - bb = m.constrainedSnapStretch(Snapper::SNAPPOINT_BBOX, _bbox_points, _items_const, default_scale[axis], _origin_for_bboxpoints, axis, symmetrical); - sn = m.constrainedSnapStretch(Snapper::SNAPPOINT_NODE, _snap_points, _items_const, geom_scale[axis], _origin_for_specpoints, axis, symmetrical); + bb = m.constrainedSnapStretch(Snapper::SNAPPOINT_BBOX, _bbox_points, default_scale[axis], _origin_for_bboxpoints, axis, symmetrical); + sn = m.constrainedSnapStretch(Snapper::SNAPPOINT_NODE, _snap_points, geom_scale[axis], _origin_for_specpoints, axis, symmetrical); if (bb.getSnapped()) { // We snapped the bbox (which is either visual or geometric) @@ -1057,6 +1060,7 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, NR:: if (!(bb.getSnapped() || sn.getSnapped())) { // We didn't snap at all! Don't update the handle position, just calculate the new transformation _calcAbsAffineDefault(default_scale); + _desktop->snapindicator->remove_snappoint(); } else if (bd < sd) { _desktop->snapindicator->set_new_snappoint(bb); // Calculate the new transformation and update the handle position @@ -1143,12 +1147,13 @@ gboolean Inkscape::SelTrans::skewRequest(SPSelTransHandle const &handle, NR::Poi } else { // Snap to objects, grids, guides - SnapManager const &m = _desktop->namedview->snap_manager; + SnapManager &m = _desktop->namedview->snap_manager; + m.setup(NULL, _items_const); //TODO: While skewing, scaling in the opposite direction by integer multiples is also allowed. This is not handled though by freeSnapSkew / _snapTransformed yet! //TODO: We need a constrainedSnapSkew instead of a freeSnapSkew - Inkscape::SnappedPoint bb = m.freeSnapSkew(Inkscape::Snapper::SNAPPOINT_BBOX, _bbox_points, _items_const, skew[dim_a], _origin, dim_b); - Inkscape::SnappedPoint sn = m.freeSnapSkew(Inkscape::Snapper::SNAPPOINT_NODE, _snap_points, _items_const, skew[dim_a], _origin, dim_b); + Inkscape::SnappedPoint bb = m.freeSnapSkew(Inkscape::Snapper::SNAPPOINT_BBOX, _bbox_points, skew[dim_a], _origin, dim_b); + Inkscape::SnappedPoint sn = m.freeSnapSkew(Inkscape::Snapper::SNAPPOINT_NODE, _snap_points, skew[dim_a], _origin, dim_b); if (bb.getSnapped() || sn.getSnapped()) { // We snapped something, so change the skew to reflect it @@ -1161,7 +1166,9 @@ gboolean Inkscape::SelTrans::skewRequest(SPSelTransHandle const &handle, NR::Poi _desktop->snapindicator->set_new_snappoint(sn); skew[dim_a] = sd; } - } + } else { + _desktop->snapindicator->remove_snappoint(); + } } // Update the handle position @@ -1252,8 +1259,9 @@ gboolean Inkscape::SelTrans::rotateRequest(NR::Point &pt, guint state) gboolean Inkscape::SelTrans::centerRequest(NR::Point &pt, guint state) { - SnapManager const &m = _desktop->namedview->snap_manager; - pt = m.freeSnap(Snapper::SNAPPOINT_NODE, pt, NULL).getPoint(); + SnapManager &m = _desktop->namedview->snap_manager; + m.setup(_desktop); + pt = m.freeSnap(Snapper::SNAPPOINT_NODE, pt).getPoint(); if (state & GDK_CONTROL_MASK) { if ( fabs(_point[NR::X] - pt[NR::X]) > fabs(_point[NR::Y] - pt[NR::Y]) ) { @@ -1345,7 +1353,8 @@ void sp_sel_trans_center(Inkscape::SelTrans *seltrans, SPSelTransHandle const &, void Inkscape::SelTrans::moveTo(NR::Point const &xy, guint state) { - SnapManager const &m = _desktop->namedview->snap_manager; + SnapManager &m = _desktop->namedview->snap_manager; + m.setup(_desktop, _items_const); /* The amount that we've moved by during this drag */ NR::Point dxy = xy - _point; @@ -1360,7 +1369,7 @@ void Inkscape::SelTrans::moveTo(NR::Point const &xy, guint state) ** FIXME: this will snap to more than just the grid, nowadays. */ - dxy = m.freeSnap(Snapper::SNAPPOINT_NODE, dxy, NULL).getPoint(); + dxy = m.freeSnap(Snapper::SNAPPOINT_NODE, dxy).getPoint(); } else if (!shift) { @@ -1379,13 +1388,11 @@ void Inkscape::SelTrans::moveTo(NR::Point const &xy, guint state) for (unsigned int dim = 0; dim < 2; dim++) { s.push_back(m.constrainedSnapTranslation(Inkscape::Snapper::SNAPPOINT_BBOX, _bbox_points, - _items_const, Inkscape::Snapper::ConstraintLine(component_vectors[dim]), dxy)); s.push_back(m.constrainedSnapTranslation(Inkscape::Snapper::SNAPPOINT_NODE, _snap_points, - _items_const, Inkscape::Snapper::ConstraintLine(component_vectors[dim]), dxy)); } @@ -1398,10 +1405,8 @@ void Inkscape::SelTrans::moveTo(NR::Point const &xy, guint state) g_get_current_time(&starttime); */ /* Snap to things with no constraint */ - s.push_back(m.freeSnapTranslation(Inkscape::Snapper::SNAPPOINT_BBOX, - _bbox_points, _items_const, dxy)); - s.push_back(m.freeSnapTranslation(Inkscape::Snapper::SNAPPOINT_NODE, - _snap_points, _items_const, dxy)); + s.push_back(m.freeSnapTranslation(Inkscape::Snapper::SNAPPOINT_BBOX, _bbox_points, dxy)); + s.push_back(m.freeSnapTranslation(Inkscape::Snapper::SNAPPOINT_NODE, _snap_points, dxy)); /*g_get_current_time(&endtime); double elapsed = ((((double)endtime.tv_sec - starttime.tv_sec) * G_USEC_PER_SEC + (endtime.tv_usec - starttime.tv_usec))) / 1000.0; @@ -1424,6 +1429,8 @@ void Inkscape::SelTrans::moveTo(NR::Point const &xy, guint state) } if (best_snapped_point.getSnapped()) { _desktop->snapindicator->set_new_snappoint(best_snapped_point); + } else { + _desktop->snapindicator->remove_snappoint(); } } diff --git a/src/snap.cpp b/src/snap.cpp index 2d23a7745..c9944cb04 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -29,6 +29,7 @@ #include #include "display/canvas-grid.h" +#include "display/snap-indicator.h" #include "inkscape.h" #include "desktop.h" @@ -167,153 +168,92 @@ bool SnapManager::getSnapModeGuide() const return object.getSnapFrom(Inkscape::Snapper::SNAPPOINT_GUIDE); } -/** - * Try to snap a point to any interested snappers. - * - * \param t Type of point. - * \param p Point. - * \param it Item to ignore when snapping. - * \return Snapped point. - */ - -Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::Snapper::PointType t, - NR::Point const &p, - SPItem const *it, - NR::Maybe point_not_to_snap_to) const - -{ - std::vector lit; - if (it) { - lit.push_back(it); - } - - std::vector points_to_snap; - points_to_snap.push_back(p); - - return freeSnap(t, p, true, points_to_snap, lit, NULL); -} - -/** - * Try to snap a point to any interested snappers. - * - * \param t Type of point. - * \param p Point. - * \param it Item to ignore when snapping. - * \return Snapped point. - */ - -Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::Snapper::PointType t, - NR::Point const &p, - SPItem const *it, - std::vector *unselected_nodes) const - -{ - std::vector lit; - if (it) { - lit.push_back(it); - } - - std::vector points_to_snap; - points_to_snap.push_back(p); - - return freeSnap(t, p, true, points_to_snap, lit, unselected_nodes); -} - - /** * Try to snap a point to any of the specified snappers. * - * \param t Type of point. + * \param point_type Type of point. * \param p Point. * \param first_point If true then this point is the first one from a whole bunch of points * \param points_to_snap The whole bunch of points, all from the same selection and having the same transformation - * \param it List of items to ignore when snapping. - * \param snappers List of snappers to try to snap to + * \param snappers List of snappers to try to snap to * \return Snapped point. */ -Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::Snapper::PointType t, +Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::Snapper::PointType point_type, NR::Point const &p, - bool const &first_point, - std::vector &points_to_snap, - std::vector const &it, - std::vector *unselected_nodes) const + bool first_point, + NR::Maybe const &bbox_to_snap) const { if (!SomeSnapperMightSnap()) { return Inkscape::SnappedPoint(p, NR_HUGE, 0, false); } - SnappedConstraints sc; + std::vector *items_to_ignore; + if (_item_to_ignore) { // If we have only a single item to ignore + // then build a list containing this single item; + // This single-item list will prevail over any other _items_to_ignore list, should that exist + items_to_ignore = new std::vector; + items_to_ignore->push_back(_item_to_ignore); + } else { + items_to_ignore = _items_to_ignore; + } + SnappedConstraints sc; SnapperList const snappers = getSnappers(); - + for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) { - (*i)->freeSnap(sc, t, p, first_point, points_to_snap, it, unselected_nodes); - } - - return findBestSnap(p, sc, false); -} - -/** - * Try to snap a point to any interested snappers. A snap will only occur along - * a line described by a Inkscape::Snapper::ConstraintLine. - * - * \param t Type of point. - * \param p Point. - * \param c Constraint line. - * \param it Item to ignore when snapping. - * \return Snapped point. - */ - -Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::Snapper::PointType t, - NR::Point const &p, - Inkscape::Snapper::ConstraintLine const &c, - SPItem const *it) const -{ - std::vector lit; - if (it) { - lit.push_back(it); + (*i)->freeSnap(sc, point_type, p, first_point, bbox_to_snap, items_to_ignore, _unselected_nodes); } - std::vector points_to_snap; - points_to_snap.push_back(p); + if (_item_to_ignore) { + delete items_to_ignore; + } - return constrainedSnap(t, p, true, points_to_snap, c, lit); + return findBestSnap(p, sc, false); } - - /** * Try to snap a point to any interested snappers. A snap will only occur along * a line described by a Inkscape::Snapper::ConstraintLine. * - * \param t Type of point. + * \param point_type Type of point. * \param p Point. * \param first_point If true then this point is the first one from a whole bunch of points * \param points_to_snap The whole bunch of points, all from the same selection and having the same transformation - * \param c Constraint line. - * \param it List of items to ignore when snapping. + * \param constraint Constraint line. * \return Snapped point. */ -Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::Snapper::PointType t, +Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::Snapper::PointType point_type, NR::Point const &p, - bool const &first_point, - std::vector &points_to_snap, - Inkscape::Snapper::ConstraintLine const &c, - std::vector const &it) const + Inkscape::Snapper::ConstraintLine const &constraint, + bool first_point, + NR::Maybe const &bbox_to_snap) const { if (!SomeSnapperMightSnap()) { return Inkscape::SnappedPoint(p, NR_HUGE, 0, false); } - SnappedConstraints sc; - + std::vector *items_to_ignore; + if (_item_to_ignore) { // If we have only a single item to ignore + // then build a list containing this single item; + // This single-item list will prevail over any other _items_to_ignore list, should that exist + items_to_ignore = new std::vector; + items_to_ignore->push_back(_item_to_ignore); + } else { + items_to_ignore = _items_to_ignore; + } + + SnappedConstraints sc; SnapperList const snappers = getSnappers(); for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) { - (*i)->constrainedSnap(sc, t, p, first_point, points_to_snap, c, it); + (*i)->constrainedSnap(sc, point_type, p, first_point, bbox_to_snap, constraint, items_to_ignore); } - + + if (_item_to_ignore) { + delete items_to_ignore; + } + return findBestSnap(p, sc, true); } @@ -340,7 +280,6 @@ Inkscape::SnappedPoint SnapManager::guideSnap(NR::Point const &p, * * \param type Type of points being snapped. * \param points List of points to snap. - * \param ignore List of items to ignore while snapping. * \param constrained true if the snap is constrained. * \param constraint Constraint line to use, if `constrained' is true, otherwise undefined. * \param transformation_type Type of transformation to apply to points before trying to snap them. @@ -353,7 +292,6 @@ Inkscape::SnappedPoint SnapManager::guideSnap(NR::Point const &p, Inkscape::SnappedPoint SnapManager::_snapTransformed( Inkscape::Snapper::PointType type, std::vector const &points, - std::vector const &ignore, bool constrained, Inkscape::Snapper::ConstraintLine const &constraint, Transformation transformation_type, @@ -375,6 +313,7 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( } std::vector transformed_points; + NR::Rect bbox; for (std::vector::const_iterator i = points.begin(); i != points.end(); i++) { @@ -408,6 +347,12 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( } // add the current transformed point to the box hulling all transformed points + if (i == points.begin()) { + bbox = NR::Rect(transformed, transformed); + } else { + bbox.expandTo(transformed); + } + transformed_points.push_back(transformed); } @@ -445,9 +390,9 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( if (transformation_type == SCALE && !uniform) { g_warning("Non-uniform constrained scaling is not supported!"); } - snapped_point = constrainedSnap(type, *j, i == points.begin(), transformed_points, dedicated_constraint, ignore); + snapped_point = constrainedSnap(type, *j, dedicated_constraint, i == points.begin(), bbox); } else { - snapped_point = freeSnap(type, *j, i == points.begin(), transformed_points, ignore, NULL); + snapped_point = freeSnap(type, *j, i == points.begin(), bbox); } NR::Point result; @@ -590,19 +535,17 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( * Try to snap a list of points to any interested snappers after they have undergone * a translation. * - * \param t Type of points. + * \param point_type Type of points. * \param p Points. - * \param it List of items to ignore when snapping. * \param tr Proposed translation. * \return Snapped translation, if a snap occurred, and a flag indicating whether a snap occurred. */ -Inkscape::SnappedPoint SnapManager::freeSnapTranslation(Inkscape::Snapper::PointType t, +Inkscape::SnappedPoint SnapManager::freeSnapTranslation(Inkscape::Snapper::PointType point_type, std::vector const &p, - std::vector const &it, NR::Point const &tr) const { - return _snapTransformed(t, p, it, false, NR::Point(), TRANSLATION, tr, NR::Point(), NR::X, false); + return _snapTransformed(point_type, p, false, NR::Point(), TRANSLATION, tr, NR::Point(), NR::X, false); } @@ -611,21 +554,19 @@ Inkscape::SnappedPoint SnapManager::freeSnapTranslation(Inkscape::Snapper::Point * translation. A snap will only occur along a line described by a * Inkscape::Snapper::ConstraintLine. * - * \param t Type of points. + * \param point_type Type of points. * \param p Points. - * \param it List of items to ignore when snapping. - * \param c Constraint line. + * \param constraint Constraint line. * \param tr Proposed translation. * \return Snapped translation, if a snap occurred, and a flag indicating whether a snap occurred. */ -Inkscape::SnappedPoint SnapManager::constrainedSnapTranslation(Inkscape::Snapper::PointType t, +Inkscape::SnappedPoint SnapManager::constrainedSnapTranslation(Inkscape::Snapper::PointType point_type, std::vector const &p, - std::vector const &it, - Inkscape::Snapper::ConstraintLine const &c, + Inkscape::Snapper::ConstraintLine const &constraint, NR::Point const &tr) const { - return _snapTransformed(t, p, it, true, c, TRANSLATION, tr, NR::Point(), NR::X, false); + return _snapTransformed(point_type, p, true, constraint, TRANSLATION, tr, NR::Point(), NR::X, false); } @@ -633,21 +574,19 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapTranslation(Inkscape::Snapper * Try to snap a list of points to any interested snappers after they have undergone * a scale. * - * \param t Type of points. + * \param point_type Type of points. * \param p Points. - * \param it List of items to ignore when snapping. * \param s Proposed scale. * \param o Origin of proposed scale. * \return Snapped scale, if a snap occurred, and a flag indicating whether a snap occurred. */ -Inkscape::SnappedPoint SnapManager::freeSnapScale(Inkscape::Snapper::PointType t, +Inkscape::SnappedPoint SnapManager::freeSnapScale(Inkscape::Snapper::PointType point_type, std::vector const &p, - std::vector const &it, NR::scale const &s, NR::Point const &o) const { - return _snapTransformed(t, p, it, false, NR::Point(), SCALE, NR::Point(s[NR::X], s[NR::Y]), o, NR::X, false); + return _snapTransformed(point_type, p, false, NR::Point(), SCALE, NR::Point(s[NR::X], s[NR::Y]), o, NR::X, false); } @@ -656,22 +595,20 @@ Inkscape::SnappedPoint SnapManager::freeSnapScale(Inkscape::Snapper::PointType t * a scale. A snap will only occur along a line described by a * Inkscape::Snapper::ConstraintLine. * - * \param t Type of points. + * \param point_type Type of points. * \param p Points. - * \param it List of items to ignore when snapping. * \param s Proposed scale. * \param o Origin of proposed scale. * \return Snapped scale, if a snap occurred, and a flag indicating whether a snap occurred. */ -Inkscape::SnappedPoint SnapManager::constrainedSnapScale(Inkscape::Snapper::PointType t, +Inkscape::SnappedPoint SnapManager::constrainedSnapScale(Inkscape::Snapper::PointType point_type, std::vector const &p, - std::vector const &it, NR::scale const &s, NR::Point const &o) const { // When constrained scaling, only uniform scaling is supported. - return _snapTransformed(t, p, it, true, NR::Point(), SCALE, NR::Point(s[NR::X], s[NR::Y]), o, NR::X, true); + return _snapTransformed(point_type, p, true, NR::Point(), SCALE, NR::Point(s[NR::X], s[NR::Y]), o, NR::X, true); } @@ -679,9 +616,8 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapScale(Inkscape::Snapper::Poin * Try to snap a list of points to any interested snappers after they have undergone * a stretch. * - * \param t Type of points. + * \param point_type Type of points. * \param p Points. - * \param it List of items to ignore when snapping. * \param s Proposed stretch. * \param o Origin of proposed stretch. * \param d Dimension in which to apply proposed stretch. @@ -689,15 +625,14 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapScale(Inkscape::Snapper::Poin * \return Snapped stretch, if a snap occurred, and a flag indicating whether a snap occurred. */ -Inkscape::SnappedPoint SnapManager::constrainedSnapStretch(Inkscape::Snapper::PointType t, +Inkscape::SnappedPoint SnapManager::constrainedSnapStretch(Inkscape::Snapper::PointType point_type, std::vector const &p, - std::vector const &it, NR::Coord const &s, NR::Point const &o, NR::Dim2 d, bool u) const { - return _snapTransformed(t, p, it, true, NR::Point(), STRETCH, NR::Point(s, s), o, d, u); + return _snapTransformed(point_type, p, true, NR::Point(), STRETCH, NR::Point(s, s), o, d, u); } @@ -705,23 +640,21 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapStretch(Inkscape::Snapper::Po * Try to snap a list of points to any interested snappers after they have undergone * a skew. * - * \param t Type of points. + * \param point_type Type of points. * \param p Points. - * \param it List of items to ignore when snapping. * \param s Proposed skew. * \param o Origin of proposed skew. * \param d Dimension in which to apply proposed skew. * \return Snapped skew, if a snap occurred, and a flag indicating whether a snap occurred. */ -Inkscape::SnappedPoint SnapManager::freeSnapSkew(Inkscape::Snapper::PointType t, +Inkscape::SnappedPoint SnapManager::freeSnapSkew(Inkscape::Snapper::PointType point_type, std::vector const &p, - std::vector const &it, NR::Coord const &s, NR::Point const &o, NR::Dim2 d) const { - return _snapTransformed(t, p, it, false, NR::Point(), SKEW, NR::Point(s, s), o, d, false); + return _snapTransformed(point_type, p, false, NR::Point(), SKEW, NR::Point(s, s), o, d, false); } Inkscape::SnappedPoint SnapManager::findBestSnap(NR::Point const &p, SnappedConstraints &sc, bool constrained) const @@ -821,9 +754,35 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(NR::Point const &p, SnappedCons } } + + // Update the snap indicator, if requested + if (_desktop_for_snapindicator) { + if (bestSnappedPoint.getSnapped()) { + _desktop_for_snapindicator->snapindicator->set_new_snappoint(bestSnappedPoint); + } else { + _desktop_for_snapindicator->snapindicator->remove_snappoint(); + } + } + return bestSnappedPoint; } +void SnapManager::setup(SPDesktop const *desktop_for_snapindicator, SPItem const *item_to_ignore, std::vector *unselected_nodes) +{ + _item_to_ignore = item_to_ignore; + _items_to_ignore = NULL; + _desktop_for_snapindicator = desktop_for_snapindicator; + _unselected_nodes = unselected_nodes; +} + +void SnapManager::setup(SPDesktop const *desktop_for_snapindicator, std::vector &items_to_ignore, std::vector *unselected_nodes) +{ + _item_to_ignore = NULL; + _items_to_ignore = &items_to_ignore; + _desktop_for_snapindicator = desktop_for_snapindicator; + _unselected_nodes = unselected_nodes; +} + /* Local Variables: mode:c++ diff --git a/src/snap.h b/src/snap.h index 0de8902f4..f11b7c743 100644 --- a/src/snap.h +++ b/src/snap.h @@ -46,79 +46,58 @@ public: typedef std::list SnapperList; bool SomeSnapperMightSnap() const; - - Inkscape::SnappedPoint freeSnap(Inkscape::Snapper::PointType t, - NR::Point const &p, - SPItem const *it, - NR::Maybe point_not_to_snap_to = NR::Nothing()) const; - - Inkscape::SnappedPoint freeSnap(Inkscape::Snapper::PointType t, - NR::Point const &p, - SPItem const *it, - std::vector *unselected_nodes) const; - Inkscape::SnappedPoint freeSnap(Inkscape::Snapper::PointType t, + void setup(SPDesktop const *desktop_for_snapindicator = NULL, SPItem const *item_to_ignore = NULL, std::vector *unselected_nodes = NULL); + void setup(SPDesktop const *desktop_for_snapindicator, std::vector &items_to_ignore, std::vector *unselected_nodes = NULL); + + Inkscape::SnappedPoint freeSnap(Inkscape::Snapper::PointType point_type, NR::Point const &p, - bool const &first_point, - std::vector &points_to_snap, - std::vector const &it, - std::vector *unselected_nodes) const; + bool first_point = true, + NR::Maybe const &bbox_to_snap = NR::Nothing()) const; - Inkscape::SnappedPoint constrainedSnap(Inkscape::Snapper::PointType t, + Inkscape::SnappedPoint constrainedSnap(Inkscape::Snapper::PointType point_type, NR::Point const &p, - Inkscape::Snapper::ConstraintLine const &c, - SPItem const *it) const; - - Inkscape::SnappedPoint constrainedSnap(Inkscape::Snapper::PointType t, - NR::Point const &p, - bool const &first_point, - std::vector &points_to_snap, - Inkscape::Snapper::ConstraintLine const &c, - std::vector const &it) const; + Inkscape::Snapper::ConstraintLine const &constraint, + bool first_point = true, + NR::Maybe const &bbox_to_snap = NR::Nothing()) const; Inkscape::SnappedPoint guideSnap(NR::Point const &p, NR::Point const &guide_normal) const; - Inkscape::SnappedPoint freeSnapTranslation(Inkscape::Snapper::PointType t, + Inkscape::SnappedPoint freeSnapTranslation(Inkscape::Snapper::PointType point_type, std::vector const &p, - std::vector const &it, NR::Point const &tr) const; - Inkscape::SnappedPoint constrainedSnapTranslation(Inkscape::Snapper::PointType t, + Inkscape::SnappedPoint constrainedSnapTranslation(Inkscape::Snapper::PointType point_type, std::vector const &p, - std::vector const &it, - Inkscape::Snapper::ConstraintLine const &c, + Inkscape::Snapper::ConstraintLine const &constraint, NR::Point const &tr) const; - Inkscape::SnappedPoint freeSnapScale(Inkscape::Snapper::PointType t, + Inkscape::SnappedPoint freeSnapScale(Inkscape::Snapper::PointType point_type, std::vector const &p, - std::vector const &it, NR::scale const &s, NR::Point const &o) const; - Inkscape::SnappedPoint constrainedSnapScale(Inkscape::Snapper::PointType t, + Inkscape::SnappedPoint constrainedSnapScale(Inkscape::Snapper::PointType point_type, std::vector const &p, - std::vector const &it, NR::scale const &s, NR::Point const &o) const; - Inkscape::SnappedPoint constrainedSnapStretch(Inkscape::Snapper::PointType t, + Inkscape::SnappedPoint constrainedSnapStretch(Inkscape::Snapper::PointType point_type, std::vector const &p, - std::vector const &it, NR::Coord const &s, NR::Point const &o, NR::Dim2 d, bool uniform) const; - Inkscape::SnappedPoint freeSnapSkew(Inkscape::Snapper::PointType t, + Inkscape::SnappedPoint freeSnapSkew(Inkscape::Snapper::PointType point_type, std::vector const &p, - std::vector const &it, NR::Coord const &s, NR::Point const &o, NR::Dim2 d) const; - Inkscape::SnappedPoint guideSnap(NR::Point const &p, - Inkscape::ObjectSnapper::DimensionToSnap const snap_dim) const; + //Inkscape::SnappedPoint guideSnap(NR::Point const &p, + // Inkscape::ObjectSnapper::DimensionToSnap const snap_dim) const; Inkscape::GuideSnapper guide; ///< guide snapper @@ -136,8 +115,8 @@ public: void setSnapIntersectionGG(bool enabled) {_intersectionGG = enabled;} void setSnapIntersectionLS(bool enabled) {_intersectionLS = enabled;} - bool getSnapIntersectionGG() { return _intersectionGG;} - bool getSnapIntersectionLS() { return _intersectionLS;} + bool getSnapIntersectionGG() {return _intersectionGG;} + bool getSnapIntersectionLS() {return _intersectionLS;} void setIncludeItemCenter(bool enabled) { _include_item_center = enabled; @@ -178,9 +157,13 @@ private: bool _intersectionLS; bool _snap_enabled_globally; //Toggles ALL snapping + std::vector *_items_to_ignore; + SPItem const *_item_to_ignore; + SPDesktop const *_desktop_for_snapindicator; + std::vector *_unselected_nodes; + Inkscape::SnappedPoint _snapTransformed(Inkscape::Snapper::PointType type, std::vector const &points, - std::vector const &ignore, bool constrained, Inkscape::Snapper::ConstraintLine const &constraint, Transformation transformation_type, diff --git a/src/snapper.cpp b/src/snapper.cpp index 803506e76..4dfb9042e 100644 --- a/src/snapper.cpp +++ b/src/snapper.cpp @@ -85,115 +85,6 @@ void Inkscape::Snapper::setEnabled(bool s) _snap_enabled = s; } - -/** - * Try to snap a point to whatever this snapper is interested in. Any - * snap that occurs will be to the nearest "interesting" thing (e.g. a - * grid or guide line) - * - * \param t Point type. - * \param p Point to snap (desktop coordinates). - * \param it Item that should not be snapped to. - * \return Snapped point. - */ - -void Inkscape::Snapper::freeSnap(SnappedConstraints &sc, - PointType const &t, - NR::Point const &p, - bool const &first_point, - std::vector &points_to_snap, - SPItem const *it) const -{ - std::vector lit; - if (it) { - lit.push_back(it); - } - - freeSnap(sc, t, p, first_point, points_to_snap, lit, NULL); -} - -/** - * Try to snap a point to whatever this snapper is interested in. Any - * snap that occurs will be to the nearest "interesting" thing (e.g. a - * grid or guide line) - * - * \param t Point type. - * \param p Point to snap (desktop coordinates). - * \param it Items that should not be snapped to. - * \return Snapped point. - */ - -void Inkscape::Snapper::freeSnap(SnappedConstraints &sc, - PointType const &t, - NR::Point const &p, - bool const &first_point, - std::vector &points_to_snap, - std::vector const &it, - std::vector *unselected_nodes) const -{ - if (_snap_enabled == false || getSnapFrom(t) == false) { - return; - } - - _doFreeSnap(sc, t, p, first_point, points_to_snap, it, unselected_nodes); -} - - - - -/** - * Try to snap a point to whatever this snapper is interested in, where - * the snap point is constrained to lie along a specified vector from the - * original point. - * - * \param p Point to snap (desktop coordinates). - * \param c Vector to constrain the snap to. - * \param it Items that should not be snapped to. - * \return Snapped point. - */ - -void Inkscape::Snapper::constrainedSnap(SnappedConstraints &sc, - PointType const &t, - NR::Point const &p, - bool const &first_point, - std::vector &points_to_snap, - ConstraintLine const &c, - SPItem const *it) const -{ - std::vector lit; - if (it) { - lit.push_back(it); - } - constrainedSnap(sc, t, p, first_point, points_to_snap, c, lit); -} - - -/** - * Try to snap a point to whatever this snapper is interested in, where - * the snap point is constrained to lie along a specified vector from the - * original point. - * - * \param p Point to snap (desktop coordinates). - * \param c Vector to constrain the snap to. - * \param it Items that should not be snapped to. - * \return Snapped point. - */ - -void Inkscape::Snapper::constrainedSnap(SnappedConstraints &sc, - PointType const &t, - NR::Point const &p, - bool const &first_point, - std::vector &points_to_snap, - ConstraintLine const &c, - std::vector const &it) const -{ - if (_snap_enabled == false || getSnapFrom(t) == false) { - return; - } - - _doConstrainedSnap(sc, t, p, first_point, points_to_snap, c, it); -} - /* Local Variables: mode:c++ diff --git a/src/snapper.h b/src/snapper.h index cad4200ab..533a39090 100644 --- a/src/snapper.h +++ b/src/snapper.h @@ -63,20 +63,13 @@ public: void setEnabled(bool s); bool getEnabled() const {return _snap_enabled;} - void freeSnap(SnappedConstraints &sc, + virtual void freeSnap(SnappedConstraints &sc, PointType const &t, NR::Point const &p, bool const &first_point, - std::vector &points_to_snap, - SPItem const *it) const; - - void freeSnap(SnappedConstraints &sc, - PointType const &t, - NR::Point const &p, - bool const &first_point, - std::vector &points_to_snap, - std::vector const &it, - std::vector *unselected_nodes) const; + NR::Maybe const &bbox_to_snap, + std::vector const *it, + std::vector *unselected_nodes) const {}; class ConstraintLine { @@ -103,21 +96,13 @@ public: NR::Point _direction; }; - void constrainedSnap(SnappedConstraints &sc, - PointType const &t, - NR::Point const &p, - bool const &first_point, - std::vector &points_to_snap, - ConstraintLine const &c, - SPItem const *it) const; - - void constrainedSnap(SnappedConstraints &sc, + virtual void constrainedSnap(SnappedConstraints &sc, PointType const &t, NR::Point const &p, bool const &first_point, - std::vector &points_to_snap, + NR::Maybe const &bbox_to_snap, ConstraintLine const &c, - std::vector const &it) const; + std::vector const *it) const {}; protected: SPNamedView const *_named_view; @@ -129,41 +114,6 @@ private: // must be private to enforce the usage of getTolerance(), which retrieves // the tolerance in screen pixels (making it zoom independent) - - /** - * Try to snap a point to whatever this snapper is interested in. Any - * snap that occurs will be to the nearest "interesting" thing (e.g. a - * grid or guide line) - * - * \param p Point to snap (desktop coordinates). - * \param it Items that should not be snapped to. - * \return Snapped point. - */ - virtual void _doFreeSnap(SnappedConstraints &sc, - PointType const &t, - NR::Point const &p, - bool const &first_point, - std::vector &points_to_snap, - std::vector const &it, - std::vector *unselected_nodes) const = 0; - - /** - * Try to snap a point to whatever this snapper is interested in, where - * the snap point is constrained to lie along a specified vector from the - * original point. - * - * \param p Point to snap (desktop coordinates). - * \param c Vector to constrain the snap to. - * \param it Items that should not be snapped to. - * \return Snapped point. - */ - virtual void _doConstrainedSnap(SnappedConstraints &sc, - PointType const &t, - NR::Point const &p, - bool const &first_point, - std::vector &points_to_snap, - ConstraintLine const &c, - std::vector const &it) const = 0; }; } diff --git a/src/spiral-context.cpp b/src/spiral-context.cpp index d0404c3d0..a4c402f40 100644 --- a/src/spiral-context.cpp +++ b/src/spiral-context.cpp @@ -265,8 +265,9 @@ sp_spiral_context_root_handler(SPEventContext *event_context, GdkEvent *event) dragging = TRUE; sc->center = Inkscape::setup_for_drag_start(desktop, event_context, event); - SnapManager const &m = desktop->namedview->snap_manager; - sc->center = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, sc->center, sc->item).getPoint(); + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop, sc->item); + sc->center = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, sc->center).getPoint(); sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate), ( GDK_KEY_PRESS_MASK | @@ -293,8 +294,9 @@ sp_spiral_context_root_handler(SPEventContext *event_context, GdkEvent *event) NR::Point const motion_w(event->motion.x, event->motion.y); NR::Point motion_dt(event_context->desktop->w2d(motion_w)); - SnapManager const &m = desktop->namedview->snap_manager; - motion_dt = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, motion_dt, sc->item).getPoint(); + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop, sc->item); + motion_dt = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, motion_dt).getPoint(); sp_spiral_drag(sc, motion_dt, event->motion.state); gobble_motion_events(GDK_BUTTON1_MASK); @@ -436,8 +438,9 @@ sp_spiral_drag(SPSpiralContext *sc, NR::Point p, guint state) NR::Point const p0 = sp_desktop_dt2root_xy_point(desktop, sc->center); NR::Point p1 = sp_desktop_dt2root_xy_point(desktop, p); - SnapManager const &m = desktop->namedview->snap_manager; - p1 = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, p1, sc->item).getPoint(); + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop, sc->item); + p1 = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, p1).getPoint(); SPSpiral *spiral = SP_SPIRAL(sc->item); diff --git a/src/star-context.cpp b/src/star-context.cpp index cee03b4b1..816e6b779 100644 --- a/src/star-context.cpp +++ b/src/star-context.cpp @@ -280,8 +280,9 @@ static gint sp_star_context_root_handler(SPEventContext *event_context, GdkEvent sc->center = Inkscape::setup_for_drag_start(desktop, event_context, event); - SnapManager const &m = desktop->namedview->snap_manager; - sc->center = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, sc->center, sc->item).getPoint(); + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop, sc->item); + sc->center = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, sc->center).getPoint(); sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate), GDK_KEY_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | @@ -306,8 +307,9 @@ static gint sp_star_context_root_handler(SPEventContext *event_context, GdkEvent NR::Point const motion_w(event->motion.x, event->motion.y); NR::Point motion_dt(event_context->desktop->w2d(motion_w)); - SnapManager const &m = desktop->namedview->snap_manager; - motion_dt = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, motion_dt, sc->item).getPoint(); + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop, sc->item); + motion_dt = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, motion_dt).getPoint(); sp_star_drag (sc, motion_dt, event->motion.state); @@ -451,8 +453,9 @@ static void sp_star_drag(SPStarContext *sc, NR::Point p, guint state) NR::Point p1 = sp_desktop_dt2root_xy_point(desktop, p); /* Snap corner point with no constraints */ - SnapManager const &m = desktop->namedview->snap_manager; - p1 = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, p1, sc->item).getPoint(); + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop, sc->item); + p1 = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, p1).getPoint(); SPStar *star = SP_STAR(sc->item);