|
|
@@ -27,6 +27,11 @@ class ComponentAnimator::AnimationTask |
|
|
|
public:
|
|
|
|
AnimationTask (Component* c) noexcept : component (c) {}
|
|
|
|
|
|
|
|
~AnimationTask()
|
|
|
|
{
|
|
|
|
masterReference.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void reset (const Rectangle<int>& finalBounds,
|
|
|
|
float finalAlpha,
|
|
|
|
int millisecondsToSpendMoving,
|
|
|
@@ -63,14 +68,15 @@ public: |
|
|
|
|
|
|
|
bool useTimeslice (const int elapsed)
|
|
|
|
{
|
|
|
|
if (Component* const c = proxy != nullptr ? static_cast<Component*> (proxy)
|
|
|
|
: static_cast<Component*> (component))
|
|
|
|
if (auto* c = proxy != nullptr ? static_cast<Component*> (proxy)
|
|
|
|
: static_cast<Component*> (component))
|
|
|
|
{
|
|
|
|
msElapsed += elapsed;
|
|
|
|
double newProgress = msElapsed / (double) msTotal;
|
|
|
|
|
|
|
|
if (newProgress >= 0 && newProgress < 1.0)
|
|
|
|
{
|
|
|
|
const WeakReference<AnimationTask> weakRef (this);
|
|
|
|
newProgress = timeToDistance (newProgress);
|
|
|
|
const double delta = (newProgress - lastProgress) / (1.0 - lastProgress);
|
|
|
|
jassert (newProgress >= lastProgress);
|
|
|
@@ -99,6 +105,11 @@ public: |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check whether the animation was cancelled/deleted during
|
|
|
|
// a callback during the setBounds method
|
|
|
|
if (weakRef.wasObjectDeleted())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (isChangingAlpha)
|
|
|
|
{
|
|
|
|
alpha += (destAlpha - alpha) * delta;
|
|
|
@@ -129,9 +140,8 @@ public: |
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
class ProxyComponent : public Component
|
|
|
|
struct ProxyComponent : public Component
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ProxyComponent (Component& c)
|
|
|
|
{
|
|
|
|
setWantsKeyboardFocus (false);
|
|
|
@@ -140,15 +150,15 @@ public: |
|
|
|
setAlpha (c.getAlpha());
|
|
|
|
setInterceptsMouseClicks (false, false);
|
|
|
|
|
|
|
|
if (Component* const parent = c.getParentComponent())
|
|
|
|
if (auto* parent = c.getParentComponent())
|
|
|
|
parent->addAndMakeVisible (this);
|
|
|
|
else if (c.isOnDesktop() && c.getPeer() != nullptr)
|
|
|
|
addToDesktop (c.getPeer()->getStyleFlags() | ComponentPeer::windowIgnoresKeyPresses);
|
|
|
|
else
|
|
|
|
jassertfalse; // seem to be trying to animate a component that's not visible..
|
|
|
|
|
|
|
|
const float scale = (float) Desktop::getInstance().getDisplays()
|
|
|
|
.getDisplayContaining (getScreenBounds().getCentre()).scale;
|
|
|
|
auto scale = (float) Desktop::getInstance().getDisplays()
|
|
|
|
.getDisplayContaining (getScreenBounds().getCentre()).scale;
|
|
|
|
|
|
|
|
image = c.createComponentSnapshot (c.getLocalBounds(), false, scale);
|
|
|
|
|
|
|
@@ -169,6 +179,9 @@ public: |
|
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProxyComponent)
|
|
|
|
};
|
|
|
|
|
|
|
|
WeakReference<AnimationTask>::Master masterReference;
|
|
|
|
friend class WeakReference<AnimationTask>;
|
|
|
|
|
|
|
|
WeakReference<Component> component;
|
|
|
|
ScopedPointer<Component> proxy;
|
|
|
|
|
|
|
@@ -187,6 +200,8 @@ private: |
|
|
|
: 0.5 * (startSpeed + 0.5 * (midSpeed - startSpeed))
|
|
|
|
+ (time - 0.5) * (midSpeed + (time - 0.5) * (endSpeed - midSpeed));
|
|
|
|
}
|
|
|
|
|
|
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AnimationTask)
|
|
|
|
};
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
@@ -216,7 +231,7 @@ void ComponentAnimator::animateComponent (Component* const component, |
|
|
|
|
|
|
|
if (component != nullptr)
|
|
|
|
{
|
|
|
|
AnimationTask* at = findTaskFor (component);
|
|
|
|
auto* at = findTaskFor (component);
|
|
|
|
|
|
|
|
if (at == nullptr)
|
|
|
|
{
|
|
|
@@ -273,7 +288,7 @@ void ComponentAnimator::cancelAllAnimations (const bool moveComponentsToTheirFin |
|
|
|
void ComponentAnimator::cancelAnimation (Component* const component,
|
|
|
|
const bool moveComponentToItsFinalPosition)
|
|
|
|
{
|
|
|
|
if (AnimationTask* const at = findTaskFor (component))
|
|
|
|
if (auto* at = findTaskFor (component))
|
|
|
|
{
|
|
|
|
if (moveComponentToItsFinalPosition)
|
|
|
|
at->moveToFinalDestination();
|
|
|
@@ -287,7 +302,7 @@ Rectangle<int> ComponentAnimator::getComponentDestination (Component* const comp |
|
|
|
{
|
|
|
|
jassert (component != nullptr);
|
|
|
|
|
|
|
|
if (AnimationTask* const at = findTaskFor (component))
|
|
|
|
if (auto* at = findTaskFor (component))
|
|
|
|
return at->destination;
|
|
|
|
|
|
|
|
return component->getBounds();
|
|
|
@@ -305,18 +320,18 @@ bool ComponentAnimator::isAnimating() const noexcept |
|
|
|
|
|
|
|
void ComponentAnimator::timerCallback()
|
|
|
|
{
|
|
|
|
const uint32 timeNow = Time::getMillisecondCounter();
|
|
|
|
auto timeNow = Time::getMillisecondCounter();
|
|
|
|
|
|
|
|
if (lastTime == 0 || lastTime == timeNow)
|
|
|
|
if (lastTime == 0)
|
|
|
|
lastTime = timeNow;
|
|
|
|
|
|
|
|
const int elapsed = (int) (timeNow - lastTime);
|
|
|
|
auto elapsed = (int) (timeNow - lastTime);
|
|
|
|
|
|
|
|
for (int i = tasks.size(); --i >= 0;)
|
|
|
|
for (auto* task : Array<AnimationTask*> (tasks.begin(), tasks.size()))
|
|
|
|
{
|
|
|
|
if (! tasks.getUnchecked(i)->useTimeslice (elapsed))
|
|
|
|
if (tasks.contains (task) && ! task->useTimeslice (elapsed))
|
|
|
|
{
|
|
|
|
tasks.remove (i);
|
|
|
|
tasks.removeObject (task);
|
|
|
|
sendChangeMessage();
|
|
|
|
}
|
|
|
|
}
|
|
|
|