Code

When snapping to a bounding box, flash that bounding box together with the snap indicator
authorDiederik van Lierop <mailat-signdiedenrezidotnl>
Tue, 19 Jan 2010 20:16:06 +0000 (21:16 +0100)
committerDiederik van Lierop <mailat-signdiedenrezidotnl>
Tue, 19 Jan 2010 20:16:06 +0000 (21:16 +0100)
src/display/snap-indicator.cpp
src/display/snap-indicator.h
src/object-snapper.cpp
src/snap-candidate.h
src/snapped-curve.cpp
src/snapped-curve.h
src/snapped-point.cpp
src/snapped-point.h

index 84bc1709bea9d0ea7c01f962b7180674c055889f..54671cb28b2361f75cfb73608dfb6262b26f73d8 100644 (file)
@@ -16,7 +16,9 @@
 #include "desktop.h"
 #include "desktop-handles.h"
 #include "display/sodipodi-ctrl.h"
+#include "display/sodipodi-ctrlrect.h"
 #include "display/canvas-text.h"
+#include "display/sp-canvas-util.h"
 #include "knot.h"
 #include "preferences.h"
 #include <glibmm/i18n.h>
@@ -27,6 +29,7 @@ namespace Display {
 SnapIndicator::SnapIndicator(SPDesktop * desktop)
     :   _snaptarget(NULL),
         _snaptarget_tooltip(NULL),
+        _snaptarget_bbox(NULL),
         _snapsource(NULL),
         _desktop(desktop)
 {
@@ -216,7 +219,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p)
                                             "anchor", GTK_ANCHOR_CENTER,
                                             "size", 10.0,
                                             "stroked", TRUE,
-                                            "stroke_color", 0xf000f0ff,
+                                            "stroke_color", 0xff0000ff,
                                             "mode", SP_KNOT_MODE_XOR,
                                             "shape", SP_KNOT_SHAPE_DIAMOND,
                                             NULL );
@@ -226,7 +229,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p)
                                             "anchor", GTK_ANCHOR_CENTER,
                                             "size", 10.0,
                                             "stroked", TRUE,
-                                            "stroke_color", 0xf000f0ff,
+                                            "stroke_color", 0xff0000ff,
                                             "mode", SP_KNOT_MODE_XOR,
                                             "shape", SP_KNOT_SHAPE_CROSS,
                                             NULL );
@@ -245,6 +248,19 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p)
 
         sp_canvastext_set_anchor((SPCanvasText* )canvas_tooltip, -1, 1);
         _snaptarget_tooltip = _desktop->add_temporary_canvasitem(canvas_tooltip, timeout_val);
+
+        Geom::OptRect const bbox = p.getTargetBBox();
+        if (bbox) {
+            SPCanvasItem* box = sp_canvas_item_new(sp_desktop_tempgroup (_desktop),
+                                                     SP_TYPE_CTRLRECT,
+                                                     NULL);
+
+            SP_CTRLRECT(box)->setRectangle(*bbox);
+            SP_CTRLRECT(box)->setColor(0xff0000ff, 0, 0);
+            SP_CTRLRECT(box)->setDashed(true);
+            sp_canvas_item_move_to_z(box, 0);
+            _snaptarget_bbox = _desktop->add_temporary_canvasitem(box, timeout_val);
+        }
     }
 }
 
@@ -261,6 +277,11 @@ SnapIndicator::remove_snaptarget()
         _snaptarget_tooltip = NULL;
     }
 
+    if (_snaptarget_bbox) {
+        _desktop->remove_temporary_canvasitem(_snaptarget_bbox);
+        _snaptarget_bbox = NULL;
+    }
+
 }
 
 void
@@ -279,7 +300,7 @@ SnapIndicator::set_new_snapsource(Inkscape::SnapCandidatePoint const &p)
                                                         "anchor", GTK_ANCHOR_CENTER,
                                                         "size", 6.0,
                                                         "stroked", TRUE,
-                                                        "stroke_color", 0xf000f0ff,
+                                                        "stroke_color", 0xff0000ff,
                                                         "mode", SP_KNOT_MODE_XOR,
                                                         "shape", SP_KNOT_SHAPE_CIRCLE,
                                                         NULL );
index d896042a203018c94c3fe173d3cc6b750912e2a0..feb118baabdf2bc9bea0855cbba69c984a903308 100644 (file)
@@ -35,6 +35,7 @@ public:
 protected:
     TemporaryItem *_snaptarget;
     TemporaryItem *_snaptarget_tooltip;
+    TemporaryItem *_snaptarget_bbox;
     TemporaryItem *_snapsource;
     SPDesktop *_desktop;
 
index 6396569e919298fbfe51514f8d58f87ddac96ed4..47d4196292753e091eb6f96ac7ee12eebdfa3e7f 100644 (file)
@@ -266,7 +266,7 @@ void Inkscape::ObjectSnapper::_snapNodes(SnappedConstraints &sc,
     for (std::vector<SnapCandidatePoint>::const_iterator k = _points_to_snap_to->begin(); k != _points_to_snap_to->end(); k++) {
         Geom::Coord dist = Geom::L2((*k).getPoint() - p.getPoint());
         if (dist < getSnapperTolerance() && dist < s.getSnapDistance()) {
-            s = SnappedPoint((*k).getPoint(), p.getSourceType(), p.getSourceNum(), (*k).getTargetType(), dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true);
+            s = SnappedPoint((*k).getPoint(), p.getSourceType(), p.getSourceNum(), (*k).getTargetType(), dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true, (*k).getTargetBBox());
             success = true;
         }
     }
@@ -301,7 +301,7 @@ void Inkscape::ObjectSnapper::_snapTranslatingGuideToNodes(SnappedConstraints &s
         Geom::Coord dist = Geom::L2((*k).getPoint() - 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()) {
-            s = SnappedPoint((*k).getPoint(), SNAPSOURCE_GUIDE, 0, (*k).getTargetType(), dist, tol, getSnapperAlwaysSnap(), true);
+            s = SnappedPoint((*k).getPoint(), SNAPSOURCE_GUIDE, 0, (*k).getTargetType(), dist, tol, getSnapperAlwaysSnap(), true, (*k).getTargetBBox());
             sc.points.push_back(s);
         }
     }
@@ -338,7 +338,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(Inkscape::SnapCandidatePath(border_path, SNAPTARGET_PAGE_BORDER));
+                _paths_to_snap_to->push_back(Inkscape::SnapCandidatePath(border_path, SNAPTARGET_PAGE_BORDER, Geom::OptRect()));
             }
         }
 
@@ -386,7 +386,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(Inkscape::SnapCandidatePath(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(Inkscape::SnapCandidatePath(borderpathv, SNAPTARGET_PATH, Geom::OptRect())); // Perhaps for speed, get a reference to the Geom::pathvector, and store the transformation besides it.
                             curve->unref();
                         }
                     }
@@ -403,7 +403,8 @@ 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(Inkscape::SnapCandidatePath(path, SNAPTARGET_BBOX_EDGE));
+                            rect = sp_item_bbox_desktop(root_item, bbox_type);
+                            _paths_to_snap_to->push_back(Inkscape::SnapCandidatePath(path, SNAPTARGET_BBOX_EDGE, rect));
                         }
                     }
                 }
@@ -437,7 +438,7 @@ void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc,
             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(Inkscape::SnapCandidatePath(pathv, SNAPTARGET_PATH, true));
+                _paths_to_snap_to->push_back(Inkscape::SnapCandidatePath(pathv, SNAPTARGET_PATH, Geom::OptRect(), true));
                 curve->unref();
             }
         }
@@ -484,7 +485,7 @@ void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc,
                 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, p.getSourceType(), p.getSourceNum(), it_p->target_type));
+                        sc.curves.push_back(Inkscape::SnappedCurve(sp_dt, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), false, curve, p.getSourceType(), p.getSourceNum(), it_p->target_type, it_p->target_bbox));
                     }
                 }
             }
@@ -556,7 +557,7 @@ void Inkscape::ObjectSnapper::_snapPathsConstrained(SnappedConstraints &sc,
                         // 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), p.getSourceType(), p.getSourceNum(), k->target_type, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true);
+                        SnappedPoint s(_snapmanager->getDesktop()->doc2dt(p_inters), p.getSourceType(), p.getSourceNum(), k->target_type, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true, k->target_bbox);
                         sc.points.push_back(s);
                     }
                 }
