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_sdext.hxx" 26 27 #include "PresenterScrollBar.hxx" 28 #include "PresenterBitmapContainer.hxx" 29 #include "PresenterCanvasHelper.hxx" 30 #include "PresenterComponent.hxx" 31 #include "PresenterGeometryHelper.hxx" 32 #include "PresenterPaintManager.hxx" 33 #include "PresenterTimer.hxx" 34 #include "PresenterUIPainter.hxx" 35 #include <com/sun/star/awt/PosSize.hpp> 36 #include <com/sun/star/awt/WindowAttribute.hpp> 37 #include <com/sun/star/awt/XWindowPeer.hpp> 38 #include <com/sun/star/awt/XToolkit.hpp> 39 #include <com/sun/star/rendering/CompositeOperation.hpp> 40 #include <com/sun/star/rendering/TexturingMode.hpp> 41 #include <com/sun/star/rendering/XPolyPolygon2D.hpp> 42 #include <boost/bind.hpp> 43 #include <boost/enable_shared_from_this.hpp> 44 #include <boost/weak_ptr.hpp> 45 #include <math.h> 46 47 using namespace ::com::sun::star; 48 using namespace ::com::sun::star::uno; 49 using ::rtl::OUString; 50 51 #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString))) 52 53 const static double gnScrollBarGap (10); 54 55 namespace sdext { namespace presenter { 56 57 //===== PresenterScrollBar::MousePressRepeater ================================ 58 59 class PresenterScrollBar::MousePressRepeater 60 : public ::boost::enable_shared_from_this<MousePressRepeater> 61 { 62 public: 63 MousePressRepeater (const ::rtl::Reference<PresenterScrollBar>& rpScrollBar); 64 void Dispose (void); 65 void Start (const PresenterScrollBar::Area& reArea); 66 void Stop (void); 67 void SetMouseArea (const PresenterScrollBar::Area& reArea); 68 69 private: 70 void Callback (const TimeValue& rCurrentTime); 71 void Execute (void); 72 73 sal_Int32 mnMousePressRepeaterTaskId; 74 ::rtl::Reference<PresenterScrollBar> mpScrollBar; 75 PresenterScrollBar::Area meMouseArea; 76 }; 77 78 79 80 81 //===== PresenterScrollBar ==================================================== 82 83 boost::weak_ptr<PresenterBitmapContainer> PresenterScrollBar::mpSharedBitmaps; 84 85 PresenterScrollBar::PresenterScrollBar ( 86 const Reference<XComponentContext>& rxComponentContext, 87 const Reference<awt::XWindow>& rxParentWindow, 88 const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager, 89 const ::boost::function<void(double)>& rThumbMotionListener) 90 : PresenterScrollBarInterfaceBase(m_aMutex), 91 mxComponentContext(rxComponentContext), 92 mxParentWindow(rxParentWindow), 93 mxWindow(), 94 mxCanvas(), 95 mxPresenterHelper(), 96 mpPaintManager(rpPaintManager), 97 mnThumbPosition(0), 98 mnTotalSize(0), 99 mnThumbSize(0), 100 mnLineHeight(10), 101 maDragAnchor(-1,-1), 102 maThumbMotionListener(rThumbMotionListener), 103 meButtonDownArea(None), 104 meMouseMoveArea(None), 105 mbIsNotificationActive(false), 106 mpBitmaps(), 107 mpPrevButtonDescriptor(), 108 mpNextButtonDescriptor(), 109 mpPagerStartDescriptor(), 110 mpPagerCenterDescriptor(), 111 mpPagerEndDescriptor(), 112 mpThumbStartDescriptor(), 113 mpThumbCenterDescriptor(), 114 mpThumbEndDescriptor(), 115 mpMousePressRepeater(new MousePressRepeater(this)), 116 mpBackgroundBitmap(), 117 mpCanvasHelper(new PresenterCanvasHelper()) 118 { 119 try 120 { 121 Reference<lang::XMultiComponentFactory> xFactory (rxComponentContext->getServiceManager()); 122 if ( ! xFactory.is()) 123 throw RuntimeException(); 124 125 mxPresenterHelper = Reference<drawing::XPresenterHelper>( 126 xFactory->createInstanceWithContext( 127 OUString::createFromAscii("com.sun.star.comp.Draw.PresenterHelper"), 128 rxComponentContext), 129 UNO_QUERY_THROW); 130 131 if (mxPresenterHelper.is()) 132 mxWindow = mxPresenterHelper->createWindow(rxParentWindow, 133 sal_False, 134 sal_False, 135 sal_False, 136 sal_False); 137 138 // Make the background transparent. The slide show paints its own background. 139 Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY_THROW); 140 if (xPeer.is()) 141 { 142 xPeer->setBackground(0xff000000); 143 } 144 145 mxWindow->setVisible(sal_True); 146 mxWindow->addWindowListener(this); 147 mxWindow->addPaintListener(this); 148 mxWindow->addMouseListener(this); 149 mxWindow->addMouseMotionListener(this); 150 } 151 catch (RuntimeException&) 152 { 153 } 154 } 155 156 157 158 159 PresenterScrollBar::~PresenterScrollBar (void) 160 { 161 } 162 163 164 165 166 void SAL_CALL PresenterScrollBar::disposing (void) 167 { 168 mpMousePressRepeater->Dispose(); 169 170 if (mxWindow.is()) 171 { 172 mxWindow->removeWindowListener(this); 173 mxWindow->removePaintListener(this); 174 mxWindow->removeMouseListener(this); 175 mxWindow->removeMouseMotionListener(this); 176 177 Reference<lang::XComponent> xComponent (mxWindow, UNO_QUERY); 178 mxWindow = NULL; 179 if (xComponent.is()) 180 xComponent->dispose(); 181 } 182 183 mpBitmaps.reset(); 184 } 185 186 187 188 189 void PresenterScrollBar::SetVisible (const bool bIsVisible) 190 { 191 if (mxWindow.is()) 192 mxWindow->setVisible(bIsVisible); 193 } 194 195 196 197 198 void PresenterScrollBar::SetPosSize (const css::geometry::RealRectangle2D& rBox) 199 { 200 if (mxWindow.is()) 201 { 202 mxWindow->setPosSize( 203 sal_Int32(floor(rBox.X1)), 204 sal_Int32(ceil(rBox.Y1)), 205 sal_Int32(ceil(rBox.X2-rBox.X1)), 206 sal_Int32(floor(rBox.Y2-rBox.Y1)), 207 awt::PosSize::POSSIZE); 208 UpdateBorders(); 209 } 210 } 211 212 213 214 215 void PresenterScrollBar::SetThumbPosition ( 216 double nPosition, 217 const bool bAsynchronousUpdate) 218 { 219 SetThumbPosition(nPosition, bAsynchronousUpdate, true, true); 220 } 221 222 223 224 225 void PresenterScrollBar::SetThumbPosition ( 226 double nPosition, 227 const bool bAsynchronousUpdate, 228 const bool bValidate, 229 const bool bNotify) 230 { 231 if (bValidate) 232 nPosition = ValidateThumbPosition(nPosition); 233 234 if (nPosition != mnThumbPosition && ! mbIsNotificationActive) 235 { 236 mnThumbPosition = nPosition; 237 238 UpdateBorders(); 239 Repaint(GetRectangle(Total), bAsynchronousUpdate); 240 if (bNotify) 241 NotifyThumbPositionChange(); 242 } 243 } 244 245 246 247 248 double PresenterScrollBar::GetThumbPosition (void) const 249 { 250 return mnThumbPosition; 251 } 252 253 254 255 256 void PresenterScrollBar::SetTotalSize (const double nTotalSize) 257 { 258 if (mnTotalSize != nTotalSize) 259 { 260 mnTotalSize = nTotalSize + 1; 261 UpdateBorders(); 262 Repaint(GetRectangle(Total), false); 263 } 264 } 265 266 267 268 269 double PresenterScrollBar::GetTotalSize (void) const 270 { 271 return mnTotalSize; 272 } 273 274 275 276 277 void PresenterScrollBar::SetThumbSize (const double nThumbSize) 278 { 279 OSL_ASSERT(nThumbSize>=0); 280 if (mnThumbSize != nThumbSize) 281 { 282 mnThumbSize = nThumbSize; 283 UpdateBorders(); 284 Repaint(GetRectangle(Total), false); 285 } 286 } 287 288 289 290 291 double PresenterScrollBar::GetThumbSize (void) const 292 { 293 return mnThumbSize; 294 } 295 296 297 298 299 void PresenterScrollBar::SetLineHeight (const double nLineHeight) 300 { 301 mnLineHeight = nLineHeight; 302 } 303 304 305 306 307 double PresenterScrollBar::GetLineHeight (void) const 308 { 309 return mnLineHeight; 310 } 311 312 313 314 315 void PresenterScrollBar::SetCanvas (const Reference<css::rendering::XCanvas>& rxCanvas) 316 { 317 if (mxCanvas != rxCanvas) 318 { 319 mxCanvas = rxCanvas; 320 if (mxCanvas.is()) 321 { 322 if (mpBitmaps.get()==NULL) 323 { 324 if (mpSharedBitmaps.expired()) 325 { 326 try 327 { 328 mpBitmaps.reset(new PresenterBitmapContainer( 329 OUString::createFromAscii("PresenterScreenSettings/ScrollBar/Bitmaps"), 330 ::boost::shared_ptr<PresenterBitmapContainer>(), 331 mxComponentContext, 332 mxCanvas, 333 PresenterComponent::GetBasePath(mxComponentContext))); 334 mpSharedBitmaps = mpBitmaps; 335 } 336 catch(Exception&) 337 { 338 OSL_ASSERT(false); 339 } 340 } 341 else 342 mpBitmaps = ::boost::shared_ptr<PresenterBitmapContainer>(mpSharedBitmaps); 343 UpdateBitmaps(); 344 UpdateBorders(); 345 } 346 347 Repaint(GetRectangle(Total), false); 348 } 349 } 350 } 351 352 353 354 355 void PresenterScrollBar::SetBackground (const SharedBitmapDescriptor& rpBackgroundBitmap) 356 { 357 mpBackgroundBitmap = rpBackgroundBitmap; 358 } 359 360 361 362 void PresenterScrollBar::CheckValues (void) 363 { 364 mnThumbPosition = ValidateThumbPosition(mnThumbPosition); 365 } 366 367 368 369 370 double PresenterScrollBar::ValidateThumbPosition (double nPosition) 371 { 372 if (nPosition + mnThumbSize > mnTotalSize) 373 nPosition = mnTotalSize - mnThumbSize; 374 if (nPosition < 0) 375 nPosition = 0; 376 return nPosition; 377 } 378 379 380 381 382 void PresenterScrollBar::Paint ( 383 const awt::Rectangle& rUpdateBox, 384 const bool bNoClip) 385 { 386 if ( ! mxCanvas.is() || ! mxWindow.is()) 387 { 388 OSL_ASSERT(mxCanvas.is()); 389 OSL_ASSERT(mxWindow.is()); 390 return; 391 } 392 393 if ( ! bNoClip) 394 { 395 if (PresenterGeometryHelper::AreRectanglesDisjoint (rUpdateBox, mxWindow->getPosSize())) 396 return; 397 } 398 399 PaintBackground(rUpdateBox); 400 PaintComposite(rUpdateBox, PagerUp, 401 mpPagerStartDescriptor, mpPagerCenterDescriptor, SharedBitmapDescriptor()); 402 PaintComposite(rUpdateBox, PagerDown, 403 SharedBitmapDescriptor(), mpPagerCenterDescriptor, mpPagerEndDescriptor); 404 PaintComposite(rUpdateBox, Thumb, 405 mpThumbStartDescriptor, mpThumbCenterDescriptor, mpThumbEndDescriptor); 406 PaintBitmap(rUpdateBox, PrevButton, mpPrevButtonDescriptor); 407 PaintBitmap(rUpdateBox, NextButton, mpNextButtonDescriptor); 408 409 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY); 410 if (xSpriteCanvas.is()) 411 xSpriteCanvas->updateScreen(sal_False); 412 } 413 414 415 416 417 418 419 //----- XWindowListener ------------------------------------------------------- 420 421 void SAL_CALL PresenterScrollBar::windowResized (const css::awt::WindowEvent& rEvent) 422 throw (css::uno::RuntimeException) 423 { 424 (void)rEvent; 425 } 426 427 428 429 430 431 void SAL_CALL PresenterScrollBar::windowMoved (const css::awt::WindowEvent& rEvent) 432 throw (css::uno::RuntimeException) 433 { 434 (void)rEvent; 435 } 436 437 438 439 440 void SAL_CALL PresenterScrollBar::windowShown (const css::lang::EventObject& rEvent) 441 throw (css::uno::RuntimeException) 442 { 443 (void)rEvent; 444 } 445 446 447 448 449 void SAL_CALL PresenterScrollBar::windowHidden (const css::lang::EventObject& rEvent) 450 throw (css::uno::RuntimeException) 451 { 452 (void)rEvent; 453 } 454 455 456 457 458 //----- XPaintListener -------------------------------------------------------- 459 460 void SAL_CALL PresenterScrollBar::windowPaint (const css::awt::PaintEvent& rEvent) 461 throw (css::uno::RuntimeException) 462 { 463 if (mxWindow.is()) 464 { 465 awt::Rectangle aRepaintBox (rEvent.UpdateRect); 466 const awt::Rectangle aWindowBox (mxWindow->getPosSize()); 467 aRepaintBox.X += aWindowBox.X; 468 aRepaintBox.Y += aWindowBox.Y; 469 Paint(aRepaintBox); 470 471 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY); 472 if (xSpriteCanvas.is()) 473 xSpriteCanvas->updateScreen(sal_False); 474 } 475 } 476 477 478 479 480 //----- XMouseListener -------------------------------------------------------- 481 482 void SAL_CALL PresenterScrollBar::mousePressed (const css::awt::MouseEvent& rEvent) 483 throw(css::uno::RuntimeException) 484 { 485 maDragAnchor.X = rEvent.X; 486 maDragAnchor.Y = rEvent.Y; 487 meButtonDownArea = GetArea(rEvent.X, rEvent.Y); 488 489 mpMousePressRepeater->Start(meButtonDownArea); 490 } 491 492 493 494 495 void SAL_CALL PresenterScrollBar::mouseReleased (const css::awt::MouseEvent& rEvent) 496 throw(css::uno::RuntimeException) 497 { 498 (void)rEvent; 499 500 mpMousePressRepeater->Stop(); 501 502 if (mxPresenterHelper.is()) 503 mxPresenterHelper->releaseMouse(mxWindow); 504 } 505 506 507 508 509 void SAL_CALL PresenterScrollBar::mouseEntered (const css::awt::MouseEvent& rEvent) 510 throw(css::uno::RuntimeException) 511 { 512 (void)rEvent; 513 } 514 515 516 517 518 void SAL_CALL PresenterScrollBar::mouseExited (const css::awt::MouseEvent& rEvent) 519 throw(css::uno::RuntimeException) 520 { 521 (void)rEvent; 522 if (meMouseMoveArea != None) 523 { 524 const Area eOldMouseMoveArea (meMouseMoveArea); 525 meMouseMoveArea = None; 526 Repaint(GetRectangle(eOldMouseMoveArea), true); 527 } 528 meButtonDownArea = None; 529 meMouseMoveArea = None; 530 531 mpMousePressRepeater->Stop(); 532 } 533 534 535 536 537 538 //----- XMouseMotionListener -------------------------------------------------- 539 540 void SAL_CALL PresenterScrollBar::mouseMoved (const css::awt::MouseEvent& rEvent) 541 throw (css::uno::RuntimeException) 542 { 543 const Area eArea (GetArea(rEvent.X, rEvent.Y)); 544 if (eArea != meMouseMoveArea) 545 { 546 const Area eOldMouseMoveArea (meMouseMoveArea); 547 meMouseMoveArea = eArea; 548 if (eOldMouseMoveArea != None) 549 Repaint(GetRectangle(eOldMouseMoveArea), meMouseMoveArea==None); 550 if (meMouseMoveArea != None) 551 Repaint(GetRectangle(meMouseMoveArea), true); 552 } 553 mpMousePressRepeater->SetMouseArea(eArea); 554 } 555 556 557 558 559 void SAL_CALL PresenterScrollBar::mouseDragged (const css::awt::MouseEvent& rEvent) 560 throw (css::uno::RuntimeException) 561 { 562 if (meButtonDownArea != Thumb) 563 return; 564 565 mpMousePressRepeater->Stop(); 566 567 if (mxPresenterHelper.is()) 568 mxPresenterHelper->captureMouse(mxWindow); 569 570 const double nDragDistance (GetDragDistance(rEvent.X,rEvent.Y)); 571 UpdateDragAnchor(nDragDistance); 572 if (nDragDistance != 0) 573 { 574 SetThumbPosition(mnThumbPosition + nDragDistance, false, true, true); 575 } 576 } 577 578 579 580 581 //----- lang::XEventListener -------------------------------------------------- 582 583 void SAL_CALL PresenterScrollBar::disposing (const css::lang::EventObject& rEvent) 584 throw (css::uno::RuntimeException) 585 { 586 if (rEvent.Source == mxWindow) 587 mxWindow = NULL; 588 } 589 590 591 592 593 //----------------------------------------------------------------------------- 594 595 geometry::RealRectangle2D PresenterScrollBar::GetRectangle (const Area eArea) const 596 { 597 OSL_ASSERT(eArea>=0 && eArea<__AreaCount__); 598 599 return maBox[eArea]; 600 } 601 602 603 604 605 void PresenterScrollBar::Repaint ( 606 const geometry::RealRectangle2D aBox, 607 const bool bAsynchronousUpdate) 608 { 609 if (mpPaintManager.get() != NULL) 610 mpPaintManager->Invalidate( 611 mxWindow, 612 PresenterGeometryHelper::ConvertRectangle(aBox), 613 bAsynchronousUpdate); 614 } 615 616 617 618 619 void PresenterScrollBar::PaintBackground( 620 const css::awt::Rectangle& rUpdateBox) 621 { 622 if (mpBackgroundBitmap.get() == NULL) 623 return; 624 625 const awt::Rectangle aWindowBox (mxWindow->getPosSize()); 626 mpCanvasHelper->Paint( 627 mpBackgroundBitmap, 628 mxCanvas, 629 rUpdateBox, 630 aWindowBox, 631 awt::Rectangle()); 632 } 633 634 635 636 637 void PresenterScrollBar::PaintBitmap( 638 const css::awt::Rectangle& rUpdateBox, 639 const Area eArea, 640 const SharedBitmapDescriptor& rpBitmaps) 641 { 642 const geometry::RealRectangle2D aLocalBox (GetRectangle(eArea)); 643 const awt::Rectangle aWindowBox (mxWindow->getPosSize()); 644 geometry::RealRectangle2D aBox (aLocalBox); 645 aBox.X1 += aWindowBox.X; 646 aBox.Y1 += aWindowBox.Y; 647 aBox.X2 += aWindowBox.X; 648 aBox.Y2 += aWindowBox.Y; 649 650 Reference<rendering::XBitmap> xBitmap (GetBitmap(eArea,rpBitmaps)); 651 652 if (xBitmap.is()) 653 { 654 Reference<rendering::XPolyPolygon2D> xClipPolygon ( 655 PresenterGeometryHelper::CreatePolygon( 656 PresenterGeometryHelper::Intersection(rUpdateBox, 657 PresenterGeometryHelper::ConvertRectangle(aBox)), 658 mxCanvas->getDevice())); 659 660 const rendering::ViewState aViewState ( 661 geometry::AffineMatrix2D(1,0,0, 0,1,0), 662 xClipPolygon); 663 664 const geometry::IntegerSize2D aBitmapSize (xBitmap->getSize()); 665 rendering::RenderState aRenderState ( 666 geometry::AffineMatrix2D( 667 1,0,aBox.X1 + (aBox.X2-aBox.X1 - aBitmapSize.Width)/2, 668 0,1,aBox.Y1 + (aBox.Y2-aBox.Y1 - aBitmapSize.Height)/2), 669 NULL, 670 Sequence<double>(4), 671 rendering::CompositeOperation::SOURCE); 672 673 mxCanvas->drawBitmap( 674 xBitmap, 675 aViewState, 676 aRenderState); 677 } 678 } 679 680 681 682 683 void PresenterScrollBar::NotifyThumbPositionChange (void) 684 { 685 if ( ! mbIsNotificationActive) 686 { 687 mbIsNotificationActive = true; 688 689 try 690 { 691 maThumbMotionListener(mnThumbPosition); 692 } 693 catch (Exception&) 694 { 695 } 696 697 mbIsNotificationActive = false; 698 } 699 } 700 701 702 703 704 PresenterScrollBar::Area PresenterScrollBar::GetArea (const double nX, const double nY) const 705 { 706 const geometry::RealPoint2D aPoint(nX, nY); 707 708 if (PresenterGeometryHelper::IsInside(GetRectangle(Pager), aPoint)) 709 { 710 if (PresenterGeometryHelper::IsInside(GetRectangle(Thumb), aPoint)) 711 return Thumb; 712 else if (PresenterGeometryHelper::IsInside(GetRectangle(PagerUp), aPoint)) 713 return PagerUp; 714 else if (PresenterGeometryHelper::IsInside(GetRectangle(PagerDown), aPoint)) 715 return PagerDown; 716 } 717 else if (PresenterGeometryHelper::IsInside(GetRectangle(PrevButton), aPoint)) 718 return PrevButton; 719 else if (PresenterGeometryHelper::IsInside(GetRectangle(NextButton), aPoint)) 720 return NextButton; 721 722 return None; 723 } 724 725 726 727 728 void PresenterScrollBar::UpdateWidthOrHeight ( 729 sal_Int32& rSize, 730 const SharedBitmapDescriptor& rpDescriptor) 731 { 732 if (rpDescriptor.get() != NULL) 733 { 734 Reference<rendering::XBitmap> xBitmap (rpDescriptor->GetNormalBitmap()); 735 if (xBitmap.is()) 736 { 737 const geometry::IntegerSize2D aBitmapSize (xBitmap->getSize()); 738 const sal_Int32 nBitmapSize = (sal_Int32)GetMinor(aBitmapSize.Width, aBitmapSize.Height); 739 if (nBitmapSize > rSize) 740 rSize = nBitmapSize; 741 } 742 } 743 } 744 745 746 747 748 css::uno::Reference<css::rendering::XBitmap> PresenterScrollBar::GetBitmap ( 749 const Area eArea, 750 const SharedBitmapDescriptor& rpBitmaps) const 751 { 752 if (rpBitmaps.get() == NULL) 753 return NULL; 754 else 755 return rpBitmaps->GetBitmap(GetBitmapMode(eArea)); 756 } 757 758 759 760 761 PresenterBitmapContainer::BitmapDescriptor::Mode PresenterScrollBar::GetBitmapMode ( 762 const Area eArea) const 763 { 764 if (IsDisabled(eArea)) 765 return PresenterBitmapContainer::BitmapDescriptor::Disabled; 766 else if (eArea == meMouseMoveArea) 767 return PresenterBitmapContainer::BitmapDescriptor::MouseOver; 768 else 769 return PresenterBitmapContainer::BitmapDescriptor::Normal; 770 } 771 772 773 774 775 bool PresenterScrollBar::IsDisabled (const Area eArea) const 776 { 777 OSL_ASSERT(eArea>=0 && eArea<__AreaCount__); 778 779 return ! maEnabledState[eArea]; 780 } 781 782 783 784 785 //===== PresenterVerticalScrollBar ============================================ 786 787 PresenterVerticalScrollBar::PresenterVerticalScrollBar ( 788 const Reference<XComponentContext>& rxComponentContext, 789 const Reference<awt::XWindow>& rxParentWindow, 790 const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager, 791 const ::boost::function<void(double)>& rThumbMotionListener) 792 : PresenterScrollBar(rxComponentContext, rxParentWindow, rpPaintManager, rThumbMotionListener), 793 mnScrollBarWidth(0) 794 { 795 } 796 797 798 799 800 PresenterVerticalScrollBar::~PresenterVerticalScrollBar (void) 801 { 802 } 803 804 805 806 807 double PresenterVerticalScrollBar::GetDragDistance (const sal_Int32 nX, const sal_Int32 nY) const 808 { 809 (void)nX; 810 const double nDistance (nY - maDragAnchor.Y); 811 if (nDistance == 0) 812 return 0; 813 else 814 { 815 const awt::Rectangle aWindowBox (mxWindow->getPosSize()); 816 const double nBarWidth (aWindowBox.Width); 817 const double nPagerHeight (aWindowBox.Height - 2*nBarWidth); 818 const double nDragDistance (mnTotalSize / nPagerHeight * nDistance); 819 if (nDragDistance + mnThumbPosition < 0) 820 return -mnThumbPosition; 821 else if (mnThumbPosition + nDragDistance > mnTotalSize-mnThumbSize) 822 return mnTotalSize-mnThumbSize-mnThumbPosition; 823 else 824 return nDragDistance; 825 } 826 } 827 828 829 830 831 void PresenterVerticalScrollBar::UpdateDragAnchor (const double nDragDistance) 832 { 833 const awt::Rectangle aWindowBox (mxWindow->getPosSize()); 834 const double nBarWidth (aWindowBox.Width); 835 const double nPagerHeight (aWindowBox.Height - 2*nBarWidth); 836 maDragAnchor.Y += nDragDistance * nPagerHeight / mnTotalSize; 837 } 838 839 840 841 842 sal_Int32 PresenterVerticalScrollBar::GetSize (void) const 843 { 844 return mnScrollBarWidth; 845 } 846 847 848 849 850 geometry::RealPoint2D PresenterVerticalScrollBar::GetPoint ( 851 const double nMajor, const double nMinor) const 852 { 853 return geometry::RealPoint2D(nMinor, nMajor); 854 } 855 856 857 858 859 double PresenterVerticalScrollBar::GetMajor (const double nX, const double nY) const 860 { 861 (void)nX; 862 return nY; 863 } 864 865 866 867 868 double PresenterVerticalScrollBar::GetMinor (const double nX, const double nY) const 869 { 870 (void)nY; 871 return nX; 872 } 873 874 875 876 877 void PresenterVerticalScrollBar::UpdateBorders (void) 878 { 879 const awt::Rectangle aWindowBox (mxWindow->getPosSize()); 880 double nBottom = aWindowBox.Height; 881 882 if (mpNextButtonDescriptor.get() != NULL) 883 { 884 Reference<rendering::XBitmap> xBitmap (mpNextButtonDescriptor->GetNormalBitmap()); 885 if (xBitmap.is()) 886 { 887 geometry::IntegerSize2D aSize (xBitmap->getSize()); 888 maBox[NextButton] = geometry::RealRectangle2D( 889 0, nBottom - aSize.Height, aWindowBox.Width, nBottom); 890 nBottom -= aSize.Height + gnScrollBarGap; 891 } 892 } 893 if (mpPrevButtonDescriptor.get() != NULL) 894 { 895 Reference<rendering::XBitmap> xBitmap (mpPrevButtonDescriptor->GetNormalBitmap()); 896 if (xBitmap.is()) 897 { 898 geometry::IntegerSize2D aSize (xBitmap->getSize()); 899 maBox[PrevButton] = geometry::RealRectangle2D( 900 0, nBottom - aSize.Height, aWindowBox.Width, nBottom); 901 nBottom -= aSize.Height + gnScrollBarGap; 902 } 903 } 904 const double nPagerHeight (nBottom); 905 maBox[Pager] = geometry::RealRectangle2D( 906 0,0, aWindowBox.Width, nBottom); 907 if (mnTotalSize < 1) 908 { 909 maBox[Thumb] = maBox[Pager]; 910 911 // Set up the enabled/disabled states. 912 maEnabledState[PrevButton] = false; 913 maEnabledState[PagerUp] = false; 914 maEnabledState[NextButton] = false; 915 maEnabledState[PagerDown] = false; 916 maEnabledState[Thumb] = false; 917 } 918 else 919 { 920 const double nThumbSize = ::std::min(mnThumbSize,mnTotalSize); 921 const double nThumbPosition = ::std::min(::std::max(0.0,mnThumbPosition), mnTotalSize - nThumbSize); 922 maBox[Thumb] = geometry::RealRectangle2D( 923 0, nThumbPosition / mnTotalSize * nPagerHeight, 924 aWindowBox.Width, 925 (nThumbPosition+nThumbSize) / mnTotalSize * nPagerHeight); 926 927 // Set up the enabled/disabled states. 928 maEnabledState[PrevButton] = nThumbPosition>0; 929 maEnabledState[PagerUp] = nThumbPosition>0; 930 maEnabledState[NextButton] = nThumbPosition+nThumbSize < mnTotalSize; 931 maEnabledState[PagerDown] = nThumbPosition+nThumbSize < mnTotalSize; 932 maEnabledState[Thumb] = nThumbSize < mnTotalSize; 933 } 934 maBox[PagerUp] = geometry::RealRectangle2D( 935 maBox[Pager].X1, maBox[Pager].Y1, maBox[Pager].X2, maBox[Thumb].Y1-1); 936 maBox[PagerDown] = geometry::RealRectangle2D( 937 maBox[Pager].X1, maBox[Thumb].Y2+1, maBox[Pager].X2, maBox[Pager].Y2); 938 maBox[Total] = PresenterGeometryHelper::Union( 939 PresenterGeometryHelper::Union(maBox[PrevButton], maBox[NextButton]), 940 maBox[Pager]); 941 } 942 943 944 945 946 void PresenterVerticalScrollBar::UpdateBitmaps (void) 947 { 948 if (mpBitmaps.get() != NULL) 949 { 950 mpPrevButtonDescriptor = mpBitmaps->GetBitmap(A2S("Up")); 951 mpNextButtonDescriptor = mpBitmaps->GetBitmap(A2S("Down")); 952 mpPagerStartDescriptor = mpBitmaps->GetBitmap(A2S("PagerTop")); 953 mpPagerCenterDescriptor = mpBitmaps->GetBitmap(A2S("PagerVertical")); 954 mpPagerEndDescriptor = mpBitmaps->GetBitmap(A2S("PagerBottom")); 955 mpThumbStartDescriptor = mpBitmaps->GetBitmap(A2S("ThumbTop")); 956 mpThumbCenterDescriptor = mpBitmaps->GetBitmap(A2S("ThumbVertical")); 957 mpThumbEndDescriptor = mpBitmaps->GetBitmap(A2S("ThumbBottom")); 958 959 mnScrollBarWidth = 0; 960 UpdateWidthOrHeight(mnScrollBarWidth, mpPrevButtonDescriptor); 961 UpdateWidthOrHeight(mnScrollBarWidth, mpNextButtonDescriptor); 962 UpdateWidthOrHeight(mnScrollBarWidth, mpPagerStartDescriptor); 963 UpdateWidthOrHeight(mnScrollBarWidth, mpPagerCenterDescriptor); 964 UpdateWidthOrHeight(mnScrollBarWidth, mpPagerEndDescriptor); 965 UpdateWidthOrHeight(mnScrollBarWidth, mpThumbStartDescriptor); 966 UpdateWidthOrHeight(mnScrollBarWidth, mpThumbCenterDescriptor); 967 UpdateWidthOrHeight(mnScrollBarWidth, mpThumbEndDescriptor); 968 if (mnScrollBarWidth == 0) 969 mnScrollBarWidth = 20; 970 } 971 } 972 973 974 975 976 void PresenterVerticalScrollBar::PaintComposite( 977 const css::awt::Rectangle& rUpdateBox, 978 const Area eArea, 979 const SharedBitmapDescriptor& rpStartBitmaps, 980 const SharedBitmapDescriptor& rpCenterBitmaps, 981 const SharedBitmapDescriptor& rpEndBitmaps) 982 { 983 const awt::Rectangle aWindowBox (mxWindow->getPosSize()); 984 geometry::RealRectangle2D aBox (GetRectangle(eArea)); 985 aBox.X1 += aWindowBox.X; 986 aBox.Y1 += aWindowBox.Y; 987 aBox.X2 += aWindowBox.X; 988 aBox.Y2 += aWindowBox.Y; 989 990 // Get bitmaps and sizes. 991 992 PresenterUIPainter::PaintVerticalBitmapComposite( 993 mxCanvas, 994 rUpdateBox, 995 (eArea == Thumb 996 ? PresenterGeometryHelper::ConvertRectangleWithConstantSize(aBox) 997 : PresenterGeometryHelper::ConvertRectangle(aBox)), 998 GetBitmap(eArea, rpStartBitmaps), 999 GetBitmap(eArea, rpCenterBitmaps), 1000 GetBitmap(eArea, rpEndBitmaps)); 1001 } 1002 1003 1004 1005 1006 //===== PresenterHorizontalScrollBar ============================================ 1007 1008 PresenterHorizontalScrollBar::PresenterHorizontalScrollBar ( 1009 const Reference<XComponentContext>& rxComponentContext, 1010 const Reference<awt::XWindow>& rxParentWindow, 1011 const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager, 1012 const ::boost::function<void(double)>& rThumbMotionListener) 1013 : PresenterScrollBar(rxComponentContext, rxParentWindow, rpPaintManager, rThumbMotionListener), 1014 mnScrollBarHeight(0) 1015 { 1016 } 1017 1018 1019 1020 1021 PresenterHorizontalScrollBar::~PresenterHorizontalScrollBar (void) 1022 { 1023 } 1024 1025 1026 1027 1028 double PresenterHorizontalScrollBar::GetDragDistance (const sal_Int32 nX, const sal_Int32 nY) const 1029 { 1030 (void)nY; 1031 const double nDistance (nX - maDragAnchor.X); 1032 if (nDistance == 0) 1033 return 0; 1034 else 1035 { 1036 const awt::Rectangle aWindowBox (mxWindow->getPosSize()); 1037 const double nBarHeight (aWindowBox.Height); 1038 const double nPagerWidth (aWindowBox.Width - 2*nBarHeight); 1039 const double nDragDistance (mnTotalSize / nPagerWidth * nDistance); 1040 if (nDragDistance + mnThumbPosition < 0) 1041 return -mnThumbPosition; 1042 else if (mnThumbPosition + nDragDistance > mnTotalSize-mnThumbSize) 1043 return mnTotalSize-mnThumbSize-mnThumbPosition; 1044 else 1045 return nDragDistance; 1046 } 1047 } 1048 1049 1050 1051 1052 void PresenterHorizontalScrollBar::UpdateDragAnchor (const double nDragDistance) 1053 { 1054 const awt::Rectangle aWindowBox (mxWindow->getPosSize()); 1055 const double nBarHeight (aWindowBox.Height); 1056 const double nPagerWidth (aWindowBox.Width - 2*nBarHeight); 1057 maDragAnchor.X += nDragDistance * nPagerWidth / mnTotalSize; 1058 } 1059 1060 1061 1062 1063 sal_Int32 PresenterHorizontalScrollBar::GetSize (void) const 1064 { 1065 return mnScrollBarHeight; 1066 } 1067 1068 1069 1070 1071 1072 geometry::RealPoint2D PresenterHorizontalScrollBar::GetPoint ( 1073 const double nMajor, const double nMinor) const 1074 { 1075 return geometry::RealPoint2D(nMajor, nMinor); 1076 } 1077 1078 1079 1080 1081 double PresenterHorizontalScrollBar::GetMajor (const double nX, const double nY) const 1082 { 1083 (void)nY; 1084 return nX; 1085 } 1086 1087 1088 1089 1090 double PresenterHorizontalScrollBar::GetMinor (const double nX, const double nY) const 1091 { 1092 (void)nX; 1093 return nY; 1094 } 1095 1096 1097 1098 1099 void PresenterHorizontalScrollBar::UpdateBorders (void) 1100 { 1101 const awt::Rectangle aWindowBox (mxWindow->getPosSize()); 1102 double nRight = aWindowBox.Width; 1103 const double nGap (2); 1104 1105 if (mpNextButtonDescriptor.get() != NULL) 1106 { 1107 Reference<rendering::XBitmap> xBitmap (mpNextButtonDescriptor->GetNormalBitmap()); 1108 if (xBitmap.is()) 1109 { 1110 geometry::IntegerSize2D aSize (xBitmap->getSize()); 1111 maBox[NextButton] = geometry::RealRectangle2D( 1112 nRight - aSize.Width,0, nRight, aWindowBox.Height); 1113 nRight -= aSize.Width + nGap; 1114 } 1115 } 1116 if (mpPrevButtonDescriptor.get() != NULL) 1117 { 1118 Reference<rendering::XBitmap> xBitmap (mpPrevButtonDescriptor->GetNormalBitmap()); 1119 if (xBitmap.is()) 1120 { 1121 geometry::IntegerSize2D aSize (xBitmap->getSize()); 1122 maBox[PrevButton] = geometry::RealRectangle2D( 1123 nRight - aSize.Width,0, nRight, aWindowBox.Height); 1124 nRight -= aSize.Width + nGap; 1125 } 1126 } 1127 1128 const double nPagerWidth (nRight); 1129 maBox[Pager] = geometry::RealRectangle2D( 1130 0,0, nRight, aWindowBox.Height); 1131 if (mnTotalSize == 0) 1132 { 1133 maBox[Thumb] = maBox[Pager]; 1134 1135 // Set up the enabled/disabled states. 1136 maEnabledState[PrevButton] = false; 1137 maEnabledState[PagerUp] = false; 1138 maEnabledState[NextButton] = false; 1139 maEnabledState[PagerDown] = false; 1140 maEnabledState[Thumb] = false; 1141 } 1142 else 1143 { 1144 const double nThumbSize = ::std::min(mnThumbSize,mnTotalSize); 1145 const double nThumbPosition = ::std::min(::std::max(0.0,mnThumbPosition), mnTotalSize - nThumbSize); 1146 maBox[Thumb] = geometry::RealRectangle2D( 1147 (nThumbPosition) / mnTotalSize * nPagerWidth, 0, 1148 (nThumbPosition+nThumbSize) / mnTotalSize * nPagerWidth, aWindowBox.Height); 1149 1150 // Set up the enabled/disabled states. 1151 maEnabledState[PrevButton] = nThumbPosition>0; 1152 maEnabledState[PagerUp] = nThumbPosition>0; 1153 maEnabledState[NextButton] = nThumbPosition+nThumbSize < mnTotalSize; 1154 maEnabledState[PagerDown] = nThumbPosition+nThumbSize < mnTotalSize; 1155 maEnabledState[Thumb] = nThumbSize < mnTotalSize; 1156 } 1157 maBox[PagerUp] = geometry::RealRectangle2D( 1158 maBox[Pager].X1, maBox[Pager].Y1, maBox[Thumb].X1-1, maBox[Pager].Y2); 1159 maBox[PagerDown] = geometry::RealRectangle2D( 1160 maBox[Thumb].X2+1, maBox[Pager].Y1, maBox[Pager].X2, maBox[Pager].Y2); 1161 maBox[Total] = PresenterGeometryHelper::Union( 1162 PresenterGeometryHelper::Union(maBox[PrevButton], maBox[NextButton]), 1163 maBox[Pager]); 1164 } 1165 1166 1167 1168 1169 void PresenterHorizontalScrollBar::UpdateBitmaps (void) 1170 { 1171 if (mpBitmaps.get() != NULL) 1172 { 1173 mpPrevButtonDescriptor = mpBitmaps->GetBitmap(A2S("Left")); 1174 mpNextButtonDescriptor = mpBitmaps->GetBitmap(A2S("Right")); 1175 mpPagerStartDescriptor = mpBitmaps->GetBitmap(A2S("PagerLeft")); 1176 mpPagerCenterDescriptor = mpBitmaps->GetBitmap(A2S("PagerHorizontal")); 1177 mpPagerEndDescriptor = mpBitmaps->GetBitmap(A2S("PagerRight")); 1178 mpThumbStartDescriptor = mpBitmaps->GetBitmap(A2S("ThumbLeft")); 1179 mpThumbCenterDescriptor = mpBitmaps->GetBitmap(A2S("ThumbHorizontal")); 1180 mpThumbEndDescriptor = mpBitmaps->GetBitmap(A2S("ThumbRight")); 1181 1182 mnScrollBarHeight = 0; 1183 UpdateWidthOrHeight(mnScrollBarHeight, mpPrevButtonDescriptor); 1184 UpdateWidthOrHeight(mnScrollBarHeight, mpNextButtonDescriptor); 1185 UpdateWidthOrHeight(mnScrollBarHeight, mpPagerStartDescriptor); 1186 UpdateWidthOrHeight(mnScrollBarHeight, mpPagerCenterDescriptor); 1187 UpdateWidthOrHeight(mnScrollBarHeight, mpPagerEndDescriptor); 1188 UpdateWidthOrHeight(mnScrollBarHeight, mpThumbStartDescriptor); 1189 UpdateWidthOrHeight(mnScrollBarHeight, mpThumbCenterDescriptor); 1190 UpdateWidthOrHeight(mnScrollBarHeight, mpThumbEndDescriptor); 1191 if (mnScrollBarHeight == 0) 1192 mnScrollBarHeight = 20; 1193 } 1194 } 1195 1196 1197 1198 void PresenterHorizontalScrollBar::PaintComposite( 1199 const css::awt::Rectangle& rUpdateBox, 1200 const Area eArea, 1201 const SharedBitmapDescriptor& rpStartBitmaps, 1202 const SharedBitmapDescriptor& rpCenterBitmaps, 1203 const SharedBitmapDescriptor& rpEndBitmaps) 1204 { 1205 const awt::Rectangle aWindowBox (mxWindow->getPosSize()); 1206 geometry::RealRectangle2D aBox (GetRectangle(eArea)); 1207 aBox.X1 += aWindowBox.X; 1208 aBox.Y1 += aWindowBox.Y; 1209 aBox.X2 += aWindowBox.X; 1210 aBox.Y2 += aWindowBox.Y; 1211 1212 PresenterUIPainter::PaintHorizontalBitmapComposite( 1213 mxCanvas, 1214 rUpdateBox, 1215 PresenterGeometryHelper::ConvertRectangle(aBox), 1216 GetBitmap(eArea, rpStartBitmaps), 1217 GetBitmap(eArea, rpCenterBitmaps), 1218 GetBitmap(eArea, rpEndBitmaps)); 1219 } 1220 1221 1222 1223 1224 //===== PresenterScrollBar::MousePressRepeater ================================ 1225 1226 PresenterScrollBar::MousePressRepeater::MousePressRepeater ( 1227 const ::rtl::Reference<PresenterScrollBar>& rpScrollBar) 1228 : mnMousePressRepeaterTaskId(PresenterTimer::NotAValidTaskId), 1229 mpScrollBar(rpScrollBar), 1230 meMouseArea(PresenterScrollBar::None) 1231 { 1232 } 1233 1234 1235 1236 1237 void PresenterScrollBar::MousePressRepeater::Dispose (void) 1238 { 1239 Stop(); 1240 mpScrollBar = NULL; 1241 } 1242 1243 1244 1245 1246 void PresenterScrollBar::MousePressRepeater::Start (const PresenterScrollBar::Area& reArea) 1247 { 1248 meMouseArea = reArea; 1249 1250 if (mnMousePressRepeaterTaskId == PresenterTimer::NotAValidTaskId) 1251 { 1252 // Execute key press operation at least this one time. 1253 Execute(); 1254 1255 // Schedule repeated executions. 1256 mnMousePressRepeaterTaskId = PresenterTimer::ScheduleRepeatedTask ( 1257 ::boost::bind(&PresenterScrollBar::MousePressRepeater::Callback, shared_from_this(), _1), 1258 500000000, 1259 250000000); 1260 } 1261 else 1262 { 1263 // There is already an active repeating task. 1264 } 1265 } 1266 1267 1268 1269 1270 void PresenterScrollBar::MousePressRepeater::Stop (void) 1271 { 1272 if (mnMousePressRepeaterTaskId != PresenterTimer::NotAValidTaskId) 1273 { 1274 const sal_Int32 nTaskId (mnMousePressRepeaterTaskId); 1275 mnMousePressRepeaterTaskId = PresenterTimer::NotAValidTaskId; 1276 PresenterTimer::CancelTask(nTaskId); 1277 } 1278 } 1279 1280 1281 1282 1283 void PresenterScrollBar::MousePressRepeater::SetMouseArea(const PresenterScrollBar::Area& reArea) 1284 { 1285 if (meMouseArea != reArea) 1286 { 1287 if (mnMousePressRepeaterTaskId != PresenterTimer::NotAValidTaskId) 1288 { 1289 Stop(); 1290 } 1291 } 1292 } 1293 1294 1295 1296 1297 void PresenterScrollBar::MousePressRepeater::Callback (const TimeValue& rCurrentTime) 1298 { 1299 (void)rCurrentTime; 1300 1301 if (mpScrollBar.get() == NULL) 1302 { 1303 Stop(); 1304 return; 1305 } 1306 1307 Execute(); 1308 } 1309 1310 1311 1312 1313 void PresenterScrollBar::MousePressRepeater::Execute (void) 1314 { 1315 const double nThumbPosition (mpScrollBar->GetThumbPosition()); 1316 switch (meMouseArea) 1317 { 1318 case PrevButton: 1319 mpScrollBar->SetThumbPosition(nThumbPosition - mpScrollBar->GetLineHeight(), true); 1320 break; 1321 1322 case NextButton: 1323 mpScrollBar->SetThumbPosition(nThumbPosition + mpScrollBar->GetLineHeight(), true); 1324 break; 1325 1326 case PagerUp: 1327 mpScrollBar->SetThumbPosition(nThumbPosition - mpScrollBar->GetThumbSize()*0.8, true); 1328 break; 1329 1330 case PagerDown: 1331 mpScrollBar->SetThumbPosition(nThumbPosition + mpScrollBar->GetThumbSize()*0.8, true); 1332 break; 1333 1334 default: 1335 break; 1336 } 1337 } 1338 1339 1340 1341 } } // end of namespace ::sdext::presenter 1342