1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
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
46 /** Create an IntrinsicAnimationActivity.
49 Common slideshow objects
52 Shape to control the intrinsic animation for
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.
61 Vector of timeout values, to wait before the next
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 IntrinsicAnimationActivity(const IntrinsicAnimationActivity
&) = delete;
70 IntrinsicAnimationActivity
& operator=(const IntrinsicAnimationActivity
&) = delete;
72 virtual void dispose() override
;
73 virtual double calcTimeLag() const override
;
74 virtual bool perform() override
;
75 virtual bool isActive() const override
;
76 virtual void dequeued() override
;
77 virtual void end() override
;
79 bool enableAnimations();
82 SlideShowContext maContext
;
83 std::weak_ptr
<DrawShape
> mpDrawShape
;
84 WakeupEventSharedPtr mpWakeupEvent
;
85 IntrinsicAnimationEventHandlerSharedPtr
const mpListener
;
86 ::std::vector
<double> maTimeouts
;
87 ::std::size_t mnCurrIndex
;
88 ::std::size_t const mnNumLoops
;
89 ::std::size_t mnLoopCount
;
94 class IntrinsicAnimationListener
: public IntrinsicAnimationEventHandler
97 explicit IntrinsicAnimationListener( IntrinsicAnimationActivity
& rActivity
) :
98 mrActivity( rActivity
)
100 IntrinsicAnimationListener(const IntrinsicAnimationListener
&) = delete;
101 IntrinsicAnimationListener
& operator=(const IntrinsicAnimationListener
&) = delete;
105 virtual bool enableAnimations() override
{ return mrActivity
.enableAnimations(); }
106 virtual bool disableAnimations() override
{ mrActivity
.end(); return true; }
108 IntrinsicAnimationActivity
& mrActivity
;
112 IntrinsicAnimationActivity::IntrinsicAnimationActivity( const SlideShowContext
& rContext
,
113 const DrawShapeSharedPtr
& rDrawShape
,
114 const WakeupEventSharedPtr
& rWakeupEvent
,
115 const ::std::vector
<double>& rTimeouts
,
116 ::std::size_t nNumLoops
) :
117 maContext( rContext
),
118 mpDrawShape( rDrawShape
),
119 mpWakeupEvent( rWakeupEvent
),
120 mpListener( new IntrinsicAnimationListener(*this) ),
121 maTimeouts( rTimeouts
),
123 mnNumLoops(nNumLoops
),
127 ENSURE_OR_THROW( rContext
.mpSubsettableShapeManager
,
128 "IntrinsicAnimationActivity::IntrinsicAnimationActivity(): Invalid shape manager" );
129 ENSURE_OR_THROW( rDrawShape
,
130 "IntrinsicAnimationActivity::IntrinsicAnimationActivity(): Invalid draw shape" );
131 ENSURE_OR_THROW( rWakeupEvent
,
132 "IntrinsicAnimationActivity::IntrinsicAnimationActivity(): Invalid wakeup event" );
133 ENSURE_OR_THROW( !rTimeouts
.empty(),
134 "IntrinsicAnimationActivity::IntrinsicAnimationActivity(): Empty timeout vector" );
136 maContext
.mpSubsettableShapeManager
->addIntrinsicAnimationHandler(
140 void IntrinsicAnimationActivity::dispose()
145 mpWakeupEvent
->dispose();
149 mpWakeupEvent
.reset();
153 maContext
.mpSubsettableShapeManager
->removeIntrinsicAnimationHandler(
157 double IntrinsicAnimationActivity::calcTimeLag() const
162 bool IntrinsicAnimationActivity::perform()
167 DrawShapeSharedPtr
pDrawShape( mpDrawShape
.lock() );
168 if( !pDrawShape
|| !mpWakeupEvent
)
170 // event or draw shape vanished, no sense living on ->
176 const ::std::size_t nNumFrames(maTimeouts
.size());
178 // mnNumLoops == 0 means infinite looping
179 if( mnNumLoops
!= 0 &&
180 mnLoopCount
>= mnNumLoops
)
182 // #i55294# After finishing the loops, display the last frame
183 // powerpoint 2013 and firefox etc show the last frame when
184 // the animation ends
185 pDrawShape
->setIntrinsicAnimationFrame(nNumFrames
- 1);
186 maContext
.mpSubsettableShapeManager
->notifyShapeUpdate( pDrawShape
);
193 ::std::size_t nNewIndex
= 0;
195 pDrawShape
->setIntrinsicAnimationFrame( mnCurrIndex
);
197 mpWakeupEvent
->start();
198 mpWakeupEvent
->setNextTimeout( maTimeouts
[mnCurrIndex
] );
200 mnLoopCount
+= (mnCurrIndex
+ 1) / nNumFrames
;
201 nNewIndex
= (mnCurrIndex
+ 1) % nNumFrames
;
203 maContext
.mrEventQueue
.addEvent( mpWakeupEvent
);
204 maContext
.mpSubsettableShapeManager
->notifyShapeUpdate( pDrawShape
);
205 mnCurrIndex
= nNewIndex
;
207 return false; // don't reinsert, WakeupEvent will perform
208 // that after the given timeout
211 bool IntrinsicAnimationActivity::isActive() const
216 void IntrinsicAnimationActivity::dequeued()
221 void IntrinsicAnimationActivity::end()
223 // there is no dedicated end state, just become inactive:
227 bool IntrinsicAnimationActivity::enableAnimations()
230 return maContext
.mrActivitiesQueue
.addActivity( std::dynamic_pointer_cast
<Activity
>(shared_from_this()) );
235 ActivitySharedPtr
createIntrinsicAnimationActivity(
236 const SlideShowContext
& rContext
,
237 const DrawShapeSharedPtr
& rDrawShape
,
238 const WakeupEventSharedPtr
& rWakeupEvent
,
239 const ::std::vector
<double>& rTimeouts
,
240 sal_uInt32 nNumLoops
)
242 return ActivitySharedPtr(
243 new IntrinsicAnimationActivity(rContext
,
252 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */