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