halflife-photomode/cl_dll/vgui_CustomObjects.cpp

535 lines
12 KiB
C++

//=========== (C) Copyright 1999 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()
{
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()
{
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()
{
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()
{
// 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()
{
// 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()
{
return m_pParentMenu;
}
//-----------------------------------------------------------------------------
// Purpose: Sets the menu that contains this button
// Input : *pParentMenu -
//-----------------------------------------------------------------------------
void CommandButton::setParentMenu(CCommandMenu* pParentMenu)
{
m_pParentMenu = pParentMenu;
}
//===========================================================
bool 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?
// 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 (
(!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()
{
if (m_pTGA)
{
int iXSize, iYSize;
m_pTGA->getSize(iXSize, iYSize);
return iXSize;
}
else
{
return 1;
}
}
int CImageLabel::getImageTall()
{
if (m_pTGA)
{
int iXSize, iYSize;
m_pTGA->getSize(iXSize, iYSize);
return iYSize;
}
else
{
return 1;
}
}
void CImageLabel::LoadImage(const char* pImageName)
{
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()
{
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()
{
/*
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()
{
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".
bool bAutoKill = CVAR_GET_FLOAT("hud_classautokill") != 0;
if (bAutoKill && g_iPlayerClass != 0)
gEngfuncs.pfnClientCmd("kill");
}