xref: /trunk/main/svx/inc/svx/svdsnpv.hxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef _SVDSNPV_HXX
29 #define _SVDSNPV_HXX
30 
31 #include <svx/svdpntv.hxx>
32 #include <svx/svdhlpln.hxx>
33 #include "svx/svxdllapi.h"
34 
35 //************************************************************
36 //   Defines
37 //************************************************************
38 
39 #define SDRSNAP_NOTSNAPPED  0x0000
40 #define SDRSNAP_XSNAPPED    0x0001
41 #define SDRSNAP_YSNAPPED    0x0002
42 #define SDRSNAP_XYSNAPPED   0x0003
43 
44 // SDRCROOK_STRETCH ist noch nicht implementiert!
45 enum SdrCrookMode {
46 	SDRCROOK_ROTATE,
47 	SDRCROOK_SLANT,
48 	SDRCROOK_STRETCH
49 };
50 
51 ////////////////////////////////////////////////////////////////////////////////////////////////////
52 ////////////////////////////////////////////////////////////////////////////////////////////////////
53 //
54 //  @@@@  @@  @@  @@@@  @@@@@   @@ @@ @@ @@@@@ @@   @@
55 // @@  @@ @@@ @@ @@  @@ @@  @@  @@ @@ @@ @@    @@   @@
56 // @@     @@@@@@ @@  @@ @@  @@  @@ @@ @@ @@    @@ @ @@
57 //  @@@@  @@@@@@ @@@@@@ @@@@@   @@@@@ @@ @@@@  @@@@@@@
58 //     @@ @@ @@@ @@  @@ @@       @@@  @@ @@    @@@@@@@
59 // @@  @@ @@  @@ @@  @@ @@       @@@  @@ @@    @@@ @@@
60 //  @@@@  @@  @@ @@  @@ @@        @   @@ @@@@@ @@   @@
61 //
62 ////////////////////////////////////////////////////////////////////////////////////////////////////
63 ////////////////////////////////////////////////////////////////////////////////////////////////////
64 
65 // #114409#-1 Migrate PageOrigin
66 class ImplPageOriginOverlay;
67 
68 class SVX_DLLPUBLIC SdrSnapView: public SdrPaintView
69 {
70 protected:
71 	// #114409#-1 Migrate PageOrigin
72 	class ImplPageOriginOverlay*			mpPageOriginOverlay;
73 
74 	// #114409#-2 Migrate HelpLine
75 	class ImplHelpLineOverlay*				mpHelpLineOverlay;
76 
77 	Size						aMagnSiz;
78 	Fraction					aSnapWdtX;
79 	Fraction					aSnapWdtY;
80 
81 	sal_uInt16						nMagnSizPix;
82 	long						nSnapAngle;
83 	long						nEliminatePolyPointLimitAngle;
84 
85 	SdrCrookMode				eCrookMode;
86 
87 	unsigned					bSnapEnab : 1;
88 	unsigned					bGridSnap : 1;
89 	unsigned					bSnapTo1Pix : 1;             // Wenn GridSnap aus, auf ein Pixel fangen um Werte wie 10.01 zu vermeiden
90 	unsigned					bBordSnap : 1;
91 	unsigned					bHlplSnap : 1;
92 	unsigned					bOFrmSnap : 1;
93 	unsigned					bOPntSnap : 1;
94 	unsigned					bOConSnap : 1;
95 	unsigned					bMoveMFrmSnap : 1;
96 	unsigned					bMoveOFrmSnap : 1;
97 	unsigned					bMoveOPntSnap : 1;
98 	unsigned					bMoveOConSnap : 1;
99 	unsigned					bMoveSnapOnlyTopLeft : 1;    //  Speacial fuer den Dialogeditor
100 	unsigned					bOrtho : 1;
101 	unsigned					bBigOrtho : 1;
102 	unsigned					bAngleSnapEnab : 1;
103 	unsigned					bMoveOnlyDragging : 1;       // Objekte nur verschieben bei Resize/Rotate/...
104 	unsigned					bSlantButShear : 1;          // Slant anstelle von Shear anwenden
105 	unsigned					bCrookNoContortion : 1;      // Objekte bei Crook nicht verzerren
106 	unsigned					bHlplFixed : 1;       // sal_True=Hilfslinien fixiert, also nicht verschiebbar
107 	unsigned					bEliminatePolyPoints : 1;
108 
109 private:
110 	SVX_DLLPRIVATE void ClearVars();
111 
112 protected:
113 	// #i71538# make constructors of SdrView sub-components protected to avoid incomplete incarnations which may get casted to SdrView
114 	SdrSnapView(SdrModel* pModel1, OutputDevice* pOut = 0L);
115 	virtual ~SdrSnapView();
116 
117 public:
118 	virtual sal_Bool IsAction() const;
119 	virtual void MovAction(const Point& rPnt);
120 	virtual void EndAction();
121 	virtual void BckAction();
122 	virtual void BrkAction(); // f.abg.Klassen Actions z,B, Draggen abbrechen.
123 	virtual void TakeActionRect(Rectangle& rRect) const;
124 
125 	void SetSnapGridWidth(const Fraction& rX, const Fraction& rY) { aSnapWdtX=rX; aSnapWdtY=rY; }
126 	const Fraction& GetSnapGridWidthX() const { return aSnapWdtX; }
127 	const Fraction& GetSnapGridWidthY() const { return aSnapWdtY; }
128 
129 	void SetSnapMagnetic(const Size& rSiz) { if (rSiz!=aMagnSiz) { aMagnSiz=rSiz; } }
130 	const Size& GetSnapMagnetic() const { return aMagnSiz; }
131 	void SetSnapMagneticPixel(sal_uInt16 nPix) { nMagnSizPix=nPix; }
132 	sal_uInt16 GetSnapMagneticPixel() const { return nMagnSizPix; }
133 
134 	// RecalcLogicSnapMagnetic muss bei jedem Wechsel des OutputDevices
135 	// sowie bei jedem Wechsel des MapModes gerufen werden!
136 	void RecalcLogicSnapMagnetic(const OutputDevice& rOut) { SetSnapMagnetic(rOut.PixelToLogic(Size(nMagnSizPix,nMagnSizPix))); }
137 	void SetActualWin(const OutputDevice* pWin) { SdrPaintView::SetActualWin(pWin); if (pWin!=NULL) RecalcLogicSnapMagnetic(*pWin); }
138 
139 	// Auf die View bezogene Koordinaten!
140 	// Rueckgabewerte sind SDRSNAP_NOTSNAPPED,SDRSNAP_XSNAPPED,
141 	// SDRSNAP_YSNAPPED oder SDRSNAP_XYSNAPPED
142 	sal_uInt16 SnapPos(Point& rPnt, const SdrPageView* pPV) const;
143 	Point GetSnapPos(const Point& rPnt, const SdrPageView* pPV) const;
144 	sal_uInt16 SnapRect(const Rectangle& rRect, const SdrPageView* pPV, long& rDX, long& rDY) const;
145 	void CheckSnap(const Point& rPt, const SdrPageView* pPV, long& nBestXSnap, long& nBestYSnap, bool& bXSnapped, bool& bYSnapped) const;
146 
147 	// Alle Fangeinstellungen sind Persistent.
148 	sal_Bool IsSnapEnabled() const { return bSnapEnab; }
149 	sal_Bool IsGridSnap() const { return bGridSnap; } // Fang auf Rastergitter
150 	sal_Bool IsBordSnap() const { return bBordSnap; } // Fang auf Seitenraender
151 	sal_Bool IsHlplSnap() const { return bHlplSnap; } // Fang auf Hilfslinien
152 	sal_Bool IsOFrmSnap() const { return bOFrmSnap; } // Fang auf LogFram von umgebenden Zeichenobjekten
153 	sal_Bool IsOPntSnap() const { return bOPntSnap; } // Fang auf ausgepraegte Punkte von umgebenden Zeichenobjekten
154 	sal_Bool IsOConSnap() const { return bOConSnap; } // Fang auf Konnektoren der Zeichenobjekte
155 	void SetSnapEnabled(sal_Bool bOn) { bSnapEnab=bOn; }
156 	void SetGridSnap(sal_Bool bOn) { bGridSnap=bOn; }
157 	void SetBordSnap(sal_Bool bOn) { bBordSnap=bOn; }
158 	void SetHlplSnap(sal_Bool bOn) { bHlplSnap=bOn; }
159 	void SetOFrmSnap(sal_Bool bOn) { bOFrmSnap=bOn; }
160 	void SetOPntSnap(sal_Bool bOn) { bOPntSnap=bOn; }
161 	void SetOConSnap(sal_Bool bOn) { bOConSnap=bOn; }
162 
163 	// Normalerweise werden beim Move-Dragging von Zeichenobjekten alle
164 	// 4 Ecken des Object-SnapRects gefangen. Folgende Einstellmoeglichkeit,
165 	// wenn man nur auf die linke obere Ecke fangen will (z.B. DialogEditor):
166 	// Persistent, Default=FALSE.
167 	void SetMoveSnapOnlyTopLeft(sal_Bool bOn) { bMoveSnapOnlyTopLeft=bOn; }
168 	sal_Bool IsMoveSnapOnlyTopLeft() const { return bMoveSnapOnlyTopLeft; }
169 
170 	// Hilfslinien fixiert (nicht verschiebbar)
171 	// Persistent, Default=FALSE.
172 	sal_Bool IsHlplFixed() const { return bHlplFixed; }
173 	void SetHlplFixed(sal_Bool bOn) { bHlplFixed=bOn; }
174 
175 	sal_Bool IsMoveMFrmSnap() const { return bMoveMFrmSnap; } // Fang des LogFram aller markierten Objekte
176 	sal_Bool IsMoveOFrmSnap() const { return bMoveOFrmSnap; } // Fang aller LogFram der markierten Objekte
177 	sal_Bool IsMoveOPntSnap() const { return bMoveOPntSnap; } // Fang ausgepraegter Punkte der markierten Objekte
178 	sal_Bool IsMoveOConSnap() const { return bMoveOConSnap; } // Fang der Konnektoren der markierten Objekte
179 
180 	void SetMoveMFrmSnap(sal_Bool bOn) { bMoveMFrmSnap=bOn; }
181 	void SetMoveOFrmSnap(sal_Bool bOn) { bMoveOFrmSnap=bOn; }
182 	void SetMoveOPntSnap(sal_Bool bOn) { bMoveOPntSnap=bOn; }
183 	void SetMoveOConSnap(sal_Bool bOn) { bMoveOConSnap=bOn; }
184 
185 	// #114409#-1 Migrate PageOrigin
186 	sal_Bool BegSetPageOrg(const Point& rPnt);
187 	void MovSetPageOrg(const Point& rPnt);
188 	sal_Bool EndSetPageOrg();
189 	void BrkSetPageOrg();
190 	sal_Bool IsSetPageOrg() const { return (0L != mpPageOriginOverlay); }
191 
192 	// HitTest. Bei sal_True steht in rnHelpLineNum die Nummer der Hilfslinie und in rpPV
193 	// die zugehoerige PageView.
194 	sal_Bool PickHelpLine(const Point& rPnt, short nTol, const OutputDevice& rOut, sal_uInt16& rnHelpLineNum, SdrPageView*& rpPV) const;
195 
196 	// Verschieben einer vorhandenen Hilfslinie. nHelpLineNum und pPV von PickHelpLine verwenden.
197 	sal_Bool BegDragHelpLine(sal_uInt16 nHelpLineNum, SdrPageView* pPV);
198 	// Interaktives einfuegen einer neuen Hilfslinie
199 	sal_Bool BegDragHelpLine(const Point& rPnt, SdrHelpLineKind eNewKind);
200 	Pointer GetDraggedHelpLinePointer() const;
201 
202 	// Aendern des Hilfslinientyps waerend des draggens
203 	// void SetDraggedHelpLineKind(SdrHelpLineKind eNewKind);
204 	void MovDragHelpLine(const Point& rPnt);
205 	sal_Bool EndDragHelpLine();
206 	void BrkDragHelpLine();
207 	sal_Bool IsDragHelpLine() const { return (0L != mpHelpLineOverlay); }
208 
209 	// SnapAngle ist fuer Winkel im Kreis, RotateDragging, ...
210 	// Der Winkelfang wird unterdrueckt, wenn er mit
211 	// durch SetAngleSnapEnabled(sal_False) ausgeschaltet ist.
212 	// Der Winkelfang ist unabhaengig vom Koordinatenfang
213 	// und somit von der Einstellung IsSnapEnabled()
214 	// Es sollten nur Werte angegeben werden fuer die gilt:
215 	//     36000 modulu nWink = 0
216 	// Implementiert fuer:
217 	// - Rotate (Dragging)
218 	// - Shear (Dragging)
219 	// - Kreisbogen/-sektor/-abschnitt Winkel (Create und Dragging)
220 	// Persistent.
221 	void SetAngleSnapEnabled(sal_Bool bOn) { bAngleSnapEnab=bOn; }
222 	sal_Bool IsAngleSnapEnabled() const { return bAngleSnapEnab; }
223 	void SetSnapAngle(long nWink) { nSnapAngle=nWink; }
224 	long GetSnapAngle() const { return nSnapAngle; }
225 
226 	// Ortho hat je nach Kontext verschiedene Effekte:
227 	// - Create
228 	//   - Linien werden nur im 45deg Raster zugelassen
229 	//   - Statt Rechtecke werden Quadrate erzeugt
230 	//   - Statt Ellipsen werden Kreise erzeugt
231 	// - Dragging
232 	//   - allgemeines Dragging
233 	//     - Move nur Hor, Vert oder 45deg
234 	//     - Resize proportional
235 	//     - Mirror: nichts
236 	//     - Shear ohne Resize
237 	//     - Crook ohne Resize
238 	//   - verschieben der Handles
239 	//     - Spiegelachse nur 45deg Raster
240 	//   - Objekteigenes Dragging
241 	//     - Rechteck Eckenradius: nichts
242 	//     - Kreisobjekt Winkel: nichts
243 	//     - Linie behaelt beim Draggen ihren Winkel bei und wird nur    (ni)
244 	//       verlaengert bzw. verkuerzt.
245 	// Defaultmaessig ist Ortho ausgeschaltet. Persistent.
246 	void SetOrtho(sal_Bool bOn) { bOrtho=bOn; } // unvollstaendig
247 	sal_Bool IsOrtho() const { return bOrtho; }
248 
249 	// BigOrtho hat nur Relevanz wenn Ortho eingeschaltet ist.
250 	// Beispiel: Ein Rechteck wird mit eingeschaltetem Ortho (also ein Quadrat)
251 	//   erzeugt und die Maus wurde dabei vom Nullpunkt zu den Koordinaten
252 	//   (80,30) gedraggt. Dann stuenden nun 2 Alternativen zur Bestimmung der
253 	//   Kantenlaenge des Quadrats zur Wahl: 30 und 80.
254 	//   Die normale Ortho-Funktuionalitaet brachte hierbei ein Quadrat mit
255 	//   Kantenlaenge 30 (also immer die kleinere Groesse). Bei hinzugeschal-
256 	//   tetem BigOrtho bekaeme man dagegen ein Quadrat der Kantenlaenge 80.
257 	// Gleiches gilt auch fuer Resize.
258 	// Defaultmaessig ist BigOrtho eingeschaltet. Persistent.
259 	void SetBigOrtho(sal_Bool bOn) { bBigOrtho=bOn; }
260 	sal_Bool IsBigOrtho() const { return bBigOrtho; }
261 
262 	// bei MoveOnlyDragging=sal_True wird bei Resize/Rotate/Shear/Mirror/Crook
263 	// nur das Zentrum der markierten Objekte transformiert. Groesse, Form
264 	// und Drehwinkel der Objekte bleiben erhalten, nur ihre Positionen
265 	// aendern sich. Persistent. Default=FALSE. (ni)
266 	void SetMoveOnlyDragging(sal_Bool bOn) { bMoveOnlyDragging=bOn; }
267 	sal_Bool IsMoveOnlyDragging() const { return bMoveOnlyDragging; }
268 
269 	// Slant anstelle von Shear anwenden. Persistent. Default=FALSE.
270 	void SetSlantButShear(sal_Bool bOn) { bSlantButShear=bOn; }
271 	sal_Bool IsSlantButShear() const { return bSlantButShear; }
272 
273 	// Objekte bei Crook nicht verzerren. Persistent. Default=FALSE. (ni)
274 	void SetCrookNoContortion(sal_Bool bOn) { bCrookNoContortion=bOn; }
275 	sal_Bool IsCrookNoContortion() const { return bCrookNoContortion; }
276 
277 	// Crook-Modus. Persistent. Default=SDRCROOK_ROTATE. (ni)
278 	void SetCrookMode(SdrCrookMode eMode) { eCrookMode=eMode; }
279 	SdrCrookMode GetCrookMode() const { return eCrookMode; }
280 
281 	// Special fuer IBM: Beim Draggen eines Polygonpunkts wird dieser
282 	// geloescht, wenn seine beiden angrenzenden Linien eh' fast eine
283 	// durchgehende Linie sind.
284 	void SetEliminatePolyPoints(sal_Bool bOn) { bEliminatePolyPoints=bOn; }
285 	sal_Bool IsEliminatePolyPoints() const { return bEliminatePolyPoints; }
286 	void SetEliminatePolyPointLimitAngle(long nAngle) { nEliminatePolyPointLimitAngle=nAngle; }
287 	long GetEliminatePolyPointLimitAngle() const { return nEliminatePolyPointLimitAngle; }
288 };
289 
290 ////////////////////////////////////////////////////////////////////////////////////////////////////
291 //
292 // Begriffsdefinition:
293 //   - Etwas fangen=Gefangen werden kann z.B. der Mauszeiger oder die z.Zt. im
294 //     Drag befindlichen markierten Objekte.
295 //   - Auf etwas fangen=Man kann z.B. auf das Grid oder auf Hilfslinien fangen.
296 //
297 // Grundsaetzlich wird nur gefangen auf sichtbare Elemente (-> Border,
298 // Hilfslinien, Konnektoren; Ausnahme: Grid). Ebenso koennen nur sichtbare
299 // Elemente gefangen werden (->Konnektoren).
300 //
301 // Auf's Grid wird immer erst dann gefangen, wenn nix Anderes in der Naehe
302 // (->Magnetic) ist.
303 //
304 // Der "Cursor" (also der Mauszeiger) beim Erzeugen von Objekten, beim Draggen
305 // von Polygonpunkten, ... wird immer auf allen eingeschalteten Fangalternativen
306 // gefangen (max 6).
307 //
308 // Beim Verschieben markierter Objekte ist das etwas anders. Statt des einen
309 // Mauscursors gibt es hier 4 Alternativen an den markierten Objekten, die
310 // gefangen werden koennen:
311 //   1. die logisch-umschliessenden Rahmen der einzelnen Objekte
312 //   2. der logisch-umschliessende Rahmen aller markierten Objekte
313 //   3. ausgezeichnete Punkte der markierten Objekte (Polygonpunkte, ...)
314 //   4. die Konnektoren der markierten Objekte
315 // Da 1. und 2. einander ausschliessen (2. ist eine Verfeinerung von 1.)
316 // bleiben 3 voneinander unabhaengige Alternativen. Bei 6. Moeglichkeiten auf
317 // die gefangen werden kann kaeme man auf max. 18 Kombinationsmoeglichkeiten!
318 // Deshalb werden folgende Vereinfachungen festgelegt:
319 //   1. Konnektoren fangen sich nur auf Konnektoren.
320 // Verbleiben also nun noch max. 2x5+1=11 Fangkombinationen beim MoveDrag:
321 //   1-3.  umschliessende(r) Rahmen auf Grid/Border/Hilfslinien
322 //   4.    umschliessende(r) Rahmen auf ausgezeichnete Objektpunkte
323 //   5.    umschliessende(r) Rahmen auf umschliessenden Rahmen
324 //   6-8.  ausgezeichnete Punkte auf Grid/Border/Hilfslinien
325 //   7.    ausgezeichnete Punkte auf ausgezeichnete Objektpunkte
326 //   8-10. ausgezeichnete Punkte auf umschliessenden Rahmen
327 //   11.   Konnektoren auf Konnektoren
328 // Beim MouseMove-Event im DragMove werden also diese bis zu max. 11 moeglichen
329 // Alternativen durchgetestet und die mit dem gerigsten Korrekturaufwand
330 // vollzogen.
331 //
332 // Beim Resize, ... wird immer nur der logisch-umschliessende Rahmen der
333 // markierten Objekte gefangen.
334 //
335 ////////////////////////////////////////////////////////////////////////////////////////////////////
336 
337 #endif //_SVDSNPV_HXX
338 
339