/src/libreoffice/include/svx/svdsnpv.hxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | |
20 | | #pragma once |
21 | | |
22 | | #include <svx/svdpntv.hxx> |
23 | | #include <svx/svdhlpln.hxx> |
24 | | #include <svx/svxdllapi.h> |
25 | | #include <tools/degree.hxx> |
26 | | #include <o3tl/typed_flags_set.hxx> |
27 | | |
28 | | /** |
29 | | * Definition: |
30 | | * - snap something means e.g. the mouse pointer or some marked objects in drag can be snapped |
31 | | * - snap on something means you can e.g. snap on the grid or on auxiliary lines |
32 | | * |
33 | | * |
34 | | * Basically, we only catch visible elements (borders, helper lines, connectors), |
35 | | * with the exception of the grid. Likewise, we can only catch visible elements (i.e. connectors). |
36 | | * We only catch on the grid, if nothing else is close by (magnetic behaviour). |
37 | | * |
38 | | * The cursor which is used during creation of objects, while dragging polygon points |
39 | | * etc. (i.e. the mouse cursor) is always caught on all enabled catch alternatives (max 6). |
40 | | * |
41 | | * This is different, when moving selected objects. Instead of one mouse cursor, there are |
42 | | * four alternatives, which can be caught at the selected objects: |
43 | | * 1. the logically enclosing frame of every single object |
44 | | * 2. the logically enclosing frame of all selected objects |
45 | | * 3. highlighted points of all selected objects (polygon points, ...) |
46 | | * 4. the connectors of the selected objects |
47 | | * |
48 | | * As the first and second case exclude each other (the second is a refinement of the first one) |
49 | | * three alternatives remain, which are independent from each other. For 6 possible values for the |
50 | | * caught ones, we would end up with max. 18 different possible combinations! |
51 | | * |
52 | | * Therefore, we introduce the following simplifications: |
53 | | * 1. Connectors only catch on connectors |
54 | | * |
55 | | * Only max. 2*5+1 = 11 combinations remain for MoveDrag: |
56 | | * 1-3. enclosing frame on grid/border/helper lines |
57 | | * 4. enclosing frame on highlighted object points |
58 | | * 5. enclosing frame on enclosing frame |
59 | | * 6-8. highlighted points on grid/border/helper lines |
60 | | * 7. highlighted points on highlighted object points |
61 | | * 8-10. highlighted points on enclosing frame |
62 | | * 11. connectors on connectors |
63 | | * |
64 | | * We test for all of these possible 11 combinations in the MouseMove event in the DragMove |
65 | | * and those with the least need of correction are carried out. |
66 | | * |
67 | | * In the Resize() etc. methods we only catch the logically enclosing frame of the highlighted objects. |
68 | | */ |
69 | | |
70 | | /** Return value for SnapPos() method */ |
71 | | enum class SdrSnap |
72 | | { |
73 | | NOTSNAPPED = 0x00, |
74 | | XSNAPPED = 0x01, |
75 | | YSNAPPED = 0x02 |
76 | | }; |
77 | | namespace o3tl |
78 | | { |
79 | | template<> struct typed_flags<SdrSnap> : is_typed_flags<SdrSnap, 3> {}; |
80 | | } |
81 | | |
82 | | // TODO SdrCrookMode::Stretch is not implemented yet! |
83 | | enum class SdrCrookMode { |
84 | | Rotate, |
85 | | Slant, |
86 | | Stretch |
87 | | }; |
88 | | |
89 | | |
90 | | // #114409#-1 Migrate PageOrigin |
91 | | |
92 | | class SVXCORE_DLLPUBLIC SdrSnapView : public SdrPaintView |
93 | | { |
94 | | protected: |
95 | | // #114409#-1 Migrate PageOrigin |
96 | | class ImplPageOriginOverlay* mpPageOriginOverlay; |
97 | | |
98 | | // #114409#-2 Migrate HelpLine |
99 | | class ImplHelpLineOverlay* mpHelpLineOverlay; |
100 | | |
101 | | Size maMagnSiz; |
102 | | Fraction maSnapWdtX; |
103 | | Fraction maSnapWdtY; |
104 | | |
105 | | sal_uInt16 mnMagnSizPix; |
106 | | Degree100 mnSnapAngle; |
107 | | Degree100 mnEliminatePolyPointLimitAngle; |
108 | | |
109 | | SdrCrookMode meCrookMode; |
110 | | |
111 | | bool mbSnapEnab : 1; |
112 | | bool mbGridSnap : 1; |
113 | | bool mbBordSnap : 1; |
114 | | bool mbHlplSnap : 1; |
115 | | bool mbOFrmSnap : 1; |
116 | | bool mbOPntSnap : 1; |
117 | | bool mbOConSnap : 1; |
118 | | bool mbMoveSnapOnlyTopLeft : 1; // Special for dialogeditor |
119 | | bool mbOrtho : 1; |
120 | | bool mbBigOrtho : 1; |
121 | | bool mbAngleSnapEnab : 1; |
122 | | bool mbMoveOnlyDragging : 1; // only move objects while Resize/Rotate/... |
123 | | bool mbSlantButShear : 1; // use slant instead of shear |
124 | | bool mbCrookNoContortion : 1; // no contorsion while Crook |
125 | | bool mbEliminatePolyPoints : 1; |
126 | | |
127 | | protected: |
128 | | // #i71538# make constructors of SdrView sub-components protected to avoid incomplete incarnations which may get casted to SdrView |
129 | | SdrSnapView( |
130 | | SdrModel& rSdrModel, |
131 | | OutputDevice* pOut); |
132 | | |
133 | | virtual ~SdrSnapView() override; |
134 | | |
135 | | public: |
136 | | virtual bool IsAction() const override; |
137 | | virtual void MovAction(const Point& rPnt) override; |
138 | | virtual void EndAction() override; |
139 | | virtual void BckAction() override; |
140 | | virtual void BrkAction() override; // break actions for derived classes e.g. interrupt dragging. |
141 | | virtual void TakeActionRect(tools::Rectangle& rRect) const override; |
142 | | |
143 | 83.4k | void SetSnapGridWidth(const Fraction& rX, const Fraction& rY) { maSnapWdtX=rX; maSnapWdtY=rY; } |
144 | 1.50k | const Fraction& GetSnapGridWidthX() const { return maSnapWdtX; } |
145 | 1.50k | const Fraction& GetSnapGridWidthY() const { return maSnapWdtY; } |
146 | | |
147 | 116 | void SetSnapMagnetic(const Size& rSiz) { if (rSiz!=maMagnSiz) { maMagnSiz=rSiz; } } |
148 | 8.56k | void SetSnapMagneticPixel(sal_uInt16 nPix) { mnMagnSizPix=nPix; } |
149 | 5 | sal_uInt16 GetSnapMagneticPixel() const { return mnMagnSizPix; } |
150 | | |
151 | | // RecalcLogicSnapMagnetic has to be called for every change of OutputDevices and every change of the MapMode! |
152 | 116 | void RecalcLogicSnapMagnetic(const OutputDevice& rOut) { SetSnapMagnetic(rOut.PixelToLogic(Size(mnMagnSizPix,mnMagnSizPix))); } |
153 | 116 | void SetActualWin(const OutputDevice* pWin) { SdrPaintView::SetActualWin(pWin); if (pWin!=nullptr) RecalcLogicSnapMagnetic(*pWin); } |
154 | | |
155 | | // Coordinates referred to the view! |
156 | | // Returnvalues are SdrSnap::NOTSNAPPED,SdrSnap::XSNAPPED, |
157 | | // SdrSnap::YSNAPPED or SdrSnap::XYSNAPPED |
158 | | SdrSnap SnapPos(Point& rPnt, const SdrPageView* pPV) const; |
159 | | Point GetSnapPos(const Point& rPnt, const SdrPageView* pPV) const; |
160 | | void CheckSnap(const Point& rPt, tools::Long& nBestXSnap, tools::Long& nBestYSnap, bool& bXSnapped, bool& bYSnapped) const; |
161 | | |
162 | | // All attitudes to snap are persistent. |
163 | 0 | bool IsSnapEnabled() const { return mbSnapEnab; } |
164 | 6.83k | bool IsGridSnap() const { return mbGridSnap; } // Snap to grid |
165 | 5 | bool IsBordSnap() const { return mbBordSnap; } // Snap to border |
166 | 5 | bool IsHlplSnap() const { return mbHlplSnap; } // Snap to auxiliary line |
167 | 5 | bool IsOFrmSnap() const { return mbOFrmSnap; } // Snap to LogFram from surrounding drawing objects |
168 | 5 | bool IsOPntSnap() const { return mbOPntSnap; } // Snap to distinct points from surrounding drawing objects |
169 | 5 | bool IsOConSnap() const { return mbOConSnap; } // Snap to connectors of the drawing objects |
170 | 0 | void SetSnapEnabled(bool bOn) { mbSnapEnab=bOn; } |
171 | 67.7k | void SetGridSnap(bool bOn) { mbGridSnap=bOn; } |
172 | 8.94k | void SetBordSnap(bool bOn) { mbBordSnap=bOn; } |
173 | 8.96k | void SetHlplSnap(bool bOn) { mbHlplSnap=bOn; } |
174 | 8.96k | void SetOFrmSnap(bool bOn) { mbOFrmSnap=bOn; } |
175 | 8.95k | void SetOPntSnap(bool bOn) { mbOPntSnap=bOn; } |
176 | 8.57k | void SetOConSnap(bool bOn) { mbOConSnap=bOn; } |
177 | | |
178 | | // Usually every 4 corners of Object-SnapRects are snapped for Move-Dragging. |
179 | | // The following attitudes e.g. if you only want to snap the left corner on the top (e.g. DialogEditor) |
180 | | // persistent, Default=FALSE. |
181 | 0 | void SetMoveSnapOnlyTopLeft(bool bOn) { mbMoveSnapOnlyTopLeft=bOn; } |
182 | 0 | bool IsMoveSnapOnlyTopLeft() const { return mbMoveSnapOnlyTopLeft; } |
183 | | |
184 | | // #114409#-1 Migrate PageOrigin |
185 | | void BegSetPageOrg(const Point& rPnt); |
186 | | void MovSetPageOrg(const Point& rPnt); |
187 | | void EndSetPageOrg(); |
188 | | void BrkSetPageOrg(); |
189 | 388k | bool IsSetPageOrg() const { return (nullptr != mpPageOriginOverlay); } |
190 | | |
191 | | // HitTest. If sal_True, in rnHelpLineNum is the number of the auxiliary line and in rpPv |
192 | | // the appended PageView. |
193 | | bool PickHelpLine(const Point& rPnt, short nTol, const OutputDevice& rOut, sal_uInt16& rnHelpLineNum, SdrPageView*& rpPV) const; |
194 | | |
195 | | // Move of an available auxiliary line. Use nHelpLineNum and pPV from PickHelpLine. |
196 | | bool BegDragHelpLine(sal_uInt16 nHelpLineNum, SdrPageView* pPV); |
197 | | // interactive insertion of a new auxiliary line |
198 | | void BegDragHelpLine(const Point& rPnt, SdrHelpLineKind eNewKind); |
199 | | PointerStyle GetDraggedHelpLinePointer() const; |
200 | | |
201 | | // change the type of auxiliary line while dragging |
202 | | // void SetDraggedHelpLineKind(SdrHelpLineKind eNewKind); |
203 | | void MovDragHelpLine(const Point& rPnt); |
204 | | bool EndDragHelpLine(); |
205 | | void BrkDragHelpLine(); |
206 | 388k | bool IsDragHelpLine() const { return (nullptr != mpHelpLineOverlay); } |
207 | | |
208 | | // SnapAngle is for angles in circle, RotateDragging, ... |
209 | | // The snapping of an angle is beared down, if it is switched off |
210 | | // with SetAngleSnapEnabled(sal_False) |
211 | | // The snapping angles is independent of snapping coordinates |
212 | | // and so independent of the attitude IsSnapEnabled() |
213 | | // Only values should be specified for them is applied: |
214 | | // 36000 modulo nAngle = 0 |
215 | | // Implemented for: |
216 | | // - Rotate (Dragging) |
217 | | // - Shear (Dragging) |
218 | | // - circular arc/-sector/-section angle (Create and Dragging) |
219 | | // persistent. |
220 | 9.09k | void SetAngleSnapEnabled(bool bOn) { mbAngleSnapEnab=bOn; } |
221 | 5 | bool IsAngleSnapEnabled() const { return mbAngleSnapEnab; } |
222 | 9.25k | void SetSnapAngle(Degree100 nAngle) { mnSnapAngle=nAngle; } |
223 | 5 | Degree100 GetSnapAngle() const { return mnSnapAngle; } |
224 | | |
225 | | // different effects from Ortho (depending on the context): |
226 | | // - Create |
227 | | // - only lines in 45deg grid |
228 | | // - instead of rectangles squares are created |
229 | | // - instead of ellipse circles are created |
230 | | // - Dragging |
231 | | // - general Dragging |
232 | | // - Move only horizontal, vertical or 45deg |
233 | | // - Resize proportional |
234 | | // - Mirror: nothing |
235 | | // - Shear without Resize |
236 | | // - Crook without Resize |
237 | | // - move handles |
238 | | // - mirror axis only 45deg grid |
239 | | // - object-specific Dragging |
240 | | // - rectangle corner radius: nothing |
241 | | // - circle object angle: nothing |
242 | | // - line keeps while Dragging the angle and is only stretched/ contracted |
243 | | // Default value for Ortho is off. persistent. |
244 | 8.56k | void SetOrtho(bool bOn) { mbOrtho=bOn; } // incomplete |
245 | 5 | bool IsOrtho() const { return mbOrtho; } |
246 | | |
247 | | // BigOrtho is only relevant if Ortho is switched on. |
248 | | // Example: rectangle is created and ortho is switched on (--> square) |
249 | | // and the Mouse was dragged from zero to the coordinates |
250 | | // (80,30). Now there are 2 alternatives to determine the edge length |
251 | | // of the square: 30 and 80. |
252 | | // The standard Ortho-Function took 30 (every time the smaller length) |
253 | | // If BigOrtho is switched on, you get a square with edge length of 80. |
254 | | // The same also applies to Resize. |
255 | | // Default value for BigOrtho is on. persistent. |
256 | 8.56k | void SetBigOrtho(bool bOn) { mbBigOrtho=bOn; } |
257 | 5 | bool IsBigOrtho() const { return mbBigOrtho; } |
258 | | |
259 | | // If MoveOnlyDragging=sal_True only the center of the marked objects is |
260 | | // transformed when Resize/Rotate/Shear/Mirror/Crook is executed. |
261 | | // Size, form and rotation angle of the objects are conserved only their positions |
262 | | // are changed. persistent. Default=FALSE. (ni) |
263 | 8.56k | void SetMoveOnlyDragging(bool bOn) { mbMoveOnlyDragging=bOn; } |
264 | 5 | bool IsMoveOnlyDragging() const { return mbMoveOnlyDragging; } |
265 | | |
266 | | // Use Slant instead of Shear. persistent. Default=FALSE. |
267 | 8.56k | void SetSlantButShear(bool bOn) { mbSlantButShear=bOn; } |
268 | 5 | bool IsSlantButShear() const { return mbSlantButShear; } |
269 | | |
270 | | // Don't contort object while Crook. persistent. Default=FALSE. (ni) |
271 | 8.56k | void SetCrookNoContortion(bool bOn) { mbCrookNoContortion=bOn; } |
272 | 5 | bool IsCrookNoContortion() const { return mbCrookNoContortion; } |
273 | | |
274 | | // Crook-Mode. persistent. Default=SdrCrookMode::Rotate. (ni) |
275 | 0 | void SetCrookMode(SdrCrookMode eMode) { meCrookMode=eMode; } |
276 | 0 | SdrCrookMode GetCrookMode() const { return meCrookMode; } |
277 | | |
278 | | // Special for IBM: While Dragging of a traverse station, it is deleted |
279 | | // if its adjacent lines are almost a solid line. |
280 | 8.97k | void SetEliminatePolyPoints(bool bOn) { mbEliminatePolyPoints=bOn; } |
281 | 5 | bool IsEliminatePolyPoints() const { return mbEliminatePolyPoints; } |
282 | 8.97k | void SetEliminatePolyPointLimitAngle(Degree100 nAngle) { mnEliminatePolyPointLimitAngle=nAngle; } |
283 | 5 | Degree100 GetEliminatePolyPointLimitAngle() const { return mnEliminatePolyPointLimitAngle; } |
284 | | }; |
285 | | |
286 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |