// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#pragma once
#include "afxanimationhelper.h"
#include "afxtempl.h"
#include <__atlmfc_core.h>
#pragma warning(push)
#pragma warning(disable : _ATLMFC_DISABLED_WARNINGS)
#ifdef _AFX_MINREBUILD
#pragma component(minrebuild, off)
#endif
#ifdef _AFX_PACKING
#pragma pack(push, _AFX_PACKING)
#endif
class CBaseKeyFrame;
class CAnimationVariable;
///
/// Represents a basic transition.
///
///
/// This class encapsulates IUIAnimationTransition interface and serves as a base class for all transitions.
///
class CBaseTransition : public CObject
{
DECLARE_DYNAMIC(CBaseTransition);
public:
///
/// Defines the transition types currently supported by the MFC implementation of Windows Animation API.
///
///
/// A transition type is set in the constructor of specific transition.
/// For example, CSinusoidalTransitionFromRange sets its type to SINUSOIDAL_FROM_RANGE.
///
enum TRANSITION_TYPE
{
UNKNOWN,
ACCELERATE_DECELERATE,
CONSTANT,
CUBIC,
DISCRETE,
INSTANTENEOUS,
LINEAR,
LINEAR_FROM_SPEED,
SMOOTH_STOP,
PARABOLIC_FROM_ACCELERATION,
REVERSAL,
SINUSOIDAL_FROM_RANGE,
SINUSOIDAL_FROM_VELOCITY,
CUSTOM
};
public:
///
/// Constructs a base transition object.
///
CBaseTransition() : m_type(CBaseTransition::UNKNOWN), m_pStartKeyframe(NULL), m_pEndKeyframe(NULL),
m_pRelatedVariable(NULL), m_bAdded(FALSE)
{
}
///
/// The destructor. Called when a transition object is being destroyed.
///
virtual ~CBaseTransition()
{
}
///
/// Releases encapsulated IUIAnimationTransition COM object.
///
///
/// This method should be called from a derived class's Create method in order to prevent
/// IUITransition interface leak.
///
void Clear()
{
if (m_transition != NULL)
{
m_transition.Detach()->Release();
}
}
///
/// Returns transition type.
///
///
/// One of TRANSITION_TYPE enumerated values.
///
///
/// This method can be used to identify a transition object by its type.
/// The type is set in a constructor in a derived class.
///
TRANSITION_TYPE GetType() const {return m_type;}
///
/// Creates a COM transition.
///
///
/// TRUE if a transition COM object was created successfully; otherwise FALSE.
///
///
/// This is a pure virtual function that must be overridden in a derived class.
/// It's called by the framework to instantiate the underlying COM transition object.
///
/// A pointer to transition library, which creates standard transitions. It can be NULL for custom transitions.
/// A pointer to transition factory, which creates custom transitions. It can be NULL for standard transitions.
virtual BOOL Create(IUIAnimationTransitionLibrary* pLibrary, IUIAnimationTransitionFactory* pFactory) = 0;
///
/// Returns a pointer to underlying COM transition object.
///
///
/// A valid pointer to IUIAnimationTransition or NULL if underlying transition can't be created.
///
///
/// This method returns a pointer to underlying COM transition object and creates it if necessary.
///
/// A pointer to transition library, which creates standard transitions. It can be NULL for custom transitions.
/// A pointer to transition factory, which creates custom transitions. It can be NULL for standard transitions.
IUIAnimationTransition* GetTransition(IUIAnimationTransitionLibrary* pLibrary, IUIAnimationTransitionFactory* pFactory);
///
/// Returns a pointer to underlying COM transition object.
///
///
/// A valid pointer to IUIAnimationTransition or NULL if underlying transition can't be created.
///
///
/// It's an accessor method to underlying COM transition object. It doesn't instantiates the underlying IUIAnimationTransition COM
/// object if it wasn't created.
///
IUIAnimationTransition* GetTransition()
{
return m_transition;
}
///
/// Sets keyframes for a transition.
///
///
/// This method tells the transition to start after specified keyframe and, optionally, if pEnd is not NULL, end
/// before the specified keyframe.
/// If the transition was created with a duration parameter specified, that duration is overwritten with the duration of time between the start and end keyframes.
///
/// A keyframe that specifies the beginning of the transition.
/// A keyframe that specifies the end of the transition.
void SetKeyframes(CBaseKeyFrame* pStart = NULL, CBaseKeyFrame* pEnd = NULL)
{
m_pStartKeyframe = pStart;
m_pEndKeyframe = pEnd;
}
///
/// Tells whether a transition has been added to a storyboard.
///
///
/// Returns TRUE if a transition has been added to a storyboard, otherwise FALSE.
///
///
/// This flag is set internally when the top level code adds transitions to storyboard.
///
BOOL IsAdded(){return m_bAdded;}
///
/// Returns start keyframe.
///
///
/// A valid pointer to a keyframe, or NULL if a transition should not start after a keyframe.
///
///
/// This method can be used to access a keyframe object that was previously set by SetKeyframes.
/// It's called by top level code when transitions are being added to storyboard.
///
CBaseKeyFrame* GetStartKeyframe() {return m_pStartKeyframe;}
///
/// Returns start keyframe.
///
///
/// A valid pointer to a keyframe, or NULL if a transition should not be inserted between keyframes.
///
///
/// This method can be used to access a keyframe object that was previously set by SetKeyframes.
/// It's called by top level code when transitions are being added to storyboard.
///
CBaseKeyFrame* GetEndKeyframe() {return m_pEndKeyframe;}
///
/// Establishes a relationship between animation variable and transition.
///
///
/// Establishes a relationship between animation variable and transition. A transition can be applied only to one variable.
///
/// A pointer to related animation variable.
void SetRelatedVariable(CAnimationVariable* pVariable)
{
m_pRelatedVariable = pVariable;
}
///
/// Returns a pointer to related variable.
///
///
/// A valid pointer to animation variable, or NULL if an animation variable has not been set by SetRelatedVariable.
///
///
/// This is an accessor to related animation variable.
///
CAnimationVariable* GetRelatedVariable() {return m_pRelatedVariable;}
///
/// Adds a transition to a storyboard.
///
///
/// TRUE, if transition was successfully added to a storyboard.
///
///
/// Applies the transition to the related variable in the storyboard. If this is the first transition
/// applied to this variable in this storyboard, the transition begins at the start of the storyboard.
/// Otherwise, the transition is appended to the transition added most recently to the variable.
///
/// A pointer to storyboard, which will animate the related variable.
BOOL AddToStoryboard(IUIAnimationStoryboard* pStoryboard);
///
/// Adds a transition to a storyboard.
///
///
/// TRUE, if transition was successfully added to a storyboard.
///
///
/// Applies the transition to the related variable in the storyboard. If the start keyframe was specified, the transition
/// begins at that keyframe. If the end keyframe was specified, the transition begins at the start keyframe and
/// and stops at the end keyframe. If the transition was created with a duration parameter specified, that duration is
/// overwritten with the duration of time between the start and end keyframes.
/// If no keyframe was specified, the transition is appended to the transition added most recently to the variable.
///
/// A pointer to storyboard, which will animate the related variable.
BOOL AddToStoryboardAtKeyframes(IUIAnimationStoryboard* pStoryboard);
protected:
///
/// Stores the transition type.
///
TRANSITION_TYPE m_type;
///
/// Stores a pointer to IUIAnimationTransition. NULL if a COM transition object has not been created.
///
ATL::CComPtr m_transition;
///
/// Stores a pointer to the keyframe that specifies the beginning of the transition.
///
CBaseKeyFrame* m_pStartKeyframe;
///
/// Stores a pointer to the keyframe that specifies the end of the transition.
///
CBaseKeyFrame* m_pEndKeyframe;
///
/// A pointer to an animation variable, which is animated with the transition stored in m_transition.
///
CAnimationVariable* m_pRelatedVariable;
///
/// Specifies whether a transition has been added to a storyboard.
///
BOOL m_bAdded;
};
///
/// Implements basic functionality of keyframe.
///
///
/// Encapsulates UI_ANIMATION_KEYFRAME variable. Serves as a base class for any keyframe implementation.
/// A keyframe represents a moment in time within a storyboard and can be used to specify the start and end times of transitions.
/// There are two types of keyframes - keyframes added to storyboard at the specified offset (in time), or keyframes added
/// after specified transition. Because durations of some transitions can't be known before animation starts, the actual values
/// of some keyframes are determined at runtime only.
/// Because keyframes may depend on transitions, which in their turn depend on keyframes, it's important to prevent
/// infinite recursions when building keyframe chains.
///
class CBaseKeyFrame : public CObject
{
DECLARE_DYNAMIC(CBaseKeyFrame);
friend class CAnimationGroup;
protected:
///
/// Represents a Windows Animation API keyframe. When a keyframe is not initialized
/// it is set to the predefined value UI_ANIMATION_KEYFRAME_STORYBOARD_START.
///
UI_ANIMATION_KEYFRAME m_keyframe;
///
/// Specifies whether this keyframe has been added to a storyboard.
///
BOOL m_bAdded;
///
/// Specifies whether this keyframe should be added to storyboard at an offset from
/// another existing keyframe, or at the end of some transition.
///
BOOL m_bIsKeyframeAtOffset;
public:
///
/// Constructs a keyframe object.
///
CBaseKeyFrame() : m_keyframe(UI_ANIMATION_KEYFRAME_STORYBOARD_START), m_bAdded(TRUE)
{
m_keyframe = UI_ANIMATION_KEYFRAME_STORYBOARD_START;
m_bIsKeyframeAtOffset = TRUE;
}
///
/// Returns the underlying keyframe value.
///
///
/// A current keyframe. The default value is UI_ANIMATION_KEYFRAME_STORYBOARD_START.
///
///
/// This is an accessor to the underlying keyframe value.
///
UI_ANIMATION_KEYFRAME GetAnimationKeyframe() const {return m_keyframe;}
///
/// Tells whether a keyframe has been added to storyboard.
///
///
/// TRUE if a keyframe is added to a storyboard; otherwise FALSE.
///
///
/// In the base class IsAdded always returns TRUE, but it's overridden in derived classes.
///
BOOL IsAdded() const {return m_bAdded;}
///
/// Specifies whether the keyframe should be added to storyboard at offset, or after transition.
///
///
/// TRUE if the keyframe should be added to storyboard at some specified offset.
/// FALSE if the keyframe should be added to storyboard after some transition.
///
///
/// Specifies whether the keyframe should be added to storyboard at offset.
/// The offset or transition must be specified in a derived class.
///
BOOL IsKeyframeAtOffset() const {return m_bIsKeyframeAtOffset;}
///
/// Adds a keyframe to storyboard.
///
///
/// TRUE if keyframe was added to storyboard successfully; otherwise FALSE.
///
///
/// This method is called to add a keyframe to storyboard.
///
/// A pointer to a storyboard.
/// If this parameter is TRUE and the keyframe being added depends on some other keyframe or transition, this method tries
/// to add this keyframe or transition to storyboard first.
virtual BOOL AddToStoryboard(IUIAnimationStoryboard* pStoryboard, BOOL bDeepAdd);
};
///
/// Represents an animation keyframe.
///
///
/// This class implements an animation keyframe. A keyframe represents a moment in time within a
/// storyboard and can be used to specify the start and end times of transitions.
/// A keyframe may be based on other keyframe and have an offset (in seconds) from it, or may be based on a transition and
/// represent a moment in time when this transition ends.
///
class CKeyFrame : public CBaseKeyFrame
{
DECLARE_DYNAMIC(CKeyFrame);
protected:
///
/// Stores a pointer to transition that begins at this keyframe.
///
CBaseTransition* m_pTransition;
///
/// Specifies offset of this keyframe from a keyframe stored in m_pExistingKeyFrame.
///
UI_ANIMATION_SECONDS m_offset;
///
/// Stores a pointer to an existing keyframe. This keyframe is added to storyboard with m_offset to the existing keyframe.
///
CBaseKeyFrame* m_pExistingKeyFrame;
public:
///
/// Constructs a keyframe that depends on a transition.
///
///
/// The constructed keyframe will represent a moment in time within a storyboard when the specified transition ends.
///
/// A pointer to a transition.
CKeyFrame(CBaseTransition* pTransition);
///
/// Constructs a keyframe that depends on other keyframe.
///
///
/// The constructed keyframe will represent a moment in time within a storyboard, which has a specified offset from pKeyframe.
///
/// A pointer to keyframe.
/// Offset, in seconds, from keyframe specified by pKeyframe.
CKeyFrame(CBaseKeyFrame* pKeyframe, UI_ANIMATION_SECONDS offset = 0.0);
///
/// Returns a pointer to a transition this keyframe depends on.
///
///
/// A valid pointer to transition, or NULL if this keyframe does not depend on transition.
///
///
/// This is an accessor to a transition this keyframe depends on.
///
CBaseTransition* GetTransition() {return m_pTransition;}
///
/// Returns a pointer to a keyframe this keyframe depends on.
///
///
/// A valid pointer to keyframe, or NULL if this keyframe does not depend on other keyframe.
///
///
/// This is an accessor to a keyframe this keyframe depends on.
///
CBaseKeyFrame* GetExistingKeyframe() {return m_pExistingKeyFrame;}
///
/// Returns an offset from other keyframe.
///
///
/// An offset in seconds from other keyframe.
///
///
/// This method should be called to determine an offset in seconds from other keyframe.
///
UI_ANIMATION_SECONDS GetOffset() {return m_offset;}
///
/// Adds a keyframe to a storyboard.
///
///
/// TRUE, if keyframe was added successfully.
///
///
/// This method adds a keyframe to storyboard. If it depends on other keyframe or transition and bDeepAdd is TRUE,
/// this method tries to add them recursively.
///
/// A pointer to a storyboard.
/// Specifies whether to add keyframe or transition recursively.
BOOL AddToStoryboard(IUIAnimationStoryboard* pStoryboard, BOOL bDeepAdd) override;
///
/// Adds a keyframe to storyboard after transition.
///
///
/// TRUE, if keyframe was added successfully.
///
///
/// This function is called by the framework to add a keyframe to storyboard after transition.
///
/// A pointer to a storyboard.
/// Specifies whether to add a transition recursively.
BOOL AddToStoryboardAfterTransition(IUIAnimationStoryboard* pStoryboard, BOOL bDeepAdd);
///
/// Adds a keyframe to storyboard at offset.
///
///
/// TRUE, if keyframe was added successfully.
///
///
/// This function is called by the framework to add a keyframe to storyboard at offset.
///
/// A pointer to a storyboard.
/// Specifies whether to add a keyframe this keyframe depend on recursively.
virtual BOOL AddToStoryboardAtOffset(IUIAnimationStoryboard* pStoryboard, BOOL bDeepAdd);
};
class CAnimationController;
class CAnimationBaseObject;
///
/// Represents an animation variable.
///
///
/// The CAnimationVariable class encapsulates IUIAnimationVariable COM object. It also holds a list of transitions
/// to be applied to the animation variable in a storyboard. CAnimationVariable objects are embedded to
/// animation objects, which can represent in an application an animated value, point, size, color and rectangle.
///
class CAnimationVariable
{
friend class CAnimationBaseObject;
protected:
///
/// Stores a pointer to IUIAnimationVariable COM object. NULL if the COM object has not been created yet, or if creation failed.
///
ATL::CComPtr m_variable;
///
/// Specifies the default value, which is propagated to IUIAnimationVariable.
///
DOUBLE m_dblDefaultValue;
///
/// Contains a list of transitions that animate this animation variable.
///
CObList m_lstTransitions;
///
/// A pointer to an animation object that encapsulates this animation variable.
///
CAnimationBaseObject* m_pParentObject;
protected:
///
/// Sets the relationship between an animation variable and an animation object.
///
///
/// This method is called internally to establish one-to-one relationship between an animation variable and an animation object that encapsulates it.
///
/// A pointer to an animation object that contains this variable.
void SetParentAnimationObject(CAnimationBaseObject* pParentObject) {m_pParentObject = pParentObject;}
public:
///
/// Constructs an animation variable object.
///
///
/// Constructs an animation variable object and sets its default value. A default value is used when
/// a variable is not animated, or can't be animated.
///
/// Specifies the default value.
CAnimationVariable(DOUBLE dblDefaultValue = 0.0);
///
/// The destructor. Called when a CAnimationVariable object is being destroyed.
///
virtual ~CAnimationVariable();
///
/// Returns the parent animation object.
///
///
/// A pointer to parent animation object, if relationship was established, otherwise NULL.
///
///
/// This method can be called to retrieve a pointer to a parent animation object (a container).
///
CAnimationBaseObject* GetParentAnimationObject() {return m_pParentObject;}
///
/// Returns a pointer to IUIAnimationVariable COM object.
///
///
/// A valid pointer to IUIAnimationVariable COM object, or NULL if animation variable was not created, or can't be created.
///
///
/// Use this function to access the underlying IUIAnimationVariable COM object and call its methods directly if needed.
///
IUIAnimationVariable* GetVariable() {return m_variable;}
///
/// Sets default value and releases IUIAnimationVariable COM object.
///
///
/// Use this method to reset the default value. This method releases the internal IUIAnimationVariable COM object,
/// therefore when animation variable is recreated, the underlying COM object gets the new default value.
/// The default value is returned by GetValue if the COM object representing the animation variable is not created,
/// or if the variable has not been animated.
///
/// Specifies the new default value.
void SetDefaultValue(DOUBLE dblDefaultValue);
///
/// Creates the underlying animation variable COM object.
///
///
/// TRUE if the animation variable was successfully created; otherwise FALSE.
///
///
/// This method creates the underlying animation variable COM object and sets its default value.
///
/// A pointer to animation manager.
virtual BOOL Create(IUIAnimationManager* pManager);
///
/// Creates all transitions to be applied to this animation variable.
///
///
/// TRUE if transitions were created successfully; otherwise FALSE.
///
///
/// This method is called by the framework when it needs to create transitions that have been added
/// to the variable's internal list of transitions.
///
/// A pointer to transition library.
/// A pointer to transition factory.
BOOL CreateTransitions(IUIAnimationTransitionLibrary* pLibrary, IUIAnimationTransitionFactory* pFactory);
///
/// Returns the current value of animation variable.
///
///
/// S_OK if the value was obtained successfully, or underlying animation variable has not been created. Otherwise
/// HRESULT error code.
///
///
/// This method can be called to retrieve the current value of animation variable. If the underlying COM object
/// has not been created, dblValue will contain a default value, when the function returns.
///
/// The current value of the animation variable.
HRESULT GetValue(DOUBLE& dblValue);
///
/// Returns the current value of animation variable.
///
///
/// S_OK if the value was obtained successfully, or underlying animation variable has not been created. Otherwise
/// HRESULT error code.
///
///
/// This method can be called to retrieve the current value of animation variable. If the underlying COM object
/// has not been created, dblValue will contain a default value, when the function returns.
///
/// The current value of the animation variable.
HRESULT GetValue(INT32& nValue);
///
/// Adds a transition.
///
///
/// This method is called to add a transition to the internal list of transitions to be applied to the animation variable.
/// This list should be cleared when an animation has been scheduled.
///
/// A pointer to a transition to add.
void AddTransition(CBaseTransition* pTransition);
///
/// Clears transitions.
///
///
/// This method removes all transitions from the internal list of transitions. If bAutodestroy is TRUE, or
/// m_bAutodestroyTransitions is TRUE, then transitions are deleted. Otherwise the caller should deallocate
/// the transition objects.
///
/// Specifies whether this method should delete transition objects.
void ClearTransitions(BOOL bAutodestroy);
///
/// Adds transitions from the internal list to storyboard.
///
///
/// This method adds transitions from the internal list to storyboard. It's called from the
/// top level code several times to add transitions that do not depend on keyframes and add
/// transitions that depend on keyframes. If the underlying animation variable
/// COM object has not been created, this method creates it at this stage.
///
/// A pointer to parent animation controller.
/// A pointer to storyboard.
/// TRUE, if this method should add transitions that depend on keyframes.
void ApplyTransitions(CAnimationController* pController, IUIAnimationStoryboard* pStoryboard, BOOL bDependOnKeyframes);
///
/// Enables or disables the ValueChanged event.
///
///
/// When ValueChanged event is enabled, the framework calls virtual method CAnimationController::OnAnimationValueChanged.
/// You need to override it in a class derived from CAnimationController in order to process this event. This method is called every time
/// the value of animation variable is changed.
///
/// A pointer to parent controller.
/// TRUE - enable event, FALSE - disable event.
void EnableValueChangedEvent (CAnimationController* pController, BOOL bEnable);
///
/// Enables or disables the IntegerValueChanged event.
///
///
/// When ValueChanged event is enabled, the framework calls virtual method CAnimationController::OnAnimationIntegerValueChanged.
/// You need to override it in a class derived from CAnimationController in order to process this event. This method is called every time
/// the integer value of animation variable is changed.
///
/// A pointer to parent controller.
/// TRUE - enable event, FALSE - disable event.
void EnableIntegerValueChangedEvent (CAnimationController* pController, BOOL bEnable);
///
/// Returns default value.
///
///
/// The default value.
///
///
/// Use this function to obtain default value of animation variable. The default value can be set in constructor or by
/// SetDefaultValue method.
///
DOUBLE GetDefaultValue() const {return m_dblDefaultValue;}
public:
///
/// Specifies whether related transition objects should be deleted.
///
///
/// Set this value to TRUE to force deletion of transition objects when they are being removed from the internal list
/// of transitions. If this value is FALSE the transitions should be deleted by calling application.
/// The list of transitions is always cleared after an animation has been scheduled. The default value is FALSE.
///
BOOL m_bAutodestroyTransitions;
};
///
/// The base class for all animation objects.
///
///
/// This class implements basic methods for all animation objects. An animation object can represent a value, point,
/// size, rectangle or color in an application, as well as any custom entity. Animation objects are stored in animation groups
/// (see CAnimationGroup). Each group can be animated separately and can be treated as an analogue of storyboard.
/// An animation object encapsulates one or more animation variables (see CAnimationVariable), depending on its logical
/// representation. For example, CAnimationRect contains four animation variables - one variable for each side of rectangle.
/// Each animation object class exposes overloaded AddTransition method, which should be used to apply transitions to
/// encapsulated animation variables.
/// An animation object can be identified by Object ID (optionally) and by Group ID. A Group ID is necessary in order
/// to place an animation object to correct group, but if a Group ID is not specified, an object is placed in the default group with ID 0.
/// If you call SetID with different GroupID, an animation object will be moved to another group (a new group is created if necessary).
///
class CAnimationBaseObject : public CObject
{
DECLARE_DYNAMIC(CAnimationBaseObject)
friend class CAnimationController;
protected:
///
/// Specifies the Group ID of the animation object.
///
UINT32 m_nGroupID;
///
/// Specifies the Object ID of the animation object.
///
UINT32 m_nObjectID;
///
/// Stores user-defined data.
///
DWORD_PTR m_dwUserData;
///
/// Specifies whether related transitions should be automatically destroyed.
///
BOOL m_bAutodestroyTransitions;
///
/// A pointer to the parent animation controller.
///
CAnimationController* m_pParentController;
public:
///
/// Constructs an animation object.
///
///
/// Constructs an animation objects and assigns default Object ID (0) and Group ID (0).
///
CAnimationBaseObject();
///
/// Constructs an animation object.
///
///
/// Constructs an animation object with specified Object ID and Group ID.
///
/// Specifies Group ID.
/// Specifies Object ID.
/// User-defined data, which can be associated with animation object and retrieved later at runtime.
CAnimationBaseObject(UINT32 nGroupID, UINT32 nObjectID = (UINT32)-1, DWORD_PTR dwUserData = 0);
///
/// The destructor. Called when an animation object is being destroyed.
///
virtual ~CAnimationBaseObject();
///
/// Creates transitions associated with an animation object.
///
///
/// TRUE if transitions were created successfully; otherwise FALSE.
///
///
/// Loops over list of animation variables encapsulated in a derived animation object and creates transitions
/// associated with each animation variable.
///
BOOL CreateTransitions();
///
/// Sets new IDs.
///
///
/// Allows to change Object ID and Group ID. If the new Group ID differs from the current ID, an animation object
/// is moved to another group (a new group will be created, if necessary).
///
/// Specifies new Object ID.
/// Specifies new Group ID.
void SetID(UINT32 nObjectID, UINT32 nGroupID = 0);
///
/// Sets user-defined data.
///
///
/// Use this method to associate a custom data with an animation object. This data may be retrieved later at runtime by GetUserData.
///
/// Specifies the custom data.
void SetUserData (DWORD_PTR dwUserData)
{
m_dwUserData = dwUserData;
}
///
/// Detaches an animation object from parent animation controller.
///
///
/// This method is used internally.
///
void DetachFromController()
{
m_pParentController = NULL;
}
///
/// Returns current Object ID.
///
///
/// Current Object ID.
///
///
/// Use this method to retrieve Object ID. It's 0 if Object ID has not been set explicitly in constructor or with SetID.
///
UINT32 GetObjectID() const {return m_nObjectID;}
///
/// Returns current Group ID.
///
///
/// Current Group ID.
///
///
/// Use this method to retrieve Group ID. It's 0 if Group ID has not been set explicitly in constructor or with SetID.
///
UINT32 GetGroupID() const {return m_nGroupID;}
///
/// Returns user defined data.
///
///
/// A value of custom data.
///
///
/// Call this method to retrieve the custom data at runtime. The returned value will be 0 if it was not explicitly initialized in constructor or with SetUserData.
///
DWORD_PTR GetUserData() const {return m_dwUserData;}
///
/// Sets a flag that orders to automatically destroy transitions.
///
///
/// Set this flag only if you allocated transition objects using operator new. If for some reason transition
/// objects are allocated on the stack, the auto destroy flag should be FALSE. By default this flag is TRUE.
///
/// Specifies the auto destroy flag.
void SetAutodestroyTransitions(BOOL bValue)
{
m_bAutodestroyTransitions = bValue;
}
///
/// Tells whether related transition are destroyed automatically.
///
///
/// If TRUE, related transitions are destroyed automatically; if FALSE, transition objects should be deallocated by calling application.
///
///
/// By default this flag is TRUE. Set this flag only if you allocated transition on the stack and/or transitions should be deallocated by
/// the calling application.
///
BOOL GetAutodestroyTransitions() const
{
return m_bAutodestroyTransitions;
}
///
/// Adds transitions to storyboard with encapsulated animation variable.
///
///
/// TRUE if transitions were added successfully.
///
///
/// Adds related transitions, that have been added with AddTransition (overloaded methods in derived classes), to storyboard.
///
/// A pointer to a storyboard.
/// With FALSE this method adds only those transitions that do not depend on keyframes.
virtual BOOL ApplyTransitions(IUIAnimationStoryboard* pStoryboard, BOOL bDependOnKeyframes);
///
/// Removes all related transitions.
///
///
/// Removes all related transitions and destroys them if bAutodestroy or m_bAutodestroyTransitions flag is TRUE.
/// Transitions should be destroyed automatically only if they are not allocated on the stack.
/// If the above flags are FALSE, transitions are just removed from the internal list of related transitions.
///
/// Specifies whether to destroy transition objects automatically, or just remove them from the related list.
virtual void ClearTransitions(BOOL bAutodestroy);
///
/// Sets up Value Changed event handler.
///
///
/// If the Value Changed event handler is enabled, you can handle this event in CAnimationController::OnAnimationValueChanged method,
/// which should be overridden in a CAnimationController-derived class. This method is called every time the animation value has changed.
///
/// A pointer to a parent controller.
/// Specifies whether to enable, or disable Value Changed event.
virtual void EnableValueChangedEvent(CAnimationController* pController, BOOL bEnable);
///
/// Sets up Integer Value Changed event handler.
///
///
/// If the Integer Value Changed event handler is enabled, you can handle this event in CAnimationController::OnAnimationIntegerValueChanged method,
/// which should be overridden in a CAnimationController-derived class. This method is called every time the animation integer value has changed.
///
/// A pointer to a parent controller.
/// Specifies whether to enable, or disable Integer Value Changed event.
virtual void EnableIntegerValueChangedEvent(CAnimationController* pController, BOOL bEnable);
///
/// Determines whether an animation object contains a particular animation variable.
///
///
/// TRUE if the animation variable is contained in the animation object; otherwise FALSE.
///
///
/// This method can be used to determine whether an animation variable specified by pVariable is contained
/// within an animation object. An animation object, depending on its type, may contain several animation variables.
/// For example, CAnimationColor contains three variables, one for each color component (red, green and blue). When a
/// value of animation variable has changed, Windows Animation API sends ValueChanged or IntegerValueChanged events (if enabled),
/// and the parameter of this event is a pointer to interface IUIAnimationVariable of animation variable.
/// This method helps to obtain a pointer to animation from a pointer to contained COM object.
///
/// A pointer to animation variable.
virtual BOOL ContainsVariable(IUIAnimationVariable* pVariable);
protected:
///
/// Collects pointers to contained animation variables.
///
///
/// This is a pure virtual method that must be overridden in a derived class.
/// An animation object, depending on its type, contains one or more animation variables. For example, CAnimationPoint
/// contains two variables, for X and Y coordinates respectively. The base class CAnimationBaseObject implements
/// some generic methods, which act on a list of animation variables: ApplyTransitions, ClearTransitions,
/// EnableValueChangedEvent, EnableIntegerValueChangedEvent. These methods call GetAnimationVariableList, which is filled
/// in a derived class with actual animation variables contained in a particular animation object, then loop over the
/// list and perform necessary actions.
/// If you create a custom animation object, you must add to lst all animation variables contained in that object.
///
/// A list that must be filled with animation variables contained in an animation object.
virtual void GetAnimationVariableList(CList& lst) = 0;
///
/// Establishes relationship between animation variables, contained in an animation object, and their container.
///
///
/// This is a helper that can be used to establish relationship between animation variables, contained in an animation object,
/// and their container. It loops over animation variables and sets a back pointer to a parent animation object
/// to each animation variable.
/// In the current implementation the actual relationship is established in CAnimationBaseObject::ApplyTransitions, therefore
/// back pointers are not set until you call CAnimationGroup::Animate.
/// Knowing the relationship may be helpful when you processing events and need to get a parent animation object
/// from CAnimationVariable (use CAnimationVariable::GetParentAnimationObject).
///
virtual void SetParentAnimationObjects();
};
///
/// Implements the functionality of animation object with one value.
///
///
/// The CAnimationValue class encapsulates a single CAnimationVariable object and can represent in applications
/// a single animated value. For example, you can use this class for animated transparency (fade effect), angle (to rotate objects),
/// or for any other case when you need to create an animation depending on a single animated value.
/// To use this class in application, just instantiate an object of this class, add it to animation controller using
/// CAnimationController::AddAnimationObject and call AddTransition for each transition to be applied to the value.
///
class CAnimationValue : public CAnimationBaseObject
{
DECLARE_DYNAMIC(CAnimationValue)
protected:
///
/// The encapsulated animation variable that represents animation value.
///
CAnimationVariable m_value;
public:
///
/// Constructs a CAnimationValue object.
///
///
/// Constructs CAnimationValue object with default properties: default value, Group ID and Object ID are set to 0.
///
CAnimationValue();
///
/// Constructs a CAnimationValue object.
///
///
/// Constructs CAnimationValue object with specified properties.
///
/// Specifies default value.
/// Specifies Group ID.
/// Specifies Object ID.
/// specifies user-defined data.
CAnimationValue(DOUBLE dblDefaultValue, UINT32 nGroupID, UINT32 nObjectID = (UINT32)-1, DWORD_PTR dwUserData = 0);
///
/// Sets default value.
///
///
/// Use this method to set a default value. A default value is returned to application when animation has not been started
/// and/or underlying COM object has not been created. If the underlying COM object encapsulated in CAnimationVarible
/// was already created, this method recreates it, therefore you might need to call EnableValueChanged/EnableIntegerValueChanged
/// methods again.
///
/// Specifies the default value.
void SetDefaultValue(DOUBLE dblDefaultValue)
{
m_value.SetDefaultValue(dblDefaultValue);
}
///
/// Retrieves the current value.
///
///
/// TRUE if the current value was retrieved successfully; otherwise FALSE.
///
///
/// Call this function to retrieve the current value. This implementation calls the encapsulated COM object, and if
/// the call fails, this method returns the default value that was previously set in constructor or with SetDefaultValue.
///
/// Output. When the function returns it contains a current value of animation variable.
BOOL GetValue(DOUBLE& dblValue);
///
/// Retrieves the current value.
///
///
/// TRUE if the current value was retrieved successfully; otherwise FALSE.
///
///
/// Call this function to retrieve the current value. This implementation calls the encapsulated COM object, and if
/// the call fails, this method returns the default value that was previously set in constructor or with SetDefaultValue.
///
/// Output. When the function returns it contains a current value of animation variable.
BOOL GetValue(INT32& nValue);
///
/// Provides conversion between CAnimationValue and DOUBLE.
///
///
/// Current value of Animation Value.
///
///
/// Provides conversion between CAnimationValue and DOUBLE. This method internally calls GetValue and doesn't check for
/// errors. If GetValue fails, the returned value will contain a default value previously set in constructor or with SetDefaultValue.
///
operator DOUBLE()
{
DOUBLE dblVal = 0.;
GetValue(dblVal);
return dblVal;
}
///
/// Provides conversion between CAnimationValue and INT32.
///
///
/// Current value of Animation Value as integer.
///
///
/// Provides conversion between CAnimationValue and INT32. This method internally calls GetValue and doesn't check for
/// errors. If GetValue fails, the returned value will contain a default value previously set in constructor or with SetDefaultValue.
///
operator INT32()
{
INT32 nVal = 0;
GetValue(nVal);
return nVal;
}
///
/// Assigns a DOUBLE value to CAnimationValue.
///
///
/// Assigns a DOUBLE value to CAnimationValue. This value is set as a default value for encapsulated animation variable.
/// If you subscribed this animation object to events (ValueChanged or IntegerValueChanged), you need to re-enable these events.
///
/// Specifies the value to be assigned to Animation Value.
void operator=(DOUBLE dblVal)
{
SetDefaultValue(dblVal);
}
///
/// Assigns an INT32 value to CAnimationValue.
///
///
/// Assigns an INT32 value to CAnimationValue. This value is set as a default value for encapsulated animation variable.
/// If you subscribed this animation object to events (ValueChanged or IntegerValueChanged), you need to re-enable these events.
///
/// Specifies the value to be assigned to Animation Value.
void operator=(INT32 nVal)
{
SetDefaultValue((DOUBLE)nVal);
}
///
/// Provides access to encapsulated animation variable.
///
///
/// A reference to encapsulated animation variable.
///
///
/// Use this method to access the encapsulated animation variable. From CAnimationVariable you get access
/// to underlying IUIAnimationVariable object, whose pointer can be NULL if animation variable has not been created.
///
CAnimationVariable& GetVariable() {return m_value;}
///
/// Adds a transition to be applied to a value.
///
///
/// Call this function to add a transition to internal list of transitions to be applied to an animation variable.
/// When you add transitions, they are not applied immediately and stored in an internal list. Transitions are applied
/// (added to a storyboard for a particular value) when you call CAnimationController::AnimateGroup.
///
/// A pointer to transition object.
void AddTransition(CBaseTransition* pTransition);
protected:
///
/// Puts the encapsulated animation variable into a list.
///
/// When the function returns, it contains a pointer to CAnimationVariable representing the animated value.
void GetAnimationVariableList(CList& lst) override;
};
///
/// Implements the functionality of a point whose coordinates can be animated.
///
///
/// The CAnimationPoint class encapsulates two CAnimationVariable objects and can represent in applications
/// a point. For example, you can use this class to animate a position of any object on the screen (like text string, circle, point etc).
/// To use this class in application, just instantiate an object of this class, add it to animation controller using
/// CAnimationController::AddAnimationObject and call AddTransition for each transition to be applied to X and/or Y coordinates.
///
class CAnimationPoint : public CAnimationBaseObject
{
DECLARE_DYNAMIC(CAnimationPoint)
protected:
///
/// The encapsulated animation variable that represents X coordinate of animation point.
///
CAnimationVariable m_xValue;
///
/// The encapsulated animation variable that represents Y coordinate of animation point.
///
CAnimationVariable m_yValue;
public:
///
/// Constructs CAnimationPoint object.
///
///
/// Constructs CAnimationPoint object with default properties: default point coordinates, Group ID and Object ID are set to 0.
///
CAnimationPoint();
///
/// Constructs CAnimationPoint object.
///
///
/// Constructs CAnimationPoint object with specified properties.
///
/// Specifies default point coordinates.
/// Specifies Group ID.
/// Specifies Object ID.
/// Specifies user-defined data.
CAnimationPoint(const CPoint& ptDefault, UINT32 nGroupID, UINT32 nObjectID = (UINT32)-1, DWORD_PTR dwUserData = 0);
///
/// Sets default value.
///
///
/// Use this function to set a default value to animation object. This methods assigns default values to X and Y
/// coordinates of animation point. It also recreates underlying COM objects if they have been created. If you
/// subscribed this animation object to events (ValueChanged or IntegerValueChanged), you need to re-enable these events.
///
/// Specifies the default point value.
void SetDefaultValue(const POINT& ptDefault);
///
/// Returns the default values for X and Y coordinates.
///
///
/// A point containing default value.
///
///
/// Call this function to retrieve default value, which was previously set by constructor or SetDefaultValue.
///
CPoint GetDefaultValue();
///
/// Returns current value.
///
///
/// TRUE, if the current value was successfully retrieved; otherwise FALSE.
///
///
/// Call this function to retrieve the current value of animation point. If this method fails or underlying COM objects for
/// X and Y coordinates have not been initialized, ptValue contains default
/// value, which was previously set in constructor or by SetDefaultValue.
///
/// Output. Contains the current value when this method returns.
BOOL GetValue(CPoint& ptValue);
///
/// Assigns ptSrc to CAnimationPoint.
///
///
/// Assigns ptSrc to CAnimationPoint. It's recommended to do that before animation start, because this operator calls
/// SetDefaultValue, which recreates the underlying COM objects for X and Y coordinates if they have been created. If you
/// subscribed this animation object to events (ValueChanged or IntegerValueChanged), you need to re-enable these events.
///
/// Refers to CPoint or POINT.
void operator=(const CPoint& ptSrc)
{
SetDefaultValue(ptSrc);
}
///
/// Converts a CAnimationPoint to a CPoint.
///
///
/// Current value of CAnimationPoint as CPoint.
///
///
/// This function internally calls GetValue. If GetValue for some reason fails, the returned point will contain default values for X and Y coordinates.
///
operator CPoint()
{
CPoint pt;
GetValue(pt);
return pt;
}
///
/// Provides access to CAnimationVariable for X coordinate.
///
///
/// A reference to encapsulated CAnimationVariable representing X coordinate.
///
///
/// You can call this method to get direct access to underlying CAnimationVariable representing X coordinate.
///
CAnimationVariable& GetX() {return m_xValue;}
///
/// Provides access to CAnimationVariable for Y coordinate.
///
///
/// A reference to encapsulated CAnimationVariable representing Y coordinate.
///
///
/// You can call this method to get direct access to underlying CAnimationVariable representing Y coordinate.
///
CAnimationVariable& GetY() {return m_yValue;}
///
/// Adds transitions for X and Y coordinates.
///
///
/// Call this function to add the specified transitions to the internal list of transitions to be applied to animation variables for X and Y coordinates.
/// When you add transitions, they are not applied immediately and stored in an internal list. Transitions are applied
/// (added to a storyboard for a particular value) when you call CAnimationController::AnimateGroup.
/// If you don't need to apply a transition to one of coordinates, you can pass NULL.
///
/// A pointer to transition for X coordinates.
/// A pointer to transition for Y coordinate.
void AddTransition(CBaseTransition* pXTransition, CBaseTransition* pYTransition);
protected:
///
/// Puts the encapsulated animation variables into a list.
///
/// When the function returns, it contains pointers to two CAnimationVariable objects
/// representing the X and Y coordinates.
void GetAnimationVariableList(CList& lst) override;
};
///
/// Implements the functionality of a size object whose dimensions can be animated.
///
///
/// The CAnimationSize class encapsulates two CAnimationVariable objects and can represent in applications
/// a size. For example, you can use this class to animate a size of any two dimensional object on the screen (like rectangle, control etc).
/// To use this class in application, just instantiate an object of this class, add it to animation controller using
/// CAnimationController::AddAnimationObject and call AddTransition for each transition to be applied to Width and/or Height.
///
class CAnimationSize : public CAnimationBaseObject
{
DECLARE_DYNAMIC(CAnimationSize)
protected:
///
/// The encapsulated animation variable that represents width of animation size.
///
CAnimationVariable m_cxValue;
///
/// The encapsulated animation variable that represents height of animation size.
///
CAnimationVariable m_cyValue;
public:
///
/// Constructs an animation size object.
///
///
/// The object is constructed with default values for width, height, Object ID and Group ID, which will be set to 0. They can be changed
/// later at runtime using SetDefaultValue and SetID.
///
CAnimationSize();
///
/// Constructs an animation size object.
///
///
/// The object is constructed with specified values for width, height, Object ID and Group ID. They can be changed
/// later at runtime using SetDefaultValue and SetID.
///
/// Specifies default size.
/// Specifies Group ID.
/// Specifies Object ID.
/// Specifies user-defined data.
CAnimationSize(const CSize& szDefault, UINT32 nGroupID, UINT32 nObjectID = (UINT32)-1, DWORD_PTR dwUserData = 0);
///
/// Sets default value.
///
///
/// Use this function to set a default value to animation object. This methods assigns default values to Width and Height
/// of animation size. It also recreates underlying COM objects if they have been created. If you
/// subscribed this animation object to events (ValueChanged or IntegerValueChanged), you need to re-enable these events.
///
/// Specifies new default size.
void SetDefaultValue(const CSize& szDefault);
///
/// Returns the default values for Width and Height.
///
///
/// A CSize object containing default values.
///
///
/// Call this function to retrieve default value, which was previously set by constructor or SetDefaultValue.
///
CSize GetDefaultValue();
///
/// Returns current value.
///
///
/// TRUE, if the current value was successfully retrieved; otherwise FALSE.
///
///
/// Call this function to retrieve the current value of animation size. If this method fails or underlying COM objects for
/// Width and Size have not been initialized, szValue contains default value, which was previously set in constructor or by SetDefaultValue.
///
/// Output. Contains the current value when this method returns.
BOOL GetValue(CSize& szValue);
///
/// Provides access to CAnimationVariable representing Width.
///
///
/// A reference to encapsulated CAnimationVariable representing Width.
///
///
/// You can call this method to get direct access to underlying CAnimationVariable representing Width.
///
CAnimationVariable& GetCX() {return m_cxValue;}
///
/// Provides access to CAnimationVariable representing Height.
///
///
/// A reference to encapsulated CAnimationVariable representing Height.
///
///
/// You can call this method to get direct access to underlying CAnimationVariable representing Height.
///
CAnimationVariable& GetCY() {return m_cyValue;}
///
/// Assigns szSrc to CAnimationSize.
///
///
/// Assigns szSrc to CAnimationSize. It's recommended to do that before animation start, because this operator calls
/// SetDefaultValue, which recreates the underlying COM objects for Width and Height if they have been created. If you
/// subscribed this animation object to events (ValueChanged or IntegerValueChanged), you need to re-enable these events.
///
/// Refers to CSize or SIZE.
void operator=(const CSize& szSrc)
{
SetDefaultValue(szSrc);
}
///
/// Converts a CAnimationSize to a CSize.
///
///
/// Current value of animation size as CSize.
///
///
/// This function internally calls GetValue. If GetValue for some reason fails, the returned size will contain default values for Width and Height.
///
operator CSize()
{
CSize sz;
GetValue(sz);
return sz;
}
///
/// Adds transitions for Width and Height.
///
///
/// Call this function to add the specified transitions to the internal list of transitions to be applied to animation variables for Width and Height.
/// When you add transitions, they are not applied immediately and stored in an internal list. Transitions are applied
/// (added to a storyboard for a particular value) when you call CAnimationController::AnimateGroup.
/// If you don't need to apply a transition to one of dimensions, you can pass NULL.
///
/// A pointer to transition for Width.
/// A pointer to transition for Height.
void AddTransition(CBaseTransition* pCXTransition, CBaseTransition* pCYTransition);
protected:
///
/// Puts the encapsulated animation variables into a list.
///
/// When the function returns, it contains pointers to two CAnimationVariable objects
/// representing the width and height.
void GetAnimationVariableList(CList& lst) override;
};
///
/// Implements the functionality of a color whose red, green and blue components can be animated.
///
///
/// The CAnimationColor class encapsulates three CAnimationVariable objects and can represent in applications
/// a color. For example, you can use this class to animate colors of any object on the screen (like text color, background color etc).
/// To use this class in application, just instantiate an object of this class, add it to animation controller using
/// CAnimationController::AddAnimationObject and call AddTransition for each transition to be applied to Red, Green and Blue components.
///
class CAnimationColor : public CAnimationBaseObject
{
DECLARE_DYNAMIC(CAnimationColor)
protected:
///
/// The encapsulated animation variable that represents Red component of animation color.
///
CAnimationVariable m_rValue;
///
/// The encapsulated animation variable that represents Green component of animation color.
///
CAnimationVariable m_gValue;
///
/// The encapsulated animation variable that represents Blue component of animation color.
///
CAnimationVariable m_bValue;
public:
///
/// Constructs a CAnimationColor object.
///
///
/// The object is constructed with default values for red, green, blue, Object ID and Group ID, which will be set to 0. They can be changed
/// later at runtime using SetDefaultValue and SetID.
///
CAnimationColor();
///
/// Constructs an animation color object.
///
///
/// The object is constructed with specified values for RGB components, Object ID and Group ID. They can be changed
/// later at runtime using SetDefaultValue and SetID.
///
/// Specifies default color.
/// Specifies Group ID.
/// Specifies Object ID.
/// Specifies user-defined data.
CAnimationColor(COLORREF color, UINT32 nGroupID, UINT32 nObjectID = (UINT32)-1, DWORD_PTR dwUserData = 0);
///
/// Sets default value.
///
///
/// Use this function to set a default value to animation object. This methods assigns default values to color components
/// of animation color. It also recreates underlying COM objects if they have been created. If you
/// subscribed this animation object to events (ValueChanged or IntegerValueChanged), you need to re-enable these events.
///
/// Specifies new default values for red, green and blue components.
void SetDefaultValue(COLORREF color);
///
/// Returns the default values for color components.
///
///
/// A COLORREF value containing defaults for RGB components.
///
///
/// Call this function to retrieve default value, which was previously set by constructor or SetDefaultValue.
///
COLORREF GetDefaultValue();
///
/// Returns current value.
///
///
/// TRUE, if the current value was successfully retrieved; otherwise FALSE.
///
///
/// Call this function to retrieve the current value of animation color. If this method fails or underlying COM objects for
/// color components have not been initialized, color contains default value, which was previously set in constructor or by SetDefaultValue.
///
/// Output. Contains the current value when this method returns.
BOOL GetValue(COLORREF& color);
///
/// Provides access to CAnimationVariable representing Red component.
///
///
/// A reference to encapsulated CAnimationVariable representing Red component.
///
///
/// You can call this method to get direct access to underlying CAnimationVariable representing Red component.
///
CAnimationVariable& GetR() {return m_rValue;}
///
/// Provides access to CAnimationVariable representing Green component.
///
///
/// A reference to encapsulated CAnimationVariable representing Green component.
///
///
/// You can call this method to get direct access to underlying CAnimationVariable representing Green component.
///
CAnimationVariable& GetG() {return m_gValue;}
///
/// Provides access to CAnimationVariable representing Blue component.
///
///
/// A reference to encapsulated CAnimationVariable representing Blue component.
///
///
/// You can call this method to get direct access to underlying CAnimationVariable representing Blue component.
///
CAnimationVariable& GetB() {return m_bValue;}
///
/// Assigns color to CAnimationColor.
///
///
/// It's recommended to do that before animation start, because this operator calls
/// SetDefaultValue, which recreates the underlying COM objects for color components if they have been created. If you
/// subscribed this animation object to events (ValueChanged or IntegerValueChanged), you need to re-enable these events.
///
/// Specifies new value Animation Color.
void operator=(COLORREF color)
{
SetDefaultValue(color);
}
///
/// Converts a CAnimationColor to COLORREF.
///
///
/// Current value of animation color object as COLORREF.
///
///
/// This function internally calls GetValue. If GetValue for some reason fails, the returned COLORREF will contain default values for all color components.
///
operator COLORREF()
{
COLORREF color;
GetValue(color);
return color;
}
///
/// Adds transitions for Red, Green and Blue components.
///
///
/// Call this function to add the specified transitions to the internal list of transitions to be applied to animation variables representing color components.
/// When you add transitions, they are not applied immediately and stored in an internal list. Transitions are applied
/// (added to a storyboard for a particular value) when you call CAnimationController::AnimateGroup.
/// If you don't need to apply a transition to one of the color components, you can pass NULL.
///
/// Transition for Red component.
/// Transition for Green component.
/// Transition for Blue component.
void AddTransition(CBaseTransition* pRTransition, CBaseTransition* pGTransition, CBaseTransition* pBTransition);
protected:
///
/// Puts the encapsulated animation variables into a list.
///
/// When the function returns, it contains pointers to three CAnimationVariable objects
/// representing red, green and blue components.
void GetAnimationVariableList(CList& lst) override;
};
///
/// Implements the functionality of a rectangle whose top, left, right and bottom sides can be animated.
///
///
/// The CAnimationRect class encapsulates four CAnimationVariable objects and can represent in applications
/// a rectangle.
/// To use this class in application, just instantiate an object of this class, add it to animation controller using
/// CAnimationController::AddAnimationObject and call AddTransition for each transition to be applied to left, right top and bottom coordinates.
///
class CAnimationRect : public CAnimationBaseObject
{
DECLARE_DYNAMIC(CAnimationRect)
protected:
///
/// The encapsulated animation variable that represents Left bound of animation rectangle.
///
CAnimationVariable m_leftValue;
///
/// The encapsulated animation variable that represents Top bound of animation rectangle.
///
CAnimationVariable m_topValue;
///
/// The encapsulated animation variable that represents Right bound of animation rectangle.
///
CAnimationVariable m_rightValue;
///
/// The encapsulated animation variable that represents Bottom bound of animation rectangle.
///
CAnimationVariable m_bottomValue;
///
/// Specifies initial size of animation rectangle.
///
CSize m_szInitial;
public:
///
/// Constructs a CAnimationRect object.
///
///
/// The object is constructed with default values for left, top, right and bottom, Object ID and Group ID, which will be set to 0. They can be changed
/// later at runtime using SetDefaultValue and SetID.
///
CAnimationRect();
///
/// Constructs an animation rect object.
///
///
/// The object is constructed with specified rect coordinates, Object ID and Group ID. They can be changed
/// later at runtime using SetDefaultValue and SetID.
///
/// Specifies default rectangle.
/// Specifies Group ID.
/// Specifies Object ID.
/// Specifies user-defined data.
CAnimationRect(const CRect& rect, UINT32 nGroupID, UINT32 nObjectID = (UINT32)-1, DWORD_PTR dwUserData = 0);
///
/// Constructs an animation rect object.
///
///
/// The object is constructed with specified top-left corner coordinates and size of rectangle, Object ID and Group ID. They can be changed
/// later at runtime using SetDefaultValue and SetID.
///
/// Coordinate of top-left corner.
/// Size of rectangle.
/// Specifies Group ID.
/// Specifies Object ID.
/// Specifies user-defined data.
CAnimationRect(const CPoint& pt, const CSize& sz, UINT32 nGroupID, UINT32 nObjectID = (UINT32)-1, DWORD_PTR dwUserData = 0);
///
/// Constructs an animation rect object.
///
///
/// The object is constructed with specified coordinates of each side, Object ID and Group ID. They can be changed
/// later at runtime using SetDefaultValue and SetID.
///
/// Specifies coordinate of left bound.
/// Specifies coordinate of top bound.
/// Specifies coordinate of right bound.
/// Specifies coordinate of bottom bound.
/// Specifies Group ID.
/// Specifies Object ID.
/// Specifies user-defined data.
CAnimationRect(int nLeft, int nTop, int nRight, int nBottom, UINT32 nGroupID, UINT32 nObjectID = (UINT32)-1, DWORD_PTR dwUserData = 0);
///
/// Sets default value.
///
///
/// Use this function to set a default value to animation object. This methods assigns default values to rectangle's bounds.
/// It also recreates underlying COM objects if they have been created. If you
/// subscribed this animation object to events (ValueChanged or IntegerValueChanged), you need to re-enable these events.
///
/// Specifies new default values for left, top, right and bottom.
void SetDefaultValue(const CRect& rect);
///
/// Returns the default values for rectangle's bounds.
///
///
/// A CRect value containing defaults for left, right, top and bottom.
///
///
/// Call this function to retrieve default value, which was previously set by constructor or SetDefaultValue.
///
CRect GetDefaultValue();
///
/// Returns current value.
///
///
/// TRUE, if the current value was successfully retrieved; otherwise FALSE.
///
///
/// Call this function to retrieve the current value of animation rectangle. If this method fails or underlying COM objects for
/// left, top, right and bottom have not been initialized, rect contains default value, which was previously set in constructor or by SetDefaultValue.
///
/// Output. Contains the current value when this method returns.
BOOL GetValue(CRect& rect);
///
/// Provides access to CAnimationVariable representing left coordinate.
///
///
/// A reference to encapsulated CAnimationVariable representing left coordinate.
///
///
/// You can call this method to get direct access to underlying CAnimationVariable representing the left coordinate.
///
CAnimationVariable& GetLeft() {return m_leftValue;}
///
/// Provides access to CAnimationVariable representing top coordinate.
///
///
/// A reference to encapsulated CAnimationVariable representing top coordinate.
///
///
/// You can call this method to get direct access to underlying CAnimationVariable representing the top coordinate.
///
CAnimationVariable& GetTop() {return m_topValue;}
///
/// Provides access to CAnimationVariable representing right coordinate.
///
///
/// A reference to encapsulated CAnimationVariable representing right coordinate.
///
///
/// You can call this method to get direct access to underlying CAnimationVariable representing the right coordinate.
///
CAnimationVariable& GetRight() {return m_rightValue;}
///
/// Provides access to CAnimationVariable representing bottom coordinate.
///
///
/// A reference to encapsulated CAnimationVariable representing bottom coordinate.
///
///
/// You can call this method to get direct access to underlying CAnimationVariable representing the bottom coordinate.
///
CAnimationVariable& GetBottom() {return m_bottomValue;}
///
/// Assigns rect to CAnimationRect.
///
///
/// It's recommended to do that before animation start, because this operator calls
/// SetDefaultValue, which recreates the underlying COM objects for color components if they have been created. If you
/// subscribed this animation object to events (ValueChanged or IntegerValueChanged), you need to re-enable these events.
///
/// The new value of animation rectangle.
void operator=(const RECT& rect)
{
SetDefaultValue(rect);
}
///
/// Converts a CAnimationRect to RECT.
///
///
/// Current value of animation rectangle as RECT.
///
///
/// This function internally calls GetValue. If GetValue for some reason fails, the returned RECT will contain default values for all rectangle coordinates.
///
operator RECT()
{
CRect rect;
GetValue(rect);
return rect;
}
///
/// Adds transitions for left, top, right and bottom coordinates.
///
///
/// Call this function to add the specified transitions to the internal list of transitions to be applied to animation variables for each rectangle sides.
/// When you add transitions, they are not applied immediately and stored in an internal list. Transitions are applied
/// (added to a storyboard for a particular value) when you call CAnimationController::AnimateGroup.
/// If you don't need to apply a transition to one of the rectangle sides, you can pass NULL.
///
/// Specifies transition for the left side.
/// Specifies transition for the top side.
/// Specifies transition for the right side.
/// Specifies transition for the bottom side.
void AddTransition(CBaseTransition* pLeftTransition, CBaseTransition* pTopTransition,
CBaseTransition* pRightTransition, CBaseTransition* pBottomTransition);
public:
///
/// Specifies whether the rectangle has fixed size.
///
///
/// If this member is true, then the size of rectangle is fixed and right and bottom values
/// are recalculated each time the top-left corner is moved according to the fixed size.
/// Set this value to TRUE to easily move the rectangle around the screen. In this case transitions applied to
/// right and bottom coordinates are ignored. The size is stored internally when you construct the object and/or
/// call SetDefaultValue. By default this member is set to FALSE.
///
BOOL m_bFixedSize;
protected:
///
/// Puts the encapsulated animation variables into a list.
///
/// When the function returns, it contains pointers to four CAnimationVariable objects
/// representing coordinates of rectangle.
void GetAnimationVariableList(CList& lst) override;
};
///
/// Implements an animation group, which combines an animation storyboard, animation objects and transitions
/// to define an animation.
///
///
/// Animation groups are created automatically by animation controller (CAnimationController) when you add animation
/// objects using CAnimationController::AddAnimationObject.
/// An animation group is identified by GroupID, which is usually taken as a parameter to manipulate animation groups.
/// The GroupID is taken from the first animation object being added to a new animation group.
/// An encapsulated animation storyboard is created after you call CAnimationController::AnimateGroup and can be
/// accessed via public member m_pStoryboard.
///
class CAnimationGroup
{
protected:
///
/// A unique identifier of animation group.
///
UINT32 m_nGroupID;
///
/// A pointer to animation controller this group belongs to.
///
CAnimationController* m_pParentController;
protected:
///
/// A helper that adds keyframes to a storyboard.
///
/// A pointer to a storyboard COM object.
/// Specifies whether this method should add to the storyboard keyframes that depend on other keyframes.
void AddKeyframes(IUIAnimationStoryboard* pStoryboard, BOOL bAddDeep);
///
/// A helper that adds transitions to a storyboard.
///
/// A pointer to a storyboard COM object.
/// Specifies whether this method should add to the storyboard transitions that depend on other keyframes.
void AddTransitions(IUIAnimationStoryboard* pStoryboard, BOOL bDependOnKeyframes);
///
/// A helper that creates COM transition objects.
///
///
/// TRUE is the method succeeds, otherwise FALSE.
///
BOOL CreateTransitions();
public:
///
/// Constructs an animation group.
///
/// A pointer to animation controller that creates a group.
/// Specifies GroupID.
CAnimationGroup(CAnimationController* pParentController, UINT32 nGroupID);
///
/// The destructor. Called when an animation group is being destroyed.
///
~CAnimationGroup();
///
/// Returns GroupID.
///
///
/// A group identifier.
///
UINT32 GetGroupID() const {return m_nGroupID;}
///
/// Applies transitions to animation objects.
///
///
/// This method ASSERTS in debug mode if storyboard has not been created.
/// It creates all transitions first, then adds "static" keyframes (keyframes that depend on offsets),
/// adds transitions that do not depend on keyframes, adds keyframes depending on transitions and other keyframes,
/// and at last adds transitions that depend on keyframes.
///
void ApplyTransitions();
///
/// Removes transitions from animation objects that belong to an animation group.
///
///
/// If m_bAutoclearTransitions flag is set to TRUE, this method loops over all animation objects that belong to the group
/// and calls CAnimationObject::ClearTransitions(FALSE).
///
void RemoveTransitions();
///
/// Removes and optionally destroys all keyframes that belong to an animation group.
///
///
/// If m_bAutodestroyKeyframes member is TRUE then keyframes are removed and destroyed, otherwise keyframes are
/// just removed from the internal list of keyframes.
///
void RemoveKeyframes();
///
/// Finds an animation object that contains the specified animation variable.
///
///
/// A pointer to animation object, or NULL if animation object is not found.
///
/// A pointer to animation variable.
CAnimationBaseObject* FindAnimationObject(IUIAnimationVariable* pVariable);
///
/// Animates a group.
///
///
/// TRUE if the method succeeds; otherwise FALSE.
///
///
/// This method creates an internal storyboard, creates and applies transitions and schedules an animation
/// if bScheduleNow is TRUE. If bScheduleNow is FALSE, you need to call Schedule to start animation at the
/// specified time.
///
///
///
///
BOOL Animate(IUIAnimationManager* pManager, IUIAnimationTimer* pTimer, BOOL bScheduleNow);
///
/// Schedules an animation at the specified time.
///
///
/// TRUE if the method succeeds; FALSE if the method fails or if Animate has not been called with bScheduleNow set to FALSE.
///
///
/// Call this function to schedule an animation at the specified time. You must call Animate with bScheduleNow set to FALSE first.
///
/// A pointer to animation timer.
/// Specifies time to schedule the animation.
BOOL Schedule(IUIAnimationTimer* pTimer, UI_ANIMATION_SECONDS time);
///
/// Directs all animation objects that belong to group automatically destroy transitions.
///
///
/// Set this value to FALSE only if you allocate transitions on the stack. The default value is TRUE, therefore
/// it's highly recommended to allocate transition objects using operator new.
///
/// Specifies how to destroy transitions.
void SetAutodestroyTransitions(BOOL bAutoDestroy = TRUE);
public:
///
/// Contains a list of animation objects.
///
CObList m_lstAnimationObjects;
///
/// Contains a list of keyframes.
///
CObList m_lstKeyFrames;
///
/// Points to animation storyboard. This pointer is valid only after call on Animate.
///
ATL::CComPtr m_pStoryboard;
///
/// Specifies how to destroy keyframes. If this value is TRUE, all keyframes are removed and destroyed;
/// otherwise they are removed from the list only. The default value is TRUE.
///
BOOL m_bAutodestroyKeyframes;
///
/// Specifies how to clear transitions from animation objects that belong to group. If this member is TRUE,
/// transitions are removed automatically when an animation has been scheduled. Otherwise you need to remove
/// transitions manually.
///
BOOL m_bAutoclearTransitions;
///
/// Specifies how to destroy animation objects. If this parameter is TRUE, animation objects will be destroyed automatically
/// when the group is destroyed. Otherwise animation objects must be destroyed manually. The default value is FALSE.
/// Set this value to TRUE only if all animation objects that belong to group are allocated dynamically with operator new.
///
BOOL m_bAutodestroyAnimationObjects;
};
// PHT - priority handler type
#define UI_ANIMATION_PHT_NONE 0x0000
#define UI_ANIMATION_PHT_CANCEL 0x0001
#define UI_ANIMATION_PHT_CONCLUDE 0x0002
#define UI_ANIMATION_PHT_COMPRESS 0x0004
#define UI_ANIMATION_PHT_TRIM 0x0008
#define UI_ANIMATION_PHT_ALL 0x00FF
#define UI_ANIMATION_PHT_CANCEL_REMOVE 0x0010
#define UI_ANIMATION_PHT_CONCLUDE_REMOVE 0x0020
#define UI_ANIMATION_PHT_COMPRESS_REMOVE 0x0040
#define UI_ANIMATION_PHT_TRIM_REMOVE 0x0080
///
/// Implements the animation controller, which provides a central interface for creating and managing UI animations.
///
///
/// The CAnimationController class is the key class that manages animations.
/// You may create one or more instances of animation controller in an application and, optionally, connect an instance of
/// animation controller to a CWnd object using CAnimationController::SetRelatedWnd. This connection is required to send WM_PAINT messages
/// to the related window automatically when animation manager status has changed or animation timer has been updated.
/// If you do not enable this relation, you must redraw a window that displays an animation manually. For this purpose you can derive a class
/// from CAnimationController and override OnAnimationManagerStatusChanged and/or OnAnimationTimerPostUpdate and invalidate one or
/// more windows when necessary.
///
class CAnimationController : public CObject
{
DECLARE_DYNCREATE(CAnimationController)
protected:
///
/// Specifies whether an animation controller is valid or not.
/// This member is set to FALSE if current OS does not support Windows Animation API.
///
BOOL m_bIsValid;
///
/// Stores a pointer to Animation Manager COM object.
///
ATL::CComPtr m_pAnimationManager;
///
/// Stores a pointer to Transition Library COM object.
///
ATL::CComPtr m_pTransitionLibrary;
///
/// Stores a pointer to Animation Timer COM object.
///
ATL::CComPtr m_pAnimationTimer;
///
/// Stores a pointer to Transition Factory COM object.
///
ATL::CComPtr m_pTransitionFactory;
///
/// A pointer to a related CWnd object, which can be automatically redrawn when
/// the status of animation manager has changed, or post update event has occurred. Can be NULL.
///
CWnd* m_pRelatedWnd;
///
/// A list of animation groups that belong to this animation controller.
///
CList m_lstAnimationGroups;
///
/// A keyframe that represents start of storyboard.
///
static CBaseKeyFrame g_KeyframeStoryboardStart;
public:
///
/// Constructs an animation controller.
///
CAnimationController(void);
///
/// The destructor. Called when animation controller object is being destroyed.
///
virtual ~CAnimationController(void);
///
/// Provides access to encapsulated IUIAnimationManager object.
///
///
/// A pointer to IUIAnimationManager interface or NULL, if creation of animation manager failed.
///
///
/// If current OS does not support Windows Animation API, this method returns NULL and after that all subsequent calls
/// on CAnimationController::IsValid return FALSE.
/// You may need to access IUIAnimationManager in order to call its interface methods, which are not wrapped by
/// animation controller.
///
IUIAnimationManager* GetUIAnimationManager();
///
/// Provides access to encapsulated IUIAnimationTransitionLibrary object.
///
///
/// A pointer to IUIAnimationTransitionLibrary interface or NULL, if creation of transition library failed.
///
///
/// If current OS does not support Windows Animation API, this method returns NULL and after that all subsequent calls
/// on CAnimationController::IsValid return FALSE.
///
IUIAnimationTransitionLibrary* GetUITransitionLibrary();
///
/// Provides access to encapsulated IUIAnimationTimer object.
///
///
/// A pointer to IUIAnimationTimer interface or NULL, if creation of animation timer failed.
///
///
/// If current OS does not support Windows Animation API, this method returns NULL and after that all subsequent calls
/// on CAnimationController::IsValid return FALSE.
///
IUIAnimationTimer* GetUIAnimationTimer();
///
/// A pointer to IUIAnimationTransitionFactory interface or NULL, if creation of transition library failed.
///
///
/// A pointer to IUIAnimationTransitionFactory or NULL, if creation of transition factory failed.
///
///
/// If current OS does not support Windows Animation API, this method returns NULL and after that all subsequent calls
/// on CAnimationController::IsValid return FALSE.
///
IUIAnimationTransitionFactory* GetUITransitionFactory();
///
/// Tells whether animation controller is valid.
///
///
/// TRUE if animation controller is valid; otherwise FALSE.
///
///
/// This method returns FALSE only if Windows Animation API is not supported on the current OS and creation of
/// animation manager failed because it's not registered. You need to call GetUIAnimationManager at least once after initialization of
/// COM libraries to cause setting of this flag.
///
BOOL IsValid() const {return m_bIsValid;}
///
/// Returns a keyframe that identifies start of storyboard.
///
///
/// A pointer to base keyframe, which identifies start of storyboard.
///
///
/// Obtain this keyframe to base any other keyframes or transitions on the moment in time when a storyboard starts.
///
static CBaseKeyFrame* GetKeyframeStoryboardStart();
///
/// Sets or releases a handler to call when animation manager's status changes.
///
///
/// TRUE if the handler was successfully set or released.
///
///
/// When a handler is set (enabled) Windows Animation calls OnAnimationManagerStatusChanged when animation manager's status changes.
///
/// Specifies whether to set or release a handler.
virtual BOOL EnableAnimationManagerEvent(BOOL bEnable = TRUE);
///
/// Sets or releases the priority comparison handler to call to determine whether a scheduled storyboard can be cancelled,
/// concluded, trimmed or compressed.
///
///
/// TRUE if the handler was successfully set or released.
///
///
/// When a handler is set (enabled) Windows Animation calls the following virtual methods depending on dwHandlerType:
/// OnHasPriorityCancel, OnHasPriorityConclude, OnHasPriorityTrim, OnHasPriorityCompress.
/// dwHandler can be a combination of the following flags:
/// UI_ANIMATION_PHT_NONE - release all handlers
/// UI_ANIMATION_PHT_CANCEL - set Cancel comparison handler
/// UI_ANIMATION_PHT_CONCLUDE - set Conclude comparison handler
/// UI_ANIMATION_PHT_COMPRESS - set Compress comparison handler
/// UI_ANIMATION_PHT_TRIM - set Trim comparison handler
/// UI_ANIMATION_PHT_CANCEL_REMOVE - remove Cancel comparison handler
/// UI_ANIMATION_PHT_CONCLUDE_REMOVE - remove Conclude comparison handler
/// UI_ANIMATION_PHT_COMPRESS_REMOVE - remove Compress comparison handler
/// UI_ANIMATION_PHT_TRIM_REMOVE - remove Trim comparison handler
///
/// A combination of UI_ANIMATION_PHT_ flags (see remarks), which specifies what handlers to set or release.
virtual BOOL EnablePriorityComparisonHandler(DWORD_PTR dwHandlerType);
///
/// Sets or releases a handler for storyboard status and update events.
///
///
/// TRUE if the handler was successfully set or released; FALSE if the specified animation group is now found or
/// animation for the specified group has not been initiated and its internal storyboard is NULL.
///
///
/// When a handler is set (enabled) Windows Animation API calls OnStoryboardStatusChanges and OnStoryboardUpdated virtual methods.
/// A handler must be set after CAnimationController::Animate has been called for the specified animation group, because
/// it creates encapsulated IUIAnimationStoryboard object.
///
/// Specifies Group ID.
/// Specifies whether to set or release a handler.
virtual BOOL EnableStoryboardEventHandler(UINT32 nGroupID, BOOL bEnable = TRUE);
///
/// Sets or releases a handler for timing events and handler for timing updates.
///
///
/// TRUE if handlers were successfully set or released; FALSE if this method is called for a second time without
/// releasing the handlers first, or if any other error occurs.
///
///
/// When the handlers are set (enabled) Windows Animation API calls OnAnimationTimerPreUpdate, OnAnimationTimerPostUpdate,
/// OnRenderingTooSlow methods.
/// You need to enable animation timers to allow Windows Animation API update storyboards. Otherwise you'll need to
/// call CAnimationController::UpdateAnimationManager in order to direct the animation manager to update the values
/// of all animation variables.
///
/// Specifies whether to set or release the handlers.
/// Specifies idle behavior for timer update handler.
virtual BOOL EnableAnimationTimerEventHandler(BOOL bEnable = TRUE, UI_ANIMATION_IDLE_BEHAVIOR idleBehavior = UI_ANIMATION_IDLE_BEHAVIOR_DISABLE);
///
/// Directs the animation manager to update the values of all animation variables.
///
///
/// Calling this method advances the animation manager to current time, changing statuses of storyboards as necessary
/// and updating any animation variables to appropriate interpolated values. Internally this method calls
/// IUIAnimationTimer::GetTime(timeNow) and IUIAnimationManager::Update(timeNow). Override this method in a derived
/// class to customize this behavior.
///
virtual void UpdateAnimationManager();
///
/// Tells whether at least one group is playing animation.
///
///
/// TRUE if there is an animation in progress for this animation controller; otherwise FALSE.
///
///
/// Checks status of animation manager and returns TRUE if the status is UI_ANIMATION_MANAGER_BUSY.
///
virtual BOOL IsAnimationInProgress();
///
/// Establishes a relationship between animation controller and a window.
///
///
/// If a related CWnd object is set, the animation controller can automatically update it (send WM_PAINT message) when
/// the status of animation manager has changed or timer post update event has occurred.
///
/// A pointer to window object to set.
void SetRelatedWnd(CWnd* pWnd)
{
m_pRelatedWnd = pWnd;
}
///
/// Adds an animation object to a group that belongs to the animation controller.
///
///
/// A pointer to existing or new animation group where pObject has been added if function succeeds; NULL if
/// pObject has already been added to a group that belongs to another animation controller.
///
///
/// Call this method to add an animation object to the animation controller. An object will be added to a group
/// according to object's GroupID (see CAnimationBaseObject::SetID). The animation controller will create a new
/// group if it's the first object being added with the specified GroupID. An animation object can be added to
/// one animation controller only. If you need to add an object to another controller, call RemoveAnimationObject first.
/// If you call SetID with new GroupID for an object that has been already added to a group, the object will be removed
/// from the old group and added to another group with specified ID.
///
/// A pointer to an animation object.
CAnimationGroup* AddAnimationObject(CAnimationBaseObject* pObject);
///
/// Remove an animation object from animation controller.
///
///
/// Removes an animation object from animation controller and animation group. Call this function if
/// a particular object should not be animated anymore, or if you need to move the object to another animation controller.
/// In the last case bNoDelete must be TRUE.
///
/// A pointer to an animation object.
/// If this parameter is TRUE the object will not be deleted upon remove.
void RemoveAnimationObject(CAnimationBaseObject* pObject, BOOL bNoDelete = FALSE);
///
/// Removes an animation group with specified ID from animation controller.
///
///
/// This method removes an animation group from the internal list of groups and deletes it, therefore if you stored
/// a pointer to that animation group, it must be invalidated. If CAnimationGroup::m_bAutodestroyAnimationObjects is TRUE,
/// all animation objects that belong to that group will be deleted; otherwise their references to parent animation
/// controller will be set to NULL and they can be added to another controller.
///
/// Specifies animation group ID.
void RemoveAnimationGroup(UINT32 nGroupID);
///
/// Removes all animation groups from animation controller.
///
///
/// All groups will be deleted, their pointer, if stored at the application level, must be invalidated.
/// If CAnimationGroup::m_bAutodestroyAnimationObjects for a group being deleted is TRUE,
/// all animation objects that belong to that group will be deleted; otherwise their references to parent animation
/// controller will be set to NULL and they can be added to another controller.
///
void RemoveAllAnimationGroups();
///
/// Removes transitions from animation objects that belong to the specified group.
///
///
/// The group loops over its animation objects and calls ClearTransitions(FALSE) for each animation object.
/// This method is called by the framework after animation has been scheduled.
///
/// Specifies Group ID.
void RemoveTransitions(UINT32 nGroupID);
///
/// Creates a keyframe that depends on transition and adds it to the specified group.
///
///
/// A pointer to newly created keyframe if the function succeeds.
///
///
/// You can store the returned pointer and base other keyframes on the newly created keyframe (see the second overload).
/// It's possible to begin transitions at keyframes - see CBaseTransition::SetKeyframes.
/// You don't need to delete keyframes created in this way, because they are deleted automatically by animation groups.
/// Be careful when creating keyframes based on other keyframes and transitions and avoid circular references.
///
/// Specifies Group ID for which keyframe is created.
/// A pointer to transition. Keyframe will be inserted to storyboard after this transition.
CKeyFrame* CreateKeyframe(UINT32 nGroupID, CBaseTransition* pTransition);
///
/// Creates a keyframe that depends on other keyframe with optional offset in seconds and adds it to the specified group.
///
///
/// A pointer to newly created keyframe if the function succeeds.
///
///
/// You can store the returned pointer and base other keyframes on the newly created keyframe (see the second overload).
/// It's possible to begin transitions at keyframes - see CBaseTransition::SetKeyframes.
/// You don't need to delete keyframes created in this way, because they are deleted automatically by animation groups.
/// Be careful when creating keyframes based on other keyframes and transitions and avoid circular references.
///
/// Specifies Group ID for which keyframe is created.
/// A pointer to base keyframe for this keyframe.
/// Offset in seconds from the base keyframe specified by pKeyframe.
CKeyFrame* CreateKeyframe(UINT32 nGroupID, CBaseKeyFrame* pKeyframe, UI_ANIMATION_SECONDS offset = 0.0);
///
/// Adds a keyframe to group.
///
///
/// TRUE if the function succeeds; otherwise FALSE.
///
///
/// Usually you don't need to call this method, use CAnimationController::CreateKeyframe instead, which creates
/// and adds the created keyframe to a group automatically.
///
/// Specifies Group ID.
/// A pointer to a keyframe.
BOOL AddKeyframeToGroup(UINT32 nGroupID, CBaseKeyFrame* pKeyframe);
///
/// Finds an animation group by its Group ID.
///
///
/// A pointer to animation group or NULL if the group with specified ID is not found.
///
///
/// Use this method to find an animation group at runtime. A group is created and added to the internal list of animation groups
/// when a first animation object with particular GroupID is being added to animation controller.
///
/// Specifies a GroupID.
CAnimationGroup* FindAnimationGroup(UINT32 nGroupID);
///
/// Finds an animation group by its storyboard.
///
///
/// A pointer to animation group if succeeds, or NULL if no group plays the specified storyboard.
///
///
/// This method is usually called from event handlers to find a group by pointer to storyboard that comes as a parameter to an event handler.
///
/// A pointer to a storyboard.
CAnimationGroup* FindAnimationGroup(IUIAnimationStoryboard* pStoryboard);
///
/// Finds animation object containing a specified animation variable.
///
///
/// TRUE if object was found; otherwise FALSE.
///
///
/// Called from event handlers when it's required to find an animation object from incoming animation variable.
///
/// A pointer to animation variable.
/// Output. Contains a pointer to animation object or NULL.
/// Output. Contains a pointer to animation group that holds the animation object, or NULL.
BOOL FindAnimationObject(IUIAnimationVariable* pVariable, CAnimationBaseObject** ppObject, CAnimationGroup** ppGroup);
///
/// Prepares a group to run animation and optionally schedules it.
///
///
/// TRUE if animation was successfully scheduled and run.
///
///
/// This method does the actual work creating storyboard, adding animation variables, applying transitions and setting keyframes.
/// It's possible to delay scheduling if you set bScheduleNow to FALSE. In this case the specified group
/// will hold a storyboard that has been set up for animation. At that point you can setup events for the storyboard and
/// animation variables. When you actually need to run the animation call CAnimationController::ScheduleGroup.
///
/// Specifies GroupID.
/// Specifies whether to run animation right away.
BOOL AnimateGroup(UINT32 nGroupID, BOOL bScheduleNow = TRUE);
///
/// Schedules an animation.
///
///
/// TRUE if animation was scheduled successfully. FALSE if storyboard has not been created, or other error occurs.
///
///
/// You must call AnimateGroup with parameter bScheduleNow set to FALSE prior ScheduleGroup. You can specify the
/// desired animation time obtained from IUIAnimationTimer::GetTime. If the time parameter is 0.0, the animation is scheduled for the
/// current time.
///
/// Specifies animation Group ID to schedule.
/// Specifies time to schedule.
BOOL ScheduleGroup(UINT32 nGroupID, UI_ANIMATION_SECONDS time = 0.0);
///
/// Called by the framework to clean up the group when animation has been scheduled.
///
///
/// This method removes all transitions and keyframes from the specified group, because they are not relevant
/// after an animation has been scheduled.
///
/// Specifies GroupID.
void CleanUpGroup(UINT32 nGroupID);
///
/// Called by the framework right before the animation is scheduled.
///
///
/// This call is routed to related CWnd and can be overridden in a derived class to perform any
/// additional actions before the animation starts for the specified group.
///
/// A pointer to an animation group whose animation is about to start.
virtual void OnBeforeAnimationStart(CAnimationGroup* pGroup);
///
/// Called by the framework in response to StatusChanged event from animation manager.
///
///
/// This method is called if you enable animation manager events with EnableAnimationManagerEvent.
/// It can be overridden in a derived class to take application-specific actions. The default implementation
/// updates a related window if it has been set with SetRelatedWnd.
///
/// New animation manager status.
/// Previous animation manager status.
virtual void OnAnimationManagerStatusChanged(UI_ANIMATION_MANAGER_STATUS newStatus, UI_ANIMATION_MANAGER_STATUS previousStatus);
///
/// Called by the framework when value of animation variable has changed.
///
///
/// This method is called if you enable animation variable events with EnableValueChangedEvent called for a specific
/// animation variable or animation object.
/// It can be overridden in a derived class to take application-specific actions.
///
/// A pointer to an animation group that holds an animation object whose value has changed.
/// A pointer to an animation object that contains an animation variable whose value has changed.
/// A pointer to an animation variable.
/// Specifies new value.
/// Specifies previous value.
virtual void OnAnimationValueChanged(CAnimationGroup* pGroup, CAnimationBaseObject* pObject, IUIAnimationVariable* variable, DOUBLE newValue, DOUBLE prevValue);
///
/// Called by the framework when integer value of animation variable has changed.
///
///
/// This method is called if you enable animation variable events with EnableIntegerValueChangedEvent called for a specific
/// animation variable or animation object.
/// It can be overridden in a derived class to take application-specific actions.
///
/// A pointer to an animation group that holds an animation object whose value has changed.
/// A pointer to an animation object that contains an animation variable whose value has changed.
/// A pointer to an animation variable.
/// Specifies new value.
/// Specifies previous value.
virtual void OnAnimationIntegerValueChanged(CAnimationGroup* pGroup, CAnimationBaseObject* pObject, IUIAnimationVariable* variable, INT32 newValue, INT32 prevValue);
///
/// Called by the framework when storyboard status has changed.
///
///
/// This method is called if you enable storyboard events using CAnimationController::EnableStoryboardEventHandler.
/// It can be overridden in a derived class to take application-specific actions.
///
/// A pointer to an animation group that owns the storyboard whose status has changed.
/// Specifies the new status.
/// Specifies the previous status.
virtual void OnStoryboardStatusChanged(CAnimationGroup* pGroup, UI_ANIMATION_STORYBOARD_STATUS newStatus, UI_ANIMATION_STORYBOARD_STATUS previousStatus);
///
/// Called by the framework when storyboard has been updated.
///
///
/// This method is called if you enable storyboard events using CAnimationController::EnableStoryboardEventHandler.
/// It can be overridden in a derived class to take application-specific actions.
///
/// A pointer to a group that owns the storyboard.
virtual void OnStoryboardUpdated(CAnimationGroup* pGroup);
///
/// Called by the framework to resolve scheduling conflicts.
///
///
/// Should return TRUE if storyboard owned by pGroupNew has priority. Should return FALSE if storyboard owned by
/// pGroupScheduled has priority.
///
///
/// This method is called if you enable priority comparison events using CAnimationController::EnablePriorityComparisonHandler
/// and specify UI_ANIMATION_PHT_CANCEL.
/// It can be overridden in a derived class to take application-specific actions.
/// Read Windows Animation API documentation for more information about Conflict Management (http://msdn.microsoft.com/en-us/library/dd371759(VS.85).aspx).
///
/// The group that owns the currently scheduled storyboard.
/// The group that owns the new storyboard that is in scheduling conflict with the scheduled storyboard owned by pGroupScheduled.
/// The potential effect on pGroupNew if pGroupScheduled has a higher priority.
virtual BOOL OnHasPriorityCancel(CAnimationGroup* pGroupScheduled, CAnimationGroup* pGroupNew, UI_ANIMATION_PRIORITY_EFFECT priorityEffect);
///
/// Called by the framework to resolve scheduling conflicts.
///
///
/// Should return TRUE if storyboard owned by pGroupNew has priority. Should return FALSE if storyboard owned by
/// pGroupScheduled has priority.
///
///
/// This method is called if you enable priority comparison events using CAnimationController::EnablePriorityComparisonHandler
/// and specify UI_ANIMATION_PHT_CONCLUDE.
/// It can be overridden in a derived class to take application-specific actions.
/// Read Windows Animation API documentation for more information about Conflict Management (http://msdn.microsoft.com/en-us/library/dd371759(VS.85).aspx).
///
/// The group that owns the currently scheduled storyboard.
/// The group that owns the new storyboard that is in scheduling conflict with the scheduled storyboard owned by pGroupScheduled.
/// The potential effect on pGroupNew if pGroupScheduled has a higher priority.
virtual BOOL OnHasPriorityConclude(CAnimationGroup* pGroupScheduled, CAnimationGroup* pGroupNew, UI_ANIMATION_PRIORITY_EFFECT priorityEffect);
///
/// Called by the framework to resolve scheduling conflicts.
///
///
/// Should return TRUE if storyboard owned by pGroupNew has priority. Should return FALSE if storyboard owned by
/// pGroupScheduled has priority.
///
///
/// This method is called if you enable priority comparison events using CAnimationController::EnablePriorityComparisonHandler
/// and specify UI_ANIMATION_PHT_TRIM.
/// It can be overridden in a derived class to take application-specific actions.
/// Read Windows Animation API documentation for more information about Conflict Management (http://msdn.microsoft.com/en-us/library/dd371759(VS.85).aspx).
///
/// The group that owns the currently scheduled storyboard.
/// The group that owns the new storyboard that is in scheduling conflict with the scheduled storyboard owned by pGroupScheduled.
/// The potential effect on pGroupNew if pGroupScheduled has a higher priority.
virtual BOOL OnHasPriorityTrim(CAnimationGroup* pGroupScheduled, CAnimationGroup* pGroupNew, UI_ANIMATION_PRIORITY_EFFECT priorityEffect);
///
/// Called by the framework to resolve scheduling conflicts.
///
///
/// Should return TRUE if storyboard owned by pGroupNew has priority. Should return FALSE if storyboard owned by
/// pGroupScheduled has priority.
///
///
/// This method is called if you enable priority comparison events using CAnimationController::EnablePriorityComparisonHandler
/// and specify UI_ANIMATION_PHT_COMPRESS.
/// It can be overridden in a derived class to take application-specific actions.
/// Read Windows Animation API documentation for more information about Conflict Management (http://msdn.microsoft.com/en-us/library/dd371759(VS.85).aspx).
///
/// The group that owns the currently scheduled storyboard.
/// The group that owns the new storyboard that is in scheduling conflict with the scheduled storyboard owned by pGroupScheduled.
/// The potential effect on pGroupNew if pGroupScheduled has a higher priority.
virtual BOOL OnHasPriorityCompress(CAnimationGroup* pGroupScheduled, CAnimationGroup* pGroupNew, UI_ANIMATION_PRIORITY_EFFECT priorityEffect);
///
/// Called by the framework before an animation update begins.
///
///
/// This method is called if you enable timer event handlers using EnableAnimationTimerEventHandler.
/// It can be overridden in a derived class to take application-specific actions.
///
virtual void OnAnimationTimerPreUpdate();
///
/// Called by the framework after an animation update is finished.
///
///
/// This method is called if you enable timer event handlers using EnableAnimationTimerEventHandler.
/// It can be overridden in a derived class to take application-specific actions.
///
virtual void OnAnimationTimerPostUpdate();
///
/// Called by the framework when the rendering frame rate for an animation falls below a minimum desirable frame rate.
///
///
/// This method is called if you enable timer event handlers using EnableAnimationTimerEventHandler.
/// It can be overridden in a derived class to take application-specific actions.
/// The minimum desirable frame rate is specified by calling IUIAnimationTimer::SetFrameRateThreshold.
///
/// The current frame rate in frames per second.
virtual void OnAnimationTimerRenderingTooSlow(UINT32 fps);
protected:
///
/// Called by the framework when an animation for the specified group has just been scheduled.
///
///
/// The default implementation removes keyframes from the specified group and transitions from animation variables that
/// belong to the specified group. Can be overridden in a derived class to take any additional actions upon animation schedule.
///
/// A pointer to an animation group, which has been scheduled.
virtual void OnAfterSchedule(CAnimationGroup* pGroup);
///
/// A helper that cleans up the group.
///
///
/// This method removes all transitions and keyframes from the specified group.
///
/// A pointer to animation group to clean.
void CleanUpGroup(CAnimationGroup* pGroup);
};
//----------------------------
// Event handler definitions
//----------------------------
///
/// Implements a callback, which is called by Animation API when a status of animation manager changed.
///
///
/// This event handler is created and passed to IUIAnimationManager::SetManagerEventHandler method,
/// when you call CAnimationController::EnableAnimationManagerEvent.
///
class CAnimationManagerEventHandler : public CUIAnimationManagerEventHandlerBase
{
CAnimationController* m_pAnimationController;
public:
///
/// Constructs a CAnimationManagerEventHandler object.
///
CAnimationManagerEventHandler() : m_pAnimationController(NULL)
{
}
///
/// Creates an instance of CAnimationManagerEventHandler object.
///
///
/// If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
/// A pointer to animation controller, which will receive events.
/// Output. If the method succeeds it contains a pointer to COM object that will handle
/// status updates to an animation manager.
static COM_DECLSPEC_NOTHROW HRESULT CreateInstance(CAnimationController* pAnimationController, IUIAnimationManagerEventHandler **ppManagerEventHandler)
{
CAnimationManagerEventHandler *pManagerEventHandler = NULL;
HRESULT hr = CUIAnimationCallbackBase::CreateInstance(ppManagerEventHandler, &pManagerEventHandler);
if (SUCCEEDED(hr))
{
pManagerEventHandler->SetAnimationController (pAnimationController);
}
return hr;
}
///
/// Stores a pointer to animation controller to route events.
///
/// A pointer to animation controller, which will receive events.
void SetAnimationController(CAnimationController* pAnimationController)
{
m_pAnimationController = pAnimationController;
}
///
/// Called when a status of animation manager has changed.
///
///
/// Current implementation always returns S_OK;
///
/// New status.
/// Previous status.
#pragma warning(suppress:26433)
IFACEMETHOD(OnManagerStatusChanged)(_In_ UI_ANIMATION_MANAGER_STATUS newStatus, _In_ UI_ANIMATION_MANAGER_STATUS previousStatus)
{
if (m_pAnimationController != NULL)
{
m_pAnimationController->OnAnimationManagerStatusChanged(newStatus, previousStatus);
}
return S_OK;
}
};
///
/// Implements a call back, which is called by Animation API when the value of an animation variable changes.
///
///
/// This event handler is created and passed to IUIAnimationVariable::SetVariableChangeHandler method,
/// when you call CAnimationVariable::EnableValueChangedEvent or CAnimationBaseObject::EnableValueChangedEvent
/// (which enables this event for all animation variables encapsulated in an animation object).
///
class CAnimationVariableChangeHandler : public CUIAnimationVariableChangeHandlerBase
{
CAnimationController* m_pAnimationController;
public:
///
/// Constructs a CAnimationVariableChangeHandler object.
///
CAnimationVariableChangeHandler() : m_pAnimationController(NULL)
{
}
///
/// Creates an instance of CAnimationVariableChangeHandler object.
///
///
/// If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
/// A pointer to animation controller, which will receive events.
/// Output. If the method succeeds it contains a pointer to COM object that will handle
/// variable change events.
static COM_DECLSPEC_NOTHROW HRESULT CreateInstance(CAnimationController* pAnimationController, IUIAnimationVariableChangeHandler **ppHandler)
{
CAnimationVariableChangeHandler *pHandler = NULL;
HRESULT hr = CUIAnimationCallbackBase::CreateInstance(ppHandler, &pHandler);
if (SUCCEEDED(hr))
{
pHandler->SetAnimationController (pAnimationController);
}
return hr;
}
///
/// Stores a pointer to animation controller to route events.
///
/// A pointer to animation controller, which will receive events.
void SetAnimationController(CAnimationController* pAnimationController)
{
m_pAnimationController = pAnimationController;
}
///
/// Called when a value of an animation variable has changed.
///
///
/// If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
/// The storyboard that is animating the variable.
/// The animation variable that was updated.
/// The new value.
/// The previous value.
#pragma warning(suppress:26433)
IFACEMETHOD(OnValueChanged)
(
_In_ IUIAnimationStoryboard *storyboard,
_In_ IUIAnimationVariable *variable,
_In_ DOUBLE newValue,
_In_ DOUBLE previousValue
)
{
if (m_pAnimationController == NULL)
{
TRACE(_T("An instance of OnValueChanged event handler has not been initialized.\n"));
return E_FAIL;
}
if (storyboard == NULL && variable != NULL)
{
(void)variable->GetCurrentStoryboard(&storyboard);
}
CAnimationGroup* pGroup = NULL;
CAnimationBaseObject* pObject = NULL;
if (storyboard != NULL)
{
pGroup = m_pAnimationController->FindAnimationGroup(storyboard);
if (pGroup == NULL)
{
TRACE(_T("Got OnValueChanged event for a storyboard, which does not belong to any Animation Group.\n"));
return E_FAIL;
}
pObject = pGroup->FindAnimationObject(variable);
if (pObject == NULL)
{
TRACE(_T("Got OnValueChanged event from an animation variable, which does not belong to any Animation Group.\n"));
return E_FAIL;
}
}
else
{
m_pAnimationController->FindAnimationObject(variable, &pObject, &pGroup);
}
m_pAnimationController->OnAnimationValueChanged(pGroup, pObject, variable, newValue, previousValue);
return S_OK;
}
};
///
/// Implements a call back, which is called by Animation API when the value of an animation variable changes.
///
///
/// This event handler is created and passed to IUIAnimationVariable::SetVariableIntegerChangeHandler method,
/// when you call CAnimationVariable::EnableIntegerValueChangedEvent or CAnimationBaseObject::EnableIntegerValueChangedEvent
/// (which enables this event for all animation variables encapsulated in an animation object).
///
class CAnimationVariableIntegerChangeHandler : public CUIAnimationVariableIntegerChangeHandlerBase
{
CAnimationController* m_pAnimationController;
public:
///
/// Constructs a CAnimationVariableIntegerChangeHandler object.
///
CAnimationVariableIntegerChangeHandler () : m_pAnimationController(NULL)
{
}
///
/// Creates an instance of CAnimationVariableIntegerChangeHandler callback.
///
///
/// If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
/// A pointer to animation controller, which will receive events.
/// Output. If the method succeeds it contains a pointer to COM object that will handle
/// variable integer change events.
static COM_DECLSPEC_NOTHROW HRESULT CreateInstance(CAnimationController* pAnimationController, IUIAnimationVariableIntegerChangeHandler **ppHandler)
{
CAnimationVariableIntegerChangeHandler *pHandler = NULL;
HRESULT hr = CUIAnimationCallbackBase::CreateInstance(ppHandler, &pHandler);
if (SUCCEEDED(hr))
{
pHandler->SetAnimationController (pAnimationController);
}
return hr;
}
///
/// Stores a pointer to animation controller to route events.
///
/// A pointer to animation controller, which will receive events.
void SetAnimationController(CAnimationController* pAnimationController)
{
m_pAnimationController = pAnimationController;
}
///
/// Called when a value of an animation variable has changed.
///
///
/// S_OK if the method succeeds; otherwise E_FAIL.
///
/// The storyboard that is animating the variable.
/// The animation variable that was updated.
/// The new rounded value.
/// The previous rounded value.
#pragma warning(suppress:26433)
IFACEMETHOD(OnIntegerValueChanged)
(
_In_ IUIAnimationStoryboard *storyboard,
_In_ IUIAnimationVariable *variable,
_In_ INT32 newValue,
_In_ INT32 previousValue
)
{
if (m_pAnimationController == NULL)
{
TRACE(_T("An instance of OnIntegerValueChanged event handler has not been initialized.\n"));
return E_FAIL;
}
if (storyboard == NULL && variable != NULL)
{
(void)variable->GetCurrentStoryboard(&storyboard);
}
CAnimationGroup* pGroup = NULL;
CAnimationBaseObject* pObject = NULL;
if (storyboard != NULL)
{
pGroup = m_pAnimationController->FindAnimationGroup(storyboard);
if (pGroup == NULL)
{
TRACE(_T("Got OnIntegerValueChanged event for a storyboard, which does not belong to any Animation Group.\n"));
return E_FAIL;
}
pObject = pGroup->FindAnimationObject(variable);
if (pObject == NULL)
{
TRACE(_T("Got OnIntegerValueChanged event from an animation variable, which does not belong to any Animation Group.\n"));
return E_FAIL;
}
}
else
{
m_pAnimationController->FindAnimationObject(variable, &pObject, &pGroup);
}
m_pAnimationController->OnAnimationIntegerValueChanged(pGroup, pObject, variable, newValue, previousValue);
return S_OK;
}
};
///
/// Implements a callback, which is called by Animation API when storyboard's status is changed or storyboard is updated.
///
///
/// This event handler is created and passed to IUIAnimationStoryboard::SetStoryboardEventHandler method,
/// when you call CAnimationController::EnableStoryboardEventHandler.
///
class CAnimationStoryboardEventHandler : public CUIAnimationStoryboardEventHandlerBase
{
CAnimationController* m_pAnimationController;
public:
///
/// Constructs a CAnimationStoryboardEventHandler object.
///
CAnimationStoryboardEventHandler() : m_pAnimationController(NULL)
{
}
///
/// Creates an instance of CAnimationStoryboardEventHandler callback.
///
///
/// If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
/// A pointer to animation controller, which will receive events.
/// Output. If the method succeeds it contains a pointer to COM object that will handle
/// storyboard events.
static COM_DECLSPEC_NOTHROW HRESULT CreateInstance(CAnimationController* pAnimationController, IUIAnimationStoryboardEventHandler **ppHandler)
{
CAnimationStoryboardEventHandler* pHandler = NULL;
HRESULT hr = CUIAnimationCallbackBase::CreateInstance(ppHandler, &pHandler);
if (SUCCEEDED(hr))
{
pHandler->SetAnimationController (pAnimationController);
}
return hr;
}
///
/// Stores a pointer to animation controller to route events.
///
/// A pointer to animation controller, which will receive events.
void SetAnimationController(CAnimationController* pAnimationController)
{
m_pAnimationController = pAnimationController;
}
///
/// Handles OnStoryboardStatusChanged events, which occur when a storyboard's status changes
///
///
/// S_OK if the method succeeds; otherwise E_FAIL.
///
/// A pointer to storyboard whose status has changed.
/// Specifies new storyboard status.
/// Specifies previous storyboard status.
#pragma warning(suppress:26433)
IFACEMETHOD(OnStoryboardStatusChanged)
(
_In_ IUIAnimationStoryboard *storyboard, // The storyboard that changed status
_In_ UI_ANIMATION_STORYBOARD_STATUS newStatus, // The new status
_In_ UI_ANIMATION_STORYBOARD_STATUS previousStatus // The previous status
)
{
if (m_pAnimationController == NULL)
{
TRACE(_T("An instance of OnStoryboardStatusChanged event handler has not been initialized.\n"));
return E_FAIL;
}
CAnimationGroup* pGroup = m_pAnimationController->FindAnimationGroup(storyboard);
if (pGroup == NULL)
{
TRACE(_T("Got an event from storyboard, which does not belong to any Animation Group.\n"));
return E_FAIL;
}
m_pAnimationController->OnStoryboardStatusChanged(pGroup, newStatus, previousStatus);
return S_OK;
}
///
/// Handles OnStoryboardUpdated events, which occur when a storyboard is updated
///
///
/// S_OK if the method succeeds; otherwise E_FAIL.
///
/// A pointer to storyboard, which was updated.
#pragma warning(suppress:26433)
IFACEMETHOD(OnStoryboardUpdated)
(
_In_ IUIAnimationStoryboard *storyboard // The storyboard that was updated
)
{
if (m_pAnimationController == NULL)
{
TRACE(_T("An instance of OnStoryboardUpdated event handler has not been initialized.\n"));
return E_FAIL;
}
CAnimationGroup* pGroup = m_pAnimationController->FindAnimationGroup(storyboard);
if (pGroup == NULL)
{
TRACE(_T("Got an event from storyboard, which does not belong to any Animation Group.\n"));
return E_FAIL;
}
m_pAnimationController->OnStoryboardUpdated(pGroup);
return S_OK;
}
};
class PriorityComparisonMethodCancel
{
public:
static BOOL Method(CAnimationController* pController, CAnimationGroup* pGroupScheduled, CAnimationGroup* pGroupNew, UI_ANIMATION_PRIORITY_EFFECT priorityEffect)
{
return pController->OnHasPriorityCancel(pGroupScheduled, pGroupNew, priorityEffect);
}
};
class PriorityComparisonMethodConclude
{
public:
static BOOL Method(CAnimationController* pController, CAnimationGroup* pGroupScheduled, CAnimationGroup* pGroupNew, UI_ANIMATION_PRIORITY_EFFECT priorityEffect)
{
return pController->OnHasPriorityConclude(pGroupScheduled, pGroupNew, priorityEffect);
}
};
class PriorityComparisonMethodTrim
{
public:
static BOOL Method(CAnimationController* pController, CAnimationGroup* pGroupScheduled, CAnimationGroup* pGroupNew, UI_ANIMATION_PRIORITY_EFFECT priorityEffect)
{
return pController->OnHasPriorityTrim(pGroupScheduled, pGroupNew, priorityEffect);
}
};
class PriorityComparisonMethodCompress
{
public:
static BOOL Method(CAnimationController* pController, CAnimationGroup* pGroupScheduled, CAnimationGroup* pGroupNew, UI_ANIMATION_PRIORITY_EFFECT priorityEffect)
{
return pController->OnHasPriorityCompress(pGroupScheduled, pGroupNew, priorityEffect);
}
};
#pragma warning(push)
#pragma warning(disable:4634)
///
/// Implements a call back, which is called by Animation API when it needs to resolve scheduling conflicts.
///
///
/// This event handler is created and passed to one of IUIAnimationManager's Set methods that deal with priority comparisons,
/// when you call CAnimationController::EnablePriorityComparisonHandler.
///
template
class CUIAnimationPriorityComparisonHandler : public CUIAnimationPriorityComparisonBase>
{
CAnimationController* m_pAnimationController;
public:
///
/// Creates an instance of CUIAnimationPriorityComparisonHandler callback.
///
///
/// If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
/// A pointer to animation controller, which will receive events.
/// Output. If the method succeeds it contains a pointer to COM object that will handle
/// priority comparison events.
static COM_DECLSPEC_NOTHROW HRESULT CreateInstance(CAnimationController* pAnimationController, IUIAnimationPriorityComparison **ppHandler)
{
CUIAnimationPriorityComparisonHandler* pHandler = NULL;
HRESULT hr = CUIAnimationCallbackBase>::CreateInstance(ppHandler, &pHandler);
if (SUCCEEDED(hr))
{
pHandler->SetAnimationController (pAnimationController);
}
return hr;
}
///
/// Stores a pointer to animation controller to route events.
///
/// A pointer to animation controller, which will receive events.
void SetAnimationController(CAnimationController* pAnimationController)
{
m_pAnimationController = pAnimationController;
}
///
/// Determines the relative priority between a scheduled storyboard and a new storyboard.
///
///
/// Should return S_OK if pStoryboardNew has priority; should return S_FALSE if pStoryboardScheduled has priority.
///
/// Currently scheduled storyboard.
/// New storyboard that conflicts with scheduled storyboard.
/// Potential effect on attempt to schedule storyboard if HasPriority returns S_FALSE.
IFACEMETHOD(HasPriority)
(
_In_ IUIAnimationStoryboard *pStoryboardScheduled,
_In_ IUIAnimationStoryboard *pStoryboardNew,
_In_ UI_ANIMATION_PRIORITY_EFFECT priorityEffect
)
{
if (m_pAnimationController == NULL)
{
TRACE(_T("An instance of HasPriority event handler has not been initialized.\n"));
return E_FAIL;
}
CAnimationGroup* pGroupScheduled = m_pAnimationController->FindAnimationGroup(pStoryboardScheduled);
if (pGroupScheduled == NULL)
{
TRACE(_T("Got a HasPriority event for a storyboard that does not belong to any group.\n"));
return E_FAIL;
}
CAnimationGroup* pGroupNew = m_pAnimationController->FindAnimationGroup(pStoryboardNew);
if (pGroupNew == NULL)
{
TRACE(_T("Got a HasPriority event for a storyboard that does not belong to any group.\n"));
return E_FAIL;
}
BOOL bResult = PriorityComparisonMethod::Method(m_pAnimationController, pGroupScheduled, pGroupNew, priorityEffect);
return bResult ? S_OK : S_FALSE;
}
};
#pragma warning(pop)
///
/// Implements a call back, which is called by Animation API when timing events occur.
///
///
/// This event handler is created and passed to IUIAnimationTimer::SetTimerEventHandler when you call
/// CAnimationController::EnableAnimationTimerEventHandler.
///
class CAnimationTimerEventHandler : public CUIAnimationTimerEventHandlerBase
{
CAnimationController* m_pAnimationController;
public:
///
/// Creates an instance of CAnimationTimerEventHandler callback.
///
///
/// If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
/// A pointer to animation controller, which will receive events.
/// Output. If the method succeeds it contains a pointer to COM object that will handle
/// animation timer events.
static COM_DECLSPEC_NOTHROW HRESULT CreateInstance(CAnimationController* pAnimationController, IUIAnimationTimerEventHandler **ppTimerEventHandler)
{
CAnimationTimerEventHandler* pHandler = NULL;
HRESULT hr = CUIAnimationCallbackBase::CreateInstance(ppTimerEventHandler, &pHandler);
if (SUCCEEDED(hr))
{
pHandler->SetAnimationController (pAnimationController);
}
return hr;
}
///
/// Stores a pointer to animation controller to route events.
///
/// A pointer to animation controller, which will receive events.
void SetAnimationController(CAnimationController* pAnimationController)
{
m_pAnimationController = pAnimationController;
}
///
/// Handles events that occur before an animation update begins.
///
///
/// S_OK if the method succeeds; otherwise E_FAIL.
///
#pragma warning(suppress:26433)
IFACEMETHOD(OnPreUpdate)()
{
if (m_pAnimationController == NULL)
{
TRACE(_T("An instance of CAnimationTimerEventHandler event handler has not been initialized.\n"));
return E_FAIL;
}
m_pAnimationController->OnAnimationTimerPreUpdate();
return S_OK;
}
///
/// Handles events that occur after an animation update is finished.
///
///
/// S_OK if the method succeeds; otherwise E_FAIL.
///
#pragma warning(suppress:26433)
IFACEMETHOD(OnPostUpdate)()
{
if (m_pAnimationController == NULL)
{
TRACE(_T("An instance of CAnimationTimerEventHandler event handler has not been initialized.\n"));
return E_FAIL;
}
m_pAnimationController->OnAnimationTimerPostUpdate();
return S_OK;
}
///
/// Handles events that occur when the rendering frame rate for an animation falls below the minimum desirable frame rate.
///
///
/// S_OK if the method succeeds; otherwise E_FAIL.
///
#pragma warning(suppress:26433)
IFACEMETHOD(OnRenderingTooSlow)(_In_ UINT32 fps)
{
if (m_pAnimationController == NULL)
{
TRACE(_T("An instance of CAnimationTimerEventHandler event handler has not been initialized.\n"));
return E_FAIL;
}
m_pAnimationController->OnAnimationTimerRenderingTooSlow(fps);
return S_OK;
}
};
//---------------------------------
// Transition class definitions
//---------------------------------
///
/// Implements an accelerate-decelerate transition.
///
///
/// During an accelerate-decelerate transition, the animation variable speeds up and then slows down over the
/// duration of the transition, ending at a specified value. You can control how quickly the variable accelerates and
/// decelerates independently, by specifying different acceleration and deceleration ratios.
/// When the initial velocity is zero, the acceleration ratio is the fraction of the duration that the variable will
/// spend accelerating; likewise with the deceleration ratio. If the initial velocity is non-zero, it is the
/// fraction of the time between the velocity reaching zero and the end of transition. The acceleration ratio and
/// the deceleration ratio should sum to a maximum of 1.0.
/// Because all transitions are cleared automatically, it's recommended to allocated them using operator new.
/// The encapsulated IUIAnimationTransition COM object is created by CAnimationController::AnimateGroup, until then
/// it's NULL. Changing member variables after creation of this COM object has no effect.
///
class CAccelerateDecelerateTransition : public CBaseTransition
{
public:
///
/// Constructs a transition object.
///
/// The duration of the transition.
/// The value of the animation variable at the end of the transition.
/// The ratio of the time spent accelerating to the duration.
/// The ratio of the time spent decelerating to the duration.
CAccelerateDecelerateTransition(UI_ANIMATION_SECONDS duration, DOUBLE finalValue, DOUBLE accelerationRatio = 0.3,
DOUBLE decelerationRatio = 0.3) : m_duration(duration), m_finalValue(finalValue),
m_accelerationRatio(accelerationRatio), m_decelerationRatio(decelerationRatio)
{
m_type = ACCELERATE_DECELERATE;
}
public:
///
/// The duration of the transition.
///
UI_ANIMATION_SECONDS m_duration;
///
/// The value of the animation variable at the end of the transition.
///
DOUBLE m_finalValue;
///
/// The ratio of the time spent accelerating to the duration.
///
DOUBLE m_accelerationRatio;
///
/// The ratio of the time spent decelerating to the duration.
///
DOUBLE m_decelerationRatio;
///
/// Calls the transition library to create encapsulated transition COM object.
///
///
/// TRUE if transition is created successfully; otherwise FALSE.
///
/// A pointer to transition library, which is responsible for creation of standard transitions.
/// A pointer to transition factory, which is responsible for creation of custom transitions.
BOOL Create(IUIAnimationTransitionLibrary* pLibrary, IUIAnimationTransitionFactory* pFactory) override
{
UNREFERENCED_PARAMETER(pFactory);
Clear();
if (pLibrary != NULL)
{
HRESULT hr = pLibrary->CreateAccelerateDecelerateTransition(m_duration, m_finalValue, m_accelerationRatio,
m_decelerationRatio, &m_transition);
return SUCCEEDED(hr);
}
return FALSE;
}
};
///
/// Encapsulates a constant transition.
///
///
/// During a constant transition, the value of an animation variable remains at the initial value over the duration
/// of the transition.
/// Because all transitions are cleared automatically, it's recommended to allocated them using operator new.
/// The encapsulated IUIAnimationTransition COM object is created by CAnimationController::AnimateGroup, until then
/// it's NULL. Changing member variables after creation of this COM object has no effect.
///
class CConstantTransition : public CBaseTransition
{
public:
///
/// Constructs a transition object and initializes its duration.
///
/// The duration of the transition.
CConstantTransition (UI_ANIMATION_SECONDS duration) : m_duration(duration)
{
m_type = CONSTANT;
}
///
/// The duration of the transition.
///
UI_ANIMATION_SECONDS m_duration;
///
/// Calls the transition library to create encapsulated transition COM object.
///
///
/// TRUE if transition is created successfully; otherwise FALSE.
///
/// A pointer to transition library, which is responsible for creation of standard transitions.
/// A pointer to transition factory, which is responsible for creation of custom transitions.
BOOL Create(IUIAnimationTransitionLibrary* pLibrary, IUIAnimationTransitionFactory* pFactory) override
{
UNREFERENCED_PARAMETER(pFactory);
Clear();
if (pLibrary != NULL)
{
HRESULT hr = pLibrary->CreateConstantTransition(m_duration, &m_transition);
return SUCCEEDED(hr);
}
return FALSE;
}
};
///
/// Encapsulates a cubic transition.
///
///
/// During a cubic transition, the value of the animation variable changes from its initial value to a specified
/// final value over the duration of the transition, ending at a specified velocity.
/// Because all transitions are cleared automatically, it's recommended to allocated them using operator new.
/// The encapsulated IUIAnimationTransition COM object is created by CAnimationController::AnimateGroup, until then
/// it's NULL. Changing member variables after creation of this COM object has no effect.
///
class CCubicTransition : public CBaseTransition
{
public:
///
/// Constructs a transition object and initializes its parameters.
///
/// The duration of the transition.
/// The value of the animation variable at the end of the transition.
/// The velocity of the variable at the end of the transition.
CCubicTransition(UI_ANIMATION_SECONDS duration, DOUBLE finalValue, DOUBLE finalVelocity) : m_duration(duration),
m_dblFinalValue(finalValue), m_dblFinalVelocity(finalVelocity)
{
m_type = CUBIC;
}
///
/// The duration of the transition.
///
UI_ANIMATION_SECONDS m_duration;
///
/// The value of the animation variable at the end of the transition.
///
DOUBLE m_dblFinalValue;
///
/// The velocity of the variable at the end of the transition.
///
DOUBLE m_dblFinalVelocity;
///
/// Calls the transition library to create encapsulated transition COM object.
///
///
/// TRUE if transition is created successfully; otherwise FALSE.
///
/// A pointer to transition library, which is responsible for creation of standard transitions.
/// A pointer to transition factory, which is responsible for creation of custom transitions.
BOOL Create(IUIAnimationTransitionLibrary* pLibrary, IUIAnimationTransitionFactory* pFactory) override
{
UNREFERENCED_PARAMETER(pFactory);
Clear();
if (pLibrary != NULL)
{
HRESULT hr = pLibrary->CreateCubicTransition(m_duration, m_dblFinalValue, m_dblFinalVelocity, &m_transition);
return SUCCEEDED(hr);
}
return FALSE;
}
};
///
/// Encapsulates a discrete transition.
///
///
/// During a discrete transition, the animation variable remains at the initial value for a specified delay time,
/// then switches instantaneously to a specified final value and remains at that value for a given hold time.
/// Because all transitions are cleared automatically, it's recommended to allocated them using operator new.
/// The encapsulated IUIAnimationTransition COM object is created by CAnimationController::AnimateGroup, until then
/// it's NULL. Changing member variables after creation of this COM object has no effect.
///
class CDiscreteTransition : public CBaseTransition
{
public:
///
/// Constructs a discrete transition object and initializes its parameters.
///
/// The amount of time by which to delay the instantaneous switch to the final value.
/// The value of the animation variable at the end of the transition.
/// The amount of time by which to hold the variable at its final value.
CDiscreteTransition(UI_ANIMATION_SECONDS delay, DOUBLE dblFinalValue, UI_ANIMATION_SECONDS hold) : m_delay(delay),
m_dblFinalValue(dblFinalValue), m_hold(hold)
{
m_type = DISCRETE;
}
///
/// The amount of time by which to delay the instantaneous switch to the final value.
///
UI_ANIMATION_SECONDS m_delay;
///
/// The value of the animation variable at the end of the transition.
///
DOUBLE m_dblFinalValue;
///
/// The amount of time by which to hold the variable at its final value.
///
UI_ANIMATION_SECONDS m_hold;
///
/// Calls the transition library to create encapsulated transition COM object.
///
///
/// TRUE if transition is created successfully; otherwise FALSE.
///
/// A pointer to transition library, which is responsible for creation of standard transitions.
/// A pointer to transition factory, which is responsible for creation of custom transitions.
BOOL Create(IUIAnimationTransitionLibrary* pLibrary, IUIAnimationTransitionFactory* pFactory) override
{
UNREFERENCED_PARAMETER(pFactory);
Clear();
if (pLibrary != NULL)
{
HRESULT hr = pLibrary->CreateDiscreteTransition(m_delay, m_dblFinalValue, m_hold, &m_transition);
return SUCCEEDED(hr);
}
return FALSE;
}
};
///
/// Encapsulates an instantaneous transition.
///
///
/// During an instantaneous transition, the value of the animation variable changes instantly from its current
/// value to a specified final value. The duration of this transition is always zero.
/// Because all transitions are cleared automatically, it's recommended to allocated them using operator new.
/// The encapsulated IUIAnimationTransition COM object is created by CAnimationController::AnimateGroup, until then
/// it's NULL. Changing member variables after creation of this COM object has no effect.
///
class CInstantaneousTransition : public CBaseTransition
{
public:
///
/// Constructs a transition object and initializes its final value.
///
/// The value of the animation variable at the end of the transition.
CInstantaneousTransition(DOUBLE dblFinalValue) : m_dblFinalValue(dblFinalValue)
{
m_type = INSTANTENEOUS;
}
///
/// The value of the animation variable at the end of the transition.
///
DOUBLE m_dblFinalValue;
///
/// Calls the transition library to create encapsulated transition COM object.
///
///
/// TRUE if transition is created successfully; otherwise FALSE.
///
/// A pointer to transition library, which is responsible for creation of standard transitions.
/// A pointer to transition factory, which is responsible for creation of custom transitions.
BOOL Create(IUIAnimationTransitionLibrary* pLibrary, IUIAnimationTransitionFactory* pFactory) override
{
UNREFERENCED_PARAMETER(pFactory);
Clear();
if (pLibrary != NULL)
{
HRESULT hr = pLibrary->CreateInstantaneousTransition(m_dblFinalValue, &m_transition);
return SUCCEEDED(hr);
}
return FALSE;
}
};
///
/// Encapsulates a linear transition.
///
///
/// During a linear transition, the value of the animation variable transitions linearly from its initial value to a specified final value.
/// Because all transitions are cleared automatically, it's recommended to allocated them using operator new.
/// The encapsulated IUIAnimationTransition COM object is created by CAnimationController::AnimateGroup, until then
/// it's NULL. Changing member variables after creation of this COM object has no effect.
///
class CLinearTransition : public CBaseTransition
{
public:
///
/// Constructs a linear transition object and initializes it with duration and final value.
///
/// The duration of the transition.
/// The value of the animation variable at the end of the transition.
CLinearTransition(UI_ANIMATION_SECONDS duration, DOUBLE dblFinalValue) : m_duration(duration), m_dblFinalValue(dblFinalValue)
{
m_type = LINEAR;
}
///
/// The duration of the transition.
///
UI_ANIMATION_SECONDS m_duration;
///
/// The value of the animation variable at the end of the transition.
///
DOUBLE m_dblFinalValue;
///
/// Calls the transition library to create encapsulated transition COM object.
///
///
/// TRUE if transition is created successfully; otherwise FALSE.
///
/// A pointer to transition library, which is responsible for creation of standard transitions.
/// A pointer to transition factory, which is responsible for creation of custom transitions.
BOOL Create(IUIAnimationTransitionLibrary* pLibrary, IUIAnimationTransitionFactory* pFactory) override
{
UNREFERENCED_PARAMETER(pFactory);
Clear();
if (pLibrary != NULL)
{
HRESULT hr = pLibrary->CreateLinearTransition(m_duration, m_dblFinalValue, &m_transition);
return SUCCEEDED(hr);
}
return FALSE;
}
};
///
/// Encapsulates a linear-speed transition.
///
///
/// During a linear-speed transition, the value of the animation variable changes at a specified rate.
/// The duration of the transition is determined by the difference between the initial value and the specified final value.
/// Because all transitions are cleared automatically, it's recommended to allocated them using operator new.
/// The encapsulated IUIAnimationTransition COM object is created by CAnimationController::AnimateGroup, until then
/// it's NULL. Changing member variables after creation of this COM object has no effect.
///
class CLinearTransitionFromSpeed : public CBaseTransition
{
public:
///
/// Constructs a linear-speed transition object and initializes it with speed and final value.
///
/// The absolute value of the variable's velocity.
/// The value of the animation variable at the end of the transition.
CLinearTransitionFromSpeed(DOUBLE dblSpeed, DOUBLE dblFinalValue) : m_dblSpeed(dblSpeed), m_dblFinalValue(dblFinalValue)
{
m_type = LINEAR_FROM_SPEED;
}
///
/// The absolute value of the variable's velocity.
///
DOUBLE m_dblSpeed;
///
/// The value of the animation variable at the end of the transition.
///
DOUBLE m_dblFinalValue;
///
/// Calls the transition library to create encapsulated transition COM object.
///
///
/// TRUE if transition is created successfully; otherwise FALSE.
///
/// A pointer to transition library, which is responsible for creation of standard transitions.
/// A pointer to transition factory, which is responsible for creation of custom transitions.
BOOL Create(IUIAnimationTransitionLibrary* pLibrary, IUIAnimationTransitionFactory* pFactory) override
{
UNREFERENCED_PARAMETER(pFactory);
Clear();
if (pLibrary != NULL)
{
HRESULT hr = pLibrary->CreateLinearTransitionFromSpeed(m_dblSpeed, m_dblFinalValue, &m_transition);
return SUCCEEDED(hr);
}
return FALSE;
}
};
///
/// Encapsulates a smooth-stop transition.
///
///
/// A smooth-stop transition slows down as it approaches a given final value, and reaches it with a velocity of zero.
/// The duration of the transition is determined by the initial velocity, the difference between the initial and final values,
/// and the specified maximum duration. If there is no solution consisting of a single parabolic arc,
/// this method creates a cubic transition.
/// Because all transitions are cleared automatically, it's recommended to allocated them using operator new.
/// The encapsulated IUIAnimationTransition COM object is created by CAnimationController::AnimateGroup, until then
/// it's NULL. Changing member variables after creation of this COM object has no effect.
///
class CSmoothStopTransition : public CBaseTransition
{
public:
///
/// Constructs a smooth-stop transition and initializes its maximum duration and final value.
///
/// The maximum duration of the transition.
/// The value of the animation variable at the end of the transition.
CSmoothStopTransition(UI_ANIMATION_SECONDS maximumDuration, DOUBLE dblFinalValue) : m_maximumDuration(maximumDuration),
m_dblFinalValue(dblFinalValue)
{
m_type = SMOOTH_STOP;
}
///
/// The maximum duration of the transition.
///
UI_ANIMATION_SECONDS m_maximumDuration;
///
/// The value of the animation variable at the end of the transition.
///
DOUBLE m_dblFinalValue;
///
/// Calls the transition library to create encapsulated transition COM object.
///
///
/// TRUE if transition is created successfully; otherwise FALSE.
///
/// A pointer to transition library, which is responsible for creation of standard transitions.
/// A pointer to transition factory, which is responsible for creation of custom transitions.
BOOL Create(IUIAnimationTransitionLibrary* pLibrary, IUIAnimationTransitionFactory* pFactory) override
{
UNREFERENCED_PARAMETER(pFactory);
Clear();
if (pLibrary != NULL)
{
HRESULT hr = pLibrary->CreateSmoothStopTransition(m_maximumDuration, m_dblFinalValue, &m_transition);
return SUCCEEDED(hr);
}
return FALSE;
}
};
///
/// Encapsulates a parabolic-acceleration transition.
///
///
/// During a parabolic-acceleration transition, the value of the animation variable changes from the initial value
/// to the final value ending at a specified velocity. You can control how quickly the variable reaches the final
/// value by specifying the rate of acceleration.
/// Because all transitions are cleared automatically, it's recommended to allocated them using operator new.
/// The encapsulated IUIAnimationTransition COM object is created by CAnimationController::AnimateGroup, until then
/// it's NULL. Changing member variables after creation of this COM object has no effect.
///
class CParabolicTransitionFromAcceleration : public CBaseTransition
{
public:
///
/// Constructs a parabolic-acceleration transition and initializes it with specified parameters.
///
/// The value of the animation variable at the end of the transition.
/// The velocity of the animation variable at the end of the transition.
/// The acceleration of the animation variable during the transition.
CParabolicTransitionFromAcceleration(DOUBLE dblFinalValue, DOUBLE dblFinalVelocity, DOUBLE dblAcceleration) :
m_dblFinalValue(dblFinalValue), m_dblFinalVelocity(dblFinalVelocity), m_dblAcceleration(dblAcceleration)
{
m_type = PARABOLIC_FROM_ACCELERATION;
}
///
/// The value of the animation variable at the end of the transition.
///
DOUBLE m_dblFinalValue;
///
/// The velocity of the animation variable at the end of the transition.
///
DOUBLE m_dblFinalVelocity;
///
/// The acceleration of the animation variable during the transition.
///
DOUBLE m_dblAcceleration;
///
/// Calls the transition library to create encapsulated transition COM object.
///
///
/// TRUE if transition is created successfully; otherwise FALSE.
///
/// A pointer to transition library, which is responsible for creation of standard transitions.
/// A pointer to transition factory, which is responsible for creation of custom transitions.
BOOL Create(IUIAnimationTransitionLibrary* pLibrary, IUIAnimationTransitionFactory* pFactory) override
{
UNREFERENCED_PARAMETER(pFactory);
Clear();
if (pLibrary != NULL)
{
HRESULT hr = pLibrary->CreateParabolicTransitionFromAcceleration(m_dblFinalValue, m_dblFinalVelocity, m_dblAcceleration, &m_transition);
return SUCCEEDED(hr);
}
return FALSE;
}
};
///
/// Encapsulates a reversal transition.
///
///
/// A reversal transition smoothly changes direction over a given duration.
/// The final value will be the same as the initial value and the final velocity will be the negative of the initial velocity.
/// Because all transitions are cleared automatically, it's recommended to allocated them using operator new.
/// The encapsulated IUIAnimationTransition COM object is created by CAnimationController::AnimateGroup, until then
/// it's NULL. Changing member variables after creation of this COM object has no effect.
///
class CReversalTransition : public CBaseTransition
{
public:
///
/// Constructs a reversal transition object and initializes its duration.
///
/// The duration of the transition.
CReversalTransition(UI_ANIMATION_SECONDS duration) : m_duration(duration)
{
m_type = REVERSAL;
}
///
/// The duration of the transition.
///
UI_ANIMATION_SECONDS m_duration;
///
/// Calls the transition library to create encapsulated transition COM object.
///
///
/// TRUE if transition is created successfully; otherwise FALSE.
///
/// A pointer to transition library, which is responsible for creation of standard transitions.
/// A pointer to transition factory, which is responsible for creation of custom transitions.
BOOL Create(IUIAnimationTransitionLibrary* pLibrary, IUIAnimationTransitionFactory* pFactory) override
{
UNREFERENCED_PARAMETER(pFactory);
Clear();
if (pLibrary != NULL)
{
HRESULT hr = pLibrary->CreateReversalTransition(m_duration, &m_transition);
return SUCCEEDED(hr);
}
return FALSE;
}
};
///
/// Encapsulates a sinusoidal-range transition, with a given range of oscillation.
///
///
/// The value of the animation variable fluctuates between the specified minimum and maximum values over the entire
/// duration of a sinusoidal-range transition. The risingOrFalling parameter is used to disambiguate between the two possible
/// sine waves specified by the other parameters.
/// Because all transitions are cleared automatically, it's recommended to allocated them using operator new.
/// The encapsulated IUIAnimationTransition COM object is created by CAnimationController::AnimateGroup, until then
/// it's NULL. Changing member variables after creation of this COM object has no effect.
///
class CSinusoidalTransitionFromRange : public CBaseTransition
{
public:
///
/// Constructs a transition object.
///
/// The duration of the transition.
/// The value of the animation variable at a trough of the sinusoidal wave.
/// The value of the animation variable at a peak of the sinusoidal wave.
/// The period of oscillation of the sinusoidal wave in seconds.
/// Whether the start of the transition is rising or falling.
CSinusoidalTransitionFromRange(UI_ANIMATION_SECONDS duration, DOUBLE dblMinimumValue, DOUBLE dblMaximumValue,
UI_ANIMATION_SECONDS period, UI_ANIMATION_SLOPE risingOrFalling) : m_duration(duration), m_dblMinimumValue(dblMinimumValue),
m_dblMaximumValue(dblMaximumValue), m_period(period), m_slope(risingOrFalling)
{
m_type = SINUSOIDAL_FROM_RANGE;
}
///
/// The duration of the transition.
///
UI_ANIMATION_SECONDS m_duration;
///
/// The value of the animation variable at a trough of the sinusoidal wave.
///
DOUBLE m_dblMinimumValue;
///
/// The value of the animation variable at a peak of the sinusoidal wave.
///
DOUBLE m_dblMaximumValue;
///
/// The period of oscillation of the sinusoidal wave in seconds.
///
UI_ANIMATION_SECONDS m_period;
///
/// Whether the start of the transition is rising or falling.
///
UI_ANIMATION_SLOPE m_slope;
///
/// Calls the transition library to create encapsulated transition COM object.
///
///
/// TRUE if transition is created successfully; otherwise FALSE.
///
/// A pointer to transition library, which is responsible for creation of standard transitions.
/// A pointer to transition factory, which is responsible for creation of custom transitions.
BOOL Create(IUIAnimationTransitionLibrary* pLibrary, IUIAnimationTransitionFactory* pFactory) override
{
UNREFERENCED_PARAMETER(pFactory);
Clear();
if (pLibrary != NULL)
{
HRESULT hr = pLibrary->CreateSinusoidalTransitionFromRange(m_duration, m_dblMinimumValue, m_dblMaximumValue,
m_period, m_slope, &m_transition);
return SUCCEEDED(hr);
}
return FALSE;
}
};
///
/// Encapsulates a sinusoidal-velocity transition, with an amplitude determined by the animation variable's initial velocity..
///
///
/// The value of the animation variable oscillates around the initial value over the entire duration of a
/// sinusoidal-range transition. The amplitude of the oscillation is determined by the animation variable's velocity
/// when the transition begins.
/// Because all transitions are cleared automatically, it's recommended to allocated them using operator new.
/// The encapsulated IUIAnimationTransition COM object is created by CAnimationController::AnimateGroup, until then
/// it's NULL. Changing member variables after creation of this COM object has no effect.
///
class CSinusoidalTransitionFromVelocity : public CBaseTransition
{
public:
///
/// Constructs a transition object.
///
/// The duration of the transition.
/// The period of oscillation of the sinusoidal wave in seconds.
CSinusoidalTransitionFromVelocity(UI_ANIMATION_SECONDS duration, UI_ANIMATION_SECONDS period) : m_duration(duration), m_period(period)
{
m_type = SINUSOIDAL_FROM_VELOCITY;
}
///
/// The duration of the transition.
///
UI_ANIMATION_SECONDS m_duration;
///
/// The period of oscillation of the sinusoidal wave in seconds.
///
UI_ANIMATION_SECONDS m_period;
///
/// Calls the transition library to create encapsulated transition COM object.
///
///
/// TRUE if transition is created successfully; otherwise FALSE.
///
/// A pointer to transition library, which is responsible for creation of standard transitions.
/// A pointer to transition factory, which is responsible for creation of custom transitions.
BOOL Create(IUIAnimationTransitionLibrary* pLibrary, IUIAnimationTransitionFactory* pFactory) override
{
UNREFERENCED_PARAMETER(pFactory);
Clear();
if (pLibrary != NULL)
{
HRESULT hr = pLibrary->CreateSinusoidalTransitionFromVelocity(m_duration, m_period, &m_transition);
return SUCCEEDED(hr);
}
return FALSE;
}
};
//---------------------------------
// Support for custom transitions
//---------------------------------
///
/// Implements a basic interpolator.
///
///
/// Derive a class from CCustomInterpolator and override all necessary methods in order to implement a custom
/// interpolation algorithm. A pointer to this class should be passed as a parameter to CCustomTransition.
///
class CCustomInterpolator
{
protected:
///
/// The duration of the transition.
///
UI_ANIMATION_SECONDS m_duration;
///
/// The final value of a variable at the end of the transition.
///
DOUBLE m_finalValue;
///
/// The value of the variable at the start of the transition.
///
DOUBLE m_initialValue;
///
/// The velocity of the variable at the start of the transition.
///
DOUBLE m_initialVelocity;
///
/// The interpolated value.
///
DOUBLE m_currentValue;
///
/// The interpolated velocity.
///
DOUBLE m_currentVelocity;
public:
///
/// Constructs a custom interpolator object and sets all values to default 0.
///
///
/// Use CCustomInterpolator::Init to initialize duration and final value later in the code.
///
CCustomInterpolator() : m_duration(0.), m_finalValue(0.), m_initialValue(0.), m_initialVelocity(0.), m_currentValue(0.),
m_currentVelocity(0.)
{
}
///
/// Constructs a custom interpolator object and initializes duration and velocity to specified values.
///
/// The duration of the transition.
///
CCustomInterpolator(UI_ANIMATION_SECONDS duration, DOUBLE finalValue) :
m_duration(duration), m_finalValue(finalValue), m_initialValue(0.), m_initialVelocity(0.), m_currentValue(0.), m_currentVelocity(0.)
{
}
///
/// Initializes duration and final value.
///
/// The duration of the transition.
/// The final value of a variable at the end of the transition.
void Init(UI_ANIMATION_SECONDS duration, DOUBLE finalValue)
{
m_duration = duration;
m_finalValue = finalValue;
}
///
/// Sets the interpolator's initial value and velocity.
///
///
/// The basic implementation always returns TRUE. Return FALSE from overridden implementation if you wish to fail the event.
///
/// The value of the variable at the start of the transition.
/// The velocity of the variable at the start of the transition.
virtual BOOL SetInitialValueAndVelocity(DOUBLE initialValue, DOUBLE initialVelocity)
{
m_initialValue = initialValue;
m_initialVelocity = initialVelocity;
m_currentValue = initialValue;
m_currentVelocity = initialVelocity;
return TRUE;
}
///
/// Sets the interpolator's duration.
///
///
/// Basic implementation always returns TRUE. Return FALSE from overridden implementation if you wish to fail the event.
///
/// The duration of the transition.
virtual BOOL SetDuration(UI_ANIMATION_SECONDS duration)
{
m_duration = duration;
return TRUE;
}
///
/// Gets the interpolator's duration.
///
///
/// Basic implementation always returns TRUE. Return FALSE from overridden implementation if you wish to fail the event.
///
/// Output. The duration of the transition, in seconds.
virtual BOOL GetDuration(UI_ANIMATION_SECONDS *duration)
{
*duration = m_duration;
return TRUE;
}
///
/// Gets the final value to which the interpolator leads.
///
///
/// Basic implementation always returns TRUE. Return FALSE from overridden implementation if you wish to fail the event.
///
/// Output. The final value of a variable at the end of the transition.
virtual BOOL GetFinalValue(DOUBLE *value)
{
*value = m_finalValue;
return TRUE;
}
///
/// Interpolates the value at a given offset.
///
///
/// Basic implementation always returns TRUE. Return FALSE from overridden implementation if you wish to fail the event.
///
/// The offset from the start of the transition.
/// The offset is always greater than or equal to zero and less than the duration of the transition.
/// This method is not called if the duration of the transition is zero.
/// Output. The interpolated value.
virtual BOOL InterpolateValue(UI_ANIMATION_SECONDS offset, DOUBLE *value)
{
UNREFERENCED_PARAMETER(offset);
*value = m_currentValue;
return TRUE;
}
///
/// Interpolates the velocity at a given offset
///
///
/// Basic implementation always returns TRUE. Return FALSE from overridden implementation if you wish to fail the event.
///
/// The offset from the start of the transition.
/// The offset is always greater than or equal to zero and less than or equal to the duration of the transition.
/// This method is not called if the duration of the transition is zero.
/// Output. The velocity of the variable at the offset.
virtual BOOL InterpolateVelocity(UI_ANIMATION_SECONDS offset, DOUBLE *velocity)
{
UNREFERENCED_PARAMETER(offset);
*velocity = m_currentVelocity;
return TRUE;
}
///
/// Gets the interpolator's dependencies.
///
///
/// Basic implementation always returns TRUE. Return FALSE from overridden implementation if you wish to fail the event.
///
/// Output. Aspects of the interpolator that depend on the initial value passed to SetInitialValueAndVelocity.
/// Output. Aspects of the interpolator that depend on the initial velocity passed to SetInitialValueAndVelocity.
/// Output. Aspects of the interpolator that depend on the duration passed to SetDuration.
virtual BOOL GetDependencies(UI_ANIMATION_DEPENDENCIES *initialValueDependencies,
UI_ANIMATION_DEPENDENCIES *initialVelocityDependencies, UI_ANIMATION_DEPENDENCIES *durationDependencies)
{
*initialValueDependencies = UI_ANIMATION_DEPENDENCY_NONE;
*initialVelocityDependencies = UI_ANIMATION_DEPENDENCY_NONE;
*durationDependencies = UI_ANIMATION_DEPENDENCY_NONE;
return TRUE;
}
};
///
/// Implements a callback, which is called by Animation API when it needs to calculate a new value of animation variable.
///
///
/// This handler is created and passed to IUIAnimationTransitionFactory::CreateTransition when a CCustomTransition
/// object is being created as a part of animation initialization process (started by CAnimationController::AnimateGroup).
/// Usually you don't need to use this class directly, it just routs all events to a CCustomInterpolator-derived class, whose
/// pointer is passed to constructor of CCustomTransition.
///
class CInterpolatorBase : public CUIAnimationInterpolatorBase
{
CCustomInterpolator* m_pInterpolator;
public:
///
/// Constructs the CInterpolatorBase object.
///
CInterpolatorBase() : m_pInterpolator(NULL)
{
}
///
/// Stores a pointer to custom interpolator, which will be handling events.
///
/// A pointer to custom interpolator.
void SetCustomInterpolator(CCustomInterpolator* pInterpolator)
{
m_pInterpolator = pInterpolator;
}
///
/// Creates an instance of CInterpolatorBase and stores a pointer to custom interpolator, which will be handling events.
///
/// If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
/// A pointer to custom interpolator.
/// Output. Contains a pointer to instance of CInterpolatorBase when the function returns.
static COM_DECLSPEC_NOTHROW HRESULT CreateInstance(CCustomInterpolator* pInterpolator, IUIAnimationInterpolator **ppHandler)
{
CInterpolatorBase* pHandler = NULL;
HRESULT hr = CUIAnimationCallbackBase::CreateInstance(ppHandler, &pHandler);
if (SUCCEEDED(hr) && pHandler != NULL)
{
pHandler->SetCustomInterpolator(pInterpolator);
}
return hr;
}
///
/// Sets the interpolator's initial value and velocity.
///
///
/// If the method succeeds, it returns S_OK. It returns E_FAIL if CCustomInterpolator is not
/// set, or custom implementation returns FALSE from the SetInitialValueAndVelocity method.
///
/// The value of the variable at the start of the transition.
/// The velocity of the variable at the start of the transition.
#pragma warning(suppress:26433)
IFACEMETHOD(SetInitialValueAndVelocity)(_In_ DOUBLE initialValue, _In_ DOUBLE initialVelocity)
{
if (m_pInterpolator == NULL || !m_pInterpolator->SetInitialValueAndVelocity(initialValue, initialVelocity))
{
return E_FAIL;
}
return S_OK;
}
///
/// Sets the interpolator's duration
///
///
/// If the method succeeds, it returns S_OK. It returns E_FAIL if CCustomInterpolator is not
/// set, or custom implementation returns FALSE from the SetDuration method.
///
/// The duration of the transition.
#pragma warning(suppress:26433)
IFACEMETHOD(SetDuration)(_In_ UI_ANIMATION_SECONDS duration)
{
if (m_pInterpolator == NULL || !m_pInterpolator->SetDuration(duration))
{
return E_FAIL;
}
return S_OK;
}
///
/// Gets the interpolator's duration.
///
///
/// If the method succeeds, it returns S_OK. It returns E_FAIL if CCustomInterpolator is not
/// set, or custom implementation returns FALSE from the GetDuration method.
///
/// Output. The duration of the transition, in seconds.
#pragma warning(suppress:26433)
IFACEMETHOD(GetDuration)(_Out_ UI_ANIMATION_SECONDS *duration)
{
if (m_pInterpolator == NULL || !m_pInterpolator->GetDuration(duration))
{
return E_FAIL;
}
return S_OK;
}
///
/// Gets the final value to which the interpolator leads.
///
///
/// If the method succeeds, it returns S_OK. It returns E_FAIL if CCustomInterpolator is not
/// set, or custom implementation returns FALSE from the GetFinalValue method.
///
/// Output. The final value of a variable at the end of the transition.
#pragma warning(suppress:26433)
IFACEMETHOD(GetFinalValue)(_Out_ DOUBLE *value)
{
if (m_pInterpolator == NULL || !m_pInterpolator->GetFinalValue(value))
{
return E_FAIL;
}
return S_OK;
}
///
/// Interpolates the value at a given offset
///
///
/// If the method succeeds, it returns S_OK. It returns E_FAIL if CCustomInterpolator is not
/// set, or custom implementation returns FALSE from the InterpolateValue method.
///
/// The offset from the start of the transition.
/// The offset is always greater than or equal to zero and less than the duration of the transition.
/// This method is not called if the duration of the transition is zero.
/// Output. The interpolated value.
#pragma warning(suppress:26433)
IFACEMETHOD(InterpolateValue)(_In_ UI_ANIMATION_SECONDS offset, _Out_ DOUBLE *value)
{
if (m_pInterpolator == NULL || !m_pInterpolator->InterpolateValue(offset, value))
{
return E_FAIL;
}
return S_OK;
}
///
/// Interpolates the velocity at a given offset
///
///
/// If the method succeeds, it returns S_OK. It returns E_FAIL if CCustomInterpolator is not
/// set, or custom implementation returns FALSE from the InterpolateVelocity method.
///
/// The offset from the start of the transition.
/// The offset is always greater than or equal to zero and less than or equal to the duration of the transition.
/// This method is not called if the duration of the transition is zero.
/// Output. The velocity of the variable at the offset.
#pragma warning(suppress:26433)
IFACEMETHOD(InterpolateVelocity)(_In_ UI_ANIMATION_SECONDS offset, _Out_ DOUBLE *velocity)
{
if (m_pInterpolator == NULL || !m_pInterpolator->InterpolateVelocity(offset, velocity))
{
return E_FAIL;
}
return S_OK;
}
///
/// Gets the interpolator's dependencies.
///
///
/// If the method succeeds, it returns S_OK. It returns E_FAIL if CCustomInterpolator is not
/// set, or custom implementation returns FALSE from the GetDependencies method.
///
/// Output. Aspects of the interpolator that depend on the initial value passed to SetInitialValueAndVelocity.
/// Output. Aspects of the interpolator that depend on the initial velocity passed to SetInitialValueAndVelocity.
/// Output. Aspects of the interpolator that depend on the duration passed to SetDuration.
#pragma warning(suppress:26433)
IFACEMETHOD(GetDependencies)(_Out_ UI_ANIMATION_DEPENDENCIES *initialValueDependencies, _Out_ UI_ANIMATION_DEPENDENCIES *initialVelocityDependencies,
_Out_ UI_ANIMATION_DEPENDENCIES *durationDependencies)
{
if (m_pInterpolator == NULL || !m_pInterpolator->GetDependencies(initialValueDependencies, initialVelocityDependencies, durationDependencies))
{
return E_FAIL;
}
return S_OK;
}
};
///
/// Implements custom transition.
///
///
/// The CCustomTransitions class allows developers to implement custom transitions. It's created and used
/// as a standard transition, but its constructor accepts as parameter a pointer to a custom interpolator.
/// Perform the following steps to use custom transitions:
/// 1. Derive a class from CCustomInterpolator and implement at least InterpolateValue method.
/// 2. Ensure that the lifetime of custom interpolator object must be longer than duration of animation where it's used.
/// 3. Instantiate (using operator new) a CCustomTransition object and pass a pointer to custom interpolator in the constructor.
/// 4. Call CCustomTransition::SetInitialValue and CCustomTransition::SetInitialVelocity if these parameters are required for custom interpolation.
/// 5. Pass the pointer to custom transition to AddTransition method of animation object, whose value should be animated with the custom algorithm.
/// 6. When the value of animation object should change Windows Animation API will call InterpolateValue (and other relevant methods) in CCustomInterpolator.
///
class CCustomTransition : public CBaseTransition
{
protected:
///
/// Stores a pointer to a custom interpolator.
///
CCustomInterpolator* m_pInterpolator;
///
/// Specifies whether the initial value was specified with SetInitialValue.
///
BOOL m_bInitialValueSpecified;
///
/// Specifies whether the initial velocity was specified with SetInitialVelocity.
///
BOOL m_bInitialVelocitySpecified;
///
/// Stores the initial value.
///
DOUBLE m_initialValue;
///
/// Stores the initial velocity.
///
DOUBLE m_initialVelocity;
public:
///
/// Constructs a custom transition object.
///
/// A pointer to custom interpolator.
CCustomTransition(CCustomInterpolator* pInterpolator)
{
m_pInterpolator = pInterpolator;
m_bInitialValueSpecified = FALSE;
m_bInitialVelocitySpecified = FALSE;
m_initialValue = 0.;
m_initialVelocity = 0.;
m_type = CUSTOM;
}
///
/// Sets an initial value, which will be applied to an animation variable associated with this transition.
///
void SetInitialValue(DOUBLE initialValue)
{
m_initialValue = initialValue;
m_bInitialValueSpecified = TRUE;
}
///
/// Sets an initial velocity, which will be applied to an animation variable associated with this transition.
///
void SetInitialVelocity(DOUBLE initialVelocity)
{
m_initialVelocity = initialVelocity;
m_bInitialVelocitySpecified = TRUE;
}
///
/// Calls the transition library to create encapsulated transition COM object.
///
///
/// This method also can set initial value and initial velocity to be applied to an animation variable, which is
/// associated with this transition. For this purpose you have to call SetInitialValue and SetInitialVelocity before
/// the framework creates the encapsulated transition COM object (it happens when you call CAnimationController::AnimateGroup).
///
/// A pointer to transition library, which is responsible for creation of standard transitions.
/// A pointer to transition factory, which is responsible for creation of custom transitions.
BOOL Create(IUIAnimationTransitionLibrary* pLibrary, IUIAnimationTransitionFactory* pFactory) override
{
(void)pLibrary;
Clear();
if (pFactory != NULL && m_pInterpolator != NULL)
{
ATL::CComPtr pHandler;
if (FAILED(CInterpolatorBase::CreateInstance(m_pInterpolator, &pHandler)))
{
TRACE(_T("Failed to create custom transition.\n"));
return FALSE;
}
HRESULT hr = pFactory->CreateTransition(pHandler, &m_transition);
if (FAILED(hr) || m_transition == NULL)
{
TRACE1("Transition factory failed to create custom transition. Error code: %x.\n", hr);
return FALSE;
}
if (m_bInitialValueSpecified)
{
hr = m_transition->SetInitialValue(m_initialValue);
ASSERT(SUCCEEDED(hr));
}
if (m_bInitialVelocitySpecified)
{
hr = m_transition->SetInitialVelocity(m_initialVelocity);
ASSERT(SUCCEEDED(hr));
}
return TRUE;
}
return FALSE;
}
};
#ifdef _AFX_MINREBUILD
#pragma component(minrebuild, on)
#endif
#ifdef _AFX_PACKING
#pragma pack(pop)
#endif
// _ATLMFC_DISABLED_WARNINGS
#pragma warning(pop)