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.
964 lines
20 KiB
964 lines
20 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
|
|
#include "cbase.h" |
|
#include "workspacebrowser.h" |
|
#include "workspace.h" |
|
#include "project.h" |
|
#include <windows.h> |
|
#include "resource.h" |
|
#include "project.h" |
|
#include "vcdfile.h" |
|
#include "soundentry.h" |
|
#include "scene.h" |
|
|
|
#include "workspacemanager.h" |
|
#include "soundbrowser.h" |
|
#include "SoundEmitterSystem/isoundemittersystembase.h" |
|
#include "iscenemanagersound.h" |
|
#include "snd_wave_source.h" |
|
#include "cmdlib.h" |
|
#include "tabwindow.h" |
|
#include "soundproperties.h" |
|
#include "soundproperties_multiple.h" |
|
#include "wavebrowser.h" |
|
#include "wavefile.h" |
|
#include "inputproperties.h" |
|
#include "drawhelper.h" |
|
#include "utlbuffer.h" |
|
|
|
#define ENTRY_ALLSOUNDS "AllSounds" |
|
#define ENTRY_ALL_INDEX 0 |
|
#define ENTRY_SEARCHRESULTS "Search results" |
|
#define ENTRY_SEARCH_INDEX 1 |
|
|
|
enum |
|
{ |
|
// Controls |
|
IDC_SB_LISTVIEW = 101, |
|
IDC_SB_FILTERTAB, |
|
|
|
// Messages |
|
IDC_SB_PLAY = 1000, |
|
IDC_SB_SOUNDPROPERTIES, |
|
IDC_SB_SHOWINWAVEBROWSER, |
|
IDC_SB_ADDSOUND, |
|
IDC_SB_REMOVESOUND, |
|
IDC_SB_GETSENTENCE, |
|
}; |
|
|
|
enum |
|
{ |
|
COL_SOUND = 0, |
|
COL_COUNT, |
|
COL_WAV, |
|
COL_SENTENCE, |
|
COL_CHANNEL, |
|
COL_VOLUME, |
|
COL_SOUNDLEVEL, |
|
COL_PITCH, |
|
COL_SCRIPT, |
|
COL_CC, |
|
}; |
|
|
|
class CSoundList : public mxListView |
|
{ |
|
public: |
|
CSoundList( mxWindow *parent, int id = 0 ) |
|
: mxListView( parent, 0, 0, 0, 0, id ) |
|
{ |
|
// SendMessage ( (HWND)getHandle(), WM_SETFONT, (WPARAM) (HFONT) GetStockObject (ANSI_FIXED_FONT), MAKELPARAM (TRUE, 0)); |
|
|
|
//HWND wnd = (HWND)getHandle(); |
|
//DWORD style = GetWindowLong( wnd, GWL_STYLE ); |
|
//style |= LVS_SORTASCENDING; |
|
//SetWindowLong( wnd, GWL_STYLE, style ); |
|
|
|
//SceneManager_AddWindowStyle( this, LVS_SORTASCENDING ); |
|
|
|
// Add column headers |
|
insertTextColumn( COL_SOUND, 200, "Sound" ); |
|
insertTextColumn( COL_COUNT, 20, "#" ); |
|
insertTextColumn( COL_WAV, 220, "WAV Filename" ); |
|
insertTextColumn( COL_SENTENCE, 300, "Sentence Text" ); |
|
insertTextColumn( COL_CHANNEL, 100, "Channel" ); |
|
insertTextColumn( COL_VOLUME, 100, "Volume" ); |
|
insertTextColumn( COL_SOUNDLEVEL, 120, "Soundlevel" ); |
|
insertTextColumn( COL_PITCH, 100, "Pitch" ); |
|
insertTextColumn( COL_SCRIPT, 150, "Script File" ); |
|
insertTextColumn( COL_CC, 300, "CC Text" ); |
|
} |
|
}; |
|
|
|
class CSoundFilterTab : public CTabWindow |
|
{ |
|
public: |
|
typedef CTabWindow BaseClass; |
|
|
|
CSoundFilterTab( mxWindow *parent, int x, int y, int w, int h, int id = 0, int style = 0 ) : |
|
CTabWindow( parent, x, y, w, h, id, style ) |
|
{ |
|
SetInverted( true ); |
|
SetRowHeight( 20 ); |
|
} |
|
|
|
virtual void ShowRightClickMenu( int mx, int my ) |
|
{ |
|
// Nothing |
|
} |
|
|
|
void Init( CUtlSymbolTable& table, CUtlVector< CUtlSymbol >& scripts ) |
|
{ |
|
add( ENTRY_ALLSOUNDS ); |
|
add( ENTRY_SEARCHRESULTS ); |
|
|
|
int c = scripts.Count(); |
|
for ( int i = 0; i < c; i++ ) |
|
{ |
|
CUtlSymbol& sym = scripts[ i ]; |
|
add( table.String( sym ) ); |
|
} |
|
select( 0 ); |
|
} |
|
|
|
void UpdatePrefixes() |
|
{ |
|
int c = getItemCount(); |
|
// Skip All and search results |
|
for ( int i = 2; i < c; i++ ) |
|
{ |
|
setPrefix( i, "" ); |
|
|
|
char const *script = getLabel( i ); |
|
if ( !script ) |
|
continue; |
|
|
|
int scriptindex = g_pSoundEmitterSystem->FindSoundScript( va( "scripts/%s.txt", script ) ); |
|
if ( scriptindex < 0 ) |
|
continue; |
|
|
|
if ( g_pSoundEmitterSystem->IsSoundScriptDirty( scriptindex ) ) |
|
{ |
|
setPrefix( i, "* " ); |
|
} |
|
} |
|
|
|
RecomputeLayout( w2() ); |
|
redraw(); |
|
} |
|
}; |
|
|
|
|
|
class COptionsWindow : public mxWindow |
|
{ |
|
typedef mxWindow BaseClass; |
|
public: |
|
enum |
|
{ |
|
IDC_VOICE_ONLY = 1000, |
|
IDC_PLAY_SOUND, |
|
IDC_STOP_SOUNDS, |
|
IDC_SEARCH, |
|
}; |
|
|
|
COptionsWindow( CSoundBrowser *browser ) : BaseClass( browser, 0, 0, 0, 0 ), m_pBrowser( browser ) |
|
{ |
|
SceneManager_AddWindowStyle( this, WS_CLIPSIBLINGS | WS_CLIPCHILDREN ); |
|
|
|
m_szSearchString[0]=0; |
|
|
|
m_pChanVoiceOnly = new mxCheckBox( this, 0, 0, 0, 0, "CHAN_VOICE only", IDC_VOICE_ONLY ); |
|
m_pChanVoiceOnly->setChecked( true ); |
|
|
|
m_pPlay = new mxButton( this, 0, 0, 0, 0, "Play", IDC_PLAY_SOUND ); |
|
|
|
m_pStopSounds = new mxButton( this, 0, 0, 0, 0, "Stop Sounds", IDC_STOP_SOUNDS ); |
|
|
|
m_pSearch = new mxButton( this, 0, 0, 0, 0, "Search...", IDC_SEARCH ); |
|
|
|
m_pSearchString = new mxLabel( this, 0, 0, 0, 0, "" ); |
|
} |
|
|
|
bool PaintBackground( void ) |
|
{ |
|
redraw(); |
|
return false; |
|
} |
|
|
|
|
|
virtual void redraw() |
|
{ |
|
CDrawHelper 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_pPlay->setBounds( x, 1, split, h2() - 2 ); |
|
|
|
x += split + 10; |
|
|
|
m_pStopSounds->setBounds( x, 1, split, h2()-2 ); |
|
|
|
x += split + 10; |
|
|
|
m_pChanVoiceOnly->setBounds( x, 1, split, h2() - 2 ); |
|
|
|
x += split + 10; |
|
|
|
m_pSearch->setBounds( x, 1, split, h2() - 2 ); |
|
|
|
x += split + 10; |
|
|
|
m_pSearchString->setBounds( x, 2, split * 2, h2() - 4 ); |
|
|
|
x += split * 2 + 10; |
|
|
|
} |
|
break; |
|
case mxEvent::Action: |
|
{ |
|
switch ( event->action ) |
|
{ |
|
case IDC_STOP_SOUNDS: |
|
{ |
|
iret = 1; |
|
sound->StopAll(); |
|
} |
|
break; |
|
case IDC_PLAY_SOUND: |
|
{ |
|
iret = 1; |
|
m_pBrowser->OnPlay(); |
|
} |
|
break; |
|
case IDC_VOICE_ONLY: |
|
{ |
|
iret = 1; |
|
m_pBrowser->RepopulateTree(); |
|
}; |
|
break; |
|
case IDC_SEARCH: |
|
{ |
|
iret = 1; |
|
OnSearch(); |
|
}; |
|
break; |
|
default: |
|
break; |
|
} |
|
} |
|
break; |
|
} |
|
|
|
return iret; |
|
} |
|
|
|
bool IsChanVoiceOnly() const |
|
{ |
|
return m_pChanVoiceOnly->isChecked(); |
|
} |
|
|
|
char const *GetSearchString() |
|
{ |
|
return m_szSearchString; |
|
} |
|
|
|
void OnSearch() |
|
{ |
|
CInputParams params; |
|
memset( ¶ms, 0, sizeof( params ) ); |
|
Q_snprintf( params.m_szDialogTitle, sizeof( params.m_szDialogTitle ), "Search" ); |
|
Q_strcpy( params.m_szPrompt, "Find:" ); |
|
Q_strcpy( params.m_szInputText, m_szSearchString ); |
|
|
|
if ( !InputProperties( ¶ms ) ) |
|
return; |
|
|
|
Q_strcpy( m_szSearchString, params.m_szInputText ); |
|
|
|
m_pSearchString->setLabel( va( "Search: '%s'", GetSearchString() ) ); |
|
|
|
m_pBrowser->OnSearch(); |
|
} |
|
|
|
private: |
|
|
|
mxCheckBox *m_pChanVoiceOnly; |
|
mxButton *m_pStopSounds; |
|
mxButton *m_pPlay; |
|
mxButton *m_pSearch; |
|
mxLabel *m_pSearchString; |
|
|
|
CSoundBrowser *m_pBrowser; |
|
|
|
char m_szSearchString[ 256 ]; |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *parent - |
|
//----------------------------------------------------------------------------- |
|
CSoundBrowser::CSoundBrowser( mxWindow *parent, CWorkspaceManager *manager, int id ) : |
|
BaseClass( parent, 0, 0, 0, 0, "Sound Browser", id ) |
|
{ |
|
m_pManager = manager; |
|
|
|
SceneManager_MakeToolWindow( this, false ); |
|
|
|
m_pListView = new CSoundList( this, IDC_SB_LISTVIEW ); |
|
m_pFilter = new CSoundFilterTab( this, 0, 0, 0, 0, IDC_SB_FILTERTAB ); |
|
m_pOptions = new COptionsWindow( this ); |
|
|
|
HIMAGELIST list = GetWorkspaceManager()->CreateImageList(); |
|
|
|
// Associate the image list with the tree-view control. |
|
m_pListView->setImageList( (void *)list ); |
|
|
|
LoadAllSounds(); |
|
|
|
m_pFilter->select( 0 ); |
|
RepopulateTree(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CSoundBrowser::OnDelete() |
|
{ |
|
RemoveAllSounds(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *event - |
|
// Output : int |
|
//----------------------------------------------------------------------------- |
|
int CSoundBrowser::handleEvent( mxEvent *event ) |
|
{ |
|
int iret = 0; |
|
switch ( event->event ) |
|
{ |
|
default: |
|
break; |
|
case mxEvent::Action: |
|
{ |
|
iret = 1; |
|
switch ( event->action ) |
|
{ |
|
default: |
|
{ |
|
iret = 0; |
|
} |
|
break; |
|
case IDC_SB_FILTERTAB: |
|
{ |
|
RepopulateTree(); |
|
} |
|
break; |
|
case IDC_SB_LISTVIEW: |
|
{ |
|
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 ) |
|
{ |
|
CSoundEntry *se = (CSoundEntry *)m_pListView->getUserData( index, 0 ); |
|
if ( se ) |
|
{ |
|
se->Play(); |
|
|
|
CWaveBrowser *wb = GetWorkspaceManager()->GetWaveBrowser(); |
|
if ( wb && se->GetWaveCount() > 0 ) |
|
{ |
|
CWaveFile *firstwave = se->GetWave( 0 ); |
|
Assert( firstwave ); |
|
if ( firstwave ) |
|
{ |
|
wb->JumpToItem( firstwave ); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
break; |
|
case IDC_SB_PLAY: |
|
{ |
|
OnPlay(); |
|
} |
|
break; |
|
case IDC_SB_GETSENTENCE: |
|
{ |
|
OnGetSentence(); |
|
} |
|
break; |
|
case IDC_SB_SOUNDPROPERTIES: |
|
{ |
|
OnSoundProperties(); |
|
} |
|
break; |
|
case IDC_SB_SHOWINWAVEBROWSER: |
|
{ |
|
OnShowInWaveBrowser(); |
|
} |
|
break; |
|
case IDC_SB_ADDSOUND: |
|
{ |
|
OnAddSound(); |
|
} |
|
break; |
|
case IDC_SB_REMOVESOUND: |
|
{ |
|
OnRemoveSound(); |
|
} |
|
break; |
|
} |
|
} |
|
break; |
|
case mxEvent::Size: |
|
{ |
|
int optionsh = 20; |
|
int filterh = m_pFilter->GetBestHeight( w2() ); |
|
|
|
m_pOptions->setBounds( 0, 0, w2(), optionsh ); |
|
m_pListView->setBounds( 0, optionsh, w2(), h2() - filterh - optionsh ); |
|
m_pFilter->setBounds( 0, h2() - filterh, w2(), filterh ); |
|
|
|
GetWorkspaceManager()->SetWorkspaceDirty(); |
|
|
|
iret = 1; |
|
} |
|
break; |
|
case mxEvent::Close: |
|
{ |
|
iret = 1; |
|
} |
|
break; |
|
} |
|
|
|
return iret; |
|
} |
|
|
|
static bool NameLessFunc( CSoundEntry *const& name1, CSoundEntry *const& name2 ) |
|
{ |
|
if ( Q_stricmp( name1->GetName(), name2->GetName() ) < 0 ) |
|
return true; |
|
return false; |
|
} |
|
|
|
void CSoundBrowser::LoadAllSounds() |
|
{ |
|
RemoveAllSounds(); |
|
|
|
// int c = g_pSoundEmitterSystem->GetSoundCount(); |
|
int added = 0; |
|
|
|
int i; |
|
for ( i = g_pSoundEmitterSystem->First(); i != g_pSoundEmitterSystem->InvalidIndex(); i = g_pSoundEmitterSystem->Next( i ) ) |
|
{ |
|
char const *name = g_pSoundEmitterSystem->GetSoundName( i ); |
|
CSoundEntry *se = new CSoundEntry( NULL, name ); |
|
m_AllSounds.AddToTail( se ); |
|
|
|
char filebase [ 512 ]; |
|
Q_FileBase( g_pSoundEmitterSystem->GetSourceFileForSound( i ), filebase, sizeof( filebase ) ); |
|
|
|
// Add script file symbol |
|
CUtlSymbol script_sym = m_ScriptTable.AddString( filebase ); |
|
|
|
if ( m_Scripts.Find( script_sym ) == m_Scripts.InvalidIndex() ) |
|
{ |
|
m_Scripts.AddToTail( script_sym ); |
|
} |
|
|
|
++added; |
|
|
|
if ( !( added % 500 ) ) |
|
{ |
|
// Con_Printf( "CSoundBrowser: loaded %i sounds\n", added ); |
|
} |
|
} |
|
|
|
m_pFilter->Init( m_ScriptTable, m_Scripts ); |
|
} |
|
|
|
void CSoundBrowser::RemoveAllSounds() |
|
{ |
|
int c = m_AllSounds.Count(); |
|
for ( int i = 0; i < c; i++ ) |
|
{ |
|
CSoundEntry *se = m_AllSounds[ i ]; |
|
delete se; |
|
} |
|
|
|
m_AllSounds.RemoveAll(); |
|
m_Scripts.RemoveAll(); |
|
m_CurrentSelection.RemoveAll(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CSoundBrowser::PopulateTree( bool voiceonly, char const *scriptonly ) |
|
{ |
|
int i; |
|
|
|
CUtlRBTree< CSoundEntry *, int > m_Sorted( 0, 0, NameLessFunc ); |
|
|
|
bool textsearch = false; |
|
char const *texttofind = NULL; |
|
|
|
if ( scriptonly ) |
|
{ |
|
if ( !Q_stricmp( scriptonly, ENTRY_ALLSOUNDS ) ) |
|
{ |
|
scriptonly = NULL; |
|
} |
|
else if ( !Q_stricmp( scriptonly, ENTRY_SEARCHRESULTS ) ) |
|
{ |
|
scriptonly = NULL; |
|
textsearch = true; |
|
texttofind = GetSearchString(); |
|
} |
|
} |
|
|
|
int c = m_AllSounds.Count(); |
|
for ( i = 0; i < c; i++ ) |
|
{ |
|
CSoundEntry *se = m_AllSounds[ i ]; |
|
char const *name = se->GetName(); |
|
|
|
CSoundParametersInternal *params = se->GetSoundParameters(); |
|
if ( !params ) |
|
continue; |
|
|
|
if ( voiceonly && params->GetChannel() != CHAN_VOICE ) |
|
continue; |
|
|
|
if ( scriptonly ) |
|
{ |
|
if ( Q_stricmp( scriptonly, se->GetScriptFile() ) ) |
|
continue; |
|
} |
|
|
|
if ( textsearch && texttofind ) |
|
{ |
|
bool keep = false; |
|
if ( Q_stristr( name, texttofind ) ) |
|
{ |
|
keep = true; |
|
} |
|
else |
|
{ |
|
int waveCount = se->GetWaveCount(); |
|
for ( int wave = 0; wave < waveCount; wave++ ) |
|
{ |
|
CWaveFile *w = se->GetWave( wave ); |
|
if ( !w ) |
|
continue; |
|
|
|
char const *wavename = w->GetFileName(); |
|
if ( !wavename ) |
|
{ |
|
Assert( 0 ); |
|
continue; |
|
} |
|
|
|
if ( !Q_stristr( wavename, texttofind ) ) |
|
{ |
|
continue; |
|
} |
|
|
|
keep = true; |
|
break; |
|
} |
|
} |
|
|
|
|
|
if ( !keep ) |
|
{ |
|
continue; |
|
} |
|
} |
|
|
|
m_Sorted.Insert( se ); |
|
} |
|
|
|
|
|
// Repopulate tree |
|
m_pListView->removeAll(); |
|
|
|
int loadcount = 0; |
|
|
|
m_pListView->setDrawingEnabled( false ); |
|
|
|
for ( i = m_Sorted.FirstInorder(); i != m_Sorted.InvalidIndex(); i = m_Sorted.NextInorder( i ) ) |
|
{ |
|
CSoundEntry *se = m_Sorted[ i ]; |
|
char const *name = se->GetName(); |
|
CSoundParametersInternal *params = se->GetSoundParameters(); |
|
if ( !params ) |
|
continue; |
|
|
|
int slot = m_pListView->add( name ); |
|
|
|
m_pListView->setUserData( slot, COL_SOUND, (void *)se ); |
|
|
|
m_pListView->setImage( slot, COL_SOUND, se->GetIconIndex() ); |
|
|
|
int waveCount = params->NumSoundNames(); |
|
|
|
if ( waveCount >= 1 ) |
|
{ |
|
m_pListView->setLabel( slot, COL_COUNT, waveCount > 1 ? va( "%i", waveCount ) : "" ); |
|
m_pListView->setLabel( slot, COL_WAV, g_pSoundEmitterSystem->GetWaveName( params->GetSoundNames()[ 0 ].symbol ) ); |
|
} |
|
|
|
m_pListView->setLabel( slot, COL_SENTENCE, se->GetSentenceText( 0 ) ); |
|
|
|
m_pListView->setLabel( slot, COL_CHANNEL, params->ChannelToString() ); |
|
m_pListView->setLabel( slot, COL_VOLUME, params->VolumeToString() ); |
|
m_pListView->setLabel( slot, COL_SOUNDLEVEL, params->SoundLevelToString() ); |
|
m_pListView->setLabel( slot, COL_PITCH, params->PitchToString() ); |
|
|
|
wchar_t buf[ 1024 ]; |
|
se->GetCCText( buf, 1024 ); |
|
m_pListView->setLabel( slot, COL_CC, buf ); |
|
|
|
char filebase [ 512 ]; |
|
|
|
int soundIndex = g_pSoundEmitterSystem->GetSoundIndex( name ); |
|
|
|
Q_FileBase( g_pSoundEmitterSystem->GetSourceFileForSound( soundIndex ), filebase, sizeof( filebase ) ); |
|
|
|
m_pListView->setLabel( slot, COL_SCRIPT, filebase ); |
|
|
|
++loadcount; |
|
} |
|
|
|
m_pListView->setDrawingEnabled( true ); |
|
|
|
// Con_Printf( "CSoundBrowser: selected %i sounds\n", loadcount ); |
|
} |
|
|
|
CWorkspaceManager *CSoundBrowser::GetManager() |
|
{ |
|
return m_pManager; |
|
} |
|
|
|
void CSoundBrowser::RepopulateTree() |
|
{ |
|
bool voiceonly = m_pOptions->IsChanVoiceOnly(); |
|
|
|
int slot = m_pFilter->getSelectedIndex(); |
|
|
|
if ( 0 >= slot ) |
|
{ |
|
PopulateTree( voiceonly, NULL ); |
|
} |
|
else |
|
{ |
|
PopulateTree( voiceonly, m_pFilter->getLabel( slot ) ); |
|
} |
|
|
|
m_pFilter->UpdatePrefixes(); |
|
} |
|
|
|
void CSoundBrowser::BuildSelectionList( CUtlVector< CSoundEntry * >& selected ) |
|
{ |
|
selected.RemoveAll(); |
|
|
|
int idx = -1; |
|
do |
|
{ |
|
idx = m_pListView->getNextSelectedItem( idx ); |
|
if ( idx != -1 ) |
|
{ |
|
CSoundEntry *se = (CSoundEntry *)m_pListView->getUserData( idx, 0 ); |
|
if ( se ) |
|
{ |
|
selected.AddToTail( se ); |
|
} |
|
} |
|
} while ( idx != -1 ); |
|
|
|
} |
|
|
|
void CSoundBrowser::ShowContextMenu( void ) |
|
{ |
|
BuildSelectionList( m_CurrentSelection ); |
|
if ( m_CurrentSelection.Count() <= 0 ) |
|
return; |
|
|
|
POINT pt; |
|
GetCursorPos( &pt ); |
|
ScreenToClient( (HWND)getHandle(), &pt ); |
|
|
|
// New scene, edit comments |
|
mxPopupMenu *pop = new mxPopupMenu(); |
|
|
|
if ( m_CurrentSelection.Count() == 1 ) |
|
{ |
|
pop->add ("&Play", IDC_SB_PLAY ); |
|
pop->addSeparator(); |
|
} |
|
|
|
pop->add( "Refresh sentence data", IDC_SB_GETSENTENCE ); |
|
|
|
pop->add( "Add sound entry...", IDC_SB_ADDSOUND ); |
|
if ( m_CurrentSelection.Count() >= 1 ) |
|
{ |
|
pop->add( "Remove sound(s)", IDC_SB_REMOVESOUND ); |
|
} |
|
|
|
pop->addSeparator(); |
|
|
|
pop->add( "Show in Wave Browser", IDC_SB_SHOWINWAVEBROWSER ); |
|
|
|
pop->add( "&Properties...", IDC_SB_SOUNDPROPERTIES ); |
|
|
|
pop->popup( this, pt.x, pt.y ); |
|
} |
|
|
|
void CSoundBrowser::OnPlay() |
|
{ |
|
BuildSelectionList( m_CurrentSelection ); |
|
if ( m_CurrentSelection.Count() == 1 ) |
|
{ |
|
CSoundEntry *se = m_CurrentSelection[ 0 ]; |
|
if ( se ) |
|
{ |
|
se->Play(); |
|
} |
|
} |
|
} |
|
|
|
void CSoundBrowser::JumpToItem( CSoundEntry *se ) |
|
{ |
|
char const *script = se->GetScriptFile(); |
|
|
|
bool voiceonly = m_pOptions->IsChanVoiceOnly(); |
|
|
|
if ( !script || !script[ 0 ] ) |
|
{ |
|
PopulateTree( voiceonly, NULL ); |
|
} |
|
else |
|
{ |
|
PopulateTree( voiceonly, script ); |
|
} |
|
|
|
int idx = 0; |
|
int c = m_pListView->getItemCount(); |
|
for ( ; idx < c; idx++ ) |
|
{ |
|
CSoundEntry *item = (CSoundEntry *)m_pListView->getUserData( idx, 0 ); |
|
if ( !Q_stricmp( item->GetName(), se->GetName() ) ) |
|
{ |
|
break; |
|
} |
|
} |
|
|
|
if ( idx < c ) |
|
{ |
|
m_pListView->scrollToItem( idx ); |
|
} |
|
} |
|
|
|
void CSoundBrowser::OnSoundProperties() |
|
{ |
|
BuildSelectionList( m_CurrentSelection ); |
|
if ( m_CurrentSelection.Count() < 1 ) |
|
{ |
|
Con_Printf( "No selection\n" ); |
|
return; |
|
} |
|
|
|
CSoundParams params; |
|
memset( ¶ms, 0, sizeof( params ) ); |
|
|
|
Q_snprintf( params.m_szDialogTitle, sizeof( params.m_szDialogTitle ), "Sound Properties" ); |
|
|
|
int c = m_CurrentSelection.Count(); |
|
for ( int i = 0 ; i < c; i++ ) |
|
{ |
|
CSoundEntry *entry = m_CurrentSelection[ i ]; |
|
if ( !entry ) |
|
continue; |
|
|
|
params.items.AddToTail( entry ); |
|
} |
|
|
|
if ( params.items.Count() > 1 ) |
|
{ |
|
SoundProperties_Multiple( ¶ms ); |
|
} |
|
else |
|
{ |
|
SoundProperties( ¶ms ); |
|
} |
|
} |
|
|
|
void CSoundBrowser::OnShowInWaveBrowser() |
|
{ |
|
if ( m_pListView->getNumSelected() == 1 ) |
|
{ |
|
int index = m_pListView->getNextSelectedItem( -1 ); |
|
if ( index >= 0 ) |
|
{ |
|
CSoundEntry *se = (CSoundEntry *)m_pListView->getUserData( index, 0 ); |
|
if ( se ) |
|
{ |
|
CWaveBrowser *wb = GetWorkspaceManager()->GetWaveBrowser(); |
|
if ( wb && se->GetWaveCount() > 0 ) |
|
{ |
|
CWaveFile *firstwave = se->GetWave( 0 ); |
|
Assert( firstwave ); |
|
if ( firstwave ) |
|
{ |
|
wb->JumpToItem( firstwave ); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
void CSoundBrowser::OnSearch() |
|
{ |
|
m_pFilter->select( ENTRY_SEARCH_INDEX ); |
|
RepopulateTree(); |
|
} |
|
|
|
char const *CSoundBrowser::GetSearchString() |
|
{ |
|
return m_pOptions->GetSearchString(); |
|
} |
|
|
|
void CSoundBrowser::OnAddSound() |
|
{ |
|
CSoundParams params; |
|
memset( ¶ms, 0, sizeof( params ) ); |
|
params.addsound = true; |
|
|
|
Q_snprintf( params.m_szDialogTitle, sizeof( params.m_szDialogTitle ), "New Sound" ); |
|
|
|
if ( !SoundProperties( ¶ms ) ) |
|
return; |
|
|
|
if ( params.items.Count() == 1 ) |
|
{ |
|
CSoundEntry *newItem = params.items[ 0 ]; |
|
m_AllSounds.AddToTail( newItem ); |
|
|
|
int slot = g_pSoundEmitterSystem->GetSoundIndex( newItem->GetName() ); |
|
if ( g_pSoundEmitterSystem->IsValidIndex( slot ) ) |
|
{ |
|
CSoundParametersInternal *p = g_pSoundEmitterSystem->InternalGetParametersForSound( slot ); |
|
if ( p ) |
|
{ |
|
CWaveBrowser *wb = GetWorkspaceManager()->GetWaveBrowser(); |
|
Assert( wb ); |
|
|
|
int waveCount = p->NumSoundNames(); |
|
for ( int wave = 0; wave < waveCount; wave++ ) |
|
{ |
|
char const *wavname = g_pSoundEmitterSystem->GetWaveName( p->GetSoundNames()[ wave ].symbol ); |
|
if ( wavname ) |
|
{ |
|
CWaveFile *wavefile = wb->FindEntry( wavname, true ); |
|
if ( wavefile ) |
|
{ |
|
newItem->AddWave( wavefile ); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
// Repopulate things |
|
GetWorkspaceManager()->RefreshBrowsers(); |
|
} |
|
|
|
void CSoundBrowser::OnRemoveSound() |
|
{ |
|
BuildSelectionList( m_CurrentSelection ); |
|
if ( m_CurrentSelection.Count() < 1 ) |
|
{ |
|
Con_Printf( "No selection\n" ); |
|
return; |
|
} |
|
|
|
int c = m_CurrentSelection.Count(); |
|
for ( int i = c - 1; i >= 0 ; i-- ) |
|
{ |
|
CSoundEntry *se = m_CurrentSelection[ i ]; |
|
Assert( se ); |
|
|
|
// FIXME: See if still referenced by a vcd? |
|
|
|
g_pSoundEmitterSystem->RemoveSound( se->GetName() ); |
|
m_AllSounds.FindAndRemove( se ); |
|
delete se; |
|
} |
|
|
|
// Repopulate things |
|
GetWorkspaceManager()->RefreshBrowsers(); |
|
} |
|
|
|
void CSoundBrowser::OnGetSentence() |
|
{ |
|
BuildSelectionList( m_CurrentSelection ); |
|
if ( m_CurrentSelection.Count() < 1 ) |
|
{ |
|
Con_Printf( "No selection\n" ); |
|
return; |
|
} |
|
|
|
int c = m_CurrentSelection.Count(); |
|
for ( int i = c - 1; i >= 0 ; i-- ) |
|
{ |
|
CSoundEntry *se = m_CurrentSelection[ i ]; |
|
Assert( se ); |
|
|
|
int c = se->GetWaveCount(); |
|
for ( int i = 0; i < c; ++i ) |
|
{ |
|
CWaveFile *wav = se->GetWave( i ); |
|
if ( !wav->HasLoadedSentenceInfo() ) |
|
{ |
|
wav->EnsureSentence(); |
|
} |
|
} |
|
} |
|
|
|
// Repopulate things |
|
GetWorkspaceManager()->RefreshBrowsers(); |
|
}
|
|
|