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