Bump version to 6.0-36
[LibreOffice.git] / slideshow / source / engine / activities / activitybase.cxx
blob282604232f696a675028e37e9c57d15090e59931
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <tools/diagnose_ex.h>
22 #include <canvas/canvastools.hxx>
24 #include "activitybase.hxx"
27 namespace slideshow
29 namespace internal
31 // TODO(P1): Elide some virtual function calls, by templifying this
32 // static hierarchy
34 ActivityBase::ActivityBase( const ActivityParameters& rParms ) :
35 mpEndEvent( rParms.mrEndEvent ),
36 mrEventQueue( rParms.mrEventQueue ),
37 mpShape(),
38 mpAttributeLayer(),
39 maRepeats( rParms.mrRepeats ),
40 mnAccelerationFraction( rParms.mnAccelerationFraction ),
41 mnDecelerationFraction( rParms.mnDecelerationFraction ),
42 mbAutoReverse( rParms.mbAutoReverse ),
43 mbFirstPerformCall( true ),
44 mbIsActive( true ) {}
46 void ActivityBase::dispose()
48 // deactivate
49 mbIsActive = false;
51 // dispose event
52 if( mpEndEvent )
53 mpEndEvent->dispose();
55 // release references
56 mpEndEvent.reset();
57 mpShape.reset();
58 mpAttributeLayer.reset();
61 double ActivityBase::calcTimeLag() const
63 // TODO(Q1): implement different init process!
64 if (isActive() && mbFirstPerformCall)
66 mbFirstPerformCall = false;
68 // notify derived classes that we're
69 // starting now
70 const_cast<ActivityBase *>(this)->startAnimation();
72 return 0.0;
75 bool ActivityBase::perform()
77 // still active?
78 if( !isActive() )
79 return false; // no, early exit.
81 OSL_ASSERT( ! mbFirstPerformCall );
83 return true;
86 bool ActivityBase::isActive() const
88 return mbIsActive;
91 void ActivityBase::setTargets( const AnimatableShapeSharedPtr& rShape,
92 const ShapeAttributeLayerSharedPtr& rAttrLayer )
94 ENSURE_OR_THROW( rShape,
95 "ActivityBase::setTargets(): Invalid shape" );
96 ENSURE_OR_THROW( rAttrLayer,
97 "ActivityBase::setTargets(): Invalid attribute layer" );
99 mpShape = rShape;
100 mpAttributeLayer = rAttrLayer;
103 void ActivityBase::endActivity()
105 // this is a regular activity end
106 mbIsActive = false;
108 // Activity is ending, queue event, then
109 if( mpEndEvent )
110 mrEventQueue.addEvent( mpEndEvent );
112 // release references
113 mpEndEvent.reset();
116 void ActivityBase::dequeued()
118 // xxx todo:
119 // // ignored here, if we're still active. Discrete
120 // // activities are dequeued after every perform() call,
121 // // thus, the call is only significant when isActive() ==
122 // // false.
123 if( !isActive() )
124 endAnimation();
127 void ActivityBase::end()
129 if (!isActive() || isDisposed())
130 return;
131 // assure animation is started:
132 if (mbFirstPerformCall) {
133 mbFirstPerformCall = false;
134 // notify derived classes that we're starting now
135 startAnimation();
138 performEnd(); // calling private virtual
139 endAnimation();
140 endActivity();
143 double ActivityBase::calcAcceleratedTime( double nT ) const
145 // Handle acceleration/deceleration
146 // ================================
148 // clamp nT to permissible [0,1] range
149 nT = ::basegfx::clamp( nT, 0.0, 1.0 );
151 // take acceleration/deceleration into account. if the sum
152 // of mnAccelerationFraction and mnDecelerationFraction
153 // exceeds 1.0, ignore both (that's according to SMIL spec)
154 if( (mnAccelerationFraction > 0.0 ||
155 mnDecelerationFraction > 0.0) &&
156 mnAccelerationFraction + mnDecelerationFraction <= 1.0 )
159 // calc accelerated/decelerated time.
161 // We have three intervals:
162 // 1 [0,a]
163 // 2 [a,d]
164 // 3 [d,1] (with a and d being acceleration/deceleration
165 // fraction, resp.)
167 // The change rate during interval 1 is constantly
168 // increasing, reaching 1 at a. It then stays at 1,
169 // starting a linear decrease at d, ending with 0 at
170 // time 1. The integral of this function is the
171 // required new time nT'.
173 // As we arbitrarily assumed 1 as the upper value of
174 // the change rate, the integral must be normalized to
175 // reach nT'=1 at the end of the interval. This
176 // normalization constant is:
178 // c = 1 - 0.5a - 0.5d
180 // The integral itself then amounts to:
182 // 0.5 nT^2 / a + (nT-a) + (nT - 0.5 nT^2 / d)
184 // (where each of the three summands correspond to the
185 // three intervals above, and are applied only if nT
186 // has reached the corresponding interval)
188 // The graph of the change rate is a trapezoid:
190 // |
191 // 1| /--------------\
192 // | / \
193 // | / \
194 // | / \
195 // -----------------------------
196 // 0 a d 1
198 //*/
199 const double nC( 1.0 - 0.5*mnAccelerationFraction - 0.5*mnDecelerationFraction );
201 // this variable accumulates the new time value
202 double nTPrime(0.0);
204 if( nT < mnAccelerationFraction )
206 nTPrime += 0.5*nT*nT/mnAccelerationFraction; // partial first interval
208 else
210 nTPrime += 0.5*mnAccelerationFraction; // full first interval
212 if( nT <= 1.0-mnDecelerationFraction )
214 nTPrime += nT-mnAccelerationFraction; // partial second interval
216 else
218 nTPrime += 1.0 - mnAccelerationFraction - mnDecelerationFraction; // full second interval
220 const double nTRelative( nT - 1.0 + mnDecelerationFraction );
222 nTPrime += nTRelative - 0.5*nTRelative*nTRelative / mnDecelerationFraction;
226 // normalize, and assign to work variable
227 nT = nTPrime / nC;
230 return nT;
235 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */