LibreOffice Module sd (master) 1
SlsAnimator.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
21#include <utility>
23#include <osl/diagnose.h>
24
26
31{
32public:
33 Animation (
35 const double nStartOffset,
36 const double nDuration,
37 const double nGlobalTime,
38 const Animator::AnimationId nAnimationId,
39 Animator::FinishFunctor aFinishFunctor);
43 bool Run (const double nGlobalTime);
44
49 void Expire();
50 bool IsExpired() const { return mbIsExpired;}
51
55 const double mnDuration;
56 const double mnEnd;
57 const double mnGlobalTimeAtStart;
59};
60
62 : mrSlideSorter(rSlideSorter),
63 maIdle("sd slidesorter controller Animator"),
64 mbIsDisposed(false),
65 mnNextAnimationId(0)
66{
67 maIdle.SetPriority(TaskPriority::REPAINT);
68 maIdle.SetInvokeHandler(LINK(this,Animator,TimeoutHandler));
69}
70
72{
73 if ( ! mbIsDisposed)
74 {
75 OSL_ASSERT(mbIsDisposed);
76 Dispose();
77 }
78}
79
81{
82 mbIsDisposed = true;
83
85 for (const auto& rxAnimation : aCopy)
86 rxAnimation->Expire();
87
88 maIdle.Stop();
89 if (mpDrawLock)
90 {
91 mpDrawLock->Dispose();
92 mpDrawLock.reset();
93 }
94}
95
97 const AnimationFunctor& rAnimation,
98 const FinishFunctor& rFinishFunctor)
99{
100 // When the animator is already disposed then ignore this call
101 // silently (well, we show an assertion, but do not throw an exception.)
102 OSL_ASSERT( ! mbIsDisposed);
103 if (mbIsDisposed)
104 return -1;
105
106 std::shared_ptr<Animation> pAnimation =
107 std::make_shared<Animation>(
108 rAnimation,
109 0,
110 300 / 1000.0,
113 rFinishFunctor);
114 maAnimations.push_back(pAnimation);
115
117
118 return pAnimation->mnAnimationId;
119}
120
122{
123 OSL_ASSERT( ! mbIsDisposed);
124
125 const AnimationList::iterator iAnimation (::std::find_if(
126 maAnimations.begin(),
127 maAnimations.end(),
128 [nId] (std::shared_ptr<Animation> const& pAnim)
129 { return nId == pAnim->mnAnimationId; }));
130 if (iAnimation != maAnimations.end())
131 {
132 OSL_ASSERT((*iAnimation)->mnAnimationId == nId);
133 (*iAnimation)->Expire();
134 maAnimations.erase(iAnimation);
135 }
136
137 if (maAnimations.empty())
138 {
139 // Reset the animation id when we can.
141
142 // No more animations => we do not have to suppress painting
143 // anymore.
144 mpDrawLock.reset();
145 }
146}
147
149{
150 for (auto const& it : maAnimations)
151 {
152 it->Expire();
153 }
154 maAnimations.clear();
156
157 // No more animations => we do not have to suppress painting
158 // anymore.
159 mpDrawLock.reset();
160}
161
162bool Animator::ProcessAnimations (const double nTime)
163{
164 bool bExpired (false);
165
166 OSL_ASSERT( ! mbIsDisposed);
167 if (mbIsDisposed)
168 return bExpired;
169
171 for (const auto& rxAnimation : aCopy)
172 {
173 bExpired |= rxAnimation->Run(nTime);
174 }
175
176 return bExpired;
177}
178
180{
181 OSL_ASSERT( ! mbIsDisposed);
182 if (mbIsDisposed)
183 return;
184
185 AnimationList aActiveAnimations;
186
187 for (const auto& rxAnimation : maAnimations)
188 {
189 if ( ! rxAnimation->IsExpired())
190 aActiveAnimations.push_back(rxAnimation);
191 }
192
193 maAnimations.swap(aActiveAnimations);
194}
195
197{
198 if ( ! maIdle.IsActive())
199 {
200 // Prevent redraws except for the ones in TimeoutHandler. While the
201 // Animator is active it will schedule repaints regularly. Repaints
202 // in between would only lead to visual artifacts.
204 maIdle.Start();
205 }
206}
207
208IMPL_LINK_NOARG(Animator, TimeoutHandler, Timer *, void)
209{
210 if (mbIsDisposed)
211 return;
212
213 if (ProcessAnimations(maElapsedTime.getElapsedTime()))
214 CleanUpAnimationList();
215
216 // Unlock the draw lock. This should lead to a repaint.
217 mpDrawLock.reset();
218
219 if (!maAnimations.empty())
220 RequestNextFrame();
221}
222
223//===== Animator::Animation ===================================================
224
227 const double nStartOffset,
228 const double nDuration,
229 const double nGlobalTime,
230 const Animator::AnimationId nId,
231 Animator::FinishFunctor aFinishFunctor)
232 : maAnimation(std::move(aAnimation)),
233 maFinishFunctor(std::move(aFinishFunctor)),
235 mnDuration(nDuration),
236 mnEnd(nGlobalTime + nDuration + nStartOffset),
237 mnGlobalTimeAtStart(nGlobalTime + nStartOffset),
238 mbIsExpired(false)
239{
240 Run(nGlobalTime);
241}
242
243bool Animator::Animation::Run (const double nGlobalTime)
244{
245 if ( ! mbIsExpired)
246 {
247 if (mnDuration > 0)
248 {
249 if (nGlobalTime >= mnEnd)
250 {
251 maAnimation(1.0);
252 Expire();
253 }
254 else if (nGlobalTime >= mnGlobalTimeAtStart)
255 {
256 maAnimation((nGlobalTime - mnGlobalTimeAtStart) / mnDuration);
257 }
258 }
259 else if (mnDuration < 0)
260 {
261 // Animations without end have to be expired by their owner.
262 maAnimation(nGlobalTime);
263 }
264 }
265
266 return mbIsExpired;
267}
268
270{
271 if ( ! mbIsExpired)
272 {
273 mbIsExpired = true;
274 if (maFinishFunctor)
275 maFinishFunctor();
276 }
277}
278
279} // end of namespace ::sd::slidesorter::controller
280
281/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
controller::Animator::AnimationId mnAnimationId
SlideSorter & mrSlideSorter
size_t mnEnd
virtual void Start(bool bStartTimer=true) override
bool IsActive() const
void SetPriority(TaskPriority ePriority)
void Stop()
void SetInvokeHandler(const Link< Timer *, void > &rLink)
double getElapsedTime() const
Show previews for all the slides in a document and allow the user to insert or delete slides and modi...
Definition: SlideSorter.hxx:62
Handle one animation function by using a timer for frequent calls to the animations operator().
Definition: SlsAnimator.cxx:31
bool Run(const double nGlobalTime)
Run next animation step.
void Expire()
Typically called when an animation has finished, but also from Animator::Disposed().
Animation(Animator::AnimationFunctor aAnimation, const double nStartOffset, const double nDuration, const double nGlobalTime, const Animator::AnimationId nAnimationId, Animator::FinishFunctor aFinishFunctor)
Experimental class for simple eye candy animations.
Definition: SlsAnimator.hxx:39
Animator(SlideSorter &rSlideSorter)
Definition: SlsAnimator.cxx:61
std::unique_ptr< view::SlideSorterView::DrawLock, o3tl::default_delete< view::SlideSorterView::DrawLock > > mpDrawLock
Definition: SlsAnimator.hxx:98
void RemoveAnimation(const AnimationId nAnimationId)
Abort and remove an animation.
::std::function< void()> FinishFunctor
Definition: SlsAnimator.hxx:61
void RemoveAllAnimations()
A typical use case for this method is the temporary shutdown of the slidesorter when the slide sorter...
void Dispose()
When disposed the animator will stop its work immediately and not process any timer events anymore.
Definition: SlsAnimator.cxx:80
bool ProcessAnimations(const double nTime)
Execute one step of every active animation.
AnimationId AddAnimation(const AnimationFunctor &rAnimation, const FinishFunctor &rFinishFunctor)
Schedule a new animation for execution.
Definition: SlsAnimator.cxx:96
::std::function< void(double)> AnimationFunctor
An animation object is called with values between 0 and 1 as single argument to its operator() method...
Definition: SlsAnimator.hxx:60
void CleanUpAnimationList()
Remove animations that have expired.
::std::vector< std::shared_ptr< Animation > > AnimationList
Definition: SlsAnimator.hxx:93
::canvas::tools::ElapsedTime maElapsedTime
Definition: SlsAnimator.hxx:96
::Animation maAnimation
IMPL_LINK_NOARG(Animator, TimeoutHandler, Timer *, void)
sal_Int16 nId
SlideAnimations maAnimations