summaryrefslogtreecommitdiff
path: root/include/svx/svddrgv.hxx
blob: c7269ae9f9a4df164f34dbdb3218eab0e0264b87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_SVX_SVDDRGV_HXX
#define INCLUDED_SVX_SVDDRGV_HXX

#include <svx/svxdllapi.h>
#include <svx/svdxcgv.hxx>

class SdrUndoGeoObj;

class SVX_DLLPUBLIC SdrDragView: public SdrExchangeView
{
    friend class                SdrPageView;
    friend class                SdrDragMethod;

protected:
    SdrHdl*                     pDragHdl;
    SdrDragMethod*              mpCurrentSdrDragMethod;
    SdrUndoGeoObj*              pInsPointUndo;
    Rectangle                   aDragLimit;
    OUString               aInsPointUndoStr;
    SdrMarkList                 aFollowingEdges; // If nodes are dragged, all edges should follow as Xor
    SdrHdlKind                  eDragHdl;

    sal_uIntPtr                     nDragXorPolyLimit;
    sal_uIntPtr                     nDragXorPointLimit;
    sal_uInt16                      nDetailedEdgeDraggingLimit;

    bool                        bFramDrag : 1;        // currently frame dragging
    bool                        bDragSpecial : 1;     // currently Special Obj-dragging
    bool                        bMarkedHitMovesAlways : 1; // Persistent
    bool                        bDragLimit : 1;      // Limit on SnapRect instead of BoundRect
    bool                        bDragHdl : 1;        // TRUE: RefPt is slid
    bool                        bDragStripes : 1;    // Persistent
    bool                        bMirrRefDragObj : 1; // Persistent - During the drag, show the mirror axis of the mirrored objects as Xor
    bool                        mbSolidDragging : 1;  // allow solid create/drag of objects
    bool                        bMouseHideWhileDraggingPoints : 1;
    bool                        bResizeAtCenter : 1;
    bool                        bCrookAtCenter : 1;
    bool                        bDragWithCopy : 1;
    bool                        bInsGluePoint : 1;
    bool                        bInsObjPointMode : 1;
    bool                        bInsGluePointMode : 1;
    bool                        bNoDragXorPolys : 1;
    bool                        bAutoVertexCon : 1;  // automatic generation of connectors at the vertices
    bool                        bAutoCornerCon : 1;  // automatic geneartion of connectors at the corners
    bool                        bRubberEdgeDragging : 1;
    bool                        bDetailedEdgeDragging : 1;

private:
    SVX_DLLPRIVATE void ImpClearVars();

protected:
    virtual void SetMarkHandles() SAL_OVERRIDE;
    void ShowDragObj();
    void HideDragObj();
    bool ImpBegInsObjPoint(bool bIdxZwang, sal_uInt32 nIdx, const Point& rPnt, bool bNewObj, OutputDevice* pOut);

protected:
    // #i71538# make constructors of SdrView sub-components protected to avoid incomplete incarnations which may get casted to SdrView
    SdrDragView(SdrModel* pModel1, OutputDevice* pOut = 0L);
    virtual ~SdrDragView();

public:
    virtual bool IsAction() const SAL_OVERRIDE;
    virtual void MovAction(const Point& rPnt) SAL_OVERRIDE;
    virtual void EndAction() SAL_OVERRIDE;
    virtual void BckAction() SAL_OVERRIDE;
    virtual void BrkAction() SAL_OVERRIDE;
    virtual void TakeActionRect(Rectangle& rRect) const SAL_OVERRIDE;

    // special implementation for Writer:
    // TakeDragObjAnchorPos() returns the position at which an object
    // approximately ends up during dragging when it is "released"
    // (EndDrag).
    // As a general rule, this is the left upper corner of the expected
    // new SnapRect. Exception: CaptionObj. There, it is the position
    // of the "tail end".
    // In case of return value 'false', the position could not be
    // determined (e.g. point shift, multiple selection, shift of the
    // mirror axis,...)
    bool TakeDragObjAnchorPos(Point& rPos, bool bTopRight = false ) const;

    // If pForcedMeth is passed, then pHdl, ... is not evaluated, but this Drag
    // method is used. In this, the ownership of the instance passes
    // to the View and is destroyed at the end of the dragging.
    virtual bool BegDragObj(const Point& rPnt, OutputDevice* pOut=NULL, SdrHdl* pHdl=NULL, short nMinMov=-3, SdrDragMethod* pForcedMeth=NULL);
    void MovDragObj(const Point& rPnt);
    bool EndDragObj(bool bCopy=false);
    void BrkDragObj();
    bool IsDragObj() const { return mpCurrentSdrDragMethod && !bInsPolyPoint && !bInsGluePoint; }
    SdrHdl* GetDragHdl() const { return pDragHdl; }
    SdrDragMethod* GetDragMethod() const { return mpCurrentSdrDragMethod; }
    bool IsDraggingPoints() const { return eDragHdl==HDL_POLY; }
    bool IsDraggingGluePoints() const { return eDragHdl==HDL_GLUE; }

