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 #include "precompiled_sd.hxx" 29 30 #include "controller/SlsScrollBarManager.hxx" 31 32 #include "SlideSorter.hxx" 33 #include "controller/SlideSorterController.hxx" 34 #include "controller/SlsVisibleAreaManager.hxx" 35 #include "model/SlideSorterModel.hxx" 36 #include "model/SlsPageDescriptor.hxx" 37 #include "view/SlideSorterView.hxx" 38 #include "view/SlsLayouter.hxx" 39 #include "view/SlsTheme.hxx" 40 #include "Window.hxx" 41 #include "sdpage.hxx" 42 43 #include <boost/limits.hpp> 44 45 #include <vcl/scrbar.hxx> 46 47 namespace sd { namespace slidesorter { namespace controller { 48 49 ScrollBarManager::ScrollBarManager (SlideSorter& rSlideSorter) 50 : mrSlideSorter(rSlideSorter), 51 mpHorizontalScrollBar(mrSlideSorter.GetHorizontalScrollBar()), 52 mpVerticalScrollBar(mrSlideSorter.GetVerticalScrollBar()), 53 mnHorizontalPosition (0), 54 mnVerticalPosition (0), 55 maScrollBorder (20,20), 56 mnHorizontalScrollFactor (0.15), 57 mnVerticalScrollFactor (0.25), 58 mpScrollBarFiller(mrSlideSorter.GetScrollBarFiller()), 59 maAutoScrollTimer(), 60 maAutoScrollOffset(0,0), 61 mbIsAutoScrollActive(false), 62 mpContentWindow(mrSlideSorter.GetContentWindow()), 63 maAutoScrollFunctor() 64 { 65 // Hide the scroll bars by default to prevent display errors while 66 // switching between view shells: In the short time between initiating 67 // such a switch and the final rearrangement of UI controls the scroll 68 // bars and the filler where displayed in the upper left corner of the 69 // ViewTabBar. 70 mpHorizontalScrollBar->Hide(); 71 mpVerticalScrollBar->Hide(); 72 mpScrollBarFiller->Hide(); 73 74 maAutoScrollTimer.SetTimeout(25); 75 maAutoScrollTimer.SetTimeoutHdl ( 76 LINK(this, ScrollBarManager, AutoScrollTimeoutHandler)); 77 } 78 79 80 81 82 ScrollBarManager::~ScrollBarManager (void) 83 { 84 } 85 86 87 88 89 void ScrollBarManager::LateInitialization (void) 90 { 91 } 92 93 94 95 96 void ScrollBarManager::Connect (void) 97 { 98 if (mpVerticalScrollBar != NULL) 99 { 100 mpVerticalScrollBar->SetScrollHdl ( 101 LINK(this, ScrollBarManager, VerticalScrollBarHandler)); 102 } 103 if (mpHorizontalScrollBar != NULL) 104 { 105 mpHorizontalScrollBar->SetScrollHdl( 106 LINK(this, ScrollBarManager, HorizontalScrollBarHandler)); 107 } 108 } 109 110 111 112 113 void ScrollBarManager::Disconnect (void) 114 { 115 if (mpVerticalScrollBar != NULL) 116 { 117 mpVerticalScrollBar->SetScrollHdl (Link()); 118 } 119 if (mpHorizontalScrollBar != NULL) 120 { 121 mpHorizontalScrollBar->SetScrollHdl (Link()); 122 } 123 } 124 125 126 127 128 /** Placing the scroll bars is an iterative process. The visibility of one 129 scroll bar affects the remaining size and thus may lead to the other 130 scroll bar becoming visible. 131 132 First we determine the visibility of the horizontal scroll bar. After 133 that we do the same for the vertical scroll bar. To have an initial 134 value for the required size we call the layouter before that. When one 135 of the two scroll bars is made visible then the size of the browser 136 window changes and a second call to the layouter becomes necessary. 137 That call is made anyway after this method returns. 138 */ 139 Rectangle ScrollBarManager::PlaceScrollBars ( 140 const Rectangle& rAvailableArea, 141 const bool bIsHorizontalScrollBarAllowed, 142 const bool bIsVerticalScrollBarAllowed) 143 { 144 Rectangle aRemainingSpace (DetermineScrollBarVisibilities( 145 rAvailableArea, 146 bIsHorizontalScrollBarAllowed, 147 bIsVerticalScrollBarAllowed)); 148 149 if (mpHorizontalScrollBar!=NULL && mpHorizontalScrollBar->IsVisible()) 150 PlaceHorizontalScrollBar (rAvailableArea); 151 152 if (mpVerticalScrollBar!=NULL && mpVerticalScrollBar->IsVisible()) 153 PlaceVerticalScrollBar (rAvailableArea); 154 155 if (mpScrollBarFiller!=NULL && mpScrollBarFiller->IsVisible()) 156 PlaceFiller (rAvailableArea); 157 158 return aRemainingSpace; 159 } 160 161 162 163 164 void ScrollBarManager::PlaceHorizontalScrollBar (const Rectangle& aAvailableArea) 165 { 166 // Save the current relative position. 167 mnHorizontalPosition = double(mpHorizontalScrollBar->GetThumbPos()) 168 / double(mpHorizontalScrollBar->GetRange().Len()); 169 170 // Place the scroll bar. 171 Size aScrollBarSize (mpHorizontalScrollBar->GetSizePixel()); 172 mpHorizontalScrollBar->SetPosSizePixel ( 173 Point(aAvailableArea.Left(), 174 aAvailableArea.Bottom()-aScrollBarSize.Height()+1), 175 Size (aAvailableArea.GetWidth() - GetVerticalScrollBarWidth(), 176 aScrollBarSize.Height())); 177 178 // Restore the relative position. 179 mpHorizontalScrollBar->SetThumbPos( 180 (long)(0.5 + mnHorizontalPosition * mpHorizontalScrollBar->GetRange().Len())); 181 } 182 183 184 185 186 void ScrollBarManager::PlaceVerticalScrollBar (const Rectangle& aArea) 187 { 188 const sal_Int32 nThumbPosition (mpVerticalScrollBar->GetThumbPos()); 189 190 // Place the scroll bar. 191 Size aScrollBarSize (mpVerticalScrollBar->GetSizePixel()); 192 Point aPosition (aArea.Right()-aScrollBarSize.Width()+1, aArea.Top()); 193 Size aSize (aScrollBarSize.Width(), aArea.GetHeight() - GetHorizontalScrollBarHeight()); 194 mpVerticalScrollBar->SetPosSizePixel(aPosition, aSize); 195 196 // Restore the position. 197 mpVerticalScrollBar->SetThumbPos(nThumbPosition); 198 mnVerticalPosition = nThumbPosition / double(mpVerticalScrollBar->GetRange().Len()); 199 } 200 201 202 203 204 void ScrollBarManager::PlaceFiller (const Rectangle& aArea) 205 { 206 mpScrollBarFiller->SetPosSizePixel( 207 Point( 208 aArea.Right()-mpVerticalScrollBar->GetSizePixel().Width()+1, 209 aArea.Bottom()-mpHorizontalScrollBar->GetSizePixel().Height()+1), 210 Size ( 211 mpVerticalScrollBar->GetSizePixel().Width(), 212 mpHorizontalScrollBar->GetSizePixel().Height())); 213 } 214 215 216 217 218 void ScrollBarManager::UpdateScrollBars (bool bResetThumbPosition, bool bUseScrolling) 219 { 220 Rectangle aModelArea (mrSlideSorter.GetView().GetModelArea()); 221 SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); 222 Size aWindowModelSize (pWindow->PixelToLogic(pWindow->GetSizePixel())); 223 224 // The horizontal scroll bar is only shown when the window is 225 // horizontally smaller than the view. 226 if (mpHorizontalScrollBar != NULL && mpHorizontalScrollBar->IsVisible()) 227 { 228 mpHorizontalScrollBar->Show(); 229 mpHorizontalScrollBar->SetRange ( 230 Range(aModelArea.Left(), aModelArea.Right())); 231 if (bResetThumbPosition) 232 { 233 mpHorizontalScrollBar->SetThumbPos (0); 234 mnHorizontalPosition = 0; 235 } 236 else 237 mnHorizontalPosition = 238 double(mpHorizontalScrollBar->GetThumbPos()) 239 / double(mpHorizontalScrollBar->GetRange().Len()); 240 241 mpHorizontalScrollBar->SetVisibleSize (aWindowModelSize.Width()); 242 243 const long nWidth (mpContentWindow->PixelToLogic( 244 mpContentWindow->GetSizePixel()).Width()); 245 // Make the line size about 10% of the visible width. 246 mpHorizontalScrollBar->SetLineSize (nWidth / 10); 247 // Make the page size about 90% of the visible width. 248 mpHorizontalScrollBar->SetPageSize ((nWidth * 9) / 10); 249 } 250 else 251 { 252 mnHorizontalPosition = 0; 253 } 254 255 // The vertical scroll bar is always shown. 256 if (mpVerticalScrollBar != NULL && mpVerticalScrollBar->IsVisible()) 257 { 258 mpVerticalScrollBar->SetRange ( 259 Range(aModelArea.Top(), aModelArea.Bottom())); 260 if (bResetThumbPosition) 261 { 262 mpVerticalScrollBar->SetThumbPos (0); 263 mnVerticalPosition = 0; 264 } 265 else 266 mnVerticalPosition = 267 double(mpVerticalScrollBar->GetThumbPos()) 268 / double(mpVerticalScrollBar->GetRange().Len()); 269 270 mpVerticalScrollBar->SetVisibleSize (aWindowModelSize.Height()); 271 272 const long nHeight (mpContentWindow->PixelToLogic( 273 mpContentWindow->GetSizePixel()).Height()); 274 // Make the line size about 10% of the visible height. 275 mpVerticalScrollBar->SetLineSize (nHeight / 10); 276 // Make the page size about 90% of the visible height. 277 mpVerticalScrollBar->SetPageSize ((nHeight * 9) / 10); 278 } 279 else 280 { 281 mnVerticalPosition = 0; 282 } 283 284 285 double nEps (::std::numeric_limits<double>::epsilon()); 286 if (fabs(mnHorizontalPosition-pWindow->GetVisibleX()) > nEps 287 || fabs(mnVerticalPosition-pWindow->GetVisibleY()) > nEps) 288 { 289 mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); 290 if (bUseScrolling) 291 pWindow->SetVisibleXY(mnHorizontalPosition, mnVerticalPosition); 292 else 293 SetWindowOrigin(mnHorizontalPosition, mnVerticalPosition); 294 } 295 } 296 297 298 299 300 IMPL_LINK(ScrollBarManager, VerticalScrollBarHandler, ScrollBar*, pScrollBar) 301 { 302 if (pScrollBar!=NULL 303 && pScrollBar==mpVerticalScrollBar.get() 304 && pScrollBar->IsVisible() 305 && mrSlideSorter.GetContentWindow()!=NULL) 306 { 307 double nRelativePosition = double(pScrollBar->GetThumbPos()) 308 / double(pScrollBar->GetRange().Len()); 309 mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); 310 mrSlideSorter.GetContentWindow()->SetVisibleXY(-1, nRelativePosition); 311 mrSlideSorter.GetController().GetVisibleAreaManager().DeactivateCurrentSlideTracking(); 312 } 313 return sal_True; 314 } 315 316 317 318 319 IMPL_LINK(ScrollBarManager, HorizontalScrollBarHandler, ScrollBar*, pScrollBar) 320 { 321 if (pScrollBar!=NULL 322 && pScrollBar==mpHorizontalScrollBar.get() 323 && pScrollBar->IsVisible() 324 && mrSlideSorter.GetContentWindow()!=NULL) 325 { 326 double nRelativePosition = double(pScrollBar->GetThumbPos()) 327 / double(pScrollBar->GetRange().Len()); 328 mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); 329 mrSlideSorter.GetContentWindow()->SetVisibleXY(nRelativePosition, -1); 330 mrSlideSorter.GetController().GetVisibleAreaManager().DeactivateCurrentSlideTracking(); 331 } 332 return sal_True; 333 } 334 335 336 337 338 void ScrollBarManager::SetWindowOrigin ( 339 double nHorizontalPosition, 340 double nVerticalPosition) 341 { 342 mnHorizontalPosition = nHorizontalPosition; 343 mnVerticalPosition = nVerticalPosition; 344 345 SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); 346 Size aViewSize (pWindow->GetViewSize()); 347 Point aOrigin ( 348 (long int) (mnHorizontalPosition * aViewSize.Width()), 349 (long int) (mnVerticalPosition * aViewSize.Height())); 350 351 pWindow->SetWinViewPos (aOrigin); 352 pWindow->UpdateMapMode (); 353 pWindow->Invalidate (); 354 } 355 356 357 358 359 /** Determining the visibility of the scroll bars is quite complicated. The 360 visibility of one influences that of the other because showing a scroll 361 bar makes the available space smaller and may lead to the need of 362 displaying the other. 363 To solve this we test all four combinations of showing or hiding each 364 scroll bar and use the best one. The best one is that combination that 365 a) shows the least number of scroll bars with preference of showing the 366 vertical over showing the horizontal and 367 b) when not showing a scroll bar the area used by the page objects fits 368 into the available area in the scroll bars orientation. 369 */ 370 Rectangle ScrollBarManager::DetermineScrollBarVisibilities ( 371 const Rectangle& rAvailableArea, 372 const bool bIsHorizontalScrollBarAllowed, 373 const bool bIsVerticalScrollBarAllowed) 374 { 375 // Test which combination of scroll bars is the best. 376 bool bShowHorizontal = false; 377 bool bShowVertical = false; 378 if (mrSlideSorter.GetModel().GetPageCount() == 0) 379 { 380 // No pages => no scroll bars. 381 } 382 else if (TestScrollBarVisibilities(false, false, rAvailableArea)) 383 { 384 // Nothing to be done. 385 } 386 else if (bIsHorizontalScrollBarAllowed 387 && TestScrollBarVisibilities(true, false, rAvailableArea)) 388 { 389 bShowHorizontal = true; 390 } 391 else if (bIsVerticalScrollBarAllowed 392 && TestScrollBarVisibilities(false, true, rAvailableArea)) 393 { 394 bShowVertical = true; 395 } 396 else 397 { 398 bShowHorizontal = true; 399 bShowVertical = true; 400 } 401 402 // Make the visibility of the scroll bars permanent. 403 mpVerticalScrollBar->Show(bShowVertical); 404 mpHorizontalScrollBar->Show(bShowHorizontal); 405 mpScrollBarFiller->Show(bShowVertical && bShowHorizontal); 406 407 // Adapt the remaining space accordingly. 408 Rectangle aRemainingSpace (rAvailableArea); 409 if (bShowVertical) 410 aRemainingSpace.Right() -= mpVerticalScrollBar->GetSizePixel().Width(); 411 if (bShowHorizontal) 412 aRemainingSpace.Bottom() -= mpHorizontalScrollBar->GetSizePixel().Height(); 413 414 return aRemainingSpace; 415 } 416 417 418 419 420 bool ScrollBarManager::TestScrollBarVisibilities ( 421 bool bHorizontalScrollBarVisible, 422 bool bVerticalScrollBarVisible, 423 const Rectangle& rAvailableArea) 424 { 425 model::SlideSorterModel& rModel (mrSlideSorter.GetModel()); 426 427 // Adapt the available size by subtracting the sizes of the scroll bars 428 // visible in this combination. 429 Size aBrowserSize (rAvailableArea.GetSize()); 430 if (bHorizontalScrollBarVisible) 431 aBrowserSize.Height() -= mpHorizontalScrollBar->GetSizePixel().Height(); 432 if (bVerticalScrollBarVisible) 433 aBrowserSize.Width() -= mpVerticalScrollBar->GetSizePixel().Width(); 434 435 // Tell the view to rearrange its page objects and check whether the 436 // page objects can be shown without clipping. 437 bool bRearrangeSuccess (mrSlideSorter.GetView().GetLayouter().Rearrange ( 438 mrSlideSorter.GetView().GetOrientation(), 439 aBrowserSize, 440 rModel.GetPageDescriptor(0)->GetPage()->GetSize(), 441 rModel.GetPageCount())); 442 443 if (bRearrangeSuccess) 444 { 445 Size aPageSize = mrSlideSorter.GetView().GetLayouter().GetTotalBoundingBox().GetSize(); 446 Size aWindowModelSize = mpContentWindow->PixelToLogic(aBrowserSize); 447 448 // The content may be clipped, i.e. not fully visible, in one 449 // direction only when the scroll bar is visible in that direction. 450 if (aPageSize.Width() > aWindowModelSize.Width()) 451 if ( ! bHorizontalScrollBarVisible) 452 return false; 453 if (aPageSize.Height() > aWindowModelSize.Height()) 454 if ( ! bVerticalScrollBarVisible) 455 return false; 456 457 return true; 458 } 459 else 460 return false; 461 } 462 463 464 465 466 void ScrollBarManager::SetTopLeft (const Point aNewTopLeft) 467 { 468 if (( ! mpVerticalScrollBar 469 || mpVerticalScrollBar->GetThumbPos() == aNewTopLeft.Y()) 470 && ( ! mpHorizontalScrollBar 471 || mpHorizontalScrollBar->GetThumbPos() == aNewTopLeft.X())) 472 return; 473 474 // Flush pending repaints before scrolling to avoid temporary artifacts. 475 mrSlideSorter.GetContentWindow()->Update(); 476 477 if (mpVerticalScrollBar) 478 { 479 mpVerticalScrollBar->SetThumbPos(aNewTopLeft.Y()); 480 mnVerticalPosition = aNewTopLeft.Y() / double(mpVerticalScrollBar->GetRange().Len()); 481 } 482 if (mpHorizontalScrollBar) 483 { 484 mpHorizontalScrollBar->SetThumbPos(aNewTopLeft.X()); 485 mnHorizontalPosition = aNewTopLeft.X() / double(mpHorizontalScrollBar->GetRange().Len()); 486 } 487 488 mrSlideSorter.GetContentWindow()->SetVisibleXY(mnHorizontalPosition, mnVerticalPosition); 489 mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); 490 } 491 492 493 494 495 sal_Int32 ScrollBarManager::GetTop (void) const 496 { 497 if (mpVerticalScrollBar != NULL) 498 return mpVerticalScrollBar->GetThumbPos(); 499 else 500 return 0; 501 } 502 503 504 505 506 sal_Int32 ScrollBarManager::GetLeft (void) const 507 { 508 if (mpHorizontalScrollBar != NULL) 509 return mpHorizontalScrollBar->GetThumbPos(); 510 else 511 return 0; 512 } 513 514 515 516 517 int ScrollBarManager::GetVerticalScrollBarWidth (void) const 518 { 519 if (mpVerticalScrollBar != NULL && mpVerticalScrollBar->IsVisible()) 520 return mpVerticalScrollBar->GetSizePixel().Width(); 521 else 522 return 0; 523 } 524 525 526 527 528 int ScrollBarManager::GetHorizontalScrollBarHeight (void) const 529 { 530 if (mpHorizontalScrollBar != NULL && mpHorizontalScrollBar->IsVisible()) 531 return mpHorizontalScrollBar->GetSizePixel().Height(); 532 else 533 return 0; 534 } 535 536 537 538 539 void ScrollBarManager::CalcAutoScrollOffset (const Point& rMouseWindowPosition) 540 { 541 SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); 542 543 int nDx = 0; 544 int nDy = 0; 545 546 Size aWindowSize = pWindow->GetOutputSizePixel(); 547 Rectangle aWindowArea (pWindow->GetPosPixel(), aWindowSize); 548 Rectangle aViewPixelArea ( 549 pWindow->LogicToPixel(mrSlideSorter.GetView().GetModelArea())); 550 551 if (aWindowSize.Width() > maScrollBorder.Width() * 3 552 && mpHorizontalScrollBar != NULL 553 && mpHorizontalScrollBar->IsVisible()) 554 { 555 if (rMouseWindowPosition.X() < maScrollBorder.Width() 556 && aWindowArea.Left() > aViewPixelArea.Left()) 557 { 558 nDx = -1 + (int)(mnHorizontalScrollFactor 559 * (rMouseWindowPosition.X() - maScrollBorder.Width())); 560 } 561 562 if (rMouseWindowPosition.X() >= (aWindowSize.Width() - maScrollBorder.Width()) 563 && aWindowArea.Right() < aViewPixelArea.Right()) 564 { 565 nDx = 1 + (int)(mnHorizontalScrollFactor 566 * (rMouseWindowPosition.X() - aWindowSize.Width() 567 + maScrollBorder.Width())); 568 } 569 } 570 571 if (aWindowSize.Height() > maScrollBorder.Height() * 3 572 && aWindowSize.Height() < aViewPixelArea.GetHeight()) 573 { 574 if (rMouseWindowPosition.Y() < maScrollBorder.Height() 575 && aWindowArea.Top() > aViewPixelArea.Top()) 576 { 577 nDy = -1 + (int)(mnVerticalScrollFactor 578 * (rMouseWindowPosition.Y() - maScrollBorder.Height())); 579 } 580 581 if (rMouseWindowPosition.Y() >= (aWindowSize.Height() - maScrollBorder.Height()) 582 && aWindowArea.Bottom() < aViewPixelArea.Bottom()) 583 { 584 nDy = 1 + (int)(mnVerticalScrollFactor 585 * (rMouseWindowPosition.Y() - aWindowSize.Height() 586 + maScrollBorder.Height())); 587 } 588 } 589 590 maAutoScrollOffset = Size(nDx,nDy); 591 } 592 593 594 595 596 bool ScrollBarManager::AutoScroll ( 597 const Point& rMouseWindowPosition, 598 const ::boost::function<void(void)>& rAutoScrollFunctor) 599 { 600 maAutoScrollFunctor = rAutoScrollFunctor; 601 CalcAutoScrollOffset(rMouseWindowPosition); 602 bool bResult (true); 603 if ( ! mbIsAutoScrollActive) 604 bResult = RepeatAutoScroll(); 605 606 return bResult; 607 } 608 609 610 611 612 void ScrollBarManager::StopAutoScroll (void) 613 { 614 maAutoScrollTimer.Stop(); 615 mbIsAutoScrollActive = false; 616 } 617 618 619 620 621 bool ScrollBarManager::RepeatAutoScroll (void) 622 { 623 if (maAutoScrollOffset != Size(0,0)) 624 { 625 if (mrSlideSorter.GetViewShell() != NULL) 626 { 627 mrSlideSorter.GetViewShell()->Scroll( 628 maAutoScrollOffset.Width(), 629 maAutoScrollOffset.Height()); 630 mrSlideSorter.GetView().InvalidatePageObjectVisibilities(); 631 632 if (maAutoScrollFunctor) 633 maAutoScrollFunctor(); 634 635 mbIsAutoScrollActive = true; 636 maAutoScrollTimer.Start(); 637 638 return true; 639 } 640 } 641 642 maAutoScrollFunctor = ::boost::function<void(void)>(); 643 mbIsAutoScrollActive = false; 644 return false; 645 } 646 647 648 649 650 IMPL_LINK(ScrollBarManager, AutoScrollTimeoutHandler, Timer *, EMPTYARG) 651 { 652 RepeatAutoScroll(); 653 654 return 0; 655 } 656 657 658 659 660 void ScrollBarManager::Scroll( 661 const Orientation eOrientation, 662 const Unit eUnit, 663 const sal_Int32 nDistance) 664 { 665 bool bIsVertical (false); 666 switch (eOrientation) 667 { 668 case Orientation_Horizontal: bIsVertical = false; break; 669 case Orientation_Vertical: bIsVertical = true; break; 670 default: 671 OSL_ASSERT(eOrientation==Orientation_Horizontal || eOrientation==Orientation_Vertical); 672 return; 673 } 674 675 Point aNewTopLeft ( 676 mpHorizontalScrollBar ? mpHorizontalScrollBar->GetThumbPos() : 0, 677 mpVerticalScrollBar ? mpVerticalScrollBar->GetThumbPos() : 0); 678 switch (eUnit) 679 { 680 case Unit_Pixel: 681 if (bIsVertical) 682 aNewTopLeft.Y() += nDistance; 683 else 684 aNewTopLeft.X() += nDistance; 685 break; 686 687 case Unit_Slide: 688 { 689 view::Layouter& rLayouter (mrSlideSorter.GetView().GetLayouter()); 690 691 // Calculate estimate of new location. 692 if (bIsVertical) 693 aNewTopLeft.Y() += nDistance * rLayouter.GetPageObjectSize().Height(); 694 else 695 aNewTopLeft.X() += nDistance * rLayouter.GetPageObjectSize().Width(); 696 697 // Adapt location to show whole slides. 698 if (bIsVertical) 699 if (nDistance > 0) 700 { 701 const sal_Int32 nIndex (rLayouter.GetIndexAtPoint( 702 Point(aNewTopLeft.X(), aNewTopLeft.Y()+mpVerticalScrollBar->GetVisibleSize()), 703 true)); 704 aNewTopLeft.Y() = rLayouter.GetPageObjectBox(nIndex,true).Bottom() 705 - mpVerticalScrollBar->GetVisibleSize(); 706 } 707 else 708 { 709 const sal_Int32 nIndex (rLayouter.GetIndexAtPoint( 710 Point(aNewTopLeft.X(), aNewTopLeft.Y()), 711 true)); 712 aNewTopLeft.Y() = rLayouter.GetPageObjectBox(nIndex,true).Top(); 713 } 714 else 715 if (nDistance > 0) 716 { 717 const sal_Int32 nIndex (rLayouter.GetIndexAtPoint( 718 Point(aNewTopLeft.X()+mpVerticalScrollBar->GetVisibleSize(), aNewTopLeft.Y()), 719 true)); 720 aNewTopLeft.X() = rLayouter.GetPageObjectBox(nIndex,true).Right() 721 - mpVerticalScrollBar->GetVisibleSize(); 722 } 723 else 724 { 725 const sal_Int32 nIndex (rLayouter.GetIndexAtPoint( 726 Point(aNewTopLeft.X(), aNewTopLeft.Y()), 727 true)); 728 aNewTopLeft.X() = rLayouter.GetPageObjectBox(nIndex,true).Left(); 729 } 730 } 731 } 732 mrSlideSorter.GetController().GetVisibleAreaManager().DeactivateCurrentSlideTracking(); 733 SetTopLeft(aNewTopLeft); 734 } 735 736 737 } } } // end of namespace ::sd::slidesorter::controller 738