922 lines
25 KiB
C++
922 lines
25 KiB
C++
#include "stdafx.h"
|
|
#include "Ctrl.h"
|
|
#include "OldAnimation.h"
|
|
|
|
PRID OldAlphaAnimation::s_pridAlpha = 0;
|
|
PRID OldScaleAnimation::s_pridScale = 0;
|
|
PRID OldRectAnimation::s_pridRect = 0;
|
|
PRID OldRotateAnimation::s_pridRotate = 0;
|
|
|
|
static const GUID guidAlphaAnimation = { 0x41a2e2f2, 0xf262, 0x41ae, { 0x89, 0xda, 0xb7, 0x9c, 0x8f, 0xf5, 0x94, 0xbb } }; // {41A2E2F2-F262-41ae-89DA-B79C8FF594BB}
|
|
static const GUID guidScaleAnimation = { 0xa5b1df84, 0xb9c0, 0x4305, { 0xb9, 0x3a, 0x5b, 0x80, 0x31, 0x86, 0x70, 0x69 } }; // {A5B1DF84-B9C0-4305-B93A-5B8031867069}
|
|
static const GUID guidRectAnimation = { 0x8e41c241, 0x3cdf, 0x432e, { 0xa1, 0xae, 0xf, 0x7b, 0x59, 0xdc, 0x82, 0xb } }; // {8E41C241-3CDF-432e-A1AE-0F7B59DC820B}
|
|
static const GUID guidRotateAnimation = { 0x78f16dd5, 0xa198, 0x4cd2, { 0xb1, 0x78, 0x31, 0x61, 0x3e, 0x32, 0x12, 0x54 } }; // {78F16DD5-A198-4cd2-B178-31613E321254}
|
|
|
|
|
|
const IID * OldAlphaAnimation::s_rgpIID[] =
|
|
{
|
|
&__uuidof(IUnknown),
|
|
&__uuidof(IAnimation),
|
|
NULL
|
|
};
|
|
|
|
const IID * OldScaleAnimation::s_rgpIID[] =
|
|
{
|
|
&__uuidof(IUnknown),
|
|
&__uuidof(IAnimation),
|
|
NULL
|
|
};
|
|
|
|
const IID * OldRectAnimation::s_rgpIID[] =
|
|
{
|
|
&__uuidof(IUnknown),
|
|
&__uuidof(IAnimation),
|
|
NULL
|
|
};
|
|
|
|
const IID * OldRotateAnimation::s_rgpIID[] =
|
|
{
|
|
&__uuidof(IUnknown),
|
|
&__uuidof(IAnimation),
|
|
NULL
|
|
};
|
|
|
|
|
|
/***************************************************************************\
|
|
*****************************************************************************
|
|
*
|
|
* class OldAnimation
|
|
*
|
|
*****************************************************************************
|
|
\***************************************************************************/
|
|
|
|
//------------------------------------------------------------------------------
|
|
OldAnimation::~OldAnimation()
|
|
{
|
|
#if DEBUG_TRACECREATION
|
|
Trace("STOP Animation 0x%p @ %d (%d frames)\n", this, GetTickCount(), m_DEBUG_cUpdates);
|
|
#endif // DEBUG_TRACECREATION
|
|
|
|
|
|
//
|
|
// Ensure proper destruction
|
|
//
|
|
|
|
AssertMsg(m_hact == NULL, "Action should already be destroyed");
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
OldAnimation::Create(
|
|
IN const GUID * pguid,
|
|
IN OUT PRID * pprid,
|
|
IN GANI_DESC * pDesc) // Animation information
|
|
{
|
|
if (pDesc->pipol != NULL) {
|
|
pDesc->pipol->AddRef();
|
|
m_pipol = pDesc->pipol;
|
|
}
|
|
|
|
if (pDesc->pcb != NULL) {
|
|
pDesc->pcb->AddRef();
|
|
m_pcb = pDesc->pcb;
|
|
}
|
|
|
|
GMA_ACTION gma;
|
|
ZeroMemory(&gma, sizeof(gma));
|
|
gma.cbSize = sizeof(gma);
|
|
gma.flDelay = pDesc->act.flDelay;
|
|
gma.flDuration = pDesc->act.flDuration;
|
|
gma.flPeriod = pDesc->act.flPeriod;
|
|
gma.cRepeat = pDesc->act.cRepeat;
|
|
gma.dwPause = pDesc->act.dwPause;
|
|
gma.pfnProc = RawActionProc;
|
|
gma.pvData = this;
|
|
|
|
m_hact = CreateAction(&gma);
|
|
if (m_hact == NULL) {
|
|
return (HRESULT) GetLastError();
|
|
}
|
|
|
|
HRESULT hr = OldExtension::Create(pDesc->hgadChange, pguid, pprid, OldExtension::oAsyncDestroy);
|
|
if (FAILED(hr)) {
|
|
return hr;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void
|
|
OldAnimation::Destroy(BOOL fFinal)
|
|
{
|
|
//
|
|
// Mark that we have already started the destruction process and don't need
|
|
// to start again. We only want to post the destruction message once.
|
|
//
|
|
|
|
if (m_fStartDestroy) {
|
|
return;
|
|
}
|
|
m_fStartDestroy = TRUE;
|
|
|
|
|
|
//
|
|
// Give the derived Animation a chance to cleanup
|
|
//
|
|
// Check that we are still the Animation attached to this Gadget. We need
|
|
// to remove this property immediately. We can not wait for a posted
|
|
// message to be processed because we may need to set it right now if we are
|
|
// creating a new Animation.
|
|
//
|
|
|
|
if (m_hgadSubject != NULL) {
|
|
OnComplete();
|
|
|
|
#if DBG
|
|
OldAnimation * paniExist = static_cast<OldAnimation *> (GetExtension(m_hgadSubject, m_pridListen));
|
|
if (paniExist != NULL) {
|
|
AssertMsg(paniExist == this, "Animations must match");
|
|
}
|
|
#endif // DBG
|
|
|
|
CleanupChangeGadget();
|
|
}
|
|
|
|
|
|
//
|
|
// Destroy the Animation
|
|
//
|
|
|
|
AssertMsg(!fFinal, "Object is already being destructed");
|
|
if (fFinal) {
|
|
OnAsyncDestroy();
|
|
} else {
|
|
PostAsyncDestroy();
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void
|
|
OldAnimation::OnAsyncDestroy()
|
|
{
|
|
AssertMsg(m_fStartDestroy, "Must call Destroy() to start the destruction process.");
|
|
AssertMsg(!m_fProcessing, "Should not be processing when start destruction");
|
|
|
|
AssertMsg(m_hgadSubject == NULL, "Animation should already have detached from Gadget");
|
|
HACTION hact = m_hact;
|
|
|
|
//
|
|
// Notify any callback that the Animation is finished
|
|
//
|
|
|
|
if (m_pcb != NULL) {
|
|
IAnimation * paniI = static_cast<IAnimation *> (this);
|
|
|
|
__try
|
|
{
|
|
m_pcb->OnComplete(paniI, m_time);
|
|
}
|
|
__except(StdExceptionFilter(GetExceptionInformation()))
|
|
{
|
|
ExitProcess(GetExceptionCode());
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Set everything to NULL now.
|
|
//
|
|
|
|
m_hact = NULL;
|
|
OldExtension::DeleteHandle();
|
|
|
|
|
|
//
|
|
// Stop the Action
|
|
//
|
|
|
|
if (hact != NULL) {
|
|
::DeleteHandle(hact);
|
|
hact = NULL;
|
|
}
|
|
|
|
|
|
//
|
|
// Release() our cached interfaces
|
|
//
|
|
|
|
SafeRelease(m_pipol);
|
|
SafeRelease(m_pcb);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
STDMETHODIMP_(void)
|
|
OldAnimation::SetFunction(IInterpolation * pipol)
|
|
{
|
|
AssertReadPtr(pipol);
|
|
|
|
SafeRelease(m_pipol);
|
|
pipol->AddRef();
|
|
m_pipol = pipol;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
STDMETHODIMP_(void)
|
|
OldAnimation::SetTime(IAnimation::ETime time)
|
|
{
|
|
GMA_ACTIONINFO mai;
|
|
|
|
//
|
|
// TODO: Need to save these values from the last time so that they are
|
|
// valid.
|
|
//
|
|
|
|
mai.hact = m_hact;
|
|
mai.pvData = this;
|
|
mai.flDuration = 0.0f;
|
|
|
|
m_time = time;
|
|
switch (time)
|
|
{
|
|
case IAnimation::tComplete:
|
|
// Don't do anything
|
|
return;
|
|
|
|
default:
|
|
case IAnimation::tAbort:
|
|
case IAnimation::tDestroy:
|
|
goto Done;
|
|
|
|
case IAnimation::tEnd:
|
|
mai.flProgress = 1.0f;
|
|
break;
|
|
|
|
case IAnimation::tReset:
|
|
mai.flProgress = 0.0f;
|
|
break;
|
|
}
|
|
|
|
mai.cEvent = 0;
|
|
mai.cPeriods = 0;
|
|
mai.fFinished = FALSE;
|
|
|
|
m_fProcessing = TRUE;
|
|
Action(&mai);
|
|
Assert(m_fProcessing);
|
|
m_fProcessing = FALSE;
|
|
|
|
Done:
|
|
if (m_pcb != NULL) {
|
|
IAnimation * paniI = static_cast<IAnimation *> (this);
|
|
m_pcb->OnSetTime(paniI, time);
|
|
}
|
|
|
|
::DeleteHandle(m_hact);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
STDMETHODIMP_(void)
|
|
OldAnimation::SetCallback(IAnimationCallback * pcb)
|
|
{
|
|
// pcb can be NULL
|
|
|
|
SafeRelease(m_pcb);
|
|
|
|
if (pcb != NULL) {
|
|
pcb->AddRef();
|
|
m_pcb = pcb;
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
OldAnimation::GetInterface(HGADGET hgad, PRID prid, REFIID riid, void ** ppvUnk)
|
|
{
|
|
OldAnimation * paniExist = static_cast<OldAnimation *> (GetExtension(hgad, prid));
|
|
if (paniExist != NULL) {
|
|
if (IsEqualIID(riid, __uuidof(IAnimation))) {
|
|
paniExist->AddRef();
|
|
*ppvUnk = static_cast<IAnimation *> (paniExist);
|
|
return S_OK;
|
|
} else {
|
|
return paniExist->QueryInterface(riid, ppvUnk);
|
|
}
|
|
}
|
|
|
|
return DU_E_NOTFOUND; // This Animation doesn't exist on this Gadget.
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void
|
|
OldAnimation::CleanupChangeGadget()
|
|
{
|
|
Assert(m_hgadSubject != NULL);
|
|
Assert(m_pridListen != 0);
|
|
|
|
Verify(::RemoveGadgetProperty(m_hgadSubject, m_pridListen));
|
|
|
|
m_hgadSubject = NULL;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void CALLBACK
|
|
OldAnimation::RawActionProc(
|
|
IN GMA_ACTIONINFO * pmai)
|
|
{
|
|
OldAnimation * pani = (OldAnimation *) pmai->pvData;
|
|
pani->AddRef();
|
|
Assert(!pani->m_fProcessing);
|
|
|
|
#if DBG
|
|
pani->m_DEBUG_cUpdates++;
|
|
#endif // DBG
|
|
|
|
#if DEBUG_TRACECREATION
|
|
Trace("START RawActionP 0x%p @ %d\n", pani, GetTickCount());
|
|
#endif // DEBUG_TRACECREATION
|
|
|
|
if ((!pani->m_fStartDestroy) && (pani->m_hgadSubject != NULL)) {
|
|
//
|
|
// This ActionProc will be called when the Action is being destroyed, so
|
|
// we only want to invoke the Action under certain circumstances.
|
|
//
|
|
|
|
switch (pani->m_time)
|
|
{
|
|
case tComplete:
|
|
case tEnd:
|
|
case tReset:
|
|
//
|
|
// All of these are valid to complete. If it isn't in this list, we
|
|
// don't want to execute it during a shutdown.
|
|
//
|
|
|
|
pani->m_fProcessing = TRUE;
|
|
pani->Action(pmai);
|
|
Assert(pani->m_fProcessing);
|
|
pani->m_fProcessing = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (pmai->fFinished) {
|
|
pani->m_hact = NULL;
|
|
pani->Destroy(FALSE);
|
|
}
|
|
|
|
#if DEBUG_TRACECREATION
|
|
Trace("STOP RawActionP 0x%p @ %d\n", pani, GetTickCount());
|
|
#endif // DEBUG_TRACECREATION
|
|
|
|
Assert(!pani->m_fProcessing);
|
|
pani->Release();
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void
|
|
OldAnimation::OnRemoveExisting()
|
|
{
|
|
SetTime(IAnimation::tDestroy);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void
|
|
OldAnimation::OnDestroyListener()
|
|
{
|
|
AddRef();
|
|
|
|
if (m_hgadListen != NULL) {
|
|
//
|
|
// TODO: Figure out when this case can actually occur. This means that
|
|
// the MessageGadget was destroyed, but the caller didn't go through
|
|
// OldAnimation::Destroy() to do it.
|
|
//
|
|
|
|
m_hgadListen = NULL;
|
|
Destroy(FALSE);
|
|
}
|
|
VerifyMsg(Release() > 0, "Must still have lock from beginning of function");
|
|
|
|
Release();
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void
|
|
OldAnimation::OnDestroySubject()
|
|
{
|
|
AddRef();
|
|
|
|
if (m_hgadSubject != NULL) {
|
|
CleanupChangeGadget();
|
|
|
|
//
|
|
// The Gadget that we are modifying is being destroyed, so we need
|
|
// to stop animating it.
|
|
//
|
|
|
|
m_time = IAnimation::tDestroy;
|
|
Destroy(FALSE);
|
|
}
|
|
|
|
Release();
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
*****************************************************************************
|
|
*
|
|
* class OldAlphaAnimation
|
|
*
|
|
*****************************************************************************
|
|
\***************************************************************************/
|
|
|
|
//------------------------------------------------------------------------------
|
|
OldAlphaAnimation::~OldAlphaAnimation()
|
|
{
|
|
Destroy(TRUE);
|
|
|
|
#if DEBUG_TRACECREATION
|
|
Trace("OldAlphaAnimation 0x%p destroyed\n", this);
|
|
#endif // DEBUG_TRACECREATION
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
OldAlphaAnimation::Create(
|
|
IN GANI_DESC * pDesc)
|
|
{
|
|
HRESULT hr = OldAnimation::Create(&guidAlphaAnimation, &s_pridAlpha, pDesc);
|
|
if (FAILED(hr)) {
|
|
return hr;
|
|
}
|
|
|
|
|
|
//
|
|
// Get the information from the Gadget
|
|
//
|
|
|
|
GANI_ALPHADESC * pDescA = (GANI_ALPHADESC *) pDesc;
|
|
m_nOnComplete = pDescA->nOnComplete;
|
|
m_fPushToChildren = pDescA->fPushToChildren &&
|
|
(::GetGadget(m_hgadSubject, GG_TOPCHILD) != NULL);
|
|
|
|
BOOL fBuffered = TestFlag(::GetGadgetStyle(m_hgadSubject), GS_BUFFERED);
|
|
|
|
if (TestFlag(pDesc->nAniFlags, ANIF_USESTART)) {
|
|
m_flStart = pDescA->flStart;
|
|
} else {
|
|
if (fBuffered) {
|
|
//
|
|
// Gadget is already buffered, so use it current alpha value.
|
|
//
|
|
|
|
BUFFER_INFO bi;
|
|
ZeroMemory(&bi, sizeof(bi));
|
|
bi.cbSize = sizeof(bi);
|
|
bi.nMask = GBIM_ALPHA;
|
|
if (::GetGadgetBufferInfo(m_hgadSubject, &bi)) {
|
|
m_flStart = ((float) bi.bAlpha) / 255.0f;
|
|
} else {
|
|
m_flStart = 1.0f;
|
|
}
|
|
} else {
|
|
m_flStart = 1.0f;
|
|
}
|
|
}
|
|
|
|
if (m_fPushToChildren) {
|
|
//
|
|
// If we are currently alpha blended, we need to turn this off.
|
|
//
|
|
|
|
if (fBuffered) {
|
|
::SetGadgetStyle(m_hgadSubject, 0, GS_BUFFERED);
|
|
::SetGadgetStyle(m_hgadSubject, 0, GS_OPAQUE);
|
|
}
|
|
|
|
|
|
//
|
|
// Setup each direct child to be buffered for the alpha-blending
|
|
//
|
|
|
|
BYTE bAlpha = (BYTE) (m_flStart * 255.0f);
|
|
|
|
HGADGET hgadChild = ::GetGadget(m_hgadSubject, GG_TOPCHILD);
|
|
while (hgadChild != NULL) {
|
|
if (!::SetGadgetStyle(hgadChild, GS_BUFFERED | GS_OPAQUE, GS_BUFFERED | GS_OPAQUE)) {
|
|
return (HRESULT) GetLastError();
|
|
}
|
|
|
|
BUFFER_INFO bi;
|
|
bi.cbSize = sizeof(bi);
|
|
bi.nMask = GBIM_ALPHA;
|
|
bi.bAlpha = bAlpha;
|
|
if (!SetGadgetBufferInfo(hgadChild, &bi)) {
|
|
return (HRESULT) GetLastError();
|
|
}
|
|
|
|
hgadChild = ::GetGadget(hgadChild, GG_NEXT);
|
|
}
|
|
} else if (!fBuffered) {
|
|
//
|
|
// Need to mark the Gadget as being buffered to perform alpha effects
|
|
//
|
|
|
|
if (!::SetGadgetStyle(m_hgadSubject, GS_BUFFERED | GS_OPAQUE, GS_BUFFERED | GS_OPAQUE)) {
|
|
return (HRESULT) GetLastError();
|
|
}
|
|
}
|
|
|
|
m_flEnd = pDescA->flEnd;
|
|
|
|
#if DEBUG_TRACECREATION
|
|
Trace("OldAlphaAnimation 0x%p on 0x%p initialized\n", m_hgadSubject, this);
|
|
#endif // DEBUG_TRACECREATION
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
STDMETHODIMP_(UINT)
|
|
OldAlphaAnimation::GetID() const
|
|
{
|
|
return ANIMATION_ALPHA;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void
|
|
OldAlphaAnimation::Action(GMA_ACTIONINFO * pmai)
|
|
{
|
|
float flPr = pmai->flProgress;
|
|
float flAlpha = m_pipol->Compute(flPr, m_flStart, m_flEnd);
|
|
|
|
BYTE bAlpha;
|
|
if (flAlpha < 0.0f) {
|
|
bAlpha = (BYTE) 0;
|
|
} else if (flAlpha > 1.0f) {
|
|
bAlpha = (BYTE) 255;
|
|
} else {
|
|
bAlpha = (BYTE) (flAlpha * 255.0f);
|
|
}
|
|
|
|
BUFFER_INFO bi;
|
|
bi.cbSize = sizeof(bi);
|
|
bi.nMask = GBIM_ALPHA;
|
|
bi.bAlpha = bAlpha;
|
|
|
|
if (m_fPushToChildren) {
|
|
HGADGET hgadChild = ::GetGadget(m_hgadSubject, GG_TOPCHILD);
|
|
while (hgadChild != NULL) {
|
|
SetGadgetStyle(hgadChild, GS_BUFFERED | GS_OPAQUE, GS_BUFFERED | GS_OPAQUE);
|
|
SetGadgetBufferInfo(hgadChild, &bi);
|
|
InvalidateGadget(hgadChild);
|
|
|
|
hgadChild = ::GetGadget(hgadChild, GG_NEXT);
|
|
}
|
|
} else {
|
|
SetGadgetStyle(m_hgadSubject, GS_BUFFERED | GS_OPAQUE, GS_BUFFERED | GS_OPAQUE);
|
|
SetGadgetBufferInfo(m_hgadSubject, &bi);
|
|
InvalidateGadget(m_hgadSubject);
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void
|
|
OldAlphaAnimation::OnComplete()
|
|
{
|
|
if (TestFlag(m_nOnComplete, GANI_ALPHACOMPLETE_OPTIMIZE)) {
|
|
if ((m_flEnd * 255.0f) >= 245) {
|
|
if (m_fPushToChildren) {
|
|
HGADGET hgadChild = ::GetGadget(m_hgadSubject, GG_TOPCHILD);
|
|
while (hgadChild != NULL) {
|
|
SetGadgetStyle(hgadChild, 0, GS_BUFFERED);
|
|
hgadChild = ::GetGadget(hgadChild, GG_NEXT);
|
|
}
|
|
} else {
|
|
SetGadgetStyle(m_hgadSubject, 0, GS_BUFFERED);
|
|
}
|
|
InvalidateGadget(m_hgadSubject);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
*****************************************************************************
|
|
*
|
|
* class OldScaleAnimation
|
|
*
|
|
*****************************************************************************
|
|
\***************************************************************************/
|
|
|
|
//------------------------------------------------------------------------------
|
|
OldScaleAnimation::~OldScaleAnimation()
|
|
{
|
|
Destroy(TRUE);
|
|
|
|
#if DEBUG_TRACECREATION
|
|
Trace("OldScaleAnimation 0x%p destroyed\n", this);
|
|
#endif // DEBUG_TRACECREATION
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
OldScaleAnimation::Create(
|
|
IN GANI_DESC * pDesc)
|
|
{
|
|
HRESULT hr = OldAnimation::Create(&guidScaleAnimation, &s_pridScale, pDesc);
|
|
if (FAILED(hr)) {
|
|
return hr;
|
|
}
|
|
|
|
|
|
//
|
|
// Get the information from the Gadget
|
|
//
|
|
|
|
GANI_SCALEDESC * pDescS = (GANI_SCALEDESC *) pDesc;
|
|
|
|
if (TestFlag(pDesc->nAniFlags, ANIF_USESTART)) {
|
|
m_flStart = pDescS->flStart;
|
|
} else {
|
|
float flX, flY;
|
|
if (!::GetGadgetScale(m_hgadSubject, &flX, &flY)) {
|
|
return (HRESULT) GetLastError();
|
|
}
|
|
|
|
m_flStart = flX;
|
|
}
|
|
m_flEnd = pDescS->flEnd;
|
|
m_al = pDescS->al;
|
|
|
|
|
|
RECT rcParent;
|
|
::GetGadgetRect(m_hgadSubject, &rcParent, SGR_PARENT);
|
|
m_ptStart.x = rcParent.left;
|
|
m_ptStart.y = rcParent.top;
|
|
m_sizeCtrl.cx = rcParent.right - rcParent.left;
|
|
m_sizeCtrl.cy = rcParent.bottom - rcParent.top;
|
|
|
|
#if DEBUG_TRACECREATION
|
|
Trace("OldScaleAnimation 0x%p on 0x%p initialized\n", m_hgadSubject, this);
|
|
#endif // DEBUG_TRACECREATION
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
STDMETHODIMP_(UINT)
|
|
OldScaleAnimation::GetID() const
|
|
{
|
|
return ANIMATION_SCALE;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void
|
|
OldScaleAnimation::Action(GMA_ACTIONINFO * pmai)
|
|
{
|
|
float flPr = pmai->flProgress;
|
|
float flx = m_pipol->Compute(flPr, m_flStart, m_flEnd);
|
|
float fly = flx;
|
|
::SetGadgetScale(m_hgadSubject, flx, fly);
|
|
|
|
POINT ptNew;
|
|
ptNew.x = m_ptStart.x - (int) ((m_sizeCtrl.cx * flx - m_sizeCtrl.cx) / 2.0);
|
|
ptNew.y = m_ptStart.y - (int) ((m_sizeCtrl.cy * fly - m_sizeCtrl.cy) / 2.0);
|
|
::SetGadgetRect(m_hgadSubject, ptNew.x, ptNew.y, 0, 0, SGR_MOVE | SGR_PARENT);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
*****************************************************************************
|
|
*
|
|
* class OldRectAnimation
|
|
*
|
|
*****************************************************************************
|
|
\***************************************************************************/
|
|
|
|
//------------------------------------------------------------------------------
|
|
OldRectAnimation::~OldRectAnimation()
|
|
{
|
|
Destroy(TRUE);
|
|
|
|
#if DEBUG_TRACECREATION
|
|
Trace("OldRectAnimation 0x%p destroyed\n", this);
|
|
#endif // DEBUG_TRACECREATION
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
OldRectAnimation::Create(
|
|
IN GANI_DESC * pDesc)
|
|
{
|
|
HRESULT hr = OldAnimation::Create(&guidRectAnimation, &s_pridRect, pDesc);
|
|
if (FAILED(hr)) {
|
|
return hr;
|
|
}
|
|
|
|
|
|
//
|
|
// Get the information from the Gadget
|
|
//
|
|
|
|
GANI_RECTDESC * pDescR = (GANI_RECTDESC *) pDesc;
|
|
|
|
UINT nGetFlags = SGR_VALID_GET & pDescR->nChangeFlags;
|
|
if (nGetFlags == 0) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
if (TestFlag(pDesc->nAniFlags, ANIF_USESTART)) {
|
|
m_ptStart = pDescR->ptStart;
|
|
m_sizeStart = pDescR->sizeStart;
|
|
} else {
|
|
RECT rcGadget;
|
|
if (!::GetGadgetRect(m_hgadSubject, &rcGadget, nGetFlags)) {
|
|
return (HRESULT) GetLastError();
|
|
}
|
|
|
|
m_ptStart.x = rcGadget.left;
|
|
m_ptStart.y = rcGadget.top;
|
|
m_sizeStart.cx = rcGadget.right - rcGadget.left;
|
|
m_sizeStart.cy = rcGadget.bottom - rcGadget.top;
|
|
}
|
|
|
|
m_ptEnd = pDescR->ptEnd;
|
|
m_sizeEnd = pDescR->sizeEnd;
|
|
m_nChangeFlags = pDescR->nChangeFlags;
|
|
|
|
#if DEBUG_TRACECREATION
|
|
Trace("OldRectAnimation 0x%p on 0x%p initialized\n", m_hgadSubject, this);
|
|
#endif // DEBUG_TRACECREATION
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
STDMETHODIMP_(UINT)
|
|
OldRectAnimation::GetID() const
|
|
{
|
|
return ANIMATION_RECT;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void
|
|
OldRectAnimation::Action(GMA_ACTIONINFO * pmai)
|
|
{
|
|
POINT ptNew;
|
|
SIZE sizeNew;
|
|
float flProgress = pmai->flProgress;
|
|
|
|
ptNew.x = Compute(m_pipol, flProgress, m_ptStart.x, m_ptEnd.x);
|
|
ptNew.y = Compute(m_pipol, flProgress, m_ptStart.y, m_ptEnd.y);
|
|
sizeNew.cx = Compute(m_pipol, flProgress, m_sizeStart.cx, m_sizeEnd.cx);
|
|
sizeNew.cy = Compute(m_pipol, flProgress, m_sizeStart.cy, m_sizeEnd.cy);
|
|
|
|
SetGadgetRect(m_hgadSubject, ptNew.x, ptNew.y, sizeNew.cx, sizeNew.cy, m_nChangeFlags);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
*****************************************************************************
|
|
*
|
|
* class OldRotateAnimation
|
|
*
|
|
*****************************************************************************
|
|
\***************************************************************************/
|
|
|
|
//------------------------------------------------------------------------------
|
|
OldRotateAnimation::~OldRotateAnimation()
|
|
{
|
|
Destroy(TRUE);
|
|
|
|
#if DEBUG_TRACECREATION
|
|
Trace("OldRotateAnimation 0x%p destroyed\n", this);
|
|
#endif // DEBUG_TRACECREATION
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
OldRotateAnimation::Create(
|
|
IN GANI_DESC * pDesc)
|
|
{
|
|
HRESULT hr = OldAnimation::Create(&guidRotateAnimation, &s_pridRotate, pDesc);
|
|
if (FAILED(hr)) {
|
|
return hr;
|
|
}
|
|
|
|
|
|
//
|
|
// Get the information from the Gadget
|
|
//
|
|
|
|
GANI_ROTATEDESC * pDescR = (GANI_ROTATEDESC *) pDesc;
|
|
|
|
if (TestFlag(pDesc->nAniFlags, ANIF_USESTART)) {
|
|
m_flStart = pDescR->flStart;
|
|
} else {
|
|
if (!::GetGadgetRotation(m_hgadSubject, &m_flStart)) {
|
|
return (HRESULT) GetLastError();
|
|
}
|
|
}
|
|
|
|
m_flEnd = pDescR->flEnd;
|
|
m_nDir = pDescR->nDir;
|
|
|
|
|
|
//
|
|
// Adjust the starting and ending angles so that we "move" in the correct
|
|
// direction. We do this by adding or subtracting full rotations depending
|
|
// on the "move" we are trying to accomplish.
|
|
//
|
|
|
|
switch (m_nDir)
|
|
{
|
|
case GANI_ROTATEDIRECTION_SHORT:
|
|
if (m_flStart < m_flEnd) {
|
|
while ((m_flEnd - m_flStart) > (float) PI) {
|
|
m_flStart += (float) (2 * PI);
|
|
}
|
|
} else {
|
|
while ((m_flStart - m_flEnd) > (float) PI) {
|
|
m_flStart -= (float) (2 * PI);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case GANI_ROTATEDIRECTION_LONG:
|
|
if (m_flStart < m_flEnd) {
|
|
while ((m_flStart - m_flEnd) < (float) PI) {
|
|
m_flEnd -= (float) (2 * PI);
|
|
}
|
|
} else {
|
|
while ((m_flEnd - m_flStart) < (float) PI) {
|
|
m_flEnd += (float) (2 * PI);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case GANI_ROTATEDIRECTION_CW:
|
|
while (m_flStart > m_flEnd) {
|
|
m_flEnd += (float) (2 * PI);
|
|
}
|
|
break;
|
|
|
|
case GANI_ROTATEDIRECTION_CCW:
|
|
while (m_flStart < m_flEnd) {
|
|
m_flStart += (float) (2 * PI);
|
|
}
|
|
break;
|
|
}
|
|
|
|
|
|
#if DEBUG_TRACECREATION
|
|
Trace("OldRotateAnimation 0x%p on 0x%p initialized\n", m_hgadSubject, this);
|
|
#endif // DEBUG_TRACECREATION
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
STDMETHODIMP_(UINT)
|
|
OldRotateAnimation::GetID() const
|
|
{
|
|
return ANIMATION_ROTATE;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void
|
|
OldRotateAnimation::Action(GMA_ACTIONINFO * pmai)
|
|
{
|
|
float flProgress = pmai->flProgress;
|
|
float flAngleNew = Compute(m_pipol, flProgress, m_flStart, m_flEnd);
|
|
|
|
SetGadgetRotation(m_hgadSubject, flAngleNew);
|
|
}
|