You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
881 lines
24 KiB
881 lines
24 KiB
#include "stdafx.h"
|
|
#include "Ctrl.h"
|
|
#include "Flow.h"
|
|
|
|
#if ENABLE_MSGTABLE_API
|
|
|
|
PRID DuAlphaFlow::s_pridAlpha = 0;
|
|
PRID DuScaleFlow::s_pridScale = 0;
|
|
PRID DuRectFlow::s_pridRect = 0;
|
|
PRID DuRotateFlow::s_pridRotate = 0;
|
|
|
|
static const GUID guidAlphaFlow = { 0x41a2e2f2, 0xf262, 0x41ae, { 0x89, 0xda, 0xb7, 0x9c, 0x8f, 0xf5, 0x94, 0xbb } }; // {41A2E2F2-F262-41ae-89DA-B79C8FF594BB}
|
|
static const GUID guidScaleFlow = { 0xa5b1df84, 0xb9c0, 0x4305, { 0xb9, 0x3a, 0x5b, 0x80, 0x31, 0x86, 0x70, 0x69 } }; // {A5B1DF84-B9C0-4305-B93A-5B8031867069}
|
|
static const GUID guidRectFlow = { 0x8e41c241, 0x3cdf, 0x432e, { 0xa1, 0xae, 0xf, 0x7b, 0x59, 0xdc, 0x82, 0xb } }; // {8E41C241-3CDF-432e-A1AE-0F7B59DC820B}
|
|
static const GUID guidRotateFlow = { 0x78f16dd5, 0xa198, 0x4cd2, { 0xb1, 0x78, 0x31, 0x61, 0x3e, 0x32, 0x12, 0x54 } }; // {78F16DD5-A198-4cd2-B178-31613E321254}
|
|
|
|
/***************************************************************************\
|
|
*****************************************************************************
|
|
*
|
|
* Public API
|
|
*
|
|
*****************************************************************************
|
|
\***************************************************************************/
|
|
|
|
//------------------------------------------------------------------------------
|
|
PRID
|
|
DUserGetAlphaPRID()
|
|
{
|
|
return DuAlphaFlow::s_pridAlpha;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
PRID
|
|
DUserGetRectPRID()
|
|
{
|
|
return DuRectFlow::s_pridRect;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
PRID
|
|
DUserGetRotatePRID()
|
|
{
|
|
return DuRotateFlow::s_pridRotate;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
PRID
|
|
DUserGetScalePRID()
|
|
{
|
|
return DuScaleFlow::s_pridScale;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
*****************************************************************************
|
|
*
|
|
* class DuFlow
|
|
*
|
|
*****************************************************************************
|
|
\***************************************************************************/
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuFlow::ApiOnReset(Flow::OnResetMsg * pmsg)
|
|
{
|
|
UNREFERENCED_PARAMETER(pmsg);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuFlow::ApiGetKeyFrame(Flow::GetKeyFrameMsg * pmsg)
|
|
{
|
|
UNREFERENCED_PARAMETER(pmsg);
|
|
|
|
PromptInvalid("Derived Flow must override");
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuFlow::ApiSetKeyFrame(Flow::SetKeyFrameMsg * pmsg)
|
|
{
|
|
UNREFERENCED_PARAMETER(pmsg);
|
|
|
|
PromptInvalid("Derived Flow must override");
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuFlow::ApiOnAction(Flow::OnActionMsg * pmsg)
|
|
{
|
|
UNREFERENCED_PARAMETER(pmsg);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
*****************************************************************************
|
|
*
|
|
* class DuAlphaFlow
|
|
*
|
|
*****************************************************************************
|
|
\***************************************************************************/
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuAlphaFlow::InitClass()
|
|
{
|
|
s_pridAlpha = RegisterGadgetProperty(&guidAlphaFlow);
|
|
return s_pridAlpha != 0 ? S_OK : (HRESULT) GetLastError();
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuAlphaFlow::PostBuild(
|
|
IN DUser::Gadget::ConstructInfo * pci)
|
|
{
|
|
//
|
|
// Get the information from the Gadget
|
|
//
|
|
|
|
Flow::FlowCI * pDesc = static_cast<Flow::FlowCI *>(pci);
|
|
Visual * pgvSubject = pDesc->pgvSubject;
|
|
if (pgvSubject != NULL) {
|
|
//
|
|
// Given a subject, so setup from current attributes
|
|
//
|
|
|
|
UINT nStyle = 0;
|
|
pgvSubject->GetStyle(&nStyle);
|
|
|
|
if (!TestFlag(nStyle, GS_OPAQUE)) {
|
|
PromptInvalid("AlphaFlow requires GS_OPAQUE");
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
float flAlpha = 1.0f;
|
|
if (TestFlag(nStyle, GS_BUFFERED)) {
|
|
//
|
|
// 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;
|
|
HRESULT hr = pgvSubject->GetBufferInfo(&bi);
|
|
if (SUCCEEDED(hr)) {
|
|
flAlpha = ((float) bi.bAlpha) / 255.0f;
|
|
}
|
|
}
|
|
|
|
m_flStart = flAlpha;
|
|
m_flEnd = flAlpha;
|
|
} else {
|
|
//
|
|
// No subject, so use some reasonable defaults
|
|
//
|
|
|
|
m_flStart = 1.0f;
|
|
m_flEnd = 1.0f;
|
|
}
|
|
|
|
#if DEBUG_TRACECREATION
|
|
Trace("DuAlphaFlow 0x%p on 0x%p initialized\n", pgvSubject, this);
|
|
#endif // DEBUG_TRACECREATION
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuAlphaFlow::ApiGetKeyFrame(Flow::GetKeyFrameMsg * pmsg)
|
|
{
|
|
if (pmsg->pkf->cbSize != sizeof(AlphaFlow::AlphaKeyFrame)) {
|
|
PromptInvalid("Incorrect keyframe size");
|
|
return E_INVALIDARG;
|
|
}
|
|
AlphaFlow::AlphaKeyFrame * pkfA = static_cast<AlphaFlow::AlphaKeyFrame *>(pmsg->pkf);
|
|
|
|
switch (pmsg->time)
|
|
{
|
|
case Flow::tBegin:
|
|
pkfA->flAlpha = m_flStart;
|
|
return S_OK;
|
|
|
|
case Flow::tEnd:
|
|
pkfA->flAlpha = m_flEnd;
|
|
return S_OK;
|
|
|
|
default:
|
|
PromptInvalid("Invalid time");
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuAlphaFlow::ApiSetKeyFrame(Flow::SetKeyFrameMsg * pmsg)
|
|
{
|
|
if (pmsg->pkf->cbSize != sizeof(AlphaFlow::AlphaKeyFrame)) {
|
|
PromptInvalid("Incorrect keyframe size");
|
|
return E_INVALIDARG;
|
|
}
|
|
const AlphaFlow::AlphaKeyFrame * pkfA = static_cast<const AlphaFlow::AlphaKeyFrame *>(pmsg->pkf);
|
|
|
|
float flAlpha = BoxAlpha(pkfA->flAlpha);
|
|
|
|
switch (pmsg->time)
|
|
{
|
|
case Flow::tBegin:
|
|
m_flStart = flAlpha;
|
|
return S_OK;
|
|
|
|
case Flow::tEnd:
|
|
m_flEnd = flAlpha;
|
|
return S_OK;
|
|
|
|
default:
|
|
PromptInvalid("Invalid time");
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuAlphaFlow::ApiOnAction(Flow::OnActionMsg * pmsg)
|
|
{
|
|
float flResult = 0.0f;
|
|
pmsg->pipol->Compute(pmsg->flProgress, m_flStart, m_flEnd, &flResult);
|
|
SetVisualAlpha(pmsg->pgvSubject, flResult);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuAlphaFlow::ApiOnReset(Flow::OnResetMsg * pmsg)
|
|
{
|
|
SetVisualAlpha(pmsg->pgvSubject, m_flStart);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void
|
|
DuAlphaFlow::SetVisualAlpha(Visual * pgvSubject, float flAlpha)
|
|
{
|
|
AssertMsg((flAlpha <= 1.0f) && (flAlpha >= 0.0f), "Ensure valid alpha");
|
|
|
|
|
|
//
|
|
// Setup Buffer state
|
|
//
|
|
|
|
BOOL fNewBuffered = (flAlpha * 255.0f) <= 245;
|
|
|
|
UINT nStyle = 0;
|
|
VerifyHR(pgvSubject->GetStyle(&nStyle));
|
|
BOOL fOldBuffered = TestFlag(nStyle, GS_BUFFERED);
|
|
|
|
if ((!fOldBuffered) != (!fNewBuffered)) {
|
|
pgvSubject->SetStyle(fNewBuffered ? GS_BUFFERED : 0, GS_BUFFERED);
|
|
}
|
|
|
|
|
|
//
|
|
// Set Alpha level
|
|
//
|
|
|
|
if (fNewBuffered) {
|
|
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;
|
|
|
|
pgvSubject->SetBufferInfo(&bi);
|
|
}
|
|
pgvSubject->Invalidate();
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
*****************************************************************************
|
|
*
|
|
* class DuRectFlow
|
|
*
|
|
*****************************************************************************
|
|
\***************************************************************************/
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuRectFlow::InitClass()
|
|
{
|
|
s_pridRect = RegisterGadgetProperty(&guidRectFlow);
|
|
return s_pridRect != 0 ? S_OK : (HRESULT) GetLastError();
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuRectFlow::PostBuild(
|
|
IN DUser::Gadget::ConstructInfo * pci)
|
|
{
|
|
//
|
|
// Get the information from the Gadget
|
|
//
|
|
|
|
Flow::FlowCI * pDesc = static_cast<Flow::FlowCI *>(pci);
|
|
Visual * pgvSubject = pDesc->pgvSubject;
|
|
if (pgvSubject != NULL) {
|
|
//
|
|
// Given a subject, so setup from current attributes
|
|
//
|
|
|
|
RECT rcGadget;
|
|
HRESULT hr = pgvSubject->GetRect(SGR_PARENT, &rcGadget);
|
|
if (FAILED(hr)) {
|
|
return hr;
|
|
}
|
|
|
|
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 = m_ptStart;
|
|
m_sizeEnd = m_sizeStart;
|
|
m_nChangeFlags = 0;
|
|
} else {
|
|
//
|
|
// No subject, so use some reasonable defaults
|
|
//
|
|
|
|
AssertMsg((m_ptEnd.x == 0) && (m_ptEnd.y == 0) &&
|
|
(m_sizeEnd.cx == 0) && (m_sizeEnd.cy == 0) && (m_nChangeFlags == 0),
|
|
"Ensure zero-init");
|
|
}
|
|
|
|
#if DEBUG_TRACECREATION
|
|
Trace("DuRectFlow 0x%p on 0x%p initialized\n", pgvSubject, this);
|
|
#endif // DEBUG_TRACECREATION
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuRectFlow::ApiGetKeyFrame(Flow::GetKeyFrameMsg * pmsg)
|
|
{
|
|
if (pmsg->pkf->cbSize != sizeof(RectFlow::RectKeyFrame)) {
|
|
PromptInvalid("Incorrect keyframe size");
|
|
return E_INVALIDARG;
|
|
}
|
|
RectFlow::RectKeyFrame * pkfR = static_cast<RectFlow::RectKeyFrame *>(pmsg->pkf);
|
|
|
|
switch (pmsg->time)
|
|
{
|
|
case Flow::tBegin:
|
|
pkfR->rcPxl.left = m_ptStart.x;
|
|
pkfR->rcPxl.top = m_ptStart.y;
|
|
pkfR->rcPxl.right = m_ptStart.x + m_sizeStart.cx;
|
|
pkfR->rcPxl.bottom = m_ptStart.y + m_sizeStart.cy;
|
|
pkfR->nChangeFlags = m_nChangeFlags;
|
|
return S_OK;
|
|
|
|
case Flow::tEnd:
|
|
pkfR->rcPxl.left = m_ptEnd.x;
|
|
pkfR->rcPxl.top = m_ptEnd.y;
|
|
pkfR->rcPxl.right = m_ptEnd.x + m_sizeEnd.cx;
|
|
pkfR->rcPxl.bottom = m_ptEnd.y + m_sizeEnd.cy;
|
|
pkfR->nChangeFlags = 0;
|
|
return S_OK;
|
|
|
|
default:
|
|
PromptInvalid("Invalid time");
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuRectFlow::ApiSetKeyFrame(Flow::SetKeyFrameMsg * pmsg)
|
|
{
|
|
if (pmsg->pkf->cbSize != sizeof(RectFlow::RectKeyFrame)) {
|
|
PromptInvalid("Incorrect keyframe size");
|
|
return E_INVALIDARG;
|
|
}
|
|
const RectFlow::RectKeyFrame * pkfR = static_cast<const RectFlow::RectKeyFrame *>(pmsg->pkf);
|
|
if ((pkfR->nChangeFlags & SGR_VALID_SET) != pkfR->nChangeFlags) {
|
|
PromptInvalid("Invalid change flags");
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
switch (pmsg->time)
|
|
{
|
|
case Flow::tBegin:
|
|
m_ptStart.x = pkfR->rcPxl.left;
|
|
m_ptStart.y = pkfR->rcPxl.top;
|
|
m_sizeStart.cx = pkfR->rcPxl.right - pkfR->rcPxl.left;
|
|
m_sizeStart.cy = pkfR->rcPxl.bottom - pkfR->rcPxl.top;
|
|
m_nChangeFlags = pkfR->nChangeFlags;
|
|
return S_OK;
|
|
|
|
case Flow::tEnd:
|
|
m_ptEnd.x = pkfR->rcPxl.left;
|
|
m_ptEnd.y = pkfR->rcPxl.top;
|
|
m_sizeEnd.cx = pkfR->rcPxl.right - pkfR->rcPxl.left;
|
|
m_sizeEnd.cy = pkfR->rcPxl.bottom - pkfR->rcPxl.top;
|
|
m_nChangeFlags = pkfR->nChangeFlags;
|
|
return S_OK;
|
|
|
|
default:
|
|
PromptInvalid("Invalid time");
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuRectFlow::ApiOnReset(Flow::OnResetMsg * pmsg)
|
|
{
|
|
if (m_nChangeFlags != 0) {
|
|
pmsg->pgvSubject->SetRect(m_nChangeFlags, m_ptStart.x, m_ptStart.y, m_sizeStart.cx, m_sizeStart.cy);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuRectFlow::ApiOnAction(Flow::OnActionMsg * pmsg)
|
|
{
|
|
if (m_nChangeFlags != 0) {
|
|
POINT ptNew;
|
|
SIZE sizeNew;
|
|
|
|
ptNew.x = Compute(pmsg->pipol, pmsg->flProgress, m_ptStart.x, m_ptEnd.x);
|
|
ptNew.y = Compute(pmsg->pipol, pmsg->flProgress, m_ptStart.y, m_ptEnd.y);
|
|
sizeNew.cx = Compute(pmsg->pipol, pmsg->flProgress, m_sizeStart.cx, m_sizeEnd.cx);
|
|
sizeNew.cy = Compute(pmsg->pipol, pmsg->flProgress, m_sizeStart.cy, m_sizeEnd.cy);
|
|
|
|
pmsg->pgvSubject->SetRect(m_nChangeFlags, ptNew.x, ptNew.y, sizeNew.cx, sizeNew.cy);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
*****************************************************************************
|
|
*
|
|
* class DuRotateFlow
|
|
*
|
|
*****************************************************************************
|
|
\***************************************************************************/
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuRotateFlow::InitClass()
|
|
{
|
|
s_pridRotate = RegisterGadgetProperty(&guidRotateFlow);
|
|
return s_pridRotate != 0 ? S_OK : (HRESULT) GetLastError();
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuRotateFlow::PostBuild(
|
|
IN DUser::Gadget::ConstructInfo * pci)
|
|
{
|
|
//
|
|
// Get the information from the Gadget
|
|
//
|
|
|
|
Flow::FlowCI * pDesc = static_cast<Flow::FlowCI *>(pci);
|
|
Visual * pgvSubject = pDesc->pgvSubject;
|
|
if (pgvSubject != NULL) {
|
|
//
|
|
// Given a subject, so setup from current attributes
|
|
//
|
|
|
|
float flRotation;
|
|
HRESULT hr = pgvSubject->GetRotation(&flRotation);
|
|
if (FAILED(hr)) {
|
|
return hr;
|
|
}
|
|
|
|
m_flRawStart = flRotation;
|
|
m_flRawEnd = flRotation;
|
|
m_flActualStart = flRotation;
|
|
m_flActualEnd = flRotation;
|
|
} else {
|
|
//
|
|
// No subject, so use some reasonable defaults
|
|
//
|
|
|
|
AssertMsg((m_flRawStart == 0.0f) && (m_flRawEnd == 0.0f),
|
|
"Ensure zero-init");
|
|
}
|
|
|
|
m_nDir = RotateFlow::dMin;
|
|
|
|
MarkDirty();
|
|
|
|
#if DEBUG_TRACECREATION
|
|
Trace("DuRotateFlow 0x%p on 0x%p initialized\n", pgvSubject, this);
|
|
#endif // DEBUG_TRACECREATION
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuRotateFlow::ApiGetKeyFrame(Flow::GetKeyFrameMsg * pmsg)
|
|
{
|
|
if (pmsg->pkf->cbSize != sizeof(RotateFlow::RotateKeyFrame)) {
|
|
PromptInvalid("Incorrect keyframe size");
|
|
return E_INVALIDARG;
|
|
}
|
|
RotateFlow::RotateKeyFrame * pkfR = static_cast<RotateFlow::RotateKeyFrame *>(pmsg->pkf);
|
|
|
|
switch (pmsg->time)
|
|
{
|
|
case Flow::tBegin:
|
|
pkfR->flRotation = m_flRawStart;
|
|
pkfR->nDir = m_nDir;
|
|
return S_OK;
|
|
|
|
case Flow::tEnd:
|
|
pkfR->flRotation = m_flRawEnd;
|
|
pkfR->nDir = m_nDir;
|
|
return S_OK;
|
|
|
|
default:
|
|
PromptInvalid("Invalid time");
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuRotateFlow::ApiSetKeyFrame(Flow::SetKeyFrameMsg * pmsg)
|
|
{
|
|
if (pmsg->pkf->cbSize != sizeof(RotateFlow::RotateKeyFrame)) {
|
|
PromptInvalid("Incorrect keyframe size");
|
|
return E_INVALIDARG;
|
|
}
|
|
const RotateFlow::RotateKeyFrame * pkfR = static_cast<const RotateFlow::RotateKeyFrame *>(pmsg->pkf);
|
|
|
|
switch (pmsg->time)
|
|
{
|
|
case Flow::tBegin:
|
|
m_flRawStart = pkfR->flRotation;
|
|
m_nDir = pkfR->nDir;
|
|
MarkDirty();
|
|
return S_OK;
|
|
|
|
case Flow::tEnd:
|
|
m_flRawEnd = pkfR->flRotation;
|
|
m_nDir = pkfR->nDir;
|
|
MarkDirty();
|
|
return S_OK;
|
|
|
|
default:
|
|
PromptInvalid("Invalid time");
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuRotateFlow::ApiOnReset(Flow::OnResetMsg * pmsg)
|
|
{
|
|
ComputeAngles();
|
|
|
|
pmsg->pgvSubject->SetRotation(m_flActualStart);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuRotateFlow::ApiOnAction(Flow::OnActionMsg * pmsg)
|
|
{
|
|
ComputeAngles();
|
|
|
|
pmsg->pgvSubject->SetRotation(Compute(pmsg->pipol, pmsg->flProgress, m_flActualStart, m_flActualEnd));
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
*
|
|
* DuRotateFlow::ComputeAngles
|
|
*
|
|
* ComputeAngles() updates the angles to conform to the desired direction.
|
|
* This is lazily computed, allowing the application to specify the angles
|
|
* and direction in any order, then snapping the angles when actually needed.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
void
|
|
DuRotateFlow::ComputeAngles()
|
|
{
|
|
if (!m_fDirty) {
|
|
return;
|
|
}
|
|
|
|
|
|
//
|
|
// 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.
|
|
//
|
|
|
|
m_flActualStart = m_flRawStart;
|
|
m_flActualEnd = m_flRawEnd;
|
|
|
|
switch (m_nDir)
|
|
{
|
|
case RotateFlow::dShort:
|
|
if (m_flActualStart < m_flActualEnd) {
|
|
while ((m_flActualEnd - m_flActualStart) > (float) PI) {
|
|
m_flActualStart += (float) (2 * PI);
|
|
}
|
|
} else {
|
|
while ((m_flActualStart - m_flActualEnd) > (float) PI) {
|
|
m_flActualStart -= (float) (2 * PI);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case RotateFlow::dLong:
|
|
if (m_flActualStart < m_flActualEnd) {
|
|
while ((m_flActualStart - m_flActualEnd) < (float) PI) {
|
|
m_flActualEnd -= (float) (2 * PI);
|
|
}
|
|
} else {
|
|
while ((m_flActualEnd - m_flActualStart) < (float) PI) {
|
|
m_flActualEnd += (float) (2 * PI);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case RotateFlow::dCW:
|
|
while (m_flActualStart > m_flActualEnd) {
|
|
m_flActualEnd += (float) (2 * PI);
|
|
}
|
|
break;
|
|
|
|
case RotateFlow::dCCW:
|
|
while (m_flActualStart < m_flActualEnd) {
|
|
m_flActualStart += (float) (2 * PI);
|
|
}
|
|
break;
|
|
}
|
|
|
|
m_fDirty = FALSE;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
*****************************************************************************
|
|
*
|
|
* class DuScaleFlow
|
|
*
|
|
*****************************************************************************
|
|
\***************************************************************************/
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuScaleFlow::InitClass()
|
|
{
|
|
s_pridScale = RegisterGadgetProperty(&guidScaleFlow);
|
|
return s_pridScale != 0 ? S_OK : (HRESULT) GetLastError();
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuScaleFlow::PostBuild(
|
|
IN DUser::Gadget::ConstructInfo * pci)
|
|
{
|
|
//
|
|
// Get the information from the Gadget
|
|
//
|
|
|
|
Flow::FlowCI * pDesc = static_cast<Flow::FlowCI *>(pci);
|
|
Visual * pgvSubject = pDesc->pgvSubject;
|
|
if (pgvSubject != NULL) {
|
|
//
|
|
// Given a subject, so setup from current attributes
|
|
//
|
|
|
|
float flX, flY;
|
|
HRESULT hr = pgvSubject->GetScale(&flX, &flY);
|
|
if (FAILED(hr)) {
|
|
return hr;
|
|
}
|
|
|
|
m_flStart = flX;
|
|
m_flEnd = flX;
|
|
} else {
|
|
//
|
|
// No subject, so use some reasonable defaults
|
|
//
|
|
|
|
m_flStart = 1.0f;
|
|
m_flEnd = 1.0f;
|
|
}
|
|
|
|
|
|
#if DEBUG_TRACECREATION
|
|
Trace("DuScaleFlow 0x%p on 0x%p initialized\n", pgvSubject, this);
|
|
#endif // DEBUG_TRACECREATION
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuScaleFlow::ApiGetKeyFrame(Flow::GetKeyFrameMsg * pmsg)
|
|
{
|
|
if (pmsg->pkf->cbSize != sizeof(ScaleFlow::ScaleKeyFrame)) {
|
|
PromptInvalid("Incorrect keyframe size");
|
|
return E_INVALIDARG;
|
|
}
|
|
ScaleFlow::ScaleKeyFrame * pkfS = static_cast<ScaleFlow::ScaleKeyFrame *>(pmsg->pkf);
|
|
|
|
switch (pmsg->time)
|
|
{
|
|
case Flow::tBegin:
|
|
pkfS->flScale = m_flStart;
|
|
return S_OK;
|
|
|
|
case Flow::tEnd:
|
|
pkfS->flScale = m_flEnd;
|
|
return S_OK;
|
|
|
|
default:
|
|
PromptInvalid("Invalid time");
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuScaleFlow::ApiSetKeyFrame(Flow::SetKeyFrameMsg * pmsg)
|
|
{
|
|
if (pmsg->pkf->cbSize != sizeof(ScaleFlow::ScaleKeyFrame)) {
|
|
PromptInvalid("Incorrect keyframe size");
|
|
return E_INVALIDARG;
|
|
}
|
|
const ScaleFlow::ScaleKeyFrame * pkfS = static_cast<const ScaleFlow::ScaleKeyFrame *>(pmsg->pkf);
|
|
|
|
switch (pmsg->time)
|
|
{
|
|
case Flow::tBegin:
|
|
m_flStart = pkfS->flScale;
|
|
return S_OK;
|
|
|
|
case Flow::tEnd:
|
|
m_flEnd = pkfS->flScale;
|
|
return S_OK;
|
|
|
|
default:
|
|
PromptInvalid("Invalid time");
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuScaleFlow::ApiOnReset(Flow::OnResetMsg * pmsg)
|
|
{
|
|
pmsg->pgvSubject->SetScale(m_flStart, m_flStart);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
HRESULT
|
|
DuScaleFlow::ApiOnAction(Flow::OnActionMsg * pmsg)
|
|
{
|
|
float flx = Compute(pmsg->pipol, pmsg->flProgress, m_flStart, m_flEnd);
|
|
float fly = flx;
|
|
pmsg->pgvSubject->SetScale(flx, fly);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
#else // ENABLE_MSGTABLE_API
|
|
|
|
|
|
/***************************************************************************\
|
|
*****************************************************************************
|
|
*
|
|
* Public API
|
|
*
|
|
*****************************************************************************
|
|
\***************************************************************************/
|
|
|
|
//------------------------------------------------------------------------------
|
|
PRID
|
|
DUserGetAlphaPRID()
|
|
{
|
|
PromptInvalid("Not implemented without MsgTable support");
|
|
return 0;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
PRID
|
|
DUserGetRectPRID()
|
|
{
|
|
PromptInvalid("Not implemented without MsgTable support");
|
|
return 0;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
PRID
|
|
DUserGetRotatePRID()
|
|
{
|
|
PromptInvalid("Not implemented without MsgTable support");
|
|
return 0;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
PRID
|
|
DUserGetScalePRID()
|
|
{
|
|
PromptInvalid("Not implemented without MsgTable support");
|
|
return 0;
|
|
}
|
|
|
|
|
|
#endif // ENABLE_MSGTABLE_API
|