You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
200 lines
6.4 KiB
200 lines
6.4 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#include <assert.h> |
|
#include <math.h> |
|
#include <stdio.h> |
|
|
|
#include <vgui_controls/RotatingProgressBar.h> |
|
|
|
#include <vgui/IVGui.h> |
|
#include <vgui/ILocalize.h> |
|
#include <vgui/IScheme.h> |
|
#include <vgui/ISurface.h> |
|
#include <KeyValues.h> |
|
|
|
#include "mathlib/mathlib.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include <tier0/memdbgon.h> |
|
|
|
using namespace vgui; |
|
|
|
DECLARE_BUILD_FACTORY( RotatingProgressBar ); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Constructor |
|
//----------------------------------------------------------------------------- |
|
RotatingProgressBar::RotatingProgressBar(Panel *parent, const char *panelName) : ProgressBar(parent, panelName) |
|
{ |
|
m_flStartRadians = 0; |
|
m_flEndRadians = 0; |
|
m_flLastAngle = 0; |
|
|
|
m_nTextureId = -1; |
|
m_pszImageName = NULL; |
|
|
|
m_flTickDelay = 30; |
|
|
|
ivgui()->AddTickSignal(GetVPanel(), m_flTickDelay ); |
|
|
|
SetPaintBorderEnabled(false); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Destructor |
|
//----------------------------------------------------------------------------- |
|
RotatingProgressBar::~RotatingProgressBar() |
|
{ |
|
if ( vgui::surface() && m_nTextureId != -1 ) |
|
{ |
|
vgui::surface()->DestroyTextureID( m_nTextureId ); |
|
m_nTextureId = -1; |
|
} |
|
|
|
delete [] m_pszImageName; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void RotatingProgressBar::ApplySettings(KeyValues *inResourceData) |
|
{ |
|
const char *imageName = inResourceData->GetString("image", ""); |
|
if (*imageName) |
|
{ |
|
SetImage( imageName ); |
|
} |
|
|
|
// Find min and max rotations in radians |
|
m_flStartRadians = DEG2RAD(inResourceData->GetFloat( "start_degrees", 0 ) ); |
|
m_flEndRadians = DEG2RAD( inResourceData->GetFloat( "end_degrees", 0 ) ); |
|
|
|
// Start at 0 progress |
|
m_flLastAngle = m_flStartRadians; |
|
|
|
// approach speed is specified in degrees per second. |
|
// convert to radians per 1/30th of a second |
|
float flDegressPerSecond = DEG2RAD( inResourceData->GetFloat( "approach_speed", 360.0 ) ); // default is super fast |
|
m_flApproachSpeed = flDegressPerSecond * ( m_flTickDelay / 1000.0f ); // divide by number of frames in a second |
|
|
|
m_flRotOriginX = inResourceData->GetFloat( "rot_origin_x_percent", 0.5f ); |
|
m_flRotOriginY = inResourceData->GetFloat( "rot_origin_y_percent", 0.5f ); |
|
|
|
m_flRotatingX = inResourceData->GetFloat( "rotating_x", 0 ); |
|
m_flRotatingY = inResourceData->GetFloat( "rotating_y", 0 ); |
|
m_flRotatingWide = inResourceData->GetFloat( "rotating_wide", 0 ); |
|
m_flRotatingTall = inResourceData->GetFloat( "rotating_tall", 0 ); |
|
|
|
BaseClass::ApplySettings( inResourceData ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void RotatingProgressBar::ApplySchemeSettings(IScheme *pScheme) |
|
{ |
|
BaseClass::ApplySchemeSettings(pScheme); |
|
|
|
if ( m_pszImageName && strlen( m_pszImageName ) > 0 ) |
|
{ |
|
if ( m_nTextureId == -1 ) |
|
{ |
|
m_nTextureId = surface()->CreateNewTextureID(); |
|
} |
|
|
|
surface()->DrawSetTextureFile( m_nTextureId, m_pszImageName, true, false); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: sets an image by file name |
|
//----------------------------------------------------------------------------- |
|
void RotatingProgressBar::SetImage(const char *imageName) |
|
{ |
|
if ( m_pszImageName ) |
|
{ |
|
delete [] m_pszImageName; |
|
m_pszImageName = NULL; |
|
} |
|
|
|
const char *pszDir = "vgui/"; |
|
int len = Q_strlen(imageName) + 1; |
|
len += strlen(pszDir); |
|
m_pszImageName = new char[ len ]; |
|
Q_snprintf( m_pszImageName, len, "%s%s", pszDir, imageName ); |
|
InvalidateLayout(false, true); // force applyschemesettings to run |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void RotatingProgressBar::PaintBackground() |
|
{ |
|
// No background |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Update event when we aren't drawing so we don't get huge sweeps |
|
// when we start drawing it |
|
//----------------------------------------------------------------------------- |
|
void RotatingProgressBar::OnTick( void ) |
|
{ |
|
float flDesiredAngle = RemapVal( GetProgress(), 0.0, 1.0, m_flStartRadians, m_flEndRadians ); |
|
m_flLastAngle = Approach( flDesiredAngle, m_flLastAngle, m_flApproachSpeed ); |
|
|
|
BaseClass::OnTick(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void RotatingProgressBar::Paint() |
|
{ |
|
// we have an image that we rotate based on the progress, |
|
// where '0' is not rotated,'90' is rotated 90 degrees to the right. |
|
// Image is rotated around its center. |
|
|
|
// desired rotation is GetProgress() ( 0.0 -> 1.0 ) mapped into |
|
// ( m_flStartDegrees -> m_flEndDegrees ) |
|
|
|
vgui::surface()->DrawSetTexture( m_nTextureId ); |
|
vgui::surface()->DrawSetColor( Color(255,255,255,255) ); |
|
|
|
int wide, tall; |
|
GetSize( wide, tall ); |
|
|
|
float mid_x = m_flRotatingX + m_flRotOriginX * m_flRotatingWide; |
|
float mid_y = m_flRotatingY + m_flRotOriginY * m_flRotatingTall; |
|
|
|
Vertex_t vert[4]; |
|
|
|
vert[0].Init( Vector2D( m_flRotatingX, m_flRotatingY ), Vector2D(0,0) ); |
|
vert[1].Init( Vector2D( m_flRotatingX+m_flRotatingWide, m_flRotatingY ), Vector2D(1,0) ); |
|
vert[2].Init( Vector2D( m_flRotatingX+m_flRotatingWide, m_flRotatingY+m_flRotatingTall ), Vector2D(1,1) ); |
|
vert[3].Init( Vector2D( m_flRotatingX, m_flRotatingY+m_flRotatingTall ), Vector2D(0,1) ); |
|
|
|
float flCosA = cos(m_flLastAngle); |
|
float flSinA = sin(m_flLastAngle); |
|
|
|
// rotate each point around (mid_x, mid_y) by flAngle radians |
|
for ( int i=0;i<4;i++ ) |
|
{ |
|
Vector2D result; |
|
|
|
// subtract the (x,y) we're rotating around, we'll add it on at the end. |
|
vert[i].m_Position.x -= mid_x; |
|
vert[i].m_Position.y -= mid_y; |
|
|
|
result.x = ( vert[i].m_Position.x * flCosA - vert[i].m_Position.y * flSinA ) + mid_x; |
|
result.y = ( vert[i].m_Position.x * flSinA + vert[i].m_Position.y * flCosA ) + mid_y; |
|
|
|
vert[i].m_Position = result; |
|
} |
|
|
|
vgui::surface()->DrawTexturedPolygon( 4, vert ); |
|
} |