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.
882 lines
18 KiB
882 lines
18 KiB
5 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
//=============================================================================//
|
||
|
|
||
|
#include "cbase.h"
|
||
|
#include <windows.h>
|
||
|
#include "resource.h"
|
||
|
#include "vcdbrowser.h"
|
||
|
#include "SoundEmitterSystem/isoundemittersystembase.h"
|
||
|
#include "filesystem.h"
|
||
|
#include "tabwindow.h"
|
||
|
#include "inputproperties.h"
|
||
|
#include "choreowidgetdrawhelper.h"
|
||
|
#include "UtlBuffer.h"
|
||
|
#include "ChoreoEvent.h"
|
||
|
#include "ChoreoView.h"
|
||
|
|
||
|
CVCDBrowser *g_pVCDBrowser = NULL;
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
// Controls
|
||
|
IDC_VB_LISTVIEW = 101,
|
||
|
IDC_VB_FILETREE,
|
||
|
// Messages
|
||
|
IDC_VB_OPENVCD = 1000,
|
||
|
};
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
COL_VCD = 0,
|
||
|
};
|
||
|
|
||
|
class CVCDList : public mxListView
|
||
|
{
|
||
|
public:
|
||
|
CVCDList( mxWindow *parent, int id = 0 )
|
||
|
: mxListView( parent, 0, 0, 0, 0, id )
|
||
|
{
|
||
|
// Add column headers
|
||
|
insertTextColumn( COL_VCD, 700, "VCD" );
|
||
|
}
|
||
|
};
|
||
|
|
||
|
class CUtlSymbolTree : public mxTreeView
|
||
|
{
|
||
|
public:
|
||
|
CUtlSymbolTree( mxWindow *parent, int id = 0 ) : mxTreeView( parent, 0, 0, 0, 0, id ),
|
||
|
m_Paths( 0, 0, FileTreeLessFunc )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void Clear()
|
||
|
{
|
||
|
removeAll();
|
||
|
m_Paths.RemoveAll();
|
||
|
}
|
||
|
|
||
|
void FindOrAddSubdirectory( char const *subdir )
|
||
|
{
|
||
|
FileTreePath fp;
|
||
|
Q_strcpy( fp.path, subdir );
|
||
|
|
||
|
if ( m_Paths.Find( fp ) != m_Paths.InvalidIndex() )
|
||
|
return;
|
||
|
|
||
|
m_Paths.Insert( fp );
|
||
|
}
|
||
|
|
||
|
mxTreeViewItem *FindOrAddChildItem( mxTreeViewItem *parent, char const *child )
|
||
|
{
|
||
|
mxTreeViewItem *p = getFirstChild( parent );
|
||
|
if ( !p )
|
||
|
{
|
||
|
return add( parent, child );
|
||
|
}
|
||
|
|
||
|
while ( p )
|
||
|
{
|
||
|
if ( !Q_stricmp( getLabel( p ), child ) )
|
||
|
return p;
|
||
|
|
||
|
p = getNextChild( p );
|
||
|
}
|
||
|
|
||
|
return add( parent, child );
|
||
|
}
|
||
|
|
||
|
void _PopulateTree( int pathId, char const *path )
|
||
|
{
|
||
|
char sz[ 512 ];
|
||
|
Q_strcpy( sz, path );
|
||
|
char *p = sz;
|
||
|
|
||
|
// Start at root
|
||
|
mxTreeViewItem *cur = NULL;
|
||
|
|
||
|
// Tokenize path
|
||
|
while ( p && p[0] )
|
||
|
{
|
||
|
char *slash = Q_strstr( p, "/" );
|
||
|
if ( !slash )
|
||
|
{
|
||
|
slash = Q_strstr( p, "\\" );
|
||
|
}
|
||
|
|
||
|
char *check = p;
|
||
|
|
||
|
if ( slash )
|
||
|
{
|
||
|
*slash = 0;
|
||
|
|
||
|
// see if a child of current already exists with this name
|
||
|
p = slash + 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
p = NULL;
|
||
|
}
|
||
|
|
||
|
Assert( check );
|
||
|
|
||
|
cur = FindOrAddChildItem( cur, check );
|
||
|
}
|
||
|
|
||
|
setUserData( cur, (void *)pathId );
|
||
|
}
|
||
|
|
||
|
char const *GetSelectedPath( void )
|
||
|
{
|
||
|
mxTreeViewItem *tvi = getSelectedItem();
|
||
|
unsigned int id = (unsigned int)getUserData( tvi );
|
||
|
|
||
|
if ( id < 0 || id >= m_Paths.Count() )
|
||
|
{
|
||
|
Assert( 0 );
|
||
|
return "";
|
||
|
}
|
||
|
return m_Paths[ id ].path;
|
||
|
}
|
||
|
|
||
|
void PopulateTree()
|
||
|
{
|
||
|
int i;
|
||
|
for ( i = m_Paths.FirstInorder(); i != m_Paths.InvalidIndex(); i = m_Paths.NextInorder( i ) )
|
||
|
{
|
||
|
_PopulateTree( i, m_Paths[ i ].path );
|
||
|
}
|
||
|
|
||
|
mxTreeViewItem *p = getFirstChild( NULL );
|
||
|
setOpen( p, true );
|
||
|
}
|
||
|
|
||
|
struct FileTreePath
|
||
|
{
|
||
|
char path[ MAX_PATH ];
|
||
|
};
|
||
|
|
||
|
static bool FileTreeLessFunc( const FileTreePath &lhs, const FileTreePath &rhs )
|
||
|
{
|
||
|
return Q_stricmp( lhs.path, rhs.path ) < 0;
|
||
|
}
|
||
|
|
||
|
CUtlRBTree< FileTreePath, int > m_Paths;
|
||
|
};
|
||
|
|
||
|
#pragma optimize( "", off )
|
||
|
class CVCDOptionsWindow : public mxWindow
|
||
|
{
|
||
|
typedef mxWindow BaseClass;
|
||
|
public:
|
||
|
enum
|
||
|
{
|
||
|
IDC_OPENFILE = 1000,
|
||
|
IDC_SEARCH,
|
||
|
IDC_CANCELSEARCH,
|
||
|
};
|
||
|
|
||
|
CVCDOptionsWindow( CVCDBrowser *browser ) : BaseClass( browser, 0, 0, 0, 0 ), m_pBrowser( browser )
|
||
|
{
|
||
|
FacePoser_AddWindowStyle( this, WS_CLIPSIBLINGS | WS_CLIPCHILDREN );
|
||
|
|
||
|
m_szSearchString[0]=0;
|
||
|
|
||
|
m_pOpen = new mxButton( this, 0, 0, 0, 0, "Open", IDC_OPENFILE );
|
||
|
|
||
|
m_pSearch = new mxLineEdit( this, 0, 0, 0, 0, "", IDC_SEARCH );
|
||
|
|
||
|
m_pCancelSearch = new mxButton( this, 0, 0, 0, 0, "Cancel", IDC_CANCELSEARCH );
|
||
|
}
|
||
|
|
||
|
bool PaintBackground( void )
|
||
|
{
|
||
|
redraw();
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
virtual void redraw()
|
||
|
{
|
||
|
CChoreoWidgetDrawHelper drawHelper( this, GetSysColor( COLOR_BTNFACE ) );
|
||
|
}
|
||
|
virtual int handleEvent( mxEvent *event )
|
||
|
{
|
||
|
int iret = 0;
|
||
|
switch ( event->event )
|
||
|
{
|
||
|
default:
|
||
|
break;
|
||
|
case mxEvent::Size:
|
||
|
{
|
||
|
iret = 1;
|
||
|
|
||
|
int split = 120;
|
||
|
|
||
|
int x = 1;
|
||
|
|
||
|
m_pOpen->setBounds( x, 1, split, h2() - 2 );
|
||
|
|
||
|
|
||
|
x += split + 10;
|
||
|
|
||
|
m_pCancelSearch->setBounds( x, 1, split, h2() - 2 );
|
||
|
|
||
|
x += split + 10;
|
||
|
|
||
|
m_pSearch->setBounds( x, 0, split * 3, h2() - 1 );
|
||
|
|
||
|
x += split * 3 + 10;
|
||
|
}
|
||
|
break;
|
||
|
case mxEvent::KeyDown:
|
||
|
switch ( event->action )
|
||
|
{
|
||
|
default:
|
||
|
break;
|
||
|
case IDC_SEARCH:
|
||
|
{
|
||
|
if ( event->event == mxEvent::KeyDown )
|
||
|
{
|
||
|
OnSearch();
|
||
|
}
|
||
|
iret = 1;
|
||
|
};
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
case mxEvent::Action:
|
||
|
{
|
||
|
switch ( event->action )
|
||
|
{
|
||
|
case IDC_SEARCH:
|
||
|
iret = 1;
|
||
|
break;
|
||
|
case IDC_OPENFILE:
|
||
|
{
|
||
|
iret = 1;
|
||
|
m_pBrowser->OnOpen();
|
||
|
}
|
||
|
break;
|
||
|
case IDC_CANCELSEARCH:
|
||
|
{
|
||
|
iret = 1;
|
||
|
OnCancelSearch();
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return iret;
|
||
|
}
|
||
|
|
||
|
char const *GetSearchString()
|
||
|
{
|
||
|
return m_szSearchString;
|
||
|
}
|
||
|
|
||
|
void OnSearch()
|
||
|
{
|
||
|
m_pSearch->getText( m_szSearchString, sizeof( m_szSearchString ) );
|
||
|
|
||
|
m_pBrowser->OnSearch();
|
||
|
}
|
||
|
|
||
|
void OnCancelSearch()
|
||
|
{
|
||
|
m_szSearchString[ 0 ] = 0;
|
||
|
m_pSearch->clear();
|
||
|
|
||
|
m_pBrowser->OnCancelSearch();
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
|
||
|
mxButton *m_pOpen;
|
||
|
mxLineEdit *m_pSearch;
|
||
|
mxButton *m_pCancelSearch;
|
||
|
|
||
|
CVCDBrowser *m_pBrowser;
|
||
|
|
||
|
char m_szSearchString[ 256 ];
|
||
|
};
|
||
|
|
||
|
#pragma optimize( "", on )
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
// Input : *parent -
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CVCDBrowser::CVCDBrowser( mxWindow *parent )
|
||
|
: IFacePoserToolWindow( "VCDBrowser", "VCDs" ), mxWindow( parent, 0, 0, 0, 0 )
|
||
|
{
|
||
|
SetAutoProcess( false );
|
||
|
|
||
|
m_bTextSearch = false;
|
||
|
m_nPrevProcessed = -1;
|
||
|
|
||
|
m_pListView = new CVCDList( this, IDC_VB_LISTVIEW );
|
||
|
m_pOptions = new CVCDOptionsWindow( this );
|
||
|
m_pFileTree = new CUtlSymbolTree( this, IDC_VB_FILETREE );
|
||
|
|
||
|
//HIMAGELIST list = CreateImageList();
|
||
|
|
||
|
// Associate the image list with the tree-view control.
|
||
|
//m_pListView->setImageList( (void *)list );
|
||
|
|
||
|
LoadAllSounds();
|
||
|
|
||
|
PopulateTree( NULL );
|
||
|
}
|
||
|
|
||
|
#define CX_ICON 16
|
||
|
#define CY_ICON 16
|
||
|
|
||
|
HIMAGELIST CVCDBrowser::CreateImageList()
|
||
|
{
|
||
|
HIMAGELIST list;
|
||
|
|
||
|
list = ImageList_Create( CX_ICON, CY_ICON,
|
||
|
FALSE, VCD_NUM_IMAGES, 0 );
|
||
|
|
||
|
// Load the icon resources, and add the icons to the image list.
|
||
|
HICON hicon;
|
||
|
int slot;
|
||
|
#if defined( DBGFLAG_ASSERT )
|
||
|
int c = 0;
|
||
|
#endif
|
||
|
|
||
|
hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_VCD));
|
||
|
slot = ImageList_AddIcon(list, hicon);
|
||
|
Assert( slot == c++ );
|
||
|
DeleteObject( hicon );
|
||
|
|
||
|
return list;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CVCDBrowser::OnDelete()
|
||
|
{
|
||
|
RemoveAllSounds();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
// Input : *event -
|
||
|
// Output : int
|
||
|
//-----------------------------------------------------------------------------
|
||
|
int CVCDBrowser::handleEvent( mxEvent *event )
|
||
|
{
|
||
|
int iret = 0;
|
||
|
|
||
|
if ( HandleToolEvent( event ) )
|
||
|
{
|
||
|
return iret;
|
||
|
}
|
||
|
|
||
|
switch ( event->event )
|
||
|
{
|
||
|
default:
|
||
|
break;
|
||
|
case mxEvent::Action:
|
||
|
{
|
||
|
iret = 1;
|
||
|
switch ( event->action )
|
||
|
{
|
||
|
default:
|
||
|
{
|
||
|
iret = 0;
|
||
|
}
|
||
|
break;
|
||
|
case IDC_VB_LISTVIEW:
|
||
|
{
|
||
|
SetActiveTool( this );
|
||
|
|
||
|
bool rightmouse = ( event->flags == mxEvent::RightClicked ) ? true : false;
|
||
|
bool doubleclicked = ( event->flags == mxEvent::DoubleClicked ) ? true : false;
|
||
|
|
||
|
if ( rightmouse )
|
||
|
{
|
||
|
ShowContextMenu();
|
||
|
}
|
||
|
else if ( doubleclicked )
|
||
|
{
|
||
|
if ( m_pListView->getNumSelected() == 1 )
|
||
|
{
|
||
|
int index = m_pListView->getNextSelectedItem( -1 );
|
||
|
if ( index >= 0 )
|
||
|
{
|
||
|
FileNameHandle_t vcd = (FileNameHandle_t)m_pListView->getUserData( index, 0 );
|
||
|
OpenVCD( vcd );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case IDC_VB_FILETREE:
|
||
|
{
|
||
|
SetActiveTool( this );
|
||
|
|
||
|
PopulateTree( m_pFileTree->GetSelectedPath() );
|
||
|
}
|
||
|
break;
|
||
|
case IDC_VB_OPENVCD:
|
||
|
{
|
||
|
OnOpen();
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case mxEvent::Size:
|
||
|
{
|
||
|
int optionsh = 20;
|
||
|
|
||
|
m_pOptions->setBounds( 0, 0, w2(), optionsh );
|
||
|
|
||
|
int filetreewidth = 175;
|
||
|
|
||
|
m_pFileTree->setBounds( 0, optionsh, filetreewidth, h2() - optionsh );
|
||
|
m_pListView->setBounds( filetreewidth, optionsh, w2() - filetreewidth, h2() - optionsh );
|
||
|
|
||
|
iret = 1;
|
||
|
}
|
||
|
break;
|
||
|
case mxEvent::Close:
|
||
|
{
|
||
|
iret = 1;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return iret;
|
||
|
}
|
||
|
|
||
|
bool CVCDBrowser::CNameLessFunc::Less( const FileNameHandle_t &name1, const FileNameHandle_t &name2, void *pContext )
|
||
|
{
|
||
|
if ( name1 < name2 )
|
||
|
return true;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
void CVCDBrowser::OpenVCD( const FileNameHandle_t& handle )
|
||
|
{
|
||
|
char fn[ 512 ];
|
||
|
if ( filesystem->String( handle, fn, sizeof( fn ) ) )
|
||
|
{
|
||
|
char pFullPath[MAX_PATH];
|
||
|
const char *pFileName = filesystem->RelativePathToFullPath( fn, "GAME", pFullPath, sizeof(pFullPath) );
|
||
|
if ( !pFileName )
|
||
|
{
|
||
|
pFileName = fn;
|
||
|
}
|
||
|
g_pChoreoView->LoadSceneFromFile( pFileName );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#define SCENES_PREFIX_LEN 0
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Finds all .vcd files in a particular directory
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CVCDBrowser::LoadVCDsFilesInDirectory( CUtlSortVector< FileNameHandle_t, CNameLessFunc >& soundlist, char const* pDirectoryName, int nDirectoryNameLen )
|
||
|
{
|
||
|
char *pWildCard;
|
||
|
pWildCard = ( char * )stackalloc( nDirectoryNameLen + 7 );
|
||
|
Q_snprintf( pWildCard, nDirectoryNameLen + 7, "%s/*.vcd", pDirectoryName );
|
||
|
|
||
|
if ( !filesystem )
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
FileFindHandle_t findHandle;
|
||
|
const char *pFileName = filesystem->FindFirst( pWildCard, &findHandle );
|
||
|
while( pFileName )
|
||
|
{
|
||
|
if( !filesystem->FindIsDirectory( findHandle ) )
|
||
|
{
|
||
|
// Strip off the 'sound/' part of the name.
|
||
|
char *pFileNameWithPath;
|
||
|
int nAllocSize = nDirectoryNameLen + Q_strlen(pFileName) + 2;
|
||
|
pFileNameWithPath = (char *)stackalloc( nAllocSize );
|
||
|
Q_snprintf( pFileNameWithPath, nAllocSize, "%s/%s", &pDirectoryName[ SCENES_PREFIX_LEN ], pFileName );
|
||
|
Q_strnlwr( pFileNameWithPath, nAllocSize );
|
||
|
|
||
|
FileNameHandle_t vcd;
|
||
|
vcd = filesystem->FindOrAddFileName( pFileNameWithPath );
|
||
|
soundlist.InsertNoSort( vcd );
|
||
|
}
|
||
|
pFileName = filesystem->FindNext( findHandle );
|
||
|
}
|
||
|
|
||
|
m_pFileTree->FindOrAddSubdirectory( &pDirectoryName[ SCENES_PREFIX_LEN ] );
|
||
|
|
||
|
filesystem->FindClose( findHandle );
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool CVCDBrowser::InitDirectoryRecursive( CUtlSortVector< FileNameHandle_t, CNameLessFunc >& soundlist, char const* pDirectoryName )
|
||
|
{
|
||
|
// Compute directory name length
|
||
|
int nDirectoryNameLen = Q_strlen( pDirectoryName );
|
||
|
|
||
|
if (!LoadVCDsFilesInDirectory( soundlist, pDirectoryName, nDirectoryNameLen ) )
|
||
|
return false;
|
||
|
|
||
|
char *pWildCard = ( char * )stackalloc( nDirectoryNameLen + 4 );
|
||
|
strcpy(pWildCard, pDirectoryName);
|
||
|
strcat(pWildCard, "/*.");
|
||
|
int nPathStrLen = nDirectoryNameLen + 1;
|
||
|
|
||
|
FileFindHandle_t findHandle;
|
||
|
const char *pFileName = filesystem->FindFirst( pWildCard, &findHandle );
|
||
|
while( pFileName )
|
||
|
{
|
||
|
if ((pFileName[0] != '.') || (pFileName[1] != '.' && pFileName[1] != 0))
|
||
|
{
|
||
|
if( filesystem->FindIsDirectory( findHandle ) )
|
||
|
{
|
||
|
int fileNameStrLen = Q_strlen( pFileName );
|
||
|
char *pFileNameWithPath = ( char * )stackalloc( nPathStrLen + fileNameStrLen + 1 );
|
||
|
memcpy( pFileNameWithPath, pWildCard, nPathStrLen );
|
||
|
pFileNameWithPath[nPathStrLen] = '\0';
|
||
|
strcat( pFileNameWithPath, pFileName );
|
||
|
|
||
|
if (!InitDirectoryRecursive( soundlist, pFileNameWithPath ))
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
pFileName = filesystem->FindNext( findHandle );
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void CVCDBrowser::LoadAllSounds()
|
||
|
{
|
||
|
RemoveAllSounds();
|
||
|
|
||
|
Con_Printf( "Building list of all .vcds in sound/ folder\n" );
|
||
|
|
||
|
InitDirectoryRecursive( m_AllVCDs, "scenes" );
|
||
|
m_AllVCDs.RedoSort();
|
||
|
|
||
|
m_pFileTree->PopulateTree();
|
||
|
}
|
||
|
|
||
|
void CVCDBrowser::RemoveAllSounds()
|
||
|
{
|
||
|
m_AllVCDs.Purge();
|
||
|
m_Scripts.RemoveAll();
|
||
|
m_CurrentSelection.RemoveAll();
|
||
|
|
||
|
m_pFileTree->Clear();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CVCDBrowser::PopulateTree( char const *subdirectory )
|
||
|
{
|
||
|
char subdir[ 512 ];
|
||
|
subdir[ 0 ] = 0;
|
||
|
|
||
|
int i;
|
||
|
|
||
|
CUtlSortVector< FileNameHandle_t, CNameLessFunc > sorted( 0, 0 );
|
||
|
|
||
|
char const *texttofind = NULL;
|
||
|
|
||
|
if ( m_bTextSearch )
|
||
|
{
|
||
|
subdirectory = NULL;
|
||
|
texttofind = GetSearchString();
|
||
|
}
|
||
|
|
||
|
int len = 0;
|
||
|
if ( subdirectory )
|
||
|
{
|
||
|
len = Q_strlen( subdirectory );
|
||
|
Q_strncpy( subdir, subdirectory, sizeof( subdir ) );
|
||
|
Q_strlower( subdir );
|
||
|
Q_FixSlashes( subdir );
|
||
|
}
|
||
|
|
||
|
int c = m_AllVCDs.Count();
|
||
|
for ( i = 0; i < c; i++ )
|
||
|
{
|
||
|
const FileNameHandle_t &vcd = m_AllVCDs[ i ];
|
||
|
char name[ 512 ];
|
||
|
if ( !filesystem->String( vcd, name, sizeof( name ) ) )
|
||
|
continue;
|
||
|
|
||
|
if ( subdirectory )
|
||
|
{
|
||
|
if ( Q_strnicmp( subdir, name, len ) )
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if ( m_bTextSearch && texttofind )
|
||
|
{
|
||
|
if ( !Q_stristr( name, texttofind ) )
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
sorted.InsertNoSort( vcd );
|
||
|
}
|
||
|
|
||
|
sorted.RedoSort();
|
||
|
|
||
|
char prevSelectedName[ 512 ];
|
||
|
prevSelectedName[ 0 ] = 0;
|
||
|
if ( m_pListView->getNumSelected() == 1 )
|
||
|
{
|
||
|
int selectedItem = m_pListView->getNextSelectedItem( 0 );
|
||
|
if ( selectedItem >= 0 )
|
||
|
{
|
||
|
// Grab name of previously selected item
|
||
|
Q_strcpy( prevSelectedName, m_pListView->getLabel( selectedItem, 0 ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Repopulate tree
|
||
|
m_pListView->removeAll();
|
||
|
|
||
|
int loadcount = 0;
|
||
|
|
||
|
m_pListView->setDrawingEnabled( false );
|
||
|
|
||
|
int selectedSlot = -1;
|
||
|
|
||
|
for ( i = 0; i < sorted.Count(); ++i )
|
||
|
{
|
||
|
const FileNameHandle_t &vcd = sorted[ i ];
|
||
|
char name[ 512 ];
|
||
|
if ( !filesystem->String( vcd, name, sizeof( name ) ) )
|
||
|
continue;
|
||
|
|
||
|
int slot = m_pListView->add( name );
|
||
|
m_pListView->setUserData( slot, COL_VCD, (void *)vcd );
|
||
|
|
||
|
if ( !Q_stricmp( prevSelectedName, name ) )
|
||
|
{
|
||
|
selectedSlot = slot;
|
||
|
}
|
||
|
++loadcount;
|
||
|
}
|
||
|
|
||
|
m_pListView->setDrawingEnabled( true );
|
||
|
|
||
|
if ( selectedSlot != -1 )
|
||
|
{
|
||
|
m_pListView->setSelected( selectedSlot, true );
|
||
|
m_pListView->scrollToItem( selectedSlot );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CVCDBrowser::RepopulateTree()
|
||
|
{
|
||
|
PopulateTree( m_pFileTree->GetSelectedPath() );
|
||
|
}
|
||
|
|
||
|
void CVCDBrowser::BuildSelectionList( CUtlVector< FileNameHandle_t >& selected )
|
||
|
{
|
||
|
selected.RemoveAll();
|
||
|
|
||
|
int idx = -1;
|
||
|
do
|
||
|
{
|
||
|
idx = m_pListView->getNextSelectedItem( idx );
|
||
|
if ( idx != -1 )
|
||
|
{
|
||
|
FileNameHandle_t vcd = (FileNameHandle_t)m_pListView->getUserData( idx, 0 );
|
||
|
selected.AddToTail( vcd );
|
||
|
}
|
||
|
} while ( idx != -1 );
|
||
|
|
||
|
}
|
||
|
|
||
|
void CVCDBrowser::ShowContextMenu( void )
|
||
|
{
|
||
|
SetActiveTool( this );
|
||
|
|
||
|
BuildSelectionList( m_CurrentSelection );
|
||
|
if ( m_CurrentSelection.Count() <= 0 )
|
||
|
return;
|
||
|
|
||
|
POINT pt;
|
||
|
GetCursorPos( &pt );
|
||
|
ScreenToClient( (HWND)getHandle(), &pt );
|
||
|
|
||
|
mxPopupMenu *pop = new mxPopupMenu();
|
||
|
|
||
|
if ( m_CurrentSelection.Count() == 1 && m_CurrentSelection[ 0 ] )
|
||
|
{
|
||
|
char sz[ 512 ];
|
||
|
char name[ 512 ];
|
||
|
if ( filesystem->String( m_CurrentSelection[ 0 ], name, sizeof( name ) ) )
|
||
|
{
|
||
|
Q_snprintf( sz, sizeof( sz ), "&Open '%s'", name );
|
||
|
pop->add ( sz, IDC_VB_OPENVCD );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pop->popup( this, pt.x, pt.y );
|
||
|
}
|
||
|
|
||
|
void CVCDBrowser::OnOpen()
|
||
|
{
|
||
|
SetActiveTool( this );
|
||
|
|
||
|
BuildSelectionList( m_CurrentSelection );
|
||
|
if ( m_CurrentSelection.Count() == 1 )
|
||
|
{
|
||
|
FileNameHandle_t& vcd = m_CurrentSelection[ 0 ];
|
||
|
OpenVCD( vcd );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void SplitFileName( char const *in, char *path, int maxpath, char *filename, int maxfilename )
|
||
|
{
|
||
|
char drive[_MAX_DRIVE];
|
||
|
char dir[_MAX_DIR];
|
||
|
char fname[_MAX_FNAME];
|
||
|
char ext[_MAX_EXT];
|
||
|
|
||
|
_splitpath( in, drive, dir, fname, ext );
|
||
|
|
||
|
if ( dir[0] )
|
||
|
{
|
||
|
Q_snprintf( path, maxpath, "\\%s", dir );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
path[0] = 0;
|
||
|
}
|
||
|
Q_snprintf( filename, maxfilename, "%s%s", fname, ext );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
// Input : *se -
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CVCDBrowser::JumpToItem( const FileNameHandle_t& vcd )
|
||
|
{
|
||
|
SetActiveTool( this );
|
||
|
|
||
|
char path[ 256 ];
|
||
|
char filename[ 256 ];
|
||
|
|
||
|
char vcdfile[ 512 ];
|
||
|
if ( !filesystem->String( vcd, vcdfile, sizeof( vcdfile ) ) )
|
||
|
return;
|
||
|
|
||
|
SplitFileName( vcdfile, path, sizeof( path ), filename, sizeof( filename ) );
|
||
|
|
||
|
char *usepath = path + Q_strlen( "/scenes/" );
|
||
|
PopulateTree( usepath );
|
||
|
|
||
|
int idx = 0;
|
||
|
int c = m_pListView->getItemCount();
|
||
|
for ( ; idx < c; idx++ )
|
||
|
{
|
||
|
FileNameHandle_t item = (FileNameHandle_t)m_pListView->getUserData( idx, 0 );
|
||
|
if ( item == vcd )
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( idx < c )
|
||
|
{
|
||
|
m_pListView->scrollToItem( idx );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int CVCDBrowser::GetVCDCount() const
|
||
|
{
|
||
|
return m_AllVCDs.Count();
|
||
|
}
|
||
|
|
||
|
FileNameHandle_t CVCDBrowser::GetVCD( int index )
|
||
|
{
|
||
|
if ( index < 0 || index >= (int)m_AllVCDs.Count() )
|
||
|
return NULL;
|
||
|
|
||
|
return m_AllVCDs[ index ];
|
||
|
}
|
||
|
|
||
|
|
||
|
void CVCDBrowser::OnSearch()
|
||
|
{
|
||
|
if ( !GetSearchString()[ 0 ] )
|
||
|
{
|
||
|
OnCancelSearch();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
SetActiveTool( this );
|
||
|
m_bTextSearch = true;
|
||
|
PopulateTree( GetSearchString());
|
||
|
}
|
||
|
|
||
|
void CVCDBrowser::OnCancelSearch()
|
||
|
{
|
||
|
SetActiveTool( this );
|
||
|
|
||
|
m_bTextSearch = false;
|
||
|
|
||
|
PopulateTree( m_pFileTree->GetSelectedPath() );
|
||
|
}
|
||
|
|
||
|
char const *CVCDBrowser::GetSearchString()
|
||
|
{
|
||
|
return m_pOptions->GetSearchString();
|
||
|
}
|
||
|
|
||
|
void CVCDBrowser::SetCurrent( char const *filename )
|
||
|
{
|
||
|
// Get sound name and look up .vcd from it
|
||
|
char const *p = filename;
|
||
|
if ( p &&
|
||
|
( !Q_strnicmp( p, "sound/", 6 ) || !Q_strnicmp( p, "sound\\", 6 ) ) )
|
||
|
{
|
||
|
p += 6;
|
||
|
}
|
||
|
|
||
|
char fn[ 512 ];
|
||
|
Q_strncpy( fn, p, sizeof( fn ) );
|
||
|
Q_FixSlashes( fn );
|
||
|
|
||
|
int i;
|
||
|
int c = m_pListView->getItemCount();
|
||
|
|
||
|
for ( i = 0; i < c; ++i )
|
||
|
{
|
||
|
FileNameHandle_t vcd = (FileNameHandle_t)( m_pListView->getUserData( i, COL_VCD ) );
|
||
|
|
||
|
char fixed[ 512 ];
|
||
|
if ( !filesystem->String( vcd, fixed, sizeof( fixed ) ) )
|
||
|
continue;
|
||
|
|
||
|
Q_FixSlashes( fixed );
|
||
|
|
||
|
if ( !Q_stricmp( fixed, fn ) )
|
||
|
{
|
||
|
m_pListView->scrollToItem( i );
|
||
|
m_pListView->setSelected( i, true );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_pListView->setSelected( i, false );
|
||
|
}
|
||
|
}
|
||
|
}
|