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 
66 #include <memory>
67 #include <bitmaps.hlst>
68 
69 namespace {
70 
71 // #i15222#
72 // Due to the resource problems in Win95/98 with bitmap resources I
73 // will change this handle bitmap providing class. Old version was splitting
74 // and preparing all small handle bitmaps in device bitmap format, now this will
75 // be done on the fly. Thus, there is only one big bitmap in memory. With
76 // three source bitmaps, this will be 3 system bitmap resources instead of hundreds.
77 // The price for that needs to be evaluated. Maybe we will need another change here
78 // if this is too expensive.
79 class SdrHdlBitmapSet
80 {
81  // the bitmap holding all information
82  BitmapEx maMarkersBitmap;
83 
84  // the cropped Bitmaps for reusage
85  ::std::vector< BitmapEx > maRealMarkers;
86 
87  // helpers
88  BitmapEx& impGetOrCreateTargetBitmap(sal_uInt16 nIndex, const tools::Rectangle& rRectangle);
89 
90 public:
91  explicit SdrHdlBitmapSet();
92 
93  const BitmapEx& GetBitmapEx(BitmapMarkerKind eKindOfMarker, sal_uInt16 nInd);
94 };
95 
96 }
97 
98 #define KIND_COUNT (14)
99 #define INDEX_COUNT (6)
100 #define INDIVIDUAL_COUNT (5)
101 
102 SdrHdlBitmapSet::SdrHdlBitmapSet()
103  : maMarkersBitmap(SIP_SA_MARKERS),
104  // 15 kinds (BitmapMarkerKind) use index [0..5] + 5 extra
105  maRealMarkers((KIND_COUNT * INDEX_COUNT) + INDIVIDUAL_COUNT)
106 {
107 }
108 
109 BitmapEx& SdrHdlBitmapSet::impGetOrCreateTargetBitmap(sal_uInt16 nIndex, const tools::Rectangle& rRectangle)
110 {
111  BitmapEx& rTargetBitmap = maRealMarkers[nIndex];
112 
113  if(rTargetBitmap.IsEmpty())
114  {
115  rTargetBitmap = maMarkersBitmap;
116  rTargetBitmap.Crop(rRectangle);
117  }
118 
119  return rTargetBitmap;
120 }
121 
122 // change getting of bitmap to use the big resource bitmap
123 const BitmapEx& SdrHdlBitmapSet::GetBitmapEx(BitmapMarkerKind eKindOfMarker, sal_uInt16 nInd)
124 {
125  // fill in size and source position in maMarkersBitmap
126  const sal_uInt16 nYPos(nInd * 11);
127 
128  switch(eKindOfMarker)
129  {
130  default:
131  {
132  OSL_FAIL( "Unknown kind of marker." );
133  [[fallthrough]]; // return Rect_9x9 as default
134  }
136  {
137  return impGetOrCreateTargetBitmap((1 * INDEX_COUNT) + nInd, tools::Rectangle(Point(7, nYPos), Size(9, 9)));
138  }
139 
141  {
142  return impGetOrCreateTargetBitmap((0 * INDEX_COUNT) + nInd, tools::Rectangle(Point(0, nYPos), Size(7, 7)));
143  }
144 
146  {
147  return impGetOrCreateTargetBitmap((2 * INDEX_COUNT) + nInd, tools::Rectangle(Point(16, nYPos), Size(11, 11)));
148  }
149 
151  {
152  const sal_uInt16 nIndex((3 * INDEX_COUNT) + nInd);
153 
154  switch(nInd)
155  {
156  case 0:
157  {
158  return impGetOrCreateTargetBitmap(nIndex, tools::Rectangle(Point(72, 66), Size(13, 13)));
159  }
160  case 1:
161  {
162  return impGetOrCreateTargetBitmap(nIndex, tools::Rectangle(Point(85, 66), Size(13, 13)));
163  }
164  case 2:
165  {
166  return impGetOrCreateTargetBitmap(nIndex, tools::Rectangle(Point(72, 79), Size(13, 13)));
167  }
168  case 3:
169  {
170  return impGetOrCreateTargetBitmap(nIndex, tools::Rectangle(Point(85, 79), Size(13, 13)));
171  }
172  case 4:
173  {
174  return impGetOrCreateTargetBitmap(nIndex, tools::Rectangle(Point(98, 79), Size(13, 13)));
175  }
176  default: // case 5:
177  {
178  return impGetOrCreateTargetBitmap(nIndex, tools::Rectangle(Point(98, 66), Size(13, 13)));
179  }
180  }
181  }
182 
185  {
186  return impGetOrCreateTargetBitmap((4 * INDEX_COUNT) + nInd, tools::Rectangle(Point(27, nYPos), Size(7, 7)));
187  }
188 
191  {
192  return impGetOrCreateTargetBitmap((5 * INDEX_COUNT) + nInd, tools::Rectangle(Point(34, nYPos), Size(9, 9)));
193  }
194 
197  {
198  return impGetOrCreateTargetBitmap((6 * INDEX_COUNT) + nInd, tools::Rectangle(Point(43, nYPos), Size(11, 11)));
199  }
200 
202  {
203  return impGetOrCreateTargetBitmap((7 * INDEX_COUNT) + nInd, tools::Rectangle(Point(54, nYPos), Size(7, 9)));
204  }
205 
207  {
208  return impGetOrCreateTargetBitmap((8 * INDEX_COUNT) + nInd, tools::Rectangle(Point(61, nYPos), Size(9, 11)));
209  }
210 
212  {
213  return impGetOrCreateTargetBitmap((9 * INDEX_COUNT) + nInd, tools::Rectangle(Point(70, nYPos), Size(9, 7)));
214  }
215 
217  {
218  return impGetOrCreateTargetBitmap((10 * INDEX_COUNT) + nInd, tools::Rectangle(Point(79, nYPos), Size(11, 9)));
219  }
220 
222  {
223  return impGetOrCreateTargetBitmap((11 * INDEX_COUNT) + nInd, tools::Rectangle(Point(90, nYPos), Size(7, 7)));
224  }
225 
227  {
228  return impGetOrCreateTargetBitmap((12 * INDEX_COUNT) + nInd, tools::Rectangle(Point(97, nYPos), Size(9, 9)));
229  }
230 
232  {
233  return impGetOrCreateTargetBitmap((13 * INDEX_COUNT) + nInd, tools::Rectangle(Point(106, nYPos), Size(11, 11)));
234  }
235 
237  {
238  return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 0, tools::Rectangle(Point(0, 68), Size(15, 15)));
239  }
240 
242  {
243  return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 1, tools::Rectangle(Point(15, 76), Size(9, 9)));
244  }
245 
247  {
248  return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 2, tools::Rectangle(Point(15, 67), Size(9, 9)));
249  }
250 
251  case BitmapMarkerKind::Anchor: // AnchorTR for SW
253  {
254  return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 3, tools::Rectangle(Point(24, 67), Size(24, 24)));
255  }
256 
257  // add AnchorPressed to be able to animate anchor control
260  {
261  return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 4, tools::Rectangle(Point(48, 67), Size(24, 24)));
262  }
263  }
264 }
265 
266 
268  pObj(nullptr),
269  pPV(nullptr),
270  pHdlList(nullptr),
271  eKind(SdrHdlKind::Move),
272  nRotationAngle(0),
273  nObjHdlNum(0),
274  nPolyNum(0),
275  nPPntNum(0),
276  nSourceHdlNum(0),
277  bSelect(false),
278  b1PixMore(false),
279  bPlusHdl(false),
280  mbMoveOutside(false),
281  mbMouseOver(false)
282 {
283 }
284 
285 SdrHdl::SdrHdl(const Point& rPnt, SdrHdlKind eNewKind):
286  pObj(nullptr),
287  pPV(nullptr),
288  pHdlList(nullptr),
289  aPos(rPnt),
290  eKind(eNewKind),
291  nRotationAngle(0),
292  nObjHdlNum(0),
293  nPolyNum(0),
294  nPPntNum(0),
295  nSourceHdlNum(0),
296  bSelect(false),
297  b1PixMore(false),
298  bPlusHdl(false),
299  mbMoveOutside(false),
300  mbMouseOver(false)
301 {
302 }
303 
305 {
307 }
308 
309 void SdrHdl::Set1PixMore(bool bJa)
310 {
311  if(b1PixMore != bJa)
312  {
313  b1PixMore = bJa;
314 
315  // create new display
316  Touch();
317  }
318 }
319 
320 void SdrHdl::SetMoveOutside( bool bMoveOutside )
321 {
322  if(mbMoveOutside != bMoveOutside)
323  {
324  mbMoveOutside = bMoveOutside;
325 
326  // create new display
327  Touch();
328  }
329 }
330 
332 {
333  if(nRotationAngle != n)
334  {
335  nRotationAngle = n;
336 
337  // create new display
338  Touch();
339  }
340 }
341 
342 void SdrHdl::SetPos(const Point& rPnt)
343 {
344  if(aPos != rPnt)
345  {
346  // remember new position
347  aPos = rPnt;
348 
349  // create new display
350  Touch();
351  }
352 }
353 
354 void SdrHdl::SetSelected(bool bJa)
355 {
356  if(bSelect != bJa)
357  {
358  // remember new value
359  bSelect = bJa;
360 
361  // create new display
362  Touch();
363  }
364 }
365 
367 {
368  if(pHdlList != pList)
369  {
370  // remember list
371  pHdlList = pList;
372 
373  // now it's possible to create graphic representation
374  Touch();
375  }
376 }
377 
378 void SdrHdl::SetObj(SdrObject* pNewObj)
379 {
380  if(pObj != pNewObj)
381  {
382  // remember new object
383  pObj = pNewObj;
384 
385  // graphic representation may have changed
386  Touch();
387  }
388 }
389 
391 {
392  // force update of graphic representation
394 }
395 
397 {
398 
399  // OVERLAYMANAGER
401 }
402 
404 {
405  // first throw away old one
407 
409  return;
410 
413 
414  bool bRot = pHdlList->IsRotateShear();
415  if(pObj)
417  if(bRot)
418  {
419  // red rotation handles
420  if(pObj && bSelect)
421  eColIndex = BitmapColorIndex::Red;
422  else
423  eColIndex = BitmapColorIndex::LightRed;
424  }
425 
426  switch(eKind)
427  {
428  case SdrHdlKind::Move:
429  {
431  break;
432  }
437  {
438  // corner handles
439  if(bRot)
440  {
441  eKindOfMarker = BitmapMarkerKind::Circ_7x7;
442  }
443  else
444  {
445  eKindOfMarker = BitmapMarkerKind::Rect_7x7;
446  }
447  break;
448  }
449  case SdrHdlKind::Upper:
450  case SdrHdlKind::Lower:
451  {
452  // Upper/Lower handles
453  if(bRot)
454  {
455  eKindOfMarker = BitmapMarkerKind::Elli_9x7;
456  }
457  else
458  {
459  eKindOfMarker = BitmapMarkerKind::Rect_7x7;
460  }
461  break;
462  }
463  case SdrHdlKind::Left:
464  case SdrHdlKind::Right:
465  {
466  // Left/Right handles
467  if(bRot)
468  {
469  eKindOfMarker = BitmapMarkerKind::Elli_7x9;
470  }
471  else
472  {
473  eKindOfMarker = BitmapMarkerKind::Rect_7x7;
474  }
475  break;
476  }
477  case SdrHdlKind::Poly:
478  {
479  if(bRot)
480  {
482  }
483  else
484  {
486  }
487  break;
488  }
489  case SdrHdlKind::BezierWeight: // weight at poly
490  {
491  eKindOfMarker = BitmapMarkerKind::Circ_7x7;
492  break;
493  }
494  case SdrHdlKind::Circle:
495  {
496  eKindOfMarker = BitmapMarkerKind::Rect_11x11;
497  break;
498  }
499  case SdrHdlKind::Ref1:
500  case SdrHdlKind::Ref2:
501  {
502  eKindOfMarker = BitmapMarkerKind::Crosshair;
503  break;
504  }
505  case SdrHdlKind::Glue:
506  {
507  eKindOfMarker = BitmapMarkerKind::Glue;
508  break;
509  }
510  case SdrHdlKind::Anchor:
511  {
512  eKindOfMarker = BitmapMarkerKind::Anchor;
513  break;
514  }
515  case SdrHdlKind::User:
516  {
517  break;
518  }
519  // top right anchor for SW
521  {
522  eKindOfMarker = BitmapMarkerKind::AnchorTR;
523  break;
524  }
525 
526  // for SJ and the CustomShapeHandles:
528  {
530  eColIndex = BitmapColorIndex::Yellow;
531  break;
532  }
533  default:
534  break;
535  }
536 
537  SdrMarkView* pView = pHdlList->GetView();
538  SdrPageView* pPageView = pView->GetSdrPageView();
539 
540  if(!pPageView)
541  return;
542 
543  for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
544  {
545  // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
546  const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
547 
548  if(rPageWindow.GetPaintWindow().OutputToWindow())
549  {
550  Point aMoveOutsideOffset(0, 0);
551  OutputDevice& rOutDev = rPageWindow.GetPaintWindow().GetOutputDevice();
552 
553  // add offset if necessary
555  {
556  Size aOffset = rOutDev.PixelToLogic(Size(4, 4));
557 
559  aMoveOutsideOffset.AdjustY( -(aOffset.Width()) );
561  aMoveOutsideOffset.AdjustY(aOffset.Height() );
563  aMoveOutsideOffset.AdjustX( -(aOffset.Width()) );
565  aMoveOutsideOffset.AdjustX(aOffset.Height() );
566  }
567 
569  if (xManager.is())
570  {
571  basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
572  std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject;
573  if (getenv ("SVX_DRAW_HANDLES") && (eKindOfMarker == BitmapMarkerKind::Rect_7x7 || eKindOfMarker == BitmapMarkerKind::Rect_9x9 || eKindOfMarker == BitmapMarkerKind::Rect_11x11))
574  {
575  double fSize = 7.0;
576  switch (eKindOfMarker)
577  {
579  fSize = 9.0;
580  break;
582  fSize = 11.0;
583  break;
584  default:
585  break;
586  }
587  float fScalingFactor = rOutDev.GetDPIScaleFactor();
588  basegfx::B2DSize aB2DSize(fSize * fScalingFactor, fSize * fScalingFactor);
589 
590  Color aHandleFillColor(COL_LIGHTGREEN);
591  switch (eColIndex)
592  {
594  aHandleFillColor = COL_CYAN;
595  break;
597  aHandleFillColor = COL_LIGHTCYAN;
598  break;
600  aHandleFillColor = COL_RED;
601  break;
603  aHandleFillColor = COL_LIGHTRED;
604  break;
606  aHandleFillColor = COL_YELLOW;
607  break;
608  default:
609  break;
610  }
611  pNewOverlayObject.reset(new sdr::overlay::OverlayHandle(aPosition, aB2DSize, /*HandleStrokeColor*/COL_BLACK, aHandleFillColor));
612  }
613  else
614  {
615  pNewOverlayObject = CreateOverlayObject(
616  aPosition, eColIndex, eKindOfMarker,
617  aMoveOutsideOffset);
618  }
619 
620  // OVERLAYMANAGER
622  std::move(pNewOverlayObject),
623  rPageWindow.GetObjectContact(),
624  *xManager);
625  }
626  }
627  }
628 }
629 
631 {
632  BitmapMarkerKind eRetval(eKnd);
633 
634  switch(eKnd)
635  {
639 
642 
645  //case BitmapMarkerKind::Customshape_11x11: eRetval = ; break;
646 
648 
650 
653 
654  // let anchor blink with its pressed state
656 
657  // same for AnchorTR
659  default:
660  break;
661  }
662 
663  return eRetval;
664 }
665 
666 namespace
667 {
668 
669 OUString appendMarkerName(BitmapMarkerKind eKindOfMarker)
670 {
671  switch(eKindOfMarker)
672  {
674  return "rect7";
676  return "rect9";
678  return "rect11";
680  return "rect13";
683  return "circ7";
686  return "circ9";
689  return "circ11";
691  return "elli7x9";
693  return "elli9x11";
695  return "elli9x7";
697  return "elli11x9";
699  return "rectplus7";
701  return "rectplus9";
703  return "rectplus11";
705  return "cross";
708  return "anchor";
711  return "anchor-pressed";
713  return "glue-selected";
715  return "glue-unselected";
716  default:
717  break;
718  }
719  return OUString();
720 }
721 
722 OUString appendMarkerColor(BitmapColorIndex eIndex)
723 {
724  switch(eIndex)
725  {
727  return "1";
729  return "2";
731  return "3";
733  return "4";
735  return "5";
737  return "6";
738  default:
739  break;
740  }
741  return OUString();
742 }
743 
744 BitmapEx ImpGetBitmapEx(BitmapMarkerKind eKindOfMarker, BitmapColorIndex eIndex)
745 {
746  // use this code path only when we use HiDPI (for now)
747  if (Application::GetDefaultDevice()->GetDPIScalePercentage() > 100)
748  {
749  OUString sMarkerName = appendMarkerName(eKindOfMarker);
750  if (!sMarkerName.isEmpty())
751  {
752  OUString sMarkerPrefix("svx/res/marker-");
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 {};
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 && 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), vcl::PixelFormat::N24_BPP);
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_deg100) {
970  Degree100 nHdlAngle(0);
971  switch (eKind) {
972  case SdrHdlKind::LowerRight: nHdlAngle=31500_deg100; break;
973  case SdrHdlKind::Lower: nHdlAngle=27000_deg100; break;
974  case SdrHdlKind::LowerLeft: nHdlAngle=22500_deg100; break;
975  case SdrHdlKind::Left : nHdlAngle=18000_deg100; break;
976  case SdrHdlKind::UpperLeft: nHdlAngle=13500_deg100; break;
977  case SdrHdlKind::Upper: nHdlAngle=9000_deg100; break;
978  case SdrHdlKind::UpperRight: nHdlAngle=4500_deg100; break;
979  case SdrHdlKind::Right: nHdlAngle=0_deg100; break;
980  default:
981  break;
982  }
983  // a little bit more (for rounding)
984  nHdlAngle = NormAngle36000(nHdlAngle + nRotationAngle + 2249_deg100);
985  nHdlAngle/=4500_deg100;
986  switch (static_cast<sal_uInt8>(nHdlAngle.get())) {
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: // gluepoint
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  return;
1134 
1135  SdrMarkView* pView = pHdlList->GetView();
1136 
1137  if(!pView || pView->areMarkHandlesHidden())
1138  return;
1139 
1140  SdrPageView* pPageView = pView->GetSdrPageView();
1141 
1142  if(!pPageView)
1143  return;
1144 
1145  for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
1146  {
1147  const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1148 
1149  if(rPageWindow.GetPaintWindow().OutputToWindow())
1150  {
1151  const rtl::Reference< sdr::overlay::OverlayManager >& xManager = rPageWindow.GetOverlayManager();
1152  if (xManager.is())
1153  {
1155  basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
1156  std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject(new
1158  aPosition,
1159  aBmpCol,
1160  static_cast<sal_uInt16>(aBmpCol.GetSizePixel().Width() - 1) >> 1,
1161  static_cast<sal_uInt16>(aBmpCol.GetSizePixel().Height() - 1) >> 1
1162  ));
1163 
1164  // OVERLAYMANAGER
1166  std::move(pNewOverlayObject),
1167  rPageWindow.GetObjectContact(),
1168  *xManager);
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  return;
1286 
1287  SdrMarkView* pView = pHdlList->GetView();
1288 
1289  if(!pView || pView->areMarkHandlesHidden())
1290  return;
1291 
1292  SdrPageView* pPageView = pView->GetSdrPageView();
1293 
1294  if(!pPageView)
1295  return;
1296 
1297  for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
1298  {
1299  const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1300 
1301  if(rPageWindow.GetPaintWindow().OutputToWindow())
1302  {
1303  const rtl::Reference< sdr::overlay::OverlayManager >& xManager = rPageWindow.GetOverlayManager();
1304  if (xManager.is())
1305  {
1306  // striped line in between
1307  basegfx::B2DVector aVec(a2ndPos.X() - aPos.X(), a2ndPos.Y() - aPos.Y());
1308  double fVecLen = aVec.getLength();
1309  double fLongPercentArrow = (1.0 - 0.05) * fVecLen;
1310  double fHalfArrowWidth = (0.05 * 0.5) * fVecLen;
1311  aVec.normalize();
1312  basegfx::B2DVector aPerpend(-aVec.getY(), aVec.getX());
1313  sal_Int32 nMidX = static_cast<sal_Int32>(aPos.X() + aVec.getX() * fLongPercentArrow);
1314  sal_Int32 nMidY = static_cast<sal_Int32>(aPos.Y() + aVec.getY() * fLongPercentArrow);
1315  Point aMidPoint(nMidX, nMidY);
1316 
1317  basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
1318  basegfx::B2DPoint aMidPos(aMidPoint.X(), aMidPoint.Y());
1319 
1320  std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject(new
1322  aPosition, aMidPos
1323  ));
1324 
1325  pNewOverlayObject->setBaseColor(IsGradient() ? COL_BLACK : COL_BLUE);
1326 
1327  // OVERLAYMANAGER
1329  std::move(pNewOverlayObject),
1330  rPageWindow.GetObjectContact(),
1331  *xManager);
1332 
1333  // arrowhead
1334  Point aLeft(aMidPoint.X() + static_cast<sal_Int32>(aPerpend.getX() * fHalfArrowWidth),
1335  aMidPoint.Y() + static_cast<sal_Int32>(aPerpend.getY() * fHalfArrowWidth));
1336  Point aRight(aMidPoint.X() - static_cast<sal_Int32>(aPerpend.getX() * fHalfArrowWidth),
1337  aMidPoint.Y() - static_cast<sal_Int32>(aPerpend.getY() * fHalfArrowWidth));
1338 
1339  basegfx::B2DPoint aPositionLeft(aLeft.X(), aLeft.Y());
1340  basegfx::B2DPoint aPositionRight(aRight.X(), aRight.Y());
1341  basegfx::B2DPoint aPosition2(a2ndPos.X(), a2ndPos.Y());
1342 
1343  pNewOverlayObject.reset(new
1345  aPositionLeft,
1346  aPosition2,
1347  aPositionRight,
1348  IsGradient() ? COL_BLACK : COL_BLUE
1349  ));
1350 
1351  // OVERLAYMANAGER
1353  std::move(pNewOverlayObject),
1354  rPageWindow.GetObjectContact(),
1355  *xManager);
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  aGradTransVector.maPositionA = basegfx::B2DPoint(GetPos().X(), GetPos().Y());
1377  aGradTransVector.maPositionB = basegfx::B2DPoint(Get2ndPos().X(), Get2ndPos().Y());
1378  if(pColHdl1)
1379  aGradTransVector.aCol1 = pColHdl1->GetColor();
1380  if(pColHdl2)
1381  aGradTransVector.aCol2 = pColHdl2->GetColor();
1382 
1383  if(IsGradient())
1384  aOldGradTransGradient.aGradient = rSet.Get(XATTR_FILLGRADIENT).GetGradientValue();
1385  else
1386  aOldGradTransGradient.aGradient = rSet.Get(XATTR_FILLFLOATTRANSPARENCE).GetGradientValue();
1387 
1388  // transform vector data to gradient
1389  GradTransformer::VecToGrad(aGradTransVector, aGradTransGradient, aOldGradTransGradient, _pObj, bMoveSingleHandle, bMoveFirstHandle);
1390 
1391  if(bSetItemOnObject)
1392  {
1393  SdrModel& rModel(_pObj->getSdrModelFromSdrObject());
1394  SfxItemSet aNewSet(rModel.GetItemPool());
1395  const OUString aString;
1396 
1397  if(IsGradient())
1398  {
1399  XFillGradientItem aNewGradItem(aString, aGradTransGradient.aGradient);
1400  aNewSet.Put(aNewGradItem);
1401  }
1402  else
1403  {
1404  XFillFloatTransparenceItem aNewTransItem(aString, aGradTransGradient.aGradient);
1405  aNewSet.Put(aNewTransItem);
1406  }
1407 
1408  if(bUndo && rModel.IsUndoEnabled())
1409  {
1410  rModel.BegUndo(SvxResId(IsGradient() ? SIP_XA_FILLGRADIENT : SIP_XA_FILLTRANSPARENCE));
1411  rModel.AddUndo(rModel.GetSdrUndoFactory().CreateUndoAttrObject(*_pObj));
1412  rModel.EndUndo();
1413  }
1414 
1416  }
1417 
1418  // back transformation, set values on pIAOHandle
1419  GradTransformer::GradToVec(aGradTransGradient, aGradTransVector, _pObj);
1420 
1421  SetPos(Point(FRound(aGradTransVector.maPositionA.getX()), FRound(aGradTransVector.maPositionA.getY())));
1422  Set2ndPos(Point(FRound(aGradTransVector.maPositionB.getX()), FRound(aGradTransVector.maPositionB.getY())));
1423  if(pColHdl1)
1424  {
1425  pColHdl1->SetPos(Point(FRound(aGradTransVector.maPositionA.getX()), FRound(aGradTransVector.maPositionA.getY())));
1426  pColHdl1->SetColor(aGradTransVector.aCol1);
1427  }
1428  if(pColHdl2)
1429  {
1430  pColHdl2->SetPos(Point(FRound(aGradTransVector.maPositionB.getX()), FRound(aGradTransVector.maPositionB.getY())));
1431  pColHdl2->SetColor(aGradTransVector.aCol2);
1432  }
1433 }
1434 
1435 
1437 
1439 {
1440  // first throw away old one
1441  GetRidOfIAObject();
1442 
1443  if(!pHdlList)
1444  return;
1445 
1446  SdrMarkView* pView = pHdlList->GetView();
1447 
1448  if(!(pView && !pView->areMarkHandlesHidden() && pHdl1 && pHdl2))
1449  return;
1450 
1451  SdrPageView* pPageView = pView->GetSdrPageView();
1452 
1453  if(!pPageView)
1454  return;
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 
1488 {
1489  return PointerStyle::RefHand;
1490 }
1491 
1492 
1494 
1496 {
1497  // call parent
1499 
1500  // create lines
1501  if(!pHdlList)
1502  return;
1503 
1504  SdrMarkView* pView = pHdlList->GetView();
1505 
1506  if(!pView || pView->areMarkHandlesHidden())
1507  return;
1508 
1509  SdrPageView* pPageView = pView->GetSdrPageView();
1510 
1511  if(!pPageView)
1512  return;
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 
1553 {
1554  aWireframePoly = rWireframePoly;
1555 }
1556 
1558 {
1559  // create lines
1560  if(!pHdlList)
1561  return;
1562 
1563  SdrMarkView* pView = pHdlList->GetView();
1564 
1565  if(!pView || pView->areMarkHandlesHidden())
1566  return;
1567 
1568  SdrPageView* pPageView = pView->GetSdrPageView();
1569 
1570  if(!pPageView)
1571  return;
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 
1600 {
1601 }
1602 
1604 {
1605  if(nObjHdlNum <= 1 && pObj)
1606  {
1607  // first throw away old one
1608  GetRidOfIAObject();
1609 
1612 
1613  if(pHdlList)
1614  {
1615  SdrMarkView* pView = pHdlList->GetView();
1616 
1617  if(pView && !pView->areMarkHandlesHidden())
1618  {
1619  const SdrEdgeObj* pEdge = static_cast<SdrEdgeObj*>(pObj);
1620 
1621  if(pEdge->GetConnectedNode(nObjHdlNum == 0) != nullptr)
1622  eColIndex = BitmapColorIndex::LightRed;
1623 
1624  if(nPPntNum < 2)
1625  {
1626  // Handle with plus sign inside
1627  eKindOfMarker = BitmapMarkerKind::Circ_7x7;
1628  }
1629 
1630  SdrPageView* pPageView = pView->GetSdrPageView();
1631 
1632  if(pPageView)
1633  {
1634  for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
1635  {
1636  const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1637 
1638  if(rPageWindow.GetPaintWindow().OutputToWindow())
1639  {
1640  const rtl::Reference< sdr::overlay::OverlayManager >& xManager = rPageWindow.GetOverlayManager();
1641  if (xManager.is())
1642  {
1643  basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
1644  std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject(CreateOverlayObject(
1645  aPosition,
1646  eColIndex,
1647  eKindOfMarker));
1648 
1649  // OVERLAYMANAGER
1651  std::move(pNewOverlayObject),
1652  rPageWindow.GetObjectContact(),
1653  *xManager);
1654  }
1655  }
1656  }
1657  }
1658  }
1659  }
1660  }
1661  else
1662  {
1663  // call parent
1665  }
1666 }
1667 
1669 {
1670  if(eLineCode != eCode)
1671  {
1672  // remember new value
1673  eLineCode = eCode;
1674 
1675  // create new display
1676  Touch();
1677  }
1678 }
1679 
1681 {
1682  SdrEdgeObj* pEdge=dynamic_cast<SdrEdgeObj*>( pObj );
1683  if (pEdge==nullptr)
1684  return SdrHdl::GetPointer();
1685  if (nObjHdlNum<=1)
1686  return PointerStyle::MovePoint;
1687  if (IsHorzDrag())
1688  return PointerStyle::ESize;
1689  else
1690  return PointerStyle::SSize;
1691 }
1692 
1694 {
1695  SdrEdgeObj* pEdge=dynamic_cast<SdrEdgeObj*>( pObj );
1696  if (pEdge==nullptr)
1697  return false;
1698  if (nObjHdlNum<=1)
1699  return false;
1700 
1701  SdrEdgeKind eEdgeKind = pEdge->GetObjectItem(SDRATTR_EDGEKIND).GetValue();
1702 
1703  const SdrEdgeInfoRec& rInfo=pEdge->aEdgeInfo;
1704  if (eEdgeKind==SdrEdgeKind::OrthoLines || eEdgeKind==SdrEdgeKind::Bezier)
1705  {
1706  return !rInfo.ImpIsHorzLine(eLineCode,*pEdge->pEdgeTrack);
1707  }
1708  else if (eEdgeKind==SdrEdgeKind::ThreeLines)
1709  {
1710  tools::Long nAngle=nObjHdlNum==2 ? rInfo.nAngle1 : rInfo.nAngle2;
1711  return nAngle==0 || nAngle==18000;
1712  }
1713  return false;
1714 }
1715 
1716 
1718 {
1719 }
1720 
1722 {
1723  // first throw away old one
1724  GetRidOfIAObject();
1725 
1726  if(!pHdlList)
1727  return;
1728 
1729  SdrMarkView* pView = pHdlList->GetView();
1730 
1731  if(!pView || pView->areMarkHandlesHidden())
1732  return;
1733 
1736 
1737  if(nObjHdlNum > 1)
1738  {
1739  eKindOfMarker = BitmapMarkerKind::Rect_7x7;
1740  }
1741 
1742  if(bSelect)
1743  {
1744  eColIndex = BitmapColorIndex::Cyan;
1745  }
1746 
1747  SdrPageView* pPageView = pView->GetSdrPageView();
1748 
1749  if(!pPageView)
1750  return;
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 
1778 {
1779  switch (nObjHdlNum)
1780  {
1781  case 0: case 1: return PointerStyle::Hand;
1782  case 2: case 3: return PointerStyle::MovePoint;
1783  case 4: case 5: return SdrHdl::GetPointer(); // will then be rotated appropriately
1784  } // switch
1785  return PointerStyle::NotAllowed;
1786 }
1787 
1788 
1790  SdrHdl(rRect.TopLeft(),SdrHdlKind::Move),
1791  maRect(rRect)
1792 {
1793 }
1794 
1796 {
1797  // first throw away old one
1798  GetRidOfIAObject();
1799 
1800  if(!pHdlList)
1801  return;
1802 
1803  SdrMarkView* pView = pHdlList->GetView();
1804 
1805  if(!pView || pView->areMarkHandlesHidden())
1806  return;
1807 
1808  SdrPageView* pPageView = pView->GetSdrPageView();
1809 
1810  if(!pPageView)
1811  return;
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 Color aHilightColor(SvtOptionsDrawinglayer::getHilightColor());
1825  const double fTransparence(SvtOptionsDrawinglayer::GetTransparentSelectionPercent() * 0.01);
1826 
1827  std::unique_ptr<sdr::overlay::OverlayRectangle> pNewOverlayObject(new sdr::overlay::OverlayRectangle(
1828  aTopLeft,
1829  aBottomRight,
1830  aHilightColor,
1831  fTransparence,
1832  3.0,
1833  3.0,
1835  true)); // allow animation; the Handle is not shown at text edit time
1836 
1837  pNewOverlayObject->setHittable(false);
1838 
1839  // OVERLAYMANAGER
1841  std::move(pNewOverlayObject),
1842  rPageWindow.GetObjectContact(),
1843  *xManager);
1844  }
1845  }
1846  }
1847 }
1848 
1849 
1850 static bool ImpSdrHdlListSorter(std::unique_ptr<SdrHdl> const& lhs, std::unique_ptr<SdrHdl> const& rhs)
1851 {
1852  SdrHdlKind eKind1=lhs->GetKind();
1853  SdrHdlKind eKind2=rhs->GetKind();
1854  // Level 1: first normal handles, then Glue, then User, then Plus handles, then reference point handles
1855  unsigned n1=1;
1856  unsigned n2=1;
1857  if (eKind1!=eKind2)
1858  {
1859  if (eKind1==SdrHdlKind::Ref1 || eKind1==SdrHdlKind::Ref2 || eKind1==SdrHdlKind::MirrorAxis) n1=5;
1860  else if (eKind1==SdrHdlKind::Glue) n1=2;
1861  else if (eKind1==SdrHdlKind::User) n1=3;
1862  else if (eKind1==SdrHdlKind::SmartTag) n1=0;
1863  if (eKind2==SdrHdlKind::Ref1 || eKind2==SdrHdlKind::Ref2 || eKind2==SdrHdlKind::MirrorAxis) n2=5;
1864  else if (eKind2==SdrHdlKind::Glue) n2=2;
1865  else if (eKind2==SdrHdlKind::User) n2=3;
1866  else if (eKind2==SdrHdlKind::SmartTag) n2=0;
1867  }
1868  if (lhs->IsPlusHdl()) n1=4;
1869  if (rhs->IsPlusHdl()) n2=4;
1870  if (n1==n2)
1871  {
1872  // Level 2: PageView (Pointer)
1873  SdrPageView* pPV1=lhs->GetPageView();
1874  SdrPageView* pPV2=rhs->GetPageView();
1875  if (pPV1==pPV2)
1876  {
1877  // Level 3: Position (x+y)
1878  SdrObject* pObj1=lhs->GetObj();
1879  SdrObject* pObj2=rhs->GetObj();
1880  if (pObj1==pObj2)
1881  {
1882  sal_uInt32 nNum1=lhs->GetObjHdlNum();
1883  sal_uInt32 nNum2=rhs->GetObjHdlNum();
1884  if (nNum1==nNum2)
1885  {
1886  if (eKind1==eKind2)
1887  return lhs<rhs; // Hack, to always get to the same sorting
1888  return static_cast<sal_uInt16>(eKind1)<static_cast<sal_uInt16>(eKind2);
1889  }
1890  else
1891  return nNum1<nNum2;
1892  }
1893  else
1894  {
1895  return pObj1<pObj2;
1896  }
1897  }
1898  else
1899  {
1900  return pPV1<pPV2;
1901  }
1902  }
1903  else
1904  {
1905  return n1<n2;
1906  }
1907 }
1908 
1909 namespace {
1910 
1911 // Helper struct for re-sorting handles
1912 struct ImplHdlAndIndex
1913 {
1914  SdrHdl* mpHdl;
1915  sal_uInt32 mnIndex;
1916 };
1917 
1918 }
1919 
1920 extern "C" {
1921 
1922 // Helper method for sorting handles taking care of OrdNums, keeping order in
1923 // single objects and re-sorting polygon handles intuitively
1924 static int ImplSortHdlFunc( const void* pVoid1, const void* pVoid2 )
1925 {
1926  const ImplHdlAndIndex* p1 = static_cast<ImplHdlAndIndex const *>(pVoid1);
1927  const ImplHdlAndIndex* p2 = static_cast<ImplHdlAndIndex const *>(pVoid2);
1928 
1929  if(p1->mpHdl->GetObj() == p2->mpHdl->GetObj())
1930  {
1931  if(p1->mpHdl->GetObj() && dynamic_cast<const SdrPathObj*>(p1->mpHdl->GetObj()) != nullptr)
1932  {
1933  // same object and a path object
1934  if((p1->mpHdl->GetKind() == SdrHdlKind::Poly || p1->mpHdl->GetKind() == SdrHdlKind::BezierWeight)
1935  && (p2->mpHdl->GetKind() == SdrHdlKind::Poly || p2->mpHdl->GetKind() == SdrHdlKind::BezierWeight))
1936  {
1937  // both handles are point or control handles
1938  if(p1->mpHdl->GetPolyNum() == p2->mpHdl->GetPolyNum())
1939  {
1940  if(p1->mpHdl->GetPointNum() < p2->mpHdl->GetPointNum())
1941  {
1942  return -1;
1943  }
1944  else
1945  {
1946  return 1;
1947  }
1948  }
1949  else if(p1->mpHdl->GetPolyNum() < p2->mpHdl->GetPolyNum())
1950  {
1951  return -1;
1952  }
1953  else
1954  {
1955  return 1;
1956  }
1957  }
1958  }
1959  }
1960  else
1961  {
1962  if(!p1->mpHdl->GetObj())
1963  {
1964  return -1;
1965  }
1966  else if(!p2->mpHdl->GetObj())
1967  {
1968  return 1;
1969  }
1970  else
1971  {
1972  // different objects, use OrdNum for sort
1973  const sal_uInt32 nOrdNum1 = p1->mpHdl->GetObj()->GetOrdNum();
1974  const sal_uInt32 nOrdNum2 = p2->mpHdl->GetObj()->GetOrdNum();
1975 
1976  if(nOrdNum1 < nOrdNum2)
1977  {
1978  return -1;
1979  }
1980  else
1981  {
1982  return 1;
1983  }
1984  }
1985  }
1986 
1987  // fallback to indices
1988  if(p1->mnIndex < p2->mnIndex)
1989  {
1990  return -1;
1991  }
1992  else
1993  {
1994  return 1;
1995  }
1996 }
1997 
1998 }
1999 
2000 void SdrHdlList::TravelFocusHdl(bool bForward)
2001 {
2002  // security correction
2003  if (mnFocusIndex >= GetHdlCount())
2004  mnFocusIndex = SAL_MAX_SIZE;
2005 
2006  if(maList.empty())
2007  return;
2008 
2009  // take care of old handle
2010  const size_t nOldHdlNum(mnFocusIndex);
2011  SdrHdl* pOld = nullptr;
2012  if (nOldHdlNum < GetHdlCount())
2013  pOld = GetHdl(nOldHdlNum);
2014 
2015  if(pOld)
2016  {
2017  // switch off old handle
2018  mnFocusIndex = SAL_MAX_SIZE;
2019  pOld->Touch();
2020  }
2021 
2022  // allocate pointer array for sorted handle list
2023  std::unique_ptr<ImplHdlAndIndex[]> pHdlAndIndex(new ImplHdlAndIndex[maList.size()]);
2024 
2025  // build sorted handle list
2026  for( size_t a = 0; a < maList.size(); ++a)
2027  {
2028  pHdlAndIndex[a].mpHdl = maList[a].get();
2029  pHdlAndIndex[a].mnIndex = a;
2030  }
2031 
2032  qsort(pHdlAndIndex.get(), maList.size(), sizeof(ImplHdlAndIndex), ImplSortHdlFunc);
2033 
2034  // look for old num in sorted array
2035  size_t nOldHdl(nOldHdlNum);
2036 
2037  if(nOldHdlNum != SAL_MAX_SIZE)
2038  {
2039  for(size_t a = 0; a < maList.size(); ++a)
2040  {
2041  if(pHdlAndIndex[a].mpHdl == pOld)
2042  {
2043  nOldHdl = a;
2044  break;
2045  }
2046  }
2047  }
2048 
2049  // build new HdlNum
2050  size_t nNewHdl(nOldHdl);
2051 
2052  // do the focus travel
2053  if(bForward)
2054  {
2055  if(nOldHdl != SAL_MAX_SIZE)
2056  {
2057  if(nOldHdl == maList.size() - 1)
2058  {
2059  // end forward run
2060  nNewHdl = SAL_MAX_SIZE;
2061  }
2062  else
2063  {
2064  // simply the next handle
2065  nNewHdl++;
2066  }
2067  }
2068  else
2069  {
2070  // start forward run at first entry
2071  nNewHdl = 0;
2072  }
2073  }
2074  else
2075  {
2076  if(nOldHdl == SAL_MAX_SIZE)
2077  {
2078  // start backward run at last entry
2079  nNewHdl = maList.size() - 1;
2080 
2081  }
2082  else
2083  {
2084  if(nOldHdl == 0)
2085  {
2086  // end backward run
2087  nNewHdl = SAL_MAX_SIZE;
2088  }
2089  else
2090  {
2091  // simply the previous handle
2092  nNewHdl--;
2093  }
2094  }
2095  }
2096 
2097  // build new HdlNum
2098  sal_uIntPtr nNewHdlNum(nNewHdl);
2099 
2100  // look for old num in sorted array
2101  if(nNewHdl != SAL_MAX_SIZE)
2102  {
2103  SdrHdl* pNew = pHdlAndIndex[nNewHdl].mpHdl;
2104 
2105  for(size_t a = 0; a < maList.size(); ++a)
2106  {
2107  if(maList[a].get() == pNew)
2108  {
2109  nNewHdlNum = a;
2110  break;
2111  }
2112  }
2113  }
2114 
2115  // take care of next handle
2116  if(nOldHdlNum != nNewHdlNum)
2117  {
2118  mnFocusIndex = nNewHdlNum;
2119  if (mnFocusIndex < GetHdlCount())
2120  {
2121  SdrHdl* pNew = GetHdl(mnFocusIndex);
2122  pNew->Touch();
2123  }
2124  }
2125 }
2126 
2128 {
2129  if(mnFocusIndex < GetHdlCount())
2130  return GetHdl(mnFocusIndex);
2131  else
2132  return nullptr;
2133 }
2134 
2136 {
2137  if(!pNew)
2138  return;
2139 
2140  SdrHdl* pActual = GetFocusHdl();
2141 
2142  if(pActual && pActual == pNew)
2143  return;
2144 
2145  const size_t nNewHdlNum = GetHdlNum(pNew);
2146 
2147  if(nNewHdlNum != SAL_MAX_SIZE)
2148  {
2149  mnFocusIndex = nNewHdlNum;
2150 
2151  if(pActual)
2152  {
2153  pActual->Touch();
2154  }
2155 
2156  pNew->Touch();
2157  }
2158 }
2159 
2161 {
2162  SdrHdl* pHdl = GetFocusHdl();
2163 
2164  mnFocusIndex = SAL_MAX_SIZE;
2165 
2166  if(pHdl)
2167  {
2168  pHdl->Touch();
2169  }
2170 }
2171 
2172 
2174 : mnFocusIndex(SAL_MAX_SIZE),
2175  pView(pV)
2176 {
2177  nHdlSize = 3;
2178  bRotateShear = false;
2179  bMoveOutside = false;
2180  bDistortShear = false;
2181 }
2182 
2184 {
2185  Clear();
2186 }
2187 
2188 void SdrHdlList::SetHdlSize(sal_uInt16 nSiz)
2189 {
2190  if(nHdlSize != nSiz)
2191  {
2192  // remember new value
2193  nHdlSize = nSiz;
2194 
2195  // propagate change to IAOs
2196  for(size_t i=0; i<GetHdlCount(); ++i)
2197  {
2198  SdrHdl* pHdl = GetHdl(i);
2199  pHdl->Touch();
2200  }
2201  }
2202 }
2203 
2205 {
2206  if(bMoveOutside != bOn)
2207  {
2208  // remember new value
2209  bMoveOutside = bOn;
2210 
2211  // propagate change to IAOs
2212  for(size_t i=0; i<GetHdlCount(); ++i)
2213  {
2214  SdrHdl* pHdl = GetHdl(i);
2215  pHdl->Touch();
2216  }
2217  }
2218 }
2219 
2221 {
2222  bRotateShear = bOn;
2223 }
2224 
2226 {
2227  bDistortShear = bOn;
2228 }
2229 
2230 std::unique_ptr<SdrHdl> SdrHdlList::RemoveHdl(size_t nNum)
2231 {
2232  std::unique_ptr<SdrHdl> pRetval = std::move(maList[nNum]);
2233  maList.erase(maList.begin() + nNum);
2234 
2235  return pRetval;
2236 }
2237 
2239 {
2240  maList.erase(std::remove_if(maList.begin(), maList.end(),
2241  [&eKind](std::unique_ptr<SdrHdl>& rItem) { return rItem->GetKind() == eKind; }),
2242  maList.end());
2243 }
2244 
2246 {
2247  maList.clear();
2248 
2249  bRotateShear=false;
2250  bDistortShear=false;
2251 }
2252 
2254 {
2255  // remember currently focused handle
2256  SdrHdl* pPrev = GetFocusHdl();
2257 
2258  std::sort( maList.begin(), maList.end(), ImpSdrHdlListSorter );
2259 
2260  // get now and compare
2261  SdrHdl* pNow = GetFocusHdl();
2262 
2263  if(pPrev == pNow)
2264  return;
2265 
2266  if(pPrev)
2267  {
2268  pPrev->Touch();
2269  }
2270 
2271  if(pNow)
2272  {
2273  pNow->Touch();
2274  }
2275 }
2276 
2277 size_t SdrHdlList::GetHdlNum(const SdrHdl* pHdl) const
2278 {
2279  if (pHdl==nullptr)
2280  return SAL_MAX_SIZE;
2281  auto it = std::find_if( maList.begin(), maList.end(),
2282  [&](const std::unique_ptr<SdrHdl> & p) { return p.get() == pHdl; });
2283  assert(it != maList.end());
2284  if( it == maList.end() )
2285  return SAL_MAX_SIZE;
2286  return it - maList.begin();
2287 }
2288 
2289 void SdrHdlList::AddHdl(std::unique_ptr<SdrHdl> pHdl)
2290 {
2291  assert(pHdl);
2292  pHdl->SetHdlList(this);
2293  maList.push_back(std::move(pHdl));
2294 }
2295 
2296 SdrHdl* SdrHdlList::IsHdlListHit(const Point& rPnt) const
2297 {
2298  SdrHdl* pRet=nullptr;
2299  const size_t nCount=GetHdlCount();
2300  size_t nNum=nCount;
2301  while (nNum>0 && pRet==nullptr)
2302  {
2303  nNum--;
2304  SdrHdl* pHdl=GetHdl(nNum);
2305  if (pHdl->IsHdlHit(rPnt))
2306  pRet=pHdl;
2307  }
2308  return pRet;
2309 }
2310 
2312 {
2313  SdrHdl* pRet=nullptr;
2314  for (size_t i=0; i<GetHdlCount() && pRet==nullptr; ++i)
2315  {
2316  SdrHdl* pHdl=GetHdl(i);
2317  if (pHdl->GetKind()==eKind1)
2318  pRet=pHdl;
2319  }
2320  return pRet;
2321 }
2322 
2324 {
2325  for (auto & pHdl : maList)
2326  pHdl->SetHdlList(&rOther);
2327  rOther.maList.insert(rOther.maList.end(),
2328  std::make_move_iterator(maList.begin()), std::make_move_iterator(maList.end()));
2329  maList.clear();
2330 }
2331 
2333  const Point& rPnt,
2334  SdrHdlKind eNewKind,
2335  double fShearX,
2336  double fRotation)
2337 : SdrHdl(rPnt, eNewKind),
2338  mfShearX(fShearX),
2339  mfRotation(fRotation)
2340 {
2341 }
2342 
2343 
2345 {
2346  int nPixelSize = 0, nX = 0, nY = 0, nOffset = 0;
2347 
2348  if( nSize <= 3 )
2349  {
2350  nPixelSize = 13;
2351  nOffset = 0;
2352  }
2353  else if( nSize <=4 )
2354  {
2355  nPixelSize = 17;
2356  nOffset = 39;
2357  }
2358  else
2359  {
2360  nPixelSize = 21;
2361  nOffset = 90;
2362  }
2363 
2364  switch( eKind )
2365  {
2366  case SdrHdlKind::UpperLeft: nX = 0; nY = 0; break;
2367  case SdrHdlKind::Upper: nX = 1; nY = 0; break;
2368  case SdrHdlKind::UpperRight: nX = 2; nY = 0; break;
2369  case SdrHdlKind::Left: nX = 0; nY = 1; break;
2370  case SdrHdlKind::Right: nX = 2; nY = 1; break;
2371  case SdrHdlKind::LowerLeft: nX = 0; nY = 2; break;
2372  case SdrHdlKind::Lower: nX = 1; nY = 2; break;
2373  case SdrHdlKind::LowerRight: nX = 2; nY = 2; break;
2374  default: break;
2375  }
2376 
2377  tools::Rectangle aSourceRect( Point( nX * nPixelSize + nOffset, nY * nPixelSize), Size(nPixelSize, nPixelSize) );
2378 
2379  BitmapEx aRetval(rBitmap);
2380  aRetval.Crop(aSourceRect);
2381  return aRetval;
2382 }
2383 
2384 
2386 {
2387  // first throw away old one
2388  GetRidOfIAObject();
2389 
2390  SdrMarkView* pView = pHdlList ? pHdlList->GetView() : nullptr;
2391  SdrPageView* pPageView = pView ? pView->GetSdrPageView() : nullptr;
2392 
2393  if( !pPageView || pView->areMarkHandlesHidden() )
2394  return;
2395 
2396  const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
2397  int nHdlSize = pHdlList->GetHdlSize();
2398 
2399  const BitmapEx aHandlesBitmap(SIP_SA_CROP_MARKERS);
2400  BitmapEx aBmpEx1( GetBitmapForHandle( aHandlesBitmap, nHdlSize ) );
2401 
2402  for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
2403  {
2404  const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
2405 
2406  if(rPageWindow.GetPaintWindow().OutputToWindow())
2407  {
2408  const rtl::Reference< sdr::overlay::OverlayManager >& xManager = rPageWindow.GetOverlayManager();
2409  if (xManager.is())
2410  {
2411  basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
2412 
2413  std::unique_ptr<sdr::overlay::OverlayObject> pOverlayObject;
2414 
2415  // animate focused handles
2416  if(IsFocusHdl() && (pHdlList->GetFocusHdl() == this))
2417  {
2418  if( nHdlSize >= 2 )
2419  nHdlSize = 1;
2420 
2421  BitmapEx aBmpEx2( GetBitmapForHandle( aHandlesBitmap, nHdlSize + 1 ) );
2422 
2423  const sal_uInt64 nBlinkTime = rStyleSettings.GetCursorBlinkTime();
2424 
2425  pOverlayObject.reset(new sdr::overlay::OverlayAnimatedBitmapEx(
2426  aPosition,
2427  aBmpEx1,
2428  aBmpEx2,
2429  nBlinkTime,
2430  static_cast<sal_uInt16>(aBmpEx1.GetSizePixel().Width() - 1) >> 1,
2431  static_cast<sal_uInt16>(aBmpEx1.GetSizePixel().Height() - 1) >> 1,
2432  static_cast<sal_uInt16>(aBmpEx2.GetSizePixel().Width() - 1) >> 1,
2433  static_cast<sal_uInt16>(aBmpEx2.GetSizePixel().Height() - 1) >> 1,
2434  mfShearX,
2435  mfRotation));
2436  }
2437  else
2438  {
2439  // create centered handle as default
2440  pOverlayObject.reset(new sdr::overlay::OverlayBitmapEx(
2441  aPosition,
2442  aBmpEx1,
2443  static_cast<sal_uInt16>(aBmpEx1.GetSizePixel().Width() - 1) >> 1,
2444  static_cast<sal_uInt16>(aBmpEx1.GetSizePixel().Height() - 1) >> 1,
2445  0.0,
2446  mfShearX,
2447  mfRotation));
2448  }
2449 
2450  // OVERLAYMANAGER
2452  std::move(pOverlayObject),
2453  rPageWindow.GetObjectContact(),
2454  *xManager);
2455  }
2456  }
2457  }
2458 }
2459 
2460 
2461 // with the correction of crop handling I could get rid of the extra mirroring flag, adapted stuff
2462 // accordingly
2463 
2465  const basegfx::B2DHomMatrix& rObjectTransform,
2466  const Graphic& rGraphic,
2467  double fCropLeft,
2468  double fCropTop,
2469  double fCropRight,
2470  double fCropBottom)
2471 : SdrHdl(Point(), SdrHdlKind::User),
2472  maObjectTransform(rObjectTransform),
2473  maGraphic(rGraphic),
2474  mfCropLeft(fCropLeft),
2475  mfCropTop(fCropTop),
2476  mfCropRight(fCropRight),
2477  mfCropBottom(fCropBottom)
2478 {
2479 }
2480 
2481 namespace {
2482 
2483 void translateRotationToMirroring(basegfx::B2DVector & scale, double * rotate) {
2484  assert(rotate != nullptr);
2485 
2486  // detect 180 degree rotation, this is the same as mirrored in X and Y,
2487  // thus change to mirroring. Prefer mirroring here. Use the equal call
2488  // with getSmallValue here, the original which uses rtl::math::approxEqual
2489  // is too correct here. Maybe this changes with enhanced precision in aw080
2490  // to the better so that this can be reduced to the more precise call again
2491  if(basegfx::fTools::equal(fabs(*rotate), F_PI, 0.000000001))
2492  {
2493  scale.setX(scale.getX() * -1.0);
2494  scale.setY(scale.getY() * -1.0);
2495  *rotate = 0.0;
2496  }
2497 }
2498 
2499 }
2500 
2502 {
2503  GetRidOfIAObject();
2504  SdrMarkView* pView = pHdlList ? pHdlList->GetView() : nullptr;
2505  SdrPageView* pPageView = pView ? pView->GetSdrPageView() : nullptr;
2506 
2507  if(!pPageView || pView->areMarkHandlesHidden())
2508  {
2509  return;
2510  }
2511 
2512  // decompose to have current translate and scale
2513  basegfx::B2DVector aScale, aTranslate;
2514  double fRotate, fShearX;
2515 
2516  maObjectTransform.decompose(aScale, aTranslate, fRotate, fShearX);
2517 
2518  if(aScale.equalZero())
2519  {
2520  return;
2521  }
2522 
2523  translateRotationToMirroring(aScale, &fRotate);
2524 
2525  // remember mirroring, reset at Scale and adapt crop values for usage;
2526  // mirroring can stay in the object transformation, so do not have to
2527  // cope with it here (except later for the CroppedImage transformation,
2528  // see below)
2529  const bool bMirroredX(aScale.getX() < 0.0);
2530  const bool bMirroredY(aScale.getY() < 0.0);
2531  double fCropLeft(mfCropLeft);
2532  double fCropTop(mfCropTop);
2533  double fCropRight(mfCropRight);
2534  double fCropBottom(mfCropBottom);
2535 
2536  if(bMirroredX)
2537  {
2538  aScale.setX(-aScale.getX());
2539  }
2540 
2541  if(bMirroredY)
2542  {
2543  aScale.setY(-aScale.getY());
2544  }
2545 
2546  // create target translate and scale
2547  const basegfx::B2DVector aTargetScale(
2548  aScale.getX() + fCropRight + fCropLeft,
2549  aScale.getY() + fCropBottom + fCropTop);
2550  const basegfx::B2DVector aTargetTranslate(
2551  aTranslate.getX() - fCropLeft,
2552  aTranslate.getY() - fCropTop);
2553 
2554  // create ranges to make comparisons
2555  const basegfx::B2DRange aCurrentForCompare(
2556  aTranslate.getX(), aTranslate.getY(),
2557  aTranslate.getX() + aScale.getX(), aTranslate.getY() + aScale.getY());
2558  basegfx::B2DRange aCropped(
2559  aTargetTranslate.getX(), aTargetTranslate.getY(),
2560  aTargetTranslate.getX() + aTargetScale.getX(), aTargetTranslate.getY() + aTargetScale.getY());
2561 
2562  if(aCropped.isEmpty())
2563  {
2564  // nothing to return since cropped content is completely empty
2565  return;
2566  }
2567 
2568  if(aCurrentForCompare.equal(aCropped))
2569  {
2570  // no crop at all
2571  return;
2572  }
2573 
2574  // back-transform to have values in unit coordinates
2575  basegfx::B2DHomMatrix aBackToUnit;
2576  aBackToUnit.translate(-aTranslate.getX(), -aTranslate.getY());
2577  aBackToUnit.scale(
2578  basegfx::fTools::equalZero(aScale.getX()) ? 1.0 : 1.0 / aScale.getX(),
2579  basegfx::fTools::equalZero(aScale.getY()) ? 1.0 : 1.0 / aScale.getY());
2580 
2581  // transform cropped back to unit coordinates
2582  aCropped.transform(aBackToUnit);
2583 
2584  // prepare crop PolyPolygon
2585  basegfx::B2DPolygon aGraphicOutlinePolygon(
2587  aCropped));
2588  basegfx::B2DPolyPolygon aCropPolyPolygon(aGraphicOutlinePolygon);
2589 
2590  // current range is unit range
2591  basegfx::B2DRange aOverlap(0.0, 0.0, 1.0, 1.0);
2592 
2593  aOverlap.intersect(aCropped);
2594 
2595  if(!aOverlap.isEmpty())
2596  {
2597  aCropPolyPolygon.append(
2599  aOverlap));
2600  }
2601 
2602  // transform to object coordinates to prepare for clip
2603  aCropPolyPolygon.transform(maObjectTransform);
2604  aGraphicOutlinePolygon.transform(maObjectTransform);
2605 
2606  // create cropped transformation
2607  basegfx::B2DHomMatrix aCroppedTransform;
2608 
2609  aCroppedTransform.scale(
2610  aCropped.getWidth(),
2611  aCropped.getHeight());
2612  aCroppedTransform.translate(
2613  aCropped.getMinX(),
2614  aCropped.getMinY());
2615  aCroppedTransform = maObjectTransform * aCroppedTransform;
2616 
2617  // prepare graphic primitive (transformed)
2620  aCroppedTransform,
2621  maGraphic));
2622 
2623  // prepare outline polygon for whole graphic
2624  const basegfx::BColor aHilightColor(SvtOptionsDrawinglayer::getHilightColor().getBColor());
2627  aGraphicOutlinePolygon,
2628  aHilightColor));
2629 
2630  // combine these
2632  aCombination[0] = aGraphic;
2633  aCombination[1] = aGraphicOutline;
2634 
2635  // embed to MaskPrimitive2D
2638  aCropPolyPolygon,
2639  std::move(aCombination)));
2640 
2641  // embed to UnifiedTransparencePrimitive2D
2642  const drawinglayer::primitive2d::Primitive2DReference aTransparenceMaskedGraphic(
2645  0.8));
2646 
2647  const drawinglayer::primitive2d::Primitive2DContainer aSequence { aTransparenceMaskedGraphic };
2648 
2649  for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
2650  {
2651  // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
2652  const SdrPageWindow& rPageWindow = *(pPageView->GetPageWindow(b));
2653 
2654  if(rPageWindow.GetPaintWindow().OutputToWindow())
2655  {
2656  const rtl::Reference< sdr::overlay::OverlayManager >& xManager = rPageWindow.GetOverlayManager();
2657  if(xManager.is())
2658  {
2659  std::unique_ptr<sdr::overlay::OverlayObject> pNew(new sdr::overlay::OverlayPrimitive2DSequenceObject(drawinglayer::primitive2d::Primitive2DContainer(aSequence)));
2660 
2661  // only informative object, no hit
2662  pNew->setHittable(false);
2663 
2664  // OVERLAYMANAGER
2666  std::move(pNew),
2667  rPageWindow.GetObjectContact(),
2668  *xManager);
2669  }
2670  }
2671  }
2672 }
2673 
2674 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::unique_ptr< SdrHdl > RemoveHdl(size_t nNum)
Definition: svdhdl.cxx:2230
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:2344
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:1252
bool Erase(const Color &rFillColor)
SdrHdl * pHdl2
Definition: svdhdl.hxx:346
size_t GetHdlNum(const SdrHdl *pHdl) const
Definition: svdhdl.cxx:2277
virtual void CreateB2dIAObject() override
Definition: svdhdl.cxx:1603
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:342
virtual void CreateB2dIAObject() override
Definition: svdhdl.cxx:1438
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:1078
basegfx::B2DPoint maPositionB
Definition: gradtrns.hxx:32
void Set2ndPos(const Point &rPnt)
Definition: svdhdl.cxx:1267
double mfCropRight
Definition: svdhdl.hxx:515
#define INDEX_COUNT
Definition: svdhdl.cxx:99
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:1599
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:1693
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:1021
void SetSelected(bool bJa=true)
Definition: svdhdl.cxx:354
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:2464
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:2160
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()
bool equalZero() const
constexpr tools::Long Width() const
#define KIND_COUNT
Definition: svdhdl.cxx:98
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:1361
SdrHdlColor(const Point &rRef, Color aCol, const Size &rSize, bool bLuminance)
Definition: svdhdl.cxx:1111
Degree100 NormAngle36000(Degree100 deg100)
Normalize angle to -180.00..179.99.
Definition: svdtrans.cxx:409
void Clear()
Definition: svdhdl.cxx:2245
void Touch()
Definition: svdhdl.cxx:390
sal_uInt16 GetHdlSize() const
Definition: svdhdl.hxx:463
virtual PointerStyle GetPointer() const override
Definition: svdhdl.cxx:1777
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:1487
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_LIGHTRED
void SetDistortShear(bool bOn)
Definition: svdhdl.cxx:2225
bool ImpIsHorzLine(SdrEdgeLineCode eLineCode, const XPolygon &rXP) const
Definition: svdoedge.cxx:112
virtual void CreateB2dIAObject() override
Definition: svdhdl.cxx:1795
sal_uInt16 nHdlSize
Definition: svdhdl.hxx:433
SdrObject * GetConnectedNode(bool bTail1) const override
Definition: svdoedge.cxx:495
void Set1PixMore(bool bJa=true)
Definition: svdhdl.cxx:309
void SetHdlList(SdrHdlList *pList)
Definition: svdhdl.cxx:366
BitmapColorIndex
Definition: svdhdl.hxx:84
const tools::Rectangle maRect
Definition: svdhdl.hxx:418
SdrHdl * IsHdlListHit(const Point &rPnt) const
Definition: svdhdl.cxx:2296
void Sort()
Definition: svdhdl.cxx:2253
static int ImplSortHdlFunc(const void *pVoid1, const void *pVoid2)
Definition: svdhdl.cxx:1924
const SfxPoolItem & GetObjectItem(const sal_uInt16 nWhich) const
Definition: svdobj.cxx:2008
E3dVolumeMarker(const basegfx::B2DPolyPolygon &rWireframePoly)
Definition: svdhdl.cxx:1552
bool isEmpty() const
bool IsEmpty() const
virtual void CreateB2dIAObject()
Definition: svdhdl.cxx:403
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:1221
void SetObj(SdrObject *pNewObj)
Definition: svdhdl.cxx:378
Point aPos
Definition: svdhdl.hxx:142
constexpr TypedWhichId< XFillGradientItem > XATTR_FILLGRADIENT(XATTR_FILL_FIRST+2)
#define INDIVIDUAL_COUNT
Definition: svdhdl.cxx:100
int i
uno_Any a
void MoveTo(SdrHdlList &rOther)
Definition: svdhdl.cxx:2323
bool equal(T const &rfValA, T const &rfValB)
virtual void CreateB2dIAObject() override
Definition: svdhdl.cxx:2385
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:1065
B2DPolygon createPolygonFromRect(const B2DRectangle &rRect, double fRadiusX, double fRadiusY)
void RemoveAllByKind(SdrHdlKind eKind)
Definition: svdhdl.cxx:2238
constexpr tools::Long Right() const
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_GRAY
void FromIAOToItem(SdrObject *pObj, bool bSetItemOnObject, bool bUndo)
Definition: svdhdl.cxx:1367
void SetMergedItemSetAndBroadcast(const SfxItemSet &rSet, bool bClearAllItems=false)
Definition: svdobj.cxx:2018
void TravelFocusHdl(bool bForward)
Definition: svdhdl.cxx:2000
SdrEdgeKind
Definition: sxekitm.hxx:26
void scale(double fX, double fY)
SdrModel & getSdrModelFromSdrObject() const
Definition: svdobj.cxx:279
void transform(const basegfx::B2DHomMatrix &rMatrix)
std::deque< std::unique_ptr< SdrHdl > > maList
Definition: svdhdl.hxx:432
void SetMoveOutside(bool bOn)
Definition: svdhdl.cxx:2204
constexpr tools::Long Top() const
sal_uInt32 nObjHdlNum
Definition: svdhdl.hxx:147
SVX_DLLPRIVATE SdrHdlList(const SdrHdlList &)=delete
void SetHdlSize(sal_uInt16 nSiz)
Definition: svdhdl.cxx:2188
void SetMoveOutside(bool bMoveOutside)
Definition: svdhdl.cxx:320
const sdr::contact::ObjectContact & GetObjectContact() const
Abstract DrawObject.
Definition: svdobj.hxx:259
void intersect(const B2DRange &rRange)
virtual ~SdrHdl()
Definition: svdhdl.cxx:304
#define Y
float GetDPIScaleFactor() const
bool bSelect
Definition: svdhdl.hxx:152
void transform(const basegfx::B2DHomMatrix &rMatrix)
virtual void CreateB2dIAObject() override
Definition: svdhdl.cxx:2501
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:2127
void setY(double fY)
bool IsGradient() const
Definition: svdhdl.hxx:315
virtual void CreateB2dIAObject() override
Definition: svdhdl.cxx:1495
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
SdrHdl()
Definition: svdhdl.cxx:267
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
css::uno::Reference< css::graphic::XPrimitive2D > Primitive2DReference
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_LIGHTCYAN
virtual ~SdrHdlLine() override
Definition: svdhdl.cxx:1436
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:331
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:1978
virtual SVX_DLLPRIVATE void CreateB2dIAObject() override
Definition: svdhdl.cxx:1127
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_LIGHTGREEN
virtual bool supportsGridOffsets() const
SdrPaintWindow & GetPaintWindow() const
bool bMoveOutside
Definition: svdhdl.hxx:437
#define F_PI18000
void SetFocusHdl(SdrHdl *pNew)
Definition: svdhdl.cxx:2135
bool IsHdlHit(const Point &rPnt) const
Definition: svdhdl.cxx:945
void GetRidOfIAObject()
Definition: svdhdl.cxx:396
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:276
basegfx::B2DHomMatrix maObjectTransform
Definition: svdhdl.hxx:511
virtual void CreateB2dIAObject() override
Definition: svdhdl.cxx:1721
static BitmapEx createGluePointBitmap()
Definition: svdhdl.cxx:1073
void translate(double fX, double fY)
PointerStyle
SdrHdlColor * pColHdl1
Definition: svdhdl.hxx:295
virtual ~SdrHdlColor() override
Definition: svdhdl.cxx:1123
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:783
double getX() const
Link< SdrHdlColor *, void > aColorChangeHdl
Definition: svdhdl.hxx:264
static BitmapMarkerKind GetNextBigger(BitmapMarkerKind eKnd)
Definition: svdhdl.cxx:630
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:1850
SdrEdgeLineCode eLineCode
Definition: svdhdl.hxx:387
void SetLineCode(SdrEdgeLineCode eCode)
Definition: svdhdl.cxx:1668
virtual ~SdrHdlBezWgt() override
Definition: svdhdl.cxx:1493
ImpTextframeHdl(const tools::Rectangle &rRect)
Definition: svdhdl.cxx:1789
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:1557
virtual ~ImpMeasureHdl() override
Definition: svdhdl.cxx:1717
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:514
sal_uInt16 GetTransparentSelectionPercent()
SdrCropHdl(const Point &rPnt, SdrHdlKind eNewKind, double fShearX, double fRotation)
Definition: svdhdl.cxx:2332
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:436
void SetRotateShear(bool bOn)
Definition: svdhdl.cxx:2220
const Graphic maGraphic
void AddHdl(std::unique_ptr< SdrHdl > pHdl)
Definition: svdhdl.cxx:2289
SdrHdlKind GetKind() const
Definition: svdhdl.hxx:194
virtual PointerStyle GetPointer() const override
Definition: svdhdl.cxx:1680
Utility class SdrEdgeObj.
Definition: svdoedge.hxx:129
static SVX_DLLPRIVATE Color GetLuminance(const Color &rCol)
Definition: svdhdl.cxx:1214
virtual ~SdrHdlGradient() override
Definition: svdhdl.cxx:1263
double mfCropBottom
Definition: svdhdl.hxx:516
sal_uInt32 PageWindowCount() const
Definition: svdpagv.hxx:89