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