|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "cbase.h"
#include "hud.h"
#include "hudelement.h"
#include "hud_macros.h"
#include "iclientmode.h"
#include "vgui_controls/AnimationController.h"
#include "vgui_controls/Label.h"
#include "vgui/ILocalize.h"
#include "vgui/ISurface.h"
#include "text_message.h"
#include "dod_hud_freezepanel.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Purpose: Displays current ammunition level
//-----------------------------------------------------------------------------
class CDODHudHintDisplay : public vgui::Panel, public CHudElement { DECLARE_CLASS_SIMPLE( CDODHudHintDisplay, vgui::Panel );
public: CDODHudHintDisplay( const char *pElementName );
void Init(); void Reset(); void MsgFunc_HintText( bf_read &msg ); void FireGameEvent( IGameEvent * event);
bool SetHintText( wchar_t *text );
virtual void PerformLayout();
virtual bool IsVisible( void );
protected: virtual void ApplySchemeSettings( vgui::IScheme *pScheme ); virtual void OnThink();
private: vgui::HFont m_hFont; Color m_bgColor; vgui::Label *m_pLabel; CUtlVector<vgui::Label *> m_Labels; CPanelAnimationVarAliasType( int, m_iTextX, "text_xpos", "8", "proportional_int" ); CPanelAnimationVarAliasType( int, m_iTextY, "text_ypos", "8", "proportional_int" ); CPanelAnimationVarAliasType( int, m_iCenterX, "center_x", "0", "proportional_int" ); CPanelAnimationVarAliasType( int, m_iCenterY, "center_y", "0", "proportional_int" ); };
DECLARE_HUDELEMENT( CDODHudHintDisplay ); DECLARE_HUD_MESSAGE( CDODHudHintDisplay, HintText );
#define MAX_HINT_STRINGS 5
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CDODHudHintDisplay::CDODHudHintDisplay( const char *pElementName ) : BaseClass(NULL, "HudHintDisplay"), CHudElement( pElementName ) { vgui::Panel *pParent = g_pClientMode->GetViewport(); SetParent( pParent ); SetVisible( false ); SetAlpha( 0 ); m_pLabel = new vgui::Label( this, "HudHintDisplayLabel", "" );
RegisterForRenderGroup( "winpanel" ); RegisterForRenderGroup( "freezepanel" ); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDODHudHintDisplay::Init() { HOOK_HUD_MESSAGE( CDODHudHintDisplay, HintText );
// listen for client side events
ListenForGameEvent( "player_hintmessage" ); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDODHudHintDisplay::Reset() { SetHintText( NULL ); SetAlpha( 0 ); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDODHudHintDisplay::ApplySchemeSettings( vgui::IScheme *pScheme ) { BaseClass::ApplySchemeSettings( pScheme );
SetFgColor( GetSchemeColor("HintMessageFg", pScheme) ); m_hFont = pScheme->GetFont( "HudHintText", true ); m_pLabel->SetBgColor( GetSchemeColor("HintMessageBg", pScheme) ); m_pLabel->SetPaintBackgroundType( 2 ); }
//-----------------------------------------------------------------------------
// Purpose: Sets the hint text, replacing variables as necessary
//-----------------------------------------------------------------------------
bool CDODHudHintDisplay::SetHintText( wchar_t *text ) { // clear the existing text
for (int i = 0; i < m_Labels.Count(); i++) { m_Labels[i]->MarkForDeletion(); } m_Labels.RemoveAll();
wchar_t *p = text;
while ( p ) { wchar_t *line = p; wchar_t *end = wcschr( p, L'\n' ); if ( end ) { //*end = 0; //eek
p = end+1; } else { p = NULL; }
// copy to a new buf if there are vars
wchar_t buf[512]; buf[0] = '\0'; int pos = 0;
wchar_t *ws = line; while( ws != end && *ws != 0 ) { // check for variables
if ( *ws == '%' ) { ++ws;
wchar_t *end = wcschr( ws, '%' ); if ( end ) { wchar_t token[64]; wcsncpy( token, ws, end - ws ); token[end - ws] = 0;
ws += end - ws;
// lookup key names
char binding[64]; g_pVGuiLocalize->ConvertUnicodeToANSI( token, binding, sizeof(binding) );
const char *key = engine->Key_LookupBinding( *binding == '+' ? binding + 1 : binding ); if ( !key ) { key = "< not bound >"; }
//!! change some key names into better names
char friendlyName[64]; Q_snprintf( friendlyName, sizeof(friendlyName), "%s", key ); Q_strupr( friendlyName );
g_pVGuiLocalize->ConvertANSIToUnicode( friendlyName, token, sizeof(token) );
buf[pos] = '\0'; wcscat( buf, token ); pos += wcslen(token); } else { buf[pos] = *ws; ++pos; } } else { buf[pos] = *ws; ++pos; }
++ws; }
buf[pos] = '\0';
// put it in a label
//vgui::Label *label = vgui::SETUP_PANEL(new vgui::Label(this, NULL, line));
vgui::Label *label = vgui::SETUP_PANEL(new vgui::Label(this, NULL, buf)); label->SetFont( m_hFont ); label->SetPaintBackgroundEnabled( false ); label->SetPaintBorderEnabled( false ); label->SizeToContents(); label->SetContentAlignment( vgui::Label::a_west ); label->SetFgColor( GetFgColor() ); m_Labels.AddToTail( vgui::SETUP_PANEL(label) ); } InvalidateLayout( true );
return true; }
//-----------------------------------------------------------------------------
// Purpose: Resizes the label
//-----------------------------------------------------------------------------
void CDODHudHintDisplay::PerformLayout() { BaseClass::PerformLayout(); int i;
int wide, tall; GetSize( wide, tall );
// find the widest line
int labelWide = 0; for ( i=0; i<m_Labels.Count(); ++i ) { labelWide = MAX( labelWide, m_Labels[i]->GetWide() ); }
// find the total height
int fontTall = vgui::surface()->GetFontTall( m_hFont ); int labelTall = fontTall * m_Labels.Count();
labelWide += m_iTextX*2; labelTall += m_iTextY*2; int x, y; if ( m_iCenterX < 0 ) { x = 0; } else if ( m_iCenterX > 0 ) { x = wide - labelWide; } else { x = (wide - labelWide) / 2; }
if ( m_iCenterY > 0 ) { y = 0; } else if ( m_iCenterY < 0 ) { y = tall - labelTall; } else { y = (tall - labelTall) / 2; } m_pLabel->SetBounds( x, y, labelWide, labelTall );
// now lay out the sub-labels
for ( i=0; i<m_Labels.Count(); ++i ) { int xOffset = (labelWide - m_Labels[i]->GetWide())/2; m_Labels[i]->SetPos( x + xOffset, y + m_iTextY + i*fontTall ); } }
//-----------------------------------------------------------------------------
// Purpose: Updates the label color each frame
//-----------------------------------------------------------------------------
void CDODHudHintDisplay::OnThink() { m_pLabel->SetFgColor(GetFgColor()); for (int i = 0; i < m_Labels.Count(); i++) { m_Labels[i]->SetFgColor(GetFgColor()); } }
//-----------------------------------------------------------------------------
// Purpose: Activates the hint display
//-----------------------------------------------------------------------------
void CDODHudHintDisplay::MsgFunc_HintText( bf_read &msg ) { // read the string(s)
char szString[255]; static wchar_t szBuf[128]; static wchar_t *pszBuf;
// init buffers & pointers
szBuf[0] = 0; pszBuf = szBuf;
// read string and localize it
msg.ReadString( szString, sizeof(szString) );
char *tmpStr = hudtextmessage->LookupString( szString, NULL );
// try to localize
if ( tmpStr ) { pszBuf = g_pVGuiLocalize->Find( tmpStr ); } else { pszBuf = g_pVGuiLocalize->Find( szString ); }
if ( !pszBuf ) { // use plain ASCII string
g_pVGuiLocalize->ConvertANSIToUnicode( szString, szBuf, sizeof(szBuf) ); pszBuf = szBuf; }
// make it visible
if ( SetHintText( pszBuf ) ) { SetVisible( true ); //SetAlpha( 255 );
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HintMessageShow" ); } else { // it's being cleared, hide the panel
//SetAlpha( 0 );
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HintMessageHide" ); } }
//-----------------------------------------------------------------------------
// Purpose: Activates the hint display upon recieving a hint
//-----------------------------------------------------------------------------
void CDODHudHintDisplay::FireGameEvent( IGameEvent * event) { // we sometimes hide the element when it's covered, don't start
// a hint during that time
if ( !ShouldDraw() ) return;
static wchar_t *pszBuf; static wchar_t szBuf[128];
const char *hintmessage = event->GetString( "hintmessage" );
char *tmpStr = hudtextmessage->LookupString( hintmessage, NULL );
// try to localize
if ( tmpStr ) { pszBuf = g_pVGuiLocalize->Find( tmpStr ); } else { pszBuf = g_pVGuiLocalize->Find( hintmessage ); }
if ( !pszBuf ) { // its not in titles.txt or dod_english.txt, just print the text of it
// use plain ASCII string
g_pVGuiLocalize->ConvertANSIToUnicode( hintmessage, szBuf, sizeof(szBuf) ); pszBuf = szBuf; }
// make it visible
if ( SetHintText( pszBuf ) ) { SetVisible( true ); g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HintMessageShow" ); } else { // it's being cleared, hide the panel
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HintMessageHide" ); } }
bool CDODHudHintDisplay::IsVisible( void ) { if ( IsTakingAFreezecamScreenshot() ) return false;
if ( !ShouldDraw() ) return false;
return BaseClass::IsVisible(); }
|