281 lines
11 KiB
C
281 lines
11 KiB
C
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
//=============================================================================
|
||
|
|
||
|
#ifndef DMEPANEL_H
|
||
|
#define DMEPANEL_H
|
||
|
|
||
|
#ifdef _WIN32
|
||
|
#pragma once
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#include "tier0/basetypes.h"
|
||
|
#include "tier1/utlstringmap.h"
|
||
|
#include "vgui_controls/EditablePanel.h"
|
||
|
#include "datamodel/dmelement.h"
|
||
|
#include "datamodel/dmehandle.h"
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Forward declarations
|
||
|
//-----------------------------------------------------------------------------
|
||
|
class CDmElement;
|
||
|
class CBaseDmePanelFactory;
|
||
|
|
||
|
namespace vgui
|
||
|
{
|
||
|
class Panel;
|
||
|
class EditablePanel;
|
||
|
class ComboBox;
|
||
|
class IScheme;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Dme Panel factory iteration handle
|
||
|
//-----------------------------------------------------------------------------
|
||
|
DECLARE_POINTER_HANDLE( DmeFactoryHandle_t );
|
||
|
#define DMEFACTORY_HANDLE_INVALID ((DmeFactoryHandle_t)0)
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Dme Panel: used for editing arbitrary dme elements
|
||
|
//-----------------------------------------------------------------------------
|
||
|
class CDmePanel : public vgui::EditablePanel
|
||
|
{
|
||
|
DECLARE_CLASS_SIMPLE( CDmePanel, vgui::EditablePanel );
|
||
|
|
||
|
public:
|
||
|
// constructor, destructor
|
||
|
CDmePanel( vgui::Panel *pParent, const char *pPanelName, bool bComboBoxVisible = true );
|
||
|
virtual ~CDmePanel();
|
||
|
|
||
|
virtual void PerformLayout();
|
||
|
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
|
||
|
|
||
|
void SetDmeElement( CDmElement *pDmeElement, bool bForce = false, const char *pPanelName = NULL );
|
||
|
|
||
|
// Switch to a new editor
|
||
|
void SetEditor( const char *pEditorName );
|
||
|
|
||
|
// Drag/drop
|
||
|
bool IsDroppable( CUtlVector< KeyValues * >& msglist );
|
||
|
void OnPanelDropped( CUtlVector< KeyValues * >& msglist );
|
||
|
|
||
|
// Refreshes the current panel owing to external change
|
||
|
// Values only means no topological change
|
||
|
void Refresh( bool bValuesOnly );
|
||
|
|
||
|
// Sets the default editor type
|
||
|
void SetDefaultEditorType( const char *pEditorType );
|
||
|
|
||
|
private:
|
||
|
struct EditorPanelMap_t
|
||
|
{
|
||
|
vgui::EditablePanel *m_pEditorPanel;
|
||
|
CBaseDmePanelFactory *m_pFactory;
|
||
|
};
|
||
|
|
||
|
MESSAGE_FUNC( OnTextChanged, "TextChanged" );
|
||
|
MESSAGE_FUNC( OnDmeElementChanged, "DmeElementChanged" );
|
||
|
MESSAGE_FUNC_PARAMS( OnViewedElementChanged, "NotifyViewedElementChanged", kv );
|
||
|
|
||
|
// Copy/paste support
|
||
|
MESSAGE_FUNC( OnCut, "OnCut" );
|
||
|
MESSAGE_FUNC( OnCopy, "OnCopy" );
|
||
|
MESSAGE_FUNC( OnPaste, "OnPaste" );
|
||
|
MESSAGE_FUNC( OnPasteReference, "OnPasteReference" );
|
||
|
MESSAGE_FUNC( OnPasteInsert, "OnPasteInsert" );
|
||
|
MESSAGE_FUNC( OnEditDelete, "OnEditDelete" );
|
||
|
|
||
|
// Context menu support
|
||
|
MESSAGE_FUNC_PARAMS( OnOpenContextMenu, "OpenContextMenu", params );
|
||
|
|
||
|
// Delete cached panels
|
||
|
void DeleteCachedPanels();
|
||
|
|
||
|
// Populate editor name combo box
|
||
|
void PopulateEditorNames( const char *pPanelName = NULL );
|
||
|
|
||
|
// Deactivates the current editor
|
||
|
void DeactivateCurrentEditor();
|
||
|
|
||
|
// Post message to the dme panel
|
||
|
void PostMessageToDmePanel( const char *pMessage );
|
||
|
|
||
|
static bool CreateDmePanel( vgui::Panel *pParent, const char *pPanelName, CDmElement *pElement, const char *pEditorName, EditorPanelMap_t *pMap );
|
||
|
|
||
|
vgui::ComboBox *m_pEditorNames;
|
||
|
|
||
|
CDmeHandle< CDmElement > m_hElement;
|
||
|
CUtlStringMap< CUtlString > m_LastUsedEditorType;
|
||
|
CUtlStringMap< CUtlVector< EditorPanelMap_t > > m_EditorPanelCache;
|
||
|
vgui::EditablePanel *m_pDmeEditorPanel;
|
||
|
CUtlString m_CurrentEditorName;
|
||
|
CUtlString m_DefaultEditorType;
|
||
|
};
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Dme Panel factory methods
|
||
|
//-----------------------------------------------------------------------------
|
||
|
class CBaseDmePanelFactory
|
||
|
{
|
||
|
public:
|
||
|
virtual vgui::EditablePanel *CreateDmePanel( vgui::Panel *pParent, const char *pPanelName, CDmElement *pElement ) = 0;
|
||
|
virtual void SetDmeElement( vgui::EditablePanel *pPanel, CDmElement *pElement ) = 0;
|
||
|
|
||
|
protected:
|
||
|
// Constructor, protected because these should never be instanced directly
|
||
|
CBaseDmePanelFactory( const char *pElementType, const char *pEditorName, const char *pEditorDisplayName, bool bIsDefault, bool bIsOverride );
|
||
|
|
||
|
public:
|
||
|
const char *m_pElementType;
|
||
|
const char *m_pEditorName;
|
||
|
const char *m_pEditorDisplayName;
|
||
|
bool m_bIsDefault : 1;
|
||
|
bool m_bIsOverride : 1;
|
||
|
|
||
|
CBaseDmePanelFactory *m_pNext;
|
||
|
static CBaseDmePanelFactory* s_pFirstDmePanelFactory;
|
||
|
};
|
||
|
|
||
|
|
||
|
template< class PanelType, class ElementType >
|
||
|
class CDmePanelFactory : public CBaseDmePanelFactory
|
||
|
{
|
||
|
typedef CBaseDmePanelFactory BaseClass;
|
||
|
|
||
|
public:
|
||
|
// Constructor
|
||
|
CDmePanelFactory( const char *pElementType, const char *pEditorName, const char *pEditorDisplayName, bool bIsDefault, bool bIsOverride ) :
|
||
|
BaseClass( pElementType, pEditorName, pEditorDisplayName, bIsDefault, bIsOverride )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
virtual vgui::EditablePanel *CreateDmePanel( vgui::Panel *pParent, const char *pPanelName, CDmElement *pElement )
|
||
|
{
|
||
|
ElementType *pTypedElement = CastElement<ElementType>( pElement );
|
||
|
Assert( pTypedElement && pElement->IsA( m_pElementType ) );
|
||
|
|
||
|
// NOTE: The panel factory assumes T contains the following method:
|
||
|
// void SetDmeElement( ElementType *pElement );
|
||
|
// You'll get compile errors about 'SetDmeElement' not being defined if not
|
||
|
PanelType *pPanel = new PanelType( pParent, pPanelName );
|
||
|
pPanel->SetDmeElement( pTypedElement );
|
||
|
return pPanel;
|
||
|
}
|
||
|
|
||
|
virtual void SetDmeElement( vgui::EditablePanel *pPanel, CDmElement *pElement )
|
||
|
{
|
||
|
PanelType *pTypedPanel = static_cast< PanelType* >( pPanel );
|
||
|
ElementType *pTypedElement = static_cast< ElementType* >( pElement );
|
||
|
pTypedPanel->SetDmeElement( pTypedElement );
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
template< class PanelType, class ElementType, class DisplayType >
|
||
|
class CDmePanelConverterFactory : public CBaseDmePanelFactory
|
||
|
{
|
||
|
typedef CBaseDmePanelFactory BaseClass;
|
||
|
|
||
|
public:
|
||
|
// Constructor
|
||
|
CDmePanelConverterFactory( const char *pElementType, const char *pDisplayType, const char *pEditorName, const char *pEditorDisplayName, bool bIsDefault, bool bIsOverride ) :
|
||
|
BaseClass( pElementType, pEditorName, pEditorDisplayName, bIsDefault, bIsOverride )
|
||
|
{
|
||
|
m_pDisplayType = pDisplayType;
|
||
|
}
|
||
|
|
||
|
virtual vgui::EditablePanel *CreateDmePanel( vgui::Panel *pParent, const char *pPanelName, CDmElement *pElement )
|
||
|
{
|
||
|
ElementType *pTypedElement = CastElement<ElementType>( pElement );
|
||
|
Assert( pTypedElement && pElement->IsA( m_pElementType ) );
|
||
|
|
||
|
// NOTE: To use the converter factory, the element must implement a method
|
||
|
// CDmElement *GetDmePanelElement( const char *pDisplayType );
|
||
|
DisplayType *pDisplayElement = CastElement<DisplayType>( pTypedElement->GetDmePanelElement( m_pDisplayType ) );
|
||
|
|
||
|
// NOTE: The panel factory assumes T contains the following method:
|
||
|
// void SetDmeElement( ElementType *pElement );
|
||
|
// You'll get compile errors about 'SetDmeElement' not being defined if not
|
||
|
PanelType *pPanel = new PanelType( pParent, pPanelName );
|
||
|
pPanel->SetDmeElement( pDisplayElement );
|
||
|
return pPanel;
|
||
|
}
|
||
|
|
||
|
virtual void SetDmeElement( vgui::EditablePanel *pPanel, CDmElement *pElement )
|
||
|
{
|
||
|
PanelType *pTypedPanel = static_cast< PanelType* >( pPanel );
|
||
|
ElementType *pTypedElement = static_cast< ElementType* >( pElement );
|
||
|
DisplayType *pDisplayElement = CastElement<DisplayType>( pTypedElement->GetDmePanelElement( m_pDisplayType ) );
|
||
|
pTypedPanel->SetDmeElement( pDisplayElement );
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
const char *m_pDisplayType;
|
||
|
};
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Helper macro to create the panel factory
|
||
|
// IMPLEMENT_DMEPANEL_FACTORY_OVERRIDE is used by applications to override
|
||
|
// DmePanels implemented in libraries
|
||
|
//-----------------------------------------------------------------------------
|
||
|
#define IMPLEMENT_DMEPANEL_FACTORY( _panelClassName, _dmeLookupName, _editorName, _editorDisplayName, _isDefault ) \
|
||
|
CDmePanelFactory< _panelClassName, C##_dmeLookupName > g_##_panelClassName##_##_dmeLookupName##_Factory( #_dmeLookupName, _editorName, _editorDisplayName, _isDefault, false ); \
|
||
|
_panelClassName *g_##_panelClassName##_##_dmeLookupName##LinkerHack = NULL;
|
||
|
|
||
|
#define IMPLEMENT_DMEPANEL_FACTORY_OVERRIDE( _panelClassName, _dmeLookupName, _editorName, _editorDisplayName, _isDefault ) \
|
||
|
CDmePanelFactory< _panelClassName, C##_dmeLookupName > g_##_panelClassName##_##_dmeLookupName##_Factory( #_dmeLookupName, _editorName, _editorDisplayName, _isDefault, true ); \
|
||
|
_panelClassName *g_##_panelClassName##_##_dmeLookupName##LinkerHack = NULL;
|
||
|
|
||
|
#define USING_DMEPANEL_FACTORY( _panelClassName, _dmeLookupName )\
|
||
|
class _panelClassName; \
|
||
|
extern _panelClassName *g_##_panelClassName##_##_dmeLookupName##LinkerHack; \
|
||
|
_panelClassName *g_##_panelClassName##_##_dmeLookupName##PullInModule = g_##_panelClassName##_##_dmeLookupName##LinkerHack;
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Helper macro to create the converter panel factory
|
||
|
// IMPLEMENT_DMEPANEL_CONVERSION_FACTORY_OVERRIDE is used by applications to override
|
||
|
// DmePanels implemented in libraries
|
||
|
//-----------------------------------------------------------------------------
|
||
|
#define IMPLEMENT_DMEPANEL_CONVERSION_FACTORY( _panelClassName, _dmeLookupName, _dmeDisplayName, _editorName, _editorDisplayName, _isDefault ) \
|
||
|
CDmePanelConverterFactory< _panelClassName, C##_dmeLookupName, C##_dmeDisplayName > g_##_panelClassName##_##_dmeLookupName##_Factory( #_dmeLookupName, #_dmeDisplayName, _editorName, _editorDisplayName, _isDefault, false ); \
|
||
|
_panelClassName *g_##_panelClassName##_##_dmeLookupName##LinkerHack = NULL;
|
||
|
|
||
|
#define IMPLEMENT_DMEPANEL_CONVERSION_FACTORY_OVERRIDE( _panelClassName, _dmeLookupName, _dmeDisplayName, _editorName, _editorDisplayName, _isDefault ) \
|
||
|
CDmePanelConverterFactory< _panelClassName, C##_dmeLookupName, C##_dmeDisplayName > g_##_panelClassName##_##_dmeLookupName##_Factory( #_dmeLookupName, #_dmeDisplayName, _editorName, _editorDisplayName, _isDefault, true ); \
|
||
|
_panelClassName *g_##_panelClassName##_##_dmeLookupName##LinkerHack = NULL;
|
||
|
|
||
|
#define USING_DMEPANEL_CONVERSION_FACTORY( _panelClassName, _dmeLookupName ) \
|
||
|
class _panelClassName; \
|
||
|
extern _panelClassName *g_##_panelClassName##_##_dmeLookupName##LinkerHack; \
|
||
|
_panelClassName *g_##_panelClassName##_##_dmeLookupName##PullInModule = g_##_panelClassName##_##_dmeLookupName##LinkerHack;
|
||
|
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Get Dme Factories for a particular element type
|
||
|
//-----------------------------------------------------------------------------
|
||
|
DmeFactoryHandle_t DmePanelFirstFactory( CDmElement *pElement = NULL );
|
||
|
DmeFactoryHandle_t DmePanelNextFactory( DmeFactoryHandle_t h, CDmElement *pElement = NULL );
|
||
|
const char *DmePanelFactoryName( DmeFactoryHandle_t h );
|
||
|
const char *DmePanelFactoryDisplayName( DmeFactoryHandle_t h );
|
||
|
const char *DmePanelFactoryElementType( DmeFactoryHandle_t h );
|
||
|
bool DmePanelFactoryIsDefault( DmeFactoryHandle_t h );
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Dme Panel factory methods
|
||
|
//-----------------------------------------------------------------------------
|
||
|
vgui::EditablePanel *CreateDmePanel( vgui::Panel *pParent, const char *pPanelName, CDmElement *pElement, const char *pEditorName = NULL );
|
||
|
|
||
|
|
||
|
#endif // DMEPANEL_H
|