summaryrefslogtreecommitdiff
path: root/public/dme_controls/dmepanel.h
diff options
context:
space:
mode:
Diffstat (limited to 'public/dme_controls/dmepanel.h')
-rw-r--r--public/dme_controls/dmepanel.h280
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