Portable Half-Life SDK. GoldSource and Xash3D. Crossplatform.
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.

552 lines
13 KiB

//=========== (C) Copyright 1996-2002 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose: Contains implementation of various VGUI-derived objects
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================
#include "VGUI_Font.h"
#include "hud.h"
#include "cl_util.h"
#include "camera.h"
#include "kbutton.h"
#include "cvardef.h"
#include "usercmd.h"
#include "const.h"
#include "camera.h"
#include "in_defs.h"
#include "parsemsg.h"
#include "vgui_int.h"
#include "vgui_TeamFortressViewport.h"
#include "vgui_loadtga.h"
// Arrow filenames
const char *sArrowFilenames[] =
{
"arrowup",
"arrowdn",
"arrowlt",
"arrowrt",
};
// Get the name of TGA file, without a gamedir
char *GetTGANameForRes( const char *pszName )
{
int i;
char sz[256];
static char gd[256];
if( ScreenWidth < 640 )
i = 320;
else
i = 640;
sprintf( sz, pszName, i );
sprintf( gd, "gfx/vgui/%s.tga", sz );
return gd;
}
//-----------------------------------------------------------------------------
// Purpose: Loads a .tga file and returns a pointer to the VGUI tga object
//-----------------------------------------------------------------------------
BitmapTGA *LoadTGAForRes( const char* pImageName )
{
BitmapTGA *pTGA;
char sz[256];
sprintf( sz, "%%d_%s", pImageName );
pTGA = vgui_LoadTGA( GetTGANameForRes( sz ) );
return pTGA;
}
//===========================================================
// All TFC Hud buttons are derived from this one.
CommandButton::CommandButton( const char *text, int x, int y, int wide, int tall, bool bNoHighlight ) : Button( "", x, y, wide, tall )
{
m_iPlayerClass = 0;
m_bNoHighlight = bNoHighlight;
m_bFlat = false;
Init();
setText( text );
}
CommandButton::CommandButton( int iPlayerClass, const char *text, int x, int y, int wide, int tall, bool bFlat ) : Button( "", x, y, wide, tall )
{
m_iPlayerClass = iPlayerClass;
m_bNoHighlight = false;
m_bFlat = bFlat;
Init();
setText( text );
}
CommandButton::CommandButton( const char *text, int x, int y, int wide, int tall, bool bNoHighlight, bool bFlat ) : Button( "", x, y, wide, tall )
{
m_iPlayerClass = 0;
m_bFlat = bFlat;
m_bNoHighlight = bNoHighlight;
Init();
setText( text );
}
void CommandButton::Init( void )
{
m_pSubMenu = NULL;
m_pSubLabel = NULL;
m_pParentMenu = NULL;
// Set text color to orange
setFgColor( Scheme::sc_primary1 );
// left align
setContentAlignment( vgui::Label::a_west );
// Add the Highlight signal
if( !m_bNoHighlight )
addInputSignal( new CHandler_CommandButtonHighlight( this ) );
// not bound to any button yet
m_cBoundKey = 0;
}
//-----------------------------------------------------------------------------
// Purpose: Prepends the button text with the current bound key
// if no bound key, then a clear space ' ' instead
//-----------------------------------------------------------------------------
void CommandButton::RecalculateText( void )
{
char szBuf[128];
if( m_cBoundKey != 0 )
{
if( m_cBoundKey == (char)255 )
{
strcpy( szBuf, m_sMainText );
}
else
{
sprintf( szBuf, " %c %s", m_cBoundKey, m_sMainText );
}
szBuf[MAX_BUTTON_SIZE-1] = 0;
}
else
{
// just draw a space if no key bound
sprintf( szBuf, " %s", m_sMainText );
szBuf[MAX_BUTTON_SIZE - 1] = 0;
}
Button::setText( szBuf );
}
void CommandButton::setText( const char *text )
{
strncpy( m_sMainText, text, MAX_BUTTON_SIZE );
m_sMainText[MAX_BUTTON_SIZE - 1] = 0;
RecalculateText();
}
void CommandButton::setBoundKey( char boundKey )
{
m_cBoundKey = boundKey;
RecalculateText();
}
char CommandButton::getBoundKey( void )
{
return m_cBoundKey;
}
void CommandButton::AddSubMenu( CCommandMenu *pNewMenu )
{
m_pSubMenu = pNewMenu;
// Prevent this button from being pushed
setMouseClickEnabled( MOUSE_LEFT, false );
}
void CommandButton::UpdateSubMenus( int iAdjustment )
{
if( m_pSubMenu )
m_pSubMenu->RecalculatePositions( iAdjustment );
}
void CommandButton::paint()
{
// Make the sub label paint the same as the button
if( m_pSubLabel )
{
if( isSelected() )
m_pSubLabel->PushDown();
else
m_pSubLabel->PushUp();
}
// draw armed button text in white
if( isArmed() )
{
setFgColor( Scheme::sc_secondary2 );
}
else
{
setFgColor( Scheme::sc_primary1 );
}
Button::paint();
}
void CommandButton::paintBackground()
{
if( m_bFlat )
{
if( isArmed() )
{
// Orange Border
drawSetColor( Scheme::sc_secondary1 );
drawOutlinedRect( 0, 0, _size[0], _size[1] );
}
}
else
{
if( isArmed() )
{
// Orange highlight background
drawSetColor( Scheme::sc_primary2 );
drawFilledRect( 0, 0, _size[0], _size[1] );
}
// Orange Border
drawSetColor( Scheme::sc_secondary1 );
drawOutlinedRect( 0, 0, _size[0], _size[1] );
}
}
//-----------------------------------------------------------------------------
// Purpose: Highlights the current button, and all it's parent menus
//-----------------------------------------------------------------------------
void CommandButton::cursorEntered( void )
{
// unarm all the other buttons in this menu
CCommandMenu *containingMenu = getParentMenu();
if( containingMenu )
{
containingMenu->ClearButtonsOfArmedState();
// make all our higher buttons armed
CCommandMenu *pCParent = containingMenu->GetParentMenu();
if( pCParent )
{
CommandButton *pParentButton = pCParent->FindButtonWithSubmenu( containingMenu );
pParentButton->cursorEntered();
}
}
// arm ourselves
setArmed( true );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CommandButton::cursorExited( void )
{
// only clear ourselves if we have do not have a containing menu
// only stay armed if we have a sub menu
// the buttons only unarm themselves when another button is armed instead
if( !getParentMenu() || !GetSubMenu() )
{
setArmed( false );
}
}
//-----------------------------------------------------------------------------
// Purpose: Returns the command menu that the button is part of, if any
// Output : CCommandMenu *
//-----------------------------------------------------------------------------
CCommandMenu *CommandButton::getParentMenu( void )
{
return m_pParentMenu;
}
//-----------------------------------------------------------------------------
// Purpose: Sets the menu that contains this button
// Input : *pParentMenu -
//-----------------------------------------------------------------------------
void CommandButton::setParentMenu( CCommandMenu *pParentMenu )
{
m_pParentMenu = pParentMenu;
}
//===========================================================
int ClassButton::IsNotValid()
{
// If this is the main ChangeClass button, remove it if the player's only able to be civilians
if( m_iPlayerClass == -1 )
{
if( gViewPort->GetValidClasses( g_iTeamNumber ) == -1 )
return true;
return false;
}
// Is it an illegal class?
#ifdef _TFC
if( ( gViewPort->GetValidClasses( 0 ) & sTFValidClassInts[m_iPlayerClass] ) || ( gViewPort->GetValidClasses( g_iTeamNumber ) & sTFValidClassInts[m_iPlayerClass] ) )
return true;
#endif
// Only check current class if they've got autokill on
bool bAutoKill = CVAR_GET_FLOAT( "hud_classautokill" ) != 0;
if( bAutoKill )
{
// Is it the player's current class?
if (
#ifdef _TFC
(gViewPort->IsRandomPC() && m_iPlayerClass == PC_RANDOM) ||
#endif
(!gViewPort->IsRandomPC() && (m_iPlayerClass == g_iPlayerClass)) )
return true;
}
return false;
}
//===========================================================
// Button with Class image beneath it
CImageLabel::CImageLabel( const char *pImageName,int x,int y ) : Label( "", x, y )
{
setContentFitted( true );
m_pTGA = LoadTGAForRes( pImageName );
setImage( m_pTGA );
}
CImageLabel::CImageLabel( const char *pImageName, int x, int y, int wide, int tall ) : Label( "", x, y, wide, tall )
{
setContentFitted( true );
m_pTGA = LoadTGAForRes( pImageName );
setImage( m_pTGA );
}
//===========================================================
// Image size
int CImageLabel::getImageWide( void )
{
if( m_pTGA )
{
int iXSize, iYSize;
m_pTGA->getSize( iXSize, iYSize );
return iXSize;
}
else
{
return 1;
}
}
int CImageLabel::getImageTall( void )
{
if( m_pTGA )
{
int iXSize, iYSize;
m_pTGA->getSize( iXSize, iYSize );
return iYSize;
}
else
{
return 1;
}
}
void CImageLabel::LoadImage( const char *pImageName )
{
if( m_pTGA )
delete m_pTGA;
// Load the Image
m_pTGA = LoadTGAForRes( pImageName );
if( m_pTGA == NULL )
{
// we didn't find a matching image file for this resolution
// try to load file resolution independent
char sz[256];
sprintf( sz, "%s/%s", gEngfuncs.pfnGetGameDirectory(), pImageName );
FileInputStream fis( sz, false );
m_pTGA = new BitmapTGA( &fis, true );
fis.close();
}
if( m_pTGA == NULL )
return; // unable to load image
int w,t;
m_pTGA->getSize( w, t );
setSize( XRES ( w ),YRES ( t) );
setImage( m_pTGA );
}
//===========================================================
// Various overloaded paint functions for Custom VGUI objects
void CCommandMenu::paintBackground()
{
// Transparent black background
if( m_iSpectCmdMenu )
drawSetColor( 0, 0, 0, 64 );
else
drawSetColor( Scheme::sc_primary3 );
drawFilledRect( 0, 0, _size[0], _size[1] );
}
//=================================================================================
// CUSTOM SCROLLPANEL
//=================================================================================
CTFScrollButton::CTFScrollButton( int iArrow, const char *text, int x, int y, int wide, int tall ) : CommandButton( text, x, y, wide, tall )
{
// Set text color to orange
setFgColor( Scheme::sc_primary1 );
// Load in the arrow
m_pTGA = LoadTGAForRes( sArrowFilenames[iArrow] );
setImage( m_pTGA );
// Highlight signal
InputSignal *pISignal = new CHandler_CommandButtonHighlight( this );
addInputSignal( pISignal );
}
void CTFScrollButton::paint( void )
{
if( !m_pTGA )
return;
// draw armed button text in white
if( isArmed() )
{
m_pTGA->setColor( Color( 255, 255, 255, 0 ) );
}
else
{
m_pTGA->setColor( Color( 255, 255, 255, 128 ) );
}
m_pTGA->doPaint( this );
}
void CTFScrollButton::paintBackground( void )
{
/*
if( isArmed() )
{
// Orange highlight background
drawSetColor( Scheme::sc_primary2 );
drawFilledRect( 0, 0, _size[0], _size[1] );
}
// Orange Border
drawSetColor( Scheme::sc_secondary1 );
drawOutlinedRect( 0, 0, _size[0] - 1, _size[1] );
*/
}
void CTFSlider::paintBackground( void )
{
int wide, tall, nobx, noby;
getPaintSize( wide, tall );
getNobPos( nobx, noby );
// Border
drawSetColor( Scheme::sc_secondary1 );
drawOutlinedRect( 0, 0, wide, tall );
if( isVertical() )
{
// Nob Fill
drawSetColor( Scheme::sc_primary2 );
drawFilledRect( 0, nobx, wide, noby );
// Nob Outline
drawSetColor( Scheme::sc_primary1 );
drawOutlinedRect( 0, nobx, wide, noby );
}
else
{
// Nob Fill
drawSetColor( Scheme::sc_primary2 );
drawFilledRect( nobx, 0, noby, tall );
// Nob Outline
drawSetColor( Scheme::sc_primary1 );
drawOutlinedRect( nobx, 0, noby, tall );
}
}
CTFScrollPanel::CTFScrollPanel( int x, int y, int wide, int tall ) : ScrollPanel( x, y, wide, tall )
{
ScrollBar *pScrollBar = getVerticalScrollBar();
pScrollBar->setButton( new CTFScrollButton( ARROW_UP, "", 0, 0, 16, 16 ), 0 );
pScrollBar->setButton( new CTFScrollButton( ARROW_DOWN, "", 0, 0, 16, 16 ), 1 );
pScrollBar->setSlider( new CTFSlider( 0, wide - 1, wide, ( tall - ( wide * 2 ) ) + 2, true ) );
pScrollBar->setPaintBorderEnabled( false );
pScrollBar->setPaintBackgroundEnabled( false );
pScrollBar->setPaintEnabled( false );
pScrollBar = getHorizontalScrollBar();
pScrollBar->setButton( new CTFScrollButton( ARROW_LEFT, "", 0, 0, 16, 16 ), 0 );
pScrollBar->setButton( new CTFScrollButton( ARROW_RIGHT, "", 0, 0, 16, 16 ), 1 );
pScrollBar->setSlider( new CTFSlider( tall, 0, wide - ( tall * 2 ), tall, false ) );
pScrollBar->setPaintBorderEnabled( false );
pScrollBar->setPaintBackgroundEnabled( false );
pScrollBar->setPaintEnabled( false );
}
//=================================================================================
// CUSTOM HANDLERS
//=================================================================================
void CHandler_MenuButtonOver::cursorEntered(Panel *panel)
{
if( gViewPort && m_pMenuPanel )
{
m_pMenuPanel->SetActiveInfo( m_iButton );
}
}
void CMenuHandler_StringCommandClassSelect::actionPerformed( Panel *panel )
{
CMenuHandler_StringCommand::actionPerformed( panel );
// THIS IS NOW BEING DONE ON THE TFC SERVER TO AVOID KILLING SOMEONE THEN
// HAVE THE SERVER SAY "SORRY...YOU CAN'T BE THAT CLASS".
#if !defined _TFC
bool bAutoKill = CVAR_GET_FLOAT( "hud_classautokill" ) != 0;
if( bAutoKill && g_iPlayerClass != 0 )
gEngfuncs.pfnClientCmd( "kill" );
#endif
}