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.
1293 lines
35 KiB
1293 lines
35 KiB
5 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
//=============================================================================//
|
||
|
|
||
|
|
||
|
#include "cbase.h"
|
||
|
|
||
|
#include "ienginevgui.h"
|
||
|
#include <vgui_controls/ScrollBarSlider.h>
|
||
|
#include "vgui/ILocalize.h"
|
||
|
#include "vgui/ISurface.h"
|
||
|
#include "vgui/IInput.h"
|
||
|
#include "tf_controls.h"
|
||
|
#include "vgui_controls/TextImage.h"
|
||
|
#include "vgui_controls/PropertyPage.h"
|
||
|
#include "econ_item_system.h"
|
||
|
#include "iachievementmgr.h"
|
||
|
#include <vgui_controls/ListPanel.h>
|
||
|
#include <vgui_controls/PanelListPanel.h>
|
||
|
#include <vgui_controls/Label.h>
|
||
|
#include <vgui_controls/Button.h>
|
||
|
#include <vgui_controls/MessageBox.h>
|
||
|
#include <vgui_controls/CheckButton.h>
|
||
|
#include <vgui_controls/ComboBox.h>
|
||
|
#include <vgui_controls/TextEntry.h>
|
||
|
#include <../common/GameUI/cvarslider.h>
|
||
|
#include "filesystem.h"
|
||
|
|
||
|
using namespace vgui;
|
||
|
|
||
|
wchar_t* LocalizeNumberWithToken( const char* pszLocToken, int nValue )
|
||
|
{
|
||
|
static wchar_t wszOutString[ 128 ];
|
||
|
wchar_t wszCount[ 16 ];
|
||
|
_snwprintf( wszCount, ARRAYSIZE( wszCount ), L"%d", nValue );
|
||
|
const wchar_t *wpszFormat = g_pVGuiLocalize->Find( pszLocToken );
|
||
|
g_pVGuiLocalize->ConstructString_safe( wszOutString, wpszFormat, 1, wszCount );
|
||
|
|
||
|
return wszOutString;
|
||
|
}
|
||
|
|
||
|
DECLARE_BUILD_FACTORY( CExCheckButton );
|
||
|
DECLARE_BUILD_FACTORY( CTFFooter );
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Xbox-specific panel that displays button icons text labels
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CTFFooter::CTFFooter( Panel *parent, const char *panelName ) : BaseClass( parent, panelName )
|
||
|
{
|
||
|
SetVisible( true );
|
||
|
SetAlpha( 0 );
|
||
|
|
||
|
m_nButtonGap = 32;
|
||
|
m_ButtonPinRight = 100;
|
||
|
m_FooterTall = 80;
|
||
|
|
||
|
m_ButtonOffsetFromTop = 0;
|
||
|
m_ButtonSeparator = 4;
|
||
|
m_TextAdjust = 0;
|
||
|
|
||
|
m_bPaintBackground = false;
|
||
|
m_bCenterHorizontal = true;
|
||
|
|
||
|
m_szButtonFont[0] = '\0';
|
||
|
m_szTextFont[0] = '\0';
|
||
|
m_szFGColor[0] = '\0';
|
||
|
m_szBGColor[0] = '\0';
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CTFFooter::~CTFFooter()
|
||
|
{
|
||
|
ClearButtons();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTFFooter::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||
|
{
|
||
|
BaseClass::ApplySchemeSettings( pScheme );
|
||
|
|
||
|
m_hButtonFont = pScheme->GetFont( ( m_szButtonFont[0] != '\0' ) ? m_szButtonFont : "GameUIButtons" );
|
||
|
m_hTextFont = pScheme->GetFont( ( m_szTextFont[0] != '\0' ) ? m_szTextFont : "MenuLarge" );
|
||
|
|
||
|
SetFgColor( pScheme->GetColor( m_szFGColor, Color( 255, 255, 255, 255 ) ) );
|
||
|
SetBgColor( pScheme->GetColor( m_szBGColor, Color( 0, 0, 0, 255 ) ) );
|
||
|
|
||
|
int x, y, w, h;
|
||
|
GetParent()->GetBounds( x, y, w, h );
|
||
|
SetBounds( x, h - m_FooterTall, w, m_FooterTall );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTFFooter::ApplySettings( KeyValues *inResourceData )
|
||
|
{
|
||
|
BaseClass::ApplySettings( inResourceData );
|
||
|
|
||
|
// gap between hints
|
||
|
m_nButtonGap = inResourceData->GetInt( "buttongap", 32 );
|
||
|
m_ButtonPinRight = inResourceData->GetInt( "button_pin_right", 100 );
|
||
|
m_FooterTall = inResourceData->GetInt( "tall", 80 );
|
||
|
m_ButtonOffsetFromTop = inResourceData->GetInt( "buttonoffsety", 0 );
|
||
|
m_ButtonSeparator = inResourceData->GetInt( "button_separator", 4 );
|
||
|
m_TextAdjust = inResourceData->GetInt( "textadjust", 0 );
|
||
|
|
||
|
m_bCenterHorizontal = ( inResourceData->GetInt( "center", 1 ) == 1 );
|
||
|
m_bPaintBackground = ( inResourceData->GetInt( "paintbackground", 0 ) == 1 );
|
||
|
|
||
|
// fonts for text and button
|
||
|
Q_strncpy( m_szTextFont, inResourceData->GetString( "fonttext", "MenuLarge" ), sizeof( m_szTextFont ) );
|
||
|
Q_strncpy( m_szButtonFont, inResourceData->GetString( "fontbutton", "GameUIButtons" ), sizeof( m_szButtonFont ) );
|
||
|
|
||
|
// fg and bg colors
|
||
|
Q_strncpy( m_szFGColor, inResourceData->GetString( "fgcolor", "White" ), sizeof( m_szFGColor ) );
|
||
|
Q_strncpy( m_szBGColor, inResourceData->GetString( "bgcolor", "Black" ), sizeof( m_szBGColor ) );
|
||
|
|
||
|
// clear the buttons because we're going to re-add them here
|
||
|
ClearButtons();
|
||
|
|
||
|
for ( KeyValues *pButton = inResourceData->GetFirstSubKey(); pButton != NULL; pButton = pButton->GetNextKey() )
|
||
|
{
|
||
|
const char *pNameButton = pButton->GetName();
|
||
|
|
||
|
if ( !Q_stricmp( pNameButton, "button" ) )
|
||
|
{
|
||
|
// Add a button to the footer
|
||
|
const char *pName = pButton->GetString( "name", "NULL" );
|
||
|
const char *pText = pButton->GetString( "text", "NULL" );
|
||
|
const char *pIcon = pButton->GetString( "icon", "NULL" );
|
||
|
AddNewButtonLabel( pName, pText, pIcon );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
InvalidateLayout( false, true ); // force ApplySchemeSettings to run
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTFFooter::AddNewButtonLabel( const char *name, const char *text, const char *icon )
|
||
|
{
|
||
|
FooterButton_t *button = new FooterButton_t;
|
||
|
|
||
|
button->bVisible = true;
|
||
|
Q_strncpy( button->name, name, sizeof( button->name ) );
|
||
|
|
||
|
// Button icons are a single character
|
||
|
wchar_t *pIcon = g_pVGuiLocalize->Find( icon );
|
||
|
if ( pIcon )
|
||
|
{
|
||
|
button->icon[0] = pIcon[0];
|
||
|
button->icon[1] = '\0';
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
button->icon[0] = '\0';
|
||
|
}
|
||
|
|
||
|
// Set the help text
|
||
|
wchar_t *pText = g_pVGuiLocalize->Find( text );
|
||
|
if ( pText )
|
||
|
{
|
||
|
wcsncpy( button->text, pText, wcslen( pText ) + 1 );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
button->text[0] = '\0';
|
||
|
}
|
||
|
|
||
|
m_Buttons.AddToTail( button );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTFFooter::ShowButtonLabel( const char *name, bool show )
|
||
|
{
|
||
|
for ( int i = 0; i < m_Buttons.Count(); ++i )
|
||
|
{
|
||
|
if ( !Q_stricmp( m_Buttons[ i ]->name, name ) )
|
||
|
{
|
||
|
m_Buttons[ i ]->bVisible = show;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTFFooter::PaintBackground( void )
|
||
|
{
|
||
|
if ( !m_bPaintBackground )
|
||
|
return;
|
||
|
|
||
|
BaseClass::PaintBackground();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTFFooter::Paint( void )
|
||
|
{
|
||
|
// inset from right edge
|
||
|
int wide = GetWide();
|
||
|
|
||
|
// center the text within the button
|
||
|
int buttonHeight = vgui::surface()->GetFontTall( m_hButtonFont );
|
||
|
int fontHeight = vgui::surface()->GetFontTall( m_hTextFont );
|
||
|
int textY = ( buttonHeight - fontHeight )/2 + m_TextAdjust;
|
||
|
|
||
|
if ( textY < 0 )
|
||
|
{
|
||
|
textY = 0;
|
||
|
}
|
||
|
|
||
|
int y = m_ButtonOffsetFromTop;
|
||
|
|
||
|
if ( !m_bCenterHorizontal )
|
||
|
{
|
||
|
// draw the buttons, right to left
|
||
|
int x = wide - m_ButtonPinRight;
|
||
|
|
||
|
vgui::Label label( this, "temp", L"" );
|
||
|
for ( int i = m_Buttons.Count() - 1 ; i >= 0 ; --i )
|
||
|
{
|
||
|
FooterButton_t *pButton = m_Buttons[i];
|
||
|
if ( !pButton->bVisible )
|
||
|
continue;
|
||
|
|
||
|
// Get the string length
|
||
|
label.SetFont( m_hTextFont );
|
||
|
label.SetText( pButton->text );
|
||
|
label.SizeToContents();
|
||
|
|
||
|
int iTextWidth = label.GetWide();
|
||
|
|
||
|
if ( iTextWidth == 0 )
|
||
|
x += m_nButtonGap; // There's no text, so remove the gap between buttons
|
||
|
else
|
||
|
x -= iTextWidth;
|
||
|
|
||
|
// Draw the string
|
||
|
vgui::surface()->DrawSetTextFont( m_hTextFont );
|
||
|
vgui::surface()->DrawSetTextColor( GetFgColor() );
|
||
|
vgui::surface()->DrawSetTextPos( x, y + textY );
|
||
|
vgui::surface()->DrawPrintText( pButton->text, wcslen( pButton->text ) );
|
||
|
|
||
|
// Draw the button
|
||
|
// back up button width and a little extra to leave a gap between button and text
|
||
|
x -= ( vgui::surface()->GetCharacterWidth( m_hButtonFont, pButton->icon[0] ) + m_ButtonSeparator );
|
||
|
vgui::surface()->DrawSetTextFont( m_hButtonFont );
|
||
|
vgui::surface()->DrawSetTextColor( 255, 255, 255, 255 );
|
||
|
vgui::surface()->DrawSetTextPos( x, y );
|
||
|
vgui::surface()->DrawPrintText( pButton->icon, 1 );
|
||
|
|
||
|
// back up to next string
|
||
|
x -= m_nButtonGap;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// center the buttons (as a group)
|
||
|
int x = wide / 2;
|
||
|
int totalWidth = 0;
|
||
|
int i = 0;
|
||
|
int nButtonCount = 0;
|
||
|
|
||
|
vgui::Label label( this, "temp", L"" );
|
||
|
|
||
|
// need to loop through and figure out how wide our buttons and text are (with gaps between) so we can offset from the center
|
||
|
for ( i = 0; i < m_Buttons.Count(); ++i )
|
||
|
{
|
||
|
FooterButton_t *pButton = m_Buttons[i];
|
||
|
|
||
|
if ( !pButton->bVisible )
|
||
|
continue;
|
||
|
|
||
|
// Get the string length
|
||
|
label.SetFont( m_hTextFont );
|
||
|
label.SetText( pButton->text );
|
||
|
label.SizeToContents();
|
||
|
|
||
|
totalWidth += vgui::surface()->GetCharacterWidth( m_hButtonFont, pButton->icon[0] );
|
||
|
totalWidth += m_ButtonSeparator;
|
||
|
totalWidth += label.GetWide();
|
||
|
|
||
|
nButtonCount++; // keep track of how many active buttons we'll be drawing
|
||
|
}
|
||
|
|
||
|
totalWidth += ( nButtonCount - 1 ) * m_nButtonGap; // add in the gaps between the buttons
|
||
|
x -= ( totalWidth / 2 );
|
||
|
|
||
|
for ( i = 0; i < m_Buttons.Count(); ++i )
|
||
|
{
|
||
|
FooterButton_t *pButton = m_Buttons[i];
|
||
|
|
||
|
if ( !pButton->bVisible )
|
||
|
continue;
|
||
|
|
||
|
// Get the string length
|
||
|
label.SetFont( m_hTextFont );
|
||
|
label.SetText( pButton->text );
|
||
|
label.SizeToContents();
|
||
|
|
||
|
int iTextWidth = label.GetWide();
|
||
|
|
||
|
// Draw the icon
|
||
|
vgui::surface()->DrawSetTextFont( m_hButtonFont );
|
||
|
vgui::surface()->DrawSetTextColor( 255, 255, 255, 255 );
|
||
|
vgui::surface()->DrawSetTextPos( x, y );
|
||
|
vgui::surface()->DrawPrintText( pButton->icon, 1 );
|
||
|
x += vgui::surface()->GetCharacterWidth( m_hButtonFont, pButton->icon[0] ) + m_ButtonSeparator;
|
||
|
|
||
|
// Draw the string
|
||
|
vgui::surface()->DrawSetTextFont( m_hTextFont );
|
||
|
vgui::surface()->DrawSetTextColor( GetFgColor() );
|
||
|
vgui::surface()->DrawSetTextPos( x, y + textY );
|
||
|
vgui::surface()->DrawPrintText( pButton->text, wcslen( pButton->text ) );
|
||
|
|
||
|
x += iTextWidth + m_nButtonGap;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTFFooter::ClearButtons( void )
|
||
|
{
|
||
|
m_Buttons.PurgeAndDeleteElements();
|
||
|
}
|
||
|
|
||
|
#define OPTIONS_DIR "cfg"
|
||
|
#define DEFAULT_OPTIONS_FILE OPTIONS_DIR "/user_default.scr"
|
||
|
#define OPTIONS_FILE OPTIONS_DIR "/user.scr"
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Constructor
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CTFAdvancedOptionsDialog::CTFAdvancedOptionsDialog(vgui::Panel *parent) : BaseClass(NULL, "TFAdvancedOptionsDialog")
|
||
|
{
|
||
|
// Need to use the clientscheme (we're not parented to a clientscheme'd panel)
|
||
|
vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme");
|
||
|
SetScheme(scheme);
|
||
|
SetProportional( true );
|
||
|
|
||
|
m_pListPanel = new vgui::PanelListPanel( this, "PanelListPanel" );
|
||
|
|
||
|
m_pList = NULL;
|
||
|
|
||
|
m_pToolTip = new CTFTextToolTip( this );
|
||
|
m_pToolTipEmbeddedPanel = new vgui::EditablePanel( this, "TooltipPanel" );
|
||
|
m_pToolTipEmbeddedPanel->SetKeyBoardInputEnabled( false );
|
||
|
m_pToolTipEmbeddedPanel->SetMouseInputEnabled( false );
|
||
|
m_pToolTip->SetEmbeddedPanel( m_pToolTipEmbeddedPanel );
|
||
|
m_pToolTip->SetTooltipDelay( 0 );
|
||
|
|
||
|
m_pDescription = new CInfoDescription();
|
||
|
m_pDescription->InitFromFile( DEFAULT_OPTIONS_FILE );
|
||
|
m_pDescription->InitFromFile( OPTIONS_FILE, false );
|
||
|
m_pDescription->TransferCurrentValues( NULL );
|
||
|
|
||
|
// MoveToCenterOfScreen();
|
||
|
// SetSizeable( false );
|
||
|
// SetDeleteSelfOnClose( true );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Destructor
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CTFAdvancedOptionsDialog::~CTFAdvancedOptionsDialog()
|
||
|
{
|
||
|
delete m_pDescription;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTFAdvancedOptionsDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||
|
{
|
||
|
BaseClass::ApplySchemeSettings( pScheme );
|
||
|
|
||
|
LoadControlSettings("resource/ui/TFAdvancedOptionsDialog.res");
|
||
|
m_pListPanel->SetFirstColumnWidth( 0 );
|
||
|
|
||
|
CreateControls();
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTFAdvancedOptionsDialog::ApplySettings( KeyValues *inResourceData )
|
||
|
{
|
||
|
BaseClass::ApplySettings( inResourceData );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTFAdvancedOptionsDialog::OnClose()
|
||
|
{
|
||
|
BaseClass::OnClose();
|
||
|
|
||
|
TFModalStack()->PopModal( this );
|
||
|
MarkForDeletion();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
// Input : *command -
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTFAdvancedOptionsDialog::OnCommand( const char *command )
|
||
|
{
|
||
|
if ( !stricmp( command, "Ok" ) )
|
||
|
{
|
||
|
// OnApplyChanges();
|
||
|
SaveValues();
|
||
|
OnClose();
|
||
|
return;
|
||
|
}
|
||
|
else if ( !stricmp( command, "Close" ) )
|
||
|
{
|
||
|
OnClose();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
BaseClass::OnCommand( command );
|
||
|
}
|
||
|
|
||
|
void CTFAdvancedOptionsDialog::OnKeyCodeTyped(KeyCode code)
|
||
|
{
|
||
|
// force ourselves to be closed if the escape key it pressed
|
||
|
if ( code == KEY_ESCAPE )
|
||
|
{
|
||
|
OnClose();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
BaseClass::OnKeyCodeTyped(code);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTFAdvancedOptionsDialog::OnKeyCodePressed(KeyCode code)
|
||
|
{
|
||
|
// force ourselves to be closed if the escape key it pressed
|
||
|
if ( GetBaseButtonCode( code ) == KEY_XBUTTON_B || GetBaseButtonCode( code ) == STEAMCONTROLLER_B || GetBaseButtonCode( code ) == STEAMCONTROLLER_START )
|
||
|
{
|
||
|
OnClose();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
BaseClass::OnKeyCodePressed(code);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTFAdvancedOptionsDialog::GatherCurrentValues()
|
||
|
{
|
||
|
if ( !m_pDescription )
|
||
|
return;
|
||
|
|
||
|
// OK
|
||
|
CheckButton *pBox;
|
||
|
TextEntry *pEdit;
|
||
|
ComboBox *pCombo;
|
||
|
CCvarSlider *pSlider;
|
||
|
|
||
|
mpcontrol_t *pList;
|
||
|
|
||
|
CScriptObject *pObj;
|
||
|
CScriptListItem *pItem;
|
||
|
|
||
|
char szValue[256];
|
||
|
char strValue[ 256 ];
|
||
|
|
||
|
pList = m_pList;
|
||
|
while ( pList )
|
||
|
{
|
||
|
pObj = pList->pScrObj;
|
||
|
|
||
|
if ( pObj->type == O_CATEGORY )
|
||
|
{
|
||
|
pList = pList->next;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if ( !pList->pControl )
|
||
|
{
|
||
|
pObj->SetCurValue( pObj->defValue );
|
||
|
pList = pList->next;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
switch ( pObj->type )
|
||
|
{
|
||
|
case O_BOOL:
|
||
|
pBox = (CheckButton *)pList->pControl;
|
||
|
sprintf( szValue, "%s", pBox->IsSelected() ? "1" : "0" );
|
||
|
break;
|
||
|
case O_NUMBER:
|
||
|
pEdit = ( TextEntry * )pList->pControl;
|
||
|
pEdit->GetText( strValue, sizeof( strValue ) );
|
||
|
sprintf( szValue, "%s", strValue );
|
||
|
break;
|
||
|
case O_STRING:
|
||
|
pEdit = ( TextEntry * )pList->pControl;
|
||
|
pEdit->GetText( strValue, sizeof( strValue ) );
|
||
|
sprintf( szValue, "%s", strValue );
|
||
|
break;
|
||
|
case O_LIST:
|
||
|
{
|
||
|
pCombo = (ComboBox *)pList->pControl;
|
||
|
// pCombo->GetText( strValue, sizeof( strValue ) );
|
||
|
int activeItem = pCombo->GetActiveItem();
|
||
|
|
||
|
pItem = pObj->pListItems;
|
||
|
// int n = (int)pObj->fdefValue;
|
||
|
|
||
|
while ( pItem )
|
||
|
{
|
||
|
if (!activeItem--)
|
||
|
break;
|
||
|
|
||
|
pItem = pItem->pNext;
|
||
|
}
|
||
|
|
||
|
if ( pItem )
|
||
|
{
|
||
|
sprintf( szValue, "%s", pItem->szValue );
|
||
|
}
|
||
|
else // Couln't find index
|
||
|
{
|
||
|
//assert(!("Couldn't find string in list, using default value"));
|
||
|
sprintf( szValue, "%s", pObj->defValue );
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case O_SLIDER:
|
||
|
pSlider = ( CCvarSlider * )pList->pControl;
|
||
|
sprintf( szValue, "%.2f", pSlider->GetSliderValue() );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Remove double quotes and % characters
|
||
|
UTIL_StripInvalidCharacters( szValue, sizeof(szValue) );
|
||
|
|
||
|
V_strcpy_safe( strValue, szValue );
|
||
|
|
||
|
pObj->SetCurValue( strValue );
|
||
|
|
||
|
pList = pList->next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTFAdvancedOptionsDialog::CreateControls()
|
||
|
{
|
||
|
DestroyControls();
|
||
|
|
||
|
// Go through desciption creating controls
|
||
|
CScriptObject *pObj;
|
||
|
|
||
|
pObj = m_pDescription->pObjList;
|
||
|
|
||
|
// Build out the clan dropdown
|
||
|
CScriptObject *pClanObj = m_pDescription->FindObject( "cl_clanid" );
|
||
|
ISteamFriends *pFriends = steamapicontext->SteamFriends();
|
||
|
if ( pFriends && pClanObj )
|
||
|
{
|
||
|
pClanObj->RemoveAndDeleteAllItems();
|
||
|
int iGroupCount = pFriends->GetClanCount();
|
||
|
pClanObj->AddItem( new CScriptListItem( "#Cstrike_ClanTag_None", "0" ) );
|
||
|
for ( int k = 0; k < iGroupCount; ++ k )
|
||
|
{
|
||
|
CSteamID clanID = pFriends->GetClanByIndex( k );
|
||
|
const char *pName = pFriends->GetClanName( clanID );
|
||
|
const char *pTag = pFriends->GetClanTag( clanID );
|
||
|
|
||
|
char id[12];
|
||
|
Q_snprintf( id, sizeof( id ), "%d", clanID.GetAccountID() );
|
||
|
pClanObj->AddItem( new CScriptListItem( CFmtStr( "%s (%s)", pTag, pName ), id ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
mpcontrol_t *pCtrl;
|
||
|
|
||
|
CheckButton *pBox;
|
||
|
TextEntry *pEdit;
|
||
|
ComboBox *pCombo;
|
||
|
CCvarSlider *pSlider;
|
||
|
CScriptListItem *pListItem;
|
||
|
|
||
|
Panel *objParent = m_pListPanel;
|
||
|
|
||
|
IScheme *pScheme = scheme()->GetIScheme( GetScheme() );
|
||
|
vgui::HFont hTextFont = pScheme->GetFont( "HudFontSmallestBold", true );
|
||
|
Color tanDark = pScheme->GetColor( "TanDark", Color(255,0,0,255) );
|
||
|
|
||
|
while ( pObj )
|
||
|
{
|
||
|
if ( pObj->type == O_OBSOLETE )
|
||
|
{
|
||
|
pObj = pObj->pNext;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
pCtrl = new mpcontrol_t( objParent, "mpcontrol_t" );
|
||
|
pCtrl->type = pObj->type;
|
||
|
|
||
|
// Force it to invalidate scheme now, so we can change color afterwards and have it persist
|
||
|
pCtrl->InvalidateLayout( true, true );
|
||
|
|
||
|
switch ( pCtrl->type )
|
||
|
{
|
||
|
case O_BOOL:
|
||
|
pBox = new CheckButton( pCtrl, "DescCheckButton", pObj->prompt );
|
||
|
pBox->SetSelected( pObj->fdefValue != 0.0f ? true : false );
|
||
|
|
||
|
pCtrl->pControl = (Panel *)pBox;
|
||
|
pBox->SetFont( hTextFont );
|
||
|
|
||
|
pBox->InvalidateLayout( true, true );
|
||
|
|
||
|
// This is utterly fucking retarded.
|
||
|
pBox->SetFgColor( tanDark );
|
||
|
pBox->SetDefaultColor( tanDark, pBox->GetBgColor() );
|
||
|
pBox->SetArmedColor( tanDark, pBox->GetBgColor() );
|
||
|
pBox->SetDepressedColor( tanDark, pBox->GetBgColor() );
|
||
|
pBox->SetSelectedColor( tanDark, pBox->GetBgColor() );
|
||
|
pBox->SetHighlightColor( tanDark );
|
||
|
pBox->GetCheckImage()->SetColor( tanDark );
|
||
|
break;
|
||
|
case O_STRING:
|
||
|
case O_NUMBER:
|
||
|
pEdit = new TextEntry( pCtrl, "DescTextEntry");
|
||
|
pEdit->InsertString(pObj->defValue);
|
||
|
pCtrl->pControl = (Panel *)pEdit;
|
||
|
pEdit->SetFont( hTextFont );
|
||
|
|
||
|
pEdit->InvalidateLayout( true, true );
|
||
|
pEdit->SetBgColor( Color(0,0,0,255) );
|
||
|
break;
|
||
|
case O_LIST:
|
||
|
{
|
||
|
pCombo = new ComboBox( pCtrl, "DescComboBox", 5, false );
|
||
|
|
||
|
// track which row matches the current value
|
||
|
int iRow = -1;
|
||
|
int iCount = 0;
|
||
|
pListItem = pObj->pListItems;
|
||
|
while ( pListItem )
|
||
|
{
|
||
|
if ( iRow == -1 && !Q_stricmp( pListItem->szValue, pObj->curValue ) )
|
||
|
iRow = iCount;
|
||
|
|
||
|
pCombo->AddItem( pListItem->szItemText, NULL );
|
||
|
pListItem = pListItem->pNext;
|
||
|
++iCount;
|
||
|
}
|
||
|
|
||
|
|
||
|
pCombo->ActivateItemByRow( iRow );
|
||
|
|
||
|
pCtrl->pControl = (Panel *)pCombo;
|
||
|
pCombo->SetFont( hTextFont );
|
||
|
}
|
||
|
break;
|
||
|
case O_SLIDER:
|
||
|
pSlider = new CCvarSlider( pCtrl, "DescSlider", "Test", pObj->fMin, pObj->fMax, pObj->cvarname, false );
|
||
|
pCtrl->pControl = (Panel *)pSlider;
|
||
|
break;
|
||
|
case O_CATEGORY:
|
||
|
pCtrl->SetBorder( pScheme->GetBorder("OptionsCategoryBorder") );
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if ( pCtrl->type != O_BOOL )
|
||
|
{
|
||
|
pCtrl->pPrompt = new vgui::Label( pCtrl, "DescLabel", "" );
|
||
|
pCtrl->pPrompt->SetContentAlignment( vgui::Label::a_west );
|
||
|
pCtrl->pPrompt->SetTextInset( 5, 0 );
|
||
|
pCtrl->pPrompt->SetText( pObj->prompt );
|
||
|
pCtrl->pPrompt->SetFont( hTextFont );
|
||
|
|
||
|
pCtrl->pPrompt->InvalidateLayout( true, true );
|
||
|
|
||
|
if ( pCtrl->type == O_CATEGORY )
|
||
|
{
|
||
|
pCtrl->pPrompt->SetFont( pScheme->GetFont( "HudFontSmallBold", true ) );
|
||
|
pCtrl->pPrompt->SetFgColor( pScheme->GetColor( "TanLight", Color(255,0,0,255) ) );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pCtrl->pPrompt->SetFgColor( tanDark );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pCtrl->pScrObj = pObj;
|
||
|
|
||
|
switch ( pCtrl->type )
|
||
|
{
|
||
|
case O_BOOL:
|
||
|
case O_STRING:
|
||
|
case O_NUMBER:
|
||
|
case O_LIST:
|
||
|
case O_CATEGORY:
|
||
|
pCtrl->SetSize( m_iControlW, m_iControlH );
|
||
|
break;
|
||
|
case O_SLIDER:
|
||
|
pCtrl->SetSize( m_iSliderW, m_iSliderH );
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Hook up the tooltip, if the entry has one
|
||
|
if ( pObj->tooltip && pObj->tooltip[0] )
|
||
|
{
|
||
|
if ( pCtrl->pPrompt )
|
||
|
{
|
||
|
pCtrl->pPrompt->SetTooltip( m_pToolTip, pObj->tooltip );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pCtrl->SetTooltip( m_pToolTip, pObj->tooltip );
|
||
|
pCtrl->pControl->SetTooltip( m_pToolTip, pObj->tooltip );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_pListPanel->AddItem( NULL, pCtrl );
|
||
|
|
||
|
// Link it in
|
||
|
if ( !m_pList )
|
||
|
{
|
||
|
m_pList = pCtrl;
|
||
|
pCtrl->next = NULL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
mpcontrol_t *p;
|
||
|
p = m_pList;
|
||
|
while ( p )
|
||
|
{
|
||
|
if ( !p->next )
|
||
|
{
|
||
|
p->next = pCtrl;
|
||
|
pCtrl->next = NULL;
|
||
|
break;
|
||
|
}
|
||
|
p = p->next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pObj = pObj->pNext;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTFAdvancedOptionsDialog::DestroyControls()
|
||
|
{
|
||
|
mpcontrol_t *p, *n;
|
||
|
|
||
|
p = m_pList;
|
||
|
while ( p )
|
||
|
{
|
||
|
n = p->next;
|
||
|
//
|
||
|
if ( p->pControl )
|
||
|
{
|
||
|
p->pControl->MarkForDeletion();
|
||
|
p->pControl = NULL;
|
||
|
}
|
||
|
if ( p->pPrompt )
|
||
|
{
|
||
|
p->pPrompt->MarkForDeletion();
|
||
|
p->pPrompt = NULL;
|
||
|
}
|
||
|
delete p;
|
||
|
p = n;
|
||
|
}
|
||
|
|
||
|
m_pList = NULL;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTFAdvancedOptionsDialog::SaveValues()
|
||
|
{
|
||
|
// Get the values from the controls:
|
||
|
GatherCurrentValues();
|
||
|
|
||
|
// Create the game.cfg file
|
||
|
if ( m_pDescription )
|
||
|
{
|
||
|
FileHandle_t fp;
|
||
|
|
||
|
// Add settings to config.cfg
|
||
|
m_pDescription->WriteToConfig();
|
||
|
|
||
|
g_pFullFileSystem->CreateDirHierarchy( OPTIONS_DIR );
|
||
|
fp = g_pFullFileSystem->Open( OPTIONS_FILE, "wb" );
|
||
|
if ( fp )
|
||
|
{
|
||
|
m_pDescription->WriteToScriptFile( fp );
|
||
|
g_pFullFileSystem->Close( fp );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTFAdvancedOptionsDialog::Deploy( void )
|
||
|
{
|
||
|
SetVisible( true );
|
||
|
MakePopup();
|
||
|
MoveToFront();
|
||
|
SetKeyBoardInputEnabled(true);
|
||
|
SetMouseInputEnabled(true);
|
||
|
TFModalStack()->PushModal( this );
|
||
|
|
||
|
// Center it, keeping requested size
|
||
|
int x, y, ww, wt, wide, tall;
|
||
|
vgui::surface()->GetWorkspaceBounds( x, y, ww, wt );
|
||
|
GetSize(wide, tall);
|
||
|
SetPos(x + ((ww - wide) / 2), y + ((wt - tall) / 2));
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTFTextToolTip::PerformLayout()
|
||
|
{
|
||
|
if ( !ShouldLayout() )
|
||
|
return;
|
||
|
|
||
|
_isDirty = false;
|
||
|
|
||
|
// Resize our text labels to fit.
|
||
|
int iW = m_pEmbeddedPanel->GetWide();
|
||
|
int iH = 0;
|
||
|
for (int i = 0; i < m_pEmbeddedPanel->GetChildCount(); i++)
|
||
|
{
|
||
|
vgui::Label *pLabel = dynamic_cast<vgui::Label*>( m_pEmbeddedPanel->GetChild(i) );
|
||
|
if ( !pLabel )
|
||
|
continue;
|
||
|
|
||
|
// Only checking to see if we have any text
|
||
|
char szTmp[2];
|
||
|
pLabel->GetText( szTmp, sizeof(szTmp) );
|
||
|
if ( !szTmp[0] )
|
||
|
continue;
|
||
|
|
||
|
int iLX, iLY;
|
||
|
pLabel->GetPos( iLX, iLY );
|
||
|
|
||
|
int iMaxWidth = m_pEmbeddedPanel->GetWide() - (iLX * 2);
|
||
|
pLabel->GetTextImage()->ResizeImageToContentMaxWidth( iMaxWidth );
|
||
|
pLabel->SizeToContents();
|
||
|
pLabel->SetWide( iMaxWidth );
|
||
|
pLabel->InvalidateLayout(true);
|
||
|
|
||
|
int iX, iY;
|
||
|
pLabel->GetPos( iX, iY );
|
||
|
iW = MAX( iW, ( pLabel->GetWide() + (iX * 2) ) );
|
||
|
|
||
|
if ( iH == 0 )
|
||
|
{
|
||
|
iH += MAX( iH, pLabel->GetTall() + (iY * 2) );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
iH += MAX( iH, pLabel->GetTall() );
|
||
|
}
|
||
|
}
|
||
|
m_pEmbeddedPanel->SetSize( m_pEmbeddedPanel->GetWide(), iH );
|
||
|
|
||
|
m_pEmbeddedPanel->SetVisible(true);
|
||
|
|
||
|
PositionWindow( m_pEmbeddedPanel );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CTFTextToolTip::PositionWindow( Panel *pTipPanel )
|
||
|
{
|
||
|
int iTipW, iTipH;
|
||
|
pTipPanel->GetSize( iTipW, iTipH );
|
||
|
|
||
|
int cursorX, cursorY;
|
||
|
input()->GetCursorPos(cursorX, cursorY);
|
||
|
|
||
|
int px, py, wide, tall;
|
||
|
ipanel()->GetAbsPos( m_pEmbeddedPanel->GetParent()->GetVPanel(), px, py );
|
||
|
m_pEmbeddedPanel->GetParent()->GetSize(wide, tall);
|
||
|
|
||
|
if ( !m_pEmbeddedPanel->IsPopup() )
|
||
|
{
|
||
|
// Move the cursor into our parent space
|
||
|
cursorX -= px;
|
||
|
cursorY -= py;
|
||
|
}
|
||
|
|
||
|
if (wide - iTipW > cursorX)
|
||
|
{
|
||
|
cursorY += 20;
|
||
|
// menu hanging right
|
||
|
if (tall - iTipH > cursorY)
|
||
|
{
|
||
|
// menu hanging down
|
||
|
pTipPanel->SetPos(cursorX, cursorY);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// menu hanging up
|
||
|
pTipPanel->SetPos(cursorX, cursorY - iTipH - 20);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// menu hanging left
|
||
|
if (tall - iTipH > cursorY)
|
||
|
{
|
||
|
// menu hanging down
|
||
|
pTipPanel->SetPos( Max( 0, cursorX - iTipW ), cursorY);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// menu hanging up
|
||
|
pTipPanel->SetPos( Max( 0, cursorX - iTipW ), cursorY - iTipH - 20 );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static vgui::DHANDLE<CTFAdvancedOptionsDialog> g_pTFAdvancedOptionsDialog;
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Callback to open the game menus
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CL_OpenTFAdvancedOptionsDialog( const CCommand &args )
|
||
|
{
|
||
|
if ( g_pTFAdvancedOptionsDialog.Get() == NULL )
|
||
|
{
|
||
|
g_pTFAdvancedOptionsDialog = vgui::SETUP_PANEL( new CTFAdvancedOptionsDialog( NULL ) );
|
||
|
}
|
||
|
|
||
|
g_pTFAdvancedOptionsDialog->Deploy();
|
||
|
}
|
||
|
|
||
|
// the console commands
|
||
|
static ConCommand opentf2options( "opentf2options", &CL_OpenTFAdvancedOptionsDialog, "Displays the TF2 Advanced Options dialog." );
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: A scroll bar that can have specified width
|
||
|
//-----------------------------------------------------------------------------
|
||
|
class CExScrollBar : public ScrollBar
|
||
|
{
|
||
|
DECLARE_CLASS_SIMPLE( CExScrollBar, ScrollBar );
|
||
|
public:
|
||
|
|
||
|
CExScrollBar( Panel *parent, const char *name, bool bVertical )
|
||
|
: ScrollBar( parent, name, bVertical )
|
||
|
{}
|
||
|
|
||
|
virtual void ApplySchemeSettings( IScheme *pScheme ) OVERRIDE
|
||
|
{
|
||
|
// Deliberately skip ScrollBar
|
||
|
Panel::ApplySchemeSettings( pScheme );
|
||
|
}
|
||
|
};
|
||
|
|
||
|
DECLARE_BUILD_FACTORY( CExScrollingEditablePanel );
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CExScrollingEditablePanel::CExScrollingEditablePanel( Panel *pParent, const char *pszName )
|
||
|
: EditablePanel( pParent, pszName )
|
||
|
, m_nLastScrollValue( 0 )
|
||
|
, m_bUseMouseWheelToScroll( true )
|
||
|
{
|
||
|
m_pScrollBar = new CExScrollBar( this, "ScrollBar", true );
|
||
|
m_pScrollBar->AddActionSignalTarget( this );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CExScrollingEditablePanel::~CExScrollingEditablePanel()
|
||
|
{}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CExScrollingEditablePanel::ApplySettings( KeyValues *inResourceData )
|
||
|
{
|
||
|
BaseClass::ApplySettings( inResourceData );
|
||
|
|
||
|
KeyValues *pScrollbarKV = inResourceData->FindKey( "Scrollbar" );
|
||
|
if ( pScrollbarKV )
|
||
|
{
|
||
|
m_pScrollBar->ApplySettings( pScrollbarKV );
|
||
|
}
|
||
|
|
||
|
m_bUseMouseWheelToScroll = inResourceData->GetBool( "allow_mouse_wheel_to_scroll", true );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CExScrollingEditablePanel::OnSizeChanged( int newWide, int newTall )
|
||
|
{
|
||
|
BaseClass::OnSizeChanged( newWide, newTall );
|
||
|
|
||
|
int nDelta = m_nLastScrollValue;
|
||
|
// Go through all our children and move them BACK into position
|
||
|
int nNumChildren = GetChildCount();
|
||
|
for ( int i=0; i < nNumChildren; ++i )
|
||
|
{
|
||
|
Panel* pChild = GetChild( i );
|
||
|
|
||
|
if ( pChild == m_pScrollBar )
|
||
|
continue;
|
||
|
|
||
|
EditablePanel* pEditableChild = dynamic_cast< EditablePanel* >( pChild );
|
||
|
if ( pEditableChild && pEditableChild->ShouldSkipAutoResize() )
|
||
|
continue;
|
||
|
|
||
|
int x,y;
|
||
|
pChild->GetPos( x, y );
|
||
|
|
||
|
pChild->SetPos( x, y - nDelta );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CExScrollingEditablePanel::PerformLayout()
|
||
|
{
|
||
|
BaseClass::PerformLayout();
|
||
|
|
||
|
int nFurthestY = 0;
|
||
|
|
||
|
// Go through all our children and find the lowest point on the lowest child
|
||
|
// that we'd need to scroll to
|
||
|
int nNumChildren = GetChildCount();
|
||
|
for ( int i=0; i < nNumChildren; ++i )
|
||
|
{
|
||
|
Panel* pChild = GetChild( i );
|
||
|
|
||
|
if ( pChild == m_pScrollBar )
|
||
|
continue;
|
||
|
|
||
|
int x,y,wide,tall;
|
||
|
pChild->GetBounds( x, y, wide, tall );
|
||
|
|
||
|
// Offset by our scroll value
|
||
|
y += m_nLastScrollValue;
|
||
|
|
||
|
if ( m_bRestrictWidth )
|
||
|
{
|
||
|
int nMaxWide = Min( x + wide, GetWide() - m_pScrollBar->GetWide() );
|
||
|
pChild->SetWide( nMaxWide - x );
|
||
|
}
|
||
|
|
||
|
nFurthestY = Max( y + tall, nFurthestY );
|
||
|
}
|
||
|
|
||
|
int nMaxRange = nFurthestY + m_iBottomBuffer;
|
||
|
m_pScrollBar->SetRange( 0, nMaxRange );
|
||
|
m_pScrollBar->SetRangeWindow( GetTall() );
|
||
|
|
||
|
OnScrollBarSliderMoved();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Called when the scroll bar moves
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CExScrollingEditablePanel::OnScrollBarSliderMoved()
|
||
|
{
|
||
|
// Figure out how far they just scrolled
|
||
|
int nScrollAmount = m_pScrollBar->GetValue();
|
||
|
int nDelta = nScrollAmount - m_nLastScrollValue;
|
||
|
|
||
|
if ( nDelta == 0 )
|
||
|
return;
|
||
|
|
||
|
ShiftChildren( nDelta );
|
||
|
|
||
|
m_nLastScrollValue = nScrollAmount;
|
||
|
}
|
||
|
|
||
|
void CExScrollingEditablePanel::ShiftChildren( int nDistance )
|
||
|
{
|
||
|
// Go through all our children and move them
|
||
|
int nNumChildren = GetChildCount();
|
||
|
for ( int i=0; i < nNumChildren; ++i )
|
||
|
{
|
||
|
Panel* pChild = GetChild( i );
|
||
|
|
||
|
if ( pChild == m_pScrollBar )
|
||
|
continue;
|
||
|
|
||
|
int x,y;
|
||
|
pChild->GetPos( x, y );
|
||
|
|
||
|
pChild->SetPos( x, y - nDistance );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// respond to mouse wheel events
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CExScrollingEditablePanel::OnMouseWheeled( int delta )
|
||
|
{
|
||
|
if ( !m_bUseMouseWheelToScroll )
|
||
|
{
|
||
|
BaseClass::OnMouseWheeled( delta );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
int val = m_pScrollBar->GetValue();
|
||
|
val -= ( delta * m_iScrollStep );
|
||
|
m_pScrollBar->SetValue( val );
|
||
|
}
|
||
|
|
||
|
DECLARE_BUILD_FACTORY( CScrollableList );
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Clearnup
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CScrollableList::~CScrollableList()
|
||
|
{
|
||
|
ClearAutoLayoutPanels();
|
||
|
}
|
||
|
|
||
|
void CScrollableList::PerformLayout()
|
||
|
{
|
||
|
int nYpos = -m_nLastScrollValue;
|
||
|
|
||
|
for( int i=0; i<m_vecAutoLayoutPanels.Count(); ++i )
|
||
|
{
|
||
|
LayoutInfo_t layout = m_vecAutoLayoutPanels[ i ];
|
||
|
nYpos += layout.m_nGap;
|
||
|
|
||
|
layout.m_pPanel->SetPos( layout.m_pPanel->GetXPos(), nYpos );
|
||
|
|
||
|
nYpos += layout.m_pPanel->GetTall();
|
||
|
}
|
||
|
|
||
|
BaseClass::PerformLayout();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Add a panel to the bottom
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CScrollableList::AddPanel( Panel* pPanel, int nGap )
|
||
|
{
|
||
|
// We're the captain now
|
||
|
pPanel->SetParent( this );
|
||
|
pPanel->SetAutoDelete( false );
|
||
|
|
||
|
auto idx = m_vecAutoLayoutPanels.AddToTail();
|
||
|
LayoutInfo_t& layout = m_vecAutoLayoutPanels[ idx ];
|
||
|
layout.m_pPanel = pPanel;
|
||
|
layout.m_nGap = nGap;
|
||
|
|
||
|
// Need to do a perform layout so we get sized correctly
|
||
|
InvalidateLayout();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Delete any panels we own
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CScrollableList::ClearAutoLayoutPanels()
|
||
|
{
|
||
|
FOR_EACH_VEC( m_vecAutoLayoutPanels, i )
|
||
|
{
|
||
|
m_vecAutoLayoutPanels[ i ].m_pPanel->MarkForDeletion();
|
||
|
}
|
||
|
|
||
|
m_vecAutoLayoutPanels.Purge();
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CExpandablePanel::CExpandablePanel( Panel* pParent, const char* pszName )
|
||
|
: vgui::EditablePanel( pParent, pszName )
|
||
|
, m_bExpanded( false )
|
||
|
, m_flAnimEndTime( 0.f )
|
||
|
, m_flResizeTime( 0.f )
|
||
|
{}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Set spcific collapsed state
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CExpandablePanel::SetCollapsed( bool bCollapsed )
|
||
|
{
|
||
|
if ( bCollapsed == m_bExpanded )
|
||
|
{
|
||
|
ToggleCollapse();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Toggle collapsed state
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CExpandablePanel::ToggleCollapse()
|
||
|
{
|
||
|
m_bExpanded = !m_bExpanded;
|
||
|
// Allow for quick bounce-back if they click while we're already animating
|
||
|
float flEndTime = RemapValClamped( GetPercentAnimated(), 0.f, 1.f, 0.f, m_flResizeTime );
|
||
|
m_flAnimEndTime = Plat_FloatTime() + flEndTime;
|
||
|
|
||
|
OnToggleCollapse( m_bExpanded );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Toggle collapsed state
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CExpandablePanel::OnCommand( const char *command )
|
||
|
{
|
||
|
if ( FStrEq( "toggle_collapse", command ) )
|
||
|
{
|
||
|
ToggleCollapse();
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
BaseClass::OnCommand( command );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Do collapsing interpolation
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CExpandablePanel::OnThink()
|
||
|
{
|
||
|
BaseClass::OnThink();
|
||
|
|
||
|
float flTimeProgress = Gain( GetPercentAnimated(), 0.8f );
|
||
|
|
||
|
const int& nStartHeight = m_bExpanded ? m_nCollapsedHeight : m_nExpandedHeight;
|
||
|
const int& nEndHeight = m_bExpanded ? m_nExpandedHeight : m_nCollapsedHeight;
|
||
|
int nCurrentHeight = RemapValClamped( flTimeProgress, 0.f, 1.f, nStartHeight, nEndHeight );
|
||
|
|
||
|
if ( nCurrentHeight != GetTall() )
|
||
|
{
|
||
|
SetTall( nCurrentHeight );
|
||
|
Panel* pParent = GetParent();
|
||
|
if ( pParent )
|
||
|
{
|
||
|
pParent->InvalidateLayout();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Where we're at in our interpolation
|
||
|
//-----------------------------------------------------------------------------
|
||
|
float CExpandablePanel::GetPercentAnimated() const
|
||
|
{
|
||
|
return RemapValClamped( Plat_FloatTime() - ( m_flAnimEndTime - m_flResizeTime ), 0.f, m_flResizeTime, 0.f, 1.f );
|
||
|
}
|
||
|
|