    // If you want to define that already during BegDrag
    // or in the middle.
    // (Is reset to 'false' on each BegDrag, so set it after BegDrag.)
    void SetDragWithCopy(bool bOn) { bDragWithCopy = bOn; }
    bool IsDragWithCopy() const { return bDragWithCopy; }

    void SetInsertGluePoint(bool bOn) { bInsGluePoint = bOn; }
    bool IsInsertGluePoint() const { return bInsGluePoint; }

    // Interactive insertion of a new point. nIdx=0 => in front of the first point
    bool IsInsObjPointPossible() const;
    bool BegInsObjPoint(const Point& rPnt, bool bNewObj) { return ImpBegInsObjPoint(false, 0L, rPnt, bNewObj, 0L); }
    void MovInsObjPoint(const Point& rPnt) { MovDragObj(rPnt); }
    bool EndInsObjPoint(SdrCreateCmd eCmd);
    void BrkInsObjPoint() { BrkDragObj(); }
    bool IsInsObjPoint() const { return mpCurrentSdrDragMethod && bInsPolyPoint; }

    // For the app to manage the status. GetPreferredPointer() is
    // possibly going to deliver a matching pointer for it.
    void SetInsObjPointMode(bool bOn) { bInsObjPointMode = bOn; }
    bool IsInsObjPointMode() const { return bInsObjPointMode; }

    bool IsInsGluePointPossible() const;
    bool BegInsGluePoint(const Point& rPnt);
    void MovInsGluePoint(const Point& rPnt) { MovDragObj(rPnt); }
    bool EndInsGluePoint() { return EndDragObj(); }
    void BrkInsGluePoint() { BrkDragObj(); }
    bool IsInsGluePoint() const { return mpCurrentSdrDragMethod && bInsGluePoint; }

    // For the app to manage the status. GetPreferredPointer() is
    // possibly going to deliver a matching pointer for it.
    void SetInsGluePointMode(bool bOn) { bInsGluePointMode = bOn; }
    bool IsInsGluePointMode() const { return bInsGluePointMode; }

    // border lines over the whole win persistent during the
    // whole dragging. Default=FALSE.
    void SetDragStripes(bool bOn);
    bool IsDragStripes() const { return bDragStripes; }

    // hide handles during dragging
    //HMHvoid SetDragHdlHide(bool bOn);
    //HMHBOOL IsDragHdlHide() const { return bNoDragHdl; }

    // Hide the mouse when dragging polygon points or glue points.
    // Default=false
    void SetMouseHideWhileDraggingPoints(bool bOn) { bMouseHideWhileDraggingPoints = bOn; }
    bool IsMouseHideWhileDraggingPoints() const { return bMouseHideWhileDraggingPoints; }

    // As a general rule, the contours of the selected objects
    // are displayed as Xor-polygons. If this flag is set, only one
    // Xor-Frame is drawn (e.g. in case of multiple selection).
    // In case of object-specific dragging (polygon points, corner radius,...),
    // this setting has no influence.
    // Also changeable during the dragging.
    // Default=Off
    void SetNoDragXorPolys(bool bOn);
    bool IsNoDragXorPolys() const { return bNoDragXorPolys; }

    // If the number of selected objects exceeds te value set here,
    // NoDragPolys is (temporarily) activated implicitely.
    // PolyPolygons etc. are regarded as multiple objects respectively.
    // Default=100
    void  SetDragXorPolyLimit(sal_uIntPtr nObjAnz) { nDragXorPolyLimit=nObjAnz; }
    sal_uIntPtr GetDragXorPolyLimit() const { return nDragXorPolyLimit; }

    // Like DragXorPolyLimit, but in respect to the total number of
    // all polygons. Default=500.
    // NoDragPolys is (temporarily) activated, if one of the limits
    // is exceeded.
    void  SetDragXorPointLimit(sal_uIntPtr nPntAnz) { nDragXorPointLimit=nPntAnz; }
    sal_uIntPtr GetDragXorPointLimit() const { return nDragXorPointLimit; }

    void SetSolidDragging(bool bOn);
    bool IsSolidDragging() const;

    // Dragging/Creation of connectors:
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Stick Connectors to vertices
    // Default=true=Yes
    void SetAutoVertexConnectors(bool bOn) { bAutoVertexCon = bOn; }
    bool IsAutoVertexConnectors() const { return bAutoVertexCon; }

    // Stick Connectors to Corners
    // Default=false=No
    void SetAutoCornerConnectors(bool bOn) { bAutoCornerCon = bOn; }
    bool IsAutoCornerConnectors() const { return bAutoCornerCon; }

    // Dragging of connected objects (Nodes):
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // DetailedEdgeDraggingLimit: like RubberEdgeDraggingLimit,
    // but this limit refers to the detailed depiction, i.e. not
    // only rubber bands but total recalculations are visible while
    // dragging. This detailed depiction is only possible in MoveDrag.
    // Default value: 10
    bool IsDetailedEdgeDragging() const { return bDetailedEdgeDragging; }

    sal_uInt16 GetDetailedEdgeDraggingLimit() const { return nDetailedEdgeDraggingLimit; }

    // EdgeDraggingLimit: If more than nEdgeObjCount edges are affected,
    // they are not shown in the interactive dragging.
    // This here talks about the "rubber bands", which take less computing time
    // than the complete recalculations in the DetailedEdgeDragging.
    // default value: 100
    bool IsRubberEdgeDragging() const { return bRubberEdgeDragging; }

    // Connector handling is thus as follows (when using default settings):
    // - If at most 10 Connectors are affected, they are recalculated
    //   on each MouseMove.
    // - If 11 to 100 Connectors are affected, the connections
    //   are shown as straight lines while dragging.
    // - In case of more than 100 affected Connectors, nothing that refers
    //   to the Connectors is drawn while dragging.

    // If a special drag mode like Rotate, Mirror or Crook is enabled,
    // then a Hit on the selected object triggers exactly this dragging.
    // If MarkedHitMovesAlways is set to 'true', a Hit on the selected
    // object always triggers a Move, independent of the DragMode that is
    // set. This flag is persistent and should be configurable in the app
    // by the user!
    void SetMarkedHitMovesAlways(bool bOn) { bMarkedHitMovesAlways = bOn; }
    bool IsMarkedHitMovesAlways() const { return bMarkedHitMovesAlways; }

    // Show the mirror image of the selected objects as Xor while dragging
    // the mirror axis? Persistent. Not yet implemented. Default: true
    void SetMirrRefDragObj(bool bOn) { bMirrRefDragObj = bOn; }
    bool IsMirrRefDragObj() const { return bMirrRefDragObj; }

    bool IsOrthoDesired() const;

    // center as reference on Resize
    // Default=FALSE.
    bool IsResizeAtCenter() const { return bResizeAtCenter; }
    void SetResizeAtCenter(bool bOn) { bResizeAtCenter = bOn; }

    // symmetric Crook
    // Default=FALSE.
    bool IsCrookAtCenter() const { return bCrookAtCenter; }
    void SetCrookAtCenter(bool bOn) { bCrookAtCenter = bOn; }

    // Limitation of the working area. The limitation refers to the View,
    // not to the single PageViews. This limitation is only evaluated by
    // the View on interactions like Dragging and Create.
    // In case of actions controlled by the app through algorithms or
    // UI-controlled actions (SetGeoAttr, MoveMarkedObj, ...), the
    // app must honor this limit itself.
    // Furthermore, this limit is to be seen as a rough limit. In certain
    // cases (e.g. while rotating), objects cannot be dragged exactly
    // up to this limit, objects can overlap a bit because of rounding
    // errors,...
    // Default=EmptyRect=no limitation
    // only partially implemented
    void SetWorkArea(const Rectangle& rRect) { aMaxWorkArea=rRect; }
    const Rectangle& GetWorkArea() const { return aMaxWorkArea; }


    // The DragLimit refers to the Page of the object.
    // (TODO or to the View?? - must be researched...)
    // 'false' = no limit
    // The return Rect must contain absolute coordinates. The maximum
    // drag area is then selected by the View in a way that the object's
    // SnapRect is moved or resized at most up to the corner of the
    // LimitRect. For objects like Bezier curves, rotated rectangles,
    // it must be taken into account that because of subsequent
    // recalculation of the SnapRect (on Resize), rounding errors can
    // occur, because of which the LimitRect might be exceeded by a
    // very small extent....
    // Implemented for Move and Resize
    virtual bool TakeDragLimit(SdrDragMode eMode, Rectangle& rRect) const;
};

#endif // INCLUDED_SVX_SVDDRGV_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */