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.
656 lines
19 KiB
656 lines
19 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//============================================================================= |
|
|
|
#include "dme_controls/dmepanel.h" |
|
#include "tier1/KeyValues.h" |
|
#include "dme_controls/dmecontrols.h" |
|
#include "vgui_controls/combobox.h" |
|
#include "datamodel/dmelement.h" |
|
#include "dme_controls/dmecontrols_utils.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
using namespace vgui; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// All DmePanels used by the system must be listed here to link them in |
|
//----------------------------------------------------------------------------- |
|
USING_DMEPANEL_FACTORY( CDmeElementPanel, DmElement ); |
|
USING_DMEPANEL_FACTORY( CDmeSourceSkinPanel, DmeSourceSkin ); |
|
USING_DMEPANEL_FACTORY( CAssetBuilder, DmeMakefile ); |
|
USING_DMEPANEL_FACTORY( CDmeSourceDCCFilePanel, DmeSourceDCCFile ); |
|
USING_DMEPANEL_FACTORY( CDmeDagRenderPanel, DmeDag ); |
|
USING_DMEPANEL_FACTORY( CDmeDagRenderPanel, DmeSourceAnimation ); |
|
USING_DMEPANEL_FACTORY( CDmeDagRenderPanel, DmeSourceSkin ); |
|
USING_DMEPANEL_FACTORY( CDmeDagRenderPanel, DmeDCCMakefile ); |
|
USING_DMEPANEL_FACTORY( CDmeDagEditPanel, DmeDag ); |
|
USING_DMEPANEL_FACTORY( CDmeDagEditPanel, DmeSourceAnimation ); |
|
USING_DMEPANEL_FACTORY( CDmeDagEditPanel, DmeSourceSkin ); |
|
USING_DMEPANEL_FACTORY( CDmeDagEditPanel, DmeDCCMakefile ); |
|
USING_DMEPANEL_FACTORY( CDmeMDLPanel, DmeMDLMakefile ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// constructor, destructor |
|
//----------------------------------------------------------------------------- |
|
CDmePanel::CDmePanel( vgui::Panel *pParent, const char *pPanelName, bool bComboBoxVisible ) : |
|
BaseClass( pParent, pPanelName ) |
|
{ |
|
m_pEditorNames = new vgui::ComboBox( this, "EditorDisplayNames", 6, false ); |
|
if ( bComboBoxVisible ) |
|
{ |
|
m_pEditorNames->AddActionSignalTarget( this ); |
|
} |
|
else |
|
{ |
|
m_pEditorNames->SetVisible( false ); |
|
} |
|
m_pDmeEditorPanel = NULL; |
|
m_hElement = NULL; |
|
|
|
SetDropEnabled( true ); |
|
} |
|
|
|
CDmePanel::~CDmePanel() |
|
{ |
|
DeleteCachedPanels(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Scheme |
|
//----------------------------------------------------------------------------- |
|
void CDmePanel::ApplySchemeSettings( vgui::IScheme *pScheme ) |
|
{ |
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
m_pEditorNames->SetFont( pScheme->GetFont( "DefaultVerySmall" ) ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Layout |
|
//----------------------------------------------------------------------------- |
|
void CDmePanel::PerformLayout() |
|
{ |
|
BaseClass::PerformLayout(); |
|
|
|
int w, h; |
|
GetSize( w, h ); |
|
if ( m_pEditorNames->IsVisible() ) |
|
{ |
|
m_pEditorNames->SetBounds( 1, 1, w-2, 20 ); |
|
if ( m_pDmeEditorPanel ) |
|
{ |
|
m_pDmeEditorPanel->SetBounds( 0, 24, w, h-24 ); |
|
} |
|
} |
|
else |
|
{ |
|
if ( m_pDmeEditorPanel ) |
|
{ |
|
m_pDmeEditorPanel->SetBounds( 0, 0, w, h ); |
|
} |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Drag/drop |
|
//----------------------------------------------------------------------------- |
|
bool CDmePanel::IsDroppable( CUtlVector< KeyValues * >& msglist ) |
|
{ |
|
if ( msglist.Count() != 1 ) |
|
return false; |
|
|
|
KeyValues *data = msglist[ 0 ]; |
|
CDmElement *ptr = GetElementKeyValue<CDmElement>( data, "dmeelement" ); |
|
if ( !ptr ) |
|
return false; |
|
|
|
if ( ptr == m_hElement.Get() ) |
|
return false; |
|
|
|
return true; |
|
} |
|
|
|
void CDmePanel::OnPanelDropped( CUtlVector< KeyValues * >& msglist ) |
|
{ |
|
if ( msglist.Count() != 1 ) |
|
return; |
|
|
|
KeyValues *data = msglist[ 0 ]; |
|
CDmElement *ptr = GetElementKeyValue<CDmElement>( data, "dmeelement" ); |
|
if ( !ptr ) |
|
return; |
|
|
|
// Already browsing |
|
if ( ptr == m_hElement.Get() ) |
|
return; |
|
|
|
SetDmeElement( ptr ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets the default editor type |
|
//----------------------------------------------------------------------------- |
|
void CDmePanel::SetDefaultEditorType( const char *pEditorType ) |
|
{ |
|
m_DefaultEditorType = pEditorType; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Populate editor name combo box |
|
//----------------------------------------------------------------------------- |
|
void CDmePanel::PopulateEditorNames( const char *pPanelName ) |
|
{ |
|
m_pEditorNames->RemoveAll(); |
|
m_pEditorNames->SetText( "" ); |
|
if ( !m_pEditorNames->IsVisible() ) |
|
{ |
|
SetEditor( pPanelName ); |
|
return; |
|
} |
|
|
|
if ( !m_hElement.Get() ) |
|
{ |
|
OnTextChanged(); |
|
return; |
|
} |
|
|
|
const char *pPreferredEditor = NULL; |
|
if ( m_LastUsedEditorType.Defined( m_hElement->GetTypeString() ) ) |
|
{ |
|
pPreferredEditor = m_LastUsedEditorType[ m_hElement->GetTypeString() ].Get(); |
|
} |
|
else |
|
{ |
|
pPreferredEditor = m_DefaultEditorType; |
|
} |
|
|
|
int nBestInheritanceDepth = -1; |
|
int nActiveItemID = -1; |
|
bool bFoundPanelName = false; |
|
DmeFactoryHandle_t h = DmePanelFirstFactory( m_hElement.Get() ); |
|
for ( ; h != DMEFACTORY_HANDLE_INVALID; h = DmePanelNextFactory( h, m_hElement.Get() ) ) |
|
{ |
|
const char *pDisplayName = DmePanelFactoryDisplayName( h ); |
|
const char *pEditorName = DmePanelFactoryName( h ); |
|
KeyValues *pKeyValues = new KeyValues( "entry", "editorName", pEditorName ); |
|
|
|
int nItemID = m_pEditorNames->AddItem( pDisplayName, pKeyValues ); |
|
|
|
if ( pPanelName && !Q_stricmp( pPanelName, pEditorName ) ) |
|
{ |
|
nBestInheritanceDepth = 0; |
|
nActiveItemID = nItemID; |
|
bFoundPanelName = true; |
|
continue; |
|
} |
|
|
|
if ( pPreferredEditor && !bFoundPanelName && !Q_stricmp( pPreferredEditor, pEditorName ) ) |
|
{ |
|
nBestInheritanceDepth = 0; |
|
nActiveItemID = nItemID; |
|
continue; |
|
} |
|
|
|
// Don't select this as the default if it's not a default factory |
|
if ( !DmePanelFactoryIsDefault(h) ) |
|
continue; |
|
|
|
// Choose this factory if it's more derived than the previous best |
|
const char *pElementType = DmePanelFactoryElementType( h ); |
|
int nInheritanceDepth = m_hElement->GetInheritanceDepth( pElementType ); |
|
Assert( nInheritanceDepth >= 0 ); |
|
if ( nBestInheritanceDepth >= 0 && ( nInheritanceDepth >= nBestInheritanceDepth ) ) |
|
continue; |
|
|
|
nBestInheritanceDepth = nInheritanceDepth; |
|
nActiveItemID = nItemID; |
|
} |
|
|
|
if ( m_pEditorNames->GetItemCount() == 0 ) |
|
{ |
|
// ItemCount == 0; |
|
m_pEditorNames->SetText( "" ); |
|
m_CurrentEditorName = NULL; |
|
OnTextChanged(); |
|
return; |
|
} |
|
|
|
if ( nActiveItemID >= 0 ) |
|
{ |
|
m_pEditorNames->ActivateItem( nActiveItemID ); |
|
} |
|
else |
|
{ |
|
m_pEditorNames->ActivateItemByRow( 0 ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when the dme element was changed |
|
//----------------------------------------------------------------------------- |
|
void CDmePanel::OnDmeElementChanged() |
|
{ |
|
PostActionSignal( new KeyValues( "DmeElementChanged" ) ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Context menu support |
|
//----------------------------------------------------------------------------- |
|
void CDmePanel::OnOpenContextMenu( KeyValues *params ) |
|
{ |
|
// Forward the context menu message to the DME panel |
|
KeyValues *pMsg = params->MakeCopy(); |
|
if ( m_pDmeEditorPanel ) |
|
{ |
|
PostMessage( m_pDmeEditorPanel->GetVPanel(), pMsg ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Copy/paste support |
|
//----------------------------------------------------------------------------- |
|
void CDmePanel::PostMessageToDmePanel( const char *pMessage ) |
|
{ |
|
if ( m_pDmeEditorPanel ) |
|
{ |
|
PostMessage( m_pDmeEditorPanel->GetVPanel(), new KeyValues( pMessage ) ); |
|
} |
|
} |
|
|
|
void CDmePanel::OnCut() |
|
{ |
|
PostMessageToDmePanel( "OnCut" ); |
|
} |
|
|
|
void CDmePanel::OnCopy() |
|
{ |
|
PostMessageToDmePanel( "OnCopy" ); |
|
} |
|
|
|
void CDmePanel::OnPaste() |
|
{ |
|
PostMessageToDmePanel( "OnPaste" ); |
|
} |
|
|
|
void CDmePanel::OnPasteInsert() |
|
{ |
|
PostMessageToDmePanel( "OnPasteInsert" ); |
|
} |
|
|
|
void CDmePanel::OnPasteReference() |
|
{ |
|
PostMessageToDmePanel( "OnPasteReference" ); |
|
} |
|
|
|
void CDmePanel::OnEditDelete() |
|
{ |
|
PostMessageToDmePanel( "OnEditDelete" ); |
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when a child of the dme panel switches the thing it's looking at |
|
//----------------------------------------------------------------------------- |
|
void CDmePanel::OnViewedElementChanged( KeyValues *kv ) |
|
{ |
|
// This is kind of tricky. It's called by the element properties tree |
|
// when doing the back/forward searching. Just calling the normal SetDmeElement |
|
// doesn't work because it reorders the history. What we want is to |
|
// populate the combo box without causing the OnTextChanged message to get sent. |
|
|
|
// FIXME: Perhaps it would be better to extract the back/forward/search |
|
// out of the element properties tree and put it into the dme panel? |
|
CDmElement *pElement = GetElementKeyValue<CDmElement>( kv, "dmeelement" ); |
|
if ( pElement == m_hElement ) |
|
return; |
|
|
|
// If the current editor isn't supported by this new element, then just reset. Too bad. |
|
bool bFound = false; |
|
if ( m_CurrentEditorName.Length() && pElement ) |
|
{ |
|
DmeFactoryHandle_t h = DmePanelFirstFactory( pElement ); |
|
for ( ; h != DMEFACTORY_HANDLE_INVALID; h = DmePanelNextFactory( h, pElement ) ) |
|
{ |
|
const char *pEditorName = DmePanelFactoryName( h ); |
|
if ( !Q_stricmp( m_CurrentEditorName, pEditorName ) ) |
|
{ |
|
bFound = true; |
|
break; |
|
} |
|
} |
|
} |
|
|
|
if ( !bFound ) |
|
{ |
|
SetDmeElement( pElement ); |
|
return; |
|
} |
|
|
|
// Remove obsolete items |
|
int nCount = m_pEditorNames->GetItemCount(); |
|
while ( --nCount >= 0 ) |
|
{ |
|
int nItemID = m_pEditorNames->GetItemIDFromRow( nCount ); |
|
KeyValues *kv = m_pEditorNames->GetItemUserData( nItemID ); |
|
if ( Q_stricmp( m_CurrentEditorName, kv->GetString( "editorName" ) ) ) |
|
{ |
|
m_pEditorNames->DeleteItem( nItemID ); |
|
} |
|
} |
|
|
|
// Just want to populate the combo box with new items |
|
DmeFactoryHandle_t h = DmePanelFirstFactory( pElement ); |
|
for ( ; h != DMEFACTORY_HANDLE_INVALID; h = DmePanelNextFactory( h, pElement ) ) |
|
{ |
|
const char *pEditorName = DmePanelFactoryName( h ); |
|
if ( Q_stricmp( pEditorName, m_CurrentEditorName ) ) |
|
{ |
|
const char *pDisplayName = DmePanelFactoryDisplayName( h ); |
|
KeyValues *pKeyValues = new KeyValues( "entry", "editorName", pEditorName ); |
|
m_pEditorNames->AddItem( pDisplayName, pKeyValues ); |
|
} |
|
} |
|
|
|
m_hElement = pElement; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Delete cached panels |
|
//----------------------------------------------------------------------------- |
|
void CDmePanel::DeleteCachedPanels() |
|
{ |
|
int nCount = m_EditorPanelCache.GetNumStrings(); |
|
for ( int i = 0; i < nCount; ++i ) |
|
{ |
|
int nEditorCount = m_EditorPanelCache[ i ].Count(); |
|
for ( int j = 0; j < nEditorCount; ++j ) |
|
{ |
|
m_EditorPanelCache[ i ][ j ].m_pEditorPanel->MarkForDeletion(); |
|
} |
|
} |
|
m_EditorPanelCache.Clear(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Refreshes the current panel owing to external change |
|
// Values only means no topological change |
|
//----------------------------------------------------------------------------- |
|
void CDmePanel::Refresh( bool bValuesOnly ) |
|
{ |
|
if ( m_pDmeEditorPanel ) |
|
{ |
|
KeyValues *pKeyValues = new KeyValues( "ElementChangedExternally", "valuesOnly", bValuesOnly ); |
|
PostMessage( m_pDmeEditorPanel, pKeyValues ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Deactivates the current editor |
|
//----------------------------------------------------------------------------- |
|
void CDmePanel::DeactivateCurrentEditor() |
|
{ |
|
if ( m_pDmeEditorPanel ) |
|
{ |
|
m_pDmeEditorPanel->SetParent( (vgui::Panel*)NULL ); |
|
m_pDmeEditorPanel = NULL; |
|
m_CurrentEditorName = NULL; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Switch to a new editor |
|
//----------------------------------------------------------------------------- |
|
void CDmePanel::SetEditor( const char *pEditorName ) |
|
{ |
|
if ( pEditorName && !Q_stricmp( m_CurrentEditorName, pEditorName ) ) |
|
return; |
|
|
|
DeactivateCurrentEditor(); |
|
|
|
if ( !m_hElement.Get() || !pEditorName ) |
|
return; |
|
|
|
if ( m_EditorPanelCache.Defined( pEditorName ) ) |
|
{ |
|
CUtlVector< EditorPanelMap_t > &entries = m_EditorPanelCache[ pEditorName ]; |
|
int nCount = entries.Count(); |
|
for ( int i = 0; i < nCount; ++i ) |
|
{ |
|
EditorPanelMap_t &entry = entries[i]; |
|
if ( !m_hElement->IsA( entry.m_pFactory->m_pElementType ) ) |
|
continue; |
|
|
|
m_pDmeEditorPanel = entry.m_pEditorPanel; |
|
m_pDmeEditorPanel->SetParent( this ); |
|
entry.m_pFactory->SetDmeElement( m_pDmeEditorPanel, m_hElement ); |
|
break; |
|
} |
|
} |
|
|
|
if ( !m_pDmeEditorPanel ) |
|
{ |
|
EditorPanelMap_t entry; |
|
if ( CreateDmePanel( this, "DmePanelEditor", m_hElement, pEditorName, &entry ) ) |
|
{ |
|
m_EditorPanelCache[ pEditorName ].AddToTail( entry ); |
|
m_pDmeEditorPanel = entry.m_pEditorPanel; |
|
} |
|
} |
|
|
|
if ( m_pDmeEditorPanel ) |
|
{ |
|
// Store the last selected type of editor |
|
m_LastUsedEditorType[ m_hElement->GetTypeString() ] = pEditorName; |
|
m_CurrentEditorName = pEditorName; |
|
m_pDmeEditorPanel->AddActionSignalTarget( this ); |
|
} |
|
InvalidateLayout(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when a new element in the combo box has been selected |
|
//----------------------------------------------------------------------------- |
|
void CDmePanel::OnTextChanged() |
|
{ |
|
KeyValues *kv = m_pEditorNames->GetActiveItemUserData(); |
|
const char *pEditorName = kv ? kv->GetString( "editorName", NULL ) : NULL; |
|
SetEditor( pEditorName ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Setting a new element |
|
//----------------------------------------------------------------------------- |
|
void CDmePanel::SetDmeElement( CDmElement *pDmeElement, bool bForce, const char *pPanelName ) |
|
{ |
|
if ( ( m_hElement == pDmeElement ) && !bForce ) |
|
{ |
|
if ( !pPanelName || !Q_stricmp( pPanelName, m_CurrentEditorName.Get() ) ) |
|
return; |
|
} |
|
|
|
m_hElement = pDmeElement; |
|
m_CurrentEditorName = NULL; |
|
|
|
// Populate the editor type list |
|
PopulateEditorNames( pPanelName ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Statics for the panel factory |
|
//----------------------------------------------------------------------------- |
|
CBaseDmePanelFactory* CBaseDmePanelFactory::s_pFirstDmePanelFactory; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Constructor |
|
//----------------------------------------------------------------------------- |
|
CBaseDmePanelFactory::CBaseDmePanelFactory( const char *pElementType, const char *pEditorName, |
|
const char *pEditorDisplayName, bool bIsDefault, bool bIsOverride ) |
|
{ |
|
// Prior to linking this in, look to see if this has been overridden |
|
CBaseDmePanelFactory *pPrevFactory = NULL; |
|
for( CBaseDmePanelFactory* pFactory = s_pFirstDmePanelFactory; pFactory; |
|
pPrevFactory = pFactory, pFactory = pFactory->m_pNext ) |
|
{ |
|
if ( !Q_stricmp( pFactory->m_pElementType, pElementType ) && |
|
!Q_stricmp( pFactory->m_pEditorDisplayName, pEditorDisplayName ) ) |
|
{ |
|
// Collision found! If this is not an override, then we've been overridden |
|
if ( !bIsOverride ) |
|
{ |
|
AssertMsg( pFactory->m_bIsOverride, ( "Two DmePanel factories have the same name (\"%s\") + type (\"%s\")!\n", pElementType, pEditorName ) ); |
|
return; |
|
} |
|
|
|
// If this *is* an override, replace the previous version |
|
AssertMsg( !pFactory->m_bIsOverride, ( "Two DmePanel factories have the same name (\"%s\") + type (\"%s\")!\n", pElementType, pEditorName ) ); |
|
if ( pPrevFactory ) |
|
{ |
|
pPrevFactory->m_pNext = pFactory->m_pNext; |
|
} |
|
else |
|
{ |
|
s_pFirstDmePanelFactory = pFactory->m_pNext; |
|
} |
|
break; |
|
} |
|
} |
|
|
|
m_pNext = s_pFirstDmePanelFactory; |
|
s_pFirstDmePanelFactory = this; |
|
|
|
m_pElementType = pElementType; |
|
m_pEditorName = pEditorName; |
|
m_pEditorDisplayName = pEditorDisplayName; |
|
m_bIsDefault = bIsDefault; |
|
m_bIsOverride = bIsOverride; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Dme Panel factory iteration methods |
|
//----------------------------------------------------------------------------- |
|
DmeFactoryHandle_t DmePanelFirstFactory( CDmElement *pElement ) |
|
{ |
|
CBaseDmePanelFactory *pFactory = CBaseDmePanelFactory::s_pFirstDmePanelFactory; |
|
for ( ; pFactory; pFactory = pFactory->m_pNext ) |
|
{ |
|
if ( !pElement || pElement->IsA( pFactory->m_pElementType ) ) |
|
return (DmeFactoryHandle_t)pFactory; |
|
} |
|
|
|
return DMEFACTORY_HANDLE_INVALID; |
|
} |
|
|
|
|
|
DmeFactoryHandle_t DmePanelNextFactory( DmeFactoryHandle_t h, CDmElement *pElement ) |
|
{ |
|
CBaseDmePanelFactory *pFactory = (CBaseDmePanelFactory*)h; |
|
if ( !pFactory ) |
|
return DMEFACTORY_HANDLE_INVALID; |
|
|
|
for ( pFactory = pFactory->m_pNext; pFactory; pFactory = pFactory->m_pNext ) |
|
{ |
|
if ( !pElement || pElement->IsA( pFactory->m_pElementType ) ) |
|
return (DmeFactoryHandle_t)pFactory; |
|
} |
|
|
|
return DMEFACTORY_HANDLE_INVALID; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Dme Panel factory info methods |
|
//----------------------------------------------------------------------------- |
|
const char *DmePanelFactoryName( DmeFactoryHandle_t h ) |
|
{ |
|
CBaseDmePanelFactory *pFactory = (CBaseDmePanelFactory*)h; |
|
return pFactory ? pFactory->m_pEditorName : NULL; |
|
} |
|
|
|
const char *DmePanelFactoryDisplayName( DmeFactoryHandle_t h ) |
|
{ |
|
CBaseDmePanelFactory *pFactory = (CBaseDmePanelFactory*)h; |
|
return pFactory ? pFactory->m_pEditorDisplayName : NULL; |
|
} |
|
|
|
const char *DmePanelFactoryElementType( DmeFactoryHandle_t h ) |
|
{ |
|
CBaseDmePanelFactory *pFactory = (CBaseDmePanelFactory*)h; |
|
return pFactory ? pFactory->m_pElementType : NULL; |
|
} |
|
|
|
bool DmePanelFactoryIsDefault( DmeFactoryHandle_t h ) |
|
{ |
|
CBaseDmePanelFactory *pFactory = (CBaseDmePanelFactory*)h; |
|
return pFactory ? pFactory->m_bIsDefault : false; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Dme Panel factory methods |
|
//----------------------------------------------------------------------------- |
|
bool CDmePanel::CreateDmePanel( vgui::Panel *pParent, const char *pPanelName, CDmElement *pElement, const char *pEditorName, EditorPanelMap_t *pMap ) |
|
{ |
|
int nBestInheritanceDepth = -1; |
|
CBaseDmePanelFactory *pBestFactory = NULL; |
|
CBaseDmePanelFactory *pFactory = CBaseDmePanelFactory::s_pFirstDmePanelFactory; |
|
for ( ; pFactory; pFactory = pFactory->m_pNext ) |
|
{ |
|
if ( !pElement->IsA( pFactory->m_pElementType ) ) |
|
continue; |
|
|
|
if ( pEditorName ) |
|
{ |
|
if ( !Q_stricmp( pEditorName, pFactory->m_pEditorName ) ) |
|
{ |
|
pBestFactory = pFactory; |
|
break; |
|
} |
|
continue; |
|
} |
|
|
|
// No editor name specified? Only use default factories |
|
if ( !pFactory->m_bIsDefault ) |
|
continue; |
|
|
|
// Choose this factory if it's more derived than the previous best |
|
int nInheritanceDepth = pElement->GetInheritanceDepth( pFactory->m_pElementType ); |
|
Assert( nInheritanceDepth >= 0 ); |
|
if ( nBestInheritanceDepth >= 0 && ( nInheritanceDepth > nBestInheritanceDepth ) ) |
|
continue; |
|
|
|
nBestInheritanceDepth = nInheritanceDepth; |
|
pBestFactory = pFactory; |
|
} |
|
|
|
if ( pBestFactory ) |
|
{ |
|
pMap->m_pFactory = pBestFactory; |
|
pMap->m_pEditorPanel = pBestFactory->CreateDmePanel( pParent, pPanelName, pElement ); |
|
return true; |
|
} |
|
return false; |
|
} |
|
|
|
|