Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "controller/SlsVisibleAreaManager.hxx"
31 : : #include "controller/SlideSorterController.hxx"
32 : : #include "controller/SlsProperties.hxx"
33 : : #include "controller/SlsAnimationFunction.hxx"
34 : : #include "controller/SlsScrollBarManager.hxx"
35 : : #include "controller/SlsCurrentSlideManager.hxx"
36 : :
37 : :
38 : : namespace sd { namespace slidesorter { namespace controller {
39 : :
40 : : namespace {
41 : 0 : class VisibleAreaScroller
42 : : {
43 : : public:
44 : : VisibleAreaScroller (
45 : : SlideSorter& rSlideSorter,
46 : : const Point aStart,
47 : : const Point aEnd);
48 : : void operator() (const double nValue);
49 : : private:
50 : : SlideSorter& mrSlideSorter;
51 : : Point maStart;
52 : : const Point maEnd;
53 : : const ::boost::function<double(double)> maAccelerationFunction;
54 : : };
55 : :
56 : : } // end of anonymous namespace
57 : :
58 : :
59 : :
60 : 130 : VisibleAreaManager::VisibleAreaManager (SlideSorter& rSlideSorter)
61 : : : mrSlideSorter(rSlideSorter),
62 : : maVisibleRequests(),
63 : : mnScrollAnimationId(Animator::NotAnAnimationId),
64 : : maRequestedVisibleTopLeft(),
65 : : meRequestedAnimationMode(Animator::AM_Immediate),
66 : : mbIsCurrentSlideTrackingActive(true),
67 [ + - ]: 130 : mnDisableCount(0)
68 : : {
69 : 130 : }
70 : :
71 : :
72 : :
73 : :
74 : 130 : VisibleAreaManager::~VisibleAreaManager (void)
75 : : {
76 : 130 : }
77 : :
78 : :
79 : :
80 : :
81 : 0 : void VisibleAreaManager::ActivateCurrentSlideTracking (void)
82 : : {
83 : 0 : mbIsCurrentSlideTrackingActive = true;
84 : 0 : }
85 : :
86 : :
87 : :
88 : :
89 : 0 : void VisibleAreaManager::DeactivateCurrentSlideTracking (void)
90 : : {
91 : 0 : mbIsCurrentSlideTrackingActive = false;
92 : 0 : }
93 : :
94 : :
95 : :
96 : :
97 : 0 : bool VisibleAreaManager::IsCurrentSlideTrackingActive (void) const
98 : : {
99 : 0 : return mbIsCurrentSlideTrackingActive;
100 : : }
101 : :
102 : :
103 : :
104 : :
105 : 838 : void VisibleAreaManager::RequestVisible (
106 : : const model::SharedPageDescriptor& rpDescriptor,
107 : : const bool bForce)
108 : : {
109 [ + - ]: 838 : if (rpDescriptor)
110 : : {
111 [ + + ]: 838 : if (mnDisableCount == 0)
112 : : {
113 : : maVisibleRequests.push_back(
114 : 570 : mrSlideSorter.GetView().GetLayouter().GetPageObjectBox(
115 : : rpDescriptor->GetPageIndex(),
116 [ + - ]: 1140 : true));
117 : : }
118 [ + + ][ - + ]: 838 : if (bForce && ! mbIsCurrentSlideTrackingActive)
119 : 0 : ActivateCurrentSlideTracking();
120 : 838 : MakeVisible();
121 : : }
122 : 838 : }
123 : :
124 : :
125 : :
126 : :
127 : 302 : void VisibleAreaManager::RequestCurrentSlideVisible (void)
128 : : {
129 [ + - ][ + - ]: 302 : if (mbIsCurrentSlideTrackingActive && mnDisableCount==0)
130 : : RequestVisible(
131 [ + - ][ + - ]: 302 : mrSlideSorter.GetController().GetCurrentSlideManager()->GetCurrentSlide());
[ + - ]
132 : 302 : }
133 : :
134 : :
135 : :
136 : :
137 : 838 : void VisibleAreaManager::MakeVisible (void)
138 : : {
139 [ + + ]: 838 : if (maVisibleRequests.empty())
140 : : return;
141 : :
142 [ + - ]: 570 : SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
143 [ - + ]: 570 : if ( ! pWindow)
144 : : return;
145 [ + - ]: 570 : const Point aCurrentTopLeft (pWindow->PixelToLogic(Point(0,0)));
146 : :
147 [ + - ]: 570 : const ::boost::optional<Point> aNewVisibleTopLeft (GetRequestedTopLeft());
148 : 570 : maVisibleRequests.clear();
149 [ + - ][ + - ]: 570 : if ( ! aNewVisibleTopLeft)
150 : : return;
151 : :
152 : : // We now know what the visible area shall be. Scroll accordingly
153 : : // unless that is not already the visible area or a running scroll
154 : : // animation has it as its target area.
155 [ # # ][ # # ]: 0 : if (mnScrollAnimationId!=Animator::NotAnAnimationId
[ # # ]
156 [ # # ]: 0 : && maRequestedVisibleTopLeft==aNewVisibleTopLeft)
157 : : return;
158 : :
159 : : // Stop a running animation.
160 [ # # ]: 0 : if (mnScrollAnimationId != Animator::NotAnAnimationId)
161 [ # # ][ # # ]: 0 : mrSlideSorter.GetController().GetAnimator()->RemoveAnimation(mnScrollAnimationId);
[ # # ][ # # ]
162 : :
163 [ # # ]: 0 : maRequestedVisibleTopLeft = aNewVisibleTopLeft.get();
164 : : VisibleAreaScroller aAnimation(
165 : : mrSlideSorter,
166 : : aCurrentTopLeft,
167 [ # # ]: 0 : maRequestedVisibleTopLeft);
168 [ # # ][ # # ]: 0 : if (meRequestedAnimationMode==Animator::AM_Animated
[ # # ]
169 [ # # ][ # # ]: 0 : && mrSlideSorter.GetProperties()->IsSmoothSelectionScrolling())
[ # # ][ # # ]
[ # # ]
170 : : {
171 [ # # ]: 0 : mnScrollAnimationId = mrSlideSorter.GetController().GetAnimator()->AddAnimation(
172 : : aAnimation,
173 : : 0,
174 [ # # ][ # # ]: 0 : 300);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
175 : : }
176 : : else
177 : : {
178 : : // Execute the animation at its final value.
179 [ # # ]: 0 : aAnimation(1.0);
180 : : }
181 [ # # ][ + - ]: 838 : meRequestedAnimationMode = Animator::AM_Immediate;
[ + - ][ + - ]
[ - + ]
182 : : }
183 : :
184 : :
185 : :
186 : :
187 : 570 : ::boost::optional<Point> VisibleAreaManager::GetRequestedTopLeft (void) const
188 : : {
189 [ + - ]: 570 : SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
190 [ - + ]: 570 : if ( ! pWindow)
191 [ # # ]: 0 : return ::boost::optional<Point>();
192 : :
193 : : // Get the currently visible area and the model area.
194 : 570 : const Rectangle aVisibleArea (pWindow->PixelToLogic(
195 : : Rectangle(
196 : : Point(0,0),
197 [ + - + - ]: 1140 : pWindow->GetOutputSizePixel())));
198 [ + - ][ + - ]: 570 : const Rectangle aModelArea (mrSlideSorter.GetView().GetModelArea());
199 : :
200 : 570 : sal_Int32 nVisibleTop (aVisibleArea.Top());
201 [ + - ]: 570 : const sal_Int32 nVisibleWidth (aVisibleArea.GetWidth());
202 : 570 : sal_Int32 nVisibleLeft (aVisibleArea.Left());
203 [ + - ]: 570 : const sal_Int32 nVisibleHeight (aVisibleArea.GetHeight());
204 : :
205 : : // Find the longest run of boxes whose union fits into the visible area.
206 [ + - ]: 570 : Rectangle aBoundingBox;
207 [ + - ][ + - ]: 1140 : for (::std::vector<Rectangle>::const_iterator
[ + + ]
208 : 570 : iBox(maVisibleRequests.begin()),
209 : 570 : iEnd(maVisibleRequests.end());
210 : : iBox!=iEnd;
211 : : ++iBox)
212 : : {
213 [ + - ][ + + ]: 570 : if (nVisibleTop+nVisibleHeight <= iBox->Bottom())
214 [ + - ]: 260 : nVisibleTop = iBox->Bottom()-nVisibleHeight;
215 [ + - ][ + + ]: 570 : if (nVisibleTop > iBox->Top())
216 [ + - ]: 260 : nVisibleTop = iBox->Top();
217 : :
218 [ + - ][ + + ]: 570 : if (nVisibleLeft+nVisibleWidth <= iBox->Right())
219 [ + - ]: 260 : nVisibleLeft = iBox->Right()-nVisibleWidth;
220 [ + - ][ + + ]: 570 : if (nVisibleLeft > iBox->Left())
221 [ + - ]: 260 : nVisibleLeft = iBox->Left();
222 : :
223 : : // Make sure the visible area does not move outside the model area.
224 [ + + ]: 570 : if (nVisibleTop + nVisibleHeight > aModelArea.Bottom())
225 : 302 : nVisibleTop = aModelArea.Bottom() - nVisibleHeight;
226 [ + + ]: 570 : if (nVisibleTop < aModelArea.Top())
227 : 302 : nVisibleTop = aModelArea.Top();
228 : :
229 [ + + ]: 570 : if (nVisibleLeft + nVisibleWidth > aModelArea.Right())
230 : 310 : nVisibleLeft = aModelArea.Right() - nVisibleWidth;
231 [ + + ]: 570 : if (nVisibleLeft < aModelArea.Left())
232 : 310 : nVisibleLeft = aModelArea.Left();
233 : : }
234 : :
235 : 570 : const Point aRequestedTopLeft (nVisibleLeft, nVisibleTop);
236 [ + - ]: 570 : if (aRequestedTopLeft == aVisibleArea.TopLeft())
237 [ + - ]: 570 : return ::boost::optional<Point>();
238 : : else
239 [ # # ][ + - ]: 570 : return ::boost::optional<Point>(aRequestedTopLeft);
240 : : }
241 : :
242 : :
243 : :
244 : :
245 : : //===== VisibleAreaManager::TemporaryDisabler =================================
246 : :
247 : 268 : VisibleAreaManager::TemporaryDisabler::TemporaryDisabler (SlideSorter& rSlideSorter)
248 : 268 : : mrVisibleAreaManager(rSlideSorter.GetController().GetVisibleAreaManager())
249 : : {
250 : 268 : ++mrVisibleAreaManager.mnDisableCount;
251 : 268 : }
252 : :
253 : :
254 : :
255 : :
256 : 268 : VisibleAreaManager::TemporaryDisabler::~TemporaryDisabler (void)
257 : : {
258 : 268 : --mrVisibleAreaManager.mnDisableCount;
259 : 268 : }
260 : :
261 : :
262 : :
263 : : //===== VerticalVisibleAreaScroller ===========================================
264 : :
265 : : namespace {
266 : :
267 : : const static sal_Int32 gnMaxScrollDistance = 300;
268 : :
269 : 0 : VisibleAreaScroller::VisibleAreaScroller (
270 : : SlideSorter& rSlideSorter,
271 : : const Point aStart,
272 : : const Point aEnd)
273 : : : mrSlideSorter(rSlideSorter),
274 : : maStart(aStart),
275 : : maEnd(aEnd),
276 : : maAccelerationFunction(
277 : : controller::AnimationParametricFunction(
278 [ # # ][ # # ]: 0 : controller::AnimationBezierFunction (0.1,0.6)))
[ # # ][ # # ]
279 : : {
280 : : // When the distance to scroll is larger than a threshold then first
281 : : // jump to within this distance of the final value and start the
282 : : // animation from there.
283 [ # # ]: 0 : if (abs(aStart.X()-aEnd.X()) > gnMaxScrollDistance)
284 : : {
285 [ # # ]: 0 : if (aStart.X() < aEnd.X())
286 : 0 : maStart.X() = aEnd.X()-gnMaxScrollDistance;
287 : : else
288 : 0 : maStart.X() = aEnd.X()+gnMaxScrollDistance;
289 : : }
290 [ # # ]: 0 : if (abs(aStart.Y()-aEnd.Y()) > gnMaxScrollDistance)
291 : : {
292 [ # # ]: 0 : if (aStart.Y() < aEnd.Y())
293 : 0 : maStart.Y() = aEnd.Y()-gnMaxScrollDistance;
294 : : else
295 : 0 : maStart.Y() = aEnd.Y()+gnMaxScrollDistance;
296 : : }
297 : 0 : }
298 : :
299 : :
300 : :
301 : :
302 : 0 : void VisibleAreaScroller::operator() (const double nTime)
303 : : {
304 : 0 : const double nLocalTime (maAccelerationFunction(nTime));
305 [ # # ][ # # ]: 0 : mrSlideSorter.GetController().GetScrollBarManager().SetTopLeft(
306 : : Point(
307 : 0 : sal_Int32(0.5 + maStart.X() * (1.0 - nLocalTime) + maEnd.X() * nLocalTime),
308 [ # # ]: 0 : sal_Int32 (0.5 + maStart.Y() * (1.0 - nLocalTime) + maEnd.Y() * nLocalTime)));
309 : 0 : }
310 : :
311 : : } // end of anonymous namespace
312 : :
313 : : } } } // end of namespace ::sd::slidesorter::controller
314 : :
315 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|