Update ooo320-m1
[ooovba.git] / slideshow / source / engine / activities / simplecontinuousactivitybase.cxx
blob9bad8cbdc5c48e88ee147a08e4da5358c0f6a02d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: simplecontinuousactivitybase.cxx,v $
10 * $Revision: 1.11 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_slideshow.hxx"
34 // must be first
35 #include <canvas/debug.hxx>
36 #include <canvas/verbosetrace.hxx>
38 #include <simplecontinuousactivitybase.hxx>
41 namespace slideshow
43 namespace internal
45 SimpleContinuousActivityBase::SimpleContinuousActivityBase(
46 const ActivityParameters& rParms ) :
47 ActivityBase( rParms ),
48 maTimer( rParms.mrActivitiesQueue.getTimer() ),
49 mnMinSimpleDuration( rParms.mnMinDuration ),
50 mnMinNumberOfFrames( rParms.mnMinNumberOfFrames ),
51 mnCurrPerformCalls( 0 )
55 void SimpleContinuousActivityBase::startAnimation()
57 // init timer. We measure animation time only when we're
58 // actually started.
59 maTimer.reset();
62 double SimpleContinuousActivityBase::calcTimeLag() const
64 ActivityBase::calcTimeLag();
65 if (! isActive())
66 return 0.0;
68 // retrieve locally elapsed time
69 const double nCurrElapsedTime( maTimer.getElapsedTime() );
71 // log time
72 VERBOSE_TRACE( "SimpleContinuousActivityBase::calcTimeLag(): "
73 "next step is based on time: %f", nCurrElapsedTime );
75 // go to great length to ensure a proper animation
76 // run. Since we don't know how often we will be called
77 // here, try to spread the animator calls uniquely over
78 // the [0,1] parameter range. Be aware of the fact that
79 // perform will be called at least mnMinNumberOfTurns
80 // times.
82 // fraction of time elapsed
83 const double nFractionElapsedTime(
84 nCurrElapsedTime / mnMinSimpleDuration );
86 // fraction of minimum calls performed
87 const double nFractionRequiredCalls(
88 double(mnCurrPerformCalls) / mnMinNumberOfFrames );
90 // okay, so now, the decision is easy:
92 // If the fraction of time elapsed is smaller than the
93 // number of calls required to be performed, then we calc
94 // the position on the animation range according to
95 // elapsed time. That is, we're so to say ahead of time.
97 // In contrary, if the fraction of time elapsed is larger,
98 // then we're lagging, and we thus calc the position on
99 // the animation time line according to the fraction of
100 // calls performed. Thus, the animation is forced to slow
101 // down, and take the required minimal number of steps,
102 // sufficiently equally distributed across the animation
103 // time line.
104 if( nFractionElapsedTime < nFractionRequiredCalls )
106 VERBOSE_TRACE( "SimpleContinuousActivityBase::calcTimeLag(): "
107 "t=%f is based on time", nFractionElapsedTime );
108 return 0.0;
110 else
112 VERBOSE_TRACE( "SimpleContinuousActivityBase::perform(): "
113 "t=%f is based on number of calls",
114 nFractionRequiredCalls );
116 // lag global time, so all other animations lag, too:
117 return ((nFractionElapsedTime - nFractionRequiredCalls)
118 * mnMinSimpleDuration);
122 bool SimpleContinuousActivityBase::perform()
124 // call base class, for start() calls and end handling
125 if( !ActivityBase::perform() )
126 return false; // done, we're ended
129 // get relative animation position
130 // ===============================
132 const double nCurrElapsedTime( maTimer.getElapsedTime() );
133 double nT( nCurrElapsedTime / mnMinSimpleDuration );
136 // one of the stop criteria reached?
137 // =================================
139 // will be set to true below, if one of the termination criteria
140 // matched.
141 bool bActivityEnding( false );
143 if( isRepeatCountValid() )
145 // Finite duration
146 // ===============
148 // When we've autoreverse on, the repeat count
149 // doubles
150 const double nRepeatCount( getRepeatCount() );
151 const double nEffectiveRepeat( isAutoReverse() ?
152 2.0*nRepeatCount :
153 nRepeatCount );
155 // time (or frame count) elapsed?
156 if( nEffectiveRepeat <= nT )
158 // okee. done for now. Will not exit right here,
159 // to give animation the chance to render the last
160 // frame below
161 bActivityEnding = true;
163 // clamp animation to max permissible value
164 nT = nEffectiveRepeat;
169 // need to do auto-reverse?
170 // ========================
172 double nRepeats;
173 double nRelativeSimpleTime;
175 // TODO(Q3): Refactor this mess
176 if( isAutoReverse() )
178 // divert active duration into repeat and
179 // fractional part.
180 const double nFractionalActiveDuration( modf(nT, &nRepeats) );
182 // for auto-reverse, map ranges [1,2), [3,4), ...
183 // to ranges [0,1), [1,2), etc.
184 if( ((int)nRepeats) % 2 )
186 // we're in an odd range, reverse sweep
187 nRelativeSimpleTime = 1.0 - nFractionalActiveDuration;
189 else
191 // we're in an even range, pass on as is
192 nRelativeSimpleTime = nFractionalActiveDuration;
195 // effective repeat count for autoreverse is half of
196 // the input time's value (each run of an autoreverse
197 // cycle is half of a repeat)
198 nRepeats /= 2;
200 else
202 // determine repeat
203 // ================
205 // calc simple time and number of repeats from nT
206 // Now, that's easy, since the fractional part of
207 // nT gives the relative simple time, and the
208 // integer part the number of full repeats:
209 nRelativeSimpleTime = modf(nT, &nRepeats);
211 // clamp repeats to max permissible value (maRepeats.getValue() - 1.0)
212 if( isRepeatCountValid() &&
213 nRepeats >= getRepeatCount() )
215 // Note that this code here only gets
216 // triggered if maRepeats.getValue() is an
217 // _integer_. Otherwise, nRepeats will never
218 // reach nor exceed
219 // maRepeats.getValue(). Thus, the code below
220 // does not need to handle cases of fractional
221 // repeats, and can always assume that a full
222 // animation run has ended (with
223 // nRelativeSimpleTime=1.0 for
224 // non-autoreversed activities).
226 // with modf, nRelativeSimpleTime will never
227 // become 1.0, since nRepeats is incremented and
228 // nRelativeSimpleTime set to 0.0 then.
230 // For the animation to reach its final value,
231 // nRepeats must although become
232 // maRepeats.getValue()-1.0, and
233 // nRelativeSimpleTime=1.0.
234 nRelativeSimpleTime = 1.0;
235 nRepeats -= 1.0;
239 // actually perform something
240 // ==========================
242 simplePerform( nRelativeSimpleTime,
243 // nRepeats is already integer-valued
244 static_cast<sal_uInt32>( nRepeats ) );
247 // delayed endActivity() call from end condition check
248 // below. Issued after the simplePerform() call above, to
249 // give animations the chance to correctly reach the
250 // animation end value, without spurious bail-outs because
251 // of isActive() returning false.
252 if( bActivityEnding )
253 endActivity();
255 // one more frame successfully performed
256 ++mnCurrPerformCalls;
258 return isActive();