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 .
20 #include "controller/SlsAnimator.hxx"
21 #include "view/SlideSorterView.hxx"
23 #include <boost/bind.hpp>
25 namespace sd
{ namespace slidesorter
{ namespace controller
{
27 /** Handle one animation function by using a timer for frequent calls to
28 the animations operator().
30 class Animator::Animation
34 const Animator::AnimationFunctor
& rAnimation
,
35 const double nStartOffset
,
36 const double nDuration
,
37 const double nGlobalTime
,
38 const Animator::AnimationId nAnimationId
,
39 const Animator::FinishFunctor
& rFinishFunctor
);
41 /** Run next animation step. If animation has reached its end it is
44 bool Run (const double nGlobalTime
);
46 /** Typically called when an animation has finished, but also from
47 Animator::Disposed(). The finish functor is called and the
48 animation is marked as expired to prevent another run.
51 bool IsExpired() { return mbIsExpired
;}
53 Animator::AnimationFunctor maAnimation
;
54 Animator::FinishFunctor maFinishFunctor
;
55 const Animator::AnimationId mnAnimationId
;
56 const double mnDuration
;
58 const double mnGlobalTimeAtStart
;
62 Animator::Animator (SlideSorter
& rSlideSorter
)
63 : mrSlideSorter(rSlideSorter
),
71 maIdle
.SetPriority(SchedulerPriority::REPAINT
);
72 maIdle
.SetIdleHdl(LINK(this,Animator
,TimeoutHandler
));
79 OSL_ASSERT(mbIsDisposed
);
84 void Animator::Dispose()
88 AnimationList
aCopy (maAnimations
);
89 AnimationList::const_iterator iAnimation
;
90 for (iAnimation
=aCopy
.begin(); iAnimation
!=aCopy
.end(); ++iAnimation
)
91 (*iAnimation
)->Expire();
96 mpDrawLock
->Dispose();
101 Animator::AnimationId
Animator::AddAnimation (
102 const AnimationFunctor
& rAnimation
,
103 const sal_Int32 nStartOffset
,
104 const sal_Int32 nDuration
,
105 const FinishFunctor
& rFinishFunctor
)
107 // When the animator is already disposed then ignore this call
108 // silently (well, we show an assertion, but do not throw an exception.)
109 OSL_ASSERT( ! mbIsDisposed
);
113 boost::shared_ptr
<Animation
> pAnimation (
116 nStartOffset
/ 1000.0,
118 maElapsedTime
.getElapsedTime(),
121 maAnimations
.push_back(pAnimation
);
125 return pAnimation
->mnAnimationId
;
128 void Animator::RemoveAnimation (const Animator::AnimationId nId
)
130 OSL_ASSERT( ! mbIsDisposed
);
132 const AnimationList::iterator
iAnimation (::std::find_if(
133 maAnimations
.begin(),
136 ::std::equal_to
<Animator::AnimationId
>(),
138 ::boost::bind(&Animation::mnAnimationId
, _1
))));
139 if (iAnimation
!= maAnimations
.end())
141 OSL_ASSERT((*iAnimation
)->mnAnimationId
== nId
);
142 (*iAnimation
)->Expire();
143 maAnimations
.erase(iAnimation
);
146 if (maAnimations
.empty())
148 // Reset the animation id when we can.
149 mnNextAnimationId
= 0;
151 // No more animations => we do not have to suppress painting
157 void Animator::RemoveAllAnimations()
160 maAnimations
.begin(),
165 maAnimations
.clear();
166 mnNextAnimationId
= 0;
168 // No more animations => we do not have to suppress painting
173 bool Animator::ProcessAnimations (const double nTime
)
175 bool bExpired (false);
177 OSL_ASSERT( ! mbIsDisposed
);
181 AnimationList
aCopy (maAnimations
);
182 AnimationList::const_iterator iAnimation
;
183 for (iAnimation
=aCopy
.begin(); iAnimation
!=aCopy
.end(); ++iAnimation
)
185 bExpired
|= (*iAnimation
)->Run(nTime
);
191 void Animator::CleanUpAnimationList()
193 OSL_ASSERT( ! mbIsDisposed
);
197 AnimationList aActiveAnimations
;
199 AnimationList::const_iterator iAnimation
;
200 for (iAnimation
=maAnimations
.begin(); iAnimation
!=maAnimations
.end(); ++iAnimation
)
202 if ( ! (*iAnimation
)->IsExpired())
203 aActiveAnimations
.push_back(*iAnimation
);
206 maAnimations
.swap(aActiveAnimations
);
209 void Animator::RequestNextFrame (const double nFrameStart
)
212 if ( ! maIdle
.IsActive())
214 // Prevent redraws except for the ones in TimeoutHandler. While the
215 // Animator is active it will schedule repaints regularly. Repaints
216 // in between would only lead to visual artifacts.
217 mpDrawLock
.reset(new view::SlideSorterView::DrawLock(mrSlideSorter
));
222 IMPL_LINK_NOARG_TYPED(Animator
, TimeoutHandler
, Idle
*, void)
227 if (ProcessAnimations(maElapsedTime
.getElapsedTime()))
228 CleanUpAnimationList();
230 // Unlock the draw lock. This should lead to a repaint.
233 if (!maAnimations
.empty())
237 //===== Animator::Animation ===================================================
239 Animator::Animation::Animation (
240 const Animator::AnimationFunctor
& rAnimation
,
241 const double nStartOffset
,
242 const double nDuration
,
243 const double nGlobalTime
,
244 const Animator::AnimationId nId
,
245 const Animator::FinishFunctor
& rFinishFunctor
)
246 : maAnimation(rAnimation
),
247 maFinishFunctor(rFinishFunctor
),
249 mnDuration(nDuration
),
250 mnEnd(nGlobalTime
+ nDuration
+ nStartOffset
),
251 mnGlobalTimeAtStart(nGlobalTime
+ nStartOffset
),
257 Animator::Animation::~Animation()
261 bool Animator::Animation::Run (const double nGlobalTime
)
267 if (nGlobalTime
>= mnEnd
)
272 else if (nGlobalTime
>= mnGlobalTimeAtStart
)
274 maAnimation((nGlobalTime
- mnGlobalTimeAtStart
) / mnDuration
);
277 else if (mnDuration
< 0)
279 // Animations without end have to be expired by their owner.
280 maAnimation(nGlobalTime
);
287 void Animator::Animation::Expire()
297 } } } // end of namespace ::sd::slidesorter::controller
299 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */