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.
411 lines
12 KiB
411 lines
12 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//===========================================================================// |
|
|
|
#include "LoadCommentaryDialog.h" |
|
#include "EngineInterface.h" |
|
#include "IGameUIFuncs.h" |
|
|
|
#include "vgui/ISystem.h" |
|
#include "vgui/IVGui.h" |
|
#include "tier1/KeyValues.h" |
|
#include "tier1/convar.h" |
|
#include "filesystem.h" |
|
|
|
#include "vgui_controls/PanelListPanel.h" |
|
#include "vgui_controls/Label.h" |
|
#include "vgui_controls/ImagePanel.h" |
|
#include "vgui_controls/Button.h" |
|
#include "vgui_controls/Button.h" |
|
#include "vgui_controls/PanelListPanel.h" |
|
#include "vgui_controls/QueryBox.h" |
|
|
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
|
|
#include "BasePanel.h" |
|
|
|
#include "GameUI_Interface.h" |
|
|
|
#include "MouseMessageForwardingPanel.h" |
|
#include "TGAImagePanel.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
using namespace vgui; |
|
|
|
|
|
void OpenLoadCommentaryDialog( void ) |
|
{ |
|
DHANDLE<CLoadCommentaryDialog> hCommentaryDialog; |
|
if ( !hCommentaryDialog.Get() ) |
|
{ |
|
hCommentaryDialog = new CLoadCommentaryDialog( BasePanel() ); |
|
} |
|
|
|
GameUI().ActivateGameUI(); |
|
hCommentaryDialog->Activate(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CC_LoadCommentary_Test( void ) |
|
{ |
|
OpenLoadCommentaryDialog(); |
|
} |
|
static ConCommand commentary_testfirstrun("loadcommentary", CC_LoadCommentary_Test, 0 ); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Describes the layout of a commentary map list item |
|
//----------------------------------------------------------------------------- |
|
class CCommentaryItemPanel : public vgui::EditablePanel |
|
{ |
|
DECLARE_CLASS_SIMPLE( CCommentaryItemPanel, vgui::EditablePanel ); |
|
public: |
|
CCommentaryItemPanel( PanelListPanel *parent, const char *name, int iListItemID ) : BaseClass( parent, name ) |
|
{ |
|
m_iListItemID = iListItemID; |
|
m_pParent = parent; |
|
m_pCommentaryScreenshot = new CTGAImagePanel( this, "CommentaryMapScreenshot" ); |
|
m_pCommentaryScreenshotBackground = new ImagePanel( this, "CommentaryScreenshotBackground" ); |
|
|
|
// map name |
|
m_pMapNameLabel = new Label( this, "MapName", "" ); |
|
|
|
// description |
|
m_pDescriptionLabel = new Label( this, "Description", "" ); |
|
|
|
CMouseMessageForwardingPanel *panel = new CMouseMessageForwardingPanel(this, NULL); |
|
panel->SetZPos(2); |
|
|
|
SetSize( 200, 140 ); |
|
|
|
LoadControlSettings( "resource/CommentaryItem.res" ); |
|
|
|
m_FillColor = m_pCommentaryScreenshotBackground->GetFillColor(); |
|
} |
|
|
|
void SetCommentaryInfo( CommentaryItem_t &item ) |
|
{ |
|
// set the bitmap to display |
|
char tga[_MAX_PATH]; |
|
Q_strncpy( tga, item.szMapFileName, sizeof(tga) ); |
|
char *ext = strstr( tga, ".txt" ); |
|
if ( ext ) |
|
{ |
|
strcpy( ext, ".tga" ); |
|
} |
|
m_pCommentaryScreenshot->SetTGA( tga ); |
|
|
|
// set the title text |
|
m_pMapNameLabel->SetText( item.szPrintName ); |
|
m_pDescriptionLabel->SetText( item.szDescription ); |
|
} |
|
|
|
MESSAGE_FUNC_INT( OnPanelSelected, "PanelSelected", state ) |
|
{ |
|
if ( state ) |
|
{ |
|
// set the text color to be orange, and the pic border to be orange |
|
m_pCommentaryScreenshotBackground->SetFillColor( m_SelectedColor ); |
|
m_pMapNameLabel->SetFgColor( m_SelectedColor ); |
|
m_pDescriptionLabel->SetFgColor( m_SelectedColor ); |
|
} |
|
else |
|
{ |
|
m_pCommentaryScreenshotBackground->SetFillColor( m_FillColor ); |
|
m_pMapNameLabel->SetFgColor( m_TextColor ); |
|
m_pDescriptionLabel->SetFgColor( m_TextColor ); |
|
} |
|
|
|
PostMessage( m_pParent->GetVParent(), new KeyValues("PanelSelected") ); |
|
} |
|
|
|
virtual void OnMousePressed( vgui::MouseCode code ) |
|
{ |
|
m_pParent->SetSelectedPanel( this ); |
|
} |
|
|
|
virtual void ApplySchemeSettings( IScheme *pScheme ) |
|
{ |
|
m_TextColor = pScheme->GetColor( "NewGame.TextColor", Color(255, 255, 255, 255) ); |
|
m_SelectedColor = pScheme->GetColor( "NewGame.SelectionColor", Color(255, 255, 255, 255) ); |
|
|
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
} |
|
|
|
virtual void OnMouseDoublePressed( vgui::MouseCode code ) |
|
{ |
|
// call the panel |
|
OnMousePressed( code ); |
|
PostMessage( m_pParent->GetParent(), new KeyValues("Command", "command", "loadcommentary") ); |
|
} |
|
|
|
int GetListItemID() |
|
{ |
|
return m_iListItemID; |
|
} |
|
|
|
private: |
|
vgui::PanelListPanel *m_pParent; |
|
|
|
vgui::Label *m_pMapNameLabel; |
|
vgui::Label *m_pDescriptionLabel; |
|
CTGAImagePanel *m_pCommentaryScreenshot; |
|
ImagePanel *m_pCommentaryScreenshotBackground; |
|
|
|
Color m_TextColor, m_FillColor, m_SelectedColor; |
|
|
|
int m_iListItemID; |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose:Constructor |
|
//----------------------------------------------------------------------------- |
|
CLoadCommentaryDialog::CLoadCommentaryDialog(vgui::Panel *parent) : BaseClass(parent, "LoadCommentaryDialog") |
|
{ |
|
SetDeleteSelfOnClose(true); |
|
SetBounds(0, 0, 512, 384); |
|
SetMinimumSize( 256, 300 ); |
|
SetSizeable( true ); |
|
|
|
SetTitle("#GameUI_LoadCommentary", true); |
|
|
|
vgui::Button *cancel = new vgui::Button( this, "Cancel", "#GameUI_Cancel" ); |
|
cancel->SetCommand( "Close" ); |
|
|
|
CreateCommentaryItemList(); |
|
|
|
new vgui::Button( this, "loadcommentary", "" ); |
|
SetControlEnabled( "loadcommentary", false ); |
|
|
|
LoadControlSettings("resource/LoadCommentaryDialog.res"); |
|
|
|
// Look for commentary .txt files in the map directory |
|
ScanCommentaryFiles(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CLoadCommentaryDialog::OnCommand( const char *command ) |
|
{ |
|
if ( !Q_stricmp( command, "loadcommentary" ) ) |
|
{ |
|
int itemIndex = GetSelectedItemIndex(); |
|
if ( m_CommentaryItems.IsValidIndex(itemIndex) ) |
|
{ |
|
const char *mapName = m_CommentaryItems[itemIndex].szMapName; |
|
if ( mapName && mapName[ 0 ] ) |
|
{ |
|
// Load the game, return to top and switch to engine |
|
char sz[ 256 ]; |
|
Q_snprintf(sz, sizeof( sz ), "progress_enable\ncommentary 1\nmap %s\n", mapName ); |
|
|
|
// Close this dialog |
|
OnClose(); |
|
|
|
engine->ClientCmd_Unrestricted( sz ); |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
BaseClass::OnCommand( command ); |
|
} |
|
} |
|
|
|
void CLoadCommentaryDialog::OnKeyCodePressed( vgui::KeyCode code ) |
|
{ |
|
if ( code == KEY_XBUTTON_A || code == STEAMCONTROLLER_A ) |
|
{ |
|
OnCommand( "loadcommentary" ); |
|
return; |
|
} |
|
else if ( code == KEY_XBUTTON_B ) |
|
{ |
|
OnCommand( "Close" ); |
|
return; |
|
} |
|
|
|
BaseClass::OnKeyCodePressed(code); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Creates the load game display list |
|
//----------------------------------------------------------------------------- |
|
void CLoadCommentaryDialog::CreateCommentaryItemList() |
|
{ |
|
m_pGameList = new vgui::PanelListPanel( this, "listpanel_commentary" ); |
|
m_pGameList->SetFirstColumnWidth( 0 ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: returns the save file name of the selected item |
|
//----------------------------------------------------------------------------- |
|
int CLoadCommentaryDialog::GetSelectedItemIndex() |
|
{ |
|
CCommentaryItemPanel *panel = dynamic_cast<CCommentaryItemPanel *>(m_pGameList->GetSelectedPanel()); |
|
if ( panel ) |
|
{ |
|
// find the panel in the list |
|
for ( int i = 0; i < m_CommentaryItems.Count(); i++ ) |
|
{ |
|
if ( i == panel->GetListItemID() ) |
|
{ |
|
return i; |
|
} |
|
} |
|
} |
|
return m_CommentaryItems.InvalidIndex(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: builds save game list from directory |
|
//----------------------------------------------------------------------------- |
|
void CLoadCommentaryDialog::ScanCommentaryFiles() |
|
{ |
|
// populate list box with all saved games on record: |
|
char szDirectory[_MAX_PATH]; |
|
Q_snprintf( szDirectory, sizeof( szDirectory ), "maps/*commentary.txt" ); |
|
|
|
// clear the current list |
|
m_pGameList->DeleteAllItems(); |
|
m_CommentaryItems.RemoveAll(); |
|
|
|
// iterate the files |
|
FileFindHandle_t handle; |
|
const char *pFileName = g_pFullFileSystem->FindFirst( szDirectory, &handle ); |
|
while (pFileName) |
|
{ |
|
char szFileName[_MAX_PATH]; |
|
Q_snprintf(szFileName, sizeof( szFileName ), "maps/%s", pFileName); |
|
|
|
// Only load save games from the current mod's save dir |
|
if( !g_pFullFileSystem->FileExists( szFileName, "MOD" ) ) |
|
{ |
|
pFileName = g_pFullFileSystem->FindNext( handle ); |
|
continue; |
|
} |
|
|
|
ParseCommentaryFile( szFileName, pFileName ); |
|
|
|
pFileName = g_pFullFileSystem->FindNext( handle ); |
|
} |
|
|
|
g_pFullFileSystem->FindClose( handle ); |
|
|
|
// sort the save list |
|
qsort( m_CommentaryItems.Base(), m_CommentaryItems.Count(), sizeof(CommentaryItem_t), &SaveGameSortFunc ); |
|
|
|
// add to the list |
|
for ( int saveIndex = 0; saveIndex < m_CommentaryItems.Count() && saveIndex < MAX_LISTED_COMMENTARY_ITEMS; saveIndex++ ) |
|
{ |
|
// add the item to the panel |
|
AddCommentaryItemToList( saveIndex ); |
|
} |
|
|
|
// display a message if there are no save games |
|
if ( !m_CommentaryItems.Count() ) |
|
{ |
|
vgui::Label *pNoCommentaryItemsLabel = SETUP_PANEL(new Label(m_pGameList, "NoCommentaryItemsLabel", "#GameUI_NoCommentaryItemsToDisplay")); |
|
pNoCommentaryItemsLabel->SetTextColorState(vgui::Label::CS_DULL); |
|
m_pGameList->AddItem( NULL, pNoCommentaryItemsLabel ); |
|
} |
|
|
|
SetControlEnabled( "loadcommentary", false ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Adds an item to the list |
|
//----------------------------------------------------------------------------- |
|
void CLoadCommentaryDialog::AddCommentaryItemToList( int itemIndex ) |
|
{ |
|
// create the new panel and add to the list |
|
CCommentaryItemPanel *commentaryItemPanel = new CCommentaryItemPanel( m_pGameList, "CommentaryItemPanel", itemIndex ); |
|
commentaryItemPanel->SetCommentaryInfo( m_CommentaryItems[itemIndex] ); |
|
m_pGameList->AddItem( NULL, commentaryItemPanel ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Parses the save game info out of the .sav file header |
|
//----------------------------------------------------------------------------- |
|
void CLoadCommentaryDialog::ParseCommentaryFile( char const *pszFileName, char const *pszShortName ) |
|
{ |
|
if ( !pszFileName || !pszShortName ) |
|
return; |
|
|
|
// load the file as keyvalues |
|
KeyValues *pData = new KeyValues( "commentary_data" ); |
|
|
|
if ( false == pData->LoadFromFile( g_pFullFileSystem, pszFileName, "MOD" ) ) |
|
{ |
|
pData->deleteThis(); |
|
return; |
|
} |
|
|
|
// walk the platform menu loading all the interfaces |
|
KeyValues *menuKeys = pData->FindKey("trackinfo", false); |
|
if ( menuKeys ) |
|
{ |
|
for (KeyValues *track = menuKeys->GetFirstSubKey(); track != NULL; track = track->GetNextKey()) |
|
{ |
|
//Msg( "track found: %s %s\n", track->GetString("map", "?"), track->GetString( "description", "asdf" ) ); |
|
|
|
CommentaryItem_t item; |
|
Q_strncpy( item.szMapFileName, pszFileName, sizeof(item.szMapFileName) ); |
|
Q_strncpy( item.szMapName, track->GetString( "map", "" ), sizeof(item.szMapName) ); |
|
Q_strncpy( item.szPrintName, track->GetString( "printname", "" ), sizeof(item.szPrintName) ); |
|
Q_strncpy( item.szDescription, track->GetString( "description", "" ), sizeof(item.szDescription) ); |
|
|
|
//item.iChannel = track->GetInt( "channel" ); |
|
|
|
m_CommentaryItems.AddToTail( item ); |
|
} |
|
} |
|
else |
|
{ |
|
CommentaryItem_t item; |
|
Q_strncpy( item.szMapFileName, pszFileName, sizeof(item.szMapFileName) ); |
|
|
|
char mapname[_MAX_PATH]; |
|
Q_strncpy( mapname, pszFileName, sizeof(item.szMapName) ); |
|
char *ext = strstr( mapname, "_commentary" ); |
|
if ( !ext ) |
|
return; |
|
|
|
*ext = '\0'; |
|
Q_FileBase( mapname, item.szMapName, sizeof(item.szMapName) ); |
|
|
|
Q_strncpy( item.szPrintName, "No trackinfo found.", sizeof(item.szPrintName) ); |
|
Q_strncpy( item.szDescription, "No trackinfo found.", sizeof(item.szDescription) ); |
|
m_CommentaryItems.AddToTail( item ); |
|
} |
|
|
|
return; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: timestamp sort function for savegames |
|
//----------------------------------------------------------------------------- |
|
int CLoadCommentaryDialog::SaveGameSortFunc( const void *lhs, const void *rhs ) |
|
{ |
|
// Sort by map name |
|
const CommentaryItem_t *s1 = (const CommentaryItem_t *)lhs; |
|
const CommentaryItem_t *s2 = (const CommentaryItem_t *)rhs; |
|
|
|
return Q_stricmp( s1->szPrintName, s2->szPrintName ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: One item has been selected |
|
//----------------------------------------------------------------------------- |
|
void CLoadCommentaryDialog::OnPanelSelected() |
|
{ |
|
SetControlEnabled( "loadcommentary", true ); |
|
}
|
|
|