~danieljabailey/inkscape/arc_node_editor

« back to all changes in this revision

Viewing changes to src/snap.h

  • Committer: scislac
  • Date: 2009-08-12 07:57:52 UTC
  • Revision ID: scislac@users.sourceforge.net-20090812075752-3zt99jgeqr3bm16j
much better quality multi-size windows icon, thanks ChrisMorgan

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Per-desktop object that handles snapping queries.
 
1
#ifndef SEEN_SNAP_H
 
2
#define SEEN_SNAP_H
 
3
 
 
4
/**
 
5
 * \file snap.h
 
6
 * \brief SnapManager class.
 
7
 *
 
8
 * The SnapManager class handles most (if not all) of the interfacing of the snapping mechanisms with the
 
9
 * other parts of the code base. It stores the references to the various types of snappers for grid, guides
 
10
 * and objects, and it stores most of the snapping preferences. Besides that it provides methods to setup
 
11
 * the snapping environment (e.g. keeps a list of the items to ignore when looking for snap target candidates,
 
12
 * and toggling of the snap indicator), and it provides many different methods for the snapping itself (free
 
13
 * snapping vs. constrained snapping, returning the result by reference or through a return statement, etc.)
3
14
 *
4
15
 * Authors:
5
16
 *   Lauris Kaplinski <lauris@kaplinski.com>
9
20
 *
10
21
 * Copyright (C) 2006-2007 Johan Engelen <johan@shouraizou.nl>
11
22
 * Copyright (C) 2000-2002 Lauris Kaplinski
12
 
 * Copyright (C) 2000-2012 Authors
 
23
 * Copyright (C) 2000-2009 Authors
13
24
 *
14
25
 * Released under GNU GPL, read the file 'COPYING' for more information
15
26
 */
16
27
 
17
 
#ifndef SEEN_SNAP_H
18
 
#define SEEN_SNAP_H
19
 
 
20
28
#include <vector>
 
29
 
21
30
#include "guide-snapper.h"
22
31
#include "object-snapper.h"
23
32
#include "snap-preferences.h"
24
 
//#include "pure-transform.h"
25
 
 
26
 
 
27
 
// Guides
 
33
 
 
34
/* Guides */
28
35
enum SPGuideDragType { // used both here and in desktop-events.cpp
29
36
    SP_DRAG_TRANSLATE,
30
37
    SP_DRAG_ROTATE,
32
39
    SP_DRAG_NONE
33
40
};
34
41
 
35
 
class SPGuide;
36
42
class SPNamedView;
37
43
 
38
 
namespace Inkscape {
39
 
    class PureTransform;
40
 
}
41
 
 
 
44
/// Class to coordinate snapping operations
42
45
 
43
46
/**
44
 
 * Class to coordinate snapping operations.
45
 
 *
46
 
 * The SnapManager class handles most (if not all) of the interfacing of the snapping mechanisms
47
 
 * with the other parts of the code base. It stores the references to the various types of snappers
48
 
 * for grid, guides and objects, and it stores most of the snapping preferences. Besides that
49
 
 * it provides methods to setup the snapping environment (e.g. keeps a list of the items to ignore
50
 
 * when looking for snap target candidates, and toggling of the snap indicator), and it provides
51
 
 * many different methods for snapping queries (free snapping vs. constrained snapping,
52
 
 * returning the result by reference or through a return statement, etc.)
53
 
 * 
54
 
 * Each SPNamedView has one of these.  It offers methods to snap points to whatever
55
 
 * snappers are defined (e.g. grid, guides etc.).  It also allows callers to snap
56
 
 * points which have undergone some transformation (e.g. translation, scaling etc.)
57
 
 *
58
 
 * \par How snapping is implemented in Inkscape
59
 
 * \par
60
 
 * The snapping system consists of two key elements. The first one is the snap manager
61
 
 * (this class), which keeps some data about objects in the document and answers queries
62
 
 * of the type "given this point and type of transformation, what is the best place
63
 
 * to snap to?".
64
 
 * 
65
 
 * The second is in event-context.cpp and implements the snapping timeout. Whenever a motion
66
 
 * events happens over the canvas, it stores it for later use and initiates a timeout.
67
 
 * This timeout is discarded whenever a new motion event occurs. When the timeout expires,
68
 
 * a global flag in SnapManager, accessed via getSnapPostponedGlobally(), is set to true
69
 
 * and the stored event is replayed, but this time with snapping enabled. This way you can
70
 
 * write snapping code directly in your control point's dragged handler as if there was
71
 
 * no timeout.
 
47
 *  Each SPNamedView has one of these.  It offers methods to snap points to whatever
 
48
 *  snappers are defined (e.g. grid, guides etc.).  It also allows callers to snap
 
49
 *  points which have undergone some transformation (e.g. translation, scaling etc.)
72
50
 */
 
51
 
73
52
class SnapManager
74
53
{
75
54
public:
76
 
    enum Transformation {
77
 
        TRANSLATE,
 
55
        enum Transformation {
 
56
        TRANSLATION,
78
57
        SCALE,
79
58
        STRETCH,
80
 
        SKEW,
81
 
        ROTATE
 
59
        SKEW
82
60
    };
83
61
 
84
 
    /**
85
 
     * Construct a SnapManager for a SPNamedView.
86
 
     *
87
 
     * @param v 'Owning' SPNamedView.
88
 
     */
89
 
    SnapManager(SPNamedView const *v);
 
62
        SnapManager(SPNamedView const *v);
90
63
 
91
64
    typedef std::list<const Inkscape::Snapper*> SnapperList;
92
65
 
93
 
    /**
94
 
     * Return true if any snapping might occur, whether its to grids, guides or objects.
95
 
     *
96
 
     * Each snapper instance handles its own snapping target, e.g. grids, guides or
97
 
     * objects. This method iterates through all these snapper instances and returns
98
 
     * true if any of the snappers might possible snap, considering only the relevant
99
 
     * snapping preferences.
100
 
     *
101
 
     * @return true if one of the snappers will try to snap to something.
102
 
     */
103
 
    bool someSnapperMightSnap(bool immediately = true) const;
104
 
 
105
 
    /**
106
 
     * @return true if one of the grids might be snapped to.
107
 
     */
 
66
    bool someSnapperMightSnap() const;
108
67
    bool gridSnapperMightSnap() const;
109
68
 
110
 
    /**
111
 
     * Convenience shortcut when there is only one item to ignore.
112
 
     */
113
 
    void setup(SPDesktop const *desktop,
114
 
            bool snapindicator = true,
115
 
            SPItem const *item_to_ignore = NULL,
116
 
            std::vector<Inkscape::SnapCandidatePoint> *unselected_nodes = NULL,
117
 
            SPGuide *guide_to_ignore = NULL);
118
 
 
119
 
    /**
120
 
     * Prepare the snap manager for the actual snapping, which includes building a list of snap targets
121
 
     * to ignore and toggling the snap indicator.
122
 
     *
123
 
     * There are two overloaded setup() methods, of which the other one only allows for a single item to be ignored
124
 
     * whereas this one will take a list of items to ignore
125
 
     *
126
 
     * @param desktop Reference to the desktop to which this snap manager is attached.
127
 
     * @param snapindicator If true then a snap indicator will be displayed automatically (when enabled in the preferences).
128
 
     * @param items_to_ignore These items will not be snapped to, e.g. the items that are currently being dragged. This avoids "self-snapping".
129
 
     * @param unselected_nodes Stationary nodes of the path that is currently being edited in the node tool and
130
 
     * that can be snapped too. Nodes not in this list will not be snapped to, to avoid "self-snapping". Of each
131
 
     * unselected node both the position (Geom::Point) and the type (Inkscape::SnapTargetType) will be stored.
132
 
     * @param guide_to_ignore Guide that is currently being dragged and should not be snapped to.
133
 
     */
134
 
    void setup(SPDesktop const *desktop,
135
 
               bool snapindicator,
136
 
               std::vector<SPItem const *> &items_to_ignore,
137
 
               std::vector<Inkscape::SnapCandidatePoint> *unselected_nodes = NULL,
138
 
               SPGuide *guide_to_ignore = NULL);
139
 
 
140
 
    void setupIgnoreSelection(SPDesktop const *desktop,
141
 
                              bool snapindicator = true,
142
 
                              std::vector<Inkscape::SnapCandidatePoint> *unselected_nodes = NULL,
143
 
                              SPGuide *guide_to_ignore = NULL);
144
 
 
145
 
    void unSetup() {_rotation_center_source_items.clear();
146
 
                    _guide_to_ignore = NULL;
147
 
                    _desktop = NULL;
148
 
                    _unselected_nodes = NULL;}
149
 
 
150
 
    // If we're dragging a rotation center, then setRotationCenterSource() stores the parent item
151
 
    // of this rotation center; this reference is used to make sure that we do not snap a rotation
152
 
    // center to itself
153
 
    // NOTE: Must be called after calling setup(), not before!
154
 
    void setRotationCenterSource(const std::vector<SPItem*> &items) {_rotation_center_source_items = items;}
155
 
    const std::vector<SPItem*> &getRotationCenterSource() {return _rotation_center_source_items;}
 
69
    void setup(SPDesktop const *desktop,
 
70
                        bool snapindicator = true,
 
71
                        SPItem const *item_to_ignore = NULL,
 
72
                        std::vector<std::pair<Geom::Point, int> > *unselected_nodes = NULL,
 
73
                        SPGuide *guide_to_ignore = NULL);
 
74
 
 
75
    void setup(SPDesktop const *desktop,
 
76
                bool snapindicator,
 
77
                std::vector<SPItem const *> &items_to_ignore,
 
78
                std::vector<std::pair<Geom::Point, int> > *unselected_nodes = NULL,
 
79
                SPGuide *guide_to_ignore = NULL);
156
80
 
157
81
    // freeSnapReturnByRef() is preferred over freeSnap(), because it only returns a
158
82
    // point if snapping has occurred (by overwriting p); otherwise p is untouched
159
 
 
160
 
    /**
161
 
     * Try to snap a point to grids, guides or objects.
162
 
     *
163
 
     * Try to snap a point to grids, guides or objects, in two degrees-of-freedom,
164
 
     * i.e. snap in any direction on the two dimensional canvas to the nearest
165
 
     * snap target. freeSnapReturnByRef() is equal in snapping behavior to
166
 
     * freeSnap(), but the former returns the snapped point trough the referenced
167
 
     * parameter p. This parameter p initially contains the position of the snap
168
 
     * source and will we overwritten by the target position if snapping has occurred.
169
 
     * This makes snapping transparent to the calling code. If this is not desired
170
 
     * because either the calling code must know whether snapping has occurred, or
171
 
     * because the original position should not be touched, then freeSnap() should be
172
 
     * called instead.
173
 
     *
174
 
     * PS:
175
 
     * 1) SnapManager::setup() must have been called before calling this method,
176
 
     * although only once for each set of points
177
 
     * 2) Only to be used when a single source point is to be snapped; it assumes
178
 
     * that source_num = 0, which is inefficient when snapping sets our source points
179
 
     *
180
 
     * @param p Current position of the snap source; will be overwritten by the position of the snap target if snapping has occurred.
181
 
     * @param source_type Detailed description of the source type, will be used by the snap indicator.
182
 
     * @param bbox_to_snap Bounding box hulling the set of points, all from the same selection and having the same transformation.
183
 
     */
184
 
    void freeSnapReturnByRef(Geom::Point &p,
185
 
                             Inkscape::SnapSourceType const source_type,
186
 
                             Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const;
187
 
 
188
 
    /**
189
 
     * Try to snap a point to grids, guides or objects.
190
 
     *
191
 
     * Try to snap a point to grids, guides or objects, in two degrees-of-freedom,
192
 
     * i.e. snap in any direction on the two dimensional canvas to the nearest
193
 
     * snap target. freeSnap() is equal in snapping behavior to
194
 
     * freeSnapReturnByRef(). Please read the comments of the latter for more details
195
 
     *
196
 
     * PS: SnapManager::setup() must have been called before calling this method,
197
 
     * although only once for each set of points
198
 
     *
199
 
     * @param p Source point to be snapped.
200
 
     * @param bbox_to_snap Bounding box hulling the set of points, all from the same selection and having the same transformation.
201
 
     * @param to_path_only Only snap to points on a path, such as path intersections with itself or with grids/guides. This is used for
202
 
     *        example when adding nodes to a path. We will not snap for example to grid intersections
203
 
     * @return An instance of the SnappedPoint class, which holds data on the snap source, snap target, and various metrics.
204
 
     */
205
 
    Inkscape::SnappedPoint freeSnap(Inkscape::SnapCandidatePoint const &p,
206
 
                                    Geom::OptRect const &bbox_to_snap = Geom::OptRect(),
207
 
                                    bool to_path_only = false) const;
208
 
 
209
 
    void preSnap(Inkscape::SnapCandidatePoint const &p, bool to_path_only = false);
210
 
 
211
 
    /**
212
 
     * Snap to the closest multiple of a grid pitch.
213
 
     *
214
 
     * When pasting, we would like to snap to the grid. Problem is that we don't know which
215
 
     * nodes were aligned to the grid at the time of copying, so we don't know which nodes
216
 
     * to snap. If we'd snap an unaligned node to the grid, previously aligned nodes would
217
 
     * become unaligned. That's undesirable. Instead we will make sure that the offset
218
 
     * between the source and its pasted copy is a multiple of the grid pitch. If the source
219
 
     * was aligned, then the copy will therefore also be aligned.
220
 
     *
221
 
     * PS: Whether we really find a multiple also depends on the snapping range! Most users
222
 
     * will have "always snap" enabled though, in which case a multiple will always be found.
223
 
     * PS2: When multiple grids are present then the result will become ambiguous. There is no
224
 
     * way to control to which grid this method will snap.
225
 
     *
226
 
     * @param t Vector that represents the offset of the pasted copy with respect to the original.
227
 
     * @return Offset vector after snapping to the closest multiple of a grid pitch.
228
 
     */
229
 
    Geom::Point multipleOfGridPitch(Geom::Point const &t, Geom::Point const &origin);
 
83
    void freeSnapReturnByRef(Inkscape::SnapPreferences::PointType point_type,
 
84
                                                        Geom::Point &p,
 
85
                                                        Inkscape::SnapSourceType const source_type,
 
86
                                                        bool first_point = true,
 
87
                                                        Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const;
 
88
 
 
89
 
 
90
    Inkscape::SnappedPoint freeSnap(Inkscape::SnapPreferences::PointType point_type,
 
91
                                                                        Geom::Point const &p,
 
92
                                                            Inkscape::SnapSourceType const &source_type,
 
93
                                        bool first_point = true,
 
94
                                    Geom::OptRect const &bbox_to_snap = Geom::OptRect() ) const;
 
95
 
 
96
    Geom::Point multipleOfGridPitch(Geom::Point const &t) const;
230
97
 
231
98
    // constrainedSnapReturnByRef() is preferred over constrainedSnap(), because it only returns a
232
99
    // point, by overwriting p, if snapping has occurred; otherwise p is untouched
233
 
 
234
 
    /**
235
 
     * Try to snap a point along a constraint line to grids, guides or objects.
236
 
     *
237
 
     * Try to snap a point to grids, guides or objects, in only one degree-of-freedom,
238
 
     * i.e. snap in a specific direction on the two dimensional canvas to the nearest
239
 
     * snap target.
240
 
     *
241
 
     * constrainedSnapReturnByRef() is equal in snapping behavior to
242
 
     * constrainedSnap(), but the former returns the snapped point trough the referenced
243
 
     * parameter p. This parameter p initially contains the position of the snap
244
 
     * source and will be overwritten by the target position if snapping has occurred.
245
 
     * This makes snapping transparent to the calling code. If this is not desired
246
 
     * because either the calling code must know whether snapping has occurred, or
247
 
     * because the original position should not be touched, then constrainedSnap() should
248
 
     * be called instead. If there's nothing to snap to or if snapping has been disabled,
249
 
     * then this method will still apply the constraint (but without snapping)
250
 
     *
251
 
     * PS:
252
 
     * 1) SnapManager::setup() must have been called before calling this method,
253
 
     * although only once for each set of points
254
 
     * 2) Only to be used when a single source point is to be snapped; it assumes
255
 
     * that source_num = 0, which is inefficient when snapping sets our source points
256
 
 
257
 
     *
258
 
     * @param p Current position of the snap source; will be overwritten by the position of the snap target if snapping has occurred.
259
 
     * @param source_type Detailed description of the source type, will be used by the snap indicator.
260
 
     * @param constraint The direction or line along which snapping must occur.
261
 
     * @param bbox_to_snap Bounding box hulling the set of points, all from the same selection and having the same transformation.
262
 
     */
263
 
    void constrainedSnapReturnByRef(Geom::Point &p,
264
 
                                    Inkscape::SnapSourceType const source_type,
265
 
                                    Inkscape::Snapper::SnapConstraint const &constraint,
266
 
                                    Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const;
267
 
 
268
 
    /**
269
 
     * Try to snap a point along a constraint line to grids, guides or objects.
270
 
     *
271
 
     * Try to snap a point to grids, guides or objects, in only one degree-of-freedom,
272
 
     * i.e. snap in a specific direction on the two dimensional canvas to the nearest
273
 
     * snap target. constrainedSnap is equal in snapping behavior to
274
 
     * constrainedSnapReturnByRef(). Please read the comments of the latter for more details.
275
 
     *
276
 
     * PS: SnapManager::setup() must have been called before calling this method,
277
 
     * although only once for each set of points
278
 
     * PS: If there's nothing to snap to or if snapping has been disabled, then this
279
 
     * method will still apply the constraint (but without snapping)
280
 
     *
281
 
     * @param p Source point to be snapped.
282
 
     * @param constraint The direction or line along which snapping must occur.
283
 
     * @param bbox_to_snap Bounding box hulling the set of points, all from the same selection and having the same transformation.
284
 
     */
285
 
    Inkscape::SnappedPoint constrainedSnap(Inkscape::SnapCandidatePoint const &p,
286
 
                                           Inkscape::Snapper::SnapConstraint const &constraint,
 
100
    void constrainedSnapReturnByRef(Inkscape::SnapPreferences::PointType point_type,
 
101
                                                                        Geom::Point &p,
 
102
                                                                        Inkscape::SnapSourceType const source_type,
 
103
                                                                        Inkscape::Snapper::ConstraintLine const &constraint,
 
104
                                                                        bool first_point = true,
 
105
                                                                        Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const;
 
106
 
 
107
    Inkscape::SnappedPoint constrainedSnap(Inkscape::SnapPreferences::PointType point_type,
 
108
                                                                                   Geom::Point const &p,
 
109
                                                                                   Inkscape::SnapSourceType const &source_type,
 
110
                                                                                   Inkscape::Snapper::ConstraintLine const &constraint,
 
111
                                                                                   bool first_point = true,
287
112
                                           Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const;
288
113
 
289
 
    Inkscape::SnappedPoint multipleConstrainedSnaps(Inkscape::SnapCandidatePoint const &p,
290
 
                                                    std::vector<Inkscape::Snapper::SnapConstraint> const &constraints,
291
 
                                                    bool dont_snap = false,
292
 
                                                    Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const;
293
 
 
294
 
    /**
295
 
     * Try to snap a point to something at a specific angle.
296
 
     *
297
 
     * When drawing a straight line or modifying a gradient, it will snap to specific angle increments
298
 
     * if CTRL is being pressed. This method will enforce this angular constraint (even if there is nothing
299
 
     * to snap to)
300
 
     *
301
 
     * @param p Source point to be snapped.
302
 
     * @param p_ref Optional original point, relative to which the angle should be calculated. If empty then
303
 
     * the angle will be calculated relative to the y-axis.
304
 
     * @param snaps Number of angular increments per PI radians; E.g. if snaps = 2 then we will snap every PI/2 = 90 degrees.
305
 
     */
306
 
    Inkscape::SnappedPoint constrainedAngularSnap(Inkscape::SnapCandidatePoint const &p,
307
 
                                                    boost::optional<Geom::Point> const &p_ref,
308
 
                                                    Geom::Point const &o,
309
 
                                                    unsigned const snaps) const;
310
 
 
311
 
    /**
312
 
     * Wrapper method to make snapping of the guide origin a bit easier (i.e. simplifies the calling code).
313
 
     *
314
 
     * PS: SnapManager::setup() must have been called before calling this method,
315
 
     *
316
 
     * @param p Current position of the point on the guide that is to be snapped; will be overwritten by the position of the snap target if snapping has occurred.
317
 
     * @param origin_or_vector Data used for tangential and perpendicular snapping. When rotating a guide the origin of the rotation is specified here, whereas when
318
 
     * dragging a guide its vector is specified here
319
 
     * @param origin If true then origin_or_vector contains an origin, other it contains a vector
320
 
     * @param freeze_angle If true (in which case origin is false), then the vector specified in origin_or_vector will not be touched, i.e. the guide will
321
 
     * in all circumstances keep its angle. Otherwise the vector in origin_or_vector can be updated, meaning that the guide might take on the angle of a curve that
322
 
     * has been snapped too tangentially or perpendicularly
323
 
     */
324
 
    void guideFreeSnap(Geom::Point &p, Geom::Point &origin_or_vector, bool origin, bool freeze_angle) const;
325
 
 
326
 
    /**
327
 
     * Wrapper method to make snapping of the guide origin a bit easier (i.e. simplifies the calling code).
328
 
     *
329
 
     * PS: SnapManager::setup() must have been called before calling this method,
330
 
     *
331
 
     * @param p Current position of the point on the guide that is to be snapped; will be overwritten by the position of the snap target if snapping has occurred.
332
 
     * @param guideline The guide that is currently being dragged
333
 
     */
 
114
    void guideFreeSnap(Geom::Point &p, Geom::Point const &guide_normal, SPGuideDragType drag_type) const;
334
115
    void guideConstrainedSnap(Geom::Point &p, SPGuide const &guideline) const;
335
116
 
 
117
    Inkscape::SnappedPoint freeSnapTranslation(Inkscape::SnapPreferences::PointType point_type,
 
118
                                               std::vector<std::pair<Geom::Point, int> > const &p,
 
119
                                               Geom::Point const &pointer,
 
120
                                               Geom::Point const &tr) const;
 
121
 
 
122
    Inkscape::SnappedPoint constrainedSnapTranslation(Inkscape::SnapPreferences::PointType point_type,
 
123
                                                      std::vector<std::pair<Geom::Point, int> > const &p,
 
124
                                                      Geom::Point const &pointer,
 
125
                                                      Inkscape::Snapper::ConstraintLine const &constraint,
 
126
                                                      Geom::Point const &tr) const;
 
127
 
 
128
    Inkscape::SnappedPoint freeSnapScale(Inkscape::SnapPreferences::PointType point_type,
 
129
                                         std::vector<std::pair<Geom::Point, int> > const &p,
 
130
                                         Geom::Point const &pointer,
 
131
                                         Geom::Scale const &s,
 
132
                                         Geom::Point const &o) const;
 
133
 
 
134
    Inkscape::SnappedPoint constrainedSnapScale(Inkscape::SnapPreferences::PointType point_type,
 
135
                                                std::vector<std::pair<Geom::Point, int> > const &p,
 
136
                                                Geom::Point const &pointer,
 
137
                                                Geom::Scale const &s,
 
138
                                                Geom::Point const &o) const;
 
139
 
 
140
    Inkscape::SnappedPoint constrainedSnapStretch(Inkscape::SnapPreferences::PointType point_type,
 
141
                                                  std::vector<std::pair<Geom::Point, int> > const &p,
 
142
                                                  Geom::Point const &pointer,
 
143
                                                  Geom::Coord const &s,
 
144
                                                  Geom::Point const &o,
 
145
                                                  Geom::Dim2 d,
 
146
                                                  bool uniform) const;
 
147
 
 
148
    Inkscape::SnappedPoint constrainedSnapSkew(Inkscape::SnapPreferences::PointType point_type,
 
149
                                               std::vector<std::pair<Geom::Point, int> > const &p,
 
150
                                               Geom::Point const &pointer,
 
151
                                               Inkscape::Snapper::ConstraintLine const &constraint,
 
152
                                               Geom::Point const &s, // s[0] = skew factor, s[1] = scale factor
 
153
                                               Geom::Point const &o,
 
154
                                               Geom::Dim2 d) const;
 
155
 
336
156
    Inkscape::GuideSnapper guide;      ///< guide snapper
337
157
    Inkscape::ObjectSnapper object;    ///< snapper to other objects
338
158
    Inkscape::SnapPreferences snapprefs;
339
159
 
340
 
    /**
341
 
     * Return a list of snappers.
342
 
     *
343
 
     * Inkscape snaps to objects, grids, and guides. For each of these snap targets a
344
 
     * separate class is used, which has been derived from the base Snapper class. The
345
 
     * getSnappers() method returns a list of pointers to instances of this class. This
346
 
     * list contains exactly one instance of the guide snapper and of the object snapper
347
 
     * class, but any number of grid snappers (because each grid has its own snapper
348
 
     * instance)
349
 
     *
350
 
     * @return List of snappers that we use.
351
 
     */
352
160
    SnapperList getSnappers() const;
353
 
 
354
 
    /**
355
 
     * Return a list of gridsnappers.
356
 
     *
357
 
     * Each grid has its own instance of the snapper class. This way snapping can
358
 
     * be enabled per grid individually. A list will be returned containing the
359
 
     * pointers to these instances, but only for grids that are being displayed
360
 
     * and for which snapping is enabled.
361
 
     *
362
 
     * @return List of gridsnappers that we use.
363
 
     */
364
161
    SnapperList getGridSnappers() const;
365
162
 
366
163
    SPDesktop const *getDesktop() const {return _desktop;}
370
167
 
371
168
    bool getSnapIndicator() const {return _snapindicator;}
372
169
 
373
 
    /**
374
 
     * Given a set of possible snap targets, find the best target (which is not necessarily
375
 
     * also the nearest target), and show the snap indicator if requested.
376
 
     *
377
 
     * @param p Source point to be snapped.
378
 
     * @param isr A structure holding all snap targets that have been found so far.
379
 
     * @param constrained True if the snap is constrained, e.g. for stretching or for purely horizontal translation.
380
 
     * @param allowOffScreen If true, then snapping to points which are off the screen is allowed (needed for example when pasting to the grid).
381
 
     * @param to_path_only Only snap to points on a path, such as path intersections with itself or with grids/guides. This is used for
382
 
     *        example when adding nodes to a path. We will not snap for example to grid intersections
383
 
     * @return An instance of the SnappedPoint class, which holds data on the snap source, snap target, and various metrics.
384
 
     */
385
 
    Inkscape::SnappedPoint findBestSnap(Inkscape::SnapCandidatePoint const &p, IntermSnapResults const &isr, bool constrained, bool allowOffScreen = false, bool to_paths_only = false) const;
386
 
 
387
 
    /**
388
 
     * Mark the location of the snap source (not the snap target!) on the canvas by drawing a symbol.
389
 
     *
390
 
     * @param point_type Category of points to which the source point belongs: node, guide or bounding box.
391
 
     * @param p The transformed position of the source point, paired with an identifier of the type of the snap source.
392
 
     */
393
 
    void displaySnapsource(Inkscape::SnapCandidatePoint const &p) const;
394
 
 
395
 
    /**
396
 
     * Method for snapping sets of points while they are being transformed.
397
 
     *
398
 
     * Method for snapping sets of points while they are being transformed, when using
399
 
     * for example the selector tool. This method is for internal use only, and should
400
 
     * not have to be called directly. Use freeSnapTransalation(), constrainedSnapScale(),
401
 
     * etc. instead.
402
 
     *
403
 
     * This is what is being done in this method: transform each point, find out whether
404
 
     * a free snap or constrained snap is more appropriate, do the snapping, calculate
405
 
     * some metrics to quantify the snap "distance", and see if it's better than the
406
 
     * previous snap. Finally, the best ("nearest") snap from all these points is returned.
407
 
     * If no snap has occurred and we're asked for a constrained snap then the constraint
408
 
     * will be applied nevertheless
409
 
     *
410
 
     * @param points Collection of points to snap (snap sources), at their untransformed position, all points undergoing the same transformation. Paired with an identifier of the type of the snap source.
411
 
     * @param pointer Location of the mouse pointer at the time dragging started (i.e. when the selection was still untransformed).
412
 
     * @param transform Describes the type of transformation, it's parameters, and any additional constraints
413
 
     */
414
 
    void snapTransformed(std::vector<Inkscape::SnapCandidatePoint> const &points,
415
 
                                            Geom::Point const &pointer,
416
 
                                            Inkscape::PureTransform &transform);
417
 
 
418
170
protected:
419
171
    SPNamedView const *_named_view;
420
172
 
421
173
private:
422
 
    std::vector<SPItem const *> _items_to_ignore; ///< Items that should not be snapped to, for example the items that are currently being dragged. Set using the setup() method
423
 
    std::vector<SPItem*> _rotation_center_source_items; // to avoid snapping a rotation center to itself
 
174
    std::vector<SPItem const *> *_items_to_ignore; ///< Items that should not be snapped to, for example the items that are currently being dragged. Set using the setup() method
 
175
    SPItem const *_item_to_ignore; ///< Single item that should not be snapped to. If not NULL then this takes precedence over _items_to_ignore. Set using the setup() method
424
176
    SPGuide *_guide_to_ignore; ///< A guide that should not be snapped to, e.g. the guide that is currently being dragged
425
177
    SPDesktop const *_desktop;
426
178
    bool _snapindicator; ///< When true, an indicator will be drawn at the position that was being snapped to
427
 
    std::vector<Inkscape::SnapCandidatePoint> *_unselected_nodes; ///< Nodes of the path that is currently being edited and which have not been selected and which will therefore be stationary. Only these nodes will be considered for snapping to. Of each unselected node both the position (Geom::Point) and the type (Inkscape::SnapTargetType) will be stored
428
 
 
 
179
    std::vector<std::pair<Geom::Point, int> > *_unselected_nodes; ///< Nodes of the path that is currently being edited and which have not been selected and which will therefore be stationary. Only these nodes will be considered for snapping to. Of each unselected node both the position (Geom::Point) and the type (Inkscape::SnapTargetType) will be stored
 
180
    //TODO: Make _unselected_nodes type safe; in the line above int is used for Inkscape::SnapTargetType, but if I remember
 
181
    //correctly then in other cases the int is being used for Inkscape::SnapSourceType, or for both. How to make
 
182
    //this type safe?
 
183
 
 
184
    Inkscape::SnappedPoint _snapTransformed(Inkscape::SnapPreferences::PointType type,
 
185
                                            std::vector<std::pair<Geom::Point, int> > const &points,
 
186
                                            Geom::Point const &pointer,
 
187
                                            bool constrained,
 
188
                                            Inkscape::Snapper::ConstraintLine const &constraint,
 
189
                                            Transformation transformation_type,
 
190
                                            Geom::Point const &transformation,
 
191
                                            Geom::Point const &origin,
 
192
                                            Geom::Dim2 dim,
 
193
                                            bool uniform) const;
 
194
 
 
195
    Geom::Point _transformPoint(std::pair<Geom::Point, int> const &p,
 
196
                                            Transformation const transformation_type,
 
197
                                            Geom::Point const &transformation,
 
198
                                            Geom::Point const &origin,
 
199
                                            Geom::Dim2 const dim,
 
200
                                            bool const uniform) const;
 
201
 
 
202
    void _displaySnapsource(Inkscape::SnapPreferences::PointType point_type, std::pair<Geom::Point, int> const &p) const;
 
203
 
 
204
    Inkscape::SnappedPoint findBestSnap(Geom::Point const &p, Inkscape::SnapSourceType const source_type, SnappedConstraints &sc, bool constrained, bool noCurves = false) const;
429
205
};
430
206
 
431
 
#endif // !SEEN_SNAP_H
 
207
#endif /* !SEEN_SNAP_H */
432
208
 
433
209
/*
434
210
  Local Variables: