//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // //=============================================================================// #ifndef ANIMATIONCONTROLLER_H #define ANIMATIONCONTROLLER_H #ifdef _WIN32 #pragma once #endif #include #include #include "tier1/utlsymbol.h" #include "tier1/utlvector.h" namespace vgui { //----------------------------------------------------------------------------- // Purpose: Handles controlling panel animation // It is never visible, but needs to be a panel so that can receive messages //----------------------------------------------------------------------------- class AnimationController : public Panel { DECLARE_CLASS_SIMPLE( AnimationController, Panel ); public: AnimationController(Panel *parent); ~AnimationController(); // sets which script file to use bool SetScriptFile( VPANEL sizingPanel, const char *fileName, bool wipeAll = false ); // reloads the currently set script file void ReloadScriptFile(); // runs a frame of animation (time is passed in so slow motion, etc. works) void UpdateAnimations( float curtime ); int GetNumActiveAnimations( void ) { return m_ActiveAnimations.Count(); } // plays all animations to completion instantly void RunAllAnimationsToCompletion(); // stops all animations void CancelAllAnimations(); // starts an animation sequence script bool StartAnimationSequence(const char *sequenceName, bool bCanBeCancelled = true ); bool StartAnimationSequence(Panel *pWithinParent, const char *sequenceName, bool bCanBeCancelled = true ); bool StopAnimationSequence( Panel *pWithinParent, const char *sequenceName ); void CancelAnimationsForPanel( Panel *pWithinParent ); // gets the length of an animation sequence, in seconds float GetAnimationSequenceLength(const char *sequenceName); // sets that the script file should be reloaded each time a script is ran // used for development void SetAutoReloadScript(bool state); enum Interpolators_e { INTERPOLATOR_LINEAR, INTERPOLATOR_ACCEL, INTERPOLATOR_DEACCEL, INTERPOLATOR_PULSE, INTERPOLATOR_FLICKER, INTERPOLATOR_SIMPLESPLINE, // ease in / out INTERPOLATOR_BOUNCE, // gravitational bounce INTERPOLATOR_BIAS, INTERPOLATOR_GAIN, }; // runs the specific animation command (doesn't use script file at all) void RunAnimationCommand(vgui::Panel *panel, const char *variable, float targetValue, float startDelaySeconds, float durationSeconds, Interpolators_e interpolator, float animParameter = 0 ); void RunAnimationCommand(vgui::Panel *panel, const char *variable, Color targetValue, float startDelaySeconds, float durationSeconds, Interpolators_e interpolator, float animParameter = 0 ); private: bool UpdateScreenSize(); bool LoadScriptFile(const char *fileName); bool ParseScriptFile(char *pMem, int length); void UpdatePostedMessages(bool bRunToCompletion); void UpdateActiveAnimations(bool bRunToCompletion); bool m_bAutoReloadScript; float m_flCurrentTime; enum AnimCommandType_e { CMD_ANIMATE, CMD_RUNEVENT, CMD_STOPEVENT, CMD_STOPANIMATION, CMD_STOPPANELANIMATIONS, CMD_SETFONT, CMD_SETTEXTURE, CMD_SETSTRING, CMD_RUNEVENTCHILD, CMD_FIRECOMMAND, CMD_PLAYSOUND, CMD_SETVISIBLE, CMD_SETINPUTENABLED, }; enum RelativeAlignment { a_northwest = 0, a_north, a_northeast, a_west, a_center, a_east, a_southwest, a_south, a_southeast, }; struct RelativeAlignmentLookup { RelativeAlignment align; char const *name; }; // a single animatable value // some var types use 1, 2, 3 or all 4 of the values struct Value_t { float a, b, c, d; }; struct AnimAlign_t { // For Position, Xpos, YPos bool relativePosition; UtlSymId_t alignPanel; RelativeAlignment alignment; }; // info for the animate command struct AnimCmdAnimate_t { UtlSymId_t panel; UtlSymId_t variable; Value_t target; int interpolationFunction; float interpolationParameter; float startTime; float duration; AnimAlign_t align; }; // info for the run event command struct AnimCmdEvent_t { UtlSymId_t event; UtlSymId_t variable; UtlSymId_t variable2; float timeDelay; }; // holds a single command from an animation sequence struct AnimCommand_t { AnimCommandType_e commandType; union { AnimCmdAnimate_t animate; AnimCmdEvent_t runEvent; } cmdData; }; // holds a full sequence struct AnimSequence_t { UtlSymId_t name; float duration; CUtlVector cmdList; }; // holds the list of sequences CUtlVector m_Sequences; // list of active animations struct ActiveAnimation_t { PHandle panel; UtlSymId_t seqName; // the sequence this belongs to UtlSymId_t variable; bool started; Value_t startValue; Value_t endValue; int interpolator; float interpolatorParam; float startTime; float endTime; bool canBeCancelled; AnimAlign_t align; }; CUtlVector m_ActiveAnimations; // posted messages struct PostedMessage_t { AnimCommandType_e commandType; UtlSymId_t seqName; UtlSymId_t event; UtlSymId_t variable; UtlSymId_t variable2; float startTime; PHandle parent; bool canBeCancelled; }; CUtlVector m_PostedMessages; struct RanEvent_t { UtlSymId_t event; Panel *pParent; bool operator==( const RanEvent_t &other ) const { return ( event == other.event && pParent == other.pParent ); } }; // variable names UtlSymId_t m_sPosition, m_sSize, m_sFgColor, m_sBgColor; UtlSymId_t m_sXPos, m_sYPos, m_sWide, m_sTall; UtlSymId_t m_sModelPos; // file name CUtlVector m_ScriptFileNames; // runs a single line of the script void ExecAnimationCommand(UtlSymId_t seqName, AnimCommand_t &animCommand, Panel *pWithinParent, bool bCanBeCancelled); // removes all commands belonging to a script void RemoveQueuedAnimationCommands(UtlSymId_t seqName, vgui::Panel *panel = NULL); // removes an existing instance of a command void RemoveQueuedAnimationByType(vgui::Panel *panel, UtlSymId_t variable, UtlSymId_t sequenceToIgnore); // handlers void StartCmd_Animate(UtlSymId_t seqName, AnimCmdAnimate_t &cmd, Panel *pWithinParent, bool bCanBeCancelled); void StartCmd_Animate(Panel *panel, UtlSymId_t seqName, AnimCmdAnimate_t &cmd, bool bCanBeCancelled); void RunCmd_RunEvent(PostedMessage_t &msg); void RunCmd_StopEvent(PostedMessage_t &msg); void RunCmd_StopPanelAnimations(PostedMessage_t &msg); void RunCmd_StopAnimation(PostedMessage_t &msg); void RunCmd_SetFont(PostedMessage_t &msg); void RunCmd_SetTexture(PostedMessage_t &msg); void RunCmd_SetString(PostedMessage_t &msg); // value access Value_t GetValue(ActiveAnimation_t& anim, Panel *panel, UtlSymId_t var); void SetValue(ActiveAnimation_t& anim, Panel *panel, UtlSymId_t var, Value_t &value); // interpolation Value_t GetInterpolatedValue(int interpolator, float interpolatorParam, float currentTime, float startTime, float endTime, Value_t &startValue, Value_t &endValue); void SetupPosition( AnimCmdAnimate_t& cmd, float *output, char const *psz, int screendimension ); static RelativeAlignment LookupAlignment( char const *token ); static RelativeAlignmentLookup g_AlignmentLookup[]; int GetRelativeOffset( AnimAlign_t& cmd, bool xcoord ); VPANEL m_hSizePanel; int m_nScreenBounds[ 4 ]; }; // singleton accessor for use only by other vgui_controls extern AnimationController *GetAnimationController(); } // namespace vgui #endif // ANIMATIONCONTROLLER_H