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 INCLUDED_SVX_SVDDRGV_HXX
21 #define INCLUDED_SVX_SVDDRGV_HXX
22 
23 #include <svx/svxdllapi.h>
24 #include <svx/svdxcgv.hxx>
25 #include <memory>
26 
27 class SdrUndoGeoObj;
28 
29 class SVXCORE_DLLPUBLIC SdrDragView : public SdrExchangeView
30 {
31     friend class                SdrPageView;
32     friend class                SdrDragMethod;
33 
34     // See GetDragXorPolyLimit/GetDragXorPointLimit
35     enum : size_t {
36         eDragXorPolyLimit = 100,
37         eDragXorPointLimit = 500
38     };
39 
40 protected:
41     SdrHdl*                     mpDragHdl;
42     std::unique_ptr<SdrDragMethod> mpCurrentSdrDragMethod;
43     SdrUndoGeoObj*              mpInsPointUndo;
44     tools::Rectangle            maDragLimit;
45     OUString                    maInsPointUndoStr;
46     SdrHdlKind                  meDragHdl;
47 
48     bool                        mbFramDrag : 1;        // currently frame dragging
49     bool                        mbMarkedHitMovesAlways : 1; // Persistent
50     bool                        mbDragLimit : 1;      // Limit on SnapRect instead of BoundRect
51     bool                        mbDragHdl : 1;        // TRUE: RefPt is slid
52     bool                        mbDragStripes : 1;    // Persistent
53     bool                        mbSolidDragging : 1;  // allow solid create/drag of objects
54     bool                        mbResizeAtCenter : 1;
55     bool                        mbCrookAtCenter : 1;
56     bool                        mbDragWithCopy : 1;
57     bool                        mbInsGluePoint : 1;
58     bool                        mbInsObjPointMode : 1;
59     bool                        mbInsGluePointMode : 1;
60     bool                        mbNoDragXorPolys : 1;
61 
62 protected:
63     virtual void SetMarkHandles(SfxViewShell* pOtherShell) override;
64     void ShowDragObj();
65     void HideDragObj();
66     bool ImpBegInsObjPoint(bool bIdxZwang, const Point& rPnt, bool bNewObj, OutputDevice* pOut);
67 
68 protected:
69     // #i71538# make constructors of SdrView sub-components protected to avoid incomplete incarnations which may get casted to SdrView
70     SdrDragView(
71         SdrModel& rSdrModel,
72         OutputDevice* pOut);
73 
74     virtual ~SdrDragView() override;
75 
76 public:
77     virtual bool IsAction() const override;
78     virtual void MovAction(const Point& rPnt) override;
79     virtual void EndAction() override;
80     virtual void BckAction() override;
81     virtual void BrkAction() override;
82     virtual void TakeActionRect(tools::Rectangle& rRect) const override;
83 
84     // special implementation for Writer:
85     // TakeDragObjAnchorPos() returns the position at which an object
86     // approximately ends up during dragging when it is "released"
87     // (EndDrag).
88     // As a general rule, this is the left upper corner of the expected
89     // new SnapRect. Exception: CaptionObj. There, it is the position
90     // of the "tail end".
91     // In case of return value 'false', the position could not be
92     // determined (e.g. point shift, multiple selection, shift of the
93     // mirror axis,...)
94     bool TakeDragObjAnchorPos(Point& rPos, bool bTopRight ) const;
95 
96     // If pForcedMeth is passed, then pHdl, ... is not evaluated, but this Drag
97     // method is used. In this, the ownership of the instance passes
98     // to the View and is destroyed at the end of the dragging.
99     virtual bool BegDragObj(const Point& rPnt, OutputDevice* pOut, SdrHdl* pHdl, short nMinMov=-3, SdrDragMethod* pForcedMeth=nullptr);
100     void MovDragObj(const Point& rPnt);
101     bool EndDragObj(bool bCopy=false);
102     void BrkDragObj();
IsDragObj() const103     bool IsDragObj() const { return mpCurrentSdrDragMethod && !mbInsPolyPoint && !mbInsGluePoint; }
GetDragHdl() const104     SdrHdl* GetDragHdl() const { return mpDragHdl; }
GetDragMethod() const105     SdrDragMethod* GetDragMethod() const { return mpCurrentSdrDragMethod.get(); }
IsDraggingPoints() const106     bool IsDraggingPoints() const { return meDragHdl==SdrHdlKind::Poly; }
IsDraggingGluePoints() const107     bool IsDraggingGluePoints() const { return meDragHdl==SdrHdlKind::Glue; }
108 
109     // If you want to define that already during BegDrag
110     // or in the middle.
111     // (Is reset to 'false' on each BegDrag, so set it after BegDrag.)
SetDragWithCopy(bool bOn)112     void SetDragWithCopy(bool bOn) { mbDragWithCopy = bOn; }
IsDragWithCopy() const113     bool IsDragWithCopy() const { return mbDragWithCopy; }
114 
SetInsertGluePoint(bool bOn)115     void SetInsertGluePoint(bool bOn) { mbInsGluePoint = bOn; }
IsInsertGluePoint() const116     bool IsInsertGluePoint() const { return mbInsGluePoint; }
117 
118     // Interactive insertion of a new point. nIdx=0 => in front of the first point
119     bool IsInsObjPointPossible() const;
BegInsObjPoint(const Point & rPnt,bool bNewObj)120     bool BegInsObjPoint(const Point& rPnt, bool bNewObj) { return ImpBegInsObjPoint(false, rPnt, bNewObj, nullptr); }
MovInsObjPoint(const Point & rPnt)121     void MovInsObjPoint(const Point& rPnt) { MovDragObj(rPnt); }
122     bool EndInsObjPoint(SdrCreateCmd eCmd);
IsInsObjPoint() const123     bool IsInsObjPoint() const { return mpCurrentSdrDragMethod && mbInsPolyPoint; }
124 
125     // For the app to manage the status. GetPreferredPointer() is
126     // possibly going to deliver a matching pointer for it.
SetInsObjPointMode(bool bOn)127     void SetInsObjPointMode(bool bOn) { mbInsObjPointMode = bOn; }
IsInsObjPointMode() const128     bool IsInsObjPointMode() const { return mbInsObjPointMode; }
129 
130     bool IsInsGluePointPossible() const;
131     bool BegInsGluePoint(const Point& rPnt);
IsInsGluePoint() const132     bool IsInsGluePoint() const { return mpCurrentSdrDragMethod && mbInsGluePoint; }
133 
134     // For the app to manage the status. GetPreferredPointer() is
135     // possibly going to deliver a matching pointer for it.
SetInsGluePointMode(bool bOn)136     void SetInsGluePointMode(bool bOn) { mbInsGluePointMode = bOn; }
IsInsGluePointMode() const137     bool IsInsGluePointMode() const { return mbInsGluePointMode; }
138 
139     // border lines over the whole win persistent during the
140     // whole dragging. Default=FALSE.
141     void SetDragStripes(bool bOn);
IsDragStripes() const142     bool IsDragStripes() const { return mbDragStripes; }
143 
144     // As a general rule, the contours of the selected objects
145     // are displayed as Xor-polygons. If this flag is set, only one
146     // Xor-Frame is drawn (e.g. in case of multiple selection).
147     // In case of object-specific dragging (polygon points, corner radius,...),
148     // this setting has no influence.
149     // Also changeable during the dragging.
150     // Default=Off
151     void SetNoDragXorPolys(bool bOn);
IsNoDragXorPolys() const152     bool IsNoDragXorPolys() const { return mbNoDragXorPolys; }
153 
154     // If the number of selected objects exceeds the value set here,
155     // NoDragPolys is (temporarily) activated implicitly.
156     // PolyPolygons etc. are regarded as multiple objects respectively.
GetDragXorPolyLimit()157     static size_t GetDragXorPolyLimit() { return eDragXorPolyLimit; }
158 
159     // Like DragXorPolyLimit, but in respect to the total number of
160     // all polygons.
161     // NoDragPolys is (temporarily) activated, if one of the limits
162     // is exceeded.
GetDragXorPointLimit()163     static size_t GetDragXorPointLimit() { return eDragXorPointLimit; }
164 
165     void SetSolidDragging(bool bOn);
166     bool IsSolidDragging() const;
167 
168     // Connector handling is thus as follows (when using default settings):
169     // - If at most 10 Connectors are affected, they are recalculated
170     //   on each MouseMove.
171     // - If 11 to 100 Connectors are affected, the connections
172     //   are shown as straight lines while dragging.
173     // - In case of more than 100 affected Connectors, nothing that refers
174     //   to the Connectors is drawn while dragging.
175 
176     // If a special drag mode like Rotate, Mirror or Crook is enabled,
177     // then a Hit on the selected object triggers exactly this dragging.
178     // If MarkedHitMovesAlways is set to 'true', a Hit on the selected
179     // object always triggers a Move, independent of the DragMode that is
180     // set. This flag is persistent and should be configurable in the app
181     // by the user!
SetMarkedHitMovesAlways(bool bOn)182     void SetMarkedHitMovesAlways(bool bOn) { mbMarkedHitMovesAlways = bOn; }
IsMarkedHitMovesAlways() const183     bool IsMarkedHitMovesAlways() const { return mbMarkedHitMovesAlways; }
184 
185     bool IsOrthoDesired() const;
186 
187     // center as reference on Resize
188     // Default=FALSE.
IsResizeAtCenter() const189     bool IsResizeAtCenter() const { return mbResizeAtCenter; }
SetResizeAtCenter(bool bOn)190     void SetResizeAtCenter(bool bOn) { mbResizeAtCenter = bOn; }
191 
192     // symmetric Crook
193     // Default=FALSE.
IsCrookAtCenter() const194     bool IsCrookAtCenter() const { return mbCrookAtCenter; }
SetCrookAtCenter(bool bOn)195     void SetCrookAtCenter(bool bOn) { mbCrookAtCenter = bOn; }
196 
197     // Limitation of the working area. The limitation refers to the View,
198     // not to the single PageViews. This limitation is only evaluated by
199     // the View on interactions like Dragging and Create.
200     // In case of actions controlled by the app through algorithms or
201     // UI-controlled actions (SetGeoAttr, MoveMarkedObj, ...), the
202     // app must honor this limit itself.
203     // Furthermore, this limit is to be seen as a rough limit. In certain
204     // cases (e.g. while rotating), objects cannot be dragged exactly
205     // up to this limit, objects can overlap a bit because of rounding
206     // errors,...
207     // Default=EmptyRect=no limitation
208     // only partially implemented
SetWorkArea(const tools::Rectangle & rRect)209     void SetWorkArea(const tools::Rectangle& rRect) { maMaxWorkArea=rRect; }
GetWorkArea() const210     const tools::Rectangle& GetWorkArea() const { return maMaxWorkArea; }
211 
212 
213     // The DragLimit refers to the Page of the object.
214     // (TODO or to the View?? - must be researched...)
215     // 'false' = no limit
216     // The return Rect must contain absolute coordinates. The maximum
217     // drag area is then selected by the View in a way that the object's
218     // SnapRect is moved or resized at most up to the corner of the
219     // LimitRect. For objects like Bezier curves, rotated rectangles,
220     // it must be taken into account that because of subsequent
221     // recalculation of the SnapRect (on Resize), rounding errors can
222     // occur, because of which the LimitRect might be exceeded by a
223     // very small extent...
224     // Implemented for Move and Resize
225     virtual bool TakeDragLimit(SdrDragMode eMode, tools::Rectangle& rRect) const;
226 };
227 
228 #endif // INCLUDED_SVX_SVDDRGV_HXX
229 
230 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
231