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