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.
456 lines
13 KiB
456 lines
13 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//============================================================================= |
|
|
|
#include "cbase.h" |
|
#include <vgui_controls/Controls.h> |
|
#include <vgui_controls/Panel.h> |
|
#include <vgui/ISurface.h> |
|
#include "vgui_avatarimage.h" |
|
#if defined( _X360 ) |
|
#include "xbox/xbox_win32stubs.h" |
|
#endif |
|
#include "steam/steam_api.h" |
|
|
|
DECLARE_BUILD_FACTORY( CAvatarImagePanel ); |
|
|
|
|
|
CUtlMap< AvatarImagePair_t, int> CAvatarImage::s_AvatarImageCache; // cache of steam id's to textureids to use for images |
|
bool CAvatarImage::m_sbInitializedAvatarCache = false; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CAvatarImage::CAvatarImage( void ) |
|
: m_sPersonaStateChangedCallback( this, &CAvatarImage::OnPersonaStateChanged ) |
|
{ |
|
ClearAvatarSteamID(); |
|
m_pFriendIcon = NULL; |
|
m_nX = 0; |
|
m_nY = 0; |
|
m_wide = m_tall = 0; |
|
m_avatarWide = m_avatarTall = 0; |
|
m_Color = Color( 255, 255, 255, 255 ); |
|
m_bLoadPending = false; |
|
m_fNextLoadTime = 0.0f; |
|
m_AvatarSize = k_EAvatarSize32x32; |
|
|
|
//============================================================================= |
|
// HPE_BEGIN: |
|
//============================================================================= |
|
// [tj] Default to drawing the friend icon for avatars |
|
m_bDrawFriend = true; |
|
|
|
// [menglish] Default icon for avatar icons if there is no avatar icon for the player |
|
m_iTextureID = -1; |
|
|
|
// set up friend icon |
|
m_pFriendIcon = gHUD.GetIcon( "ico_friend_indicator_avatar" ); |
|
|
|
m_pDefaultImage = NULL; |
|
|
|
SetAvatarSize(DEFAULT_AVATAR_SIZE, DEFAULT_AVATAR_SIZE); |
|
|
|
//============================================================================= |
|
// HPE_END |
|
//============================================================================= |
|
|
|
if ( !m_sbInitializedAvatarCache) |
|
{ |
|
m_sbInitializedAvatarCache = true; |
|
SetDefLessFunc( s_AvatarImageCache ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: reset the image to a default state (will render with the default image) |
|
//----------------------------------------------------------------------------- |
|
void CAvatarImage::ClearAvatarSteamID( void ) |
|
{ |
|
m_bValid = false; |
|
m_bFriend = false; |
|
m_bLoadPending = false; |
|
m_SteamID.Set( 0, k_EUniverseInvalid, k_EAccountTypeInvalid ); |
|
m_sPersonaStateChangedCallback.Unregister(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Set the CSteamID for this image; this will cause a deferred load |
|
//----------------------------------------------------------------------------- |
|
bool CAvatarImage::SetAvatarSteamID( CSteamID steamIDUser, EAvatarSize avatarSize /*= k_EAvatarSize32x32 */ ) |
|
{ |
|
ClearAvatarSteamID(); |
|
|
|
m_SteamID = steamIDUser; |
|
m_AvatarSize = avatarSize; |
|
m_bLoadPending = true; |
|
|
|
m_sPersonaStateChangedCallback.Register( this, &CAvatarImage::OnPersonaStateChanged ); |
|
|
|
LoadAvatarImage(); |
|
UpdateFriendStatus(); |
|
|
|
return m_bValid; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Called when somebody changes their avatar image |
|
//----------------------------------------------------------------------------- |
|
void CAvatarImage::OnPersonaStateChanged( PersonaStateChange_t *info ) |
|
{ |
|
if ( ( info->m_ulSteamID == m_SteamID.ConvertToUint64() ) && ( info->m_nChangeFlags & k_EPersonaChangeAvatar ) ) |
|
{ |
|
// Mark us as invalid. |
|
m_bValid = false; |
|
m_bLoadPending = true; |
|
|
|
// Poll |
|
LoadAvatarImage(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: load the avatar image if we have a load pending |
|
//----------------------------------------------------------------------------- |
|
void CAvatarImage::LoadAvatarImage() |
|
{ |
|
#ifdef CSS_PERF_TEST |
|
return; |
|
#endif |
|
// attempt to retrieve the avatar image from Steam |
|
if ( m_bLoadPending && steamapicontext->SteamFriends() && steamapicontext->SteamUtils() && gpGlobals->curtime >= m_fNextLoadTime ) |
|
{ |
|
if ( !steamapicontext->SteamFriends()->RequestUserInformation( m_SteamID, false ) ) |
|
{ |
|
int iAvatar = 0; |
|
switch( m_AvatarSize ) |
|
{ |
|
case k_EAvatarSize32x32: |
|
iAvatar = steamapicontext->SteamFriends()->GetSmallFriendAvatar( m_SteamID ); |
|
break; |
|
case k_EAvatarSize64x64: |
|
iAvatar = steamapicontext->SteamFriends()->GetMediumFriendAvatar( m_SteamID ); |
|
break; |
|
case k_EAvatarSize184x184: |
|
iAvatar = steamapicontext->SteamFriends()->GetLargeFriendAvatar( m_SteamID ); |
|
break; |
|
} |
|
|
|
//Msg( "Got avatar %d for SteamID %llud (%s)\n", iAvatar, m_SteamID.ConvertToUint64(), steamapicontext->SteamFriends()->GetFriendPersonaName( m_SteamID ) ); |
|
|
|
if ( iAvatar > 0 ) // if its zero, user doesn't have an avatar. If -1, Steam is telling us that it's fetching it |
|
{ |
|
uint32 wide = 0, tall = 0; |
|
if ( steamapicontext->SteamUtils()->GetImageSize( iAvatar, &wide, &tall ) && wide > 0 && tall > 0 ) |
|
{ |
|
int destBufferSize = wide * tall * 4; |
|
byte *rgbDest = (byte*)stackalloc( destBufferSize ); |
|
if ( steamapicontext->SteamUtils()->GetImageRGBA( iAvatar, rgbDest, destBufferSize ) ) |
|
InitFromRGBA( iAvatar, rgbDest, wide, tall ); |
|
|
|
stackfree( rgbDest ); |
|
} |
|
} |
|
} |
|
|
|
if ( m_bValid ) |
|
{ |
|
// if we have a valid image, don't attempt to load it again |
|
m_bLoadPending = false; |
|
} |
|
else |
|
{ |
|
// otherwise schedule another attempt to retrieve the image |
|
m_fNextLoadTime = gpGlobals->curtime + 1.0f; |
|
} |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Query Steam to set the m_bFriend status flag |
|
//----------------------------------------------------------------------------- |
|
void CAvatarImage::UpdateFriendStatus( void ) |
|
{ |
|
if ( !m_SteamID.IsValid() ) |
|
return; |
|
|
|
if ( steamapicontext->SteamFriends() && steamapicontext->SteamUtils() ) |
|
m_bFriend = steamapicontext->SteamFriends()->HasFriend( m_SteamID, k_EFriendFlagImmediate ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Initialize the surface with the supplied raw RGBA image data |
|
//----------------------------------------------------------------------------- |
|
void CAvatarImage::InitFromRGBA( int iAvatar, const byte *rgba, int width, int height ) |
|
{ |
|
int iTexIndex = s_AvatarImageCache.Find( AvatarImagePair_t( m_SteamID, iAvatar ) ); |
|
if ( iTexIndex == s_AvatarImageCache.InvalidIndex() ) |
|
{ |
|
m_iTextureID = vgui::surface()->CreateNewTextureID( true ); |
|
vgui::surface()->DrawSetTextureRGBA( m_iTextureID, rgba, width, height, false, false ); |
|
iTexIndex = s_AvatarImageCache.Insert( AvatarImagePair_t( m_SteamID, iAvatar ) ); |
|
s_AvatarImageCache[ iTexIndex ] = m_iTextureID; |
|
} |
|
else |
|
m_iTextureID = s_AvatarImageCache[ iTexIndex ]; |
|
|
|
m_bValid = true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Draw the image and optional friend icon |
|
//----------------------------------------------------------------------------- |
|
void CAvatarImage::Paint( void ) |
|
{ |
|
if ( m_bFriend && m_pFriendIcon && m_bDrawFriend) |
|
{ |
|
m_pFriendIcon->DrawSelf( m_nX, m_nY, m_wide, m_tall, m_Color ); |
|
} |
|
|
|
int posX = m_nX; |
|
int posY = m_nY; |
|
|
|
if (m_bDrawFriend) |
|
{ |
|
posX += FRIEND_ICON_AVATAR_INDENT_X * m_avatarWide / DEFAULT_AVATAR_SIZE; |
|
posY += FRIEND_ICON_AVATAR_INDENT_Y * m_avatarTall / DEFAULT_AVATAR_SIZE; |
|
} |
|
|
|
if ( m_bLoadPending ) |
|
{ |
|
LoadAvatarImage(); |
|
} |
|
|
|
if ( m_bValid ) |
|
{ |
|
vgui::surface()->DrawSetTexture( m_iTextureID ); |
|
vgui::surface()->DrawSetColor( m_Color ); |
|
vgui::surface()->DrawTexturedRect(posX, posY, posX + m_avatarWide, posY + m_avatarTall); |
|
} |
|
else if (m_pDefaultImage) |
|
{ |
|
// draw default |
|
m_pDefaultImage->SetSize(m_avatarWide, m_avatarTall); |
|
m_pDefaultImage->SetPos(posX, posY); |
|
m_pDefaultImage->SetColor(m_Color); |
|
m_pDefaultImage->Paint(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Set the avatar size; scale the total image and friend icon to fit |
|
//----------------------------------------------------------------------------- |
|
void CAvatarImage::SetAvatarSize(int wide, int tall) |
|
{ |
|
m_avatarWide = wide; |
|
m_avatarTall = tall; |
|
|
|
if (m_bDrawFriend) |
|
{ |
|
// scale the size of the friend background frame icon |
|
m_wide = FRIEND_ICON_SIZE_X * m_avatarWide / DEFAULT_AVATAR_SIZE; |
|
m_tall = FRIEND_ICON_SIZE_Y * m_avatarTall / DEFAULT_AVATAR_SIZE; |
|
} |
|
else |
|
{ |
|
m_wide = m_avatarWide; |
|
m_tall = m_avatarTall; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Set the total image size; scale the avatar portion to fit |
|
//----------------------------------------------------------------------------- |
|
void CAvatarImage::SetSize( int wide, int tall ) |
|
{ |
|
m_wide = wide; |
|
m_tall = tall; |
|
|
|
if (m_bDrawFriend) |
|
{ |
|
// scale the size of the avatar portion based on the total image size |
|
m_avatarWide = DEFAULT_AVATAR_SIZE * m_wide / FRIEND_ICON_SIZE_X; |
|
m_avatarTall = DEFAULT_AVATAR_SIZE * m_tall / FRIEND_ICON_SIZE_Y ; |
|
} |
|
else |
|
{ |
|
m_avatarWide = m_wide; |
|
m_avatarTall = m_tall; |
|
} |
|
} |
|
|
|
bool CAvatarImage::Evict() |
|
{ |
|
return false; |
|
} |
|
|
|
int CAvatarImage::GetNumFrames() |
|
{ |
|
return 0; |
|
} |
|
|
|
void CAvatarImage::SetFrame( int nFrame ) |
|
{ |
|
} |
|
|
|
vgui::HTexture CAvatarImage::GetID() |
|
{ |
|
return 0; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CAvatarImagePanel::CAvatarImagePanel( vgui::Panel *parent, const char *name ) : BaseClass( parent, name ) |
|
{ |
|
m_bScaleImage = false; |
|
m_pImage = new CAvatarImage(); |
|
m_bSizeDirty = true; |
|
m_bClickable = false; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Set the avatar by C_BasePlayer pointer |
|
//----------------------------------------------------------------------------- |
|
void CAvatarImagePanel::SetPlayer( C_BasePlayer *pPlayer, EAvatarSize avatarSize ) |
|
{ |
|
if ( pPlayer ) |
|
{ |
|
int iIndex = pPlayer->entindex(); |
|
SetPlayer(iIndex, avatarSize); |
|
} |
|
else |
|
m_pImage->ClearAvatarSteamID(); |
|
|
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Set the avatar by entity number |
|
//----------------------------------------------------------------------------- |
|
void CAvatarImagePanel::SetPlayer( int entindex, EAvatarSize avatarSize ) |
|
{ |
|
m_pImage->ClearAvatarSteamID(); |
|
|
|
player_info_t pi; |
|
if ( engine->GetPlayerInfo(entindex, &pi) ) |
|
{ |
|
if ( pi.friendsID != 0 && steamapicontext->SteamUtils() ) |
|
{ |
|
CSteamID steamIDForPlayer( pi.friendsID, 1, steamapicontext->SteamUtils()->GetConnectedUniverse(), k_EAccountTypeIndividual ); |
|
SetPlayer(steamIDForPlayer, avatarSize); |
|
} |
|
else |
|
{ |
|
m_pImage->ClearAvatarSteamID(); |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Set the avatar by SteamID |
|
//----------------------------------------------------------------------------- |
|
void CAvatarImagePanel::SetPlayer(CSteamID steamIDForPlayer, EAvatarSize avatarSize ) |
|
{ |
|
m_pImage->ClearAvatarSteamID(); |
|
|
|
if (steamIDForPlayer.GetAccountID() != 0 ) |
|
m_pImage->SetAvatarSteamID( steamIDForPlayer, avatarSize ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CAvatarImagePanel::PaintBackground( void ) |
|
{ |
|
if ( m_bSizeDirty ) |
|
UpdateSize(); |
|
|
|
m_pImage->Paint(); |
|
} |
|
|
|
void CAvatarImagePanel::ClearAvatar() |
|
{ |
|
m_pImage->ClearAvatarSteamID(); |
|
} |
|
|
|
void CAvatarImagePanel::SetDefaultAvatar( vgui::IImage* pDefaultAvatar ) |
|
{ |
|
m_pImage->SetDefaultImage(pDefaultAvatar); |
|
} |
|
|
|
void CAvatarImagePanel::SetAvatarSize( int width, int height ) |
|
{ |
|
if ( m_bScaleImage ) |
|
{ |
|
// panel is charge of image size - setting avatar size this way not allowed |
|
Assert(false); |
|
return; |
|
} |
|
else |
|
{ |
|
m_pImage->SetAvatarSize( width, height ); |
|
m_bSizeDirty = true; |
|
} |
|
} |
|
|
|
void CAvatarImagePanel::OnSizeChanged( int newWide, int newTall ) |
|
{ |
|
BaseClass::OnSizeChanged(newWide, newTall); |
|
m_bSizeDirty = true; |
|
} |
|
|
|
void CAvatarImagePanel::OnMousePressed(vgui::MouseCode code) |
|
{ |
|
if ( !m_bClickable || code != MOUSE_LEFT ) |
|
return; |
|
|
|
PostActionSignal( new KeyValues("AvatarMousePressed") ); |
|
|
|
// audible feedback |
|
const char *soundFilename = "ui/buttonclick.wav"; |
|
|
|
vgui::surface()->PlaySound( soundFilename ); |
|
} |
|
|
|
void CAvatarImagePanel::SetShouldScaleImage( bool bScaleImage ) |
|
{ |
|
m_bScaleImage = bScaleImage; |
|
m_bSizeDirty = true; |
|
} |
|
|
|
void CAvatarImagePanel::SetShouldDrawFriendIcon( bool bDrawFriend ) |
|
{ |
|
m_pImage->SetDrawFriend(bDrawFriend); |
|
m_bSizeDirty = true; |
|
} |
|
|
|
void CAvatarImagePanel::UpdateSize() |
|
{ |
|
if ( m_bScaleImage ) |
|
{ |
|
// the panel is in charge of the image size |
|
m_pImage->SetAvatarSize(GetWide(), GetTall()); |
|
} |
|
else |
|
{ |
|
// the image is in charge of the panel size |
|
SetSize(m_pImage->GetAvatarWide(), m_pImage->GetAvatarTall() ); |
|
} |
|
|
|
m_bSizeDirty = false; |
|
} |
|
|
|
void CAvatarImagePanel::ApplySettings( KeyValues *inResourceData ) |
|
{ |
|
m_bScaleImage = inResourceData->GetInt("scaleImage", 0); |
|
|
|
BaseClass::ApplySettings(inResourceData); |
|
}
|
|
|