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