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