LMMS
Loading...
Searching...
No Matches
juce_ComponentAnimator.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce
27{
28
30{
31public:
33
35 {
36 proxy.deleteAndZero();
37 }
38
39 void reset (const Rectangle<int>& finalBounds,
40 float finalAlpha,
41 int millisecondsToSpendMoving,
42 bool useProxyComponent,
43 double startSpd, double endSpd)
44 {
45 msElapsed = 0;
46 msTotal = jmax (1, millisecondsToSpendMoving);
47 lastProgress = 0;
48 destination = finalBounds;
49 destAlpha = finalAlpha;
50
51 isMoving = (finalBounds != component->getBounds());
52 isChangingAlpha = (finalAlpha != component->getAlpha());
53
54 left = component->getX();
55 top = component->getY();
56 right = component->getRight();
57 bottom = component->getBottom();
58 alpha = component->getAlpha();
59
60 const double invTotalDistance = 4.0 / (startSpd + endSpd + 2.0);
61 startSpeed = jmax (0.0, startSpd * invTotalDistance);
62 midSpeed = invTotalDistance;
63 endSpeed = jmax (0.0, endSpd * invTotalDistance);
64
65 proxy.deleteAndZero();
66
67 if (useProxyComponent)
69
70 component->setVisible (! useProxyComponent);
71 }
72
73 bool useTimeslice (const int elapsed)
74 {
75 if (auto* c = proxy != nullptr ? proxy.getComponent()
76 : component.get())
77 {
78 msElapsed += elapsed;
79 double newProgress = msElapsed / (double) msTotal;
80
81 if (newProgress >= 0 && newProgress < 1.0)
82 {
83 const WeakReference<AnimationTask> weakRef (this);
84 newProgress = timeToDistance (newProgress);
85 const double delta = (newProgress - lastProgress) / (1.0 - lastProgress);
86 jassert (newProgress >= lastProgress);
87 lastProgress = newProgress;
88
89 if (delta < 1.0)
90 {
91 bool stillBusy = false;
92
93 if (isMoving)
94 {
95 left += (destination.getX() - left) * delta;
96 top += (destination.getY() - top) * delta;
97 right += (destination.getRight() - right) * delta;
98 bottom += (destination.getBottom() - bottom) * delta;
99
100 const Rectangle<int> newBounds (roundToInt (left),
101 roundToInt (top),
103 roundToInt (bottom - top));
104
105 if (newBounds != destination)
106 {
107 c->setBounds (newBounds);
108 stillBusy = true;
109 }
110 }
111
112 // Check whether the animation was cancelled/deleted during
113 // a callback during the setBounds method
114 if (weakRef.wasObjectDeleted())
115 return false;
116
117 if (isChangingAlpha)
118 {
119 alpha += (destAlpha - alpha) * delta;
120 c->setAlpha ((float) alpha);
121 stillBusy = true;
122 }
123
124 if (stillBusy)
125 return true;
126 }
127 }
128 }
129
131 return false;
132 }
133
135 {
136 if (component != nullptr)
137 {
138 const WeakReference<AnimationTask> weakRef (this);
139 component->setAlpha ((float) destAlpha);
140 component->setBounds (destination);
141
142 if (! weakRef.wasObjectDeleted())
143 if (proxy != nullptr)
144 component->setVisible (destAlpha > 0);
145 }
146 }
147
148 //==============================================================================
149 struct ProxyComponent : public Component
150 {
152 {
153 setWantsKeyboardFocus (false);
154 setBounds (c.getBounds());
155 setTransform (c.getTransform());
156 setAlpha (c.getAlpha());
157 setInterceptsMouseClicks (false, false);
158
159 if (auto* parent = c.getParentComponent())
160 parent->addAndMakeVisible (this);
161 else if (c.isOnDesktop() && c.getPeer() != nullptr)
162 addToDesktop (c.getPeer()->getStyleFlags() | ComponentPeer::windowIgnoresKeyPresses);
163 else
164 jassertfalse; // seem to be trying to animate a component that's not visible..
165
166 auto scale = (float) Desktop::getInstance().getDisplays().getDisplayForRect (getScreenBounds())->scale
168
169 image = c.createComponentSnapshot (c.getLocalBounds(), false, scale);
170
171 setVisible (true);
172 toBehind (&c);
173 }
174
175 void paint (Graphics& g) override
176 {
177 g.setOpacity (1.0f);
178 g.drawImageTransformed (image, AffineTransform::scale ((float) getWidth() / (float) jmax (1, image.getWidth()),
179 (float) getHeight() / (float) jmax (1, image.getHeight())), false);
180 }
181
182 private:
183 std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override
184 {
186 }
187
189
191 };
192
195
197 double destAlpha;
198
203
204private:
205 double timeToDistance (const double time) const noexcept
206 {
207 return (time < 0.5) ? time * (startSpeed + time * (midSpeed - startSpeed))
208 : 0.5 * (startSpeed + 0.5 * (midSpeed - startSpeed))
209 + (time - 0.5) * (midSpeed + (time - 0.5) * (endSpeed - midSpeed));
210 }
211
214};
215
216//==============================================================================
219
220//==============================================================================
222{
223 for (int i = tasks.size(); --i >= 0;)
224 if (component == tasks.getUnchecked(i)->component.get())
225 return tasks.getUnchecked(i);
226
227 return nullptr;
228}
229
231 const Rectangle<int>& finalBounds,
232 const float finalAlpha,
233 const int millisecondsToSpendMoving,
234 const bool useProxyComponent,
235 const double startSpeed,
236 const double endSpeed)
237{
238 // the speeds must be 0 or greater!
239 jassert (startSpeed >= 0 && endSpeed >= 0);
240
241 if (component != nullptr)
242 {
243 auto* at = findTaskFor (component);
244
245 if (at == nullptr)
246 {
247 at = new AnimationTask (component);
248 tasks.add (at);
250 }
251
252 at->reset (finalBounds, finalAlpha, millisecondsToSpendMoving,
253 useProxyComponent, startSpeed, endSpeed);
254
255 if (! isTimerRunning())
256 {
258 startTimerHz (50);
259 }
260 }
261}
262
263void ComponentAnimator::fadeOut (Component* component, int millisecondsToTake)
264{
265 if (component != nullptr)
266 {
267 if (component->isShowing() && millisecondsToTake > 0)
268 animateComponent (component, component->getBounds(), 0.0f, millisecondsToTake, true, 1.0, 1.0);
269
270 component->setVisible (false);
271 }
272}
273
274void ComponentAnimator::fadeIn (Component* component, int millisecondsToTake)
275{
276 if (component != nullptr && ! (component->isVisible() && component->getAlpha() == 1.0f))
277 {
278 component->setAlpha (0.0f);
279 component->setVisible (true);
280 animateComponent (component, component->getBounds(), 1.0f, millisecondsToTake, false, 1.0, 1.0);
281 }
282}
283
284void ComponentAnimator::cancelAllAnimations (const bool moveComponentsToTheirFinalPositions)
285{
286 if (tasks.size() > 0)
287 {
288 if (moveComponentsToTheirFinalPositions)
289 for (int i = tasks.size(); --i >= 0;)
290 tasks.getUnchecked(i)->moveToFinalDestination();
291
292 tasks.clear();
294 }
295}
296
298 const bool moveComponentToItsFinalPosition)
299{
300 if (auto* at = findTaskFor (component))
301 {
302 if (moveComponentToItsFinalPosition)
303 at->moveToFinalDestination();
304
305 tasks.removeObject (at);
307 }
308}
309
311{
312 jassert (component != nullptr);
313
314 if (auto* at = findTaskFor (component))
315 return at->destination;
316
317 return component->getBounds();
318}
319
320bool ComponentAnimator::isAnimating (Component* component) const noexcept
321{
322 return findTaskFor (component) != nullptr;
323}
324
326{
327 return tasks.size() != 0;
328}
329
331{
332 auto timeNow = Time::getMillisecondCounter();
333
334 if (lastTime == 0)
335 lastTime = timeNow;
336
337 auto elapsed = (int) (timeNow - lastTime);
338
339 for (auto* task : Array<AnimationTask*> (tasks.begin(), tasks.size()))
340 {
341 if (tasks.contains (task) && ! task->useTimeslice (elapsed))
342 {
343 tasks.removeObject (task);
345 }
346 }
347
348 lastTime = timeNow;
349
350 if (tasks.size() == 0)
351 stopTimer();
352}
353
354} // namespace juce
Type jmax(const Type a, const Type b)
Definition MathsFunctions.h:48
#define noexcept
Definition DistrhoDefines.h:72
static AffineTransform scale(float factorX, float factorY) noexcept
Definition juce_AffineTransform.cpp:141
Definition juce_Array.h:56
void sendChangeMessage()
Definition juce_ChangeBroadcaster.cpp:65
Definition juce_Component.h:2287
Definition juce_ComponentAnimator.cpp:30
bool isChangingAlpha
Definition juce_ComponentAnimator.cpp:202
WeakReference< Component > component
Definition juce_ComponentAnimator.cpp:193
double alpha
Definition juce_ComponentAnimator.cpp:201
Component::SafePointer< Component > proxy
Definition juce_ComponentAnimator.cpp:194
double left
Definition juce_ComponentAnimator.cpp:201
double startSpeed
Definition juce_ComponentAnimator.cpp:200
void moveToFinalDestination()
Definition juce_ComponentAnimator.cpp:134
double timeToDistance(const double time) const noexcept
Definition juce_ComponentAnimator.cpp:205
bool useTimeslice(const int elapsed)
Definition juce_ComponentAnimator.cpp:73
double midSpeed
Definition juce_ComponentAnimator.cpp:200
bool isMoving
Definition juce_ComponentAnimator.cpp:202
double lastProgress
Definition juce_ComponentAnimator.cpp:200
void reset(const Rectangle< int > &finalBounds, float finalAlpha, int millisecondsToSpendMoving, bool useProxyComponent, double startSpd, double endSpd)
Definition juce_ComponentAnimator.cpp:39
double right
Definition juce_ComponentAnimator.cpp:201
double destAlpha
Definition juce_ComponentAnimator.cpp:197
int msTotal
Definition juce_ComponentAnimator.cpp:199
double top
Definition juce_ComponentAnimator.cpp:201
Rectangle< int > destination
Definition juce_ComponentAnimator.cpp:196
double bottom
Definition juce_ComponentAnimator.cpp:201
double endSpeed
Definition juce_ComponentAnimator.cpp:200
AnimationTask(Component *c) noexcept
Definition juce_ComponentAnimator.cpp:32
~AnimationTask()
Definition juce_ComponentAnimator.cpp:34
int msElapsed
Definition juce_ComponentAnimator.cpp:199
void animateComponent(Component *component, const Rectangle< int > &finalBounds, float finalAlpha, int animationDurationMilliseconds, bool useProxyComponent, double startSpeed, double endSpeed)
Definition juce_ComponentAnimator.cpp:230
void cancelAllAnimations(bool moveComponentsToTheirFinalPositions)
Definition juce_ComponentAnimator.cpp:284
void timerCallback() override
Definition juce_ComponentAnimator.cpp:330
Rectangle< int > getComponentDestination(Component *component)
Definition juce_ComponentAnimator.cpp:310
void fadeOut(Component *component, int millisecondsToTake)
Definition juce_ComponentAnimator.cpp:263
uint32 lastTime
Definition juce_ComponentAnimator.h:154
AnimationTask * findTaskFor(Component *) const noexcept
Definition juce_ComponentAnimator.cpp:221
~ComponentAnimator() override
Definition juce_ComponentAnimator.cpp:218
void cancelAnimation(Component *component, bool moveComponentToItsFinalPosition)
Definition juce_ComponentAnimator.cpp:297
bool isAnimating(Component *component) const noexcept
Definition juce_ComponentAnimator.cpp:320
OwnedArray< AnimationTask > tasks
Definition juce_ComponentAnimator.h:153
void fadeIn(Component *component, int millisecondsToTake)
Definition juce_ComponentAnimator.cpp:274
ComponentAnimator()
Definition juce_ComponentAnimator.cpp:217
Definition juce_Component.h:36
void setTransform(const AffineTransform &transform)
Definition juce_Component.cpp:1341
void toBehind(Component *other)
Definition juce_Component.cpp:1004
void setInterceptsMouseClicks(bool allowClicksOnThisComponent, bool allowClicksOnChildComponents) noexcept
Definition juce_Component.cpp:1420
bool isVisible() const noexcept
Definition juce_Component.h:122
int getHeight() const noexcept
Definition juce_Component.h:274
bool isShowing() const
Definition juce_Component.cpp:634
static float JUCE_CALLTYPE getApproximateScaleFactorForComponent(const Component *targetComponent)
Definition juce_Component.cpp:1383
void setAlpha(float newAlpha)
Definition juce_Component.cpp:1892
float getAlpha() const noexcept
Definition juce_Component.cpp:1887
Rectangle< int > getBounds() const noexcept
Definition juce_Component.h:304
Component() noexcept
Definition juce_Component.cpp:517
Rectangle< int > getScreenBounds() const
Definition juce_Component.cpp:1134
virtual void addToDesktop(int windowStyleFlags, void *nativeWindowToAttachTo=nullptr)
Definition juce_Component.cpp:658
void setBounds(int x, int y, int width, int height)
Definition juce_Component.cpp:1147
void setWantsKeyboardFocus(bool wantsFocus) noexcept
Definition juce_Component.cpp:2842
static std::unique_ptr< AccessibilityHandler > createIgnoredAccessibilityHandler(Component &)
Definition juce_Component.cpp:3292
int getWidth() const noexcept
Definition juce_Component.h:271
virtual void setVisible(bool shouldBeVisible)
Definition juce_Component.cpp:575
@ windowIgnoresKeyPresses
Definition juce_ComponentPeer.h:71
static Desktop &JUCE_CALLTYPE getInstance()
Definition juce_Desktop.cpp:50
Definition juce_GraphicsContext.h:45
Definition juce_Image.h:58
Definition juce_Rectangle.h:67
static uint32 getMillisecondCounter() noexcept
Definition juce_Time.cpp:241
void stopTimer() noexcept
Definition juce_Timer.cpp:357
void startTimerHz(int timerFrequencyHz) noexcept
Definition juce_Timer.cpp:349
bool isTimerRunning() const noexcept
Definition juce_Timer.h:111
Definition juce_WeakReference.h:78
bool wasObjectDeleted() const noexcept
Definition juce_WeakReference.h:117
int g
Definition inflate.c:1573
register unsigned i
Definition inflate.c:1575
static uintptr_t parent
Definition pugl.h:1644
#define jassert(expression)
#define JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(className)
#define jassertfalse
#define JUCE_DECLARE_WEAK_REFERENCEABLE(Class)
Definition juce_WeakReference.h:234
Definition carla_juce.cpp:31
constexpr Type jmax(Type a, Type b)
Definition juce_MathsFunctions.h:94
int roundToInt(const FloatType value) noexcept
Definition juce_MathsFunctions.h:465
Definition juce_ComponentAnimator.cpp:150
Image image
Definition juce_ComponentAnimator.cpp:188
void paint(Graphics &g) override
Definition juce_ComponentAnimator.cpp:175
ProxyComponent(Component &c)
Definition juce_ComponentAnimator.cpp:151
std::unique_ptr< AccessibilityHandler > createAccessibilityHandler() override
Definition juce_ComponentAnimator.cpp:183
return c
Definition crypt.c:175
typedef int(UZ_EXP MsgFn)()
#define const
Definition zconf.h:137