build fix
[LibreOffice.git] / slideshow / source / engine / shapes / intrinsicanimationactivity.cxx
blobba1d4817d6a8f66de713f6cf250dae319c8ee901
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>
23 #include "drawshapesubsetting.hxx"
24 #include "subsettableshapemanager.hxx"
25 #include "eventqueue.hxx"
26 #include "eventmultiplexer.hxx"
27 #include "intrinsicanimationactivity.hxx"
28 #include "intrinsicanimationeventhandler.hxx"
30 #include <memory>
32 namespace slideshow
34 namespace internal
36 /** Activity for intrinsic shape animations
38 This is an Activity interface implementation for intrinsic
39 shape animations. Intrinsic shape animations are
40 animations directly within a shape, e.g. drawing layer
41 animations, or GIF animations.
43 class IntrinsicAnimationActivity : public Activity
45 public:
46 /** Create an IntrinsicAnimationActivity.
48 @param rContext
49 Common slideshow objects
51 @param rDrawShape
52 Shape to control the intrinsic animation for
54 @param rWakeupEvent
55 Externally generated wakeup event, to set this
56 activity to sleep during inter-frame intervals. Must
57 come from the outside, since wakeup event and this
58 object have mutual references to each other.
60 @param rTimeouts
61 Vector of timeout values, to wait before the next
62 frame is shown.
64 IntrinsicAnimationActivity( const SlideShowContext& rContext,
65 const DrawShapeSharedPtr& rDrawShape,
66 const WakeupEventSharedPtr& rWakeupEvent,
67 const ::std::vector<double>& rTimeouts,
68 ::std::size_t nNumLoops,
69 CycleMode eCycleMode );
70 IntrinsicAnimationActivity(const IntrinsicAnimationActivity&) = delete;
71 IntrinsicAnimationActivity& operator=(const IntrinsicAnimationActivity&) = delete;
73 virtual void dispose() override;
74 virtual double calcTimeLag() const override;
75 virtual bool perform() override;
76 virtual bool isActive() const override;
77 virtual void dequeued() override;
78 virtual void end() override;
80 bool enableAnimations();
82 private:
83 SlideShowContext maContext;
84 std::weak_ptr<DrawShape> mpDrawShape;
85 WakeupEventSharedPtr mpWakeupEvent;
86 IntrinsicAnimationEventHandlerSharedPtr mpListener;
87 ::std::vector<double> maTimeouts;
88 CycleMode meCycleMode;
89 ::std::size_t mnCurrIndex;
90 ::std::size_t mnNumLoops;
91 ::std::size_t mnLoopCount;
92 bool mbIsActive;
96 class IntrinsicAnimationListener : public IntrinsicAnimationEventHandler
98 public:
99 explicit IntrinsicAnimationListener( IntrinsicAnimationActivity& rActivity ) :
100 mrActivity( rActivity )
102 IntrinsicAnimationListener(const IntrinsicAnimationListener&) = delete;
103 IntrinsicAnimationListener& operator=(const IntrinsicAnimationListener&) = delete;
105 private:
107 virtual bool enableAnimations() override { return mrActivity.enableAnimations(); }
108 virtual bool disableAnimations() override { mrActivity.end(); return true; }
110 IntrinsicAnimationActivity& mrActivity;
114 IntrinsicAnimationActivity::IntrinsicAnimationActivity( const SlideShowContext& rContext,
115 const DrawShapeSharedPtr& rDrawShape,
116 const WakeupEventSharedPtr& rWakeupEvent,
117 const ::std::vector<double>& rTimeouts,
118 ::std::size_t nNumLoops,
119 CycleMode eCycleMode ) :
120 maContext( rContext ),
121 mpDrawShape( rDrawShape ),
122 mpWakeupEvent( rWakeupEvent ),
123 mpListener( new IntrinsicAnimationListener(*this) ),
124 maTimeouts( rTimeouts ),
125 meCycleMode( eCycleMode ),
126 mnCurrIndex(0),
127 mnNumLoops(nNumLoops),
128 mnLoopCount(0),
129 mbIsActive(false)
131 ENSURE_OR_THROW( rContext.mpSubsettableShapeManager,
132 "IntrinsicAnimationActivity::IntrinsicAnimationActivity(): Invalid shape manager" );
133 ENSURE_OR_THROW( rDrawShape,
134 "IntrinsicAnimationActivity::IntrinsicAnimationActivity(): Invalid draw shape" );
135 ENSURE_OR_THROW( rWakeupEvent,
136 "IntrinsicAnimationActivity::IntrinsicAnimationActivity(): Invalid wakeup event" );
137 ENSURE_OR_THROW( !rTimeouts.empty(),
138 "IntrinsicAnimationActivity::IntrinsicAnimationActivity(): Empty timeout vector" );
140 maContext.mpSubsettableShapeManager->addIntrinsicAnimationHandler(
141 mpListener );
144 void IntrinsicAnimationActivity::dispose()
146 end();
148 if( mpWakeupEvent )
149 mpWakeupEvent->dispose();
151 maContext.dispose();
152 mpDrawShape.reset();
153 mpWakeupEvent.reset();
154 maTimeouts.clear();
155 mnCurrIndex = 0;
157 maContext.mpSubsettableShapeManager->removeIntrinsicAnimationHandler(
158 mpListener );
161 double IntrinsicAnimationActivity::calcTimeLag() const
163 return 0.0;
166 bool IntrinsicAnimationActivity::perform()
168 if( !isActive() )
169 return false;
171 DrawShapeSharedPtr pDrawShape( mpDrawShape.lock() );
172 if( !pDrawShape || !mpWakeupEvent )
174 // event or draw shape vanished, no sense living on ->
175 // commit suicide.
176 dispose();
177 return false;
180 // mnNumLoops == 0 means infinite looping
181 if( mnNumLoops != 0 &&
182 mnLoopCount >= mnNumLoops )
184 // #i55294# After finishing the loops, display the first frame
185 pDrawShape->setIntrinsicAnimationFrame( 0 );
186 maContext.mpSubsettableShapeManager->notifyShapeUpdate( pDrawShape );
188 end();
190 return false;
193 ::std::size_t nNewIndex = 0;
194 const ::std::size_t nNumFrames(maTimeouts.size());
195 switch( meCycleMode )
197 case CYCLE_LOOP:
199 pDrawShape->setIntrinsicAnimationFrame( mnCurrIndex );
201 mpWakeupEvent->start();
202 mpWakeupEvent->setNextTimeout( maTimeouts[mnCurrIndex] );
204 mnLoopCount += (mnCurrIndex + 1) / nNumFrames;
205 nNewIndex = (mnCurrIndex + 1) % nNumFrames;
206 break;
209 case CYCLE_PINGPONGLOOP:
211 ::std::size_t nTrueIndex( mnCurrIndex < nNumFrames ?
212 mnCurrIndex :
213 2*nNumFrames - mnCurrIndex - 1 );
214 pDrawShape->setIntrinsicAnimationFrame( nTrueIndex );
216 mpWakeupEvent->start();
217 mpWakeupEvent->setNextTimeout( maTimeouts[nTrueIndex] );
219 mnLoopCount += (mnCurrIndex + 1) / (2*nNumFrames);
220 nNewIndex = (mnCurrIndex + 1) % 2*nNumFrames;
221 break;
225 maContext.mrEventQueue.addEvent( mpWakeupEvent );
226 maContext.mpSubsettableShapeManager->notifyShapeUpdate( pDrawShape );
227 mnCurrIndex = nNewIndex;
229 return false; // don't reinsert, WakeupEvent will perform
230 // that after the given timeout
233 bool IntrinsicAnimationActivity::isActive() const
235 return mbIsActive;
238 void IntrinsicAnimationActivity::dequeued()
240 // not used here
243 void IntrinsicAnimationActivity::end()
245 // there is no dedicated end state, just become inactive:
246 mbIsActive = false;
249 bool IntrinsicAnimationActivity::enableAnimations()
251 mbIsActive = true;
252 return maContext.mrActivitiesQueue.addActivity( std::dynamic_pointer_cast<Activity>(shared_from_this()) );
257 ActivitySharedPtr createIntrinsicAnimationActivity(
258 const SlideShowContext& rContext,
259 const DrawShapeSharedPtr& rDrawShape,
260 const WakeupEventSharedPtr& rWakeupEvent,
261 const ::std::vector<double>& rTimeouts,
262 ::std::size_t nNumLoops,
263 CycleMode eCycleMode )
265 return ActivitySharedPtr(
266 new IntrinsicAnimationActivity(rContext,
267 rDrawShape,
268 rWakeupEvent,
269 rTimeouts,
270 nNumLoops,
271 eCycleMode) );
276 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */