update dev300-m58
[ooovba.git] / svx / source / svdraw / svdhdl.cxx
blob9606b6e59485e3987bce7c07c8b670275a6d66e3
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svdhdl.cxx,v $
10 * $Revision: 1.34.18.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #include <algorithm>
36 #include <svx/svdhdl.hxx>
37 #include <svx/svdpagv.hxx>
38 #include <svx/svdetc.hxx>
39 #include <svx/svdmrkv.hxx>
40 #include <vcl/window.hxx>
42 #include <vcl/virdev.hxx>
43 #include <tools/poly.hxx>
44 #include <vcl/bmpacc.hxx>
46 #include <svx/sxekitm.hxx>
47 #include "svdstr.hrc"
48 #include "svdglob.hxx"
50 #include <svx/svdmodel.hxx>
51 #include "gradtrns.hxx"
52 #include <svx/xflgrit.hxx>
53 #include <svx/svdundo.hxx>
54 #include <svx/dialmgr.hxx>
55 #include <svx/xflftrit.hxx>
57 // #105678#
58 #include <svx/svdopath.hxx>
59 #include <basegfx/vector/b2dvector.hxx>
60 #include <basegfx/polygon/b2dpolygon.hxx>
61 #include <svx/sdr/overlay/overlaymanager.hxx>
62 #include <svx/sdr/overlay/overlayanimatedbitmapex.hxx>
63 #include <svx/sdr/overlay/overlaybitmapex.hxx>
64 #include <svx/sdr/overlay/overlayline.hxx>
65 #include <svx/sdr/overlay/overlaytriangle.hxx>
66 #include <svx/sdr/overlay/overlayhatchrect.hxx>
67 #include <svx/sdrpagewindow.hxx>
68 #include <sdrpaintwindow.hxx>
69 #include <vcl/svapp.hxx>
70 #include <svx/sdr/overlay/overlaypolypolygon.hxx>
72 ////////////////////////////////////////////////////////////////////////////////////////////////////
73 // #i15222#
74 // Due to the ressource problems in Win95/98 with bitmap ressources i
75 // will change this handle bitmap provinging class. Old version was splitting
76 // and preparing all small handle bitmaps in device bitmap format, now this will
77 // be done on the fly. Thus, tehre is only the one big bitmap remembered. With
78 // three source bitmaps, this will be 3 system bitmap ressources instead of hundreds.
79 // The price for that needs to be evaluated. Maybe we will need another change here
80 // if this is too expensive.
81 class SdrHdlBitmapSet
83 // the bitmap holding all infos
84 BitmapEx maMarkersBitmap;
86 // the cropped Bitmaps for reusage
87 ::std::vector< BitmapEx > maRealMarkers;
89 // elpers
90 BitmapEx& impGetOrCreateTargetBitmap(sal_uInt16 nIndex, const Rectangle& rRectangle);
92 public:
93 SdrHdlBitmapSet(UINT16 nResId);
94 ~SdrHdlBitmapSet();
96 const BitmapEx& GetBitmapEx(BitmapMarkerKind eKindOfMarker, UINT16 nInd=0);
99 ////////////////////////////////////////////////////////////////////////////////////////////////////
100 #define KIND_COUNT (14)
101 #define INDEX_COUNT (6)
102 #define INDIVIDUAL_COUNT (4)
104 SdrHdlBitmapSet::SdrHdlBitmapSet(UINT16 nResId)
105 : maMarkersBitmap(),
106 // 14 kinds (BitmapMarkerKind) use index [0..5], 4 extra
107 maRealMarkers((KIND_COUNT * INDEX_COUNT) + INDIVIDUAL_COUNT)
109 // #101928# change color used for transparent parts to 0x00ff00ff (ImageList standard)
110 const Color aColTransparent(0x00ff00ff);
111 const Bitmap aBitmap(ResId(nResId, *ImpGetResMgr()));
112 const Bitmap aMask(aBitmap.CreateMask(aColTransparent));
114 // create a real BitmapEx with an AlphaMask
115 maMarkersBitmap = BitmapEx(aBitmap, aMask);
116 // maMarkersBitmap = BitmapEx(aBitmap, aColTransparent);
119 SdrHdlBitmapSet::~SdrHdlBitmapSet()
123 BitmapEx& SdrHdlBitmapSet::impGetOrCreateTargetBitmap(sal_uInt16 nIndex, const Rectangle& rRectangle)
125 BitmapEx& rTargetBitmap = maRealMarkers[nIndex];
127 if(rTargetBitmap.IsEmpty())
129 rTargetBitmap = maMarkersBitmap;
130 rTargetBitmap.Crop(rRectangle);
133 return rTargetBitmap;
136 // change getting of bitmap to use the big ressource bitmap
137 const BitmapEx& SdrHdlBitmapSet::GetBitmapEx(BitmapMarkerKind eKindOfMarker, UINT16 nInd)
139 // fill in size and source position in maMarkersBitmap
140 const sal_uInt16 nYPos(nInd * 11);
142 switch(eKindOfMarker)
144 default:
146 DBG_ERROR( "unknown kind of marker" );
147 // no break here, return Rect_7x7 as default
149 case Rect_7x7:
151 return impGetOrCreateTargetBitmap((0 * INDEX_COUNT) + nInd, Rectangle(Point(0, nYPos), Size(7, 7)));
154 case Rect_9x9:
156 return impGetOrCreateTargetBitmap((1 * INDEX_COUNT) + nInd, Rectangle(Point(7, nYPos), Size(9, 9)));
159 case Rect_11x11:
161 return impGetOrCreateTargetBitmap((2 * INDEX_COUNT) + nInd, Rectangle(Point(16, nYPos), Size(11, 11)));
164 case Rect_13x13:
166 const sal_uInt16 nIndex((3 * INDEX_COUNT) + nInd);
168 switch(nInd)
170 case 0:
172 return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(72, 66), Size(13, 13)));
174 case 1:
176 return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(85, 66), Size(13, 13)));
178 case 2:
180 return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(72, 78), Size(13, 13)));
182 case 3:
184 return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(85, 78), Size(13, 13)));
186 case 4:
188 return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(98, 78), Size(13, 13)));
190 default: // case 5:
192 return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(98, 66), Size(13, 13)));
197 case Circ_7x7:
199 return impGetOrCreateTargetBitmap((4 * INDEX_COUNT) + nInd, Rectangle(Point(27, nYPos), Size(7, 7)));
202 case Circ_9x9:
203 case Customshape1:
205 return impGetOrCreateTargetBitmap((5 * INDEX_COUNT) + nInd, Rectangle(Point(34, nYPos), Size(9, 9)));
208 case Circ_11x11:
210 return impGetOrCreateTargetBitmap((6 * INDEX_COUNT) + nInd, Rectangle(Point(43, nYPos), Size(11, 11)));
213 case Elli_7x9:
215 return impGetOrCreateTargetBitmap((7 * INDEX_COUNT) + nInd, Rectangle(Point(54, nYPos), Size(7, 9)));
218 case Elli_9x11:
220 return impGetOrCreateTargetBitmap((8 * INDEX_COUNT) + nInd, Rectangle(Point(61, nYPos), Size(9, 11)));
223 case Elli_9x7:
225 return impGetOrCreateTargetBitmap((9 * INDEX_COUNT) + nInd, Rectangle(Point(70, nYPos), Size(9, 7)));
228 case Elli_11x9:
230 return impGetOrCreateTargetBitmap((10 * INDEX_COUNT) + nInd, Rectangle(Point(79, nYPos), Size(11, 9)));
233 case RectPlus_7x7:
235 return impGetOrCreateTargetBitmap((11 * INDEX_COUNT) + nInd, Rectangle(Point(90, nYPos), Size(7, 7)));
238 case RectPlus_9x9:
240 return impGetOrCreateTargetBitmap((12 * INDEX_COUNT) + nInd, Rectangle(Point(97, nYPos), Size(9, 9)));
243 case RectPlus_11x11:
245 return impGetOrCreateTargetBitmap((13 * INDEX_COUNT) + nInd, Rectangle(Point(106, nYPos), Size(11, 11)));
248 case Crosshair:
250 return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 0, Rectangle(Point(0, 68), Size(15, 15)));
253 case Glue:
255 return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 1, Rectangle(Point(15, 74), Size(9, 9)));
258 case Anchor: // #101688# AnchorTR for SW
259 case AnchorTR:
261 return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 2, Rectangle(Point(24, 68), Size(24, 23)));
264 // #98388# add AnchorPressed to be able to aninate anchor control
265 case AnchorPressed:
266 case AnchorPressedTR:
268 return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 3, Rectangle(Point(48, 68), Size(24, 23)));
272 // cannot happen since all pathes return something; return Rect_7x7 as default (see switch)
273 return maRealMarkers[0];
276 ////////////////////////////////////////////////////////////////////////////////////////////////////
278 SdrHdlBitmapSet* SdrHdl::pSimpleSet = NULL;
279 SdrHdlBitmapSet* SdrHdl::pModernSet = NULL;
280 SdrHdlBitmapSet* SdrHdl::pHighContrastSet = NULL;
282 ////////////////////////////////////////////////////////////////////////////////////////////////////
284 SdrHdl::SdrHdl():
285 pObj(NULL),
286 pPV(NULL),
287 pHdlList(NULL),
288 eKind(HDL_MOVE),
289 nDrehWink(0),
290 nObjHdlNum(0),
291 nPolyNum(0),
292 nPPntNum(0),
293 nSourceHdlNum(0),
294 bSelect(FALSE),
295 b1PixMore(FALSE),
296 bPlusHdl(FALSE),
297 mbMoveOutside(false)
299 if(!pSimpleSet)
300 pSimpleSet = new SdrHdlBitmapSet(SIP_SA_MARKERS);
301 DBG_ASSERT(pSimpleSet, "Could not construct SdrHdlBitmapSet()!");
303 if(!pModernSet)
304 pModernSet = new SdrHdlBitmapSet(SIP_SA_FINE_MARKERS);
305 DBG_ASSERT(pModernSet, "Could not construct SdrHdlBitmapSet()!");
307 // #101928#
308 if(!pHighContrastSet)
309 pHighContrastSet = new SdrHdlBitmapSet(SIP_SA_ACCESSIBILITY_MARKERS);
310 DBG_ASSERT(pHighContrastSet, "Could not construct SdrHdlBitmapSet()!");
313 SdrHdl::SdrHdl(const Point& rPnt, SdrHdlKind eNewKind):
314 pObj(NULL),
315 pPV(NULL),
316 pHdlList(NULL),
317 aPos(rPnt),
318 eKind(eNewKind),
319 nDrehWink(0),
320 nObjHdlNum(0),
321 nPolyNum(0),
322 nPPntNum(0),
323 nSourceHdlNum(0),
324 bSelect(FALSE),
325 b1PixMore(FALSE),
326 bPlusHdl(FALSE),
327 mbMoveOutside(false)
329 if(!pSimpleSet)
330 pSimpleSet = new SdrHdlBitmapSet(SIP_SA_MARKERS);
331 DBG_ASSERT(pSimpleSet, "Could not construct SdrHdlBitmapSet()!");
333 if(!pModernSet)
334 pModernSet = new SdrHdlBitmapSet(SIP_SA_FINE_MARKERS);
335 DBG_ASSERT(pModernSet, "Could not construct SdrHdlBitmapSet()!");
337 // #101928#
338 if(!pHighContrastSet)
339 pHighContrastSet = new SdrHdlBitmapSet(SIP_SA_ACCESSIBILITY_MARKERS);
340 DBG_ASSERT(pHighContrastSet, "Could not construct SdrHdlBitmapSet()!");
343 SdrHdl::~SdrHdl()
345 GetRidOfIAObject();
348 void SdrHdl::Set1PixMore(BOOL bJa)
350 if(b1PixMore != bJa)
352 b1PixMore = bJa;
354 // create new display
355 Touch();
359 void SdrHdl::SetMoveOutside( bool bMoveOutside )
361 if(mbMoveOutside != bMoveOutside)
363 mbMoveOutside = bMoveOutside;
365 // create new display
366 Touch();
370 void SdrHdl::SetDrehWink(long n)
372 if(nDrehWink != n)
374 nDrehWink = n;
376 // create new display
377 Touch();
381 void SdrHdl::SetPos(const Point& rPnt)
383 if(aPos != rPnt)
385 // remember new position
386 aPos = rPnt;
388 // create new display
389 Touch();
393 void SdrHdl::SetSelected(BOOL bJa)
395 if(bSelect != bJa)
397 // remember new value
398 bSelect = bJa;
400 // create new display
401 Touch();
405 void SdrHdl::SetHdlList(SdrHdlList* pList)
407 if(pHdlList != pList)
409 // rememver list
410 pHdlList = pList;
412 // now its possible to create graphic representation
413 Touch();
417 void SdrHdl::SetObj(SdrObject* pNewObj)
419 if(pObj != pNewObj)
421 // remember new object
422 pObj = pNewObj;
424 // graphic representation may have changed
425 Touch();
429 void SdrHdl::Touch()
431 // force update of graphic representation
432 CreateB2dIAObject();
435 void SdrHdl::GetRidOfIAObject()
437 //OLMaIAOGroup.Delete();
439 // OVERLAYMANAGER
440 maOverlayGroup.clear();
443 void SdrHdl::CreateB2dIAObject()
445 // first throw away old one
446 GetRidOfIAObject();
448 if(pHdlList && pHdlList->GetView() && !pHdlList->GetView()->areMarkHandlesHidden())
450 BitmapColorIndex eColIndex = LightGreen;
451 BitmapMarkerKind eKindOfMarker = Rect_7x7;
453 BOOL bRot = pHdlList->IsRotateShear();
454 if(pObj)
455 eColIndex = (bSelect) ? Cyan : LightCyan;
456 if(bRot)
458 // Drehhandles in Rot
459 if(pObj && bSelect)
460 eColIndex = Red;
461 else
462 eColIndex = LightRed;
465 switch(eKind)
467 case HDL_MOVE:
469 eKindOfMarker = (b1PixMore) ? Rect_9x9 : Rect_7x7;
470 break;
472 case HDL_UPLFT:
473 case HDL_UPRGT:
474 case HDL_LWLFT:
475 case HDL_LWRGT:
477 // corner handles
478 if(bRot)
480 eKindOfMarker = Circ_7x7;
482 else
484 eKindOfMarker = Rect_7x7;
486 break;
488 case HDL_UPPER:
489 case HDL_LOWER:
491 // Upper/Lower handles
492 if(bRot)
494 eKindOfMarker = Elli_9x7;
496 else
498 eKindOfMarker = Rect_7x7;
500 break;
502 case HDL_LEFT:
503 case HDL_RIGHT:
505 // Left/Right handles
506 if(bRot)
508 eKindOfMarker = Elli_7x9;
510 else
512 eKindOfMarker = Rect_7x7;
514 break;
516 case HDL_POLY:
518 if(bRot)
520 eKindOfMarker = (b1PixMore) ? Circ_9x9 : Circ_7x7;
522 else
524 eKindOfMarker = (b1PixMore) ? Rect_9x9 : Rect_7x7;
526 break;
528 case HDL_BWGT: // weight at poly
530 eKindOfMarker = Circ_7x7;
531 break;
533 case HDL_CIRC:
535 eKindOfMarker = Rect_11x11;
536 break;
538 case HDL_REF1:
539 case HDL_REF2:
541 eKindOfMarker = Crosshair;
542 break;
544 case HDL_GLUE:
546 eKindOfMarker = Glue;
547 break;
549 case HDL_ANCHOR:
551 eKindOfMarker = Anchor;
552 break;
554 case HDL_USER:
556 break;
558 // #101688# top right anchor for SW
559 case HDL_ANCHOR_TR:
561 eKindOfMarker = AnchorTR;
562 break;
565 // for SJ and the CustomShapeHandles:
566 case HDL_CUSTOMSHAPE1:
568 eKindOfMarker = Customshape1;
569 eColIndex = Yellow;
570 break;
572 default:
573 break;
576 SdrMarkView* pView = pHdlList->GetView();
577 SdrPageView* pPageView = pView->GetSdrPageView();
579 if(pPageView)
581 for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
583 // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
584 const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
586 if(rPageWindow.GetPaintWindow().OutputToWindow())
588 Point aMoveOutsideOffset(0, 0);
590 // add offset if necessary
591 if(pHdlList->IsMoveOutside() || mbMoveOutside)
593 OutputDevice& rOutDev = rPageWindow.GetPaintWindow().GetOutputDevice();
594 Size aOffset = rOutDev.PixelToLogic(Size(4, 4));
596 if(eKind == HDL_UPLFT || eKind == HDL_UPPER || eKind == HDL_UPRGT)
597 aMoveOutsideOffset.Y() -= aOffset.Width();
598 if(eKind == HDL_LWLFT || eKind == HDL_LOWER || eKind == HDL_LWRGT)
599 aMoveOutsideOffset.Y() += aOffset.Height();
600 if(eKind == HDL_UPLFT || eKind == HDL_LEFT || eKind == HDL_LWLFT)
601 aMoveOutsideOffset.X() -= aOffset.Width();
602 if(eKind == HDL_UPRGT || eKind == HDL_RIGHT || eKind == HDL_LWRGT)
603 aMoveOutsideOffset.X() += aOffset.Height();
606 if(rPageWindow.GetOverlayManager())
608 basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
609 ::sdr::overlay::OverlayObject* pNewOverlayObject = CreateOverlayObject(
610 aPosition,
611 eColIndex,
612 eKindOfMarker,
613 aMoveOutsideOffset);
615 // OVERLAYMANAGER
616 if(pNewOverlayObject)
618 rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
619 maOverlayGroup.append(*pNewOverlayObject);
628 BitmapMarkerKind SdrHdl::GetNextBigger(BitmapMarkerKind eKnd) const
630 BitmapMarkerKind eRetval(eKnd);
632 switch(eKnd)
634 case Rect_7x7: eRetval = Rect_9x9; break;
635 case Rect_9x9: eRetval = Rect_11x11; break;
636 case Rect_11x11: eRetval = Rect_13x13; break;
637 //case Rect_13x13: eRetval = ; break;
639 case Circ_7x7: eRetval = Circ_9x9; break;
640 case Circ_9x9: eRetval = Circ_11x11; break;
641 //case Circ_11x11: eRetval = ; break;
643 case Elli_7x9: eRetval = Elli_9x11; break;
644 //case Elli_9x11: eRetval = ; break;
646 case Elli_9x7: eRetval = Elli_11x9; break;
647 //case Elli_11x9: eRetval = ; break;
649 case RectPlus_7x7: eRetval = RectPlus_9x9; break;
650 case RectPlus_9x9: eRetval = RectPlus_11x11; break;
651 //case RectPlus_11x11: eRetval = ; break;
653 //case Crosshair: eRetval = ; break;
654 //case Glue: eRetval = ; break;
656 // #98388# let anchor blink with it's pressed state
657 case Anchor: eRetval = AnchorPressed; break;
659 // #101688# same for AnchorTR
660 case AnchorTR: eRetval = AnchorPressedTR; break;
661 default:
662 break;
665 return eRetval;
668 // #101928#
669 BitmapEx SdrHdl::ImpGetBitmapEx(BitmapMarkerKind eKindOfMarker, sal_uInt16 nInd, sal_Bool bFine, sal_Bool bIsHighContrast)
671 if(bIsHighContrast)
673 return pHighContrastSet->GetBitmapEx(eKindOfMarker, nInd);
675 else
677 if(bFine)
679 return pModernSet->GetBitmapEx(eKindOfMarker, nInd);
681 else
683 return pSimpleSet->GetBitmapEx(eKindOfMarker, nInd);
688 ::sdr::overlay::OverlayObject* SdrHdl::CreateOverlayObject(
689 const basegfx::B2DPoint& rPos,
690 BitmapColorIndex eColIndex, BitmapMarkerKind eKindOfMarker, Point aMoveOutsideOffset)
692 ::sdr::overlay::OverlayObject* pRetval = 0L;
693 sal_Bool bIsFineHdl(pHdlList->IsFineHdl());
694 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
695 sal_Bool bIsHighContrast(rStyleSettings.GetHighContrastMode());
697 // support bigger sizes
698 sal_Bool bForceBiggerSize(sal_False);
700 if(pHdlList->GetHdlSize() > 3)
702 bForceBiggerSize = sal_True;
705 // #101928# ...for high contrast, too.
706 if(!bForceBiggerSize && bIsHighContrast)
708 // #107925#
709 // ...but not for anchors, else they will not blink when activated
710 if(Anchor != eKindOfMarker && AnchorTR != eKindOfMarker)
712 bForceBiggerSize = sal_True;
716 if(bForceBiggerSize)
718 eKindOfMarker = GetNextBigger(eKindOfMarker);
721 // #97016# II This handle has the focus, visualize it
722 if(IsFocusHdl() && pHdlList && pHdlList->GetFocusHdl() == this)
724 // create animated handle
725 BitmapMarkerKind eNextBigger = GetNextBigger(eKindOfMarker);
727 if(eNextBigger == eKindOfMarker)
729 // this may happen for the not supported getting-bigger types.
730 // Choose an alternative here
731 switch(eKindOfMarker)
733 case Rect_13x13: eNextBigger = Rect_11x11; break;
734 case Circ_11x11: eNextBigger = Elli_11x9; break;
735 case Elli_9x11: eNextBigger = Elli_11x9; break;
736 case Elli_11x9: eNextBigger = Elli_9x11; break;
737 case RectPlus_11x11: eNextBigger = Rect_13x13; break;
739 case Crosshair:
740 eNextBigger = Glue;
741 break;
743 case Glue:
744 eNextBigger = Crosshair;
745 break;
746 default:
747 break;
751 // create animated hdl
752 // #101928# use ImpGetBitmapEx(...) now
753 BitmapEx aBmpEx1 = ImpGetBitmapEx(eKindOfMarker, (sal_uInt16)eColIndex, bIsFineHdl, bIsHighContrast);
754 BitmapEx aBmpEx2 = ImpGetBitmapEx(eNextBigger, (sal_uInt16)eColIndex, bIsFineHdl, bIsHighContrast);
756 // #i53216# Use system cursor blink time. Use the unsigned value.
757 const sal_uInt32 nBlinkTime((sal_uInt32)Application::GetSettings().GetStyleSettings().GetCursorBlinkTime());
759 if(eKindOfMarker == Anchor || eKindOfMarker == AnchorPressed)
761 // #98388# when anchor is used take upper left as reference point inside the handle
762 pRetval = new ::sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime);
764 else if(eKindOfMarker == AnchorTR || eKindOfMarker == AnchorPressedTR)
766 // #101688# AnchorTR for SW, take top right as (0,0)
767 pRetval = new ::sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime,
768 (UINT16)(aBmpEx1.GetSizePixel().Width() - 1), 0,
769 (UINT16)(aBmpEx2.GetSizePixel().Width() - 1), 0);
771 else
773 // create centered handle as default
774 pRetval = new ::sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime,
775 (UINT16)(aBmpEx1.GetSizePixel().Width() - 1) >> 1,
776 (UINT16)(aBmpEx1.GetSizePixel().Height() - 1) >> 1,
777 (UINT16)(aBmpEx2.GetSizePixel().Width() - 1) >> 1,
778 (UINT16)(aBmpEx2.GetSizePixel().Height() - 1) >> 1);
781 else
783 // create normal handle
784 // #101928# use ImpGetBitmapEx(...) now
785 BitmapEx aBmpEx = ImpGetBitmapEx(eKindOfMarker, (sal_uInt16)eColIndex, bIsFineHdl, bIsHighContrast);
787 if(eKindOfMarker == Anchor || eKindOfMarker == AnchorPressed)
789 // #98388# upper left as reference point inside the handle for AnchorPressed, too
790 pRetval = new ::sdr::overlay::OverlayBitmapEx(rPos, aBmpEx);
792 else if(eKindOfMarker == AnchorTR || eKindOfMarker == AnchorPressedTR)
794 // #101688# AnchorTR for SW, take top right as (0,0)
795 pRetval = new ::sdr::overlay::OverlayBitmapEx(rPos, aBmpEx,
796 (UINT16)(aBmpEx.GetSizePixel().Width() - 1), 0);
798 else
800 sal_uInt16 nCenX((sal_uInt16)(aBmpEx.GetSizePixel().Width() - 1L) >> 1);
801 sal_uInt16 nCenY((sal_uInt16)(aBmpEx.GetSizePixel().Height() - 1L) >> 1);
803 if(aMoveOutsideOffset.X() > 0)
805 nCenX = 0;
807 else if(aMoveOutsideOffset.X() < 0)
809 nCenX = (sal_uInt16)(aBmpEx.GetSizePixel().Width() - 1);
812 if(aMoveOutsideOffset.Y() > 0)
814 nCenY = 0;
816 else if(aMoveOutsideOffset.Y() < 0)
818 nCenY = (sal_uInt16)(aBmpEx.GetSizePixel().Height() - 1);
821 // create centered handle as default
822 pRetval = new ::sdr::overlay::OverlayBitmapEx(rPos, aBmpEx, nCenX, nCenY);
826 return pRetval;
829 bool SdrHdl::IsHdlHit(const Point& rPnt) const
831 // OVERLAYMANAGER
832 basegfx::B2DPoint aPosition(rPnt.X(), rPnt.Y());
833 return maOverlayGroup.isHitLogic(aPosition);
836 Pointer SdrHdl::GetPointer() const
838 PointerStyle ePtr=POINTER_MOVE;
839 const BOOL bSize=eKind>=HDL_UPLFT && eKind<=HDL_LWRGT;
840 const BOOL bRot=pHdlList!=NULL && pHdlList->IsRotateShear();
841 const BOOL bDis=pHdlList!=NULL && pHdlList->IsDistortShear();
842 if (bSize && pHdlList!=NULL && (bRot || bDis)) {
843 switch (eKind) {
844 case HDL_UPLFT: case HDL_UPRGT:
845 case HDL_LWLFT: case HDL_LWRGT: ePtr=bRot ? POINTER_ROTATE : POINTER_REFHAND; break;
846 case HDL_LEFT : case HDL_RIGHT: ePtr=POINTER_VSHEAR; break;
847 case HDL_UPPER: case HDL_LOWER: ePtr=POINTER_HSHEAR; break;
848 default:
849 break;
851 } else {
852 // Fuer Resize von gedrehten Rechtecken die Mauszeiger etwas mitdrehen
853 if (bSize && nDrehWink!=0) {
854 long nHdlWink=0;
855 switch (eKind) {
856 case HDL_LWRGT: nHdlWink=31500; break;
857 case HDL_LOWER: nHdlWink=27000; break;
858 case HDL_LWLFT: nHdlWink=22500; break;
859 case HDL_LEFT : nHdlWink=18000; break;
860 case HDL_UPLFT: nHdlWink=13500; break;
861 case HDL_UPPER: nHdlWink=9000; break;
862 case HDL_UPRGT: nHdlWink=4500; break;
863 case HDL_RIGHT: nHdlWink=0; break;
864 default:
865 break;
867 nHdlWink+=nDrehWink+2249; // und etwas drauf (zum runden)
868 while (nHdlWink<0) nHdlWink+=36000;
869 while (nHdlWink>=36000) nHdlWink-=36000;
870 nHdlWink/=4500;
871 switch ((BYTE)nHdlWink) {
872 case 0: ePtr=POINTER_ESIZE; break;
873 case 1: ePtr=POINTER_NESIZE; break;
874 case 2: ePtr=POINTER_NSIZE; break;
875 case 3: ePtr=POINTER_NWSIZE; break;
876 case 4: ePtr=POINTER_WSIZE; break;
877 case 5: ePtr=POINTER_SWSIZE; break;
878 case 6: ePtr=POINTER_SSIZE; break;
879 case 7: ePtr=POINTER_SESIZE; break;
880 } // switch
881 } else {
882 switch (eKind) {
883 case HDL_UPLFT: ePtr=POINTER_NWSIZE; break;
884 case HDL_UPPER: ePtr=POINTER_NSIZE; break;
885 case HDL_UPRGT: ePtr=POINTER_NESIZE; break;
886 case HDL_LEFT : ePtr=POINTER_WSIZE; break;
887 case HDL_RIGHT: ePtr=POINTER_ESIZE; break;
888 case HDL_LWLFT: ePtr=POINTER_SWSIZE; break;
889 case HDL_LOWER: ePtr=POINTER_SSIZE; break;
890 case HDL_LWRGT: ePtr=POINTER_SESIZE; break;
891 case HDL_POLY : ePtr=POINTER_MOVEPOINT; break;
892 case HDL_CIRC : ePtr=POINTER_HAND; break;
893 case HDL_REF1 : ePtr=POINTER_REFHAND; break;
894 case HDL_REF2 : ePtr=POINTER_REFHAND; break;
895 case HDL_BWGT : ePtr=POINTER_MOVEBEZIERWEIGHT; break;
896 case HDL_GLUE : ePtr=POINTER_MOVEPOINT; break;
897 case HDL_CUSTOMSHAPE1 : ePtr=POINTER_HAND; break;
898 default:
899 break;
903 return Pointer(ePtr);
906 // #97016# II
907 BOOL SdrHdl::IsFocusHdl() const
909 switch(eKind)
911 case HDL_UPLFT: // Oben links
912 case HDL_UPPER: // Oben
913 case HDL_UPRGT: // Oben rechts
914 case HDL_LEFT: // Links
915 case HDL_RIGHT: // Rechts
916 case HDL_LWLFT: // Unten links
917 case HDL_LOWER: // Unten
918 case HDL_LWRGT: // Unten rechts
920 // if it's a activated TextEdit, it's moved to extended points
921 if(pHdlList && pHdlList->IsMoveOutside())
922 return FALSE;
923 else
924 return TRUE;
927 case HDL_MOVE: // Handle zum Verschieben des Objekts
928 case HDL_POLY: // Punktselektion an Polygon oder Bezierkurve
929 case HDL_BWGT: // Gewicht an einer Bezierkurve
930 case HDL_CIRC: // Winkel an Kreissegmenten, Eckenradius am Rect
931 case HDL_REF1: // Referenzpunkt 1, z.B. Rotationsmitte
932 case HDL_REF2: // Referenzpunkt 2, z.B. Endpunkt der Spiegelachse
933 //case HDL_MIRX: // Die Spiegelachse selbst
934 case HDL_GLUE: // GluePoint
936 // #98388# do NOT activate here, let SW implement their own SdrHdl and
937 // overload IsFocusHdl() there to make the anchor accessible
938 //case HDL_ANCHOR: // anchor symbol (SD, SW)
939 // #101688# same for AnchorTR
940 //case HDL_ANCHOR_TR: // anchor symbol (SD, SW)
942 //case HDL_TRNS: // interactive transparence
943 //case HDL_GRAD: // interactive gradient
944 //case HDL_COLR: // interactive color
946 // for SJ and the CustomShapeHandles:
947 case HDL_CUSTOMSHAPE1:
949 case HDL_USER:
951 return TRUE;
954 default:
956 return FALSE;
961 ////////////////////////////////////////////////////////////////////////////////////////////////////
962 // class SdrHdlColor
964 SdrHdlColor::SdrHdlColor(const Point& rRef, Color aCol, const Size& rSize, BOOL bLum)
965 : SdrHdl(rRef, HDL_COLR),
966 aMarkerSize(rSize),
967 bUseLuminance(bLum)
969 if(IsUseLuminance())
970 aCol = GetLuminance(aCol);
972 // remember color
973 aMarkerColor = aCol;
976 SdrHdlColor::~SdrHdlColor()
980 void SdrHdlColor::CreateB2dIAObject()
982 // first throw away old one
983 GetRidOfIAObject();
985 if(pHdlList)
987 SdrMarkView* pView = pHdlList->GetView();
989 if(pView && !pView->areMarkHandlesHidden())
991 SdrPageView* pPageView = pView->GetSdrPageView();
993 if(pPageView)
995 for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
997 // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
998 const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1000 if(rPageWindow.GetPaintWindow().OutputToWindow())
1002 if(rPageWindow.GetOverlayManager())
1004 Bitmap aBmpCol(CreateColorDropper(aMarkerColor));
1005 basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
1006 ::sdr::overlay::OverlayObject* pNewOverlayObject = new
1007 ::sdr::overlay::OverlayBitmapEx(
1008 aPosition,
1009 BitmapEx(aBmpCol),
1010 (UINT16)(aBmpCol.GetSizePixel().Width() - 1) >> 1,
1011 (UINT16)(aBmpCol.GetSizePixel().Height() - 1) >> 1
1013 DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
1015 // OVERLAYMANAGER
1016 if(pNewOverlayObject)
1018 rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1019 maOverlayGroup.append(*pNewOverlayObject);
1029 Bitmap SdrHdlColor::CreateColorDropper(Color aCol)
1031 // get the Bitmap
1032 Bitmap aRetval(aMarkerSize, 24);
1033 aRetval.Erase(aCol);
1035 // get write access
1036 BitmapWriteAccess* pWrite = aRetval.AcquireWriteAccess();
1037 DBG_ASSERT(pWrite, "Got NO write access to a new Bitmap !!!");
1039 if(pWrite)
1041 // draw outer border
1042 INT32 nWidth = aMarkerSize.Width();
1043 INT32 nHeight = aMarkerSize.Height();
1045 pWrite->SetLineColor(Color(COL_LIGHTGRAY));
1046 pWrite->DrawLine(Point(0, 0), Point(0, nHeight - 1));
1047 pWrite->DrawLine(Point(1, 0), Point(nWidth - 1, 0));
1048 pWrite->SetLineColor(Color(COL_GRAY));
1049 pWrite->DrawLine(Point(1, nHeight - 1), Point(nWidth - 1, nHeight - 1));
1050 pWrite->DrawLine(Point(nWidth - 1, 1), Point(nWidth - 1, nHeight - 2));
1052 // draw lighter UpperLeft
1053 const Color aLightColor(
1054 (sal_uInt8)(::std::min((sal_Int16)((sal_Int16)aCol.GetRed() + (sal_Int16)0x0040), (sal_Int16)0x00ff)),
1055 (sal_uInt8)(::std::min((sal_Int16)((sal_Int16)aCol.GetGreen() + (sal_Int16)0x0040), (sal_Int16)0x00ff)),
1056 (sal_uInt8)(::std::min((sal_Int16)((sal_Int16)aCol.GetBlue() + (sal_Int16)0x0040), (sal_Int16)0x00ff)));
1057 pWrite->SetLineColor(aLightColor);
1058 pWrite->DrawLine(Point(1, 1), Point(1, nHeight - 2));
1059 pWrite->DrawLine(Point(2, 1), Point(nWidth - 2, 1));
1061 // draw darker LowerRight
1062 const Color aDarkColor(
1063 (sal_uInt8)(::std::max((sal_Int16)((sal_Int16)aCol.GetRed() - (sal_Int16)0x0040), (sal_Int16)0x0000)),
1064 (sal_uInt8)(::std::max((sal_Int16)((sal_Int16)aCol.GetGreen() - (sal_Int16)0x0040), (sal_Int16)0x0000)),
1065 (sal_uInt8)(::std::max((sal_Int16)((sal_Int16)aCol.GetBlue() - (sal_Int16)0x0040), (sal_Int16)0x0000)));
1066 pWrite->SetLineColor(aDarkColor);
1067 pWrite->DrawLine(Point(2, nHeight - 2), Point(nWidth - 2, nHeight - 2));
1068 pWrite->DrawLine(Point(nWidth - 2, 2), Point(nWidth - 2, nHeight - 3));
1070 // get rid of write access
1071 delete pWrite;
1074 return aRetval;
1077 Color SdrHdlColor::GetLuminance(const Color& rCol)
1079 UINT8 aLum = rCol.GetLuminance();
1080 Color aRetval(aLum, aLum, aLum);
1081 return aRetval;
1084 void SdrHdlColor::CallColorChangeLink()
1086 aColorChangeHdl.Call(this);
1089 void SdrHdlColor::SetColor(Color aNew, BOOL bCallLink)
1091 if(IsUseLuminance())
1092 aNew = GetLuminance(aNew);
1094 if(aMarkerColor != aNew)
1096 // remember new color
1097 aMarkerColor = aNew;
1099 // create new display
1100 Touch();
1102 // tell about change
1103 if(bCallLink)
1104 CallColorChangeLink();
1108 void SdrHdlColor::SetSize(const Size& rNew)
1110 if(rNew != aMarkerSize)
1112 // remember new size
1113 aMarkerSize = rNew;
1115 // create new display
1116 Touch();
1120 ////////////////////////////////////////////////////////////////////////////////////////////////////
1121 // class SdrHdlGradient
1123 SdrHdlGradient::SdrHdlGradient(const Point& rRef1, const Point& rRef2, BOOL bGrad)
1124 : SdrHdl(rRef1, bGrad ? HDL_GRAD : HDL_TRNS),
1125 pColHdl1(NULL),
1126 pColHdl2(NULL),
1127 a2ndPos(rRef2),
1128 bGradient(bGrad)
1132 SdrHdlGradient::~SdrHdlGradient()
1136 void SdrHdlGradient::Set2ndPos(const Point& rPnt)
1138 if(a2ndPos != rPnt)
1140 // remember new position
1141 a2ndPos = rPnt;
1143 // create new display
1144 Touch();
1148 void SdrHdlGradient::CreateB2dIAObject()
1150 // first throw away old one
1151 GetRidOfIAObject();
1153 if(pHdlList)
1155 SdrMarkView* pView = pHdlList->GetView();
1157 if(pView && !pView->areMarkHandlesHidden())
1159 SdrPageView* pPageView = pView->GetSdrPageView();
1161 if(pPageView)
1163 for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
1165 const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1167 if(rPageWindow.GetPaintWindow().OutputToWindow())
1169 if(rPageWindow.GetOverlayManager())
1171 // striped line in between
1172 basegfx::B2DVector aVec(a2ndPos.X() - aPos.X(), a2ndPos.Y() - aPos.Y());
1173 double fVecLen = aVec.getLength();
1174 double fLongPercentArrow = (1.0 - 0.05) * fVecLen;
1175 double fHalfArrowWidth = (0.05 * 0.5) * fVecLen;
1176 aVec.normalize();
1177 basegfx::B2DVector aPerpend(-aVec.getY(), aVec.getX());
1178 INT32 nMidX = (INT32)(aPos.X() + aVec.getX() * fLongPercentArrow);
1179 INT32 nMidY = (INT32)(aPos.Y() + aVec.getY() * fLongPercentArrow);
1180 Point aMidPoint(nMidX, nMidY);
1182 basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
1183 basegfx::B2DPoint aMidPos(aMidPoint.X(), aMidPoint.Y());
1185 ::sdr::overlay::OverlayObject* pNewOverlayObject = new
1186 ::sdr::overlay::OverlayLineStriped(
1187 aPosition, aMidPos
1189 DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
1191 pNewOverlayObject->setBaseColor(IsGradient() ? Color(COL_BLACK) : Color(COL_BLUE));
1192 rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1193 maOverlayGroup.append(*pNewOverlayObject);
1195 // arrowhead
1196 Point aLeft(aMidPoint.X() + (INT32)(aPerpend.getX() * fHalfArrowWidth),
1197 aMidPoint.Y() + (INT32)(aPerpend.getY() * fHalfArrowWidth));
1198 Point aRight(aMidPoint.X() - (INT32)(aPerpend.getX() * fHalfArrowWidth),
1199 aMidPoint.Y() - (INT32)(aPerpend.getY() * fHalfArrowWidth));
1201 basegfx::B2DPoint aPositionLeft(aLeft.X(), aLeft.Y());
1202 basegfx::B2DPoint aPositionRight(aRight.X(), aRight.Y());
1203 basegfx::B2DPoint aPosition2(a2ndPos.X(), a2ndPos.Y());
1205 pNewOverlayObject = new
1206 ::sdr::overlay::OverlayTriangle(
1207 aPositionLeft,
1208 aPosition2,
1209 aPositionRight,
1210 IsGradient() ? Color(COL_BLACK) : Color(COL_BLUE)
1212 DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
1214 rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1215 maOverlayGroup.append(*pNewOverlayObject);
1224 IMPL_LINK(SdrHdlGradient, ColorChangeHdl, SdrHdl*, /*pHdl*/)
1226 if(GetObj())
1227 FromIAOToItem(GetObj(), TRUE, TRUE);
1228 return 0;
1231 void SdrHdlGradient::FromIAOToItem(SdrObject* _pObj, BOOL bSetItemOnObject, BOOL bUndo)
1233 // from IAO positions and colors to gradient
1234 const SfxItemSet& rSet = _pObj->GetMergedItemSet();
1236 GradTransformer aGradTransformer;
1237 GradTransGradient aOldGradTransGradient;
1238 GradTransGradient aGradTransGradient;
1239 GradTransVector aGradTransVector;
1241 String aString;
1243 aGradTransVector.maPositionA = basegfx::B2DPoint(GetPos().X(), GetPos().Y());
1244 aGradTransVector.maPositionB = basegfx::B2DPoint(Get2ndPos().X(), Get2ndPos().Y());
1245 if(pColHdl1)
1246 aGradTransVector.aCol1 = pColHdl1->GetColor();
1247 if(pColHdl2)
1248 aGradTransVector.aCol2 = pColHdl2->GetColor();
1250 if(IsGradient())
1251 aOldGradTransGradient.aGradient = ((XFillGradientItem&)rSet.Get(XATTR_FILLGRADIENT)).GetGradientValue();
1252 else
1253 aOldGradTransGradient.aGradient = ((XFillFloatTransparenceItem&)rSet.Get(XATTR_FILLFLOATTRANSPARENCE)).GetGradientValue();
1255 // transform vector data to gradient
1256 aGradTransformer.VecToGrad(aGradTransVector, aGradTransGradient, aOldGradTransGradient, _pObj, bMoveSingleHandle, bMoveFirstHandle);
1258 if(bSetItemOnObject)
1260 SdrModel* pModel = _pObj->GetModel();
1261 SfxItemSet aNewSet(pModel->GetItemPool());
1263 if(IsGradient())
1265 aString = String();
1266 XFillGradientItem aNewGradItem(aString, aGradTransGradient.aGradient);
1267 aNewSet.Put(aNewGradItem);
1269 else
1271 aString = String();
1272 XFillFloatTransparenceItem aNewTransItem(aString, aGradTransGradient.aGradient);
1273 aNewSet.Put(aNewTransItem);
1276 if(bUndo && pModel->IsUndoEnabled())
1278 pModel->BegUndo(SVX_RESSTR(IsGradient() ? SIP_XA_FILLGRADIENT : SIP_XA_FILLTRANSPARENCE));
1279 pModel->AddUndo(pModel->GetSdrUndoFactory().CreateUndoAttrObject(*_pObj));
1280 pModel->EndUndo();
1283 pObj->SetMergedItemSetAndBroadcast(aNewSet);
1286 // back transformation, set values on pIAOHandle
1287 aGradTransformer.GradToVec(aGradTransGradient, aGradTransVector, _pObj);
1289 SetPos(Point(FRound(aGradTransVector.maPositionA.getX()), FRound(aGradTransVector.maPositionA.getY())));
1290 Set2ndPos(Point(FRound(aGradTransVector.maPositionB.getX()), FRound(aGradTransVector.maPositionB.getY())));
1291 if(pColHdl1)
1293 pColHdl1->SetPos(Point(FRound(aGradTransVector.maPositionA.getX()), FRound(aGradTransVector.maPositionA.getY())));
1294 pColHdl1->SetColor(aGradTransVector.aCol1);
1296 if(pColHdl2)
1298 pColHdl2->SetPos(Point(FRound(aGradTransVector.maPositionB.getX()), FRound(aGradTransVector.maPositionB.getY())));
1299 pColHdl2->SetColor(aGradTransVector.aCol2);
1303 ////////////////////////////////////////////////////////////////////////////////////////////////////
1305 SdrHdlLine::~SdrHdlLine() {}
1307 void SdrHdlLine::CreateB2dIAObject()
1309 // first throw away old one
1310 GetRidOfIAObject();
1312 if(pHdlList)
1314 SdrMarkView* pView = pHdlList->GetView();
1316 if(pView && !pView->areMarkHandlesHidden() && pHdl1 && pHdl2)
1318 SdrPageView* pPageView = pView->GetSdrPageView();
1320 if(pPageView)
1322 for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
1324 const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1326 if(rPageWindow.GetPaintWindow().OutputToWindow())
1328 if(rPageWindow.GetOverlayManager())
1330 basegfx::B2DPoint aPosition1(pHdl1->GetPos().X(), pHdl1->GetPos().Y());
1331 basegfx::B2DPoint aPosition2(pHdl2->GetPos().X(), pHdl2->GetPos().Y());
1333 ::sdr::overlay::OverlayObject* pNewOverlayObject = new
1334 ::sdr::overlay::OverlayLineStriped(
1335 aPosition1,
1336 aPosition2
1338 DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
1340 // OVERLAYMANAGER
1341 if(pNewOverlayObject)
1343 // color(?)
1344 pNewOverlayObject->setBaseColor(Color(COL_LIGHTRED));
1346 rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1347 maOverlayGroup.append(*pNewOverlayObject);
1357 Pointer SdrHdlLine::GetPointer() const
1359 return Pointer(POINTER_REFHAND);
1362 ////////////////////////////////////////////////////////////////////////////////////////////////////
1364 SdrHdlBezWgt::~SdrHdlBezWgt() {}
1366 void SdrHdlBezWgt::CreateB2dIAObject()
1368 // call parent
1369 SdrHdl::CreateB2dIAObject();
1371 // create lines
1372 if(pHdlList)
1374 SdrMarkView* pView = pHdlList->GetView();
1376 if(pView && !pView->areMarkHandlesHidden())
1378 SdrPageView* pPageView = pView->GetSdrPageView();
1380 if(pPageView)
1382 for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
1384 const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1386 if(rPageWindow.GetPaintWindow().OutputToWindow())
1388 if(rPageWindow.GetOverlayManager())
1390 basegfx::B2DPoint aPosition1(pHdl1->GetPos().X(), pHdl1->GetPos().Y());
1391 basegfx::B2DPoint aPosition2(aPos.X(), aPos.Y());
1393 if(!aPosition1.equal(aPosition2))
1395 ::sdr::overlay::OverlayObject* pNewOverlayObject = new
1396 ::sdr::overlay::OverlayLineStriped(
1397 aPosition1,
1398 aPosition2
1400 DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
1402 // OVERLAYMANAGER
1403 if(pNewOverlayObject)
1405 // line part is not hittable
1406 pNewOverlayObject->setHittable(sal_False);
1408 // color(?)
1409 pNewOverlayObject->setBaseColor(Color(COL_LIGHTBLUE));
1411 rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1412 maOverlayGroup.append(*pNewOverlayObject);
1423 ////////////////////////////////////////////////////////////////////////////////////////////////////
1425 E3dVolumeMarker::E3dVolumeMarker(const basegfx::B2DPolyPolygon& rWireframePoly)
1427 aWireframePoly = rWireframePoly;
1430 void E3dVolumeMarker::CreateB2dIAObject()
1432 // create lines
1433 if(pHdlList)
1435 SdrMarkView* pView = pHdlList->GetView();
1437 if(pView && !pView->areMarkHandlesHidden())
1439 SdrPageView* pPageView = pView->GetSdrPageView();
1441 if(pPageView)
1443 for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
1445 const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1447 if(rPageWindow.GetPaintWindow().OutputToWindow())
1449 if(rPageWindow.GetOverlayManager() && aWireframePoly.count())
1451 ::sdr::overlay::OverlayObject* pNewOverlayObject = new
1452 ::sdr::overlay::OverlayPolyPolygonStriped(aWireframePoly);
1453 DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
1455 // OVERLAYMANAGER
1456 if(pNewOverlayObject)
1458 pNewOverlayObject->setBaseColor(Color(COL_BLACK));
1460 rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1461 maOverlayGroup.append(*pNewOverlayObject);
1471 ////////////////////////////////////////////////////////////////////////////////////////////////////
1473 ImpEdgeHdl::~ImpEdgeHdl()
1477 void ImpEdgeHdl::CreateB2dIAObject()
1479 if(nObjHdlNum <= 1 && pObj)
1481 // first throw away old one
1482 GetRidOfIAObject();
1484 BitmapColorIndex eColIndex = LightCyan;
1485 BitmapMarkerKind eKindOfMarker = Rect_7x7;
1487 if(pHdlList)
1489 SdrMarkView* pView = pHdlList->GetView();
1491 if(pView && !pView->areMarkHandlesHidden())
1493 const SdrEdgeObj* pEdge = (SdrEdgeObj*)pObj;
1495 if(pEdge->GetConnectedNode(nObjHdlNum == 0) != NULL)
1496 eColIndex = LightRed;
1498 if(nPPntNum < 2)
1500 // Handle with plus sign inside
1501 eKindOfMarker = Circ_7x7;
1504 SdrPageView* pPageView = pView->GetSdrPageView();
1506 if(pPageView)
1508 for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
1510 const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1512 if(rPageWindow.GetPaintWindow().OutputToWindow())
1514 if(rPageWindow.GetOverlayManager())
1516 basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
1518 ::sdr::overlay::OverlayObject* pNewOverlayObject = CreateOverlayObject(
1519 aPosition,
1520 eColIndex,
1521 eKindOfMarker);
1523 // OVERLAYMANAGER
1524 if(pNewOverlayObject)
1526 rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1527 maOverlayGroup.append(*pNewOverlayObject);
1536 else
1538 // call parent
1539 SdrHdl::CreateB2dIAObject();
1543 void ImpEdgeHdl::SetLineCode(SdrEdgeLineCode eCode)
1545 if(eLineCode != eCode)
1547 // remember new value
1548 eLineCode = eCode;
1550 // create new display
1551 Touch();
1555 Pointer ImpEdgeHdl::GetPointer() const
1557 SdrEdgeObj* pEdge=PTR_CAST(SdrEdgeObj,pObj);
1558 if (pEdge==NULL)
1559 return SdrHdl::GetPointer();
1560 if (nObjHdlNum<=1)
1561 return Pointer(POINTER_MOVEPOINT); //Pointer(POINTER_DRAW_CONNECT);
1562 if (IsHorzDrag())
1563 return Pointer(POINTER_ESIZE);
1564 else
1565 return Pointer(POINTER_SSIZE);
1568 BOOL ImpEdgeHdl::IsHorzDrag() const
1570 SdrEdgeObj* pEdge=PTR_CAST(SdrEdgeObj,pObj);
1571 if (pEdge==NULL)
1572 return FALSE;
1573 if (nObjHdlNum<=1)
1574 return FALSE;
1576 SdrEdgeKind eEdgeKind = ((SdrEdgeKindItem&)(pEdge->GetObjectItem(SDRATTR_EDGEKIND))).GetValue();
1578 const SdrEdgeInfoRec& rInfo=pEdge->aEdgeInfo;
1579 if (eEdgeKind==SDREDGE_ORTHOLINES || eEdgeKind==SDREDGE_BEZIER)
1581 return !rInfo.ImpIsHorzLine(eLineCode,*pEdge->pEdgeTrack);
1583 else if (eEdgeKind==SDREDGE_THREELINES)
1585 long nWink=nObjHdlNum==2 ? rInfo.nAngle1 : rInfo.nAngle2;
1586 if (nWink==0 || nWink==18000)
1587 return TRUE;
1588 else
1589 return FALSE;
1591 return FALSE;
1594 ////////////////////////////////////////////////////////////////////////////////////////////////////
1596 ImpMeasureHdl::~ImpMeasureHdl()
1600 void ImpMeasureHdl::CreateB2dIAObject()
1602 // first throw away old one
1603 GetRidOfIAObject();
1605 if(pHdlList)
1607 SdrMarkView* pView = pHdlList->GetView();
1609 if(pView && !pView->areMarkHandlesHidden())
1611 BitmapColorIndex eColIndex = LightCyan;
1612 BitmapMarkerKind eKindOfMarker = Rect_9x9;
1614 if(nObjHdlNum > 1)
1616 eKindOfMarker = Rect_7x7;
1619 if(bSelect)
1621 eColIndex = Cyan;
1624 SdrPageView* pPageView = pView->GetSdrPageView();
1626 if(pPageView)
1628 for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
1630 const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1632 if(rPageWindow.GetPaintWindow().OutputToWindow())
1634 if(rPageWindow.GetOverlayManager())
1636 basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
1638 ::sdr::overlay::OverlayObject* pNewOverlayObject = CreateOverlayObject(
1639 aPosition,
1640 eColIndex,
1641 eKindOfMarker);
1643 // OVERLAYMANAGER
1644 if(pNewOverlayObject)
1646 rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1647 maOverlayGroup.append(*pNewOverlayObject);
1657 Pointer ImpMeasureHdl::GetPointer() const
1659 switch (nObjHdlNum)
1661 case 0: case 1: return Pointer(POINTER_HAND);
1662 case 2: case 3: return Pointer(POINTER_MOVEPOINT);
1663 case 4: case 5: return SdrHdl::GetPointer(); // wird dann entsprechend gedreht
1664 } // switch
1665 return Pointer(POINTER_NOTALLOWED);
1668 ////////////////////////////////////////////////////////////////////////////////////////////////////
1670 ImpTextframeHdl::ImpTextframeHdl(const Rectangle& rRect) :
1671 SdrHdl(rRect.TopLeft(),HDL_MOVE),
1672 maRect(rRect)
1676 void ImpTextframeHdl::CreateB2dIAObject()
1678 // first throw away old one
1679 GetRidOfIAObject();
1681 if(pHdlList)
1683 SdrMarkView* pView = pHdlList->GetView();
1685 if(pView && !pView->areMarkHandlesHidden())
1687 SdrPageView* pPageView = pView->GetSdrPageView();
1689 if(pPageView)
1691 for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
1693 const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1695 if(rPageWindow.GetPaintWindow().OutputToWindow())
1697 if(rPageWindow.GetOverlayManager())
1699 const basegfx::B2DPoint aTopLeft(maRect.Left(), maRect.Top());
1700 const basegfx::B2DPoint aBottomRight(maRect.Right(), maRect.Bottom());
1701 const svtools::ColorConfig aColorConfig;
1702 const Color aHatchCol( aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor );
1704 ::sdr::overlay::OverlayHatchRect* pNewOverlayObject = new ::sdr::overlay::OverlayHatchRect(
1705 aTopLeft,
1706 aBottomRight,
1707 aHatchCol,
1708 3.0,
1709 3.0,
1710 45 * F_PI180,
1711 nDrehWink * -F_PI18000);
1712 pNewOverlayObject->setHittable(false);
1714 // OVERLAYMANAGER
1715 if(pNewOverlayObject)
1717 rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1718 maOverlayGroup.append(*pNewOverlayObject);
1728 ////////////////////////////////////////////////////////////////////////////////////////////////////
1730 class ImpSdrHdlListSorter: public ContainerSorter {
1731 public:
1732 ImpSdrHdlListSorter(Container& rNewCont): ContainerSorter(rNewCont) {}
1733 virtual int Compare(const void* pElem1, const void* pElem2) const;
1736 int ImpSdrHdlListSorter::Compare(const void* pElem1, const void* pElem2) const
1738 SdrHdlKind eKind1=((SdrHdl*)pElem1)->GetKind();
1739 SdrHdlKind eKind2=((SdrHdl*)pElem2)->GetKind();
1740 // Level 1: Erst normale Handles, dann Glue, dann User, dann Plushandles, dann Retpunkt-Handles
1741 unsigned n1=1;
1742 unsigned n2=1;
1743 if (eKind1!=eKind2)
1745 if (eKind1==HDL_REF1 || eKind1==HDL_REF2 || eKind1==HDL_MIRX) n1=5;
1746 else if (eKind1==HDL_GLUE) n1=2;
1747 else if (eKind1==HDL_USER) n1=3;
1748 else if (eKind1==HDL_SMARTTAG) n1=0;
1749 if (eKind2==HDL_REF1 || eKind2==HDL_REF2 || eKind2==HDL_MIRX) n2=5;
1750 else if (eKind2==HDL_GLUE) n2=2;
1751 else if (eKind2==HDL_USER) n2=3;
1752 else if (eKind2==HDL_SMARTTAG) n2=0;
1754 if (((SdrHdl*)pElem1)->IsPlusHdl()) n1=4;
1755 if (((SdrHdl*)pElem2)->IsPlusHdl()) n2=4;
1756 if (n1==n2)
1758 // Level 2: PageView (Pointer)
1759 SdrPageView* pPV1=((SdrHdl*)pElem1)->GetPageView();
1760 SdrPageView* pPV2=((SdrHdl*)pElem2)->GetPageView();
1761 if (pPV1==pPV2)
1763 // Level 3: Position (x+y)
1764 SdrObject* pObj1=((SdrHdl*)pElem1)->GetObj();
1765 SdrObject* pObj2=((SdrHdl*)pElem2)->GetObj();
1766 if (pObj1==pObj2)
1768 sal_uInt32 nNum1=((SdrHdl*)pElem1)->GetObjHdlNum();
1769 sal_uInt32 nNum2=((SdrHdl*)pElem2)->GetObjHdlNum();
1770 if (nNum1==nNum2)
1771 { // #48763#
1772 if (eKind1==eKind2)
1773 return (long)pElem1<(long)pElem2 ? -1 : 1; // Notloesung, um immer die gleiche Sortierung zu haben
1774 return (USHORT)eKind1<(USHORT)eKind2 ? -1 : 1;
1776 else
1777 return nNum1<nNum2 ? -1 : 1;
1779 else
1781 return (long)pObj1<(long)pObj2 ? -1 : 1;
1784 else
1786 return (long)pPV1<(long)pPV2 ? -1 : 1;
1789 else
1791 return n1<n2 ? -1 : 1;
1795 SdrMarkView* SdrHdlList::GetView() const
1797 return pView;
1800 // #105678# Help struct for re-sorting handles
1801 struct ImplHdlAndIndex
1803 SdrHdl* mpHdl;
1804 sal_uInt32 mnIndex;
1807 // #105678# Help method for sorting handles taking care of OrdNums, keeping order in
1808 // single objects and re-sorting polygon handles intuitively
1809 extern "C" int __LOADONCALLAPI ImplSortHdlFunc( const void* pVoid1, const void* pVoid2 )
1811 const ImplHdlAndIndex* p1 = (ImplHdlAndIndex*)pVoid1;
1812 const ImplHdlAndIndex* p2 = (ImplHdlAndIndex*)pVoid2;
1814 if(p1->mpHdl->GetObj() == p2->mpHdl->GetObj())
1816 if(p1->mpHdl->GetObj() && p1->mpHdl->GetObj()->ISA(SdrPathObj))
1818 // same object and a path object
1819 if((p1->mpHdl->GetKind() == HDL_POLY || p1->mpHdl->GetKind() == HDL_BWGT)
1820 && (p2->mpHdl->GetKind() == HDL_POLY || p2->mpHdl->GetKind() == HDL_BWGT))
1822 // both handles are point or control handles
1823 if(p1->mpHdl->GetPolyNum() == p2->mpHdl->GetPolyNum())
1825 if(p1->mpHdl->GetPointNum() < p2->mpHdl->GetPointNum())
1827 return -1;
1829 else
1831 return 1;
1834 else if(p1->mpHdl->GetPolyNum() < p2->mpHdl->GetPolyNum())
1836 return -1;
1838 else
1840 return 1;
1845 else
1847 if(!p1->mpHdl->GetObj())
1849 return -1;
1851 else if(!p2->mpHdl->GetObj())
1853 return 1;
1855 else
1857 // different objects, use OrdNum for sort
1858 const sal_uInt32 nOrdNum1 = p1->mpHdl->GetObj()->GetOrdNum();
1859 const sal_uInt32 nOrdNum2 = p2->mpHdl->GetObj()->GetOrdNum();
1861 if(nOrdNum1 < nOrdNum2)
1863 return -1;
1865 else
1867 return 1;
1872 // fallback to indices
1873 if(p1->mnIndex < p2->mnIndex)
1875 return -1;
1877 else
1879 return 1;
1883 ////////////////////////////////////////////////////////////////////////////////////////////////////
1884 // #97016# II
1886 void SdrHdlList::TravelFocusHdl(sal_Bool bForward)
1888 // security correction
1889 if(mnFocusIndex != CONTAINER_ENTRY_NOTFOUND && mnFocusIndex >= GetHdlCount())
1890 mnFocusIndex = CONTAINER_ENTRY_NOTFOUND;
1892 if(aList.Count())
1894 // take care of old handle
1895 const ULONG nOldHdlNum(mnFocusIndex);
1896 SdrHdl* pOld = GetHdl(nOldHdlNum);
1897 //SDOsal_Bool bRefresh(sal_False);
1899 if(pOld)
1901 // switch off old handle
1902 mnFocusIndex = CONTAINER_ENTRY_NOTFOUND;
1903 pOld->Touch();
1904 //SDObRefresh = sal_True;
1907 // #105678# Alloc pointer array for sorted handle list
1908 ImplHdlAndIndex* pHdlAndIndex = new ImplHdlAndIndex[aList.Count()];
1910 // #105678# build sorted handle list
1911 sal_uInt32 a;
1912 for( a = 0; a < aList.Count(); a++)
1914 pHdlAndIndex[a].mpHdl = (SdrHdl*)aList.GetObject(a);
1915 pHdlAndIndex[a].mnIndex = a;
1918 // #105678# qsort all entries
1919 qsort(pHdlAndIndex, aList.Count(), sizeof(ImplHdlAndIndex), ImplSortHdlFunc);
1921 // #105678# look for old num in sorted array
1922 ULONG nOldHdl(nOldHdlNum);
1924 if(nOldHdlNum != CONTAINER_ENTRY_NOTFOUND)
1926 for(a = 0; a < aList.Count(); a++)
1928 if(pHdlAndIndex[a].mpHdl == pOld)
1930 nOldHdl = a;
1931 break;
1936 // #105678# build new HdlNum
1937 ULONG nNewHdl(nOldHdl);
1939 // #105678# do the focus travel
1940 if(bForward)
1942 if(nOldHdl != CONTAINER_ENTRY_NOTFOUND)
1944 if(nOldHdl == aList.Count() - 1)
1946 // end forward run
1947 nNewHdl = CONTAINER_ENTRY_NOTFOUND;
1949 else
1951 // simply the next handle
1952 nNewHdl++;
1955 else
1957 // start forward run at first entry
1958 nNewHdl = 0;
1961 else
1963 if(nOldHdl == CONTAINER_ENTRY_NOTFOUND)
1965 // start backward run at last entry
1966 nNewHdl = aList.Count() - 1;
1969 else
1971 if(nOldHdl == 0)
1973 // end backward run
1974 nNewHdl = CONTAINER_ENTRY_NOTFOUND;
1976 else
1978 // simply the previous handle
1979 nNewHdl--;
1984 // #105678# build new HdlNum
1985 sal_uInt32 nNewHdlNum(nNewHdl);
1987 // look for old num in sorted array
1988 if(nNewHdl != CONTAINER_ENTRY_NOTFOUND)
1990 SdrHdl* pNew = pHdlAndIndex[nNewHdl].mpHdl;
1992 for(a = 0; a < aList.Count(); a++)
1994 if((SdrHdl*)aList.GetObject(a) == pNew)
1996 nNewHdlNum = a;
1997 break;
2002 // take care of next handle
2003 if(nOldHdlNum != nNewHdlNum)
2005 mnFocusIndex = nNewHdlNum;
2006 SdrHdl* pNew = GetHdl(mnFocusIndex);
2008 if(pNew)
2010 pNew->Touch();
2011 //SDObRefresh = sal_True;
2015 // #105678# free mem again
2016 delete pHdlAndIndex;
2020 SdrHdl* SdrHdlList::GetFocusHdl() const
2022 if(mnFocusIndex != CONTAINER_ENTRY_NOTFOUND && mnFocusIndex < GetHdlCount())
2023 return GetHdl(mnFocusIndex);
2024 else
2025 return 0L;
2028 void SdrHdlList::SetFocusHdl(SdrHdl* pNew)
2030 if(pNew)
2032 SdrHdl* pActual = GetFocusHdl();
2034 if(!pActual || pActual != pNew)
2036 ULONG nNewHdlNum = GetHdlNum(pNew);
2038 if(nNewHdlNum != CONTAINER_ENTRY_NOTFOUND)
2040 //SDOsal_Bool bRefresh(sal_False);
2041 mnFocusIndex = nNewHdlNum;
2043 if(pActual)
2045 pActual->Touch();
2046 //SDObRefresh = sal_True;
2049 if(pNew)
2051 pNew->Touch();
2052 //SDObRefresh = sal_True;
2055 //OLMif(bRefresh)
2056 //OLM{
2057 //OLM if(pView)
2058 //OLM pView->RefreshAllIAOManagers();
2059 //OLM}
2065 void SdrHdlList::ResetFocusHdl()
2067 SdrHdl* pHdl = GetFocusHdl();
2069 mnFocusIndex = CONTAINER_ENTRY_NOTFOUND;
2071 if(pHdl)
2073 pHdl->Touch();
2077 ////////////////////////////////////////////////////////////////////////////////////////////////////
2079 SdrHdlList::SdrHdlList(SdrMarkView* pV)
2080 : mnFocusIndex(CONTAINER_ENTRY_NOTFOUND),
2081 pView(pV),
2082 aList(1024,32,32)
2084 nHdlSize = 3;
2085 bRotateShear = FALSE;
2086 bMoveOutside = FALSE;
2087 bDistortShear = FALSE;
2088 bFineHandles = FALSE;
2091 SdrHdlList::~SdrHdlList()
2093 Clear();
2096 void SdrHdlList::SetHdlSize(USHORT nSiz)
2098 if(nHdlSize != nSiz)
2100 // remember new value
2101 nHdlSize = nSiz;
2103 // propagate change to IAOs
2104 for(UINT32 i=0; i<GetHdlCount(); i++)
2106 SdrHdl* pHdl = GetHdl(i);
2107 pHdl->Touch();
2112 void SdrHdlList::SetMoveOutside(BOOL bOn)
2114 if(bMoveOutside != bOn)
2116 // remember new value
2117 bMoveOutside = bOn;
2119 // propagate change to IAOs
2120 for(UINT32 i=0; i<GetHdlCount(); i++)
2122 SdrHdl* pHdl = GetHdl(i);
2123 pHdl->Touch();
2128 void SdrHdlList::SetRotateShear(BOOL bOn)
2130 bRotateShear = bOn;
2133 void SdrHdlList::SetDistortShear(BOOL bOn)
2135 bDistortShear = bOn;
2138 void SdrHdlList::SetFineHdl(BOOL bOn)
2140 if(bFineHandles != bOn)
2142 // remember new state
2143 bFineHandles = bOn;
2145 // propagate change to IAOs
2146 for(UINT32 i=0; i<GetHdlCount(); i++)
2148 SdrHdl* pHdl = GetHdl(i);
2149 pHdl->Touch();
2154 SdrHdl* SdrHdlList::RemoveHdl(ULONG nNum)
2156 SdrHdl* pRetval = (SdrHdl*)aList.Remove(nNum);
2158 return pRetval;
2161 void SdrHdlList::Clear()
2163 for (ULONG i=0; i<GetHdlCount(); i++)
2165 SdrHdl* pHdl=GetHdl(i);
2166 delete pHdl;
2168 aList.Clear();
2170 bRotateShear=FALSE;
2171 bDistortShear=FALSE;
2174 void SdrHdlList::Sort()
2176 // #97016# II: remember current focused handle
2177 SdrHdl* pPrev = GetFocusHdl();
2179 ImpSdrHdlListSorter aSort(aList);
2180 aSort.DoSort();
2182 // #97016# II: get now and compare
2183 SdrHdl* pNow = GetFocusHdl();
2185 if(pPrev != pNow)
2187 //SDOsal_Bool bRefresh(sal_False);
2189 if(pPrev)
2191 pPrev->Touch();
2192 //SDObRefresh = sal_True;
2195 if(pNow)
2197 pNow->Touch();
2198 //SDObRefresh = sal_True;
2203 ULONG SdrHdlList::GetHdlNum(const SdrHdl* pHdl) const
2205 if (pHdl==NULL)
2206 return CONTAINER_ENTRY_NOTFOUND;
2207 ULONG nPos=aList.GetPos(pHdl);
2208 return nPos;
2211 void SdrHdlList::AddHdl(SdrHdl* pHdl, BOOL bAtBegin)
2213 if (pHdl!=NULL)
2215 if (bAtBegin)
2217 aList.Insert(pHdl,ULONG(0));
2219 else
2221 aList.Insert(pHdl,CONTAINER_APPEND);
2223 pHdl->SetHdlList(this);
2227 SdrHdl* SdrHdlList::IsHdlListHit(const Point& rPnt, BOOL bBack, BOOL bNext, SdrHdl* pHdl0) const
2229 SdrHdl* pRet=NULL;
2230 ULONG nAnz=GetHdlCount();
2231 ULONG nNum=bBack ? 0 : nAnz;
2232 while ((bBack ? nNum<nAnz : nNum>0) && pRet==NULL)
2234 if (!bBack)
2235 nNum--;
2236 SdrHdl* pHdl=GetHdl(nNum);
2237 if (bNext)
2239 if (pHdl==pHdl0)
2240 bNext=FALSE;
2242 else
2244 if (pHdl->IsHdlHit(rPnt))
2245 pRet=pHdl;
2247 if (bBack)
2248 nNum++;
2250 return pRet;
2253 SdrHdl* SdrHdlList::GetHdl(SdrHdlKind eKind1) const
2255 SdrHdl* pRet=NULL;
2256 for (ULONG i=0; i<GetHdlCount() && pRet==NULL; i++)
2258 SdrHdl* pHdl=GetHdl(i);
2259 if (pHdl->GetKind()==eKind1)
2260 pRet=pHdl;
2262 return pRet;
2265 // --------------------------------------------------------------------
2266 // SdrCropHdl
2267 // --------------------------------------------------------------------
2269 SdrCropHdl::SdrCropHdl(const Point& rPnt, SdrHdlKind eNewKind)
2270 : SdrHdl( rPnt, eNewKind )
2274 // --------------------------------------------------------------------
2276 BitmapEx SdrCropHdl::GetHandlesBitmap( bool bIsFineHdl, bool bIsHighContrast )
2278 if( bIsHighContrast )
2280 static BitmapEx* pHighContrastBitmap = 0;
2281 if( pHighContrastBitmap == 0 )
2282 pHighContrastBitmap = new BitmapEx(ResId(SIP_SA_ACCESSIBILITY_CROP_MARKERS, *ImpGetResMgr()));
2283 return *pHighContrastBitmap;
2285 else if( bIsFineHdl )
2287 static BitmapEx* pModernBitmap = 0;
2288 if( pModernBitmap == 0 )
2289 pModernBitmap = new BitmapEx(ResId(SIP_SA_CROP_FINE_MARKERS, *ImpGetResMgr()));
2290 return *pModernBitmap;
2292 else
2294 static BitmapEx* pSimpleBitmap = 0;
2295 if( pSimpleBitmap == 0 )
2296 pSimpleBitmap = new BitmapEx(ResId(SIP_SA_CROP_MARKERS, *ImpGetResMgr()));
2297 return *pSimpleBitmap;
2301 // --------------------------------------------------------------------
2303 BitmapEx SdrCropHdl::GetBitmapForHandle( const BitmapEx& rBitmap, int nSize )
2305 int nPixelSize = 0, nX = 0, nY = 0, nOffset = 0;
2307 if( nSize <= 3 )
2309 nPixelSize = 13;
2310 nOffset = 0;
2312 else if( nSize <=4 )
2314 nPixelSize = 17;
2315 nOffset = 36;
2317 else
2319 nPixelSize = 21;
2320 nOffset = 84;
2323 switch( eKind )
2325 case HDL_UPLFT: nX = 0; nY = 0; break;
2326 case HDL_UPPER: nX = 1; nY = 0; break;
2327 case HDL_UPRGT: nX = 2; nY = 0; break;
2328 case HDL_LEFT: nX = 0; nY = 1; break;
2329 case HDL_RIGHT: nX = 2; nY = 1; break;
2330 case HDL_LWLFT: nX = 0; nY = 2; break;
2331 case HDL_LOWER: nX = 1; nY = 2; break;
2332 case HDL_LWRGT: nX = 2; nY = 2; break;
2333 default: break;
2336 Rectangle aSourceRect( Point( nX * (nPixelSize-1) + nOffset, nY * (nPixelSize-1)), Size(nPixelSize, nPixelSize) );
2338 BitmapEx aRetval(rBitmap);
2339 aRetval.Crop(aSourceRect);
2340 return aRetval;
2343 // --------------------------------------------------------------------
2345 void SdrCropHdl::CreateB2dIAObject()
2347 // first throw away old one
2348 GetRidOfIAObject();
2350 SdrMarkView* pView = pHdlList ? pHdlList->GetView() : 0;
2351 SdrPageView* pPageView = pView ? pView->GetSdrPageView() : 0;
2353 if( pPageView && !pView->areMarkHandlesHidden() )
2355 sal_Bool bIsFineHdl(pHdlList->IsFineHdl());
2356 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
2357 sal_Bool bIsHighContrast(rStyleSettings.GetHighContrastMode());
2358 int nHdlSize = pHdlList->GetHdlSize();
2359 if( bIsHighContrast )
2360 nHdlSize = 4;
2362 const BitmapEx aHandlesBitmap( GetHandlesBitmap( bIsFineHdl, bIsHighContrast ) );
2363 BitmapEx aBmpEx1( GetBitmapForHandle( aHandlesBitmap, nHdlSize ) );
2365 for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
2367 // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
2368 const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
2370 if(rPageWindow.GetPaintWindow().OutputToWindow())
2372 if(rPageWindow.GetOverlayManager())
2374 basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
2376 ::sdr::overlay::OverlayObject* pOverlayObject = 0L;
2378 // animate focused handles
2379 if(IsFocusHdl() && (pHdlList->GetFocusHdl() == this))
2381 if( nHdlSize >= 2 )
2382 nHdlSize = 1;
2384 BitmapEx aBmpEx2( GetBitmapForHandle( aHandlesBitmap, nHdlSize + 1 ) );
2386 const sal_uInt32 nBlinkTime = sal::static_int_cast<sal_uInt32>(rStyleSettings.GetCursorBlinkTime());
2388 pOverlayObject = new ::sdr::overlay::OverlayAnimatedBitmapEx(aPosition, aBmpEx1, aBmpEx2, nBlinkTime,
2389 (UINT16)(aBmpEx1.GetSizePixel().Width() - 1) >> 1,
2390 (UINT16)(aBmpEx1.GetSizePixel().Height() - 1) >> 1,
2391 (UINT16)(aBmpEx2.GetSizePixel().Width() - 1) >> 1,
2392 (UINT16)(aBmpEx2.GetSizePixel().Height() - 1) >> 1);
2394 else
2396 // create centered handle as default
2397 pOverlayObject = new ::sdr::overlay::OverlayBitmapEx(aPosition, aBmpEx1,
2398 (UINT16)(aBmpEx1.GetSizePixel().Width() - 1) >> 1,
2399 (UINT16)(aBmpEx1.GetSizePixel().Height() - 1) >> 1);
2402 // OVERLAYMANAGER
2403 if(pOverlayObject)
2405 rPageWindow.GetOverlayManager()->add(*pOverlayObject);
2406 maOverlayGroup.append(*pOverlayObject);
2414 // --------------------------------------------------------------------