LibreOffice Module slideshow (master) 1
activitybase.cxx
Go to the documentation of this file.
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 <sal/config.h>
21
22#include <algorithm>
23
25
26#include "activitybase.hxx"
27
28
29namespace slideshow::internal
30{
31 // TODO(P1): Elide some virtual function calls, by templifying this
32 // static hierarchy
33
35 mpEndEvent( rParms.mrEndEvent ),
36 mrEventQueue( rParms.mrEventQueue ),
37 mpShape(),
38 mpAttributeLayer(),
39 maRepeats( rParms.mrRepeats ),
40 mnAccelerationFraction( rParms.mnAccelerationFraction ),
41 mnDecelerationFraction( rParms.mnDecelerationFraction ),
43 mbFirstPerformCall( true ),
44 mbIsActive( true ) {}
45
47 {
48 // deactivate
49 mbIsActive = false;
50
51 // dispose event
52 if( mpEndEvent )
53 mpEndEvent->dispose();
54
55 // release references
56 mpEndEvent.reset();
57 mpShape.reset();
58 mpAttributeLayer.reset();
59 }
60
62 {
63 // TODO(Q1): implement different init process!
65 {
66 mbFirstPerformCall = false;
67
68 // notify derived classes that we're
69 // starting now
70 const_cast<ActivityBase *>(this)->startAnimation();
71 }
72 return 0.0;
73 }
74
76 {
77 // still active?
78 if( !isActive() )
79 return false; // no, early exit.
80
81 OSL_ASSERT( ! mbFirstPerformCall );
82
83 return true;
84 }
85
87 {
88 return mbIsActive;
89 }
90
92 const ShapeAttributeLayerSharedPtr& rAttrLayer )
93 {
94 ENSURE_OR_THROW( rShape,
95 "ActivityBase::setTargets(): Invalid shape" );
96 ENSURE_OR_THROW( rAttrLayer,
97 "ActivityBase::setTargets(): Invalid attribute layer" );
98
99 mpShape = rShape;
100 mpAttributeLayer = rAttrLayer;
101 }
102
104 {
105 // this is a regular activity end
106 mbIsActive = false;
107
108 // Activity is ending, queue event, then
109 if( mpEndEvent )
111
112 // release references
113 mpEndEvent.reset();
114 }
115
117 {
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();
125 }
126
128 {
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
136 }
137
138 performEnd(); // calling private virtual
139 endAnimation();
140 endActivity();
141 }
142
143 double ActivityBase::calcAcceleratedTime( double nT ) const
144 {
145 // Handle acceleration/deceleration
146 // ================================
147
148 // clamp nT to permissible [0,1] range
149 nT = std::clamp( nT, 0.0, 1.0 );
150
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) &&
157 {
158 /*
159 // calc accelerated/decelerated time.
160
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.)
166
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'.
172
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:
177
178 // c = 1 - 0.5a - 0.5d
179
180 // The integral itself then amounts to:
181
182 // 0.5 nT^2 / a + (nT-a) + (nT - 0.5 nT^2 / d)
183
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)
187
188 // The graph of the change rate is a trapezoid:
189
190 // |
191 // 1| /--------------\
192 // | / \
193 // | / \
194 // | / \
195 // -----------------------------
196 // 0 a d 1
197
198 //*/
199 const double nC( 1.0 - 0.5*mnAccelerationFraction - 0.5*mnDecelerationFraction );
200
201 // this variable accumulates the new time value
202 double nTPrime(0.0);
203
204 if( nT < mnAccelerationFraction )
205 {
206 nTPrime += 0.5*nT*nT/mnAccelerationFraction; // partial first interval
207 }
208 else
209 {
210 nTPrime += 0.5*mnAccelerationFraction; // full first interval
211
212 if( nT <= 1.0-mnDecelerationFraction )
213 {
214 nTPrime += nT-mnAccelerationFraction; // partial second interval
215 }
216 else
217 {
218 nTPrime += 1.0 - mnAccelerationFraction - mnDecelerationFraction; // full second interval
219
220 const double nTRelative( nT - 1.0 + mnDecelerationFraction );
221
222 nTPrime += nTRelative - 0.5*nTRelative*nTRelative / mnDecelerationFraction;
223 }
224 }
225
226 // normalize, and assign to work variable
227 nT = nTPrime / nC;
228 }
229
230 return nT;
231 }
232}
233
234/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static T clamp(const T &rIn)
AnimatableShapeSharedPtr mpShape
bool mbAutoReverse
Base class for animation activities.
virtual void end() override
Activity:
virtual bool perform() override
From Activity interface.
virtual void setTargets(const AnimatableShapeSharedPtr &rShape, const ShapeAttributeLayerSharedPtr &rAttrLayer) override
Sets targets (shape and attributeLayer)
AnimatableShapeSharedPtr mpShape
virtual bool isActive() const override
Query whether this activity is still continuing.
virtual void endAnimation()=0
Hook for derived classes.
virtual void dispose() override
From Disposable interface.
virtual double calcTimeLag() const override
Calculates whether the activity lags time.
void endActivity()
End this activity, in a regular way.
ActivityBase(const ActivityParameters &rParms)
virtual void startAnimation()=0
Hook for derived classes.
virtual void dequeued() override
Notifies the Activity that it has now left the ActivitiesQueue.
double calcAcceleratedTime(double nT) const
Modify fractional time.
ShapeAttributeLayerSharedPtr mpAttributeLayer
bool addEvent(const EventSharedPtr &event)
Add the given event to the queue.
Definition: eventqueue.cxx:79
#define ENSURE_OR_THROW(c, m)
::std::shared_ptr< AnimatableShape > AnimatableShapeSharedPtr
::std::shared_ptr< ShapeAttributeLayer > ShapeAttributeLayerSharedPtr
EventQueue & mrEventQueue
Definition: slideview.cxx:729
Parameter struct for animation activities.