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