VGUI Image Progress Bar
This is an extension of the ContinuousProgressBar
class that Valve already has in place in the VGUI lib (Orange Box). This tutorial is a purely copy/paste tutorial and should not require any modification. If there are any areas that need improvement or corrections, feel free to make/add them.
The Header (.h) File
game/client/game_controls/ImageProgressBar.h
#ifndef IMAGEPROGRESSBAR_H
#define IMAGEPROGRESSBAR_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui/VGUI.h>
#include <vgui_controls/ProgressBar.h>
using namespace vgui;
class ImageProgressBar : public ContinuousProgressBar
{
DECLARE_CLASS_SIMPLE( ImageProgressBar, ContinuousProgressBar );
public:
ImageProgressBar( Panel *parent, const char *panelName );
ImageProgressBar( Panel *parent, const char *panelName, const char *topTexturename, const char *bottomTextureName );
virtual void Paint( void );
virtual void ApplySettings( KeyValues *inResourceData );
virtual void GetSettings( KeyValues *outResourceData );
void SetTopTexture( const char *topTextureName );
void SetBottomTexture( const char *bottomTextureName );
private:
int m_iTopTextureId;
int m_iBottomTextureId;
char m_szTopTextureName[64];
char m_szBottomTextureName[64];
};
#endif
The Source (.cpp) File
game/client/game_controls/ImageProgressBar.cpp
#include "cbase.h"
#include <vgui/ISurface.h>
#include <KeyValues.h>
#include "ImageProgressBar.h"
#include "tier0/memdbgon.h"
using namespace vgui;
DECLARE_BUILD_FACTORY( ImageProgressBar );
ImageProgressBar::ImageProgressBar( Panel *parent, const char *panelName ) : BaseClass( parent, panelName )
{
m_iTopTextureId = m_iBottomTextureId = -1;
memset( m_szTopTextureName, 0, sizeof( m_szTopTextureName ) );
memset( m_szBottomTextureName, 0, sizeof( m_szBottomTextureName ) );
}
ImageProgressBar::ImageProgressBar(vgui::Panel *parent, const char *panelName, const char *topTextureName, const char *bottomTextureName ) : BaseClass( parent, panelName )
{
SetTopTexture( topTextureName );
SetBottomTexture( bottomTextureName );
}
void ImageProgressBar::SetTopTexture(const char *topTextureName)
{
if( topTextureName != NULL && topTextureName[0] )
{
Q_strncpy( m_szTopTextureName, topTextureName, 64 );
m_iTopTextureId = surface()->DrawGetTextureId( topTextureName );
if( m_iTopTextureId == -1 )
{
m_iTopTextureId = surface()->CreateNewTextureID();
surface()->DrawSetTextureFile( m_iTopTextureId, topTextureName, false, true );
}
}
else
{
memset( m_szTopTextureName, 0, sizeof( m_szTopTextureName ) );
m_iTopTextureId = -1;
}
}
void ImageProgressBar::SetBottomTexture(const char *bottomTextureName)
{
if( bottomTextureName != NULL && bottomTextureName[0] )
{
Q_strncpy( m_szBottomTextureName, bottomTextureName, 64 );
m_iBottomTextureId = surface()->DrawGetTextureId( bottomTextureName );
if( m_iBottomTextureId == -1 )
{
m_iBottomTextureId = surface()->CreateNewTextureID();
surface()->DrawSetTextureFile( m_iBottomTextureId, bottomTextureName, false, true );
}
}
else
{
memset( m_szBottomTextureName, 0, sizeof( m_szBottomTextureName ) );
m_iBottomTextureId = -1;
}
}
void ImageProgressBar::ApplySettings( KeyValues *inResourceData )
{
const char *topTextureName = inResourceData->GetString("TopImage", "");
SetTopTexture( topTextureName );
const char *bottomTextureName = inResourceData->GetString("BottomImage", "");
SetBottomTexture( bottomTextureName );
BaseClass::ApplySettings( inResourceData );
}
void ImageProgressBar::GetSettings( KeyValues *outResourceData )
{
BaseClass::GetSettings( outResourceData );
outResourceData->SetString( "TopImage", m_szTopTextureName );
outResourceData->SetString( "BottomImage", m_szBottomTextureName );
}
void ImageProgressBar::Paint( void )
{
if( m_iTopTextureId == -1 )
return;
int x = 0, y = 0;
int wide, tall;
GetSize( wide, tall );
if( m_iBottomTextureId != -1 )
{
surface()->DrawSetTexture( m_iBottomTextureId );
surface()->DrawSetColor( 255, 255, 255, 255 );
surface()->DrawTexturedRect( x, y, wide, tall );
}
surface()->DrawSetTexture( m_iTopTextureId );
surface()->DrawSetColor( 255, 255, 255, 255 );
switch( m_iProgressDirection )
{
case PROGRESS_EAST:
surface()->DrawTexturedSubRect( x, y, x + (int)(wide * _progress), y + tall,
0.0f, 0.0f, _progress, 1.0f );
break;
case PROGRESS_WEST:
surface()->DrawTexturedSubRect( x + (int)(wide * (1.0f - _progress) ), y, x + wide, y + tall,
1.0f - _progress, 0.0f, 1.0f, 1.0f );
break;
case PROGRESS_NORTH:
surface()->DrawTexturedSubRect( x, y + (int)(tall * (1.0f - _progress) ), x + wide, y + tall,
0.0f, 0.0f, 1.0f, _progress );
break;
case PROGRESS_SOUTH:
surface()->DrawTexturedSubRect( x, y, x + wide, y + (int)( tall * _progress),
0.0f, 1.0f - _progress, 1.0f, 1.0f );
break;
}
}
Usage
To use this in a .res file, use it like any other progress bar. There are added keys to the *.res file so it is possible to change the images via text instead of hard-code. Here's an example that does not use a background progress bar image. Background progress images aren't required, but can be used if needed:
First, include the ImageProgressBar class.
#include "ImageProgressBar.h"
Next, declare the new handle for the image progress bar for the new hud class:
protected:
ImageProgressBar *m_pHealthProgressBar;
Place this within the constructor of your new hud class:
m_pHealthProgressBar = new ImageProgressBar( this, "HealthProgressBar", "vgui/gfx/HUD/health_bar");
m_pHealthProgressBar->SetProgressDirection( ProgressBar::PROGRESS_EAST );
If top and bottom materials need to be added via code, add this instead of the code above:
m_pHealthProgressBar = new ImageProgressBar( this, "HealthProgressBar");
m_pHealthProgressBar->SetProgressDirection( ProgressBar::PROGRESS_EAST );
m_pHealthProgressBar->SetTopTexture( <top texture> );
m_pHealthProgressBar->SetBottomTexture( <bottom texture> );
And place this within the Think function of the hud class:
//Edit this part for whatever value your image bar needs to be.
m_pHealthProgressBar->SetProgress( Value );
And to finish it off, place this inside \scripts\HudLayout.res:
"HealthProgressBar" { "ControlName" "ImageProgressBar" "fieldName" "HealthProgressBar" "xpos" "10" "ypos" "25" "wide" "200" "tall" "32" "autoResize" "1" "visible" "1" "enabled" "1" "tabPosition" "0" }