1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
23 #include <svx/svdpntv.hxx>
24 #include <svx/svdhlpln.hxx>
25 #include "svx/svxdllapi.h"
27 //************************************************************
29 //************************************************************
31 #define SDRSNAP_NOTSNAPPED 0x0000
32 #define SDRSNAP_XSNAPPED 0x0001
33 #define SDRSNAP_YSNAPPED 0x0002
34 #define SDRSNAP_XYSNAPPED 0x0003
36 // SDRCROOK_STRETCH ist noch nicht implementiert!
43 ////////////////////////////////////////////////////////////////////////////////////////////////////
44 ////////////////////////////////////////////////////////////////////////////////////////////////////
46 // @@@@ @@ @@ @@@@ @@@@@ @@ @@ @@ @@@@@ @@ @@
47 // @@ @@ @@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
48 // @@ @@@@@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @ @@
49 // @@@@ @@@@@@ @@@@@@ @@@@@ @@@@@ @@ @@@@ @@@@@@@
50 // @@ @@ @@@ @@ @@ @@ @@@ @@ @@ @@@@@@@
51 // @@ @@ @@ @@ @@ @@ @@ @@@ @@ @@ @@@ @@@
52 // @@@@ @@ @@ @@ @@ @@ @ @@ @@@@@ @@ @@
54 ////////////////////////////////////////////////////////////////////////////////////////////////////
55 ////////////////////////////////////////////////////////////////////////////////////////////////////
57 // #114409#-1 Migrate PageOrigin
58 class ImplPageOriginOverlay
;
60 class SVX_DLLPUBLIC SdrSnapView
: public SdrPaintView
63 // #114409#-1 Migrate PageOrigin
64 class ImplPageOriginOverlay
* mpPageOriginOverlay
;
66 // #114409#-2 Migrate HelpLine
67 class ImplHelpLineOverlay
* mpHelpLineOverlay
;
73 sal_uInt16 nMagnSizPix
;
75 long nEliminatePolyPointLimitAngle
;
77 SdrCrookMode eCrookMode
;
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
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;
102 SVX_DLLPRIVATE
void ClearVars();
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();
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;
117 void SetSnapGridWidth(const Fraction
& rX
, const Fraction
& rY
) { aSnapWdtX
=rX
; aSnapWdtY
=rY
; }
118 const Fraction
& GetSnapGridWidthX() const { return aSnapWdtX
; }
119 const Fraction
& GetSnapGridWidthY() const { return aSnapWdtY
; }
121 void SetSnapMagnetic(const Size
& rSiz
) { if (rSiz
!=aMagnSiz
) { aMagnSiz
=rSiz
; } }
122 const Size
& GetSnapMagnetic() const { return aMagnSiz
; }
123 void SetSnapMagneticPixel(sal_uInt16 nPix
) { nMagnSizPix
=nPix
; }
124 sal_uInt16
GetSnapMagneticPixel() const { return nMagnSizPix
; }
126 // RecalcLogicSnapMagnetic muss bei jedem Wechsel des OutputDevices
127 // sowie bei jedem Wechsel des MapModes gerufen werden!
128 void RecalcLogicSnapMagnetic(const OutputDevice
& rOut
) { SetSnapMagnetic(rOut
.PixelToLogic(Size(nMagnSizPix
,nMagnSizPix
))); }
129 void SetActualWin(const OutputDevice
* pWin
) { SdrPaintView::SetActualWin(pWin
); if (pWin
!=NULL
) RecalcLogicSnapMagnetic(*pWin
); }
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;
138 // Alle Fangeinstellungen sind Persistent.
139 sal_Bool
IsSnapEnabled() const { return bSnapEnab
; }
140 sal_Bool
IsGridSnap() const { return bGridSnap
; } // Fang auf Rastergitter
141 sal_Bool
IsBordSnap() const { return bBordSnap
; } // Fang auf Seitenraender
142 sal_Bool
IsHlplSnap() const { return bHlplSnap
; } // Fang auf Hilfslinien
143 sal_Bool
IsOFrmSnap() const { return bOFrmSnap
; } // Fang auf LogFram von umgebenden Zeichenobjekten
144 sal_Bool
IsOPntSnap() const { return bOPntSnap
; } // Fang auf ausgepraegte Punkte von umgebenden Zeichenobjekten
145 sal_Bool
IsOConSnap() const { return bOConSnap
; } // Fang auf Konnektoren der Zeichenobjekte
146 void SetSnapEnabled(sal_Bool bOn
) { bSnapEnab
=bOn
; }
147 void SetGridSnap(sal_Bool bOn
) { bGridSnap
=bOn
; }
148 void SetBordSnap(sal_Bool bOn
) { bBordSnap
=bOn
; }
149 void SetHlplSnap(sal_Bool bOn
) { bHlplSnap
=bOn
; }
150 void SetOFrmSnap(sal_Bool bOn
) { bOFrmSnap
=bOn
; }
151 void SetOPntSnap(sal_Bool bOn
) { bOPntSnap
=bOn
; }
152 void SetOConSnap(sal_Bool bOn
) { bOConSnap
=bOn
; }
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 void SetMoveSnapOnlyTopLeft(sal_Bool bOn
) { bMoveSnapOnlyTopLeft
=bOn
; }
159 sal_Bool
IsMoveSnapOnlyTopLeft() const { return bMoveSnapOnlyTopLeft
; }
161 // Hilfslinien fixiert (nicht verschiebbar)
162 // Persistent, Default=FALSE.
163 sal_Bool
IsHlplFixed() const { return bHlplFixed
; }
164 void SetHlplFixed(sal_Bool bOn
) { bHlplFixed
=bOn
; }
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
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
; }
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 sal_Bool
IsSetPageOrg() const { return (0L != mpPageOriginOverlay
); }
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;
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;
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 sal_Bool
IsDragHelpLine() const { return (0L != mpHelpLineOverlay
); }
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)
212 void SetAngleSnapEnabled(sal_Bool bOn
) { bAngleSnapEnab
=bOn
; }
213 sal_Bool
IsAngleSnapEnabled() const { return bAngleSnapEnab
; }
214 void SetSnapAngle(long nWink
) { nSnapAngle
=nWink
; }
215 long GetSnapAngle() const { return nSnapAngle
; }
217 // Ortho hat je nach Kontext verschiedene Effekte:
219 // - Linien werden nur im 45deg Raster zugelassen
220 // - Statt Rechtecke werden Quadrate erzeugt
221 // - Statt Ellipsen werden Kreise erzeugt
223 // - allgemeines Dragging
224 // - Move nur Hor, Vert oder 45deg
225 // - Resize proportional
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 void SetOrtho(bool bOn
) { bOrtho
=bOn
; } // unvollstaendig
238 bool IsOrtho() const { return bOrtho
; }
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 void SetBigOrtho(bool bOn
) { bBigOrtho
=bOn
; }
251 bool IsBigOrtho() const { return bBigOrtho
; }
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 void SetMoveOnlyDragging(sal_Bool bOn
) { bMoveOnlyDragging
=bOn
; }
258 sal_Bool
IsMoveOnlyDragging() const { return bMoveOnlyDragging
; }
260 // Slant anstelle von Shear anwenden. Persistent. Default=FALSE.
261 void SetSlantButShear(sal_Bool bOn
) { bSlantButShear
=bOn
; }
262 sal_Bool
IsSlantButShear() const { return bSlantButShear
; }
264 // Objekte bei Crook nicht verzerren. Persistent. Default=FALSE. (ni)
265 void SetCrookNoContortion(sal_Bool bOn
) { bCrookNoContortion
=bOn
; }
266 sal_Bool
IsCrookNoContortion() const { return bCrookNoContortion
; }
268 // Crook-Modus. Persistent. Default=SDRCROOK_ROTATE. (ni)
269 void SetCrookMode(SdrCrookMode eMode
) { eCrookMode
=eMode
; }
270 SdrCrookMode
GetCrookMode() const { return eCrookMode
; }
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 void SetEliminatePolyPoints(sal_Bool bOn
) { bEliminatePolyPoints
=bOn
; }
276 sal_Bool
IsEliminatePolyPoints() const { return bEliminatePolyPoints
; }
277 void SetEliminatePolyPointLimitAngle(long nAngle
) { nEliminatePolyPointLimitAngle
=nAngle
; }
278 long GetEliminatePolyPointLimitAngle() const { return nEliminatePolyPointLimitAngle
; }
281 ////////////////////////////////////////////////////////////////////////////////////////////////////
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.
288 // Grundsaetzlich wird nur gefangen auf sichtbare Elemente (-> Border,
289 // Hilfslinien, Konnektoren; Ausnahme: Grid). Ebenso koennen nur sichtbare
290 // Elemente gefangen werden (->Konnektoren).
292 // Auf's Grid wird immer erst dann gefangen, wenn nix Anderes in der Naehe
295 // Der "Cursor" (also der Mauszeiger) beim Erzeugen von Objekten, beim Draggen
296 // von Polygonpunkten, ... wird immer auf allen eingeschalteten Fangalternativen
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
323 // Beim Resize, ... wird immer nur der logisch-umschliessende Rahmen der
324 // markierten Objekte gefangen.
326 ////////////////////////////////////////////////////////////////////////////////////////////////////
328 #endif //_SVDSNPV_HXX
330 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */