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