Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgslayoutsnapper.h
3 : : -------------------
4 : : begin : July 2017
5 : : copyright : (C) 2017 by Nyall Dawson
6 : : email : nyall dot dawson at gmail dot com
7 : : ***************************************************************************/
8 : : /***************************************************************************
9 : : * *
10 : : * This program is free software; you can redistribute it and/or modify *
11 : : * it under the terms of the GNU General Public License as published by *
12 : : * the Free Software Foundation; either version 2 of the License, or *
13 : : * (at your option) any later version. *
14 : : * *
15 : : ***************************************************************************/
16 : : #ifndef QGSLAYOUTSNAPPER_H
17 : : #define QGSLAYOUTSNAPPER_H
18 : :
19 : : #include "qgis_core.h"
20 : : #include "qgslayoutmeasurement.h"
21 : : #include "qgslayoutpoint.h"
22 : : #include "qgslayoutguidecollection.h"
23 : : #include "qgslayoutserializableobject.h"
24 : : #include <QPen>
25 : :
26 : : class QgsLayout;
27 : : class QgsReadWriteContext;
28 : :
29 : : /**
30 : : * \ingroup core
31 : : * \class QgsLayoutSnapper
32 : : * \brief Manages snapping grids and preset snap lines in a layout, and handles
33 : : * snapping points to the nearest grid coordinate/snap line when possible.
34 : : * \since QGIS 3.0
35 : : */
36 : 0 : class CORE_EXPORT QgsLayoutSnapper: public QgsLayoutSerializableObject
37 : : {
38 : :
39 : : public:
40 : :
41 : : /**
42 : : * Constructor for QgsLayoutSnapper, attached to the specified \a layout.
43 : : */
44 : : QgsLayoutSnapper( QgsLayout *layout );
45 : :
46 : 0 : QString stringType() const override { return QStringLiteral( "LayoutSnapper" ); }
47 : : QgsLayout *layout() override;
48 : :
49 : : /**
50 : : * Sets the snap \a tolerance (in pixels) to use when snapping.
51 : : * \see snapTolerance()
52 : : */
53 : : void setSnapTolerance( int snapTolerance );
54 : :
55 : : /**
56 : : * Returns the snap tolerance (in pixels) to use when snapping.
57 : : * \see setSnapTolerance()
58 : : */
59 : : int snapTolerance() const { return mTolerance; }
60 : :
61 : : /**
62 : : * Returns TRUE if snapping to grid is enabled.
63 : : * \see setSnapToGrid()
64 : : */
65 : : bool snapToGrid() const { return mSnapToGrid; }
66 : :
67 : : /**
68 : : * Sets whether snapping to grid is \a enabled.
69 : : * \see snapToGrid()
70 : : */
71 : : void setSnapToGrid( bool enabled );
72 : :
73 : : /**
74 : : * Returns TRUE if snapping to guides is enabled.
75 : : * \see setSnapToGuides()
76 : : */
77 : : bool snapToGuides() const { return mSnapToGuides; }
78 : :
79 : : /**
80 : : * Sets whether snapping to guides is \a enabled.
81 : : * \see snapToGuides()
82 : : */
83 : : void setSnapToGuides( bool enabled );
84 : :
85 : : /**
86 : : * Returns TRUE if snapping to items is enabled.
87 : : * \see setSnapToItems()
88 : : */
89 : : bool snapToItems() const { return mSnapToItems; }
90 : :
91 : : /**
92 : : * Sets whether snapping to items is \a enabled.
93 : : * \see snapToItems()
94 : : */
95 : : void setSnapToItems( bool enabled );
96 : :
97 : : /**
98 : : * Snaps a layout coordinate \a point. If \a point was snapped, \a snapped will be set to TRUE.
99 : : *
100 : : * The \a scaleFactor argument should be set to the transformation from
101 : : * scalar transform from layout coordinates to pixels, i.e. the
102 : : * graphics view transform().m11() value.
103 : : *
104 : : * This method considers snapping to the grid, snap lines, etc.
105 : : *
106 : : * If the \a horizontalSnapLine and \a verticalSnapLine arguments are specified, then the snapper
107 : : * will automatically display and position these lines to indicate snapping positions to item bounds.
108 : : *
109 : : * A list of items to ignore during the snapping can be specified via the \a ignoreItems list.
110 : :
111 : : * \see snapRect()
112 : : */
113 : : QPointF snapPoint( QPointF point, double scaleFactor, bool &snapped SIP_OUT, QGraphicsLineItem *horizontalSnapLine = nullptr,
114 : : QGraphicsLineItem *verticalSnapLine = nullptr,
115 : : const QList< QgsLayoutItem * > *ignoreItems = nullptr ) const;
116 : :
117 : : /**
118 : : * Snaps a layout coordinate \a rect. If \a rect was snapped, \a snapped will be set to TRUE.
119 : : *
120 : : * Snapping occurs by moving the rectangle alone. The rectangle will not be resized
121 : : * as a result of the snap operation.
122 : : *
123 : : * The \a scaleFactor argument should be set to the transformation from
124 : : * scalar transform from layout coordinates to pixels, i.e. the
125 : : * graphics view transform().m11() value.
126 : : *
127 : : * This method considers snapping to the grid, snap lines, etc.
128 : : *
129 : : * If the \a horizontalSnapLine and \a verticalSnapLine arguments are specified, then the snapper
130 : : * will automatically display and position these lines to indicate snapping positions to item bounds.
131 : : *
132 : : * A list of items to ignore during the snapping can be specified via the \a ignoreItems list.
133 : : *
134 : : * \see snapPoint()
135 : : */
136 : : QRectF snapRect( const QRectF &rect, double scaleFactor, bool &snapped SIP_OUT, QGraphicsLineItem *horizontalSnapLine = nullptr,
137 : : QGraphicsLineItem *verticalSnapLine = nullptr,
138 : : const QList< QgsLayoutItem * > *ignoreItems = nullptr ) const;
139 : :
140 : : /**
141 : : * Snaps a layout coordinate \a point to the grid. If \a point
142 : : * was snapped horizontally, \a snappedX will be set to TRUE. If \a point
143 : : * was snapped vertically, \a snappedY will be set to TRUE.
144 : : *
145 : : * The \a scaleFactor argument should be set to the transformation from
146 : : * scalar transform from layout coordinates to pixels, i.e. the
147 : : * graphics view transform().m11() value.
148 : : *
149 : : * If snapToGrid() is disabled, this method will return the point
150 : : * unchanged.
151 : : *
152 : : * \see snapPointsToGrid()
153 : : */
154 : : QPointF snapPointToGrid( QPointF point, double scaleFactor, bool &snappedX SIP_OUT, bool &snappedY SIP_OUT ) const;
155 : :
156 : : /**
157 : : * Snaps a set of \a points to the grid. If the points
158 : : * were snapped, \a snapped will be set to TRUE.
159 : : *
160 : : * The \a scaleFactor argument should be set to the transformation from
161 : : * scalar transform from layout coordinates to pixels, i.e. the
162 : : * graphics view transform().m11() value.
163 : : *
164 : : * If snapToGrid() is disabled, this method will not attempt to snap the points.
165 : : *
166 : : * The returned value is the smallest delta which the points need to be shifted by in order to align
167 : : * one of the points to the grid.
168 : : *
169 : : * \see snapPointToGrid()
170 : : */
171 : : QPointF snapPointsToGrid( const QList< QPointF > &points, double scaleFactor, bool &snappedX SIP_OUT, bool &snappedY SIP_OUT ) const;
172 : :
173 : : /**
174 : : * Snaps an \a original layout coordinate to the guides. If the point
175 : : * was snapped, \a snapped will be set to TRUE.
176 : : *
177 : : * The \a scaleFactor argument should be set to the transformation from
178 : : * scalar transform from layout coordinates to pixels, i.e. the
179 : : * graphics view transform().m11() value.
180 : : *
181 : : * If snapToGuides() is disabled, this method will return the point
182 : : * unchanged.
183 : : *
184 : : * \see snapPointsToGuides()
185 : : */
186 : : double snapPointToGuides( double original, Qt::Orientation orientation, double scaleFactor, bool &snapped SIP_OUT ) const;
187 : :
188 : : /**
189 : : * Snaps a set of \a points to the guides. If the points
190 : : * were snapped, \a snapped will be set to TRUE.
191 : : *
192 : : * The \a scaleFactor argument should be set to the transformation from
193 : : * scalar transform from layout coordinates to pixels, i.e. the
194 : : * graphics view transform().m11() value.
195 : : *
196 : : * If snapToGuides() is disabled, this method will not attempt to snap the points.
197 : : *
198 : : * The returned value is the smallest delta which the points need to be shifted by in order to align
199 : : * one of the points to a guide.
200 : : *
201 : : * \see snapPointToGuides()
202 : : */
203 : : double snapPointsToGuides( const QList< double > &points, Qt::Orientation orientation, double scaleFactor, bool &snapped SIP_OUT ) const;
204 : :
205 : : /**
206 : : * Snaps an \a original layout coordinate to the item bounds. If the point
207 : : * was snapped, \a snapped will be set to TRUE.
208 : : *
209 : : * The \a scaleFactor argument should be set to the transformation from
210 : : * scalar transform from layout coordinates to pixels, i.e. the
211 : : * graphics view transform().m11() value.
212 : : *
213 : : * If snapToItems() is disabled, this method will return the point
214 : : * unchanged.
215 : : *
216 : : * A list of items to ignore during the snapping can be specified via the \a ignoreItems list.
217 : : *
218 : : * If \a snapLine is specified, the snapper will automatically show (or hide) the snap line
219 : : * based on the result of the snap, and position it at the correct location for the snap.
220 : : *
221 : : * \see snapPointsToItems()
222 : : */
223 : : double snapPointToItems( double original, Qt::Orientation orientation, double scaleFactor, const QList< QgsLayoutItem * > &ignoreItems, bool &snapped SIP_OUT,
224 : : QGraphicsLineItem *snapLine = nullptr ) const;
225 : :
226 : : /**
227 : : * Snaps a set of \a points to the item bounds. If the points
228 : : * were snapped, \a snapped will be set to TRUE.
229 : : *
230 : : * The \a scaleFactor argument should be set to the transformation from
231 : : * scalar transform from layout coordinates to pixels, i.e. the
232 : : * graphics view transform().m11() value.
233 : : *
234 : : * If snapToItems() is disabled, this method will not attempt to snap the points.
235 : : *
236 : : * The returned value is the smallest delta which the points need to be shifted by in order to align
237 : : * one of the points to an item bound.
238 : : *
239 : : * \see snapPointToItems()
240 : : */
241 : : double snapPointsToItems( const QList< double > &points, Qt::Orientation orientation, double scaleFactor, const QList< QgsLayoutItem * > &ignoreItems, bool &snapped SIP_OUT,
242 : : QGraphicsLineItem *snapLine = nullptr ) const;
243 : :
244 : : /**
245 : : * Stores the snapper's state in a DOM element. The \a parentElement should refer to the parent layout's DOM element.
246 : : * \see readXml()
247 : : */
248 : : bool writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const override;
249 : :
250 : : /**
251 : : * Sets the snapper's state from a DOM element. snapperElement is the DOM node corresponding to the snapper.
252 : : * \see writeXml()
253 : : */
254 : : bool readXml( const QDomElement &gridElement, const QDomDocument &document, const QgsReadWriteContext &context ) override;
255 : :
256 : : private:
257 : :
258 : : // Used for 'collapsing' undo commands
259 : : enum UndoCommand
260 : : {
261 : : UndoTolerance = 1,
262 : : UndoSnapToGrid,
263 : : UndoSnapToGuides,
264 : : };
265 : :
266 : : QgsLayout *mLayout = nullptr;
267 : :
268 : : int mTolerance = 5;
269 : : bool mSnapToGrid = false;
270 : : bool mSnapToGuides = true;
271 : : bool mSnapToItems = true;
272 : :
273 : : friend class QgsLayoutSnapperUndoCommand;
274 : :
275 : : };
276 : :
277 : : #endif //QGSLAYOUTSNAPPER_H
|