mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-22 06:06:50 +00:00
657 lines
19 KiB
C++
657 lines
19 KiB
C++
//========= 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;
|
|
}
|
|
|