Bump version to 6.4-15
[LibreOffice.git] / slideshow / source / engine / shapes / intrinsicanimationactivity.cxx
blob5461299beb2ea39cd320fa1c4eeccb11a02b046b
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 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();
81 private:
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;
90 bool mbIsActive;
94 class IntrinsicAnimationListener : public IntrinsicAnimationEventHandler
96 public:
97 explicit IntrinsicAnimationListener( IntrinsicAnimationActivity& rActivity ) :
98 mrActivity( rActivity )
100 IntrinsicAnimationListener(const IntrinsicAnimationListener&) = delete;
101 IntrinsicAnimationListener& operator=(const IntrinsicAnimationListener&) = delete;
103 private:
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 ),
122 mnCurrIndex(0),
123 mnNumLoops(nNumLoops),
124 mnLoopCount(0),
125 mbIsActive(false)
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(
137 mpListener );
140 void IntrinsicAnimationActivity::dispose()
142 end();
144 if( mpWakeupEvent )
145 mpWakeupEvent->dispose();
147 maContext.dispose();
148 mpDrawShape.reset();
149 mpWakeupEvent.reset();
150 maTimeouts.clear();
151 mnCurrIndex = 0;
153 maContext.mpSubsettableShapeManager->removeIntrinsicAnimationHandler(
154 mpListener );
157 double IntrinsicAnimationActivity::calcTimeLag() const
159 return 0.0;
162 bool IntrinsicAnimationActivity::perform()
164 if( !isActive() )
165 return false;
167 DrawShapeSharedPtr pDrawShape( mpDrawShape.lock() );
168 if( !pDrawShape || !mpWakeupEvent )
170 // event or draw shape vanished, no sense living on ->
171 // commit suicide.
172 dispose();
173 return false;
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 );
188 end();
190 return false;
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
213 return mbIsActive;
216 void IntrinsicAnimationActivity::dequeued()
218 // not used here
221 void IntrinsicAnimationActivity::end()
223 // there is no dedicated end state, just become inactive:
224 mbIsActive = false;
227 bool IntrinsicAnimationActivity::enableAnimations()
229 mbIsActive = true;
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,
244 rDrawShape,
245 rWakeupEvent,
246 rTimeouts,
247 nNumLoops) );
252 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */