LibreOffice Module slideshow (master) 1
intrinsicanimationactivity.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
22
24#include <eventqueue.hxx>
27
28#include <memory>
29
30namespace slideshow::internal
31{
32 namespace {
33
41 class IntrinsicAnimationActivity : public Activity
42 {
43 public:
62 IntrinsicAnimationActivity( const SlideShowContext& rContext,
63 const DrawShapeSharedPtr& rDrawShape,
64 const WakeupEventSharedPtr& rWakeupEvent,
65 ::std::vector<double>&& rTimeouts,
66 ::std::size_t nNumLoops );
67 IntrinsicAnimationActivity(const IntrinsicAnimationActivity&) = delete;
68 IntrinsicAnimationActivity& operator=(const IntrinsicAnimationActivity&) = delete;
69
70 virtual void dispose() override;
71 virtual double calcTimeLag() const override;
72 virtual bool perform() override;
73 virtual bool isActive() const override;
74 virtual void dequeued() override;
75 virtual void end() override;
76
77 bool enableAnimations();
78
79 private:
80 SlideShowContext maContext;
81 std::weak_ptr<DrawShape> mpDrawShape;
84 ::std::vector<double> maTimeouts;
85 ::std::size_t mnCurrIndex;
86 ::std::size_t mnNumLoops;
87 ::std::size_t mnLoopCount;
89 };
90
91
92 class IntrinsicAnimationListener : public IntrinsicAnimationEventHandler
93 {
94 public:
95 explicit IntrinsicAnimationListener( IntrinsicAnimationActivity& rActivity ) :
96 mrActivity( rActivity )
97 {}
98 IntrinsicAnimationListener(const IntrinsicAnimationListener&) = delete;
99 IntrinsicAnimationListener& operator=(const IntrinsicAnimationListener&) = delete;
100
101 private:
102
103 virtual bool enableAnimations() override { return mrActivity.enableAnimations(); }
104 virtual bool disableAnimations() override { mrActivity.end(); return true; }
105
106 IntrinsicAnimationActivity& mrActivity;
107 };
108
109 }
110
111 IntrinsicAnimationActivity::IntrinsicAnimationActivity( const SlideShowContext& rContext,
112 const DrawShapeSharedPtr& rDrawShape,
113 const WakeupEventSharedPtr& rWakeupEvent,
114 ::std::vector<double>&& rTimeouts,
115 ::std::size_t nNumLoops ) :
116 maContext( rContext ),
117 mpDrawShape( rDrawShape ),
118 mpWakeupEvent( rWakeupEvent ),
119 mpListener( std::make_shared<IntrinsicAnimationListener>(*this) ),
120 maTimeouts( std::move(rTimeouts) ),
121 mnCurrIndex(0),
122 mnNumLoops(nNumLoops),
123 mnLoopCount(0),
124 mbIsActive(false)
125 {
126 ENSURE_OR_THROW( rContext.mpSubsettableShapeManager,
127 "IntrinsicAnimationActivity::IntrinsicAnimationActivity(): Invalid shape manager" );
128 ENSURE_OR_THROW( rDrawShape,
129 "IntrinsicAnimationActivity::IntrinsicAnimationActivity(): Invalid draw shape" );
130 ENSURE_OR_THROW( rWakeupEvent,
131 "IntrinsicAnimationActivity::IntrinsicAnimationActivity(): Invalid wakeup event" );
132 ENSURE_OR_THROW( !maTimeouts.empty(),
133 "IntrinsicAnimationActivity::IntrinsicAnimationActivity(): Empty timeout vector" );
134
135 maContext.mpSubsettableShapeManager->addIntrinsicAnimationHandler(
136 mpListener );
137 }
138
139 void IntrinsicAnimationActivity::dispose()
140 {
141 end();
142
143 if( mpWakeupEvent )
144 mpWakeupEvent->dispose();
145
146 maContext.dispose();
147 mpDrawShape.reset();
148 mpWakeupEvent.reset();
149 maTimeouts.clear();
150 mnCurrIndex = 0;
151
152 maContext.mpSubsettableShapeManager->removeIntrinsicAnimationHandler(
153 mpListener );
154 }
155
156 double IntrinsicAnimationActivity::calcTimeLag() const
157 {
158 return 0.0;
159 }
160
161 bool IntrinsicAnimationActivity::perform()
162 {
163 if( !isActive() )
164 return false;
165
166 DrawShapeSharedPtr pDrawShape( mpDrawShape.lock() );
167 if( !pDrawShape || !mpWakeupEvent )
168 {
169 // event or draw shape vanished, no sense living on ->
170 // commit suicide.
171 dispose();
172 return false;
173 }
174
175 const ::std::size_t nNumFrames(maTimeouts.size());
176
177 // mnNumLoops == 0 means infinite looping
178 if( mnNumLoops != 0 &&
180 {
181 // #i55294# After finishing the loops, display the last frame
182 // powerpoint 2013 and firefox etc show the last frame when
183 // the animation ends
184 pDrawShape->setIntrinsicAnimationFrame(nNumFrames - 1);
185 maContext.mpSubsettableShapeManager->notifyShapeUpdate( pDrawShape );
186
187 end();
188
189 return false;
190 }
191
192 ::std::size_t nNewIndex = 0;
193
194 pDrawShape->setIntrinsicAnimationFrame( mnCurrIndex );
195
196 mpWakeupEvent->start();
197 mpWakeupEvent->setNextTimeout( maTimeouts[mnCurrIndex] );
198
199 mnLoopCount += (mnCurrIndex + 1) / nNumFrames;
200 nNewIndex = (mnCurrIndex + 1) % nNumFrames;
201
202 maContext.mrEventQueue.addEvent( mpWakeupEvent );
203 maContext.mpSubsettableShapeManager->notifyShapeUpdate( pDrawShape );
204 mnCurrIndex = nNewIndex;
205
206 return false; // don't reinsert, WakeupEvent will perform
207 // that after the given timeout
208 }
209
210 bool IntrinsicAnimationActivity::isActive() const
211 {
212 return mbIsActive;
213 }
214
215 void IntrinsicAnimationActivity::dequeued()
216 {
217 // not used here
218 }
219
220 void IntrinsicAnimationActivity::end()
221 {
222 // there is no dedicated end state, just become inactive:
223 mbIsActive = false;
224 }
225
226 bool IntrinsicAnimationActivity::enableAnimations()
227 {
228 mbIsActive = true;
229 return maContext.mrActivitiesQueue.addActivity( std::dynamic_pointer_cast<Activity>(shared_from_this()) );
230
231 }
232
233
235 const SlideShowContext& rContext,
236 const DrawShapeSharedPtr& rDrawShape,
237 const WakeupEventSharedPtr& rWakeupEvent,
238 ::std::vector<double>&& rTimeouts,
239 sal_uInt32 nNumLoops)
240 {
241 return std::make_shared<IntrinsicAnimationActivity>(rContext,
242 rDrawShape,
243 rWakeupEvent,
244 std::move(rTimeouts),
245 nNumLoops);
246 }
247}
248
249/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define ENSURE_OR_THROW(c, m)
::std::size_t mnCurrIndex
::std::vector< double > maTimeouts
IntrinsicAnimationEventHandlerSharedPtr mpListener
::std::size_t mnNumLoops
WakeupEventSharedPtr mpWakeupEvent
std::weak_ptr< DrawShape > mpDrawShape
::std::size_t mnLoopCount
IntrinsicAnimationActivity & mrActivity
SlideShowContext maContext
bool isActive()
std::shared_ptr< T > make_shared(Args &&... args)
end
ActivitySharedPtr createIntrinsicAnimationActivity(const SlideShowContext &rContext, const DrawShapeSharedPtr &rDrawShape, const WakeupEventSharedPtr &rWakeupEvent, ::std::vector< double > &&rTimeouts, sal_uInt32 nNumLoops)
Create an IntrinsicAnimationActivity.
::std::shared_ptr< Activity > ActivitySharedPtr
Definition: activity.hxx:83
::std::shared_ptr< DrawShape > DrawShapeSharedPtr
Definition: drawshape.hxx:43
::std::shared_ptr< IntrinsicAnimationEventHandler > IntrinsicAnimationEventHandlerSharedPtr
::std::shared_ptr< WakeupEvent > WakeupEventSharedPtr
Definition: wakeupevent.hxx:77
void dispose()
Common arguments for slideshow objects.