summaryrefslogtreecommitdiff
path: root/vgui2/dme_controls/DmeSourceDCCFilePanel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'vgui2/dme_controls/DmeSourceDCCFilePanel.cpp')
-rw-r--r--vgui2/dme_controls/DmeSourceDCCFilePanel.cpp488
1 files changed, 488 insertions, 0 deletions
diff --git a/vgui2/dme_controls/DmeSourceDCCFilePanel.cpp b/vgui2/dme_controls/DmeSourceDCCFilePanel.cpp
new file mode 100644
index 0000000..0c5f30b
--- /dev/null
+++ b/vgui2/dme_controls/DmeSourceDCCFilePanel.cpp
@@ -0,0 +1,488 @@
+//========= 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 );
+}
+