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_SVDHDL_HXX 21 #define INCLUDED_SVX_SVDHDL_HXX 22 23 #include <tools/gen.hxx> 24 #include <vcl/graph.hxx> 25 26 #include <svx/svdoedge.hxx> 27 #include <basegfx/matrix/b2dhommatrix.hxx> 28 #include <svx/sdr/overlay/overlayobjectlist.hxx> 29 #include <svx/svxdllapi.h> 30 #include <deque> 31 32 class OutputDevice; 33 class SdrHdlList; 34 class SdrMarkView; 35 class SdrObject; 36 class SdrPageView; 37 class MouseEvent; 38 class HelpEvent; 39 40 namespace sdr { namespace contact { 41 class ObjectContact; 42 }} 43 44 // Every object must be able to create its handles. They will be fetched on 45 // selection, registered at the View and made visible. 46 // When a handle is touched by the mouse (IsHit()), from the view the matching mouse pointer 47 // is picked up from the handle and passed to the app (on demand) to be switched on 48 // Handles like e.g. rotation center or the mirror axis are generated by 49 // the view if the correct transformation mode was selected by the controller. 50 // SdrHdlKind::Move...SdrHdlKind::LowerRight should always be consecutive in the enum! 51 52 enum class SdrHdlKind 53 { 54 Move, // Handle to move the object 55 UpperLeft, // Upper left 56 Upper, // Upper 57 UpperRight, // Upper right 58 Left, // Left 59 Right, // Right 60 LowerLeft, // Bottom left 61 Lower, // Bottom 62 LowerRight, // Bottom right 63 Poly, // Select point in polygon or beziercurve 64 BezierWeight, // Weight of a beziercurve 65 Circle, // Angle to circle segment, corner radius to rectangle 66 Ref1, // Reference point 1, e.g. rotation center 67 Ref2, // Reference point 2, e.g. endpoint of mirror axis 68 MirrorAxis, // Mirror axis 69 Glue, // GluePoint 70 Anchor, // Anchor symbol (SD, SW) 71 Transparence, // Interactive transparence 72 Gradient, // Interactive gradient 73 Color, // Interactive color 74 User, 75 Anchor_TR, // #101688# Anchor handle with (0,0) at top right for SW 76 77 // for SJ and the CustomShapeHandles: 78 CustomShape1, 79 80 SmartTag 81 }; 82 83 84 enum class BitmapColorIndex 85 { 86 LightGreen = 0, 87 Cyan = 1, 88 LightCyan = 2, 89 Red = 3, 90 LightRed = 4, 91 Yellow = 5, 92 }; 93 94 95 enum class BitmapMarkerKind 96 { 97 Rect_7x7, 98 Rect_9x9, 99 Rect_11x11, 100 Rect_13x13, 101 Circ_7x7, 102 Circ_9x9, 103 Circ_11x11, 104 Elli_7x9, 105 Elli_9x11, 106 Elli_9x7, 107 Elli_11x9, 108 RectPlus_7x7, 109 RectPlus_9x9, 110 RectPlus_11x11, 111 Crosshair, 112 Glue, 113 Glue_Deselected, 114 Anchor, 115 116 // #98388# add AnchorPressed to be able to animate anchor control, too. 117 AnchorPressed, 118 119 // #101688# AnchorTR for SW 120 AnchorTR, 121 AnchorPressedTR, 122 123 // for SJ and the CustomShapeHandles: 124 Customshape_7x7, 125 Customshape_9x9, 126 Customshape_11x11 127 }; 128 129 130 class SVX_DLLPUBLIC SdrHdl 131 { 132 friend class SdrMarkView; // for the access to nObjHdlNum 133 friend class SdrHdlList; 134 135 protected: 136 SdrObject* pObj; // does handle belong to an object? 137 SdrPageView* pPV; // does handle belong to an object in certain pageview? 138 SdrHdlList* pHdlList; // to store the handlesize 139 // OVERLAYMANAGER 140 sdr::overlay::OverlayObjectList maOverlayGroup; 141 142 Point aPos; 143 144 SdrHdlKind eKind; 145 146 long nRotationAngle; // turn handle or mousepointer 147 sal_uInt32 nObjHdlNum; // required by MarkView 148 sal_uInt32 nPolyNum; // Polygonpoint 149 sal_uInt32 nPPntNum; // Point number of the polygon 150 sal_uInt32 nSourceHdlNum; // still to implement 151 152 bool bSelect : 1; // is a polygon point selected? 153 bool b1PixMore : 1; // True=handle is shown 1 pixel larger 154 bool bPlusHdl : 1; // for Hld-Paint optimisation at MarkPoint/UnmarkPoint, and other ... 155 156 bool mbMoveOutside; // forces this handle to be moved outside of the selection rectangle 157 158 // create marker for this kind 159 virtual void CreateB2dIAObject(); 160 161 // cleanup marker if one exists 162 void GetRidOfIAObject(); 163 164 private: 165 bool mbMouseOver; // is true if the mouse is over this handle 166 167 protected: 168 std::unique_ptr<sdr::overlay::OverlayObject> CreateOverlayObject( 169 const basegfx::B2DPoint& rPos, 170 BitmapColorIndex eColIndex, BitmapMarkerKind eKindOfMarker, 171 Point aMoveOutsideOffset = Point()); 172 static BitmapMarkerKind GetNextBigger(BitmapMarkerKind eKnd); 173 174 // Helper to support inserting a new OverlayObject. It will do all 175 // necessary stuff involved with that: 176 // - add GridOffset for non-linear ViewToDevice transformation (calc) 177 // - add to OverlayManager 178 // - add to local OverlayObjectList - ownership change (!) 179 // It is centralized here (and protected) to avoid that new usages/ 180 // implementations forget one of these needed steps. 181 void insertNewlyCreatedOverlayObjectForSdrHdl( 182 std::unique_ptr<sdr::overlay::OverlayObject> pOverlayObject, 183 const sdr::contact::ObjectContact& rObjectContact, 184 sdr::overlay::OverlayManager& rOverlayManager); 185 186 public: 187 SdrHdl(); 188 explicit SdrHdl(const Point& rPnt, SdrHdlKind eNewKind); 189 virtual ~SdrHdl(); 190 getOverlayObjectList() const191 const sdr::overlay::OverlayObjectList& getOverlayObjectList() const { return maOverlayGroup; } 192 193 void SetHdlList(SdrHdlList* pList); GetKind() const194 SdrHdlKind GetKind() const { return eKind; } 195 void Touch(); 196 GetPos() const197 const Point& GetPos() const { return aPos; } 198 void SetPos(const Point& rPnt); 199 GetPageView() const200 SdrPageView* GetPageView() const { return pPV; } SetPageView(SdrPageView * pNewPV)201 void SetPageView(SdrPageView* pNewPV) { pPV=pNewPV; } 202 GetObj() const203 SdrObject* GetObj() const { return pObj; } 204 void SetObj(SdrObject* pNewObj); 205 IsSelected() const206 bool IsSelected() const { return bSelect; } 207 void SetSelected(bool bJa=true); 208 209 void Set1PixMore(bool bJa=true); 210 void SetRotationAngle(long n); 211 IsCornerHdl() const212 bool IsCornerHdl() const { return eKind==SdrHdlKind::UpperLeft || eKind==SdrHdlKind::UpperRight || eKind==SdrHdlKind::LowerLeft || eKind==SdrHdlKind::LowerRight; } IsVertexHdl() const213 bool IsVertexHdl() const { return eKind==SdrHdlKind::Upper || eKind==SdrHdlKind::Lower || eKind==SdrHdlKind::Left || eKind==SdrHdlKind::Right; } 214 SetObjHdlNum(sal_uInt32 nNum)215 void SetObjHdlNum(sal_uInt32 nNum) { nObjHdlNum=nNum; } GetObjHdlNum() const216 sal_uInt32 GetObjHdlNum() const { return nObjHdlNum; } 217 SetPolyNum(sal_uInt32 nNum)218 void SetPolyNum(sal_uInt32 nNum) { nPolyNum=nNum; } GetPolyNum() const219 sal_uInt32 GetPolyNum() const { return nPolyNum; } 220 SetPointNum(sal_uInt32 nNum)221 void SetPointNum(sal_uInt32 nNum) { nPPntNum=nNum; } GetPointNum() const222 sal_uInt32 GetPointNum() const { return nPPntNum; } 223 SetPlusHdl(bool bOn)224 void SetPlusHdl(bool bOn) { bPlusHdl=bOn; } IsPlusHdl() const225 bool IsPlusHdl() const { return bPlusHdl; } 226 SetSourceHdlNum(sal_uInt32 nNum)227 void SetSourceHdlNum(sal_uInt32 nNum) { nSourceHdlNum=nNum; } GetSourceHdlNum() const228 sal_uInt32 GetSourceHdlNum() const { return nSourceHdlNum; } 229 230 virtual PointerStyle GetPointer() const; 231 bool IsHdlHit(const Point& rPnt) const; 232 233 virtual bool IsFocusHdl() const; 234 235 void SetMoveOutside( bool bMoveOutside ); 236 237 /** is called when the mouse enters the area of this handle. If the handle changes his 238 visualisation during mouse over it must override this method and call Touch(). */ 239 virtual void onMouseEnter(const MouseEvent& rMEvt); 240 241 /** is called when help is requested for the area of this handle */ 242 virtual void onHelpRequest(); 243 244 /** is called when the mouse leaves the area of this handle. If the handle changes his 245 visualisation during mouse over it must override this method and call Touch(). */ 246 virtual void onMouseLeave(); 247 248 static BitmapEx createGluePointBitmap(); 249 }; 250 251 252 #define SDR_HANDLE_COLOR_SIZE_NORMAL Size(13, 13) 253 #define SDR_HANDLE_COLOR_SIZE_SELECTED Size(17, 17) 254 255 class SVX_DLLPUBLIC SdrHdlColor final : public SdrHdl 256 { 257 // size of colr markers 258 Size aMarkerSize; 259 260 // color 261 Color aMarkerColor; 262 263 // callback link when value changed 264 Link<SdrHdlColor*,void> aColorChangeHdl; 265 266 // use luminance values only 267 bool const bUseLuminance : 1; 268 269 // create marker for this kind 270 SVX_DLLPRIVATE virtual void CreateB2dIAObject() override; 271 272 // help functions 273 SVX_DLLPRIVATE BitmapEx CreateColorDropper(Color aCol); 274 SVX_DLLPRIVATE static Color GetLuminance(const Color& rCol); 275 276 public: 277 explicit SdrHdlColor(const Point& rRef, Color aCol, const Size& rSize, bool bLuminance); 278 virtual ~SdrHdlColor() override; 279 IsUseLuminance() const280 bool IsUseLuminance() const { return bUseLuminance; } 281 GetColor() const282 const Color& GetColor() const { return aMarkerColor; } 283 void SetColor(Color aNew, bool bCallLink = false); 284 285 void SetSize(const Size& rNew); 286 SetColorChangeHdl(const Link<SdrHdlColor *,void> & rLink)287 void SetColorChangeHdl(const Link<SdrHdlColor*,void>& rLink) { aColorChangeHdl = rLink; } 288 }; 289 290 291 class SdrHdlGradient final : public SdrHdl 292 { 293 private: 294 // pointer to used color handles 295 SdrHdlColor* pColHdl1; 296 SdrHdlColor* pColHdl2; 297 298 // 2nd position 299 Point a2ndPos; 300 301 // is this a gradient or a transparence 302 bool const bGradient : 1; 303 304 // select which handle to move 305 bool bMoveSingleHandle : 1; 306 bool bMoveFirstHandle : 1; 307 308 // create marker for this kind 309 virtual void CreateB2dIAObject() override; 310 311 public: 312 SdrHdlGradient(const Point& rRef1, const Point& rRef2, bool bGrad); 313 virtual ~SdrHdlGradient() override; 314 IsGradient() const315 bool IsGradient() const { return bGradient; } 316 317 // set the associated color handles SetColorHandles(SdrHdlColor * pL1,SdrHdlColor * pL2)318 void SetColorHandles(SdrHdlColor* pL1, SdrHdlColor* pL2) { pColHdl1 = pL1; pColHdl2 = pL2; } GetColorHdl1() const319 SdrHdlColor* GetColorHdl1() const { return pColHdl1; } GetColorHdl2() const320 SdrHdlColor* GetColorHdl2() const { return pColHdl2; } 321 Get2ndPos() const322 const Point& Get2ndPos() const { return a2ndPos; } 323 void Set2ndPos(const Point& rPnt); 324 325 // the link called by the color handles 326 DECL_LINK(ColorChangeHdl, SdrHdlColor*, void); 327 328 // transformation call, create gradient from this handle 329 void FromIAOToItem(SdrObject* pObj, bool bSetItemOnObject, bool bUndo); 330 331 // selection flags for interaction IsMoveSingleHandle() const332 bool IsMoveSingleHandle() const { return bMoveSingleHandle; } SetMoveSingleHandle(bool bNew)333 void SetMoveSingleHandle(bool bNew) { bMoveSingleHandle = bNew; } IsMoveFirstHandle() const334 bool IsMoveFirstHandle() const { return bMoveFirstHandle; } SetMoveFirstHandle(bool bNew)335 void SetMoveFirstHandle(bool bNew) { bMoveFirstHandle = bNew; } 336 }; 337 338 339 // Spiegelachse 340 class SdrHdlLine final : public SdrHdl 341 { 342 // create marker for this kind 343 virtual void CreateB2dIAObject() override; 344 345 SdrHdl* pHdl1; 346 SdrHdl* pHdl2; 347 348 public: SdrHdlLine(SdrHdl & rHdl1,SdrHdl & rHdl2,SdrHdlKind eNewKind)349 SdrHdlLine(SdrHdl& rHdl1, SdrHdl& rHdl2, SdrHdlKind eNewKind) { eKind=eNewKind; pHdl1=&rHdl1; pHdl2=&rHdl2; } 350 virtual ~SdrHdlLine() override; 351 352 virtual PointerStyle GetPointer() const override; 353 }; 354 355 // a SdrHdlBezWgt knows about its "base handle". Its draw method 356 // draws additionally a line from its position to the position 357 // of the base handle 358 class SdrHdlBezWgt final : public SdrHdl 359 { 360 public: 361 // this is not a Copy-Ctor!!! SdrHdlBezWgt(const SdrHdl * pRefHdl1,SdrHdlKind eNewKind=SdrHdlKind::BezierWeight)362 SdrHdlBezWgt(const SdrHdl* pRefHdl1, SdrHdlKind eNewKind=SdrHdlKind::BezierWeight) { eKind=eNewKind; pHdl1=pRefHdl1; } 363 virtual ~SdrHdlBezWgt() override; 364 365 private: 366 // create marker for this kind 367 virtual void CreateB2dIAObject() override; 368 369 const SdrHdl* pHdl1; 370 }; 371 372 373 class E3dVolumeMarker final : public SdrHdl 374 { 375 basegfx::B2DPolyPolygon aWireframePoly; 376 377 // create marker for this kind 378 virtual void CreateB2dIAObject() override; 379 380 public: 381 explicit E3dVolumeMarker(const basegfx::B2DPolyPolygon& rWireframePoly); 382 }; 383 384 385 class ImpEdgeHdl: public SdrHdl 386 { 387 SdrEdgeLineCode eLineCode; 388 389 // create marker for this kind 390 virtual void CreateB2dIAObject() override; 391 392 public: ImpEdgeHdl(const Point & rPnt,SdrHdlKind eNewKind)393 ImpEdgeHdl(const Point& rPnt, SdrHdlKind eNewKind): SdrHdl(rPnt,eNewKind),eLineCode(SdrEdgeLineCode::MiddleLine) {} 394 virtual ~ImpEdgeHdl() override; 395 396 void SetLineCode(SdrEdgeLineCode eCode); GetLineCode() const397 SdrEdgeLineCode GetLineCode() const { return eLineCode; } 398 bool IsHorzDrag() const; 399 virtual PointerStyle GetPointer() const override; 400 }; 401 402 403 class ImpMeasureHdl final : public SdrHdl 404 { 405 // create marker for this kind 406 virtual void CreateB2dIAObject() override; 407 408 public: ImpMeasureHdl(const Point & rPnt,SdrHdlKind eNewKind)409 ImpMeasureHdl(const Point& rPnt, SdrHdlKind eNewKind): SdrHdl(rPnt,eNewKind) {} 410 virtual ~ImpMeasureHdl() override; 411 412 virtual PointerStyle GetPointer() const override; 413 }; 414 415 416 class ImpTextframeHdl final : public SdrHdl 417 { 418 const tools::Rectangle maRect; 419 420 // create marker for this kind 421 virtual void CreateB2dIAObject() override; 422 423 public: 424 explicit ImpTextframeHdl(const tools::Rectangle& rRect); 425 }; 426 427 428 class SVX_DLLPUBLIC SdrHdlList 429 { 430 protected: 431 size_t mnFocusIndex; 432 SdrMarkView* const pView; 433 std::deque<std::unique_ptr<SdrHdl>> maList; 434 sal_uInt16 nHdlSize; 435 436 bool bRotateShear : 1; 437 bool bDistortShear : 1; 438 bool bMoveOutside : 1; // move handles outwards (for TextEdit) 439 440 private: 441 SVX_DLLPRIVATE SdrHdlList(const SdrHdlList&) = delete; 442 SVX_DLLPRIVATE void operator=(const SdrHdlList&) = delete; 443 444 public: 445 explicit SdrHdlList(SdrMarkView* pV); 446 ~SdrHdlList(); 447 void Clear(); 448 449 void TravelFocusHdl(bool bForward); 450 SdrHdl* GetFocusHdl() const; 451 void SetFocusHdl(SdrHdl* pNew); 452 void ResetFocusHdl(); 453 454 // Access to View GetView() const455 SdrMarkView* GetView() const { return pView;} 456 457 // Sorting: 1.Level first reference point handle, then normal handles, next Glue, then User then Plushandles 458 // 2.Level PageView (Pointer) 459 // 3.Level Position (x+y) 460 void Sort(); GetHdlCount() const461 size_t GetHdlCount() const { return maList.size(); } GetHdl(size_t nNum) const462 SdrHdl* GetHdl(size_t nNum) const { return nNum < maList.size() ? maList[nNum].get() : nullptr; } 463 size_t GetHdlNum(const SdrHdl* pHdl) const; 464 void SetHdlSize(sal_uInt16 nSiz); GetHdlSize() const465 sal_uInt16 GetHdlSize() const { return nHdlSize; } 466 void SetMoveOutside(bool bOn); IsMoveOutside() const467 bool IsMoveOutside() const { return bMoveOutside; } 468 void SetRotateShear(bool bOn); IsRotateShear() const469 bool IsRotateShear() const { return bRotateShear; } 470 void SetDistortShear(bool bOn); IsDistortShear() const471 bool IsDistortShear() const { return bDistortShear; } 472 473 // AddHdl takes ownership of the handle. It should be on the Heap 474 // as Clear() deletes it. 475 void AddHdl(std::unique_ptr<SdrHdl> pHdl); 476 std::unique_ptr<SdrHdl> RemoveHdl(size_t nNum); 477 void RemoveAllByKind(SdrHdlKind eKind); 478 479 // move the ownership of all the SdrHdl to rOther 480 void MoveTo(SdrHdlList& rOther); 481 482 // Last inserted handles are likely hit (if the handles are above each other) 483 SdrHdl* IsHdlListHit(const Point& rPnt) const; 484 SdrHdl* GetHdl(SdrHdlKind eKind1) const; 485 }; 486 487 488 class SVX_DLLPUBLIC SdrCropHdl final : public SdrHdl 489 { 490 public: 491 SdrCropHdl( 492 const Point& rPnt, 493 SdrHdlKind eNewKind, 494 double fShearX, 495 double fRotation); 496 497 private: 498 // create marker for this kind 499 virtual void CreateB2dIAObject() override; 500 501 BitmapEx GetBitmapForHandle( const BitmapEx& rBitmap, int nSize ); 502 503 // evtl. shear and rotation, equal to the object's one to allow adaptation of 504 // the visualization handles 505 double const mfShearX; 506 double const mfRotation; 507 }; 508 509 510 class SdrCropViewHdl final : public SdrHdl 511 { 512 private: 513 basegfx::B2DHomMatrix const maObjectTransform; 514 Graphic const maGraphic; 515 double const mfCropLeft; 516 double const mfCropTop; 517 double const mfCropRight; 518 double const mfCropBottom; 519 520 public: 521 SdrCropViewHdl( 522 const basegfx::B2DHomMatrix& rObjectTransform, 523 const Graphic& rGraphic, 524 double fCropLeft, 525 double fCropTop, 526 double fCropRight, 527 double fCropBottom); 528 529 private: 530 // create marker for this kind 531 virtual void CreateB2dIAObject() override; 532 }; 533 534 535 #endif // INCLUDED_SVX_SVDHDL_HXX 536 537 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 538