388 lines
11 KiB
C++
388 lines
11 KiB
C++
// This file is part of VSTGUI. It is subject to the license terms
|
|
// in the LICENSE file found in the top-level directory of this
|
|
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
|
|
|
|
#include "animations.h"
|
|
#include "../cview.h"
|
|
#include "../cframe.h"
|
|
#include "../controls/ccontrol.h"
|
|
#include <cassert>
|
|
#include <cmath>
|
|
|
|
namespace VSTGUI {
|
|
namespace Animation {
|
|
//------------------------------------------------------------------------
|
|
/*! @defgroup AnimationTargets Animation Targets
|
|
* @ingroup animation
|
|
*/
|
|
//------------------------------------------------------------------------
|
|
|
|
/** @class AlphaValueAnimation
|
|
see @ref page_animation Support */
|
|
//-----------------------------------------------------------------------------
|
|
AlphaValueAnimation::AlphaValueAnimation (float endValue, bool forceEndValueOnFinish)
|
|
: startValue (0.f)
|
|
, endValue (endValue)
|
|
, forceEndValueOnFinish (forceEndValueOnFinish)
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void AlphaValueAnimation::animationStart (CView* view, IdStringPtr name)
|
|
{
|
|
startValue = view->getAlphaValue ();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void AlphaValueAnimation::animationTick (CView* view, IdStringPtr name, float pos)
|
|
{
|
|
float alpha = startValue + (endValue - startValue) * pos;
|
|
view->setAlphaValue (alpha);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void AlphaValueAnimation::animationFinished (CView* view, IdStringPtr name, bool wasCanceled)
|
|
{
|
|
if (!wasCanceled || forceEndValueOnFinish)
|
|
view->setAlphaValue (endValue);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
/** @class ViewSizeAnimation
|
|
see @ref page_animation Support */
|
|
//-----------------------------------------------------------------------------
|
|
ViewSizeAnimation::ViewSizeAnimation (const CRect& inNewRect, bool forceEndValueOnFinish)
|
|
: newRect (inNewRect)
|
|
, forceEndValueOnFinish (forceEndValueOnFinish)
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void ViewSizeAnimation::animationStart (CView* view, IdStringPtr name)
|
|
{
|
|
startRect = view->getViewSize ();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void ViewSizeAnimation::animationFinished (CView* view, IdStringPtr name, bool wasCanceled)
|
|
{
|
|
if (!wasCanceled || forceEndValueOnFinish)
|
|
{
|
|
if (view->getViewSize () != newRect)
|
|
{
|
|
view->invalid ();
|
|
view->setViewSize (newRect);
|
|
view->setMouseableArea (view->getViewSize ());
|
|
view->invalid ();
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void ViewSizeAnimation::animationTick (CView* view, IdStringPtr name, float pos)
|
|
{
|
|
CRect r;
|
|
r.left = (int32_t)(startRect.left + ((newRect.left - startRect.left) * pos));
|
|
r.right = (int32_t)(startRect.right + ((newRect.right - startRect.right) * pos));
|
|
r.top = (int32_t)(startRect.top + ((newRect.top - startRect.top) * pos));
|
|
r.bottom = (int32_t)(startRect.bottom + ((newRect.bottom - startRect.bottom) * pos));
|
|
if (view->getViewSize () != r)
|
|
{
|
|
view->invalid ();
|
|
view->setViewSize (r);
|
|
view->setMouseableArea (view->getViewSize ());
|
|
view->invalid ();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
/** @class ExchangeViewAnimation
|
|
see @ref page_animation Support */
|
|
//-----------------------------------------------------------------------------
|
|
ExchangeViewAnimation::ExchangeViewAnimation (CView* oldView, CView* newView, AnimationStyle style)
|
|
: newView (newView)
|
|
, viewToRemove (oldView)
|
|
, style (style)
|
|
{
|
|
vstgui_assert (newView->isAttached () == false);
|
|
vstgui_assert (viewToRemove->isAttached ());
|
|
|
|
if (auto parent = viewToRemove->getParentView ()->asViewContainer ())
|
|
parent->addView (newView);
|
|
|
|
init ();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
ExchangeViewAnimation::~ExchangeViewAnimation () noexcept
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void ExchangeViewAnimation::updateViewSize (CView* view, const CRect& rect)
|
|
{
|
|
view->invalid ();
|
|
view->setViewSize (rect);
|
|
view->setMouseableArea (rect);
|
|
view->invalid ();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void ExchangeViewAnimation::init ()
|
|
{
|
|
if (style == kAlphaValueFade)
|
|
{
|
|
oldViewAlphaValueStart = viewToRemove->getAlphaValue ();
|
|
newViewAlphaValueEnd = newView->getAlphaValue ();
|
|
newView->setAlphaValue (0.f);
|
|
}
|
|
else
|
|
{
|
|
destinationRect = viewToRemove->getViewSize ();
|
|
switch (style)
|
|
{
|
|
case kAlphaValueFade: break;
|
|
case kPushInFromLeft:
|
|
{
|
|
doPushInFromLeft (0.f);
|
|
break;
|
|
}
|
|
case kPushInFromRight:
|
|
{
|
|
doPushInFromRight (0.f);
|
|
break;
|
|
}
|
|
case kPushInFromTop:
|
|
{
|
|
doPushInFromTop (0.f);
|
|
break;
|
|
}
|
|
case kPushInFromBottom:
|
|
{
|
|
doPushInFromBottom (0.f);
|
|
break;
|
|
}
|
|
case kPushInOutFromLeft:
|
|
{
|
|
doPushInOutFromLeft (0.f);
|
|
break;
|
|
}
|
|
case kPushInOutFromRight:
|
|
{
|
|
doPushInOutFromRight (0.f);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void ExchangeViewAnimation::doAlphaFade (float pos)
|
|
{
|
|
float alpha = oldViewAlphaValueStart - (oldViewAlphaValueStart * pos);
|
|
viewToRemove->setAlphaValue (alpha);
|
|
alpha = newViewAlphaValueEnd * pos;
|
|
newView->setAlphaValue (alpha);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void ExchangeViewAnimation::doPushInFromLeft (float pos)
|
|
{
|
|
CRect viewSize (newView->getViewSize ());
|
|
CCoord leftOrigin = destinationRect.left;
|
|
CCoord offset = viewSize.getWidth () * (1.f - pos);
|
|
viewSize.offset (-viewSize.left, 0);
|
|
viewSize.offset (leftOrigin - offset, 0);
|
|
updateViewSize (newView, viewSize);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void ExchangeViewAnimation::doPushInFromRight (float pos)
|
|
{
|
|
CRect viewSize (newView->getViewSize ());
|
|
CCoord rightOrigin = destinationRect.left + destinationRect.getWidth ();
|
|
CCoord offset = viewSize.getWidth () * pos;
|
|
viewSize.offset (-viewSize.left, 0);
|
|
viewSize.offset (rightOrigin - offset, 0);
|
|
updateViewSize (newView, viewSize);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void ExchangeViewAnimation::doPushInFromTop (float pos)
|
|
{
|
|
CRect viewSize (newView->getViewSize ());
|
|
CCoord topOrigin = destinationRect.top;
|
|
CCoord offset = viewSize.getHeight () * (1.f - pos);
|
|
viewSize.offset (0, -viewSize.top);
|
|
viewSize.offset (0, topOrigin - offset);
|
|
updateViewSize (newView, viewSize);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void ExchangeViewAnimation::doPushInFromBottom (float pos)
|
|
{
|
|
CRect viewSize (newView->getViewSize ());
|
|
CCoord bottomOrigin = destinationRect.top + destinationRect.getHeight ();
|
|
CCoord offset = viewSize.getHeight () * pos;
|
|
viewSize.offset (0, -viewSize.top);
|
|
viewSize.offset (0, bottomOrigin - offset);
|
|
updateViewSize (newView, viewSize);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void ExchangeViewAnimation::doPushInOutFromLeft (float pos)
|
|
{
|
|
CRect viewSize (newView->getViewSize ());
|
|
CCoord offset = viewSize.getWidth () * (1.f - pos);
|
|
viewSize.offset (-viewSize.left, 0);
|
|
viewSize.offset (destinationRect.left - offset, 0);
|
|
updateViewSize (newView, viewSize);
|
|
|
|
offset = viewToRemove->getWidth () * pos;
|
|
viewSize = destinationRect;
|
|
viewSize.offset (offset, 0);
|
|
updateViewSize (viewToRemove, viewSize);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void ExchangeViewAnimation::doPushInOutFromRight (float pos)
|
|
{
|
|
CRect viewSize (newView->getViewSize ());
|
|
CCoord offset = viewSize.getWidth () * pos;
|
|
viewSize.offset (-viewSize.left, 0);
|
|
viewSize.offset ((destinationRect.left + destinationRect.getWidth ()) - offset, 0);
|
|
updateViewSize (newView, viewSize);
|
|
|
|
offset = viewToRemove->getWidth () * pos;
|
|
viewSize = destinationRect;
|
|
viewSize.offset (-offset, 0);
|
|
updateViewSize (viewToRemove, viewSize);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void ExchangeViewAnimation::animationStart (CView* view, IdStringPtr name)
|
|
{
|
|
#if DEBUG
|
|
CViewContainer* parent = viewToRemove->getParentView ()->asViewContainer ();
|
|
vstgui_assert (view == parent);
|
|
#endif
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void ExchangeViewAnimation::animationTick (CView* view, IdStringPtr name, float pos)
|
|
{
|
|
switch (style)
|
|
{
|
|
case kAlphaValueFade:
|
|
{
|
|
doAlphaFade (pos);
|
|
break;
|
|
}
|
|
case kPushInFromLeft:
|
|
{
|
|
doPushInFromLeft (pos);
|
|
break;
|
|
}
|
|
case kPushInFromRight:
|
|
{
|
|
doPushInFromRight (pos);
|
|
break;
|
|
}
|
|
case kPushInFromTop:
|
|
{
|
|
doPushInFromTop (pos);
|
|
break;
|
|
}
|
|
case kPushInFromBottom:
|
|
{
|
|
doPushInFromBottom (pos);
|
|
break;
|
|
}
|
|
case kPushInOutFromLeft:
|
|
{
|
|
doPushInOutFromLeft (pos);
|
|
break;
|
|
}
|
|
case kPushInOutFromRight:
|
|
{
|
|
doPushInOutFromRight (pos);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void ExchangeViewAnimation::animationFinished (CView* view, IdStringPtr name, bool wasCanceled)
|
|
{
|
|
animationTick (nullptr, nullptr, 1.f);
|
|
if (auto viewContainer = viewToRemove->getParentView ()->asViewContainer ())
|
|
{
|
|
viewContainer->removeView (viewToRemove);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
/** @class ControlValueAnimation
|
|
see @ref page_animation Support */
|
|
//-----------------------------------------------------------------------------
|
|
ControlValueAnimation::ControlValueAnimation (float endValue, bool forceEndValueOnFinish)
|
|
: startValue (0.f)
|
|
, endValue (endValue)
|
|
, forceEndValueOnFinish (forceEndValueOnFinish)
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void ControlValueAnimation::animationStart (CView* view, IdStringPtr name)
|
|
{
|
|
auto* control = dynamic_cast<CControl*> (view);
|
|
if (control)
|
|
startValue = control->getValue ();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void ControlValueAnimation::animationTick (CView* view, IdStringPtr name, float pos)
|
|
{
|
|
auto* control = dynamic_cast<CControl*> (view);
|
|
if (control)
|
|
{
|
|
float value = startValue + (endValue - startValue) * pos;
|
|
control->setValue (value);
|
|
if (control->isDirty ())
|
|
control->invalid ();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void ControlValueAnimation::animationFinished (CView* view, IdStringPtr name, bool wasCanceled)
|
|
{
|
|
auto* control = dynamic_cast<CControl*> (view);
|
|
if (control)
|
|
{
|
|
if (!wasCanceled || forceEndValueOnFinish)
|
|
control->setValue (endValue);
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
FuncAnimation::FuncAnimation (StartFunc&& start, TickFunc&& tick, FinishedFunc&& finished)
|
|
: start (std::move (start)), tick (std::move (tick)), finished (std::move (finished))
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
void FuncAnimation::animationStart (CView* view, IdStringPtr name) { start (view, name); }
|
|
|
|
//------------------------------------------------------------------------
|
|
void FuncAnimation::animationTick (CView* view, IdStringPtr name, float pos)
|
|
{
|
|
tick (view, name, pos);
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
void FuncAnimation::animationFinished (CView* view, IdStringPtr name, bool wasCanceled)
|
|
{
|
|
finished (view, name, wasCanceled);
|
|
}
|
|
}} // namespaces
|