index 13f1d069cc1c6d1c30f04c03bf0149cb15e4c610..be0b2e49090b8ce4df6c505b6a3e711a18206bbf 100644 (file)
@@ -73,24 +73,38 @@ enum SnapSourceType {
 class SnapCandidatePoint
 {
 public:
-    SnapCandidatePoint(Geom::Point const &point, Inkscape::SnapSourceType const source, long const source_num, Inkscape::SnapTargetType const target, Geom::Rect const &bbox)
-        : _point(point), _source_type(source), _target_type(target), _source_num(source_num), _target_bbox(bbox) {};
+    SnapCandidatePoint(Geom::Point const &point, Inkscape::SnapSourceType const source, long const source_num, Inkscape::SnapTargetType const target, Geom::OptRect const &bbox)
+        : _point(point),
+        _source_type(source),
+        _target_type(target),
+        _source_num(source_num),
+        _target_bbox(bbox)
+    {
+    };
 
     SnapCandidatePoint(Geom::Point const &point, Inkscape::SnapSourceType const source, Inkscape::SnapTargetType const target)
-        : _point(point), _source_type(source), _target_type(target)
+        : _point(point),
+        _source_type(source),
+        _target_type(target)
     {
         _source_num = 0;
-        _target_bbox = Geom::Rect();
+        _target_bbox = Geom::OptRect();
     }
 
     SnapCandidatePoint(Geom::Point const &point, Inkscape::SnapSourceType const source, long const source_num = 0)
-        : _point(point), _source_type(source), _target_type(Inkscape::SNAPTARGET_UNDEFINED), _source_num(source_num) {_target_bbox = Geom::Rect();}
+        : _point(point),
+        _source_type(source),
+        _target_type(Inkscape::SNAPTARGET_UNDEFINED),
+        _source_num(source_num)
+    {
+        _target_bbox = Geom::OptRect();
+    }
 
     inline Geom::Point const & getPoint() const {return _point;}
     inline Inkscape::SnapSourceType getSourceType() const {return _source_type;}
     inline Inkscape::SnapTargetType getTargetType() const {return _target_type;}
     inline long getSourceNum() const {return _source_num;}
-    inline Geom::Rect const & getTargetBBox() const {return _target_bbox;}
+    inline Geom::OptRect const getTargetBBox() const {return _target_bbox;}
 
 private:
     // Coordinates of the point
@@ -107,7 +121,7 @@ private:
 
     // If this is a target and it belongs to a bounding box, e.g. when the target type is
     // SNAPTARGET_BBOX_EDGE_MIDPOINT, then _target_bbox stores the relevant bounding box
-    Geom::Rect _target_bbox;
+    Geom::OptRect _target_bbox;
 };
 
 class SnapCandidateItem
@@ -132,12 +146,13 @@ class SnapCandidatePath
 {
 
 public:
-    SnapCandidatePath(Geom::PathVector* path, SnapTargetType target, bool edited = false)
-        : path_vector(path), target_type(target), currently_being_edited(edited) {}
+    SnapCandidatePath(Geom::PathVector* path, SnapTargetType target, Geom::OptRect bbox, bool edited = false)
+        : path_vector(path), target_type(target), target_bbox(bbox), currently_being_edited(edited) {};
     ~SnapCandidatePath() {};
 
     Geom::PathVector* path_vector;
     SnapTargetType target_type;
+    Geom::OptRect target_bbox;
     bool currently_being_edited; // true for the path that's currently being edited in the node tool (if any)
 
 };
index 33403863869525231c775f17e9580ed2a378190e..d4ef0a83fe204c53cbb6423b4c5d23b22e241f8d 100644 (file)
@@ -12,7 +12,7 @@
 #include <2geom/crossing.h>
 #include <2geom/path-intersection.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, SnapSourceType source, long source_num, 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, long source_num, SnapTargetType target, Geom::OptRect target_bbox)
 {
     _distance = snapped_distance;
     _tolerance = std::max(snapped_tolerance, 1.0);
@@ -27,6 +27,7 @@ Inkscape::SnappedCurve::SnappedCurve(Geom::Point const &snapped_point, Geom::Coo
     _source = source;
     _source_num = source_num;
     _target = target;
+    _target_bbox = target_bbox;
 }
 
 Inkscape::SnappedCurve::SnappedCurve()
@@ -44,6 +45,7 @@ Inkscape::SnappedCurve::SnappedCurve()
     _source = SNAPSOURCE_UNDEFINED;
     _source_num = 0;
     _target = SNAPTARGET_UNDEFINED;
+    _target_bbox = Geom::OptRect();
 }
 
 Inkscape::SnappedCurve::~SnappedCurve()
@@ -114,22 +116,27 @@ bool getClosestIntersectionCS(std::list<Inkscape::SnappedCurve> const &list, Geo
     bool success = false;
 
     for (std::list<Inkscape::SnappedCurve>::const_iterator i = list.begin(); i != list.end(); i++) {
-        std::list<Inkscape::SnappedCurve>::const_iterator j = i;
-        j++;
-        for (; j != list.end(); j++) {
-            Inkscape::SnappedPoint sp = (*i).intersect(*j, p, dt2doc);
-            if (sp.getAtIntersection()) {
-                // if it's the first point
-                bool const c1 = !success;
-                // or, if it's closer
-                bool const c2 = sp.getSnapDistance() < result.getSnapDistance();
-                // or, if it's just as close then look at the other distance
-                // (only relevant for snapped points which are at an intersection)
-                bool const c3 = (sp.getSnapDistance() == result.getSnapDistance()) && (sp.getSecondSnapDistance() < result.getSecondSnapDistance());
-                // then prefer this point over the previous one
-                if (c1 || c2 || c3) {
-                    result = sp;
-                    success = true;
+        if ((*i).getTarget() != Inkscape::SNAPTARGET_BBOX_EDGE) { // We don't support snapping to intersections of bboxes,
+            // as this would require two bboxes two be flashed in the snap indicator
+            std::list<Inkscape::SnappedCurve>::const_iterator j = i;
+            j++;
+            for (; j != list.end(); j++) {
+                if ((*j).getTarget() != Inkscape::SNAPTARGET_BBOX_EDGE) { // We don't support snapping to intersections of bboxes
+                    Inkscape::SnappedPoint sp = (*i).intersect(*j, p, dt2doc);
+                    if (sp.getAtIntersection()) {
+                        // if it's the first point
+                        bool const c1 = !success;
+                        // or, if it's closer
+                        bool const c2 = sp.getSnapDistance() < result.getSnapDistance();
+                        // or, if it's just as close then look at the other distance
+                        // (only relevant for snapped points which are at an intersection)
+                        bool const c3 = (sp.getSnapDistance() == result.getSnapDistance()) && (sp.getSecondSnapDistance() < result.getSecondSnapDistance());
+                        // then prefer this point over the previous one
+                        if (c1 || c2 || c3) {
+                            result = sp;
+                            success = true;
+                        }
+                    }
                 }
             }
         }
index 4eea6e7342e64f5a864a354855c4123b148d7562..21124c67814127585f7d951c19826dfb01285b40 100644 (file)
@@ -24,7 +24,7 @@ class SnappedCurve : public SnappedPoint
 {
 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, SnapSourceType source, long source_num, 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, long source_num, SnapTargetType target, Geom::OptRect target_bbox);
     ~SnappedCurve();
     Inkscape::SnappedPoint intersect(SnappedCurve const &curve, Geom::Point const &p, Geom::Matrix dt2doc) const; //intersect with another SnappedCurve
 
index e3559d655f96821baf97903962a832f2f6bff030..089aa4323e39b66fd6c91853bebeddcd00e43bd8 100644 (file)
@@ -14,8 +14,8 @@
 #include "preferences.h"
 
 // overloaded constructor
-Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapSourceType const &source, long source_num, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained)
-    : _point(p), _source(source), _source_num(source_num), _target(target), _distance(d), _tolerance(std::max(t,1.0)), _always_snap(a)
+Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapSourceType const &source, long source_num, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained, Geom::OptRect target_bbox)
+    : _point(p), _source(source), _source_num(source_num), _target(target), _distance(d), _tolerance(std::max(t,1.0)), _always_snap(a), _target_bbox(target_bbox)
 {
     // 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;
@@ -25,7 +25,6 @@ Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapSourceType const
     _second_always_snap = false;
     _transformation = Geom::Point(1,1);
     _pointer_distance = NR_HUGE;
-    _target_bbox = Geom::Rect();
 }
 
 Inkscape::SnappedPoint::SnappedPoint(Inkscape::SnapCandidatePoint const &p, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained)
@@ -41,7 +40,7 @@ Inkscape::SnappedPoint::SnappedPoint(Inkscape::SnapCandidatePoint const &p, Snap
     _second_always_snap = false;
     _transformation = Geom::Point(1,1);
     _pointer_distance = NR_HUGE;
-    _target_bbox = Geom::Rect();
+    _target_bbox = p.getTargetBBox();
 
 }
 
@@ -53,7 +52,7 @@ Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapSourceType const
     // isOtherSnapBetter. We don't want a division by zero.
     _transformation = Geom::Point(1,1);
     _pointer_distance = NR_HUGE;
-    _target_bbox = Geom::Rect();
+    _target_bbox = Geom::OptRect();
 }
 
 Inkscape::SnappedPoint::SnappedPoint()
@@ -72,7 +71,7 @@ Inkscape::SnappedPoint::SnappedPoint()
     _second_always_snap = false;
     _transformation = Geom::Point(1,1);
     _pointer_distance = NR_HUGE;
-    _target_bbox = Geom::Rect();
+    _target_bbox = Geom::OptRect();
 }
 
 Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p)
@@ -91,7 +90,7 @@ Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p)
     _second_always_snap = false;
     _transformation = Geom::Point(1,1);
     _pointer_distance = NR_HUGE;
-    _target_bbox = Geom::Rect();
+    _target_bbox = Geom::OptRect();
 }
 
 Inkscape::SnappedPoint::~SnappedPoint()
@@ -104,7 +103,7 @@ void Inkscape::SnappedPoint::getPoint(Geom::Point &p) const
     if (getSnapped()) {
         // then return the snapped point by overwriting p
         p = _point;
-    } //otherwise p will be left untouched; this way the caller doesn't have to check wether we've snapped
+    } //otherwise p will be left untouched; this way the caller doesn't have to check whether we've snapped
 }
 
 // search for the closest snapped point
index 1497802c089048acde7d80c5f1afd3cd7f782a53..33230e212a4ab87e53bb4ee2c6cb85b23b503175 100644 (file)
@@ -29,7 +29,7 @@ public:
     SnappedPoint();
     SnappedPoint(Geom::Point const &p);
     SnappedPoint(Geom::Point const &p, SnapSourceType const &source, long source_num, 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, long source_num, 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, long source_num, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained, Geom::OptRect target_bbox = Geom::OptRect());
     SnappedPoint(SnapCandidatePoint const &p, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained);
     ~SnappedPoint();
 
@@ -65,8 +65,8 @@ public:
     void setTransformation(Geom::Point const t) {_transformation = t;}
     void setTarget(SnapTargetType const target) {_target = target;}
     SnapTargetType getTarget() const {return _target;}
-    void setTargetBBox(Geom::Rect const target) {_target_bbox = target;}
-    Geom::Rect & getTargetBBox() {return _target_bbox;}
+    void setTargetBBox(Geom::OptRect const target) {_target_bbox = target;}
+    Geom::OptRect const getTargetBBox() const {return _target_bbox;}
     void setSource(SnapSourceType const source) {_source = source;}
     SnapSourceType getSource() const {return _source;}
     long getSourceNum() const {return _source_num;}
@@ -118,7 +118,7 @@ protected:
     /* The transformation (translation, scale, skew, or stretch) from the original point to the snapped point */
     Geom::Point _transformation;
     /* The bounding box we've snapped to (when applicable); will be used by the snapindicator */
-    Geom::Rect _target_bbox;
+    Geom::OptRect _target_bbox;
     /* Distance from the un-transformed point to the mouse pointer, measured at the point in time when dragging started */
     Geom::Coord _pointer_distance;
 };