fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / slideshow / source / engine / shapes / intrinsicanimationactivity.cxx
blob564addb76dba1a6cb726b8b540240bd9c2da700f
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 <canvas/debug.hxx>
22 #include <tools/diagnose_ex.h>
23 #include <canvas/verbosetrace.hxx>
25 #include "drawshapesubsetting.hxx"
26 #include "subsettableshapemanager.hxx"
27 #include "eventqueue.hxx"
28 #include "eventmultiplexer.hxx"
29 #include "intrinsicanimationactivity.hxx"
30 #include "intrinsicanimationeventhandler.hxx"
32 #include <boost/noncopyable.hpp>
33 #include <boost/enable_shared_from_this.hpp>
34 #include <boost/weak_ptr.hpp>
36 namespace slideshow
38 namespace internal
40 /** Activity for intrinsic shape animations
42 This is an Activity interface implementation for intrinsic
43 shape animations. Intrinsic shape animations are
44 animations directly within a shape, e.g. drawing layer
45 animations, or GIF animations.
47 class IntrinsicAnimationActivity : public Activity,
48 public boost::enable_shared_from_this<IntrinsicAnimationActivity>,
49 private boost::noncopyable
51 public:
52 /** Create an IntrinsicAnimationActivity.
54 @param rContext
55 Common slideshow objects
57 @param rDrawShape
58 Shape to control the intrinsic animation for
60 @param rWakeupEvent
61 Externally generated wakeup event, to set this
62 activity to sleep during inter-frame intervals. Must
63 come from the outside, since wakeup event and this
64 object have mutual references to each other.
66 @param rTimeouts
67 Vector of timeout values, to wait before the next
68 frame is shown.
70 IntrinsicAnimationActivity( const SlideShowContext& rContext,
71 const DrawShapeSharedPtr& rDrawShape,
72 const WakeupEventSharedPtr& rWakeupEvent,
73 const ::std::vector<double>& rTimeouts,
74 ::std::size_t nNumLoops,
75 CycleMode eCycleMode );
77 virtual void dispose() SAL_OVERRIDE;
78 virtual double calcTimeLag() const SAL_OVERRIDE;
79 virtual bool perform() SAL_OVERRIDE;
80 virtual bool isActive() const SAL_OVERRIDE;
81 virtual void dequeued() SAL_OVERRIDE;
82 virtual void end() SAL_OVERRIDE;
84 bool enableAnimations();
86 private:
87 SlideShowContext maContext;
88 boost::weak_ptr<DrawShape> mpDrawShape;
89 WakeupEventSharedPtr mpWakeupEvent;
90 IntrinsicAnimationEventHandlerSharedPtr mpListener;
91 ::std::vector<double> maTimeouts;
92 CycleMode meCycleMode;
93 ::std::size_t mnCurrIndex;
94 ::std::size_t mnNumLoops;
95 ::std::size_t mnLoopCount;
96 bool mbIsActive;
101 class IntrinsicAnimationListener : public IntrinsicAnimationEventHandler,
102 private boost::noncopyable
104 public:
105 explicit IntrinsicAnimationListener( IntrinsicAnimationActivity& rActivity ) :
106 mrActivity( rActivity )
109 private:
111 virtual bool enableAnimations() SAL_OVERRIDE { return mrActivity.enableAnimations(); }
112 virtual bool disableAnimations() SAL_OVERRIDE { mrActivity.end(); return true; }
114 IntrinsicAnimationActivity& mrActivity;
119 IntrinsicAnimationActivity::IntrinsicAnimationActivity( const SlideShowContext& rContext,
120 const DrawShapeSharedPtr& rDrawShape,
121 const WakeupEventSharedPtr& rWakeupEvent,
122 const ::std::vector<double>& rTimeouts,
123 ::std::size_t nNumLoops,
124 CycleMode eCycleMode ) :
125 maContext( rContext ),
126 mpDrawShape( rDrawShape ),
127 mpWakeupEvent( rWakeupEvent ),
128 mpListener( new IntrinsicAnimationListener(*this) ),
129 maTimeouts( rTimeouts ),
130 meCycleMode( eCycleMode ),
131 mnCurrIndex(0),
132 mnNumLoops(nNumLoops),
133 mnLoopCount(0),
134 mbIsActive(false)
136 ENSURE_OR_THROW( rContext.mpSubsettableShapeManager,
137 "IntrinsicAnimationActivity::IntrinsicAnimationActivity(): Invalid shape manager" );
138 ENSURE_OR_THROW( rDrawShape,
139 "IntrinsicAnimationActivity::IntrinsicAnimationActivity(): Invalid draw shape" );
140 ENSURE_OR_THROW( rWakeupEvent,
141 "IntrinsicAnimationActivity::IntrinsicAnimationActivity(): Invalid wakeup event" );
142 ENSURE_OR_THROW( !rTimeouts.empty(),
143 "IntrinsicAnimationActivity::IntrinsicAnimationActivity(): Empty timeout vector" );
145 maContext.mpSubsettableShapeManager->addIntrinsicAnimationHandler(
146 mpListener );
149 void IntrinsicAnimationActivity::dispose()
151 end();
153 if( mpWakeupEvent )
154 mpWakeupEvent->dispose();
156 maContext.dispose();
157 mpDrawShape.reset();
158 mpWakeupEvent.reset();
159 maTimeouts.clear();
160 mnCurrIndex = 0;
162 maContext.mpSubsettableShapeManager->removeIntrinsicAnimationHandler(
163 mpListener );
166 double IntrinsicAnimationActivity::calcTimeLag() const
168 return 0.0;
171 bool IntrinsicAnimationActivity::perform()
173 if( !isActive() )
174 return false;
176 DrawShapeSharedPtr pDrawShape( mpDrawShape.lock() );
177 if( !pDrawShape || !mpWakeupEvent )
179 // event or draw shape vanished, no sense living on ->
180 // commit suicide.
181 dispose();
182 return false;
185 // mnNumLoops == 0 means infinite looping
186 if( mnNumLoops != 0 &&
187 mnLoopCount >= mnNumLoops )
189 // #i55294# After finishing the loops, display the first frame
190 pDrawShape->setIntrinsicAnimationFrame( 0 );
191 maContext.mpSubsettableShapeManager->notifyShapeUpdate( pDrawShape );
193 end();
195 return false;
198 ::std::size_t nNewIndex = 0;
199 const ::std::size_t nNumFrames(maTimeouts.size());
200 switch( meCycleMode )
202 case CYCLE_LOOP:
204 pDrawShape->setIntrinsicAnimationFrame( mnCurrIndex );
206 mpWakeupEvent->start();
207 mpWakeupEvent->setNextTimeout( maTimeouts[mnCurrIndex] );
209 mnLoopCount += (mnCurrIndex + 1) / nNumFrames;
210 nNewIndex = (mnCurrIndex + 1) % nNumFrames;
211 break;
214 case CYCLE_PINGPONGLOOP:
216 ::std::size_t nTrueIndex( mnCurrIndex < nNumFrames ?
217 mnCurrIndex :
218 2*nNumFrames - mnCurrIndex - 1 );
219 pDrawShape->setIntrinsicAnimationFrame( nTrueIndex );
221 mpWakeupEvent->start();
222 mpWakeupEvent->setNextTimeout( maTimeouts[nTrueIndex] );
224 mnLoopCount += (mnCurrIndex + 1) / (2*nNumFrames);
225 nNewIndex = (mnCurrIndex + 1) % 2*nNumFrames;
226 break;
230 maContext.mrEventQueue.addEvent( mpWakeupEvent );
231 maContext.mpSubsettableShapeManager->notifyShapeUpdate( pDrawShape );
232 mnCurrIndex = nNewIndex;
234 return false; // don't reinsert, WakeupEvent will perform
235 // that after the given timeout
238 bool IntrinsicAnimationActivity::isActive() const
240 return mbIsActive;
243 void IntrinsicAnimationActivity::dequeued()
245 // not used here
248 void IntrinsicAnimationActivity::end()
250 // there is no dedicated end state, just become inactive:
251 mbIsActive = false;
254 bool IntrinsicAnimationActivity::enableAnimations()
256 mbIsActive = true;
257 return maContext.mrActivitiesQueue.addActivity(
258 shared_from_this() );
263 ActivitySharedPtr createIntrinsicAnimationActivity(
264 const SlideShowContext& rContext,
265 const DrawShapeSharedPtr& rDrawShape,
266 const WakeupEventSharedPtr& rWakeupEvent,
267 const ::std::vector<double>& rTimeouts,
268 ::std::size_t nNumLoops,
269 CycleMode eCycleMode )
271 return ActivitySharedPtr(
272 new IntrinsicAnimationActivity(rContext,
273 rDrawShape,
274 rWakeupEvent,
275 rTimeouts,
276 nNumLoops,
277 eCycleMode) );
282 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */