From 195e5fada891025f6d2f260e915ac209e0c0a5d0 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Thu, 25 Feb 2010 22:54:44 +0100 Subject: [PATCH] 1) Fix moving by an integer multiple of the grid spacing (-dragging in the selector tool) 2) Allow constrained translation for 1) (with ) 3) Fix snapping to the grid when pasting 4) Show snap indicators for all of the above 5) Implement snap delay mechanism for 1) and 2) --- src/display/snap-indicator.cpp | 10 +++++++++- src/seltrans.cpp | 14 +++++++++----- src/snap-enums.h | 3 ++- src/snap.cpp | 18 +++++++++++++----- src/snap.h | 2 +- src/snapped-point.h | 1 + src/ui/clipboard.cpp | 5 +++-- 7 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/display/snap-indicator.cpp b/src/display/snap-indicator.cpp index 25b5090c1..1e4ca12a8 100644 --- a/src/display/snap-indicator.cpp +++ b/src/display/snap-indicator.cpp @@ -208,6 +208,9 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap case SNAPSOURCE_TEXT_BASELINE: source_name = _("Text baseline"); break; + case SNAPSOURCE_GRID_PITCH: + source_name = _("Multiple of grid spacing"); + break; default: g_warning("Snap source has not yet been defined!"); break; @@ -247,7 +250,12 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap _snaptarget_is_presnap = pre_snap; // Display the tooltip, which reveals the type of snap source and the type of snap target - gchar *tooltip_str = g_strconcat(source_name, _(" to "), target_name, NULL); + gchar *tooltip_str = NULL; + if (p.getSource() != SNAPSOURCE_GRID_PITCH) { + tooltip_str = g_strconcat(source_name, _(" to "), target_name, NULL); + } else { + tooltip_str = g_strdup(source_name); + } Geom::Point tooltip_pos = p.getPoint() + _desktop->w2d(Geom::Point(15, -15)); SPCanvasItem *canvas_tooltip = sp_canvastext_new(sp_desktop_tempgroup(_desktop), _desktop, tooltip_pos, tooltip_str); diff --git a/src/seltrans.cpp b/src/seltrans.cpp index 1c601b3ea..7a08e0a7e 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -1439,13 +1439,17 @@ void Inkscape::SelTrans::moveTo(Geom::Point const &xy, guint state) if (alt) { - /* Alt pressed means keep offset: snap the moved distance to the grid. - ** FIXME: this will snap to more than just the grid, nowadays. - */ + // Alt pressed means: move only by integer multiples of the grid spacing + if (control) { // ... if also constrained to the orthogonal axes + if (fabs(dxy[Geom::X]) > fabs(dxy[Geom::Y])) { + dxy[Geom::Y] = 0; + } else { + dxy[Geom::X] = 0; + } + } m.setup(_desktop, true, _items_const); - m.freeSnapReturnByRef(dxy, Inkscape::SNAPSOURCE_UNDEFINED); - + dxy = m.multipleOfGridPitch(dxy, _point); } else if (shift) { if (control) { // shift & control: constrained movement without snapping if (fabs(dxy[Geom::X]) > fabs(dxy[Geom::Y])) { diff --git a/src/snap-enums.h b/src/snap-enums.h index 3d03711e3..cf09ba45b 100644 --- a/src/snap-enums.h +++ b/src/snap-enums.h @@ -75,7 +75,8 @@ enum SnapSourceType { SNAPSOURCE_GUIDE, SNAPSOURCE_GUIDE_ORIGIN, SNAPSOURCE_TEXT_BASELINE, - SNAPSOURCE_OTHER_HANDLE // eg. the handle of a gradient of a connector (ie not being tied to a stroke) + SNAPSOURCE_OTHER_HANDLE, // eg. the handle of a gradient of a connector (ie not being tied to a stroke) + SNAPSOURCE_GRID_PITCH, // eg. when pasting or alt-dragging in the selector tool; not realy a snap source }; } diff --git a/src/snap.cpp b/src/snap.cpp index 53832994f..0df58080e 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -249,15 +249,16 @@ void SnapManager::preSnap(Inkscape::SnapCandidatePoint const &p) * \return Offset vector after snapping to the closest multiple of a grid pitch */ -Geom::Point SnapManager::multipleOfGridPitch(Geom::Point const &t) const +Geom::Point SnapManager::multipleOfGridPitch(Geom::Point const &t, Geom::Point const &origin) { - if (!snapprefs.getSnapEnabledGlobally()) // No need to check for snapprefs.getSnapPostponedGlobally() here + if (!snapprefs.getSnapEnabledGlobally() || snapprefs.getSnapPostponedGlobally()) return t; if (_desktop && _desktop->gridsEnabled()) { bool success = false; Geom::Point nearest_multiple; Geom::Coord nearest_distance = NR_HUGE; + Inkscape::SnappedPoint bestSnappedPoint(t); // It will snap to the grid for which we find the closest snap. This might be a different // grid than to which the objects were initially aligned. I don't see an easy way to fix @@ -276,21 +277,28 @@ Geom::Point SnapManager::multipleOfGridPitch(Geom::Point const &t) const 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::SnapCandidatePoint(t_offset, Inkscape::SNAPSOURCE_UNDEFINED),Geom::OptRect(), NULL, NULL); + snapper->freeSnap(sc, Inkscape::SnapCandidatePoint(t_offset, Inkscape::SNAPSOURCE_GRID_PITCH),Geom::OptRect(), NULL, NULL); // Find the best snap for this grid, including intersections of the grid-lines - Inkscape::SnappedPoint s = findBestSnap(Inkscape::SnapCandidatePoint(t_offset, Inkscape::SNAPSOURCE_UNDEFINED), sc, false); + bool old_val = _snapindicator; + _snapindicator = false; + Inkscape::SnappedPoint s = findBestSnap(Inkscape::SnapCandidatePoint(t_offset, Inkscape::SNAPSOURCE_GRID_PITCH), sc, false); + _snapindicator = old_val; 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 success = true; nearest_multiple = s.getPoint() - to_2geom(grid->origin); nearest_distance = s.getSnapDistance(); + bestSnappedPoint = s; } } } - if (success) + if (success) { + bestSnappedPoint.setPoint(origin + nearest_multiple); + _desktop->snapindicator->set_new_snaptarget(bestSnappedPoint); return nearest_multiple; + } } return t; diff --git a/src/snap.h b/src/snap.h index 613550376..24f62ec6f 100644 --- a/src/snap.h +++ b/src/snap.h @@ -107,7 +107,7 @@ public: void preSnap(Inkscape::SnapCandidatePoint const &p); - Geom::Point multipleOfGridPitch(Geom::Point const &t) const; + Geom::Point multipleOfGridPitch(Geom::Point const &t, Geom::Point const &origin); // constrainedSnapReturnByRef() is preferred over constrainedSnap(), because it only returns a // point, by overwriting p, if snapping has occurred; otherwise p is untouched diff --git a/src/snapped-point.h b/src/snapped-point.h index 33230e212..10d36f57e 100644 --- a/src/snapped-point.h +++ b/src/snapped-point.h @@ -57,6 +57,7 @@ public: * determine itself which point is most appropriate */ Geom::Point getPoint() const {return _point;} + void setPoint(Geom::Point const &p) {_point = p;} bool getAtIntersection() const {return _at_intersection;} bool getFullyConstrained() const {return _fully_constrained;} diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index af0ec0129..f213160f4 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -822,11 +822,12 @@ void ClipboardManagerImpl::_pasteDocument(SPDocument *clipdoc, bool in_place) if (!in_place) { SnapManager &m = desktop->namedview->snap_manager; - m.setup(desktop, false); // Don't display the snapindicator + m.setup(desktop); + sp_event_context_discard_delayed_snap_event(desktop->event_context); // get offset from mouse pointer to bbox center, snap to grid if enabled Geom::Point mouse_offset = desktop->point() - sel_bbox->midpoint(); - offset = m.multipleOfGridPitch(mouse_offset - offset) + offset; + offset = m.multipleOfGridPitch(mouse_offset - offset, sel_bbox->midpoint() + offset) + offset; } sp_selection_move_relative(selection, offset); -- 2.30.2