//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======// // // Purpose: base class for all element attribute panels // An attribute panel is a one line widget that can be used by a list // or tree control. // // $NoKeywords: $ // //=============================================================================// #ifndef BASEATTRIBUTEPANEL_H #define BASEATTRIBUTEPANEL_H #ifdef _WIN32 #pragma once #endif #include "datamodel/dmattribute.h" #include "datamodel/dmattributevar.h" #include "vgui_controls/Panel.h" #include "datamodel/dmehandle.h" #include "tier1/fmtstr.h" #define FirstColumnWidth 30 #define TypeColumnWidth 75 #define ColumnBorderWidth 2 #define PickerWidth 25 #define PickerHeight 13 //----------------------------------------------------------------------------- // Forward declarations //----------------------------------------------------------------------------- class CDmElement; class IDmNotify; class IElementPropertiesChoices; struct AttributeWidgetInfo_t; class CDmeEditorAttributeInfo; class CDmeEditorTypeDictionary; namespace vgui { class Label; } using namespace vgui; //----------------------------------------------------------------------------- // CBaseAttributePanel //----------------------------------------------------------------------------- class CBaseAttributePanel : public vgui::Panel { DECLARE_CLASS_SIMPLE( CBaseAttributePanel, vgui::Panel ); public: CBaseAttributePanel( vgui::Panel *pParent, const AttributeWidgetInfo_t &info ); virtual void PostConstructor(); virtual void PerformLayout(); virtual void SetFont( HFont font ); virtual void ApplySchemeSettings( IScheme *pScheme ); virtual void OnCreateDragData( KeyValues *msg ); void SetDirty( bool dirty ); bool GetDirty() const; bool IsAutoApply() const; // Sets/gets the attribute value template< class T > void SetAttributeValue( const T& value ); void SetAttributeValue( const char *pValue ); template< class T > const T& GetAttributeValue( ); // Helper to get/set the attribute value for elements CDmElement *GetAttributeValueElement(); void SetAttributeValueElement( CDmElement *pElement ); void SetAttributeValueFromString( const char *pString ); bool GetAttributeValueAsString( char *pBuf, int nLength ); // Returns the attribute type to edit DmAttributeType_t GetAttributeType() const; CDmAttribute *GetAttribute(); // Returns the editor info CDmeEditorTypeDictionary *GetEditorTypeDictionary(); CDmeEditorAttributeInfo *GetEditorInfo(); // Call this when the data changed IDmNotify *GetNotify(); protected: enum { HIDETYPE = 0x01, HIDEVALUE = 0x02, READONLY = 0x04, DIRTY = 0x08, AUTOAPPLY = 0x10, }; // Inherited classes must implement this virtual Panel *GetDataPanel() = 0; virtual void Apply() = 0; virtual void Refresh() = 0; // Methods to get/set column size int GetSizeForColumn( Panel *panel ); void SetColumnSize( Panel *panel, int width ); virtual void GetPickerBounds( int *x, int *y, int *w, int *h ); // Returns the element being edited by the panel CDmElement *GetPanelElement(); const CDmElement *GetPanelElement() const; // Returns the attribute name const char* GetAttributeName() const; // Does the element have the attribute we're attempting to reference? bool HasAttribute() const; // Returns the attribute array count int GetAttributeArrayCount() const; // Are we editing an entry in an attribute array? bool IsArrayEntry() const; // Is a particular flag set? bool HasFlag( int flagMask ) const; private: struct colinfo_t { Panel *panel; int width; }; // Set a flag void SetFlag( int flagMask, bool bOn ); // Used to sort the column list static bool ColInfoLessFunc( const colinfo_t& lhs, const colinfo_t& rhs ); // Initializes flags from the attribute editor info void InitializeFlags( const AttributeWidgetInfo_t &info ); // Called when the OK / Apply button is pressed. Changed data should be written into document. MESSAGE_FUNC( OnApplyChanges, "ApplyChanges" ); MESSAGE_FUNC( OnRefresh, "Refresh" ); protected: Label *m_pType; private: CDmeHandle< CDmElement > m_hObject; CDmeHandle< CDmeEditorAttributeInfo > m_hEditorInfo; CDmeHandle< CDmeEditorTypeDictionary > m_hEditorTypeDict; char m_szAttributeName[ 256 ]; int m_nArrayIndex; DmAttributeType_t m_AttributeType; IDmNotify *m_pNotify; int m_nFlags; CUtlRBTree< colinfo_t, int > m_ColumnSize; HFont m_hFont; }; //----------------------------------------------------------------------------- // Inline methods //----------------------------------------------------------------------------- inline bool CBaseAttributePanel::HasFlag( int flagMask ) const { return ( m_nFlags & flagMask ) ? true : false; } inline void CBaseAttributePanel::SetFlag( int flagMask, bool bOn ) { if ( bOn ) { m_nFlags |= flagMask; } else { m_nFlags &= ~flagMask; } } inline bool CBaseAttributePanel::GetDirty() const { return HasFlag( DIRTY ); } inline bool CBaseAttributePanel::IsAutoApply() const { return HasFlag( AUTOAPPLY ); } inline DmAttributeType_t CBaseAttributePanel::GetAttributeType() const { return m_AttributeType; } inline IDmNotify *CBaseAttributePanel::GetNotify() { return m_pNotify; } inline const char* CBaseAttributePanel::GetAttributeName() const { return m_szAttributeName; } inline bool CBaseAttributePanel::IsArrayEntry() const { return ( m_nArrayIndex >= 0 ); } template< class T > inline const T& GetArrayAttributeValue( CDmElement *pElement, const char *pAttribute, int nArrayIndex ) { const CDmrArray array( pElement, pAttribute ); return array[ nArrayIndex ]; } template<> inline const DmElementHandle_t& GetArrayAttributeValue( CDmElement *pElement, const char *pAttribute, int nArrayIndex ) { const CDmrElementArray<> array( pElement, pAttribute ); return array.GetHandle( nArrayIndex ); } template< class T > inline void SetArrayAttributeValue( CDmElement *pElement, const char *pAttribute, int nArrayIndex, const T& value ) { CDmrArray array( pElement, pAttribute ); array.Set( nArrayIndex, value ); } template<> inline void SetArrayAttributeValue( CDmElement *pElement, const char *pAttribute, int nArrayIndex, const DmElementHandle_t& value ) { CDmrElementArray<> array( pElement, pAttribute ); array.SetHandle( nArrayIndex, value ); } //----------------------------------------------------------------------------- // Sets/gets the attribute value //----------------------------------------------------------------------------- template< class T > void CBaseAttributePanel::SetAttributeValue( const T& value ) { CUndoScopeGuard sg( CFmtStr( "Set %s", m_szAttributeName ) ); if ( !IsArrayEntry() ) { GetPanelElement()->SetValue( m_szAttributeName, value ); } else { SetArrayAttributeValue( GetPanelElement(), m_szAttributeName, m_nArrayIndex, value ); } } inline void CBaseAttributePanel::SetAttributeValue( const char *pValue ) { CUndoScopeGuard sg( CFmtStr( "Set %s", m_szAttributeName ) ); if ( !IsArrayEntry() ) { GetPanelElement()->SetValue( m_szAttributeName, pValue ); } else { CUtlSymbolLarge symbol = g_pDataModel->GetSymbol( pValue ); SetArrayAttributeValue( GetPanelElement(), m_szAttributeName, m_nArrayIndex, symbol ); } } template< class T > const T& CBaseAttributePanel::GetAttributeValue( ) { CDmElement *pPanelElement = GetPanelElement(); if ( !pPanelElement ) { static T temp; CDmAttributeInfo::SetDefaultValue( temp ); return temp; } if ( !IsArrayEntry() ) return pPanelElement->GetValue( m_szAttributeName ); return GetArrayAttributeValue( pPanelElement, m_szAttributeName, m_nArrayIndex ); } //----------------------------------------------------------------------------- // Returns the panel element //----------------------------------------------------------------------------- inline CDmElement *CBaseAttributePanel::GetPanelElement() { return m_hObject; } inline const CDmElement *CBaseAttributePanel::GetPanelElement() const { return m_hObject; } #endif // BASEATTRIBUTEPANEL_H