mirror of https://github.com/FWGS/hlsdk-xash3d
552 lines
13 KiB
C++
552 lines
13 KiB
C++
//=========== (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
|
|
}
|
|
|