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