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