diff options
Diffstat (limited to 'public/dme_controls/dmepanel.h')
| -rw-r--r-- | public/dme_controls/dmepanel.h | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/public/dme_controls/dmepanel.h b/public/dme_controls/dmepanel.h new file mode 100644 index 0000000..e26f0ee --- /dev/null +++ b/public/dme_controls/dmepanel.h @@ -0,0 +1,280 @@ +//========= 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 |