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