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