302 lines
8.9 KiB
C++
302 lines
8.9 KiB
C++
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
//=============================================================================
|
||
|
|
||
|
#if defined(WIN32) && !defined( _X360 )
|
||
|
#include <windows.h>
|
||
|
#endif
|
||
|
#undef PropertySheet
|
||
|
|
||
|
#include "matsys_controls/gamefiletreeview.h"
|
||
|
#include "filesystem.h"
|
||
|
#include "tier1/KeyValues.h"
|
||
|
#include "vgui/ISurface.h"
|
||
|
#include "vgui/Cursor.h"
|
||
|
|
||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||
|
#include "tier0/memdbgon.h"
|
||
|
|
||
|
|
||
|
using namespace vgui;
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// list of all tree view icons
|
||
|
//-----------------------------------------------------------------------------
|
||
|
enum
|
||
|
{
|
||
|
IMAGE_FOLDER = 1,
|
||
|
IMAGE_OPENFOLDER,
|
||
|
IMAGE_FILE,
|
||
|
};
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Constructor
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CGameFileTreeView::CGameFileTreeView( Panel *parent, const char *name, const char *pRootFolderName, const char *pRootDir, const char *pExtension ) : BaseClass(parent, name), m_Images( false )
|
||
|
{
|
||
|
m_RootDir = pRootDir;
|
||
|
|
||
|
m_Ext = pExtension;
|
||
|
m_bUseExt = ( pExtension != NULL );
|
||
|
|
||
|
m_RootFolderName = pRootFolderName;
|
||
|
|
||
|
// build our list of images
|
||
|
m_Images.AddImage( scheme()->GetImage( "resource/icon_folder", false ) );
|
||
|
m_Images.AddImage( scheme()->GetImage( "resource/icon_folder_selected", false ) );
|
||
|
m_Images.AddImage( scheme()->GetImage( "resource/icon_file", false ) );
|
||
|
SetImageList( &m_Images, false );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Refreshes the active file list
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CGameFileTreeView::RefreshFileList()
|
||
|
{
|
||
|
RemoveAll();
|
||
|
SetFgColor(Color(216, 222, 211, 255));
|
||
|
|
||
|
// add the base node
|
||
|
KeyValues *pkv = new KeyValues( "root" );
|
||
|
pkv->SetString( "text", m_RootFolderName );
|
||
|
pkv->SetInt( "root", 1 );
|
||
|
pkv->SetInt( "expand", 1 );
|
||
|
int iRoot = AddItem( pkv, GetRootItemIndex() );
|
||
|
pkv->deleteThis();
|
||
|
ExpandItem( iRoot, true );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Selects the root folder
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CGameFileTreeView::SelectRoot()
|
||
|
{
|
||
|
AddSelectedItem( GetRootItemIndex(), true );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Gets the number of root directories
|
||
|
//-----------------------------------------------------------------------------
|
||
|
int CGameFileTreeView::GetRootDirectoryCount()
|
||
|
{
|
||
|
return GetNumChildren( GetRootItemIndex() );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Gets the ith root directory
|
||
|
//-----------------------------------------------------------------------------
|
||
|
const char *CGameFileTreeView::GetRootDirectory( int nIndex )
|
||
|
{
|
||
|
int nItemIndex = GetChild( GetRootItemIndex(), nIndex );
|
||
|
KeyValues *kv = GetItemData( nItemIndex );
|
||
|
if ( !kv )
|
||
|
return NULL;
|
||
|
return kv->GetString( "path", NULL );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Populate the root node (necessary since tree view can't have multiple roots)
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CGameFileTreeView::PopulateRootNode( int itemIndex )
|
||
|
{
|
||
|
AddDirectoriesOfNode( itemIndex, m_RootDir );
|
||
|
|
||
|
if ( m_bUseExt )
|
||
|
{
|
||
|
AddFilesOfNode( itemIndex, m_RootDir, m_Ext );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Populate the root node with directories
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CGameFileTreeView::DoesDirectoryHaveSubdirectories( const char *pFilePath )
|
||
|
{
|
||
|
char pSearchString[MAX_PATH];
|
||
|
Q_snprintf( pSearchString, MAX_PATH, "%s\\*", pFilePath );
|
||
|
|
||
|
// get the list of files
|
||
|
FileFindHandle_t findHandle;
|
||
|
|
||
|
// generate children
|
||
|
// add all the items
|
||
|
const char *pszFileName = g_pFullFileSystem->FindFirstEx( pSearchString, "GAME", &findHandle );
|
||
|
while ( pszFileName )
|
||
|
{
|
||
|
bool bIsDirectory = g_pFullFileSystem->FindIsDirectory( findHandle );
|
||
|
if ( bIsDirectory && Q_strnicmp( pszFileName, ".", 2 ) && Q_strnicmp( pszFileName, "..", 3 ) )
|
||
|
return true;
|
||
|
|
||
|
pszFileName = g_pFullFileSystem->FindNext( findHandle );
|
||
|
}
|
||
|
|
||
|
g_pFullFileSystem->FindClose( findHandle );
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Populate the root node with directories
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CGameFileTreeView::AddDirectoriesOfNode( int itemIndex, const char *pFilePath )
|
||
|
{
|
||
|
char pSearchString[MAX_PATH];
|
||
|
Q_snprintf( pSearchString, MAX_PATH, "%s\\*", pFilePath );
|
||
|
|
||
|
// get the list of files
|
||
|
FileFindHandle_t findHandle;
|
||
|
|
||
|
// generate children
|
||
|
// add all the items
|
||
|
const char *pszFileName = g_pFullFileSystem->FindFirstEx( pSearchString, "GAME", &findHandle );
|
||
|
while ( pszFileName )
|
||
|
{
|
||
|
bool bIsDirectory = g_pFullFileSystem->FindIsDirectory( findHandle );
|
||
|
if ( bIsDirectory && Q_strnicmp( pszFileName, ".", 2 ) && Q_strnicmp( pszFileName, "..", 3 ) )
|
||
|
{
|
||
|
KeyValues *kv = new KeyValues( "node", "text", pszFileName );
|
||
|
|
||
|
char pFullPath[MAX_PATH];
|
||
|
Q_snprintf( pFullPath, sizeof(pFullPath), "%s/%s", pFilePath, pszFileName );
|
||
|
Q_FixSlashes( pFullPath );
|
||
|
Q_strlower( pFullPath );
|
||
|
bool bHasSubdirectories = DoesDirectoryHaveSubdirectories( pFullPath );
|
||
|
kv->SetString( "path", pFullPath );
|
||
|
|
||
|
kv->SetInt( "expand", bHasSubdirectories );
|
||
|
kv->SetInt( "dir", 1 );
|
||
|
kv->SetInt( "image", IMAGE_FOLDER );
|
||
|
|
||
|
int itemID = AddItem(kv, itemIndex);
|
||
|
kv->deleteThis();
|
||
|
|
||
|
// mark directories in orange
|
||
|
SetItemColorForDirectories( itemID );
|
||
|
}
|
||
|
|
||
|
pszFileName = g_pFullFileSystem->FindNext( findHandle );
|
||
|
}
|
||
|
|
||
|
g_pFullFileSystem->FindClose( findHandle );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Populate the root node with files
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CGameFileTreeView::AddFilesOfNode( int itemIndex, const char *pFilePath, const char *pExt )
|
||
|
{
|
||
|
char pSearchString[MAX_PATH];
|
||
|
Q_snprintf( pSearchString, MAX_PATH, "%s\\*.%s", pFilePath, pExt );
|
||
|
|
||
|
// get the list of files
|
||
|
FileFindHandle_t findHandle;
|
||
|
|
||
|
// generate children
|
||
|
// add all the items
|
||
|
const char *pszFileName = g_pFullFileSystem->FindFirst( pSearchString, &findHandle );
|
||
|
while ( pszFileName )
|
||
|
{
|
||
|
if ( !g_pFullFileSystem->FindIsDirectory( findHandle ) )
|
||
|
{
|
||
|
KeyValues *kv = new KeyValues( "node", "text", pszFileName );
|
||
|
|
||
|
char pFullPath[MAX_PATH];
|
||
|
Q_snprintf( pFullPath, MAX_PATH, "%s\\%s", pFilePath, pszFileName );
|
||
|
kv->SetString( "path", pFullPath );
|
||
|
kv->SetInt( "image", IMAGE_FILE );
|
||
|
|
||
|
AddItem(kv, itemIndex);
|
||
|
kv->deleteThis();
|
||
|
}
|
||
|
|
||
|
pszFileName = g_pFullFileSystem->FindNext( findHandle );
|
||
|
}
|
||
|
|
||
|
g_pFullFileSystem->FindClose( findHandle );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// override to incremental request and show p4 directories
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CGameFileTreeView::GenerateChildrenOfNode(int itemIndex)
|
||
|
{
|
||
|
KeyValues *pkv = GetItemData(itemIndex);
|
||
|
if ( pkv->GetInt("root") )
|
||
|
{
|
||
|
PopulateRootNode( itemIndex );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (!pkv->GetInt("dir"))
|
||
|
return;
|
||
|
|
||
|
const char *pFilePath = pkv->GetString("path", "");
|
||
|
if (!pFilePath[0])
|
||
|
return;
|
||
|
|
||
|
surface()->SetCursor(dc_waitarrow);
|
||
|
|
||
|
AddDirectoriesOfNode( itemIndex, pFilePath );
|
||
|
|
||
|
if ( m_bUseExt )
|
||
|
{
|
||
|
AddFilesOfNode( itemIndex, pFilePath, m_Ext );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// setup a context menu whenever a directory is clicked on
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CGameFileTreeView::GenerateContextMenu( int itemIndex, int x, int y )
|
||
|
{
|
||
|
return;
|
||
|
|
||
|
/*
|
||
|
KeyValues *pkv = GetItemData(itemIndex);
|
||
|
const char *pFilePath = pkv->GetString("path", "");
|
||
|
if (!pFilePath[0])
|
||
|
return;
|
||
|
|
||
|
Menu *pContext = new Menu(this, "FileContext");
|
||
|
pContext->AddMenuItem("Cloak folder", new KeyValues("CloakFolder", "item", itemIndex), GetParent(), NULL);
|
||
|
|
||
|
// show the context menu
|
||
|
pContext->SetPos(x, y);
|
||
|
pContext->SetVisible(true);
|
||
|
*/
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Sets an item to be colored as if its a menu
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CGameFileTreeView::SetItemColorForDirectories( int itemID )
|
||
|
{
|
||
|
// mark directories in orange
|
||
|
SetItemFgColor( itemID, Color(224, 192, 0, 255) );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// setup a smaller font
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CGameFileTreeView::ApplySchemeSettings(IScheme *pScheme)
|
||
|
{
|
||
|
BaseClass::ApplySchemeSettings(pScheme);
|
||
|
SetFont( pScheme->GetFont("DefaultSmall") );
|
||
|
}
|
||
|
|