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.
488 lines
15 KiB
488 lines
15 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//============================================================================= |
|
|
|
#include "dme_controls/DmeSourceDCCFilePanel.h" |
|
#include "dme_controls/DmePanel.h" |
|
#include "movieobjects/dmedccmakefile.h" |
|
#include "vgui_controls/TextEntry.h" |
|
#include "vgui_controls/ListPanel.h" |
|
#include "vgui_controls/Button.h" |
|
#include "vgui_controls/InputDialog.h" |
|
#include "vgui_controls/MessageBox.h" |
|
#include "vgui/keycode.h" |
|
#include "tier1/KeyValues.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
|
|
using namespace vgui; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// Hook into the dme panel editor system |
|
// |
|
//----------------------------------------------------------------------------- |
|
IMPLEMENT_DMEPANEL_FACTORY( CDmeSourceDCCFilePanel, DmeSourceDCCFile, "DmeSourceDCCFileDefault", "Maya/XSI Source File Editor", true ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sort by MDL name |
|
//----------------------------------------------------------------------------- |
|
static int __cdecl DccObjectSortFunc( vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 ) |
|
{ |
|
const char *string1 = item1.kv->GetString( "dccobject" ); |
|
const char *string2 = item2.kv->GetString( "dccobject" ); |
|
return Q_stricmp( string1, string2 ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Constructor, destructor |
|
//----------------------------------------------------------------------------- |
|
CDmeSourceDCCFilePanel::CDmeSourceDCCFilePanel( vgui::Panel *pParent, const char *pPanelName ) : |
|
BaseClass( pParent, pPanelName ) |
|
{ |
|
m_pRootDCCObjects = new vgui::ListPanel( this, "DCCObjectList" ); |
|
m_pRootDCCObjects->AddColumnHeader( 0, "dccobject", "Maya/XSI Object Name", 100, 0 ); |
|
m_pRootDCCObjects->AddActionSignalTarget( this ); |
|
m_pRootDCCObjects->SetSortFunc( 0, DccObjectSortFunc ); |
|
m_pRootDCCObjects->SetSortColumn( 0 ); |
|
// m_pRootDCCObjects->SetSelectIndividualCells( true ); |
|
m_pRootDCCObjects->SetEmptyListText("No sources"); |
|
// m_pRootDCCObjects->SetDragEnabled( true ); |
|
|
|
m_pDCCObjectBrowser = new vgui::Button( this, "DCCObjectBrowser", "...", this, "OnBrowseDCCObject" ); |
|
m_pDCCObjectName = new vgui::TextEntry( this, "DCCObjectName" ); |
|
m_pDCCObjectName->SendNewLine( true ); |
|
m_pDCCObjectName->AddActionSignalTarget( this ); |
|
|
|
m_pAddDCCObject = new vgui::Button( this, "AddDCCObjectButton", "Add", this, "OnAddDCCObject" ); |
|
m_pRemoveDCCObject = new vgui::Button( this, "RemoveDCCObjectButton", "Remove", this, "OnRemoveDCCObject" ); |
|
|
|
m_pApplyChanges = new vgui::Button( this, "ApplyChangesButton", "Apply", this, "OnApplyChanges" ); |
|
|
|
// Load layout settings; has to happen before pinning occurs in code |
|
LoadControlSettings( "resource/DmeSourceDCCFilePanel.res" ); |
|
} |
|
|
|
CDmeSourceDCCFilePanel::~CDmeSourceDCCFilePanel() |
|
{ |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Marks the file as dirty (or not) |
|
//----------------------------------------------------------------------------- |
|
void CDmeSourceDCCFilePanel::SetDirty() |
|
{ |
|
PostActionSignal( new KeyValues( "DmeElementChanged" ) ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Refresh the source list |
|
//----------------------------------------------------------------------------- |
|
void CDmeSourceDCCFilePanel::RefreshDCCObjectList( ) |
|
{ |
|
m_pRootDCCObjects->RemoveAll(); |
|
if ( !m_hSourceDCCFile.Get() ) |
|
return; |
|
|
|
int nCount = m_hSourceDCCFile->m_RootDCCObjects.Count(); |
|
for ( int i = 0; i < nCount; ++i ) |
|
{ |
|
KeyValues *pItemKeys = new KeyValues( "node", "dccobject", m_hSourceDCCFile->m_RootDCCObjects.Get(i) ); |
|
pItemKeys->SetInt( "dccObjectIndex", i ); |
|
m_pRootDCCObjects->AddItem( pItemKeys, 0, false, false ); |
|
} |
|
|
|
m_pRootDCCObjects->SortList(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Resets the state |
|
//----------------------------------------------------------------------------- |
|
void CDmeSourceDCCFilePanel::SetDmeElement( CDmeSourceDCCFile *pSourceDCCFile ) |
|
{ |
|
m_hSourceDCCFile = pSourceDCCFile; |
|
|
|
bool bEnabled = ( pSourceDCCFile != NULL ); |
|
m_pDCCObjectBrowser->SetEnabled( bEnabled ); |
|
m_pAddDCCObject->SetEnabled( bEnabled ); |
|
m_pRemoveDCCObject->SetEnabled( bEnabled ); |
|
m_pApplyChanges->SetEnabled( bEnabled ); |
|
if ( !bEnabled ) |
|
{ |
|
m_pRootDCCObjects->RemoveAll(); |
|
m_pDCCObjectName->SetText( "" ); |
|
return; |
|
} |
|
|
|
RefreshDCCObjectList(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when a list panel's selection changes |
|
//----------------------------------------------------------------------------- |
|
void CDmeSourceDCCFilePanel::OnItemSelectionChanged( ) |
|
{ |
|
int nCount = m_pRootDCCObjects->GetSelectedItemsCount(); |
|
bool bEnabled = ( nCount > 0 ); |
|
bool bMultiselect = ( nCount > 1 ); |
|
m_pDCCObjectBrowser->SetEnabled( bEnabled && !bMultiselect ); |
|
m_pDCCObjectName->SetEnabled( bEnabled && !bMultiselect ); |
|
m_pApplyChanges->SetEnabled( bEnabled && !bMultiselect ); |
|
m_pRemoveDCCObject->SetEnabled( bEnabled ); |
|
if ( !bEnabled || bMultiselect ) |
|
{ |
|
m_pDCCObjectName->SetText( "" ); |
|
return; |
|
} |
|
|
|
int nItemID = m_pRootDCCObjects->GetSelectedItem( 0 ); |
|
KeyValues *pKeyValues = m_pRootDCCObjects->GetItem( nItemID ); |
|
m_pDCCObjectName->SetText( pKeyValues->GetString( "dccobject" ) ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when a list panel's selection changes |
|
//----------------------------------------------------------------------------- |
|
void CDmeSourceDCCFilePanel::OnItemSelected( KeyValues *kv ) |
|
{ |
|
Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL ); |
|
if ( pPanel == m_pRootDCCObjects ) |
|
{ |
|
OnItemSelectionChanged(); |
|
return; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when a list panel's selection changes |
|
//----------------------------------------------------------------------------- |
|
void CDmeSourceDCCFilePanel::OnItemDeselected( KeyValues *kv ) |
|
{ |
|
Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL ); |
|
if ( pPanel == m_pRootDCCObjects ) |
|
{ |
|
OnItemSelectionChanged(); |
|
return; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when return is hit in a text entry field |
|
//----------------------------------------------------------------------------- |
|
void CDmeSourceDCCFilePanel::OnTextNewLine( KeyValues *kv ) |
|
{ |
|
if ( !m_hSourceDCCFile.Get() ) |
|
return; |
|
|
|
Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL ); |
|
if ( pPanel == m_pDCCObjectName ) |
|
{ |
|
OnDCCObjectNameChanged(); |
|
return; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Selects a particular DCC object |
|
//----------------------------------------------------------------------------- |
|
void CDmeSourceDCCFilePanel::SelectDCCObject( int nDCCObjectIndex ) |
|
{ |
|
if ( nDCCObjectIndex < 0 ) |
|
{ |
|
m_pRootDCCObjects->ClearSelectedItems(); |
|
return; |
|
} |
|
|
|
int nItemID = m_pRootDCCObjects->FirstItem(); |
|
for ( ; nItemID != m_pRootDCCObjects->InvalidItemID(); nItemID = m_pRootDCCObjects->NextItem( nItemID ) ) |
|
{ |
|
KeyValues *kv = m_pRootDCCObjects->GetItem( nItemID ); |
|
if ( kv->GetInt( "dccObjectIndex", -1 ) != nDCCObjectIndex ) |
|
continue; |
|
|
|
m_pRootDCCObjects->SetSingleSelectedItem( nItemID ); |
|
break; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when we're browsing for a DCC object and one was selected |
|
//----------------------------------------------------------------------------- |
|
void CDmeSourceDCCFilePanel::OnDCCObjectAdded( const char *pDCCObjectName, KeyValues *pContextKeys ) |
|
{ |
|
if ( !m_hSourceDCCFile.Get() ) |
|
return; |
|
|
|
if ( CheckForDuplicateNames( pDCCObjectName ) ) |
|
return; |
|
|
|
int nIndex = -1; |
|
{ |
|
CDisableUndoScopeGuard guard; |
|
nIndex = m_hSourceDCCFile->m_RootDCCObjects.AddToTail( pDCCObjectName ); |
|
} |
|
SetDirty( ); |
|
RefreshDCCObjectList( ); |
|
SelectDCCObject( nIndex ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when the file open dialog for browsing source files selects something |
|
//----------------------------------------------------------------------------- |
|
void CDmeSourceDCCFilePanel::OnInputCompleted( KeyValues *kv ) |
|
{ |
|
const char *pDCCObjectName = kv->GetString( "text", NULL ); |
|
if ( !pDCCObjectName ) |
|
return; |
|
|
|
KeyValues *pDialogKeys = kv->FindKey( "ChangeDCCObject" ); |
|
if ( pDialogKeys ) |
|
{ |
|
m_pDCCObjectName->SetText( pDCCObjectName ); |
|
OnDCCObjectNameChanged(); |
|
return; |
|
} |
|
|
|
pDialogKeys = kv->FindKey( "AddDCCObject" ); |
|
if ( pDialogKeys ) |
|
{ |
|
OnDCCObjectAdded( pDCCObjectName, pDialogKeys ); |
|
return; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Shows the DCC object browser (once we have one) |
|
//----------------------------------------------------------------------------- |
|
void CDmeSourceDCCFilePanel::ShowDCCObjectBrowser( const char *pTitle, const char *pPrompt, KeyValues *pDialogKeys ) |
|
{ |
|
InputDialog *pInput = new InputDialog( this, pTitle, pPrompt ); |
|
pInput->SetMultiline( false ); |
|
pInput->DoModal( pDialogKeys ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when the button to add a file is clicked |
|
//----------------------------------------------------------------------------- |
|
void CDmeSourceDCCFilePanel::OnAddDCCObject( ) |
|
{ |
|
if ( m_hSourceDCCFile.Get() ) |
|
{ |
|
KeyValues *pDialogKeys = new KeyValues( "AddDCCObject" ); |
|
ShowDCCObjectBrowser( "Add DCC Object", "Enter DCC object name to add", pDialogKeys ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when the button to browse for a source file is clicked |
|
//----------------------------------------------------------------------------- |
|
void CDmeSourceDCCFilePanel::OnBrowseDCCObject( ) |
|
{ |
|
int nCount = m_pRootDCCObjects->GetSelectedItemsCount(); |
|
if ( nCount == 0 || !m_hSourceDCCFile.Get() ) |
|
return; |
|
|
|
int nItemID = m_pRootDCCObjects->GetSelectedItem( 0 ); |
|
KeyValues *pKeyValues = m_pRootDCCObjects->GetItem( nItemID ); |
|
int nDCCObjectIndex = pKeyValues->GetInt( "dccObjectIndex", -1 ); |
|
|
|
KeyValues *pDialogKeys = new KeyValues( "ChangeDCCObject", "dccObjectIndex", nDCCObjectIndex ); |
|
ShowDCCObjectBrowser( "Edit Maya/XSI Object", "Enter new name of Maya/XSI object", pDialogKeys ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when the source file name changes |
|
//----------------------------------------------------------------------------- |
|
bool CDmeSourceDCCFilePanel::CheckForDuplicateNames( const char *pDCCObjectName, int nDCCObjectSkipIndex ) |
|
{ |
|
// Look for the existence of this source already |
|
if ( pDCCObjectName[0] ) |
|
{ |
|
int nCount = m_hSourceDCCFile->m_RootDCCObjects.Count(); |
|
for ( int i = 0; i < nCount; ++i ) |
|
{ |
|
if ( i == nDCCObjectSkipIndex ) |
|
continue; |
|
|
|
if ( !Q_stricmp( pDCCObjectName, m_hSourceDCCFile->m_RootDCCObjects[i] ) ) |
|
{ |
|
vgui::MessageBox *pError = new vgui::MessageBox( "#DmeSourceDCCFile_DuplicateSourceTitle", "#DmeSourceDCCFile_DuplicateSourceText", GetParent() ); |
|
pError->DoModal(); |
|
return true; |
|
} |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when the source file name changes |
|
//----------------------------------------------------------------------------- |
|
void CDmeSourceDCCFilePanel::OnDCCObjectNameChanged() |
|
{ |
|
int nCount = m_pRootDCCObjects->GetSelectedItemsCount(); |
|
if ( nCount == 0 || !m_hSourceDCCFile.Get() ) |
|
return; |
|
|
|
int nItemID = m_pRootDCCObjects->GetSelectedItem( 0 ); |
|
KeyValues *pKeyValues = m_pRootDCCObjects->GetItem( nItemID ); |
|
int nDCCObjectIndex = pKeyValues->GetInt( "dccObjectIndex", -1 ); |
|
if ( nDCCObjectIndex < 0 ) |
|
return; |
|
|
|
char pDCCObjectName[MAX_PATH]; |
|
m_pDCCObjectName->GetText( pDCCObjectName, sizeof(pDCCObjectName) ); |
|
|
|
if ( CheckForDuplicateNames( pDCCObjectName, nDCCObjectIndex ) ) |
|
return; |
|
|
|
{ |
|
CDisableUndoScopeGuard guard; |
|
m_hSourceDCCFile->m_RootDCCObjects.Set( nDCCObjectIndex, pDCCObjectName ); |
|
} |
|
|
|
pKeyValues->SetString( "dccobject", pDCCObjectName ); |
|
m_pRootDCCObjects->ApplyItemChanges( nItemID ); |
|
m_pRootDCCObjects->SortList(); |
|
|
|
SetDirty( ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Used for sorting below |
|
//----------------------------------------------------------------------------- |
|
static int IntCompare( const void *pSrc1, const void *pSrc2 ) |
|
{ |
|
int i1 = *(int*)pSrc1; |
|
int i2 = *(int*)pSrc2; |
|
return i1 - i2; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when the button to remove a DCC object is clicked |
|
//----------------------------------------------------------------------------- |
|
void CDmeSourceDCCFilePanel::OnRemoveDCCObject( ) |
|
{ |
|
int nCount = m_pRootDCCObjects->GetSelectedItemsCount(); |
|
if ( nCount == 0 || !m_hSourceDCCFile.Get() ) |
|
return; |
|
|
|
int nSelectedCount = 0; |
|
int *pDCCObjectIndex = (int*)alloca( nCount*sizeof(int) ); |
|
for ( int i = 0; i < nCount; ++i ) |
|
{ |
|
int nItemID = m_pRootDCCObjects->GetSelectedItem( i ); |
|
KeyValues *pKeyValues = m_pRootDCCObjects->GetItem( nItemID ); |
|
int nDCCObjectIndex = pKeyValues->GetInt( "dccObjectIndex", -1 ); |
|
if ( nDCCObjectIndex < 0 ) |
|
continue; |
|
pDCCObjectIndex[nSelectedCount++] = nDCCObjectIndex; |
|
} |
|
|
|
if ( nSelectedCount == 0 ) |
|
return; |
|
|
|
// Sort the object indices so we can remove them all |
|
qsort( pDCCObjectIndex, nSelectedCount, sizeof(int), IntCompare ); |
|
|
|
// Update the selection to be reasonable after deletion |
|
int nItemID = m_pRootDCCObjects->GetSelectedItem( 0 ); |
|
int nRow = m_pRootDCCObjects->GetItemCurrentRow( nItemID ); |
|
Assert( nRow >= 0 ); |
|
|
|
{ |
|
CDisableUndoScopeGuard guard; |
|
// Because we sorted it above, removes will occur properly |
|
for ( int i = nSelectedCount; --i >= 0; ) |
|
{ |
|
m_hSourceDCCFile->m_RootDCCObjects.Remove( pDCCObjectIndex[i] ); |
|
} |
|
SetDirty( ); |
|
} |
|
RefreshDCCObjectList(); |
|
|
|
int nVisibleRowCount = m_pRootDCCObjects->GetItemCount(); |
|
if ( nVisibleRowCount == 0 ) |
|
return; |
|
|
|
if ( nRow >= nVisibleRowCount ) |
|
{ |
|
nRow = nVisibleRowCount - 1; |
|
} |
|
|
|
int nNewItemID = m_pRootDCCObjects->GetItemIDFromRow( nRow ); |
|
m_pRootDCCObjects->SetSingleSelectedItem( nNewItemID ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when a key is typed |
|
//----------------------------------------------------------------------------- |
|
void CDmeSourceDCCFilePanel::OnKeyCodeTyped( vgui::KeyCode code ) |
|
{ |
|
if ( code == KEY_DELETE ) |
|
{ |
|
OnRemoveDCCObject(); |
|
return; |
|
} |
|
|
|
BaseClass::OnKeyCodeTyped( code ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Command handler |
|
//----------------------------------------------------------------------------- |
|
void CDmeSourceDCCFilePanel::OnCommand( const char *pCommand ) |
|
{ |
|
if ( !Q_stricmp( pCommand, "OnBrowseDCCObject" ) ) |
|
{ |
|
OnBrowseDCCObject(); |
|
return; |
|
} |
|
|
|
if ( !Q_stricmp( pCommand, "OnAddDCCObject" ) ) |
|
{ |
|
OnAddDCCObject(); |
|
return; |
|
} |
|
|
|
if ( !Q_stricmp( pCommand, "OnRemoveDCCObject" ) ) |
|
{ |
|
OnRemoveDCCObject(); |
|
return; |
|
} |
|
|
|
if ( !Q_stricmp( pCommand, "OnApplyChanges" ) ) |
|
{ |
|
OnDCCObjectNameChanged(); |
|
return; |
|
} |
|
|
|
BaseClass::OnCommand( pCommand ); |
|
} |
|
|
|
|