LibreOffice Module svx (master)  1
svdhdl.cxx
Go to the documentation of this file.
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 
21 #include <algorithm>
22 #include <cassert>
23 
24 #include <svx/svdhdl.hxx>
25 #include <svx/svdpagv.hxx>
26 #include <svx/svdmrkv.hxx>
27 #include <vcl/settings.hxx>
28 #include <vcl/virdev.hxx>
29 #include <vcl/ptrstyle.hxx>
30 
31 #include <svx/sxekitm.hxx>
32 #include <svx/strings.hrc>
33 #include <svx/svdmodel.hxx>
34 #include "gradtrns.hxx"
35 #include <svx/xflgrit.hxx>
36 #include <svx/svdundo.hxx>
37 #include <svx/dialmgr.hxx>
38 #include <svx/xflftrit.hxx>
39 
40 #include <svx/svdopath.hxx>
50 #include <svx/sdrpagewindow.hxx>
51 #include <svx/sdrpaintwindow.hxx>
52 #include <vcl/svapp.hxx>
54 #include <vcl/lazydelete.hxx>
55 #include <vcl/BitmapTools.hxx>
58 
65 #include <memory>
66 #include <bitmaps.hlst>
67 
68 namespace {
69 
70 // #i15222#
71 // Due to the resource problems in Win95/98 with bitmap resources I
72 // will change this handle bitmap providing class. Old version was splitting
73 // and preparing all small handle bitmaps in device bitmap format, now this will
74 // be done on the fly. Thus, there is only one big bitmap in memory. With
75 // three source bitmaps, this will be 3 system bitmap resources instead of hundreds.
76 // The price for that needs to be evaluated. Maybe we will need another change here
77 // if this is too expensive.
78 class SdrHdlBitmapSet
79 {
80  // the bitmap holding all information
81  BitmapEx maMarkersBitmap;
82 
83  // the cropped Bitmaps for reusage
84  ::std::vector< BitmapEx > maRealMarkers;
85 
86  // helpers
87  BitmapEx& impGetOrCreateTargetBitmap(sal_uInt16 nIndex, const tools::Rectangle& rRectangle);
88 
89 public:
90  explicit SdrHdlBitmapSet();
91 
92  const BitmapEx& GetBitmapEx(BitmapMarkerKind eKindOfMarker, sal_uInt16 nInd);
93 };
94 
95 }
96 
97 #define KIND_COUNT (14)
98 #define INDEX_COUNT (6)
99 #define INDIVIDUAL_COUNT (5)
100 
101 SdrHdlBitmapSet::SdrHdlBitmapSet()
102  : maMarkersBitmap(SIP_SA_MARKERS),
103  // 15 kinds (BitmapMarkerKind) use index [0..5] + 5 extra
104  maRealMarkers((KIND_COUNT * INDEX_COUNT) + INDIVIDUAL_COUNT)
105 {
106 }
107 
108 BitmapEx& SdrHdlBitmapSet::impGetOrCreateTargetBitmap(sal_uInt16 nIndex, const tools::Rectangle& rRectangle)
109 {
110  BitmapEx& rTargetBitmap = maRealMarkers[nIndex];
111 
112  if(rTargetBitmap.IsEmpty())
113  {
114  rTargetBitmap = maMarkersBitmap;
115  rTargetBitmap.Crop(rRectangle);
116  }
117 
118  return rTargetBitmap;
119 }
120 
121 // change getting of bitmap to use the big resource bitmap
122 const BitmapEx& SdrHdlBitmapSet::GetBitmapEx(BitmapMarkerKind eKindOfMarker, sal_uInt16 nInd)
123 {
124  // fill in size and source position in maMarkersBitmap
125  const sal_uInt16 nYPos(nInd * 11);
126 
127  switch(eKindOfMarker)
128  {
129  default:
130  {
131  OSL_FAIL( "Unknown kind of marker." );
132  [[fallthrough]]; // return Rect_9x9 as default
133  }
135  {
136  return impGetOrCreateTargetBitmap((1 * INDEX_COUNT) + nInd, tools::Rectangle(Point(7, nYPos), Size(9, 9)));
137  }
138 
140  {
141  return impGetOrCreateTargetBitmap((0 * INDEX_COUNT) + nInd, tools::Rectangle(Point(0, nYPos), Size(7, 7)));
142  }
143 
145  {
146  return impGetOrCreateTargetBitmap((2 * INDEX_COUNT) + nInd, tools::Rectangle(Point(16, nYPos), Size(11, 11)));
147  }
148 
150  {
151  const sal_uInt16 nIndex((3 * INDEX_COUNT) + nInd);
152 
153  switch(nInd)
154  {
155  case 0:
156  {
157  return impGetOrCreateTargetBitmap(nIndex, tools::Rectangle(Point(72, 66), Size(13, 13)));
158  }
159  case 1:
160  {
161  return impGetOrCreateTargetBitmap(nIndex, tools::Rectangle(Point(85, 66), Size(13, 13)));
162  }
163  case 2:
164  {
165  return impGetOrCreateTargetBitmap(nIndex, tools::Rectangle(Point(72, 79), Size(13, 13)));
166  }
167  case 3:
168  {
169  return impGetOrCreateTargetBitmap(nIndex, tools::Rectangle(Point(85, 79), Size(13, 13)));
170  }
171  case 4:
172  {
173  return impGetOrCreateTargetBitmap(nIndex, tools::Rectangle(Point(98, 79), Size(13, 13)));
174  }
175  default: // case 5:
176  {
177  return impGetOrCreateTargetBitmap(nIndex, tools::Rectangle(Point(98, 66), Size(13, 13)));
178  }
179  }
180  }
181 
184  {
185  return impGetOrCreateTargetBitmap((4 * INDEX_COUNT) + nInd, tools::Rectangle(Point(27, nYPos), Size(7, 7)));
186  }
187 
190  {
191  return impGetOrCreateTargetBitmap((5 * INDEX_COUNT) + nInd, tools::Rectangle(Point(34, nYPos), Size(9, 9)));
192  }
193 
196  {
197  return impGetOrCreateTargetBitmap((6 * INDEX_COUNT) + nInd, tools::Rectangle(Point(43, nYPos), Size(11, 11)));
198  }
199 
201  {
202  return impGetOrCreateTargetBitmap((7 * INDEX_COUNT) + nInd, tools::Rectangle(Point(54, nYPos), Size(7, 9)));
203  }
204 
206  {
207  return impGetOrCreateTargetBitmap((8 * INDEX_COUNT) + nInd, tools::Rectangle(Point(61, nYPos), Size(9, 11)));
208  }
209 
211  {
212  return impGetOrCreateTargetBitmap((9 * INDEX_COUNT) + nInd, tools::Rectangle(Point(70, nYPos), Size(9, 7)));
213  }
214 
216  {
217  return impGetOrCreateTargetBitmap((10 * INDEX_COUNT) + nInd, tools::Rectangle(Point(79, nYPos), Size(11, 9)));
218  }
219 
221  {
222  return impGetOrCreateTargetBitmap((11 * INDEX_COUNT) + nInd, tools::Rectangle(Point(90, nYPos), Size(7, 7)));
223  }
224 
226  {
227  return impGetOrCreateTargetBitmap((12 * INDEX_COUNT) + nInd, tools::Rectangle(Point(97, nYPos), Size(9, 9)));
228  }
229 
231  {
232  return impGetOrCreateTargetBitmap((13 * INDEX_COUNT) + nInd, tools::Rectangle(Point(106, nYPos), Size(11, 11)));
233  }
234 
236  {
237  return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 0, tools::Rectangle(Point(0, 68), Size(15, 15)));
238  }
239 
241  {
242  return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 1, tools::Rectangle(Point(15, 76), Size(9, 9)));
243  }
244 
246  {
247  return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 2, tools::Rectangle(Point(15, 67), Size(9, 9)));
248  }
249 
250  case BitmapMarkerKind::Anchor: // AnchorTR for SW
252  {
253  return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 3, tools::Rectangle(Point(24, 67), Size(24, 24)));
254  }
255 
256  // add AnchorPressed to be able to animate anchor control
259  {
260  return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 4, tools::Rectangle(Point(48, 67), Size(24, 24)));
261  }
262  }
263 }
264 
265 
267  pObj(nullptr),
268  pPV(nullptr),
269  pHdlList(nullptr),
270  eKind(SdrHdlKind::Move),
271  nRotationAngle(0),
272  nObjHdlNum(0),
273  nPolyNum(0),
274  nPPntNum(0),
275  nSourceHdlNum(0),
276  bSelect(false),
277  b1PixMore(false),
278  bPlusHdl(false),
279  mbMoveOutside(false),
280  mbMouseOver(false)
281 {
282 }
283 
284 SdrHdl::SdrHdl(const Point& rPnt, SdrHdlKind eNewKind):
285  pObj(nullptr),
286  pPV(nullptr),
287  pHdlList(nullptr),
288  aPos(rPnt),
289  eKind(eNewKind),
290  nRotationAngle(0),
291  nObjHdlNum(0),
292  nPolyNum(0),
293  nPPntNum(0),
294  nSourceHdlNum(0),
295  bSelect(false),
296  b1PixMore(false),
297  bPlusHdl(false),
298  mbMoveOutside(false),
299  mbMouseOver(false)
300 {
301 }
302 
304 {
306 }
307 
308 void SdrHdl::Set1PixMore(bool bJa)
309 {
310  if(b1PixMore != bJa)
311  {
312  b1PixMore = bJa;
313 
314  // create new display
315  Touch();
316  }
317 }
318 
319 void SdrHdl::SetMoveOutside( bool bMoveOutside )
320 {
321  if(mbMoveOutside != bMoveOutside)
322  {
323  mbMoveOutside = bMoveOutside;
324 
325  // create new display
326  Touch();
327  }
328 }
329 
331 {
332  if(nRotationAngle != n)
333  {
334  nRotationAngle = n;
335 
336  // create new display
337  Touch();
338  }
339 }
340 
341 void SdrHdl::SetPos(const Point& rPnt)
342 {
343  if(aPos != rPnt)
344  {
345  // remember new position
346  aPos = rPnt;
347 
348  // create new display
349  Touch();
350  }
351 }
352 
353 void SdrHdl::SetSelected(bool bJa)
354 {
355  if(bSelect != bJa)
356  {
357  // remember new value
358  bSelect = bJa;
359 
360  // create new display
361  Touch();
362  }
363 }
364 
366 {
367  if(pHdlList != pList)
368  {
369  // remember list
370  pHdlList = pList;
371 
372  // now its possible to create graphic representation
373  Touch();
374  }
375 }
376 
377 void SdrHdl::SetObj(SdrObject* pNewObj)
378 {
379  if(pObj != pNewObj)
380  {
381  // remember new object
382  pObj = pNewObj;
383 
384  // graphic representation may have changed
385  Touch();
386  }
387 }
388 
390 {
391  // force update of graphic representation
393 }
394 
396 {
397 
398  // OVERLAYMANAGER
400 }
401 
403 {
404  // first throw away old one
406 
408  {
411 
412  bool bRot = pHdlList->IsRotateShear();
413  if(pObj)
415  if(bRot)
416  {
417  // red rotation handles
418  if(pObj && bSelect)
419  eColIndex = BitmapColorIndex::Red;
420  else
421  eColIndex = BitmapColorIndex::LightRed;
422  }
423 
424  switch(eKind)
425  {
426  case SdrHdlKind::Move:
427  {
429  break;
430  }
435  {
436  // corner handles
437  if(bRot)
438  {
439  eKindOfMarker = BitmapMarkerKind::Circ_7x7;
440  }
441  else
442  {
443  eKindOfMarker = BitmapMarkerKind::Rect_7x7;
444  }
445  break;
446  }
447  case SdrHdlKind::Upper:
448  case SdrHdlKind::Lower:
449  {
450  // Upper/Lower handles
451  if(bRot)
452  {
453  eKindOfMarker = BitmapMarkerKind::Elli_9x7;
454  }
455  else
456  {
457  eKindOfMarker = BitmapMarkerKind::Rect_7x7;
458  }
459  break;
460  }
461  case SdrHdlKind::Left:
462  case SdrHdlKind::Right:
463  {
464  // Left/Right handles
465  if(bRot)
466  {
467  eKindOfMarker = BitmapMarkerKind::Elli_7x9;
468  }
469  else
470  {
471  eKindOfMarker = BitmapMarkerKind::Rect_7x7;
472  }
473  break;
474  }
475  case SdrHdlKind::Poly:
476  {
477  if(bRot)
478  {
480  }
481  else
482  {
484  }
485  break;
486  }
487  case SdrHdlKind::BezierWeight: // weight at poly
488  {
489  eKindOfMarker = BitmapMarkerKind::Circ_7x7;
490  break;
491  }
492  case SdrHdlKind::Circle:
493  {
494  eKindOfMarker = BitmapMarkerKind::Rect_11x11;
495  break;
496  }
497  case SdrHdlKind::Ref1:
498  case SdrHdlKind::Ref2:
499  {
500  eKindOfMarker = BitmapMarkerKind::Crosshair;
501  break;
502  }
503  case SdrHdlKind::Glue:
504  {
505  eKindOfMarker = BitmapMarkerKind::Glue;
506  break;
507  }
508  case SdrHdlKind::Anchor:
509  {
510  eKindOfMarker = BitmapMarkerKind::Anchor;
511  break;
512  }
513  case SdrHdlKind::User:
514  {
515  break;
516  }
517  // top right anchor for SW
519  {
520  eKindOfMarker = BitmapMarkerKind::AnchorTR;
521  break;
522  }
523 
524  // for SJ and the CustomShapeHandles:
526  {
528  eColIndex = BitmapColorIndex::Yellow;
529  break;
530  }
531  default:
532  break;
533  }
534 
535  SdrMarkView* pView = pHdlList->GetView();
536  SdrPageView* pPageView = pView->GetSdrPageView();
537 
538  if(pPageView)
539  {
540  for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
541  {
542  // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
543  const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
544 
545  if(rPageWindow.GetPaintWindow().OutputToWindow())
546  {
547  Point aMoveOutsideOffset(0, 0);
548  OutputDevice& rOutDev = rPageWindow.GetPaintWindow().GetOutputDevice();
549 
550  // add offset if necessary
552  {
553  Size aOffset = rOutDev.PixelToLogic(Size(4, 4));
554 
556  aMoveOutsideOffset.AdjustY( -(aOffset.Width()) );
558  aMoveOutsideOffset.AdjustY(aOffset.Height() );
560  aMoveOutsideOffset.AdjustX( -(aOffset.Width()) );
562  aMoveOutsideOffset.AdjustX(aOffset.Height() );
563  }
564 
566  if (xManager.is())
567  {
568  basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
569  std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject;
570  if (getenv ("SVX_DRAW_HANDLES") && (eKindOfMarker == BitmapMarkerKind::Rect_7x7 || eKindOfMarker == BitmapMarkerKind::Rect_9x9 || eKindOfMarker == BitmapMarkerKind::Rect_11x11))
571  {
572  double fSize = 7.0;
573  switch (eKindOfMarker)
574  {
576  fSize = 9.0;
577  break;
579  fSize = 11.0;
580  break;
581  default:
582  break;
583  }
584  float fScalingFactor = rOutDev.GetDPIScaleFactor();
585  basegfx::B2DSize aB2DSize(fSize * fScalingFactor, fSize * fScalingFactor);
586 
587  Color aHandleFillColor(COL_LIGHTGREEN);
588  switch (eColIndex)
589  {
591  aHandleFillColor = COL_CYAN;
592  break;
594  aHandleFillColor = COL_LIGHTCYAN;
595  break;
597  aHandleFillColor = COL_RED;
598  break;
600  aHandleFillColor = COL_LIGHTRED;
601  break;
603  aHandleFillColor = COL_YELLOW;
604  break;
605  default:
606  break;
607  }
608  pNewOverlayObject.reset(new sdr::overlay::OverlayHandle(aPosition, aB2DSize, /*HandleStrokeColor*/COL_BLACK, aHandleFillColor));
609  }
610  else
611  {
612  pNewOverlayObject = CreateOverlayObject(
613  aPosition, eColIndex, eKindOfMarker,
614  aMoveOutsideOffset);
615  }
616 
617  // OVERLAYMANAGER
619  std::move(pNewOverlayObject),
620  rPageWindow.GetObjectContact(),
621  *xManager);
622  }
623  }
624  }
625  }
626  }
627 }
628 
630 {
631  BitmapMarkerKind eRetval(eKnd);
632 
633  switch(eKnd)
634  {
638 
641 
644  //case BitmapMarkerKind::Customshape_11x11: eRetval = ; break;
645 
647 
649 
652 
653  // let anchor blink with its pressed state
655 
656  // same for AnchorTR
658  default:
659  break;
660  }
661 
662  return eRetval;
663 }
664 
665 namespace
666 {
667 
668 OUString appendMarkerName(BitmapMarkerKind eKindOfMarker)
669 {
670  switch(eKindOfMarker)
671  {
673  return "rect7";
675  return "rect9";
677  return "rect11";
679  return "rect13";
682  return "circ7";
685  return "circ9";
688  return "circ11";
690  return "elli7x9";
692  return "elli9x11";
694  return "elli9x7";
696  return "elli11x9";
698  return "rectplus7";
700  return "rectplus9";
702  return "rectplus11";
704  return "cross";
707  return "anchor";
710  return "anchor-pressed";
712  return "glue-selected";
714  return "glue-unselected";
715  default:
716  break;
717  }
718  return OUString();
719 }
720 
721 OUString appendMarkerColor(BitmapColorIndex eIndex)
722 {
723  switch(eIndex)
724  {
726  return "1";
728  return "2";
730  return "3";
732  return "4";
734  return "5";
736  return "6";
737  default:
738  break;
739  }
740  return OUString();
741 }
742 
743 BitmapEx ImpGetBitmapEx(BitmapMarkerKind eKindOfMarker, BitmapColorIndex eIndex)
744 {
745  // use this code path only when we use HiDPI (for now)
746  if (Application::GetDefaultDevice()->GetDPIScalePercentage() > 100)
747  {
748  OUString sMarkerPrefix("svx/res/marker-");
749 
750  OUString sMarkerName = appendMarkerName(eKindOfMarker);
751  if (!sMarkerName.isEmpty())
752  {
753  BitmapEx aBitmapEx;
754 
755  if (eKindOfMarker == BitmapMarkerKind::Crosshair
756  || eKindOfMarker == BitmapMarkerKind::Anchor
757  || eKindOfMarker == BitmapMarkerKind::AnchorTR
758  || eKindOfMarker == BitmapMarkerKind::AnchorPressed
759  || eKindOfMarker == BitmapMarkerKind::AnchorPressedTR
760  || eKindOfMarker == BitmapMarkerKind::Glue
761  || eKindOfMarker == BitmapMarkerKind::Glue_Deselected)
762  {
763  aBitmapEx = vcl::bitmap::loadFromName(sMarkerPrefix + sMarkerName + ".png");
764  }
765  else
766  {
767  aBitmapEx = vcl::bitmap::loadFromName(sMarkerPrefix + sMarkerName + "-" + appendMarkerColor(eIndex) + ".png");
768  }
769 
770  if (!aBitmapEx.IsEmpty())
771  return aBitmapEx;
772  }
773  }
774 
775  // if we can't load the marker...
776 
777  static vcl::DeleteOnDeinit< SdrHdlBitmapSet > aModernSet(new SdrHdlBitmapSet);
778  return aModernSet.get()->GetBitmapEx(eKindOfMarker, sal_uInt16(eIndex));
779 }
780 
781 } // end anonymous namespace
782 
783 std::unique_ptr<sdr::overlay::OverlayObject> SdrHdl::CreateOverlayObject(
784  const basegfx::B2DPoint& rPos,
785  BitmapColorIndex eColIndex, BitmapMarkerKind eKindOfMarker, Point aMoveOutsideOffset)
786 {
787  std::unique_ptr<sdr::overlay::OverlayObject> pRetval;
788 
789  // support bigger sizes
790  bool bForceBiggerSize(false);
791 
792  if(pHdlList->GetHdlSize() > 3)
793  {
794  switch(eKindOfMarker)
795  {
800  {
801  // #i121463# For anchor, do not simply make bigger because of HdlSize,
802  // do it dependent of IsSelected() which Writer can set in drag mode
803  if(IsSelected())
804  {
805  bForceBiggerSize = true;
806  }
807  break;
808  }
809  default:
810  {
811  bForceBiggerSize = true;
812  break;
813  }
814  }
815  }
816 
817  if(bForceBiggerSize)
818  {
819  eKindOfMarker = GetNextBigger(eKindOfMarker);
820  }
821 
822  // This handle has the focus, visualize it
823  if(IsFocusHdl() && pHdlList && pHdlList->GetFocusHdl() == this)
824  {
825  // create animated handle
826  BitmapMarkerKind eNextBigger = GetNextBigger(eKindOfMarker);
827 
828  if(eNextBigger == eKindOfMarker)
829  {
830  // this may happen for the not supported getting-bigger types.
831  // Choose an alternative here
832  switch(eKindOfMarker)
833  {
836  case BitmapMarkerKind::Elli_9x11: eNextBigger = BitmapMarkerKind::Elli_11x9; break;
837  case BitmapMarkerKind::Elli_11x9: eNextBigger = BitmapMarkerKind::Elli_9x11; break;
839 
841  eNextBigger = BitmapMarkerKind::Glue;
842  break;
843 
845  eNextBigger = BitmapMarkerKind::Crosshair;
846  break;
848  eNextBigger = BitmapMarkerKind::Glue;
849  break;
850  default:
851  break;
852  }
853  }
854 
855  // create animated handle
856  BitmapEx aBmpEx1 = ImpGetBitmapEx(eKindOfMarker, eColIndex);
857  BitmapEx aBmpEx2 = ImpGetBitmapEx(eNextBigger, eColIndex);
858 
859  // #i53216# Use system cursor blink time. Use the unsigned value.
860  const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
861  const sal_uInt64 nBlinkTime(rStyleSettings.GetCursorBlinkTime());
862 
863  if(eKindOfMarker == BitmapMarkerKind::Anchor || eKindOfMarker == BitmapMarkerKind::AnchorPressed)
864  {
865  // when anchor is used take upper left as reference point inside the handle
866  pRetval.reset(new sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime));
867  }
868  else if(eKindOfMarker == BitmapMarkerKind::AnchorTR || eKindOfMarker == BitmapMarkerKind::AnchorPressedTR)
869  {
870  // AnchorTR for SW, take top right as (0,0)
871  pRetval.reset(new sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime,
872  static_cast<sal_uInt16>(aBmpEx1.GetSizePixel().Width() - 1), 0,
873  static_cast<sal_uInt16>(aBmpEx2.GetSizePixel().Width() - 1), 0));
874  }
875  else
876  {
877  // create centered handle as default
878  pRetval.reset(new sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime,
879  static_cast<sal_uInt16>(aBmpEx1.GetSizePixel().Width() - 1) >> 1,
880  static_cast<sal_uInt16>(aBmpEx1.GetSizePixel().Height() - 1) >> 1,
881  static_cast<sal_uInt16>(aBmpEx2.GetSizePixel().Width() - 1) >> 1,
882  static_cast<sal_uInt16>(aBmpEx2.GetSizePixel().Height() - 1) >> 1));
883  }
884  }
885  else
886  {
887  // create normal handle: use ImpGetBitmapEx(...) now
888  BitmapEx aBmpEx = ImpGetBitmapEx(eKindOfMarker, eColIndex);
889 
890  // When the image with handles is not found, the bitmap returned is
891  // empty. This is a problem when we use LibreOffice as a library
892  // (through LOKit - for example on Android) even when we don't show
893  // the handles, because the hit test would always return false.
894  //
895  // This HACK replaces the empty bitmap with a black 13x13 bitmap handle
896  // so that the hit test works for this case.
897  if (aBmpEx.IsEmpty())
898  {
899  aBmpEx = BitmapEx(Size(13, 13), 24);
900  aBmpEx.Erase(COL_BLACK);
901  }
902 
903  if(eKindOfMarker == BitmapMarkerKind::Anchor || eKindOfMarker == BitmapMarkerKind::AnchorPressed)
904  {
905  // upper left as reference point inside the handle for AnchorPressed, too
906  pRetval.reset(new sdr::overlay::OverlayBitmapEx(rPos, aBmpEx));
907  }
908  else if(eKindOfMarker == BitmapMarkerKind::AnchorTR || eKindOfMarker == BitmapMarkerKind::AnchorPressedTR)
909  {
910  // AnchorTR for SW, take top right as (0,0)
911  pRetval.reset(new sdr::overlay::OverlayBitmapEx(rPos, aBmpEx,
912  static_cast<sal_uInt16>(aBmpEx.GetSizePixel().Width() - 1), 0));
913  }
914  else
915  {
916  sal_uInt16 nCenX(static_cast<sal_uInt16>(aBmpEx.GetSizePixel().Width() - 1) >> 1);
917  sal_uInt16 nCenY(static_cast<sal_uInt16>(aBmpEx.GetSizePixel().Height() - 1) >> 1);
918 
919  if(aMoveOutsideOffset.X() > 0)
920  {
921  nCenX = 0;
922  }
923  else if(aMoveOutsideOffset.X() < 0)
924  {
925  nCenX = static_cast<sal_uInt16>(aBmpEx.GetSizePixel().Width() - 1);
926  }
927 
928  if(aMoveOutsideOffset.Y() > 0)
929  {
930  nCenY = 0;
931  }
932  else if(aMoveOutsideOffset.Y() < 0)
933  {
934  nCenY = static_cast<sal_uInt16>(aBmpEx.GetSizePixel().Height() - 1);
935  }
936 
937  // create centered handle as default
938  pRetval.reset(new sdr::overlay::OverlayBitmapEx(rPos, aBmpEx, nCenX, nCenY));
939  }
940  }
941 
942  return pRetval;
943 }
944 
945 bool SdrHdl::IsHdlHit(const Point& rPnt) const
946 {
947  // OVERLAYMANAGER
948  basegfx::B2DPoint aPosition(rPnt.X(), rPnt.Y());
949  return maOverlayGroup.isHitLogic(aPosition);
950 }
951 
953 {
954  PointerStyle ePtr=PointerStyle::Move;
956  const bool bRot=pHdlList!=nullptr && pHdlList->IsRotateShear();
957  const bool bDis=pHdlList!=nullptr && pHdlList->IsDistortShear();
958  if (bSize && pHdlList!=nullptr && (bRot || bDis)) {
959  switch (eKind) {
961  case SdrHdlKind::LowerLeft: case SdrHdlKind::LowerRight: ePtr=bRot ? PointerStyle::Rotate : PointerStyle::RefHand; break;
962  case SdrHdlKind::Left : case SdrHdlKind::Right: ePtr=PointerStyle::VShear; break;
963  case SdrHdlKind::Upper: case SdrHdlKind::Lower: ePtr=PointerStyle::HShear; break;
964  default:
965  break;
966  }
967  } else {
968  // When resizing rotated rectangles, rotate the mouse cursor slightly, too
969  if (bSize && nRotationAngle!=0) {
970  long nHdlAngle=0;
971  switch (eKind) {
972  case SdrHdlKind::LowerRight: nHdlAngle=31500; break;
973  case SdrHdlKind::Lower: nHdlAngle=27000; break;
974  case SdrHdlKind::LowerLeft: nHdlAngle=22500; break;
975  case SdrHdlKind::Left : nHdlAngle=18000; break;
976  case SdrHdlKind::UpperLeft: nHdlAngle=13500; break;
977  case SdrHdlKind::Upper: nHdlAngle=9000; break;
978  case SdrHdlKind::UpperRight: nHdlAngle=4500; break;
979  case SdrHdlKind::Right: nHdlAngle=0; break;
980  default:
981  break;
982  }
983  // a little bit more (for rounding)
984  nHdlAngle = NormAngle36000(nHdlAngle + nRotationAngle + 2249);
985  nHdlAngle/=4500;
986  switch (static_cast<sal_uInt8>(nHdlAngle)) {
987  case 0: ePtr=PointerStyle::ESize; break;
988  case 1: ePtr=PointerStyle::NESize; break;
989  case 2: ePtr=PointerStyle::NSize; break;
990  case 3: ePtr=PointerStyle::NWSize; break;
991  case 4: ePtr=PointerStyle::WSize; break;
992  case 5: ePtr=PointerStyle::SWSize; break;
993  case 6: ePtr=PointerStyle::SSize; break;
994  case 7: ePtr=PointerStyle::SESize; break;
995  } // switch
996  } else {
997  switch (eKind) {
998  case SdrHdlKind::UpperLeft: ePtr=PointerStyle::NWSize; break;
999  case SdrHdlKind::Upper: ePtr=PointerStyle::NSize; break;
1000  case SdrHdlKind::UpperRight: ePtr=PointerStyle::NESize; break;
1001  case SdrHdlKind::Left : ePtr=PointerStyle::WSize; break;
1002  case SdrHdlKind::Right: ePtr=PointerStyle::ESize; break;
1003  case SdrHdlKind::LowerLeft: ePtr=PointerStyle::SWSize; break;
1004  case SdrHdlKind::Lower: ePtr=PointerStyle::SSize; break;
1005  case SdrHdlKind::LowerRight: ePtr=PointerStyle::SESize; break;
1006  case SdrHdlKind::Poly : ePtr=PointerStyle::MovePoint; break;
1007  case SdrHdlKind::Circle : ePtr=PointerStyle::Hand; break;
1008  case SdrHdlKind::Ref1 : ePtr=PointerStyle::RefHand; break;
1009  case SdrHdlKind::Ref2 : ePtr=PointerStyle::RefHand; break;
1010  case SdrHdlKind::BezierWeight : ePtr=PointerStyle::MoveBezierWeight; break;
1011  case SdrHdlKind::Glue : ePtr=PointerStyle::MovePoint; break;
1012  case SdrHdlKind::CustomShape1 : ePtr=PointerStyle::Hand; break;
1013  default:
1014  break;
1015  }
1016  }
1017  }
1018  return ePtr;
1019 }
1020 
1022 {
1023  switch(eKind)
1024  {
1025  case SdrHdlKind::UpperLeft:
1026  case SdrHdlKind::Upper:
1028  case SdrHdlKind::Left:
1029  case SdrHdlKind::Right:
1030  case SdrHdlKind::LowerLeft:
1031  case SdrHdlKind::Lower:
1033  {
1034  // if it's an activated TextEdit, it's moved to extended points
1035  return !pHdlList || !pHdlList->IsMoveOutside();
1036  }
1037 
1038  case SdrHdlKind::Move: // handle to move object
1039  case SdrHdlKind::Poly: // selected point of polygon or curve
1040  case SdrHdlKind::BezierWeight: // weight at a curve
1041  case SdrHdlKind::Circle: // angle of circle segments, corner radius of rectangles
1042  case SdrHdlKind::Ref1: // reference point 1, e. g. center of rotation
1043  case SdrHdlKind::Ref2: // reference point 2, e. g. endpoint of reflection axis
1044  case SdrHdlKind::Glue: // glue point
1045 
1046  // for SJ and the CustomShapeHandles:
1048 
1049  case SdrHdlKind::User:
1050  {
1051  return true;
1052  }
1053 
1054  default:
1055  {
1056  return false;
1057  }
1058  }
1059 }
1060 
1061 void SdrHdl::onMouseEnter(const MouseEvent& /*rMEvt*/)
1062 {
1063 }
1064 
1066 {
1067 }
1068 
1070 {
1071 }
1072 
1074 {
1076 }
1077 
1079  std::unique_ptr<sdr::overlay::OverlayObject> pOverlayObject,
1080  const sdr::contact::ObjectContact& rObjectContact,
1081  sdr::overlay::OverlayManager& rOverlayManager)
1082 {
1083  // check if we have an OverlayObject
1084  if(!pOverlayObject)
1085  {
1086  return;
1087  }
1088 
1089  // Add GridOffset for non-linear ViewToDevice transformation (calc)
1090  if(nullptr != GetObj() && rObjectContact.supportsGridOffsets())
1091  {
1092  basegfx::B2DVector aOffset(0.0, 0.0);
1093  const sdr::contact::ViewObjectContact& rVOC(GetObj()->GetViewContact().GetViewObjectContact(
1094  const_cast<sdr::contact::ObjectContact&>(rObjectContact)));
1095 
1096  rObjectContact.calculateGridOffsetForViewOjectContact(aOffset, rVOC);
1097 
1098  if(!aOffset.equalZero())
1099  {
1100  pOverlayObject->setOffset(aOffset);
1101  }
1102  }
1103 
1104  // add to OverlayManager
1105  rOverlayManager.add(*pOverlayObject);
1106 
1107  // add to local OverlayObjectList - ownership change (!)
1108  maOverlayGroup.append(std::move(pOverlayObject));
1109 }
1110 
1111 SdrHdlColor::SdrHdlColor(const Point& rRef, Color aCol, const Size& rSize, bool bLum)
1112 : SdrHdl(rRef, SdrHdlKind::Color),
1113  aMarkerSize(rSize),
1114  bUseLuminance(bLum)
1115 {
1116  if(IsUseLuminance())
1117  aCol = GetLuminance(aCol);
1118 
1119  // remember color
1120  aMarkerColor = aCol;
1121 }
1122 
1124 {
1125 }
1126 
1128 {
1129  // first throw away old one
1130  GetRidOfIAObject();
1131 
1132  if(pHdlList)
1133  {
1134  SdrMarkView* pView = pHdlList->GetView();
1135 
1136  if(pView && !pView->areMarkHandlesHidden())
1137  {
1138  SdrPageView* pPageView = pView->GetSdrPageView();
1139 
1140  if(pPageView)
1141  {
1142  for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
1143  {
1144  const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1145 
1146  if(rPageWindow.GetPaintWindow().OutputToWindow())
1147  {
1148  const rtl::Reference< sdr::overlay::OverlayManager >& xManager = rPageWindow.GetOverlayManager();
1149  if (xManager.is())
1150  {
1152  basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
1153  std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject(new
1155  aPosition,
1156  aBmpCol,
1157  static_cast<sal_uInt16>(aBmpCol.GetSizePixel().Width() - 1) >> 1,
1158  static_cast<sal_uInt16>(aBmpCol.GetSizePixel().Height() - 1) >> 1
1159  ));
1160 
1161  // OVERLAYMANAGER
1163  std::move(pNewOverlayObject),
1164  rPageWindow.GetObjectContact(),
1165  *xManager);
1166  }
1167  }
1168  }
1169  }
1170  }
1171  }
1172 }
1173 
1175 {
1176  // get the Bitmap
1179  pWrite->SetBackground(aCol);
1180  pWrite->Erase();
1181 
1182  // draw outer border
1183  sal_Int32 nWidth = aMarkerSize.Width();
1184  sal_Int32 nHeight = aMarkerSize.Height();
1185 
1186  pWrite->SetLineColor(COL_LIGHTGRAY);
1187  pWrite->DrawLine(Point(0, 0), Point(0, nHeight - 1));
1188  pWrite->DrawLine(Point(1, 0), Point(nWidth - 1, 0));
1189  pWrite->SetLineColor(COL_GRAY);
1190  pWrite->DrawLine(Point(1, nHeight - 1), Point(nWidth - 1, nHeight - 1));
1191  pWrite->DrawLine(Point(nWidth - 1, 1), Point(nWidth - 1, nHeight - 2));
1192 
1193  // draw lighter UpperLeft
1194  const Color aLightColor(
1195  static_cast<sal_uInt8>(::std::min(static_cast<sal_Int16>(static_cast<sal_Int16>(aCol.GetRed()) + sal_Int16(0x0040)), sal_Int16(0x00ff))),
1196  static_cast<sal_uInt8>(::std::min(static_cast<sal_Int16>(static_cast<sal_Int16>(aCol.GetGreen()) + sal_Int16(0x0040)), sal_Int16(0x00ff))),
1197  static_cast<sal_uInt8>(::std::min(static_cast<sal_Int16>(static_cast<sal_Int16>(aCol.GetBlue()) + sal_Int16(0x0040)), sal_Int16(0x00ff))));
1198  pWrite->SetLineColor(aLightColor);
1199  pWrite->DrawLine(Point(1, 1), Point(1, nHeight - 2));
1200  pWrite->DrawLine(Point(2, 1), Point(nWidth - 2, 1));
1201 
1202  // draw darker LowerRight
1203  const Color aDarkColor(
1204  static_cast<sal_uInt8>(::std::max(static_cast<sal_Int16>(static_cast<sal_Int16>(aCol.GetRed()) - sal_Int16(0x0040)), sal_Int16(0x0000))),
1205  static_cast<sal_uInt8>(::std::max(static_cast<sal_Int16>(static_cast<sal_Int16>(aCol.GetGreen()) - sal_Int16(0x0040)), sal_Int16(0x0000))),
1206  static_cast<sal_uInt8>(::std::max(static_cast<sal_Int16>(static_cast<sal_Int16>(aCol.GetBlue()) - sal_Int16(0x0040)), sal_Int16(0x0000))));
1207  pWrite->SetLineColor(aDarkColor);
1208  pWrite->DrawLine(Point(2, nHeight - 2), Point(nWidth - 2, nHeight - 2));
1209  pWrite->DrawLine(Point(nWidth - 2, 2), Point(nWidth - 2, nHeight - 3));
1210 
1211  return pWrite->GetBitmapEx(Point(0,0), aMarkerSize);
1212 }
1213 
1215 {
1216  sal_uInt8 aLum = rCol.GetLuminance();
1217  Color aRetval(aLum, aLum, aLum);
1218  return aRetval;
1219 }
1220 
1221 void SdrHdlColor::SetColor(Color aNew, bool bCallLink)
1222 {
1223  if(IsUseLuminance())
1224  aNew = GetLuminance(aNew);
1225 
1226  if(aMarkerColor != aNew)
1227  {
1228  // remember new color
1229  aMarkerColor = aNew;
1230 
1231  // create new display
1232  Touch();
1233 
1234  // tell about change
1235  if(bCallLink)
1236  aColorChangeHdl.Call(this);
1237  }
1238 }
1239 
1240 void SdrHdlColor::SetSize(const Size& rNew)
1241 {
1242  if(rNew != aMarkerSize)
1243  {
1244  // remember new size
1245  aMarkerSize = rNew;
1246 
1247  // create new display
1248  Touch();
1249  }
1250 }
1251 
1252 SdrHdlGradient::SdrHdlGradient(const Point& rRef1, const Point& rRef2, bool bGrad)
1253  : SdrHdl(rRef1, bGrad ? SdrHdlKind::Gradient : SdrHdlKind::Transparence)
1254  , pColHdl1(nullptr)
1255  , pColHdl2(nullptr)
1256  , a2ndPos(rRef2)
1257  , bGradient(bGrad)
1258  , bMoveSingleHandle(false)
1259  , bMoveFirstHandle(false)
1260 {
1261 }
1262 
1264 {
1265 }
1266 
1267 void SdrHdlGradient::Set2ndPos(const Point& rPnt)
1268 {
1269  if(a2ndPos != rPnt)
1270  {
1271  // remember new position
1272  a2ndPos = rPnt;
1273 
1274  // create new display
1275  Touch();
1276  }
1277 }
1278 
1280 {
1281  // first throw away old one
1282  GetRidOfIAObject();
1283 
1284  if(pHdlList)
1285  {
1286  SdrMarkView* pView = pHdlList->GetView();
1287 
1288  if(pView && !pView->areMarkHandlesHidden())
1289  {
1290  SdrPageView* pPageView = pView->GetSdrPageView();
1291 
1292  if(pPageView)
1293  {
1294  for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
1295  {
1296  const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1297 
1298  if(rPageWindow.GetPaintWindow().OutputToWindow())
1299  {
1300  const rtl::Reference< sdr::overlay::OverlayManager >& xManager = rPageWindow.GetOverlayManager();
1301  if (xManager.is())
1302  {
1303  // striped line in between
1304  basegfx::B2DVector aVec(a2ndPos.X() - aPos.X(), a2ndPos.Y() - aPos.Y());
1305  double fVecLen = aVec.getLength();
1306  double fLongPercentArrow = (1.0 - 0.05) * fVecLen;
1307  double fHalfArrowWidth = (0.05 * 0.5) * fVecLen;
1308  aVec.normalize();
1309  basegfx::B2DVector aPerpend(-aVec.getY(), aVec.getX());
1310  sal_Int32 nMidX = static_cast<sal_Int32>(aPos.X() + aVec.getX() * fLongPercentArrow);
1311  sal_Int32 nMidY = static_cast<sal_Int32>(aPos.Y() + aVec.getY() * fLongPercentArrow);
1312  Point aMidPoint(nMidX, nMidY);
1313 
1314  basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
1315  basegfx::B2DPoint aMidPos(aMidPoint.X(), aMidPoint.Y());
1316 
1317  std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject(new
1319  aPosition, aMidPos
1320  ));
1321 
1322  pNewOverlayObject->setBaseColor(IsGradient() ? COL_BLACK : COL_BLUE);
1323 
1324  // OVERLAYMANAGER
1326  std::move(pNewOverlayObject),
1327  rPageWindow.GetObjectContact(),
1328  *xManager);
1329 
1330  // arrowhead
1331  Point aLeft(aMidPoint.X() + static_cast<sal_Int32>(aPerpend.getX() * fHalfArrowWidth),
1332  aMidPoint.Y() + static_cast<sal_Int32>(aPerpend.getY() * fHalfArrowWidth));
1333  Point aRight(aMidPoint.X() - static_cast<sal_Int32>(aPerpend.getX() * fHalfArrowWidth),
1334  aMidPoint.Y() - static_cast<sal_Int32>(aPerpend.getY() * fHalfArrowWidth));
1335 
1336  basegfx::B2DPoint aPositionLeft(aLeft.X(), aLeft.Y());
1337  basegfx::B2DPoint aPositionRight(aRight.X(), aRight.Y());
1338  basegfx::B2DPoint aPosition2(a2ndPos.X(), a2ndPos.Y());
1339 
1340  pNewOverlayObject.reset(new
1342  aPositionLeft,
1343  aPosition2,
1344  aPositionRight,
1345  IsGradient() ? COL_BLACK : COL_BLUE
1346  ));
1347 
1348  // OVERLAYMANAGER
1350  std::move(pNewOverlayObject),
1351  rPageWindow.GetObjectContact(),
1352  *xManager);
1353  }
1354  }
1355  }
1356  }
1357  }
1358  }
1359 }
1360 
1362 {
1363  if(GetObj())
1364  FromIAOToItem(GetObj(), true, true);
1365 }
1366 
1367 void SdrHdlGradient::FromIAOToItem(SdrObject* _pObj, bool bSetItemOnObject, bool bUndo)
1368 {
1369  // from IAO positions and colors to gradient
1370  const SfxItemSet& rSet = _pObj->GetMergedItemSet();
1371 
1372  GradTransGradient aOldGradTransGradient;
1373  GradTransGradient aGradTransGradient;
1374  GradTransVector aGradTransVector;
1375 
1376  OUString aString;
1377 
1378  aGradTransVector.maPositionA = basegfx::B2DPoint(GetPos().X(), GetPos().Y());
1379  aGradTransVector.maPositionB = basegfx::B2DPoint(Get2ndPos().X(), Get2ndPos().Y());
1380  if(pColHdl1)
1381  aGradTransVector.aCol1 = pColHdl1->GetColor();
1382  if(pColHdl2)
1383  aGradTransVector.aCol2 = pColHdl2->GetColor();
1384 
1385  if(IsGradient())
1386  aOldGradTransGradient.aGradient = rSet.Get(XATTR_FILLGRADIENT).GetGradientValue();
1387  else
1388  aOldGradTransGradient.aGradient = rSet.Get(XATTR_FILLFLOATTRANSPARENCE).GetGradientValue();
1389 
1390  // transform vector data to gradient
1391  GradTransformer::VecToGrad(aGradTransVector, aGradTransGradient, aOldGradTransGradient, _pObj, bMoveSingleHandle, bMoveFirstHandle);
1392 
1393  if(bSetItemOnObject)
1394  {
1395  SdrModel& rModel(_pObj->getSdrModelFromSdrObject());
1396  SfxItemSet aNewSet(rModel.GetItemPool());
1397 
1398  if(IsGradient())
1399  {
1400  aString.clear();
1401  XFillGradientItem aNewGradItem(aString, aGradTransGradient.aGradient);
1402  aNewSet.Put(aNewGradItem);
1403  }
1404  else
1405  {
1406  aString.clear();
1407  XFillFloatTransparenceItem aNewTransItem(aString, aGradTransGradient.aGradient);
1408  aNewSet.Put(aNewTransItem);
1409  }
1410 
1411  if(bUndo && rModel.IsUndoEnabled())
1412  {
1413  rModel.BegUndo(SvxResId(IsGradient() ? SIP_XA_FILLGRADIENT : SIP_XA_FILLTRANSPARENCE));
1414  rModel.AddUndo(rModel.GetSdrUndoFactory().CreateUndoAttrObject(*_pObj));
1415  rModel.EndUndo();
1416  }
1417 
1419  }
1420 
1421  // back transformation, set values on pIAOHandle
1422  GradTransformer::GradToVec(aGradTransGradient, aGradTransVector, _pObj);
1423 
1424  SetPos(Point(FRound(aGradTransVector.maPositionA.getX()), FRound(aGradTransVector.maPositionA.getY())));
1425  Set2ndPos(Point(FRound(aGradTransVector.maPositionB.getX()), FRound(aGradTransVector.maPositionB.getY())));
1426  if(pColHdl1)
1427  {
1428  pColHdl1->SetPos(Point(FRound(aGradTransVector.maPositionA.getX()), FRound(aGradTransVector.maPositionA.getY())));
1429  pColHdl1->SetColor(aGradTransVector.aCol1);
1430  }
1431  if(pColHdl2)
1432  {
1433  pColHdl2->SetPos(Point(FRound(aGradTransVector.maPositionB.getX()), FRound(aGradTransVector.maPositionB.getY())));
1434  pColHdl2->SetColor(aGradTransVector.aCol2);
1435  }
1436 }
1437 
1438 
1440 
1442 {
1443  // first throw away old one
1444  GetRidOfIAObject();
1445 
1446  if(pHdlList)
1447  {
1448  SdrMarkView* pView = pHdlList->GetView();
1449 
1450  if(pView && !pView->areMarkHandlesHidden() && pHdl1 && pHdl2)
1451  {
1452  SdrPageView* pPageView = pView->GetSdrPageView();
1453 
1454  if(pPageView)
1455  {
1456  for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
1457  {
1458  const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1459 
1460  if(rPageWindow.GetPaintWindow().OutputToWindow())
1461  {
1462  const rtl::Reference< sdr::overlay::OverlayManager >& xManager = rPageWindow.GetOverlayManager();
1463  if (xManager.is())
1464  {
1465  basegfx::B2DPoint aPosition1(pHdl1->GetPos().X(), pHdl1->GetPos().Y());
1466  basegfx::B2DPoint aPosition2(pHdl2->GetPos().X(), pHdl2->GetPos().Y());
1467 
1468  std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject(new
1470  aPosition1,
1471  aPosition2
1472  ));
1473 
1474  // color(?)
1475  pNewOverlayObject->setBaseColor(COL_LIGHTRED);
1476 
1477  // OVERLAYMANAGER
1479  std::move(pNewOverlayObject),
1480  rPageWindow.GetObjectContact(),
1481  *xManager);
1482  }
1483  }
1484  }
1485  }
1486  }
1487  }
1488 }
1489 
1491 {
1492  return PointerStyle::RefHand;
1493 }
1494 
1495 
1497 
1499 {
1500  // call parent
1502 
1503  // create lines
1504  if(pHdlList)
1505  {
1506  SdrMarkView* pView = pHdlList->GetView();
1507 
1508  if(pView && !pView->areMarkHandlesHidden())
1509  {
1510  SdrPageView* pPageView = pView->GetSdrPageView();
1511 
1512  if(pPageView)
1513  {
1514  for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
1515  {
1516  const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1517 
1518  if(rPageWindow.GetPaintWindow().OutputToWindow())
1519  {
1520  const rtl::Reference< sdr::overlay::OverlayManager >& xManager = rPageWindow.GetOverlayManager();
1521  if (xManager.is())
1522  {
1523  basegfx::B2DPoint aPosition1(pHdl1->GetPos().X(), pHdl1->GetPos().Y());
1524  basegfx::B2DPoint aPosition2(aPos.X(), aPos.Y());
1525 
1526  if(!aPosition1.equal(aPosition2))
1527  {
1528  std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject(new
1530  aPosition1,
1531  aPosition2
1532  ));
1533 
1534  // line part is not hittable
1535  pNewOverlayObject->setHittable(false);
1536 
1537  // color(?)
1538  pNewOverlayObject->setBaseColor(COL_LIGHTBLUE);
1539 
1540  // OVERLAYMANAGER
1542  std::move(pNewOverlayObject),
1543  rPageWindow.GetObjectContact(),
1544  *xManager);
1545  }
1546  }
1547  }
1548  }
1549  }
1550  }
1551  }
1552 }
1553 
1554 
1556 {
1557  aWireframePoly = rWireframePoly;
1558 }
1559 
1561 {
1562  // create lines
1563  if(pHdlList)
1564  {
1565  SdrMarkView* pView = pHdlList->GetView();
1566 
1567  if(pView && !pView->areMarkHandlesHidden())
1568  {
1569  SdrPageView* pPageView = pView->GetSdrPageView();
1570 
1571  if(pPageView)
1572  {
1573  for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
1574  {
1575  const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1576 
1577  if(rPageWindow.GetPaintWindow().OutputToWindow())
1578  {
1579  const rtl::Reference< sdr::overlay::OverlayManager >& xManager = rPageWindow.GetOverlayManager();
1580  if (xManager.is() && aWireframePoly.count())
1581  {
1582  std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject(new
1584  aWireframePoly));
1585 
1586  pNewOverlayObject->setBaseColor(COL_BLACK);
1587 
1588  // OVERLAYMANAGER
1590  std::move(pNewOverlayObject),
1591  rPageWindow.GetObjectContact(),
1592  *xManager);
1593  }
1594  }
1595  }
1596  }
1597  }
1598  }
1599 }
1600 
1601 
1603 {
1604 }
1605 
1607 {
1608  if(nObjHdlNum <= 1 && pObj)
1609  {
1610  // first throw away old one
1611  GetRidOfIAObject();
1612 
1615 
1616  if(pHdlList)
1617  {
1618  SdrMarkView* pView = pHdlList->GetView();
1619 
1620  if(pView && !pView->areMarkHandlesHidden())
1621  {
1622  const SdrEdgeObj* pEdge = static_cast<SdrEdgeObj*>(pObj);
1623 
1624  if(pEdge->GetConnectedNode(nObjHdlNum == 0) != nullptr)
1625  eColIndex = BitmapColorIndex::LightRed;
1626 
1627  if(nPPntNum < 2)
1628  {
1629  // Handle with plus sign inside
1630  eKindOfMarker = BitmapMarkerKind::Circ_7x7;
1631  }
1632 
1633  SdrPageView* pPageView = pView->GetSdrPageView();
1634 
1635  if(pPageView)
1636  {
1637  for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
1638  {
1639  const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1640 
1641  if(rPageWindow.GetPaintWindow().OutputToWindow())
1642  {
1643  const rtl::Reference< sdr::overlay::OverlayManager >& xManager = rPageWindow.GetOverlayManager();
1644  if (xManager.is())
1645  {
1646  basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
1647  std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject(CreateOverlayObject(
1648  aPosition,
1649  eColIndex,
1650  eKindOfMarker));
1651 
1652  // OVERLAYMANAGER
1654  std::move(pNewOverlayObject),
1655  rPageWindow.GetObjectContact(),
1656  *xManager);
1657  }
1658  }
1659  }
1660  }
1661  }
1662  }
1663  }
1664  else
1665  {
1666  // call parent
1668  }
1669 }
1670 
1672 {
1673  if(eLineCode != eCode)
1674  {
1675  // remember new value
1676  eLineCode = eCode;
1677 
1678  // create new display
1679  Touch();
1680  }
1681 }
1682 
1684 {
1685  SdrEdgeObj* pEdge=dynamic_cast<SdrEdgeObj*>( pObj );
1686  if (pEdge==nullptr)
1687  return SdrHdl::GetPointer();
1688  if (nObjHdlNum<=1)
1689  return PointerStyle::MovePoint;
1690  if (IsHorzDrag())
1691  return PointerStyle::ESize;
1692  else
1693  return PointerStyle::SSize;
1694 }
1695 
1697 {
1698  SdrEdgeObj* pEdge=dynamic_cast<SdrEdgeObj*>( pObj );
1699  if (pEdge==nullptr)
1700  return false;
1701  if (nObjHdlNum<=1)
1702  return false;
1703 
1704  SdrEdgeKind eEdgeKind = pEdge->GetObjectItem(SDRATTR_EDGEKIND).GetValue();
1705 
1706  const SdrEdgeInfoRec& rInfo=pEdge->aEdgeInfo;
1707  if (eEdgeKind==SdrEdgeKind::OrthoLines || eEdgeKind==SdrEdgeKind::Bezier)
1708  {
1709  return !rInfo.ImpIsHorzLine(eLineCode,*pEdge->pEdgeTrack);
1710  }
1711  else if (eEdgeKind==SdrEdgeKind::ThreeLines)
1712  {
1713  long nAngle=nObjHdlNum==2 ? rInfo.nAngle1 : rInfo.nAngle2;
1714  return nAngle==0 || nAngle==18000;
1715  }
1716  return false;
1717 }
1718 
1719 
1721 {
1722 }
1723 
1725 {
1726  // first throw away old one
1727  GetRidOfIAObject();
1728 
1729  if(pHdlList)
1730  {
1731  SdrMarkView* pView = pHdlList->GetView();
1732 
1733  if(pView && !pView->areMarkHandlesHidden())
1734  {
1737 
1738  if(nObjHdlNum > 1)
1739  {
1740  eKindOfMarker = BitmapMarkerKind::Rect_7x7;
1741  }
1742 
1743  if(bSelect)
1744  {
1745  eColIndex = BitmapColorIndex::Cyan;
1746  }
1747 
1748  SdrPageView* pPageView = pView->GetSdrPageView();
1749 
1750  if(pPageView)
1751  {
1752  for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
1753  {
1754  const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1755 
1756  if(rPageWindow.GetPaintWindow().OutputToWindow())
1757  {
1758  const rtl::Reference< sdr::overlay::OverlayManager >& xManager = rPageWindow.GetOverlayManager();
1759  if (xManager.is())
1760  {
1761  basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
1762  std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject(CreateOverlayObject(
1763  aPosition,
1764  eColIndex,
1765  eKindOfMarker));
1766 
1767  // OVERLAYMANAGER
1769  std::move(pNewOverlayObject),
1770  rPageWindow.GetObjectContact(),
1771  *xManager);
1772  }
1773  }
1774  }
1775  }
1776  }
1777  }
1778 }
1779 
1781 {
1782  switch (nObjHdlNum)
1783  {
1784  case 0: case 1: return PointerStyle::Hand;
1785  case 2: case 3: return PointerStyle::MovePoint;
1786  case 4: case 5: return SdrHdl::GetPointer(); // will then be rotated appropriately
1787  } // switch
1788  return PointerStyle::NotAllowed;
1789 }
1790 
1791 
1793  SdrHdl(rRect.TopLeft(),SdrHdlKind::Move),
1794  maRect(rRect)
1795 {
1796 }
1797 
1799 {
1800  // first throw away old one
1801  GetRidOfIAObject();
1802 
1803  if(pHdlList)
1804  {
1805  SdrMarkView* pView = pHdlList->GetView();
1806 
1807  if(pView && !pView->areMarkHandlesHidden())
1808  {
1809  SdrPageView* pPageView = pView->GetSdrPageView();
1810 
1811  if(pPageView)
1812  {
1813  for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
1814  {
1815  const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1816 
1817  if(rPageWindow.GetPaintWindow().OutputToWindow())
1818  {
1819  const rtl::Reference< sdr::overlay::OverlayManager >& xManager = rPageWindow.GetOverlayManager();
1820  if (xManager.is())
1821  {
1822  const basegfx::B2DPoint aTopLeft(maRect.Left(), maRect.Top());
1823  const basegfx::B2DPoint aBottomRight(maRect.Right(), maRect.Bottom());
1824  const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
1825  const Color aHilightColor(aSvtOptionsDrawinglayer.getHilightColor());
1826  const double fTransparence(aSvtOptionsDrawinglayer.GetTransparentSelectionPercent() * 0.01);
1827 
1828  std::unique_ptr<sdr::overlay::OverlayRectangle> pNewOverlayObject(new sdr::overlay::OverlayRectangle(
1829  aTopLeft,
1830  aBottomRight,
1831  aHilightColor,
1832  fTransparence,
1833  3.0,
1834  3.0,
1836  true)); // allow animation; the Handle is not shown at text edit time
1837 
1838  pNewOverlayObject->setHittable(false);
1839 
1840  // OVERLAYMANAGER
1842  std::move(pNewOverlayObject),
1843  rPageWindow.GetObjectContact(),
1844  *xManager);
1845  }
1846  }
1847  }
1848  }
1849  }
1850  }
1851 }
1852 
1853 
1854 static bool ImpSdrHdlListSorter(std::unique_ptr<SdrHdl> const& lhs, std::unique_ptr<SdrHdl> const& rhs)
1855 {
1856  SdrHdlKind eKind1=lhs->GetKind();
1857  SdrHdlKind eKind2=rhs->GetKind();
1858  // Level 1: first normal handles, then Glue, then User, then Plus handles, then reference point handles
1859  unsigned n1=1;
1860  unsigned n2=1;
1861  if (eKind1!=eKind2)
1862  {
1863  if (eKind1==SdrHdlKind::Ref1 || eKind1==SdrHdlKind::Ref2 || eKind1==SdrHdlKind::MirrorAxis) n1=5;
1864  else if (eKind1==SdrHdlKind::Glue) n1=2;
1865  else if (eKind1==SdrHdlKind::User) n1=3;
1866  else if (eKind1==SdrHdlKind::SmartTag) n1=0;
1867  if (eKind2==SdrHdlKind::Ref1 || eKind2==SdrHdlKind::Ref2 || eKind2==SdrHdlKind::MirrorAxis) n2=5;
1868  else if (eKind2==SdrHdlKind::Glue) n2=2;
1869  else if (eKind2==SdrHdlKind::User) n2=3;
1870  else if (eKind2==SdrHdlKind::SmartTag) n2=0;
1871  }
1872  if (lhs->IsPlusHdl()) n1=4;
1873  if (rhs->IsPlusHdl()) n2=4;
1874  if (n1==n2)
1875  {
1876  // Level 2: PageView (Pointer)
1877  SdrPageView* pPV1=lhs->GetPageView();
1878  SdrPageView* pPV2=rhs->GetPageView();
1879  if (pPV1==pPV2)
1880  {
1881  // Level 3: Position (x+y)
1882  SdrObject* pObj1=lhs->GetObj();
1883  SdrObject* pObj2=rhs->GetObj();
1884  if (pObj1==pObj2)
1885  {
1886  sal_uInt32 nNum1=lhs->GetObjHdlNum();
1887  sal_uInt32 nNum2=rhs->GetObjHdlNum();
1888  if (nNum1==nNum2)
1889  {
1890  if (eKind1==eKind2)
1891  return lhs<rhs; // Hack, to always get to the same sorting
1892  return static_cast<sal_uInt16>(eKind1)<static_cast<sal_uInt16>(eKind2);
1893  }
1894  else
1895  return nNum1<nNum2;
1896  }
1897  else
1898  {
1899  return pObj1<pObj2;
1900  }
1901  }
1902  else
1903  {
1904  return pPV1<pPV2;
1905  }
1906  }
1907  else
1908  {
1909  return n1<n2;
1910  }
1911 }
1912 
1913 namespace {
1914 
1915 // Helper struct for re-sorting handles
1916 struct ImplHdlAndIndex
1917 {
1918  SdrHdl* mpHdl;
1919  sal_uInt32 mnIndex;
1920 };
1921 
1922 }
1923 
1924 extern "C" {
1925 
1926 // Helper method for sorting handles taking care of OrdNums, keeping order in
1927 // single objects and re-sorting polygon handles intuitively
1928 static int ImplSortHdlFunc( const void* pVoid1, const void* pVoid2 )
1929 {
1930  const ImplHdlAndIndex* p1 = static_cast<ImplHdlAndIndex const *>(pVoid1);
1931  const ImplHdlAndIndex* p2 = static_cast<ImplHdlAndIndex const *>(pVoid2);
1932 
1933  if(p1->mpHdl->GetObj() == p2->mpHdl->GetObj())
1934  {
1935  if(p1->mpHdl->GetObj() && dynamic_cast<const SdrPathObj*>(p1->mpHdl->GetObj()) != nullptr)
1936  {
1937  // same object and a path object
1938  if((p1->mpHdl->GetKind() == SdrHdlKind::Poly || p1->mpHdl->GetKind() == SdrHdlKind::BezierWeight)
1939  && (p2->mpHdl->GetKind() == SdrHdlKind::Poly || p2->mpHdl->GetKind() == SdrHdlKind::BezierWeight))
1940  {
1941  // both handles are point or control handles
1942  if(p1->mpHdl->GetPolyNum() == p2->mpHdl->GetPolyNum())
1943  {
1944  if(p1->mpHdl->GetPointNum() < p2->mpHdl->GetPointNum())
1945  {
1946  return -1;
1947  }
1948  else
1949  {
1950  return 1;
1951  }
1952  }
1953  else if(p1->mpHdl->GetPolyNum() < p2->mpHdl->GetPolyNum())
1954  {
1955  return -1;
1956  }
1957  else
1958  {
1959  return 1;
1960  }
1961  }
1962  }
1963  }
1964  else
1965  {
1966  if(!p1->mpHdl->GetObj())
1967  {
1968  return -1;
1969  }
1970  else if(!p2->mpHdl->GetObj())
1971  {
1972  return 1;
1973  }
1974  else
1975  {
1976  // different objects, use OrdNum for sort
1977  const sal_uInt32 nOrdNum1 = p1->mpHdl->GetObj()->GetOrdNum();
1978  const sal_uInt32 nOrdNum2 = p2->mpHdl->GetObj()->GetOrdNum();
1979 
1980  if(nOrdNum1 < nOrdNum2)
1981  {
1982  return -1;
1983  }
1984  else
1985  {
1986  return 1;
1987  }
1988  }
1989  }
1990 
1991  // fallback to indices
1992  if(p1->mnIndex < p2->mnIndex)
1993  {
1994  return -1;
1995  }
1996  else
1997  {
1998  return 1;
1999  }
2000 }
2001 
2002 }
2003 
2004 void SdrHdlList::TravelFocusHdl(bool bForward)
2005 {
2006  // security correction
2007  if (mnFocusIndex >= GetHdlCount())
2008  mnFocusIndex = SAL_MAX_SIZE;
2009 
2010  if(maList.empty())
2011  return;
2012 
2013  // take care of old handle
2014  const size_t nOldHdlNum(mnFocusIndex);
2015  SdrHdl* pOld = nullptr;
2016  if (nOldHdlNum < GetHdlCount())
2017  pOld = GetHdl(nOldHdlNum);
2018 
2019  if(pOld)
2020  {
2021  // switch off old handle
2022  mnFocusIndex = SAL_MAX_SIZE;
2023  pOld->Touch();
2024  }
2025 
2026  // allocate pointer array for sorted handle list
2027  std::unique_ptr<ImplHdlAndIndex[]> pHdlAndIndex(new ImplHdlAndIndex[maList.size()]);
2028 
2029  // build sorted handle list
2030  for( size_t a = 0; a < maList.size(); ++a)
2031  {
2032  pHdlAndIndex[a].mpHdl = maList[a].get();
2033  pHdlAndIndex[a].mnIndex = a;
2034  }
2035 
2036  qsort(pHdlAndIndex.get(), maList.size(), sizeof(ImplHdlAndIndex), ImplSortHdlFunc);
2037 
2038  // look for old num in sorted array
2039  size_t nOldHdl(nOldHdlNum);
2040 
2041  if(nOldHdlNum != SAL_MAX_SIZE)
2042  {
2043  for(size_t a = 0; a < maList.size(); ++a)
2044  {
2045  if(pHdlAndIndex[a].mpHdl == pOld)
2046  {
2047  nOldHdl = a;
2048  break;
2049  }
2050  }
2051  }
2052 
2053  // build new HdlNum
2054  size_t nNewHdl(nOldHdl);
2055 
2056  // do the focus travel
2057  if(bForward)
2058  {
2059  if(nOldHdl != SAL_MAX_SIZE)
2060  {
2061  if(nOldHdl == maList.size() - 1)
2062  {
2063  // end forward run
2064  nNewHdl = SAL_MAX_SIZE;
2065  }
2066  else
2067  {
2068  // simply the next handle
2069  nNewHdl++;
2070  }
2071  }
2072  else
2073  {
2074  // start forward run at first entry
2075  nNewHdl = 0;
2076  }
2077  }
2078  else
2079  {
2080  if(nOldHdl == SAL_MAX_SIZE)
2081  {
2082  // start backward run at last entry
2083  nNewHdl = maList.size() - 1;
2084 
2085  }
2086  else
2087  {
2088  if(nOldHdl == 0)
2089  {
2090  // end backward run
2091  nNewHdl = SAL_MAX_SIZE;
2092  }
2093  else
2094  {
2095  // simply the previous handle
2096  nNewHdl--;
2097  }
2098  }
2099  }
2100 
2101  // build new HdlNum
2102  sal_uIntPtr nNewHdlNum(nNewHdl);
2103 
2104  // look for old num in sorted array
2105  if(nNewHdl != SAL_MAX_SIZE)
2106  {
2107  SdrHdl* pNew = pHdlAndIndex[nNewHdl].mpHdl;
2108 
2109  for(size_t a = 0; a < maList.size(); ++a)
2110  {
2111  if(maList[a].get() == pNew)
2112  {
2113  nNewHdlNum = a;
2114  break;
2115  }
2116  }
2117  }
2118 
2119  // take care of next handle
2120  if(nOldHdlNum != nNewHdlNum)
2121  {
2122  mnFocusIndex = nNewHdlNum;
2123  if (mnFocusIndex < GetHdlCount())
2124  {
2125  SdrHdl* pNew = GetHdl(mnFocusIndex);
2126  pNew->Touch();
2127  }
2128  }
2129 }
2130 
2132 {
2133  if(mnFocusIndex < GetHdlCount())
2134  return GetHdl(mnFocusIndex);
2135  else
2136  return nullptr;
2137 }
2138 
2140 {
2141  if(pNew)
2142  {
2143  SdrHdl* pActual = GetFocusHdl();
2144 
2145  if(!pActual || pActual != pNew)
2146  {
2147  const size_t nNewHdlNum = GetHdlNum(pNew);
2148 
2149  if(nNewHdlNum != SAL_MAX_SIZE)
2150  {
2151  mnFocusIndex = nNewHdlNum;
2152 
2153  if(pActual)
2154  {
2155  pActual->Touch();
2156  }
2157 
2158  pNew->Touch();
2159  }
2160  }
2161  }
2162 }
2163 
2165 {
2166  SdrHdl* pHdl = GetFocusHdl();
2167 
2168  mnFocusIndex = SAL_MAX_SIZE;
2169 
2170  if(pHdl)
2171  {
2172  pHdl->Touch();
2173  }
2174 }
2175 
2176 
2178 : mnFocusIndex(SAL_MAX_SIZE),
2179  pView(pV)
2180 {
2181  nHdlSize = 3;
2182  bRotateShear = false;
2183  bMoveOutside = false;
2184  bDistortShear = false;
2185 }
2186 
2188 {
2189  Clear();
2190 }
2191 
2192 void SdrHdlList::SetHdlSize(sal_uInt16 nSiz)
2193 {
2194  if(nHdlSize != nSiz)
2195  {
2196  // remember new value
2197  nHdlSize = nSiz;
2198 
2199  // propagate change to IAOs
2200  for(size_t i=0; i<GetHdlCount(); ++i)
2201  {
2202  SdrHdl* pHdl = GetHdl(i);
2203  pHdl->Touch();
2204  }
2205  }
2206 }
2207 
2209 {
2210  if(bMoveOutside != bOn)
2211  {
2212  // remember new value
2213  bMoveOutside = bOn;
2214 
2215  // propagate change to IAOs
2216  for(size_t i=0; i<GetHdlCount(); ++i)
2217  {
2218  SdrHdl* pHdl = GetHdl(i);
2219  pHdl->Touch();
2220  }
2221  }
2222 }
2223 
2225 {
2226  bRotateShear = bOn;
2227 }
2228 
2230 {
2231  bDistortShear = bOn;
2232 }
2233 
2234 std::unique_ptr<SdrHdl> SdrHdlList::RemoveHdl(size_t nNum)
2235 {
2236  std::unique_ptr<SdrHdl> pRetval = std::move(maList[nNum]);
2237  maList.erase(maList.begin() + nNum);
2238 
2239  return pRetval;
2240 }
2241 
2243 {
2244  maList.erase(std::remove_if(maList.begin(), maList.end(),
2245  [&eKind](std::unique_ptr<SdrHdl>& rItem) { return rItem->GetKind() == eKind; }),
2246  maList.end());
2247 }
2248 
2250 {
2251  maList.clear();
2252 
2253  bRotateShear=false;
2254  bDistortShear=false;
2255 }
2256 
2258 {
2259  // remember currently focused handle
2260  SdrHdl* pPrev = GetFocusHdl();
2261 
2262  std::sort( maList.begin(), maList.end(), ImpSdrHdlListSorter );
2263 
2264  // get now and compare
2265  SdrHdl* pNow = GetFocusHdl();
2266 
2267  if(pPrev != pNow)
2268  {
2269 
2270  if(pPrev)
2271  {
2272  pPrev->Touch();
2273  }
2274 
2275  if(pNow)
2276  {
2277  pNow->Touch();
2278  }
2279  }
2280 }
2281 
2282 size_t SdrHdlList::GetHdlNum(const SdrHdl* pHdl) const
2283 {
2284  if (pHdl==nullptr)
2285  return SAL_MAX_SIZE;
2286  auto it = std::find_if( maList.begin(), maList.end(),
2287  [&](const std::unique_ptr<SdrHdl> & p) { return p.get() == pHdl; });
2288  assert(it != maList.end());
2289  if( it == maList.end() )
2290  return SAL_MAX_SIZE;
2291  return it - maList.begin();
2292 }
2293 
2294 void SdrHdlList::AddHdl(std::unique_ptr<SdrHdl> pHdl)
2295 {
2296  assert(pHdl);
2297  pHdl->SetHdlList(this);
2298  maList.push_back(std::move(pHdl));
2299 }
2300 
2301 SdrHdl* SdrHdlList::IsHdlListHit(const Point& rPnt) const
2302 {
2303  SdrHdl* pRet=nullptr;
2304  const size_t nCount=GetHdlCount();
2305  size_t nNum=nCount;
2306  while (nNum>0 && pRet==nullptr)
2307  {
2308  nNum--;
2309  SdrHdl* pHdl=GetHdl(nNum);
2310  if (pHdl->IsHdlHit(rPnt))
2311  pRet=pHdl;
2312  }
2313  return pRet;
2314 }
2315 
2317 {
2318  SdrHdl* pRet=nullptr;
2319  for (size_t i=0; i<GetHdlCount() && pRet==nullptr; ++i)
2320  {
2321  SdrHdl* pHdl=GetHdl(i);
2322  if (pHdl->GetKind()==eKind1)
2323  pRet=pHdl;
2324  }
2325  return pRet;
2326 }
2327 
2329 {
2330  for (auto & pHdl : maList)
2331  pHdl->SetHdlList(&rOther);
2332  rOther.maList.insert(rOther.maList.end(),
2333  std::make_move_iterator(maList.begin()), std::make_move_iterator(maList.end()));
2334  maList.clear();
2335 }
2336 
2338  const Point& rPnt,
2339  SdrHdlKind eNewKind,
2340  double fShearX,
2341  double fRotation)
2342 : SdrHdl(rPnt, eNewKind),
2343  mfShearX(fShearX),
2344  mfRotation(fRotation)
2345 {
2346 }
2347 
2348 
2350 {
2351  int nPixelSize = 0, nX = 0, nY = 0, nOffset = 0;
2352 
2353  if( nSize <= 3 )
2354  {
2355  nPixelSize = 13;
2356  nOffset = 0;
2357  }
2358  else if( nSize <=4 )
2359  {
2360  nPixelSize = 17;
2361  nOffset = 39;
2362  }
2363  else
2364  {
2365  nPixelSize = 21;
2366  nOffset = 90;
2367  }
2368 
2369  switch( eKind )
2370  {
2371  case SdrHdlKind::UpperLeft: nX = 0; nY = 0; break;
2372  case SdrHdlKind::Upper: nX = 1; nY = 0; break;
2373  case SdrHdlKind::UpperRight: nX = 2; nY = 0; break;
2374  case SdrHdlKind::Left: nX = 0; nY = 1; break;
2375  case SdrHdlKind::Right: nX = 2; nY = 1; break;
2376  case SdrHdlKind::LowerLeft: nX = 0; nY = 2; break;
2377  case SdrHdlKind::Lower: nX = 1; nY = 2; break;
2378  case SdrHdlKind::LowerRight: nX = 2; nY = 2; break;
2379  default: break;
2380  }
2381 
2382  tools::Rectangle aSourceRect( Point( nX * nPixelSize + nOffset, nY * nPixelSize), Size(nPixelSize, nPixelSize) );
2383 
2384  BitmapEx aRetval(rBitmap);
2385  aRetval.Crop(aSourceRect);
2386  return aRetval;
2387 }
2388 
2389 
2391 {
2392  // first throw away old one
2393  GetRidOfIAObject();
2394 
2395  SdrMarkView* pView = pHdlList ? pHdlList->GetView() : nullptr;
2396  SdrPageView* pPageView = pView ? pView->GetSdrPageView() : nullptr;
2397 
2398  if( pPageView && !pView->areMarkHandlesHidden() )
2399  {
2400  const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
2401  int nHdlSize = pHdlList->GetHdlSize();
2402 
2403  const BitmapEx aHandlesBitmap(SIP_SA_CROP_MARKERS);
2404  BitmapEx aBmpEx1( GetBitmapForHandle( aHandlesBitmap, nHdlSize ) );
2405 
2406  for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
2407  {
2408  const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
2409 
2410  if(rPageWindow.GetPaintWindow().OutputToWindow())
2411  {
2412  const rtl::Reference< sdr::overlay::OverlayManager >& xManager = rPageWindow.GetOverlayManager();
2413  if (xManager.is())
2414  {
2415  basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
2416 
2417  std::unique_ptr<sdr::overlay::OverlayObject> pOverlayObject;
2418 
2419  // animate focused handles
2420  if(IsFocusHdl() && (pHdlList->GetFocusHdl() == this))
2421  {
2422  if( nHdlSize >= 2 )
2423  nHdlSize = 1;
2424 
2425  BitmapEx aBmpEx2( GetBitmapForHandle( aHandlesBitmap, nHdlSize + 1 ) );
2426 
2427  const sal_uInt64 nBlinkTime = rStyleSettings.GetCursorBlinkTime();
2428 
2429  pOverlayObject.reset(new sdr::overlay::OverlayAnimatedBitmapEx(
2430  aPosition,
2431  aBmpEx1,
2432  aBmpEx2,
2433  nBlinkTime,
2434  static_cast<sal_uInt16>(aBmpEx1.GetSizePixel().Width() - 1) >> 1,
2435  static_cast<sal_uInt16>(aBmpEx1.GetSizePixel().Height() - 1) >> 1,
2436  static_cast<sal_uInt16>(aBmpEx2.GetSizePixel().Width() - 1) >> 1,
2437  static_cast<sal_uInt16>(aBmpEx2.GetSizePixel().Height() - 1) >> 1,
2438  mfShearX,
2439  mfRotation));
2440  }
2441  else
2442  {
2443  // create centered handle as default
2444  pOverlayObject.reset(new sdr::overlay::OverlayBitmapEx(
2445  aPosition,
2446  aBmpEx1,
2447  static_cast<sal_uInt16>(aBmpEx1.GetSizePixel().Width() - 1) >> 1,
2448  static_cast<sal_uInt16>(aBmpEx1.GetSizePixel().Height() - 1) >> 1,
2449  0.0,
2450  mfShearX,
2451  mfRotation));
2452  }
2453 
2454  // OVERLAYMANAGER
2456  std::move(pOverlayObject),
2457  rPageWindow.GetObjectContact(),
2458  *xManager);
2459  }
2460  }
2461  }
2462  }
2463 }
2464 
2465 
2466 // with the correction of crop handling I could get rid of the extra mirroring flag, adapted stuff
2467 // accordingly
2468 
2470  const basegfx::B2DHomMatrix& rObjectTransform,
2471  const Graphic& rGraphic,
2472  double fCropLeft,
2473  double fCropTop,
2474  double fCropRight,
2475  double fCropBottom)
2476 : SdrHdl(Point(), SdrHdlKind::User),
2477  maObjectTransform(rObjectTransform),
2478  maGraphic(rGraphic),
2479  mfCropLeft(fCropLeft),
2480  mfCropTop(fCropTop),
2481  mfCropRight(fCropRight),
2482  mfCropBottom(fCropBottom)
2483 {
2484 }
2485 
2486 namespace {
2487 
2488 void translateRotationToMirroring(basegfx::B2DVector & scale, double * rotate) {
2489  assert(rotate != nullptr);
2490 
2491  // detect 180 degree rotation, this is the same as mirrored in X and Y,
2492  // thus change to mirroring. Prefer mirroring here. Use the equal call
2493  // with getSmallValue here, the original which uses rtl::math::approxEqual
2494  // is too correct here. Maybe this changes with enhanced precision in aw080
2495  // to the better so that this can be reduced to the more precise call again
2496  if(basegfx::fTools::equal(fabs(*rotate), F_PI, 0.000000001))
2497  {
2498  scale.setX(scale.getX() * -1.0);
2499  scale.setY(scale.getY() * -1.0);
2500  *rotate = 0.0;
2501  }
2502 }
2503 
2504 }
2505 
2507 {
2508  GetRidOfIAObject();
2509  SdrMarkView* pView = pHdlList ? pHdlList->GetView() : nullptr;
2510  SdrPageView* pPageView = pView ? pView->GetSdrPageView() : nullptr;
2511 
2512  if(!pPageView || pView->areMarkHandlesHidden())
2513  {
2514  return;
2515  }
2516 
2517  // decompose to have current translate and scale
2518  basegfx::B2DVector aScale, aTranslate;
2519  double fRotate, fShearX;
2520 
2521  maObjectTransform.decompose(aScale, aTranslate, fRotate, fShearX);
2522 
2523  if(aScale.equalZero())
2524  {
2525  return;
2526  }
2527 
2528  translateRotationToMirroring(aScale, &fRotate);
2529 
2530  // remember mirroring, reset at Scale and adapt crop values for usage;
2531  // mirroring can stay in the object transformation, so do not have to
2532  // cope with it here (except later for the CroppedImage transformation,
2533  // see below)
2534  const bool bMirroredX(aScale.getX() < 0.0);
2535  const bool bMirroredY(aScale.getY() < 0.0);
2536  double fCropLeft(mfCropLeft);
2537  double fCropTop(mfCropTop);
2538  double fCropRight(mfCropRight);
2539  double fCropBottom(mfCropBottom);
2540 
2541  if(bMirroredX)
2542  {
2543  aScale.setX(-aScale.getX());
2544  }
2545 
2546  if(bMirroredY)
2547  {
2548  aScale.setY(-aScale.getY());
2549  }
2550 
2551  // create target translate and scale
2552  const basegfx::B2DVector aTargetScale(
2553  aScale.getX() + fCropRight + fCropLeft,
2554  aScale.getY() + fCropBottom + fCropTop);
2555  const basegfx::B2DVector aTargetTranslate(
2556  aTranslate.getX() - fCropLeft,
2557  aTranslate.getY() - fCropTop);
2558 
2559  // create ranges to make comparisons
2560  const basegfx::B2DRange aCurrentForCompare(
2561  aTranslate.getX(), aTranslate.getY(),
2562  aTranslate.getX() + aScale.getX(), aTranslate.getY() + aScale.getY());
2563  basegfx::B2DRange aCropped(
2564  aTargetTranslate.getX(), aTargetTranslate.getY(),
2565  aTargetTranslate.getX() + aTargetScale.getX(), aTargetTranslate.getY() + aTargetScale.getY());
2566 
2567  if(aCropped.isEmpty())
2568  {
2569  // nothing to return since cropped content is completely empty
2570  return;
2571  }
2572 
2573  if(aCurrentForCompare.equal(aCropped))
2574  {
2575  // no crop at all
2576  return;
2577  }
2578 
2579  // back-transform to have values in unit coordinates
2580  basegfx::B2DHomMatrix aBackToUnit;
2581  aBackToUnit.translate(-aTranslate.getX(), -aTranslate.getY());
2582  aBackToUnit.scale(
2583  basegfx::fTools::equalZero(aScale.getX()) ? 1.0 : 1.0 / aScale.getX(),
2584  basegfx::fTools::equalZero(aScale.getY()) ? 1.0 : 1.0 / aScale.getY());
2585 
2586  // transform cropped back to unit coordinates
2587  aCropped.transform(aBackToUnit);
2588 
2589  // prepare crop PolyPolygon
2590  basegfx::B2DPolygon aGraphicOutlinePolygon(
2592  aCropped));
2593  basegfx::B2DPolyPolygon aCropPolyPolygon(aGraphicOutlinePolygon);
2594 
2595  // current range is unit range
2596  basegfx::B2DRange aOverlap(0.0, 0.0, 1.0, 1.0);
2597 
2598  aOverlap.intersect(aCropped);
2599 
2600  if(!aOverlap.isEmpty())
2601  {
2602  aCropPolyPolygon.append(
2604  aOverlap));
2605  }
2606 
2607  // transform to object coordinates to prepare for clip
2608  aCropPolyPolygon.transform(maObjectTransform);
2609  aGraphicOutlinePolygon.transform(maObjectTransform);
2610 
2611  // create cropped transformation
2612  basegfx::B2DHomMatrix aCroppedTransform;
2613 
2614  aCroppedTransform.scale(
2615  aCropped.getWidth(),
2616  aCropped.getHeight());
2617  aCroppedTransform.translate(
2618  aCropped.getMinX(),
2619  aCropped.getMinY());
2620  aCroppedTransform = maObjectTransform * aCroppedTransform;
2621 
2622  // prepare graphic primitive (transformed)
2625  aCroppedTransform,
2626  maGraphic));
2627 
2628  // prepare outline polygon for whole graphic
2629  const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
2630  const basegfx::BColor aHilightColor(aSvtOptionsDrawinglayer.getHilightColor().getBColor());
2633  aGraphicOutlinePolygon,
2634  aHilightColor));
2635 
2636  // combine these
2638  aCombination[0] = aGraphic;
2639  aCombination[1] = aGraphicOutline;
2640 
2641  // embed to MaskPrimitive2D
2644  aCropPolyPolygon,
2645  aCombination));
2646 
2647  // embed to UnifiedTransparencePrimitive2D
2648  const drawinglayer::primitive2d::Primitive2DReference aTransparenceMaskedGraphic(
2651  0.8));
2652 
2653  const drawinglayer::primitive2d::Primitive2DContainer aSequence { aTransparenceMaskedGraphic };
2654 
2655  for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
2656  {
2657  // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
2658  const SdrPageWindow& rPageWindow = *(pPageView->GetPageWindow(b));
2659 
2660  if(rPageWindow.GetPaintWindow().OutputToWindow())
2661  {
2662  const rtl::Reference< sdr::overlay::OverlayManager >& xManager = rPageWindow.GetOverlayManager();
2663  if(xManager.is())
2664  {
2665  std::unique_ptr<sdr::overlay::OverlayObject> pNew(new sdr::overlay::OverlayPrimitive2DSequenceObject(aSequence));
2666 
2667  // only informative object, no hit
2668  pNew->setHittable(false);
2669 
2670  // OVERLAYMANAGER
2672  std::move(pNew),
2673  rPageWindow.GetObjectContact(),
2674  *xManager);
2675  }
2676  }
2677  }
2678 }
2679 
2680 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::unique_ptr< SdrHdl > RemoveHdl(size_t nNum)
Definition: svdhdl.cxx:2234
long Width() const
BitmapEx GetBitmapForHandle(const BitmapEx &rBitmap, int nSize)
Definition: svdhdl.cxx:2349
rtl::Reference< sdr::overlay::OverlayManager > const & GetOverlayManager() const
SdrHdlKind eKind
Definition: svdhdl.hxx:144
SdrHdlGradient(const Point &rRef1, const Point &rRef2, bool bGrad)
Definition: svdhdl.cxx:1252
bool Erase(const Color &rFillColor)
void setX(double fX)
SdrHdl * pHdl2
Definition: svdhdl.hxx:346
size_t GetHdlNum(const SdrHdl *pHdl) const
Definition: svdhdl.cxx:2282
virtual void CreateB2dIAObject() override
Definition: svdhdl.cxx:1606
SdrHdlList * pHdlList
Definition: svdhdl.hxx:138
constexpr::Color COL_BLACK(0x00, 0x00, 0x00)
bool IsMoveOutside() const
Definition: svdhdl.hxx:467
XGradient aGradient
Definition: gradtrns.hxx:40
sal_uInt8 GetRed() const
void SetPos(const Point &rPnt)
Definition: svdhdl.cxx:341
virtual void CreateB2dIAObject() override
Definition: svdhdl.cxx:1441
long FRound(double fVal)
SdrMarkView * GetView() const
Definition: svdhdl.hxx:455
void insertNewlyCreatedOverlayObjectForSdrHdl(std::unique_ptr< sdr::overlay::OverlayObject > pOverlayObject, const sdr::contact::ObjectContact &rObjectContact, sdr::overlay::OverlayManager &rOverlayManager)
Definition: svdhdl.cxx:1078
basegfx::B2DPoint maPositionB
Definition: gradtrns.hxx:32
void Set2ndPos(const Point &rPnt)
Definition: svdhdl.cxx:1267
constexpr::Color COL_LIGHTGREEN(0x00, 0xFF, 0x00)
double mfCropRight
Definition: svdhdl.hxx:517
static bool equal(const double &rfValA, const double &rfValB)
#define INDEX_COUNT
Definition: svdhdl.cxx:98
long Height() const
Size aMarkerSize
Definition: svdhdl.hxx:258
SdrHdlKind
Definition: svdhdl.hxx:52
int n1
constexpr::Color COL_RED(0x80, 0x00, 0x00)
double mfRotation
Definition: svdhdl.hxx:506
virtual ~ImpEdgeHdl() override
Definition: svdhdl.cxx:1602
Utility class SdrEdgeInfoRec.
Definition: svdoedge.hxx:74
virtual void calculateGridOffsetForViewOjectContact(basegfx::B2DVector &rTarget, const ViewObjectContact &rClient) const
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
sal_uInt8 GetLuminance() const
bool IsHorzDrag() const
Definition: svdhdl.cxx:1696
double getX() const
static void VecToGrad(GradTransVector const &rV, GradTransGradient &rG, GradTransGradient const &rGOld, const SdrObject *pObj, bool bMoveSingle, bool bMoveFirst)
Definition: gradtrns.cxx:182
bool bRotateShear
Definition: svdhdl.hxx:436
virtual bool IsFocusHdl() const
Definition: svdhdl.cxx:1021
void SetSelected(bool bJa=true)
Definition: svdhdl.cxx:353
SdrEdgeInfoRec aEdgeInfo
Definition: svdoedge.hxx:146
constexpr::Color COL_GRAY(0x80, 0x80, 0x80)
SdrObject * pObj
Definition: svdhdl.hxx:136
double getY() const
SdrObject * GetObj() const
Definition: svdhdl.hxx:203
SdrCropViewHdl(const basegfx::B2DHomMatrix &rObjectTransform, const Graphic &rGraphic, double fCropLeft, double fCropTop, double fCropRight, double fCropBottom)
Definition: svdhdl.cxx:2469
constexpr::Color COL_LIGHTRED(0xFF, 0x00, 0x00)
void append(std::unique_ptr< OverlayObject > pOverlayObject)
basegfx::B2DPolyPolygon aWireframePoly
Definition: svdhdl.hxx:375
const Point & GetPos() const
Definition: svdhdl.hxx:197
constexpr::Color COL_LIGHTGRAY(0xC0, 0xC0, 0xC0)
bool IsUseLuminance() const
Definition: svdhdl.hxx:280
bool IsRotateShear() const
Definition: svdhdl.hxx:469
constexpr::Color COL_YELLOW(0xFF, 0xFF, 0x00)
long NormAngle36000(long a)
Normalize angle to -180.00..179.99.
Definition: svdtrans.cxx:407
SdrHdlColor * pColHdl2
Definition: svdhdl.hxx:296
Graphic maGraphic
Definition: svdhdl.hxx:514
void ResetFocusHdl()
Definition: svdhdl.cxx:2164
virtual void CreateB2dIAObject() override
Definition: svdhdl.cxx:1279
virtual PointerStyle GetPointer() const
Definition: svdhdl.cxx:952
const Point & Get2ndPos() const
Definition: svdhdl.hxx:322
void add(OverlayObject &rOverlayObject)
static OutputDevice * GetDefaultDevice()
#define KIND_COUNT
Definition: svdhdl.cxx:97
constexpr TypedWhichId< SdrEdgeKindItem > SDRATTR_EDGEKIND(SDRATTR_EDGE_FIRST+0)
void SetBackground()
size_t mnFocusIndex
Definition: svdhdl.hxx:431
SdrPageWindow * GetPageWindow(sal_uInt32 nIndex) const
Definition: svdpagv.cxx:81
BitmapMarkerKind
Definition: svdhdl.hxx:95
long Right() const
int n2
constexpr::Color COL_LIGHTCYAN(0x00, 0xFF, 0xFF)
OUString SvxResId(const char *pId)
Definition: dialmgr.cxx:28
const Color & GetColor() const
Definition: svdhdl.hxx:282
bool OutputToWindow() const
#define X
constexpr::Color COL_CYAN(0x00, 0x80, 0x80)
int nCount
IMPL_LINK_NOARG(SdrHdlGradient, ColorChangeHdl, SdrHdlColor *, void)
Definition: svdhdl.cxx:1361
SdrHdlColor(const Point &rRef, Color aCol, const Size &rSize, bool bLuminance)
Definition: svdhdl.cxx:1111
void Clear()
Definition: svdhdl.cxx:2249
long Top() const
void Touch()
Definition: svdhdl.cxx:389
sal_uInt16 GetHdlSize() const
Definition: svdhdl.hxx:465
virtual PointerStyle GetPointer() const override
Definition: svdhdl.cxx:1780
SdrEdgeLineCode
Definition: svdoedge.hxx:71
void DrawLine(const Point &rStartPt, const Point &rEndPt)
sal_uInt8 GetBlue() const
virtual PointerStyle GetPointer() const override
Definition: svdhdl.cxx:1490
void SetDistortShear(bool bOn)
Definition: svdhdl.cxx:2229
bool ImpIsHorzLine(SdrEdgeLineCode eLineCode, const XPolygon &rXP) const
Definition: svdoedge.cxx:109
virtual void CreateB2dIAObject() override
Definition: svdhdl.cxx:1798
sal_uInt16 nHdlSize
Definition: svdhdl.hxx:434
SdrObject * GetConnectedNode(bool bTail1) const override
Definition: svdoedge.cxx:471
void Set1PixMore(bool bJa=true)
Definition: svdhdl.cxx:308
void SetHdlList(SdrHdlList *pList)
Definition: svdhdl.cxx:365
BitmapColorIndex
Definition: svdhdl.hxx:84
const tools::Rectangle maRect
Definition: svdhdl.hxx:418
SdrHdl * IsHdlListHit(const Point &rPnt) const
Definition: svdhdl.cxx:2301
void Sort()
Definition: svdhdl.cxx:2257
static int ImplSortHdlFunc(const void *pVoid1, const void *pVoid2)
Definition: svdhdl.cxx:1928
const SfxPoolItem & GetObjectItem(const sal_uInt16 nWhich) const
Definition: svdobj.cxx:1913
E3dVolumeMarker(const basegfx::B2DPolyPolygon &rWireframePoly)
Definition: svdhdl.cxx:1555
bool isEmpty() const
bool IsEmpty() const
virtual void CreateB2dIAObject()
Definition: svdhdl.cxx:402
void SetLineColor()
bool mbMoveOutside
Definition: svdhdl.hxx:156
double mfShearX
Definition: svdhdl.hxx:505
void SetColor(Color aNew, bool bCallLink=false)
Definition: svdhdl.cxx:1221
void SetRotationAngle(long n)
Definition: svdhdl.cxx:330
void SetObj(SdrObject *pNewObj)
Definition: svdhdl.cxx:377
Point aPos
Definition: svdhdl.hxx:142
constexpr TypedWhichId< XFillGradientItem > XATTR_FILLGRADIENT(XATTR_FILL_FIRST+2)
#define INDIVIDUAL_COUNT
Definition: svdhdl.cxx:99
int i
uno_Any a
void MoveTo(SdrHdlList &rOther)
Definition: svdhdl.cxx:2328
virtual void CreateB2dIAObject() override
Definition: svdhdl.cxx:2390
bool decompose(B2DTuple &rScale, B2DTuple &rTranslate, double &rRotate, double &rShearX) const
basegfx::B2DPoint maPositionA
Definition: gradtrns.hxx:31
bool IsSelected() const
Definition: svdhdl.hxx:206
bool SetOutputSizePixel(const Size &rNewSize, bool bErase=true)
sal_uInt32 nPPntNum
Definition: svdhdl.hxx:149
virtual void onHelpRequest()
is called when help is requested for the area of this handle
Definition: svdhdl.cxx:1065
B2DPolygon createPolygonFromRect(const B2DRectangle &rRect, double fRadiusX, double fRadiusY)
void RemoveAllByKind(SdrHdlKind eKind)
Definition: svdhdl.cxx:2242
static bool equalZero(const double &rfVal)
void FromIAOToItem(SdrObject *pObj, bool bSetItemOnObject, bool bUndo)
Definition: svdhdl.cxx:1367
void SetMergedItemSetAndBroadcast(const SfxItemSet &rSet, bool bClearAllItems=false)
Definition: svdobj.cxx:1923
void TravelFocusHdl(bool bForward)
Definition: svdhdl.cxx:2004
SdrEdgeKind
Definition: sxekitm.hxx:26
long Bottom() const
void scale(double fX, double fY)
SdrModel & getSdrModelFromSdrObject() const
Definition: svdobj.cxx:272
void transform(const basegfx::B2DHomMatrix &rMatrix)
std::deque< std::unique_ptr< SdrHdl > > maList
Definition: svdhdl.hxx:433
void SetMoveOutside(bool bOn)
Definition: svdhdl.cxx:2208
sal_uInt32 nObjHdlNum
Definition: svdhdl.hxx:147
SVX_DLLPRIVATE SdrHdlList(const SdrHdlList &)=delete
void SetHdlSize(sal_uInt16 nSiz)
Definition: svdhdl.cxx:2192
void SetMoveOutside(bool bMoveOutside)
Definition: svdhdl.cxx:319
const sdr::contact::ObjectContact & GetObjectContact() const
Abstract DrawObject.
Definition: svdobj.hxx:312
void intersect(const B2DRange &rRange)
virtual ~SdrHdl()
Definition: svdhdl.cxx:303
#define Y
float GetDPIScaleFactor() const
bool bSelect
Definition: svdhdl.hxx:152
void transform(const basegfx::B2DHomMatrix &rMatrix)
virtual void CreateB2dIAObject() override
Definition: svdhdl.cxx:2506
Point PixelToLogic(const Point &rDevicePt) const
double mfCropLeft
Definition: svdhdl.hxx:515
sal_uInt8 GetGreen() const
SdrHdl * GetFocusHdl() const
Definition: svdhdl.cxx:2131
bool IsGradient() const
Definition: svdhdl.hxx:315
virtual void CreateB2dIAObject() override
Definition: svdhdl.cxx:1498
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
SdrHdl()
Definition: svdhdl.cxx:266
size_t GetHdlCount() const
Definition: svdhdl.hxx:461
SdrHdl * GetHdl(size_t nNum) const
Definition: svdhdl.hxx:462
sdr::overlay::OverlayObjectList maOverlayGroup
Definition: svdhdl.hxx:140
css::uno::Reference< css::graphic::XPrimitive2D > Primitive2DReference
virtual ~SdrHdlLine() override
Definition: svdhdl.cxx:1439
constexpr TypedWhichId< XFillFloatTransparenceItem > XATTR_FILLFLOATTRANSPARENCE(XATTR_FILL_FIRST+11)
sal_uInt32 count() const
bool bMoveFirstHandle
Definition: svdhdl.hxx:306
std::unique_ptr< XPolygon > pEdgeTrack
Definition: svdoedge.hxx:144
void setY(double fY)
sal_uInt64 GetCursorBlinkTime() const
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
bool equalZero() const
unsigned char sal_uInt8
const SdrHdl * pHdl1
Definition: svdhdl.hxx:369
Point a2ndPos
Definition: svdhdl.hxx:299
const SfxItemSet & GetMergedItemSet() const
Definition: svdobj.cxx:1883
virtual SVX_DLLPRIVATE void CreateB2dIAObject() override
Definition: svdhdl.cxx:1127
virtual bool supportsGridOffsets() const
SdrPaintWindow & GetPaintWindow() const
bool bMoveOutside
Definition: svdhdl.hxx:438
#define F_PI18000
void SetFocusHdl(SdrHdl *pNew)
Definition: svdhdl.cxx:2139
bool IsHdlHit(const Point &rPnt) const
Definition: svdhdl.cxx:945
void GetRidOfIAObject()
Definition: svdhdl.cxx:395
long nRotationAngle
Definition: svdhdl.hxx:146
void * p
bool IsDistortShear() const
Definition: svdhdl.hxx:471
bool areMarkHandlesHidden() const
Definition: svdmrkv.hxx:268
basegfx::B2DHomMatrix maObjectTransform
Definition: svdhdl.hxx:513
virtual void CreateB2dIAObject() override
Definition: svdhdl.cxx:1724
static BitmapEx createGluePointBitmap()
Definition: svdhdl.cxx:1073
long Left() const
void translate(double fX, double fY)
PointerStyle
SdrHdlColor * pColHdl1
Definition: svdhdl.hxx:295
virtual ~SdrHdlColor() override
Definition: svdhdl.cxx:1123
basegfx::BColor getBColor() const
struct _ADOUser User
SdrPageView * GetSdrPageView() const
Definition: svdpntv.hxx:310
constexpr::Color COL_LIGHTBLUE(0x00, 0x00, 0xFF)
double getLength() const
bool b1PixMore
Definition: svdhdl.hxx:153
BitmapEx GetBitmapEx(const Point &rSrcPt, const Size &rSize) const
BitmapEx loadFromName(const OUString &rFileName, const ImageLoadFlags eFlags)
std::unique_ptr< sdr::overlay::OverlayObject > CreateOverlayObject(const basegfx::B2DPoint &rPos, BitmapColorIndex eColIndex, BitmapMarkerKind eKindOfMarker, Point aMoveOutsideOffset=Point())
Definition: svdhdl.cxx:783
Link< SdrHdlColor *, void > aColorChangeHdl
Definition: svdhdl.hxx:264
static BitmapMarkerKind GetNextBigger(BitmapMarkerKind eKnd)
Definition: svdhdl.cxx:629
Color aMarkerColor
Definition: svdhdl.hxx:261
virtual void onMouseEnter(const MouseEvent &rMEvt)
is called when the mouse enters the area of this handle.
Definition: svdhdl.cxx:1061
constexpr::Color COL_BLUE(0x00, 0x00, 0x80)
static bool ImpSdrHdlListSorter(std::unique_ptr< SdrHdl > const &lhs, std::unique_ptr< SdrHdl > const &rhs)
Definition: svdhdl.cxx:1854
SdrEdgeLineCode eLineCode
Definition: svdhdl.hxx:387
void SetLineCode(SdrEdgeLineCode eCode)
Definition: svdhdl.cxx:1671
virtual ~SdrHdlBezWgt() override
Definition: svdhdl.cxx:1496
ImpTextframeHdl(const tools::Rectangle &rRect)
Definition: svdhdl.cxx:1792
SVX_DLLPRIVATE BitmapEx CreateColorDropper(Color aCol)
Definition: svdhdl.cxx:1174
bool isHitLogic(const basegfx::B2DPoint &rLogicPosition, double fLogicTolerance=0.0) const
int mnIndex
virtual void CreateB2dIAObject() override
Definition: svdhdl.cxx:1560
virtual ~ImpMeasureHdl() override
Definition: svdhdl.cxx:1720
virtual void onMouseLeave()
is called when the mouse leaves the area of this handle.
Definition: svdhdl.cxx:1069
const Size & GetSizePixel() const
double mfCropTop
Definition: svdhdl.hxx:516
SdrCropHdl(const Point &rPnt, SdrHdlKind eNewKind, double fShearX, double fRotation)
Definition: svdhdl.cxx:2337
SdrHdl * pHdl1
Definition: svdhdl.hxx:345
static void GradToVec(GradTransGradient const &rG, GradTransVector &rV, const SdrObject *pObj)
Definition: gradtrns.cxx:30
bool Crop(const tools::Rectangle &rRectPixel)
bool bMoveSingleHandle
Definition: svdhdl.hxx:305
void SetSize(const Size &rNew)
Definition: svdhdl.cxx:1240
OutputDevice & GetOutputDevice() const
bool bDistortShear
Definition: svdhdl.hxx:437
void SetRotateShear(bool bOn)
Definition: svdhdl.cxx:2224
const Graphic maGraphic
void AddHdl(std::unique_ptr< SdrHdl > pHdl)
Definition: svdhdl.cxx:2294
SdrHdlKind GetKind() const
Definition: svdhdl.hxx:194
virtual PointerStyle GetPointer() const override
Definition: svdhdl.cxx:1683
Utility class SdrEdgeObj.
Definition: svdoedge.hxx:128
static SVX_DLLPRIVATE Color GetLuminance(const Color &rCol)
Definition: svdhdl.cxx:1214
Color getHilightColor() const
virtual ~SdrHdlGradient() override
Definition: svdhdl.cxx:1263
double mfCropBottom
Definition: svdhdl.hxx:518
sal_uInt32 PageWindowCount() const
Definition: svdpagv.hxx:94