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
ScrollBarManager(SlideSorter & rSlideSorter)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
~ScrollBarManager(void)78 ScrollBarManager::~ScrollBarManager (void)
79 {
80 }
81
82
83
84
LateInitialization(void)85 void ScrollBarManager::LateInitialization (void)
86 {
87 }
88
89
90
91
Connect(void)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
Disconnect(void)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 */
PlaceScrollBars(const Rectangle & rAvailableArea,const bool bIsHorizontalScrollBarAllowed,const bool bIsVerticalScrollBarAllowed)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
PlaceHorizontalScrollBar(const Rectangle & aAvailableArea)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
PlaceVerticalScrollBar(const Rectangle & aArea)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
PlaceFiller(const Rectangle & aArea)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
UpdateScrollBars(bool bResetThumbPosition,bool bUseScrolling)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
IMPL_LINK(ScrollBarManager,VerticalScrollBarHandler,ScrollBar *,pScrollBar)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
IMPL_LINK(ScrollBarManager,HorizontalScrollBarHandler,ScrollBar *,pScrollBar)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
SetWindowOrigin(double nHorizontalPosition,double nVerticalPosition)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 */
DetermineScrollBarVisibilities(const Rectangle & rAvailableArea,const bool bIsHorizontalScrollBarAllowed,const bool bIsVerticalScrollBarAllowed)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
TestScrollBarVisibilities(bool bHorizontalScrollBarVisible,bool bVerticalScrollBarVisible,const Rectangle & rAvailableArea)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
SetTopLeft(const Point aNewTopLeft)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
GetTop(void) const491 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
GetLeft(void) const502 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
GetVerticalScrollBarWidth(void) const513 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
GetHorizontalScrollBarHeight(void) const524 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
CalcAutoScrollOffset(const Point & rMouseWindowPosition)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
AutoScroll(const Point & rMouseWindowPosition,const::boost::function<void (void)> & rAutoScrollFunctor)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
StopAutoScroll(void)608 void ScrollBarManager::StopAutoScroll (void)
609 {
610 maAutoScrollTimer.Stop();
611 mbIsAutoScrollActive = false;
612 }
613
614
615
616
RepeatAutoScroll(void)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
IMPL_LINK(ScrollBarManager,AutoScrollTimeoutHandler,Timer *,EMPTYARG)646 IMPL_LINK(ScrollBarManager, AutoScrollTimeoutHandler, Timer *, EMPTYARG)
647 {
648 RepeatAutoScroll();
649
650 return 0;
651 }
652
653
654
655
Scroll(const Orientation eOrientation,const Unit eUnit,const sal_Int32 nDistance)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