This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
2020-08-04 13:13:01 -04:00

280 lines
8.4 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef ANIMATIONCONTROLLER_H
#define ANIMATIONCONTROLLER_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/PHandle.h>
#include <vgui_controls/Panel.h>
#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 StartAnimationSequence(Panel *pWithinParent, const char *sequenceName);
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
};
// 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_SETVISIBLE,
};
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<AnimCommand_t> cmdList;
};
// holds the list of sequences
CUtlVector<AnimSequence_t> 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;
AnimAlign_t align;
};
CUtlVector<ActiveAnimation_t> 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;
};
CUtlVector<PostedMessage_t> 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<UtlSymId_t> m_ScriptFileNames;
// runs a single line of the script
void ExecAnimationCommand(UtlSymId_t seqName, AnimCommand_t &animCommand,
Panel *pWithinParent);
// 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);
void StartCmd_Animate(Panel *panel, UtlSymId_t seqName,
AnimCmdAnimate_t &cmd);
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