1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: intrinsicanimationactivity.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_slideshow.hxx"
34 #include <canvas/debug.hxx>
35 #include <tools/diagnose_ex.h>
36 #include <canvas/verbosetrace.hxx>
38 #include "drawshapesubsetting.hxx"
39 #include "subsettableshapemanager.hxx"
40 #include "eventqueue.hxx"
41 #include "eventmultiplexer.hxx"
42 #include "intrinsicanimationactivity.hxx"
43 #include "intrinsicanimationeventhandler.hxx"
45 #include <boost/noncopyable.hpp>
46 #include <boost/enable_shared_from_this.hpp>
47 #include <boost/weak_ptr.hpp>
53 /** Activity for intrinsic shape animations
55 This is an Activity interface implementation for intrinsic
56 shape animations. Intrinsic shape animations are
57 animations directly within a shape, e.g. drawing layer
58 animations, or GIF animations.
60 class IntrinsicAnimationActivity
: public Activity
,
61 public boost::enable_shared_from_this
<IntrinsicAnimationActivity
>,
62 private boost::noncopyable
65 /** Create an IntrinsicAnimationActivity.
68 Common slideshow objects
71 Shape to control the intrinsic animation for
74 Externally generated wakeup event, to set this
75 activity to sleep during inter-frame intervals. Must
76 come frome the outside, since wakeup event and this
77 object have mutual references to each other.
80 Vector of timeout values, to wait before the next
83 IntrinsicAnimationActivity( const SlideShowContext
& rContext
,
84 const DrawShapeSharedPtr
& rDrawShape
,
85 const WakeupEventSharedPtr
& rWakeupEvent
,
86 const ::std::vector
<double>& rTimeouts
,
87 ::std::size_t nNumLoops
,
88 CycleMode eCycleMode
);
90 virtual void dispose();
91 virtual double calcTimeLag() const;
92 virtual bool perform();
93 virtual bool isActive() const;
94 virtual void dequeued();
97 bool enableAnimations();
100 SlideShowContext maContext
;
101 boost::weak_ptr
<DrawShape
> mpDrawShape
;
102 WakeupEventSharedPtr mpWakeupEvent
;
103 IntrinsicAnimationEventHandlerSharedPtr mpListener
;
104 ::std::vector
<double> maTimeouts
;
105 CycleMode meCycleMode
;
106 ::std::size_t mnCurrIndex
;
107 ::std::size_t mnNumLoops
;
108 ::std::size_t mnLoopCount
;
112 //////////////////////////////////////////////////////////////////////
114 class IntrinsicAnimationListener
: public IntrinsicAnimationEventHandler
,
115 private boost::noncopyable
118 explicit IntrinsicAnimationListener( IntrinsicAnimationActivity
& rActivity
) :
119 mrActivity( rActivity
)
124 virtual bool enableAnimations() { return mrActivity
.enableAnimations(); }
125 virtual bool disableAnimations() { mrActivity
.end(); return true; }
127 IntrinsicAnimationActivity
& mrActivity
;
130 //////////////////////////////////////////////////////////////////////
132 IntrinsicAnimationActivity::IntrinsicAnimationActivity( const SlideShowContext
& rContext
,
133 const DrawShapeSharedPtr
& rDrawShape
,
134 const WakeupEventSharedPtr
& rWakeupEvent
,
135 const ::std::vector
<double>& rTimeouts
,
136 ::std::size_t nNumLoops
,
137 CycleMode eCycleMode
) :
138 maContext( rContext
),
139 mpDrawShape( rDrawShape
),
140 mpWakeupEvent( rWakeupEvent
),
141 mpListener( new IntrinsicAnimationListener(*this) ),
142 maTimeouts( rTimeouts
),
143 meCycleMode( eCycleMode
),
145 mnNumLoops(nNumLoops
),
149 ENSURE_OR_THROW( rContext
.mpSubsettableShapeManager
,
150 "IntrinsicAnimationActivity::IntrinsicAnimationActivity(): Invalid shape manager" );
151 ENSURE_OR_THROW( rDrawShape
,
152 "IntrinsicAnimationActivity::IntrinsicAnimationActivity(): Invalid draw shape" );
153 ENSURE_OR_THROW( rWakeupEvent
,
154 "IntrinsicAnimationActivity::IntrinsicAnimationActivity(): Invalid wakeup event" );
155 ENSURE_OR_THROW( !rTimeouts
.empty(),
156 "IntrinsicAnimationActivity::IntrinsicAnimationActivity(): Empty timeout vector" );
158 maContext
.mpSubsettableShapeManager
->addIntrinsicAnimationHandler(
162 void IntrinsicAnimationActivity::dispose()
167 mpWakeupEvent
->dispose();
171 mpWakeupEvent
.reset();
175 maContext
.mpSubsettableShapeManager
->removeIntrinsicAnimationHandler(
179 double IntrinsicAnimationActivity::calcTimeLag() const
184 bool IntrinsicAnimationActivity::perform()
189 DrawShapeSharedPtr
pDrawShape( mpDrawShape
.lock() );
190 if( !pDrawShape
|| !mpWakeupEvent
)
192 // event or draw shape vanished, no sense living on ->
198 // mnNumLoops == 0 means infinite looping
199 if( mnNumLoops
!= 0 &&
200 mnLoopCount
>= mnNumLoops
)
202 // #i55294# After finishing the loops, display the first frame
203 pDrawShape
->setIntrinsicAnimationFrame( 0 );
204 maContext
.mpSubsettableShapeManager
->notifyShapeUpdate( pDrawShape
);
211 ::std::size_t nNewIndex
= 0;
212 const ::std::size_t nNumFrames(maTimeouts
.size());
213 switch( meCycleMode
)
217 pDrawShape
->setIntrinsicAnimationFrame( mnCurrIndex
);
219 mpWakeupEvent
->start();
220 mpWakeupEvent
->setNextTimeout( maTimeouts
[mnCurrIndex
] );
222 mnLoopCount
+= (mnCurrIndex
+ 1) / nNumFrames
;
223 nNewIndex
= (mnCurrIndex
+ 1) % nNumFrames
;
227 case CYCLE_PINGPONGLOOP
:
229 ::std::size_t nTrueIndex( mnCurrIndex
< nNumFrames
?
231 2*nNumFrames
- mnCurrIndex
- 1 );
232 pDrawShape
->setIntrinsicAnimationFrame( nTrueIndex
);
234 mpWakeupEvent
->start();
235 mpWakeupEvent
->setNextTimeout( maTimeouts
[nTrueIndex
] );
237 mnLoopCount
+= (mnCurrIndex
+ 1) / (2*nNumFrames
);
238 nNewIndex
= (mnCurrIndex
+ 1) % 2*nNumFrames
;
243 maContext
.mrEventQueue
.addEvent( mpWakeupEvent
);
244 maContext
.mpSubsettableShapeManager
->notifyShapeUpdate( pDrawShape
);
245 mnCurrIndex
= nNewIndex
;
247 return false; // don't reinsert, WakeupEvent will perform
248 // that after the given timeout
251 bool IntrinsicAnimationActivity::isActive() const
256 void IntrinsicAnimationActivity::dequeued()
261 void IntrinsicAnimationActivity::end()
263 // there is no dedicated end state, just become inactive:
267 bool IntrinsicAnimationActivity::enableAnimations()
270 return maContext
.mrActivitiesQueue
.addActivity(
271 shared_from_this() );
274 //////////////////////////////////////////////////////////////////////
276 ActivitySharedPtr
createIntrinsicAnimationActivity(
277 const SlideShowContext
& rContext
,
278 const DrawShapeSharedPtr
& rDrawShape
,
279 const WakeupEventSharedPtr
& rWakeupEvent
,
280 const ::std::vector
<double>& rTimeouts
,
281 ::std::size_t nNumLoops
,
282 CycleMode eCycleMode
)
284 return ActivitySharedPtr(
285 new IntrinsicAnimationActivity(rContext
,