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