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