aboutsummaryrefslogtreecommitdiff
path: root/mp/src/vgui2/vgui_controls/Panel.cpp
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /mp/src/vgui2/vgui_controls/Panel.cpp
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/vgui2/vgui_controls/Panel.cpp')
-rw-r--r--mp/src/vgui2/vgui_controls/Panel.cpp16902
1 files changed, 8451 insertions, 8451 deletions
diff --git a/mp/src/vgui2/vgui_controls/Panel.cpp b/mp/src/vgui2/vgui_controls/Panel.cpp
index 7fb2e630..3f3634fe 100644
--- a/mp/src/vgui2/vgui_controls/Panel.cpp
+++ b/mp/src/vgui2/vgui_controls/Panel.cpp
@@ -1,8451 +1,8451 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-
-#include <stdio.h>
-#include <assert.h>
-#include <utlvector.h>
-#include <vstdlib/IKeyValuesSystem.h>
-#include <ctype.h> // isdigit()
-
-#include <materialsystem/imaterial.h>
-
-#include <vgui/IBorder.h>
-#include <vgui/IInput.h>
-#include <vgui/IPanel.h>
-#include <vgui/IScheme.h>
-#include <vgui/ISurface.h>
-#include <vgui/ISystem.h>
-#include <vgui/ILocalize.h>
-#include <vgui/IVGui.h>
-#include <KeyValues.h>
-#include <vgui/MouseCode.h>
-
-#include <vgui_controls/Panel.h>
-#include <vgui_controls/BuildGroup.h>
-#include <vgui_controls/Tooltip.h>
-#include <vgui_controls/PHandle.h>
-#include <vgui_controls/Controls.h>
-#include "vgui_controls/Menu.h"
-#include "vgui_controls/MenuItem.h"
-
-#include "UtlSortVector.h"
-
-#include "tier1/utldict.h"
-#include "tier1/utlbuffer.h"
-#include "mempool.h"
-#include "filesystem.h"
-#include "tier0/icommandline.h"
-
-#include "tier0/vprof.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include <tier0/memdbgon.h>
-
-using namespace vgui;
-
-#define TRIPLE_PRESS_MSEC 300
-
-
-extern int GetBuildModeDialogCount();
-
-static char *CopyString( const char *in )
-{
- if ( !in )
- return NULL;
-
- int len = strlen( in );
- char *n = new char[ len + 1 ];
- Q_strncpy( n, in, len + 1 );
- return n;
-}
-
-#if defined( VGUI_USEDRAGDROP )
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-struct vgui::DragDrop_t
-{
- DragDrop_t() :
- m_bDragEnabled( false ),
- m_bShowDragHelper( true ),
- m_bDropEnabled( false ),
- m_bDragStarted( false ),
- m_nDragStartTolerance( 8 ),
- m_bDragging( false ),
- m_lDropHoverTime( 0 ),
- m_bDropMenuShown( false ),
- m_bPreventChaining( false )
- {
- m_nStartPos[ 0 ] = m_nStartPos[ 1 ] = 0;
- m_nLastPos[ 0 ] = m_nLastPos[ 1 ] = 0;
- }
-
- // Drag related data
- bool m_bDragEnabled;
- bool m_bShowDragHelper;
- bool m_bDragging;
- bool m_bDragStarted;
- // How many pixels the dragged box must move before showing the outline rect...
- int m_nDragStartTolerance;
- int m_nStartPos[ 2 ];
- int m_nLastPos[ 2 ];
- CUtlVector< KeyValues * > m_DragData;
- CUtlVector< PHandle > m_DragPanels;
-
- // Drop related data
- bool m_bDropEnabled;
- // A droppable panel can have a hover context menu, which will show up after m_flHoverContextTime of hovering
- float m_flHoverContextTime;
-
- PHandle m_hCurrentDrop;
- // Amount of time hovering over current drop target
- long m_lDropHoverTime;
- bool m_bDropMenuShown;
- DHANDLE< Menu > m_hDropContextMenu;
-
- // Misc data
- bool m_bPreventChaining;
-};
-
-//-----------------------------------------------------------------------------
-// Purpose: Helper for painting to the full screen...
-//-----------------------------------------------------------------------------
-class CDragDropHelperPanel : public Panel
-{
- DECLARE_CLASS_SIMPLE( CDragDropHelperPanel, Panel );
-public:
- CDragDropHelperPanel();
-
- virtual VPANEL IsWithinTraverse(int x, int y, bool traversePopups);
- virtual void PostChildPaint();
-
- void AddPanel( Panel *current );
-
- void RemovePanel( Panel *search );
-
-private:
- struct DragHelperPanel_t
- {
- PHandle m_hPanel;
- };
-
- CUtlVector< DragHelperPanel_t > m_PaintList;
-};
-
-vgui::DHANDLE< CDragDropHelperPanel > s_DragDropHelper;
-#endif
-
-#if defined( VGUI_USEKEYBINDINGMAPS )
-
-BoundKey_t::BoundKey_t():
- isbuiltin( true ),
- bindingname( 0 ),
- keycode( KEY_NONE ),
- modifiers( 0 )
-{
-}
-
-BoundKey_t::BoundKey_t( const BoundKey_t& src )
-{
- isbuiltin = src.isbuiltin;
- bindingname = isbuiltin ? src.bindingname : CopyString( src.bindingname );
- keycode = src.keycode;
- modifiers = src.modifiers;
-}
-
-BoundKey_t& BoundKey_t::operator =( const BoundKey_t& src )
-{
- if ( this == &src )
- return *this;
- isbuiltin = src.isbuiltin;
- bindingname = isbuiltin ? src.bindingname : CopyString( src.bindingname );
- keycode = src.keycode;
- modifiers = src.modifiers;
- return *this;
-}
-
-
-BoundKey_t::~BoundKey_t()
-{
- if ( !isbuiltin )
- {
- delete[] bindingname;
- }
-}
-
-KeyBindingMap_t::KeyBindingMap_t() :
- bindingname( 0 ),
- func( 0 ),
- helpstring( 0 ),
- docstring( 0 ),
- passive( false )
-{
-}
-
-KeyBindingMap_t::KeyBindingMap_t( const KeyBindingMap_t& src )
-{
- bindingname = src.bindingname;
- helpstring = src.helpstring;
- docstring = src.docstring;
-
- func = src.func;
- passive = src.passive;
-}
-
-KeyBindingMap_t::~KeyBindingMap_t()
-{
-}
-
-class CKeyBindingsMgr
-{
-public:
-
- CKeyBindingsMgr() :
- m_Bindings( 0, 0, KeyBindingContextHandleLessFunc ),
- m_nKeyBindingContexts( 0 )
- {
- }
-
- struct KBContext_t
- {
- KBContext_t() :
- m_KeyBindingsFile( UTL_INVAL_SYMBOL ),
- m_KeyBindingsPathID( UTL_INVAL_SYMBOL )
- {
- m_Handle = INVALID_KEYBINDINGCONTEXT_HANDLE;
- }
-
- KBContext_t( const KBContext_t& src )
- {
- m_Handle = src.m_Handle;
- m_KeyBindingsFile = src.m_KeyBindingsFile;
- m_KeyBindingsPathID = src.m_KeyBindingsPathID;
- int c = src.m_Panels.Count();
- for ( int i = 0; i < c; ++i )
- {
- m_Panels.AddToTail( src.m_Panels[ i ] );
- }
- }
-
- KeyBindingContextHandle_t m_Handle;
- CUtlSymbol m_KeyBindingsFile;
- CUtlSymbol m_KeyBindingsPathID;
- CUtlVector< Panel * > m_Panels;
- };
-
- static bool KeyBindingContextHandleLessFunc( const KBContext_t& lhs, const KBContext_t& rhs )
- {
- return lhs.m_Handle < rhs.m_Handle;
- }
-
- KeyBindingContextHandle_t CreateContext( char const *filename, char const *pathID )
- {
- KBContext_t entry;
-
- entry.m_Handle = (KeyBindingContextHandle_t)++m_nKeyBindingContexts;
- entry.m_KeyBindingsFile = filename;
- if ( pathID )
- {
- entry.m_KeyBindingsPathID = pathID;
- }
- else
- {
- entry.m_KeyBindingsPathID = UTL_INVAL_SYMBOL;
- }
-
- m_Bindings.Insert( entry );
-
- return entry.m_Handle;
- }
-
- void AddPanelToContext( KeyBindingContextHandle_t handle, Panel *panel )
- {
- if ( !panel->GetName() || !panel->GetName()[ 0 ] )
- {
- Warning( "Can't add Keybindings Context for unnamed panels\n" );
- return;
- }
-
- KBContext_t *entry = Find( handle );
- Assert( entry );
- if ( entry )
- {
- int idx = entry->m_Panels.Find( panel );
- if ( idx == entry->m_Panels.InvalidIndex() )
- {
- entry->m_Panels.AddToTail( panel );
- }
- }
- }
-
- void OnPanelDeleted( KeyBindingContextHandle_t handle, Panel *panel )
- {
- KBContext_t *kb = Find( handle );
- if ( kb )
- {
- kb->m_Panels.FindAndRemove( panel );
- }
- }
-
- KBContext_t *Find( KeyBindingContextHandle_t handle )
- {
- KBContext_t search;
- search.m_Handle = handle;
- int idx = m_Bindings.Find( search );
- if ( idx == m_Bindings.InvalidIndex() )
- {
- return NULL;
- }
- return &m_Bindings[ idx ];
- }
-
- char const *GetKeyBindingsFile( KeyBindingContextHandle_t handle )
- {
- KBContext_t *kb = Find( handle );
- if ( kb )
- {
- return kb->m_KeyBindingsFile.String();
- }
- Assert( 0 );
- return "";
- }
-
- char const *GetKeyBindingsFilePathID( KeyBindingContextHandle_t handle )
- {
- KBContext_t *kb = Find( handle );
- if ( kb )
- {
- return kb->m_KeyBindingsPathID.String();
- }
- Assert( 0 );
- return NULL;
- }
-
- int GetPanelsWithKeyBindingsCount( KeyBindingContextHandle_t handle )
- {
- KBContext_t *kb = Find( handle );
- if ( kb )
- {
- return kb->m_Panels.Count();
- }
- Assert( 0 );
- return 0;
- }
-
- //-----------------------------------------------------------------------------
- // Purpose: static method
- // Input : index -
- // Output : Panel
- //-----------------------------------------------------------------------------
- Panel *GetPanelWithKeyBindings( KeyBindingContextHandle_t handle, int index )
- {
- KBContext_t *kb = Find( handle );
- if ( kb )
- {
- Assert( index >= 0 && index < kb->m_Panels.Count() );
- return kb->m_Panels[ index ];
- }
- Assert( 0 );
- return 0;
- }
-
- CUtlRBTree< KBContext_t, int > m_Bindings;
- int m_nKeyBindingContexts;
-};
-
-static CKeyBindingsMgr g_KBMgr;
-
-//-----------------------------------------------------------------------------
-// Purpose: Static method to allocate a context
-// Input : -
-// Output : KeyBindingContextHandle_t
-//-----------------------------------------------------------------------------
-KeyBindingContextHandle_t Panel::CreateKeyBindingsContext( char const *filename, char const *pathID /*=0*/ )
-{
- return g_KBMgr.CreateContext( filename, pathID );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: static method
-// Input : -
-// Output : int
-//-----------------------------------------------------------------------------
-int Panel::GetPanelsWithKeyBindingsCount( KeyBindingContextHandle_t handle )
-{
- return g_KBMgr.GetPanelsWithKeyBindingsCount( handle );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: static method
-// Input : index -
-// Output : Panel
-//-----------------------------------------------------------------------------
-Panel *Panel::GetPanelWithKeyBindings( KeyBindingContextHandle_t handle, int index )
-{
- return g_KBMgr.GetPanelWithKeyBindings( handle, index );
-}
-
-
-//-----------------------------------------------------------------------------
-// Returns the number of keybindings
-//-----------------------------------------------------------------------------
-int Panel::GetKeyMappingCount( )
-{
- int nCount = 0;
- PanelKeyBindingMap *map = GetKBMap();
- while ( map )
- {
- nCount += map->entries.Count();
- map = map->baseMap;
- }
- return nCount;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: static method. Reverts key bindings for all registered panels (panels with keybindings actually
-// loaded from file
-// Input : -
-//-----------------------------------------------------------------------------
-void Panel::RevertKeyBindings( KeyBindingContextHandle_t handle )
-{
- int c = GetPanelsWithKeyBindingsCount( handle );
- for ( int i = 0; i < c; ++i )
- {
- Panel *kbPanel = GetPanelWithKeyBindings( handle, i );
- Assert( kbPanel );
- kbPanel->RevertKeyBindingsToDefault();
- }
-}
-
-static void BufPrint( CUtlBuffer& buf, int level, char const *fmt, ... )
-{
- char string[ 2048 ];
- va_list argptr;
- va_start( argptr, fmt );
- _vsnprintf( string, sizeof( string ) - 1, fmt, argptr );
- va_end( argptr );
- string[ sizeof( string ) - 1 ] = 0;
-
- while ( --level >= 0 )
- {
- buf.Printf( " " );
- }
- buf.Printf( "%s", string );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : handle -
-//-----------------------------------------------------------------------------
-void Panel::SaveKeyBindings( KeyBindingContextHandle_t handle )
-{
- char const *filename = g_KBMgr.GetKeyBindingsFile( handle );
- char const *pathID = g_KBMgr.GetKeyBindingsFilePathID( handle );
-
- SaveKeyBindingsToFile( handle, filename, pathID );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: static method. Saves key binding files out for all keybindings
-// Input : -
-//-----------------------------------------------------------------------------
-void Panel::SaveKeyBindingsToFile( KeyBindingContextHandle_t handle, char const *filename, char const *pathID /*= 0*/ )
-{
- CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
-
- BufPrint( buf, 0, "keybindings\n" );
- BufPrint( buf, 0, "{\n" );
-
- int c = GetPanelsWithKeyBindingsCount( handle );
- for ( int i = 0; i < c; ++i )
- {
- Panel *kbPanel = GetPanelWithKeyBindings( handle, i );
- Assert( kbPanel );
- if ( !kbPanel )
- continue;
-
- Assert( kbPanel->GetName() );
- Assert( kbPanel->GetName()[ 0 ] );
-
- if ( !kbPanel->GetName() || !kbPanel->GetName()[ 0 ] )
- continue;
-
- BufPrint( buf, 1, "\"%s\"\n", kbPanel->GetName() );
- BufPrint( buf, 1, "{\n" );
-
- kbPanel->SaveKeyBindingsToBuffer( 2, buf );
-
- BufPrint( buf, 1, "}\n" );
- }
-
- BufPrint( buf, 0, "}\n" );
-
- if ( g_pFullFileSystem->FileExists( filename, pathID ) &&
- !g_pFullFileSystem->IsFileWritable( filename, pathID ) )
- {
- Warning( "Panel::SaveKeyBindings '%s' is read-only!!!\n", filename );
- }
-
- FileHandle_t h = g_pFullFileSystem->Open( filename, "wb", pathID );
- if ( FILESYSTEM_INVALID_HANDLE != h )
- {
- g_pFullFileSystem->Write( buf.Base(), buf.TellPut(), h );
- g_pFullFileSystem->Close( h );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : handle -
-// *panelOfInterest -
-//-----------------------------------------------------------------------------
-void Panel::LoadKeyBindingsForOnePanel( KeyBindingContextHandle_t handle, Panel *panelOfInterest )
-{
- if ( !panelOfInterest )
- return;
- if ( !panelOfInterest->GetName() )
- return;
- if ( !panelOfInterest->GetName()[ 0 ] )
- return;
-
- char const *filename = g_KBMgr.GetKeyBindingsFile( handle );
- char const *pathID = g_KBMgr.GetKeyBindingsFilePathID( handle );
-
- KeyValues *kv = new KeyValues( "keybindings" );
- if ( kv->LoadFromFile( g_pFullFileSystem, filename, pathID ) )
- {
- int c = GetPanelsWithKeyBindingsCount( handle );
- for ( int i = 0; i < c; ++i )
- {
- Panel *kbPanel = GetPanelWithKeyBindings( handle, i );
- Assert( kbPanel );
-
- char const *panelName = kbPanel->GetName();
- if ( !panelName )
- {
- continue;
- }
-
- if ( Q_stricmp( panelOfInterest->GetName(), panelName ) )
- continue;
-
- KeyValues *subKey = kv->FindKey( panelName, false );
- if ( !subKey )
- {
- Warning( "Panel::ReloadKeyBindings: Can't find entry for panel '%s'\n", panelName );
- continue;
- }
-
- kbPanel->ParseKeyBindings( subKey );
- }
- }
- kv->deleteThis();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: static method. Loads all key bindings again
-// Input : -
-//-----------------------------------------------------------------------------
-
-void Panel::ReloadKeyBindings( KeyBindingContextHandle_t handle )
-{
- char const *filename = g_KBMgr.GetKeyBindingsFile( handle );
- char const *pathID = g_KBMgr.GetKeyBindingsFilePathID( handle );
-
- KeyValues *kv = new KeyValues( "keybindings" );
- if ( kv->LoadFromFile( g_pFullFileSystem, filename, pathID ) )
- {
- int c = GetPanelsWithKeyBindingsCount( handle );
- for ( int i = 0; i < c; ++i )
- {
- Panel *kbPanel = GetPanelWithKeyBindings( handle, i );
- Assert( kbPanel );
-
- char const *panelName = kbPanel->GetName();
- if ( !panelName )
- {
- continue;
- }
-
- KeyValues *subKey = kv->FindKey( panelName, false );
- if ( !subKey )
- {
- Warning( "Panel::ReloadKeyBindings: Can't find entry for panel '%s'\n", panelName );
- continue;
- }
-
- kbPanel->ParseKeyBindings( subKey );
- }
- }
- kv->deleteThis();
-}
-#endif // VGUI_USEKEYBINDINGMAPS
-
-DECLARE_BUILD_FACTORY( Panel );
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-Panel::Panel()
-{
- Init(0, 0, 64, 24);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-Panel::Panel(Panel *parent)
-{
- Init(0, 0, 64, 24);
- SetParent(parent);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-Panel::Panel(Panel *parent, const char *panelName)
-{
- Init(0, 0, 64, 24);
- SetName(panelName);
- SetParent(parent);
- SetBuildModeEditable(true);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-Panel::Panel( Panel *parent, const char *panelName, HScheme scheme )
-{
- Init(0, 0, 64, 24);
- SetName(panelName);
- SetParent(parent);
- SetBuildModeEditable(true);
- SetScheme( scheme );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Setup
-//-----------------------------------------------------------------------------
-void Panel::Init( int x, int y, int wide, int tall )
-{
- _panelName = NULL;
- _tooltipText = NULL;
- _pinToSibling = NULL;
- m_hMouseEventHandler = NULL;
- _pinCornerToSibling = PIN_TOPLEFT;
- _pinToSiblingCorner = PIN_TOPLEFT;
-
- // get ourselves an internal panel
- _vpanel = ivgui()->AllocPanel();
- ipanel()->Init(_vpanel, this);
-
- SetPos(x, y);
- SetSize(wide, tall);
- _flags.SetFlag( NEEDS_LAYOUT | NEEDS_SCHEME_UPDATE | NEEDS_DEFAULT_SETTINGS_APPLIED );
- _flags.SetFlag( AUTODELETE_ENABLED | PAINT_BORDER_ENABLED | PAINT_BACKGROUND_ENABLED | PAINT_ENABLED );
-#if defined( VGUI_USEKEYBINDINGMAPS )
- _flags.SetFlag( ALLOW_CHAIN_KEYBINDING_TO_PARENT );
-#endif
- m_nPinDeltaX = m_nPinDeltaY = 0;
- m_nResizeDeltaX = m_nResizeDeltaY = 0;
- _autoResizeDirection = AUTORESIZE_NO;
- _pinCorner = PIN_TOPLEFT;
- _cursor = dc_arrow;
- _border = NULL;
- _buildGroup = UTLHANDLE_INVALID;
- _tabPosition = 0;
- m_iScheme = 0;
- m_bIsSilent = false;
- m_bParentNeedsCursorMoveEvents = false;
-
- _buildModeFlags = 0; // not editable or deletable in buildmode dialog by default
-
- m_pTooltips = NULL;
- m_bToolTipOverridden = false;
-
- m_flAlpha = 255.0f;
- m_nPaintBackgroundType = 0;
-
- //=============================================================================
- // HPE_BEGIN:
- // [tj] Default to rounding all corners (for draw style 2)
- //=============================================================================
- m_roundedCorners = PANEL_ROUND_CORNER_ALL;
- //=============================================================================
- // HPE_END
- //=============================================================================
-
- m_nBgTextureId1 = -1;
- m_nBgTextureId2 = -1;
- m_nBgTextureId3 = -1;
- m_nBgTextureId4 = -1;
-#if defined( VGUI_USEDRAGDROP )
- m_pDragDrop = new DragDrop_t;
-
-#endif
-
- m_lLastDoublePressTime = 0L;
-
-#if defined( VGUI_USEKEYBINDINGMAPS )
- m_hKeyBindingsContext = INVALID_KEYBINDINGCONTEXT_HANDLE;
-#endif
-
- REGISTER_COLOR_AS_OVERRIDABLE( _fgColor, "fgcolor_override" );
- REGISTER_COLOR_AS_OVERRIDABLE( _bgColor, "bgcolor_override" );
-
- m_bIsConsoleStylePanel = false;
- m_NavUp = NULL;
- m_NavDown = NULL;
- m_NavLeft = NULL;
- m_NavRight = NULL;
- m_NavToRelay = NULL;
- m_NavActivate = NULL;
- m_NavBack = NULL;
- m_sNavUpName = NULL;
- m_sNavDownName = NULL;
- m_sNavLeftName = NULL;
- m_sNavRightName = NULL;
- m_sNavToRelayName = NULL;
- m_sNavActivateName = NULL;
- m_sNavBackName = NULL;
-
- m_PassUnhandledInput = true;
- m_LastNavDirection = ND_NONE;
- m_bWorldPositionCurrentFrame = false;
- m_bForceStereoRenderToFrameBuffer = false;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Destructor
-//-----------------------------------------------------------------------------
-Panel::~Panel()
-{
- // @note Tom Bui: only cleanup if we've created it
- if ( !m_bToolTipOverridden )
- {
- if ( m_pTooltips )
- {
- delete m_pTooltips;
- }
- }
-#if defined( VGUI_USEKEYBINDINGMAPS )
- if ( IsValidKeyBindingsContext() )
- {
- g_KBMgr.OnPanelDeleted( m_hKeyBindingsContext, this );
- }
-#endif // VGUI_USEKEYBINDINGMAPS
-#if defined( VGUI_USEDRAGDROP )
- if ( m_pDragDrop->m_bDragging )
- {
- OnFinishDragging( false, (MouseCode)-1 );
- }
-#endif // VGUI_USEDRAGDROP
-
- _flags.ClearFlag( AUTODELETE_ENABLED );
- _flags.SetFlag( MARKED_FOR_DELETION );
-
- // remove panel from any list
- SetParent((VPANEL)NULL);
-
- // Stop our children from pointing at us, and delete them if possible
- while (ipanel()->GetChildCount(GetVPanel()))
- {
- VPANEL child = ipanel()->GetChild(GetVPanel(), 0);
- if (ipanel()->IsAutoDeleteSet(child))
- {
- ipanel()->DeletePanel(child);
- }
- else
- {
- ipanel()->SetParent(child, NULL);
- }
- }
-
- // delete VPanel
- ivgui()->FreePanel(_vpanel);
- // free our name
- delete [] _panelName;
-
- if ( _tooltipText && _tooltipText[0] )
- {
- delete [] _tooltipText;
- }
-
- delete [] _pinToSibling;
-
- _vpanel = NULL;
-#if defined( VGUI_USEDRAGDROP )
- delete m_pDragDrop;
-#endif // VGUI_USEDRAGDROP
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: fully construct this panel so its ready for use right now (i.e fonts loaded, colors set, default label text set, ...)
-//-----------------------------------------------------------------------------
-void Panel::MakeReadyForUse()
-{
-// PerformApplySchemeSettings();
- UpdateSiblingPin();
- surface()->SolveTraverse( GetVPanel(), true );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::SetName( const char *panelName )
-{
- // No change?
- if ( _panelName &&
- panelName &&
- !Q_strcmp( _panelName, panelName ) )
- {
- return;
- }
-
- if (_panelName)
- {
- delete [] _panelName;
- _panelName = NULL;
- }
-
- if (panelName)
- {
- int len = Q_strlen(panelName) + 1;
- _panelName = new char[ len ];
- Q_strncpy( _panelName, panelName, len );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: returns the given name of the panel
-//-----------------------------------------------------------------------------
-const char *Panel::GetName()
-{
- if (_panelName)
- return _panelName;
-
- return "";
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: returns the name of the module that this instance of panel was compiled into
-//-----------------------------------------------------------------------------
-const char *Panel::GetModuleName()
-{
- return vgui::GetControlsModuleName();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: returns the classname of the panel (as specified in the panelmaps)
-//-----------------------------------------------------------------------------
-const char *Panel::GetClassName()
-{
- // loop up the panel map name
- PanelMessageMap *panelMap = GetMessageMap();
- if ( panelMap )
- {
- return panelMap->pfnClassName();
- }
-
- return "Panel";
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::SetPos(int x, int y)
-{
- if (!CommandLine()->FindParm("-hushasserts"))
- {
- Assert( abs(x) < 32768 && abs(y) < 32768 );
- }
- ipanel()->SetPos(GetVPanel(), x, y);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::GetPos(int &x, int &y)
-{
- ipanel()->GetPos(GetVPanel(), x, y);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::SetSize(int wide, int tall)
-{
- Assert( abs(wide) < 32768 && abs(tall) < 32768 );
- ipanel()->SetSize(GetVPanel(), wide, tall);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::GetSize(int &wide, int &tall)
-{
- ipanel()->GetSize(GetVPanel(), wide, tall);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::SetBounds(int x, int y, int wide, int tall)
-{
- SetPos(x,y);
- SetSize(wide,tall);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::GetBounds(int &x, int &y, int &wide, int &tall)
-{
- GetPos(x, y);
- GetSize(wide, tall);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: returns safe handle to parent
-//-----------------------------------------------------------------------------
-VPANEL Panel::GetVParent()
-{
- if ( ipanel() )
- {
- return ipanel()->GetParent(GetVPanel());
- }
-
- return 0;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: returns a pointer to a controls version of a Panel pointer
-//-----------------------------------------------------------------------------
-Panel *Panel::GetParent()
-{
- // get the parent and convert it to a Panel *
- // this is OK, the hierarchy is guaranteed to be all from the same module, except for the root node
- // the root node always returns NULL when a GetParent() is done so everything is OK
- if ( ipanel() )
- {
- VPANEL parent = ipanel()->GetParent(GetVPanel());
- if (parent)
- {
- Panel *pParent = ipanel()->GetPanel(parent, GetControlsModuleName());
- Assert(!pParent || !strcmp(pParent->GetModuleName(), GetControlsModuleName()));
- return pParent;
- }
- }
-
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Screen size change notification handler
-//-----------------------------------------------------------------------------
-void Panel::OnScreenSizeChanged(int nOldWide, int nOldTall)
-{
- // post to all children
- for (int i = 0; i < ipanel()->GetChildCount(GetVPanel()); i++)
- {
- VPANEL child = ipanel()->GetChild(GetVPanel(), i);
- PostMessage(child, new KeyValues("OnScreenSizeChanged", "oldwide", nOldWide, "oldtall", nOldTall), NULL);
- }
-
- // make any currently fullsize window stay fullsize
- int x, y, wide, tall;
- GetBounds(x, y, wide, tall);
- int screenWide, screenTall;
- surface()->GetScreenSize(screenWide, screenTall);
- if (x == 0 && y == 0 && nOldWide == wide && tall == nOldTall)
- {
- // fullsize
- surface()->GetScreenSize(wide, tall);
- SetBounds(0, 0, wide, tall);
- }
-
- // panel needs to re-get it's scheme settings
- _flags.SetFlag( NEEDS_SCHEME_UPDATE );
-
- // invalidate our settings
- InvalidateLayout();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::SetVisible(bool state)
-{
- ipanel()->SetVisible(GetVPanel(), state);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-bool Panel::IsVisible()
-{
- if (ipanel())
- {
- return ipanel()->IsVisible(GetVPanel());
- }
-
- return false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::SetEnabled(bool state)
-{
- if (state != ipanel()->IsEnabled( GetVPanel()))
- {
- ipanel()->SetEnabled(GetVPanel(), state);
- InvalidateLayout(false);
- Repaint();
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-bool Panel::IsEnabled()
-{
- return ipanel()->IsEnabled(GetVPanel());
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-bool Panel::IsPopup()
-{
- return ipanel()->IsPopup(GetVPanel());
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::Repaint()
-{
- _flags.SetFlag( NEEDS_REPAINT );
- if (surface())
- {
- surface()->Invalidate(GetVPanel());
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::Think()
-{
- if (IsVisible())
- {
- // update any tooltips
- if (m_pTooltips)
- {
- m_pTooltips->PerformLayout();
- }
- if ( _flags.IsFlagSet( NEEDS_LAYOUT ) )
- {
- InternalPerformLayout();
- }
- }
-
- OnThink();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::PaintTraverse( bool repaint, bool allowForce )
-{
- if ( m_bWorldPositionCurrentFrame )
- {
- surface()->SolveTraverse( GetVPanel() );
- }
-
- if ( !IsVisible() )
- {
- return;
- }
-
- float oldAlphaMultiplier = surface()->DrawGetAlphaMultiplier();
- float newAlphaMultiplier = oldAlphaMultiplier * m_flAlpha * 1.0f/255.0f;
-
- if ( IsXbox() && !newAlphaMultiplier )
- {
- // xbox optimization not suitable for pc
- // xbox panels are compliant and can early out and not traverse their children
- // when they have no opacity
- return;
- }
-
- if ( !repaint &&
- allowForce &&
- _flags.IsFlagSet( NEEDS_REPAINT ) )
- {
- repaint = true;
- _flags.ClearFlag( NEEDS_REPAINT );
- }
-
- VPANEL vpanel = GetVPanel();
-
- bool bPushedViewport = false;
- if( GetForceStereoRenderToFrameBuffer() )
- {
- CMatRenderContextPtr pRenderContext( materials );
- if( pRenderContext->GetRenderTarget() )
- {
- surface()->PushFullscreenViewport();
- bPushedViewport = true;
- }
- }
-
- int clipRect[4];
- ipanel()->GetClipRect( vpanel, clipRect[0], clipRect[1], clipRect[2], clipRect[3] );
- if ( ( clipRect[2] <= clipRect[0] ) || ( clipRect[3] <= clipRect[1] ) )
- {
- repaint = false;
- }
-
- // set global alpha
- surface()->DrawSetAlphaMultiplier( newAlphaMultiplier );
-
- bool bBorderPaintFirst = _border ? _border->PaintFirst() : false;
-
- // draw the border first if requested to
- if ( bBorderPaintFirst && repaint && _flags.IsFlagSet( PAINT_BORDER_ENABLED ) && ( _border != null ) )
- {
- // Paint the border over the background with no inset
- surface()->PushMakeCurrent( vpanel, false );
- PaintBorder();
- surface()->PopMakeCurrent( vpanel );
- }
-
- if ( repaint )
- {
- // draw the background with no inset
- if ( _flags.IsFlagSet( PAINT_BACKGROUND_ENABLED ) )
- {
- surface()->PushMakeCurrent( vpanel, false );
- PaintBackground();
- surface()->PopMakeCurrent( vpanel );
- }
-
- // draw the front of the panel with the inset
- if ( _flags.IsFlagSet( PAINT_ENABLED ) )
- {
- surface()->PushMakeCurrent( vpanel, true );
- Paint();
- surface()->PopMakeCurrent( vpanel );
- }
- }
-
- // traverse and paint all our children
- CUtlVector< VPANEL > &children = ipanel()->GetChildren( vpanel );
- int childCount = children.Count();
- for (int i = 0; i < childCount; i++)
- {
- VPANEL child = children[ i ];
- bool bVisible = ipanel()->IsVisible( child );
-
- if ( surface()->ShouldPaintChildPanel( child ) )
- {
- if ( bVisible )
- {
- ipanel()->PaintTraverse( child, repaint, allowForce );
- }
- }
- else
- {
- // Invalidate the child panel so that it gets redrawn
- surface()->Invalidate( child );
-
- // keep traversing the tree, just don't allow anyone to paint after here
- if ( bVisible )
- {
- ipanel()->PaintTraverse( child, false, false );
- }
- }
- }
-
- // draw the border last
- if ( repaint )
- {
- if ( !bBorderPaintFirst && _flags.IsFlagSet( PAINT_BORDER_ENABLED ) && ( _border != null ) )
- {
- // Paint the border over the background with no inset
- surface()->PushMakeCurrent( vpanel, false );
- PaintBorder();
- surface()->PopMakeCurrent( vpanel );
- }
-
-#ifdef _DEBUG
- // IsBuildGroupEnabled recurses up all the parents and ends up being very expensive as it wanders all over memory
- if ( GetBuildModeDialogCount() && IsBuildGroupEnabled() ) //&& HasFocus() )
- {
- // outline all selected panels
- CUtlVector<PHandle> *controlGroup = _buildGroup->GetControlGroup();
- for (int i=0; i < controlGroup->Size(); ++i)
- {
- // outline all selected panels
- CUtlVector<PHandle> *controlGroup = _buildGroup->GetControlGroup();
- for (int i=0; i < controlGroup->Size(); ++i)
- {
- surface()->PushMakeCurrent( ((*controlGroup)[i].Get())->GetVPanel(), false );
- ((*controlGroup)[i].Get())->PaintBuildOverlay();
- surface()->PopMakeCurrent( ((*controlGroup)[i].Get())->GetVPanel() );
- }
-
- _buildGroup->DrawRulers();
- }
- }
-#endif
-
- // All of our children have painted, etc, now allow painting in top of them
- if ( _flags.IsFlagSet( POST_CHILD_PAINT_ENABLED ) )
- {
- surface()->PushMakeCurrent( vpanel, false );
- PostChildPaint();
- surface()->PopMakeCurrent( vpanel );
- }
- }
-
- surface()->DrawSetAlphaMultiplier( oldAlphaMultiplier );
-
- surface()->SwapBuffers( vpanel );
-
- if( bPushedViewport )
- {
- surface()->PopFullscreenViewport();
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::PaintBorder()
-{
- _border->Paint(GetVPanel());
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::PaintBackground()
-{
- int wide, tall;
- GetSize( wide, tall );
- if ( m_SkipChild.Get() && m_SkipChild->IsVisible() )
- {
- if ( GetPaintBackgroundType() == 2 )
- {
- int cornerWide, cornerTall;
- GetCornerTextureSize( cornerWide, cornerTall );
-
- Color col = GetBgColor();
- DrawHollowBox( 0, 0, wide, tall, col, 1.0f );
-
- wide -= 2 * cornerWide;
- tall -= 2 * cornerTall;
-
- FillRectSkippingPanel( GetBgColor(), cornerWide, cornerTall, wide, tall, m_SkipChild.Get() );
- }
- else
- {
- FillRectSkippingPanel( GetBgColor(), 0, 0, wide, tall, m_SkipChild.Get() );
- }
- }
- else
- {
- Color col = GetBgColor();
-
- switch ( m_nPaintBackgroundType )
- {
- default:
- case 0:
- {
- surface()->DrawSetColor(col);
- surface()->DrawFilledRect(0, 0, wide, tall);
- }
- break;
- case 1:
- {
- DrawTexturedBox( 0, 0, wide, tall, col, 1.0f );
- }
- break;
- case 2:
- {
- DrawBox( 0, 0, wide, tall, col, 1.0f );
- }
- break;
- case 3:
- {
- DrawBoxFade( 0, 0, wide, tall, col, 1.0f, 255, 0, true );
- }
- break;
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::Paint()
-{
- // empty on purpose
- // PaintBackground is painted and default behavior is for Paint to do nothing
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::PostChildPaint()
-{
- // Empty on purpose
- // This is called if _postChildPaintEnabled is true and allows painting to
- // continue on the surface after all of the panel's children have painted
- // themselves. Allows drawing an overlay on top of the children, etc.
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Draws a black rectangle around the panel.
-//-----------------------------------------------------------------------------
-void Panel::PaintBuildOverlay()
-{
- int wide,tall;
- GetSize(wide,tall);
- surface()->DrawSetColor(0, 0, 0, 255);
-
- surface()->DrawFilledRect(0,0,wide,2); //top
- surface()->DrawFilledRect(0,tall-2,wide,tall); //bottom
- surface()->DrawFilledRect(0,2,2,tall-2); //left
- surface()->DrawFilledRect(wide-2,2,wide,tall-2); //right
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Returns true if the panel's draw code will fully cover it's area
-//-----------------------------------------------------------------------------
-bool Panel::IsOpaque()
-{
- // FIXME: Add code to account for the 'SkipChild' functionality in Frame
- if ( IsVisible() && _flags.IsFlagSet( PAINT_BACKGROUND_ENABLED ) && ( _bgColor[3] == 255 ) )
- return true;
-
- return false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: returns true if the settings are aligned to the right of the screen
-//-----------------------------------------------------------------------------
-bool Panel::IsRightAligned()
-{
- return (_buildModeFlags & BUILDMODE_SAVE_XPOS_RIGHTALIGNED);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: returns true if the settings are aligned to the bottom of the screen
-//-----------------------------------------------------------------------------
-bool Panel::IsBottomAligned()
-{
- return (_buildModeFlags & BUILDMODE_SAVE_YPOS_BOTTOMALIGNED);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: sets the parent
-//-----------------------------------------------------------------------------
-void Panel::SetParent(Panel *newParent)
-{
- // Assert that the parent is from the same module as the child
- // FIXME: !!! work out how to handle this properly!
- // Assert(!newParent || !strcmp(newParent->GetModuleName(), GetControlsModuleName()));
-
- if (newParent)
- {
- SetParent(newParent->GetVPanel());
- }
- else
- {
- SetParent((VPANEL)NULL);
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::SetParent(VPANEL newParent)
-{
- if (newParent)
- {
- ipanel()->SetParent(GetVPanel(), newParent);
- }
- else
- {
- ipanel()->SetParent(GetVPanel(), NULL);
- }
-
- if (GetVParent() && !IsPopup())
- {
- SetProportional(ipanel()->IsProportional(GetVParent()));
-
- // most of the time KBInput == parents kbinput
- if (ipanel()->IsKeyBoardInputEnabled(GetVParent()) != IsKeyBoardInputEnabled())
- {
- SetKeyBoardInputEnabled(ipanel()->IsKeyBoardInputEnabled(GetVParent()));
- }
-
- if (ipanel()->IsMouseInputEnabled(GetVParent()) != IsMouseInputEnabled())
- {
- SetMouseInputEnabled(ipanel()->IsMouseInputEnabled(GetVParent()));
- }
- }
-
- UpdateSiblingPin();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::OnChildAdded(VPANEL child)
-{
- Assert( !_flags.IsFlagSet( IN_PERFORM_LAYOUT ) );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: default message handler
-//-----------------------------------------------------------------------------
-void Panel::OnSizeChanged(int newWide, int newTall)
-{
- InvalidateLayout(); // our size changed so force us to layout again
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: sets Z ordering - lower numbers are always behind higher z's
-//-----------------------------------------------------------------------------
-void Panel::SetZPos(int z)
-{
- ipanel()->SetZPos(GetVPanel(), z);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: sets Z ordering - lower numbers are always behind higher z's
-//-----------------------------------------------------------------------------
-int Panel::GetZPos()
-{
- return ( ipanel()->GetZPos( GetVPanel() ) );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: sets alpha modifier for panel and all child panels [0..255]
-//-----------------------------------------------------------------------------
-void Panel::SetAlpha(int alpha)
-{
- m_flAlpha = alpha;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: data accessor
-//-----------------------------------------------------------------------------
-int Panel::GetAlpha()
-{
- return (int)m_flAlpha;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Moves the panel to the front of the z-order
-//-----------------------------------------------------------------------------
-void Panel::MoveToFront(void)
-{
- // FIXME: only use ipanel() as per src branch?
- if (IsPopup())
- {
- surface()->BringToFront(GetVPanel());
- }
- else
- {
- ipanel()->MoveToFront(GetVPanel());
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Iterates up the hierarchy looking for a particular parent
-//-----------------------------------------------------------------------------
-bool Panel::HasParent(VPANEL potentialParent)
-{
- if (!potentialParent)
- return false;
-
- return ipanel()->HasParent(GetVPanel(), potentialParent);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Finds the index of a child panel by string name
-// Output : int - -1 if no panel of that name is found
-//-----------------------------------------------------------------------------
-int Panel::FindChildIndexByName(const char *childName)
-{
- for (int i = 0; i < GetChildCount(); i++)
- {
- Panel *pChild = GetChild(i);
- if (!pChild)
- continue;
-
- if (!stricmp(pChild->GetName(), childName))
- {
- return i;
- }
- }
-
- return -1;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Finds a child panel by string name
-// Output : Panel * - NULL if no panel of that name is found
-//-----------------------------------------------------------------------------
-Panel *Panel::FindChildByName(const char *childName, bool recurseDown)
-{
- for (int i = 0; i < GetChildCount(); i++)
- {
- Panel *pChild = GetChild(i);
- if (!pChild)
- continue;
-
- if (!V_stricmp(pChild->GetName(), childName))
- {
- return pChild;
- }
-
- if (recurseDown)
- {
- Panel *panel = pChild->FindChildByName(childName, recurseDown);
- if ( panel )
- {
- return panel;
- }
- }
- }
-
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Finds a sibling panel by name
-//-----------------------------------------------------------------------------
-Panel *Panel::FindSiblingByName(const char *siblingName)
-{
- if ( !GetVParent() )
- return NULL;
-
- int siblingCount = ipanel()->GetChildCount(GetVParent());
- for (int i = 0; i < siblingCount; i++)
- {
- VPANEL sibling = ipanel()->GetChild(GetVParent(), i);
- Panel *panel = ipanel()->GetPanel(sibling, GetControlsModuleName());
- if (!stricmp(panel->GetName(), siblingName))
- {
- return panel;
- }
- }
-
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Dispatches immediately a message to the parent
-//-----------------------------------------------------------------------------
-void Panel::CallParentFunction(KeyValues *message)
-{
- if (GetVParent())
- {
- ipanel()->SendMessage(GetVParent(), message, GetVPanel());
- }
- if (message)
- {
- message->deleteThis();
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: if set to true, panel automatically frees itself when parent is deleted
-//-----------------------------------------------------------------------------
-void Panel::SetAutoDelete( bool state )
-{
- _flags.SetFlag( AUTODELETE_ENABLED, state );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-bool Panel::IsAutoDeleteSet()
-{
- return _flags.IsFlagSet( AUTODELETE_ENABLED );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Just calls 'delete this'
-//-----------------------------------------------------------------------------
-void Panel::DeletePanel()
-{
- // Avoid re-entrancy
- _flags.SetFlag( MARKED_FOR_DELETION );
- _flags.ClearFlag( AUTODELETE_ENABLED );
- delete this;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: data accessor
-//-----------------------------------------------------------------------------
-HScheme Panel::GetScheme()
-{
- if (m_iScheme)
- {
- return m_iScheme; // return our internal scheme
- }
-
- if (GetVParent()) // recurse down the heirarchy
- {
- return ipanel()->GetScheme(GetVParent());
- }
-
- return scheme()->GetDefaultScheme();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: set the scheme to render this panel with by name
-//-----------------------------------------------------------------------------
-void Panel::SetScheme(const char *tag)
-{
- if (strlen(tag) > 0 && scheme()->GetScheme(tag)) // check the scheme exists
- {
- SetScheme(scheme()->GetScheme(tag));
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: set the scheme to render this panel with
-//-----------------------------------------------------------------------------
-void Panel::SetScheme(HScheme scheme)
-{
- if (scheme != m_iScheme)
- {
- m_iScheme = scheme;
-
- // This will cause the new scheme to be applied at a later point
-// InvalidateLayout( false, true );
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: returns the char of this panels hotkey
-//-----------------------------------------------------------------------------
-Panel *Panel::HasHotkey(wchar_t key)
-{
- return NULL;
-}
-
-#if defined( VGUI_USEDRAGDROP )
-static vgui::PHandle g_DragDropCapture;
-#endif // VGUI_USEDRAGDROP
-
-void Panel::InternalCursorMoved(int x, int y)
-{
-#if defined( VGUI_USEDRAGDROP )
- if ( g_DragDropCapture.Get() )
- {
- bool started = g_DragDropCapture->GetDragDropInfo()->m_bDragStarted;
-
- g_DragDropCapture->OnContinueDragging();
-
- if ( started )
- {
- bool isEscapeKeyDown = input()->IsKeyDown( KEY_ESCAPE );
- if ( isEscapeKeyDown )
- {
- g_DragDropCapture->OnFinishDragging( true, (MouseCode)-1, true );
- }
- return;
- }
- }
-#endif // VGUI_USEDRAGDROP
-
- if ( !ShouldHandleInputMessage() )
- return;
-
- if ( IsCursorNone() )
- return;
-
- if ( !IsMouseInputEnabled() )
- {
- return;
- }
-
- if (IsBuildGroupEnabled())
- {
- if ( _buildGroup->CursorMoved(x, y, this) )
- {
- return;
- }
- }
-
- if (m_pTooltips)
- {
- if ( _tooltipText )
- {
- m_pTooltips->SetText( _tooltipText );
- }
- m_pTooltips->ShowTooltip(this);
- }
-
- ScreenToLocal(x, y);
-
- OnCursorMoved(x, y);
-}
-
-void Panel::InternalCursorEntered()
-{
- if (IsCursorNone() || !IsMouseInputEnabled())
- return;
-
- if (IsBuildGroupEnabled())
- return;
-
- if (m_pTooltips)
- {
- m_pTooltips->ResetDelay();
-
- if ( _tooltipText )
- {
- m_pTooltips->SetText( _tooltipText );
- }
- m_pTooltips->ShowTooltip(this);
- }
-
- OnCursorEntered();
-}
-
-void Panel::InternalCursorExited()
-{
- if (IsCursorNone() || !IsMouseInputEnabled())
- return;
-
- if (IsBuildGroupEnabled())
- return;
-
- if (m_pTooltips)
- {
- m_pTooltips->HideTooltip();
- }
-
- OnCursorExited();
-}
-
-bool Panel::IsChildOfSurfaceModalPanel()
-{
- VPANEL appModalPanel = input()->GetAppModalSurface();
- if ( !appModalPanel )
- return true;
-
- if ( ipanel()->HasParent( GetVPanel(), appModalPanel ) )
- return true;
-
- return false;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool Panel::IsChildOfModalSubTree()
-{
- VPANEL subTree = input()->GetModalSubTree();
- if ( !subTree )
- return true;
-
- if ( HasParent( subTree ) )
- return true;
-
- return false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Checks to see if message is being subverted due to modal subtree logic
-// Input : -
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-static bool ShouldHandleInputMessage( VPANEL p )
-{
- // If there is not modal subtree, then always handle the msg
- if ( !input()->GetModalSubTree() )
- return true;
-
- // What state are we in?
- bool bChildOfModal = false;
- VPANEL subTree = input()->GetModalSubTree();
- if ( !subTree )
- {
- bChildOfModal = true;
- }
- else if ( ipanel()->HasParent( p, subTree ) )
- {
- bChildOfModal = true;
- }
-
- if ( input()->ShouldModalSubTreeReceiveMessages() )
- return bChildOfModal;
-
- return !bChildOfModal;
-}
-
-bool Panel::ShouldHandleInputMessage()
-{
- return ::ShouldHandleInputMessage( GetVPanel() );
-}
-
-void Panel::InternalMousePressed(int code)
-{
- long curtime = system()->GetTimeMillis();
- if ( IsTriplePressAllowed() )
- {
- long elapsed = curtime - m_lLastDoublePressTime;
- if ( elapsed < TRIPLE_PRESS_MSEC )
- {
- InternalMouseTriplePressed( code );
- return;
- }
- }
-
- // The menu system passively watches for mouse released messages so it
- // can clear any open menus if the release is somewhere other than on a menu
- Menu::OnInternalMousePressed( this, (MouseCode)code );
-
- if ( !ShouldHandleInputMessage() )
- return;
-
- if ( IsCursorNone() )
- return;
-
- if ( !IsMouseInputEnabled())
- {
-#if defined( VGUI_USEDRAGDROP )
- DragDropStartDragging();
-#endif
- return;
- }
-
- if (IsBuildGroupEnabled())
- {
- if ( _buildGroup->MousePressed((MouseCode)code, this) )
- {
- return;
- }
- }
-
- Panel *pMouseHandler = m_hMouseEventHandler.Get();
- if ( pMouseHandler )
- {
- pMouseHandler->OnMousePressed( (MouseCode)code );
- }
- else
- {
- OnMousePressed( (MouseCode)code );
- }
-
-#if defined( VGUI_USEDRAGDROP )
- DragDropStartDragging();
-#endif
-}
-
-void Panel::InternalMouseDoublePressed(int code)
-{
- m_lLastDoublePressTime = system()->GetTimeMillis();
-
- if ( !ShouldHandleInputMessage() )
- return;
-
- if ( IsCursorNone() )
- return;
-
- if ( !IsMouseInputEnabled())
- {
- return;
- }
-
- if (IsBuildGroupEnabled())
- {
- if ( _buildGroup->MouseDoublePressed((MouseCode)code, this) )
- {
- return;
- }
- }
-
- Panel *pMouseHandler = m_hMouseEventHandler.Get();
- if ( pMouseHandler )
- {
- pMouseHandler->OnMouseDoublePressed( (MouseCode)code );
- }
- else
- {
- OnMouseDoublePressed( (MouseCode)code );
- }
-}
-
-#if defined( VGUI_USEDRAGDROP )
-void Panel::SetStartDragWhenMouseExitsPanel( bool state )
-{
- _flags.SetFlag( DRAG_REQUIRES_PANEL_EXIT, state );
-}
-
-bool Panel::IsStartDragWhenMouseExitsPanel() const
-{
- return _flags.IsFlagSet( DRAG_REQUIRES_PANEL_EXIT );
-}
-#endif // VGUI_USEDRAGDROP
-
-void Panel::SetTriplePressAllowed( bool state )
-{
- _flags.SetFlag( TRIPLE_PRESS_ALLOWED, state );
-}
-
-bool Panel::IsTriplePressAllowed() const
-{
- return _flags.IsFlagSet( TRIPLE_PRESS_ALLOWED );
-}
-
-void Panel::InternalMouseTriplePressed( int code )
-{
- Assert( IsTriplePressAllowed() );
- m_lLastDoublePressTime = 0L;
-
- if ( !ShouldHandleInputMessage() )
- return;
-
- if ( IsCursorNone() )
- return;
-
- if ( !IsMouseInputEnabled())
- {
-#if defined( VGUI_USEDRAGDROP )
- DragDropStartDragging();
-#endif
- return;
- }
-
- if (IsBuildGroupEnabled())
- {
- return;
- }
-
- OnMouseTriplePressed((MouseCode)code);
-#if defined( VGUI_USEDRAGDROP )
- DragDropStartDragging();
-#endif
-}
-
-void Panel::InternalMouseReleased(int code)
-{
-#if defined( VGUI_USEDRAGDROP )
- if ( g_DragDropCapture.Get() )
- {
- bool started = g_DragDropCapture->GetDragDropInfo()->m_bDragStarted;
- g_DragDropCapture->OnFinishDragging( true, (MouseCode)code );
- if ( started )
- {
- return;
- }
- }
-#endif
-
- if ( !ShouldHandleInputMessage() )
- return;
-
- if ( IsCursorNone() )
- return;
-
- if ( !IsMouseInputEnabled())
- {
- return;
- }
-
- if (IsBuildGroupEnabled())
- {
- if ( _buildGroup->MouseReleased((MouseCode)code, this) )
- {
- return;
- }
- }
-
- OnMouseReleased((MouseCode)code);
-}
-
-void Panel::InternalMouseWheeled(int delta)
-{
- if (IsBuildGroupEnabled() || !IsMouseInputEnabled())
- {
- return;
- }
-
- if ( !ShouldHandleInputMessage() )
- return;
-
- OnMouseWheeled(delta);
-}
-
-void Panel::InternalKeyCodePressed(int code)
-{
- if ( !ShouldHandleInputMessage() )
- return;
-
- if (IsKeyBoardInputEnabled())
- {
- OnKeyCodePressed((KeyCode)code);
- }
- else
- {
- CallParentFunction(new KeyValues("KeyCodePressed", "code", code));
- }
-}
-
-#if defined( VGUI_USEKEYBINDINGMAPS )
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *bindingName -
-// keycode -
-// modifiers -
-//-----------------------------------------------------------------------------
-void Panel::AddKeyBinding( char const *bindingName, int keycode, int modifiers )
-{
- PanelKeyBindingMap *map = LookupMapForBinding( bindingName );
- if ( !map )
- {
- Assert( 0 );
- return;
- }
-
- BoundKey_t kb;
- kb.isbuiltin = false;
- kb.bindingname = CopyString( bindingName );
- kb.keycode = keycode;
- kb.modifiers = modifiers;
-
- map->boundkeys.AddToTail( kb );
-}
-
-KeyBindingMap_t *Panel::LookupBinding( char const *bindingName )
-{
- PanelKeyBindingMap *map = GetKBMap();
- while( map )
- {
- int c = map->entries.Count();
- for( int i = 0; i < c ; ++i )
- {
- KeyBindingMap_t *binding = &map->entries[ i ];
- if ( !Q_stricmp( binding->bindingname, bindingName ) )
- return binding;
- }
-
- map = map->baseMap;
- }
-
- return NULL;
-}
-
-PanelKeyBindingMap *Panel::LookupMapForBinding( char const *bindingName )
-{
- PanelKeyBindingMap *map = GetKBMap();
- while( map )
- {
- int c = map->entries.Count();
- for( int i = 0; i < c ; ++i )
- {
- KeyBindingMap_t *binding = &map->entries[ i ];
- if ( !Q_stricmp( binding->bindingname, bindingName ) )
- return map;
- }
-
- map = map->baseMap;
- }
-
- return NULL;
-}
-
-KeyBindingMap_t *Panel::LookupBindingByKeyCode( KeyCode code, int modifiers )
-{
- PanelKeyBindingMap *map = GetKBMap();
- while( map )
- {
- int c = map->boundkeys.Count();
- for( int i = 0; i < c ; ++i )
- {
- BoundKey_t *kb = &map->boundkeys[ i ];
- if ( kb->keycode == code && kb->modifiers == modifiers )
- {
- KeyBindingMap_t *binding = LookupBinding( kb->bindingname );
- Assert( binding );
- if ( binding )
- {
- return binding;
- }
- }
- }
-
- map = map->baseMap;
- }
-
- return NULL;
-}
-
-BoundKey_t *Panel::LookupDefaultKey( char const *bindingName )
-{
- PanelKeyBindingMap *map = GetKBMap();
- while( map )
- {
- int c = map->defaultkeys.Count();
- for( int i = 0; i < c ; ++i )
- {
- BoundKey_t *kb = &map->defaultkeys[ i ];
- if ( !Q_stricmp( kb->bindingname, bindingName ) )
- {
- return kb;
- }
- }
-
- map = map->baseMap;
- }
- return NULL;
-}
-
-void Panel::LookupBoundKeys( char const *bindingName, CUtlVector< BoundKey_t * >& list )
-{
- PanelKeyBindingMap *map = GetKBMap();
- while( map )
- {
- int c = map->boundkeys.Count();
- for( int i = 0; i < c ; ++i )
- {
- BoundKey_t *kb = &map->boundkeys[ i ];
- if ( !Q_stricmp( kb->bindingname, bindingName ) )
- {
- list.AddToTail( kb );
- }
- }
-
- map = map->baseMap;
- }
-}
-
-void Panel::RevertKeyBindingsToDefault()
-{
- PanelKeyBindingMap *map = GetKBMap();
- while( map )
- {
- map->boundkeys.RemoveAll();
- map->boundkeys = map->defaultkeys;
-
- map = map->baseMap;
- }
-}
-
-void Panel::RemoveAllKeyBindings()
-{
- PanelKeyBindingMap *map = GetKBMap();
- while( map )
- {
- map->boundkeys.RemoveAll();
- map = map->baseMap;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-//-----------------------------------------------------------------------------
-void Panel::ReloadKeyBindings()
-{
- RevertKeyBindingsToDefault();
- LoadKeyBindingsForOnePanel( GetKeyBindingsContext(), this );
-}
-
-#define MAKE_STRING( x ) #x
-#define KEY_NAME( str, disp ) { KEY_##str, MAKE_STRING( KEY_##str ), disp }
-
-struct KeyNames_t
-{
- KeyCode code;
- char const *string;
- char const *displaystring;
-};
-
-static KeyNames_t g_KeyNames[] =
-{
-KEY_NAME( NONE, "None" ),
-KEY_NAME( 0, "0" ),
-KEY_NAME( 1, "1" ),
-KEY_NAME( 2, "2" ),
-KEY_NAME( 3, "3" ),
-KEY_NAME( 4, "4" ),
-KEY_NAME( 5, "5" ),
-KEY_NAME( 6, "6" ),
-KEY_NAME( 7, "7" ),
-KEY_NAME( 8, "8" ),
-KEY_NAME( 9, "9" ),
-KEY_NAME( A, "A" ),
-KEY_NAME( B, "B" ),
-KEY_NAME( C, "C" ),
-KEY_NAME( D, "D" ),
-KEY_NAME( E, "E" ),
-KEY_NAME( F, "F" ),
-KEY_NAME( G, "G" ),
-KEY_NAME( H, "H" ),
-KEY_NAME( I, "I" ),
-KEY_NAME( J, "J" ),
-KEY_NAME( K, "K" ),
-KEY_NAME( L, "L" ),
-KEY_NAME( M, "M" ),
-KEY_NAME( N, "N" ),
-KEY_NAME( O, "O" ),
-KEY_NAME( P, "P" ),
-KEY_NAME( Q, "Q" ),
-KEY_NAME( R, "R" ),
-KEY_NAME( S, "S" ),
-KEY_NAME( T, "T" ),
-KEY_NAME( U, "U" ),
-KEY_NAME( V, "V" ),
-KEY_NAME( W, "W" ),
-KEY_NAME( X, "X" ),
-KEY_NAME( Y, "Y" ),
-KEY_NAME( Z, "Z" ),
-KEY_NAME( PAD_0, "Key Pad 0" ),
-KEY_NAME( PAD_1, "Key Pad 1" ),
-KEY_NAME( PAD_2, "Key Pad 2" ),
-KEY_NAME( PAD_3, "Key Pad 3" ),
-KEY_NAME( PAD_4, "Key Pad 4" ),
-KEY_NAME( PAD_5, "Key Pad 5" ),
-KEY_NAME( PAD_6, "Key Pad 6" ),
-KEY_NAME( PAD_7, "Key Pad 7" ),
-KEY_NAME( PAD_8, "Key Pad 8" ),
-KEY_NAME( PAD_9, "Key Pad 9" ),
-KEY_NAME( PAD_DIVIDE, "Key Pad /" ),
-KEY_NAME( PAD_MULTIPLY, "Key Pad *" ),
-KEY_NAME( PAD_MINUS, "Key Pad -" ),
-KEY_NAME( PAD_PLUS, "Key Pad +" ),
-KEY_NAME( PAD_ENTER, "Key Pad Enter" ),
-KEY_NAME( PAD_DECIMAL, "Key Pad ." ),
-KEY_NAME( LBRACKET, "[" ),
-KEY_NAME( RBRACKET, "]" ),
-KEY_NAME( SEMICOLON, "," ),
-KEY_NAME( APOSTROPHE, "'" ),
-KEY_NAME( BACKQUOTE, "`" ),
-KEY_NAME( COMMA, "," ),
-KEY_NAME( PERIOD, "." ),
-KEY_NAME( SLASH, "/" ),
-KEY_NAME( BACKSLASH, "\\" ),
-KEY_NAME( MINUS, "-" ),
-KEY_NAME( EQUAL, "=" ),
-KEY_NAME( ENTER, "Enter" ),
-KEY_NAME( SPACE, "Space" ),
-KEY_NAME( BACKSPACE, "Backspace" ),
-KEY_NAME( TAB, "Tab" ),
-KEY_NAME( CAPSLOCK, "Caps Lock" ),
-KEY_NAME( NUMLOCK, "Num Lock" ),
-KEY_NAME( ESCAPE, "Escape" ),
-KEY_NAME( SCROLLLOCK, "Scroll Lock" ),
-KEY_NAME( INSERT, "Ins" ),
-KEY_NAME( DELETE, "Del" ),
-KEY_NAME( HOME, "Home" ),
-KEY_NAME( END, "End" ),
-KEY_NAME( PAGEUP, "PgUp" ),
-KEY_NAME( PAGEDOWN, "PgDn" ),
-KEY_NAME( BREAK, "Break" ),
-KEY_NAME( LSHIFT, "Shift" ),
-KEY_NAME( RSHIFT, "Shift" ),
-KEY_NAME( LALT, "Alt" ),
-KEY_NAME( RALT, "Alt" ),
-KEY_NAME( LCONTROL, "Ctrl" ),
-KEY_NAME( RCONTROL, "Ctrl" ),
-KEY_NAME( LWIN, "Windows" ),
-KEY_NAME( RWIN, "Windows" ),
-KEY_NAME( APP, "App" ),
-KEY_NAME( UP, "Up" ),
-KEY_NAME( LEFT, "Left" ),
-KEY_NAME( DOWN, "Down" ),
-KEY_NAME( RIGHT, "Right" ),
-KEY_NAME( F1, "F1" ),
-KEY_NAME( F2, "F2" ),
-KEY_NAME( F3, "F3" ),
-KEY_NAME( F4, "F4" ),
-KEY_NAME( F5, "F5" ),
-KEY_NAME( F6, "F6" ),
-KEY_NAME( F7, "F7" ),
-KEY_NAME( F8, "F8" ),
-KEY_NAME( F9, "F9" ),
-KEY_NAME( F10, "F10" ),
-KEY_NAME( F11, "F11" ),
-KEY_NAME( F12, "F12" ),
-KEY_NAME( CAPSLOCKTOGGLE, "Caps Lock Toggle" ),
-KEY_NAME( NUMLOCKTOGGLE, "Num Lock Toggle" ),
-KEY_NAME( SCROLLLOCKTOGGLE, "Scroll Lock Toggle" ),
-};
-
-char const *Panel::KeyCodeToString( KeyCode code )
-{
- int c = ARRAYSIZE( g_KeyNames );
- for ( int i = 0; i < c ; ++i )
- {
- if ( g_KeyNames[ i ].code == code )
- return g_KeyNames[ i ].string;
- }
-
- return "";
-}
-
-wchar_t const *Panel::KeyCodeToDisplayString( KeyCode code )
-{
- int c = ARRAYSIZE( g_KeyNames );
- for ( int i = 0; i < c ; ++i )
- {
- if ( g_KeyNames[ i ].code == code )
- {
- char const *str = g_KeyNames[ i ].displaystring;
- wchar_t *wstr = g_pVGuiLocalize->Find( str );
- if ( wstr )
- {
- return wstr;
- }
-
- static wchar_t buf[ 64 ];
- g_pVGuiLocalize->ConvertANSIToUnicode( str, buf, sizeof( buf ) );
- return buf;
- }
- }
-
- return L"";
-}
-
-static void AddModifierToString( char const *modifiername, char *buf, size_t bufsize )
-{
- char add[ 32 ];
- if ( Q_strlen( buf ) > 0 )
- {
- Q_snprintf( add, sizeof( add ), "+%s", modifiername );
- }
- else
- {
- Q_strncpy( add, modifiername, sizeof( add ) );
- }
-
- Q_strncat( buf, add, bufsize, COPY_ALL_CHARACTERS );
-
-}
-
-wchar_t const *Panel::KeyCodeModifiersToDisplayString( KeyCode code, int modifiers )
-{
- char sz[ 256 ];
- sz[ 0 ] = 0;
-
- if ( modifiers & MODIFIER_SHIFT )
- {
- AddModifierToString( "Shift", sz, sizeof( sz ) );
- }
- if ( modifiers & MODIFIER_CONTROL )
- {
- AddModifierToString( "Ctrl", sz, sizeof( sz ) );
- }
- if ( modifiers & MODIFIER_ALT )
- {
- AddModifierToString( "Alt", sz, sizeof( sz ) );
- }
-
- if ( Q_strlen( sz ) > 0 )
- {
- Q_strncat( sz, "+", sizeof( sz ), COPY_ALL_CHARACTERS );
- }
-
- static wchar_t unicode[ 256 ];
- V_swprintf_safe( unicode, L"%S%s", sz, Panel::KeyCodeToDisplayString( (KeyCode)code ) );
- return unicode;
-}
-
-KeyCode Panel::StringToKeyCode( char const *str )
-{
- int c = ARRAYSIZE( g_KeyNames );
- for ( int i = 0; i < c ; ++i )
- {
- if ( !Q_stricmp( str, g_KeyNames[ i ].string ) )
- return g_KeyNames[ i ].code;
- }
-
- return KEY_NONE;
-}
-
-static void WriteKeyBindingToBuffer( CUtlBuffer& buf, int level, const BoundKey_t& binding )
-{
- BufPrint( buf, level, "\"keycode\"\t\"%s\"\n", Panel::KeyCodeToString( (KeyCode)binding.keycode ) );
- if ( binding.modifiers & MODIFIER_SHIFT )
- {
- BufPrint( buf, level, "\"shift\"\t\"1\"\n" );
- }
- if ( binding.modifiers & MODIFIER_CONTROL )
- {
- BufPrint( buf, level, "\"ctrl\"\t\"1\"\n" );
- }
- if ( binding.modifiers & MODIFIER_ALT )
- {
- BufPrint( buf, level, "\"alt\"\t\"1\"\n" );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *filename -
-// *pathID -
-//-----------------------------------------------------------------------------
-void Panel::SaveKeyBindingsToBuffer( int level, CUtlBuffer& buf )
-{
- Assert( IsValidKeyBindingsContext() );
-
- Assert( buf.IsText() );
-
- PanelKeyBindingMap *map = GetKBMap();
- while( map )
- {
- int c = map->boundkeys.Count();
- for( int i = 0; i < c ; ++i )
- {
- const BoundKey_t& binding = map->boundkeys[ i ];
-
- // Spew to file
- BufPrint( buf, level, "\"%s\"\n", binding.bindingname );
- BufPrint( buf, level, "{\n" );
-
- WriteKeyBindingToBuffer( buf, level + 1, binding );
-
- BufPrint( buf, level, "}\n" );
- }
-
- map = map->baseMap;
- }
-}
-
-bool Panel::ParseKeyBindings( KeyValues *kv )
-{
- Assert( IsValidKeyBindingsContext() );
- if ( !IsValidKeyBindingsContext() )
- return false;
-
- // To have KB the panel must have a name
- Assert( GetName() && GetName()[ 0 ] );
- if ( !GetName() || !GetName()[ 0 ] )
- return false;
-
- bool success = false;
-
- g_KBMgr.AddPanelToContext( GetKeyBindingsContext(), this );
-
- RemoveAllKeyBindings();
-
- // Walk through bindings
- for ( KeyValues *binding = kv->GetFirstSubKey(); binding != NULL; binding = binding->GetNextKey() )
- {
- char const *bindingName = binding->GetName();
- if ( !bindingName || !bindingName[ 0 ] )
- continue;
-
- KeyBindingMap_t *b = LookupBinding( bindingName );
- if ( b )
- {
- success = true;
- const char *keycode = binding->GetString( "keycode", "" );
- int modifiers = 0;
- if ( binding->GetInt( "shift", 0 ) != 0 )
- {
- modifiers |= MODIFIER_SHIFT;
- }
- if ( binding->GetInt( "ctrl", 0 ) != 0 )
- {
- modifiers |= MODIFIER_CONTROL;
- }
- if ( binding->GetInt( "alt", 0 ) != 0 )
- {
- modifiers |= MODIFIER_ALT;
- }
-
- KeyBindingMap_t *bound = LookupBindingByKeyCode( StringToKeyCode( keycode ), modifiers );
- if ( !bound )
- {
- AddKeyBinding( bindingName, StringToKeyCode( keycode ), modifiers );
- }
- }
- else
- {
- Warning( "KeyBinding for panel '%s' contained unknown binding '%s'\n", GetName() ? GetName() : "???", bindingName );
- }
- }
-
- // Now for each binding which is currently "unbound" to any key, use the default binding
- PanelKeyBindingMap *map = GetKBMap();
- while( map )
- {
- int c = map->entries.Count();
- for( int i = 0; i < c ; ++i )
- {
- KeyBindingMap_t *binding = &map->entries[ i ];
-
- // See if there is a bound key
- CUtlVector< BoundKey_t * > list;
- LookupBoundKeys( binding->bindingname, list );
- if ( list.Count() == 0 )
- {
- // Assign the default binding to this key
- BoundKey_t *defaultKey = LookupDefaultKey( binding->bindingname );
- if ( defaultKey )
- {
- KeyBindingMap_t *alreadyBound = LookupBindingByKeyCode( (KeyCode)defaultKey->keycode, defaultKey->modifiers );
- if ( alreadyBound )
- {
- Warning( "No binding for '%s', defautl key already bound to '%s'\n", binding->bindingname, alreadyBound->bindingname );
- }
- else
- {
- AddKeyBinding( defaultKey->bindingname, defaultKey->keycode, defaultKey->modifiers );
- }
- }
- }
- }
-
- map = map->baseMap;
- }
-
- return success;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : handle -
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-void Panel::SetKeyBindingsContext( KeyBindingContextHandle_t handle )
-{
- Assert( !IsValidKeyBindingsContext() || handle == GetKeyBindingsContext() );
- g_KBMgr.AddPanelToContext( handle, this );
- m_hKeyBindingsContext = handle;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-// Output : KeyBindingContextHandle_t
-//-----------------------------------------------------------------------------
-KeyBindingContextHandle_t Panel::GetKeyBindingsContext() const
-{
- return m_hKeyBindingsContext;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool Panel::IsValidKeyBindingsContext() const
-{
- return GetKeyBindingsContext() != INVALID_KEYBINDINGCONTEXT_HANDLE;
-}
-
-char const *Panel::GetKeyBindingsFile() const
-{
- Assert( IsValidKeyBindingsContext() );
- return g_KBMgr.GetKeyBindingsFile( GetKeyBindingsContext() );
-}
-
-char const *Panel::GetKeyBindingsFilePathID() const
-{
- Assert( IsValidKeyBindingsContext() );
- return g_KBMgr.GetKeyBindingsFilePathID( GetKeyBindingsContext() );
-}
-
-void Panel::EditKeyBindings()
-{
- Assert( 0 );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Set this to false to disallow IsKeyRebound chaining to GetParent() Panels...
-// Input : state -
-//-----------------------------------------------------------------------------
-void Panel::SetAllowKeyBindingChainToParent( bool state )
-{
- _flags.SetFlag( ALLOW_CHAIN_KEYBINDING_TO_PARENT, state );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool Panel::IsKeyBindingChainToParentAllowed() const
-{
- return _flags.IsFlagSet( ALLOW_CHAIN_KEYBINDING_TO_PARENT );
-}
-
-bool Panel::IsKeyOverridden( KeyCode code, int modifiers )
-{
- // By default assume all keys should pass through binding system
- return false;
-}
-
-bool Panel::IsKeyRebound( KeyCode code, int modifiers )
-{
- if ( IsKeyBoardInputEnabled() )
- {
- KeyBindingMap_t* binding = LookupBindingByKeyCode( code, modifiers );
- // Only dispatch if we're part of the current modal subtree
- if ( binding && IsChildOfSurfaceModalPanel() )
- {
- // Found match, post message to panel
- if ( binding->func )
- {
- // dispatch the func
- (this->*binding->func)();
- }
- else
- {
- Assert( 0 );
- }
-
- if ( !binding->passive )
- {
- // Exit this function...
- return true;
- }
- }
- }
-
- // Chain to parent
- Panel* pParent = GetParent();
- if ( IsKeyBindingChainToParentAllowed() && pParent && !IsKeyOverridden( code, modifiers ) )
- return pParent->IsKeyRebound( code, modifiers );
-
- // No suitable binding found
- return false;
-}
-
-static bool s_bSuppressRebindChecks = false;
-#endif // VGUI_USEKEYBINDINGMAPS
-
-void Panel::InternalKeyCodeTyped( int code )
-{
- if ( !ShouldHandleInputMessage() )
- {
- input()->OnKeyCodeUnhandled( code );
- return;
- }
-
- if (IsKeyBoardInputEnabled())
- {
- bool shift = (input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT));
- bool ctrl = (input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL));
- bool alt = (input()->IsKeyDown(KEY_LALT) || input()->IsKeyDown(KEY_RALT));
-
- int modifiers = 0;
- if ( shift )
- {
- modifiers |= MODIFIER_SHIFT;
- }
- if ( ctrl )
- {
- modifiers |= MODIFIER_CONTROL;
- }
- if ( alt )
- {
- modifiers |= MODIFIER_ALT;
- }
-
- // Things in build mode don't have accelerators
- if (IsBuildGroupEnabled())
- {
- _buildGroup->KeyCodeTyped((KeyCode)code, this);
- return;
- }
-
- if ( !s_bSuppressRebindChecks && IsKeyRebound( (KeyCode)code, modifiers ) )
- {
- return;
- }
-
- bool oldVal = s_bSuppressRebindChecks;
- s_bSuppressRebindChecks = true;
- OnKeyCodeTyped((KeyCode)code);
- s_bSuppressRebindChecks = oldVal;
- }
- else
- {
- if ( GetVPanel() == surface()->GetEmbeddedPanel() )
- {
- input()->OnKeyCodeUnhandled( code );
- }
- CallParentFunction(new KeyValues("KeyCodeTyped", "code", code));
- }
-}
-
-void Panel::InternalKeyTyped(int unichar)
-{
- if ( !ShouldHandleInputMessage() )
- return;
-
- if (IsKeyBoardInputEnabled())
- {
- if ( IsBuildGroupEnabled() )
- {
- if ( _buildGroup->KeyTyped( (wchar_t)unichar, this ) )
- {
- return;
- }
- }
-
- OnKeyTyped((wchar_t)unichar);
- }
- else
- {
- CallParentFunction(new KeyValues("KeyTyped", "unichar", unichar));
- }
-}
-
-void Panel::InternalKeyCodeReleased(int code)
-{
- if ( !ShouldHandleInputMessage() )
- return;
-
- if (IsKeyBoardInputEnabled())
- {
- if (IsBuildGroupEnabled())
- {
- if ( _buildGroup->KeyCodeReleased((KeyCode)code, this) )
- {
- return;
- }
- }
-
- OnKeyCodeReleased((KeyCode)code);
- }
- else
- {
- CallParentFunction(new KeyValues("KeyCodeReleased", "code", code));
- }
-}
-
-void Panel::InternalKeyFocusTicked()
-{
- if (IsBuildGroupEnabled())
- return;
-
- OnKeyFocusTicked();
-}
-
-void Panel::InternalMouseFocusTicked()
-{
- if (IsBuildGroupEnabled())
- {
- // must repaint so the numbers will be accurate
- if (_buildGroup->HasRulersOn())
- {
- PaintTraverse(true);
- }
- return;
- }
-
- // update cursor
- InternalSetCursor();
- OnMouseFocusTicked();
-}
-
-
-void Panel::InternalSetCursor()
-{
- bool visible = IsVisible();
-
- if (visible)
- {
-#if defined( VGUI_USEDRAGDROP )
- // Drag drop is overriding cursor?
- if ( m_pDragDrop->m_bDragging ||
- g_DragDropCapture.Get() != NULL )
- return;
-#endif
- // chain up and make sure all our parents are also visible
- VPANEL p = GetVParent();
- while (p)
- {
- visible &= ipanel()->IsVisible(p);
- p = ipanel()->GetParent(p);
- }
-
- // only change the cursor if this panel is visible, and if its part of the main VGUI tree
- if (visible && HasParent(surface()->GetEmbeddedPanel()))
- {
- HCursor cursor = GetCursor();
-
- if (IsBuildGroupEnabled())
- {
- cursor = _buildGroup->GetCursor(this);
- }
-
- if (input()->GetCursorOveride())
- {
- cursor = input()->GetCursorOveride();
- }
-
- surface()->SetCursor(cursor);
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Called every frame the panel is visible, designed to be overridden
-//-----------------------------------------------------------------------------
-void Panel::OnThink()
-{
-#if defined( VGUI_USEDRAGDROP )
- if ( IsPC() &&
- m_pDragDrop->m_bDragEnabled &&
- m_pDragDrop->m_bDragging &&
- m_pDragDrop->m_bDragStarted )
- {
- bool isEscapeKeyDown = input()->IsKeyDown( KEY_ESCAPE );
- if ( isEscapeKeyDown )
- {
- OnContinueDragging();
- OnFinishDragging( true, (MouseCode)-1, true );
- return;
- }
-
- if ( m_pDragDrop->m_hCurrentDrop != 0 )
- {
- if ( !input()->IsMouseDown( MOUSE_LEFT ) )
- {
- OnContinueDragging();
- OnFinishDragging( true, (MouseCode)-1 );
- return;
- }
-
- // allow the cursor to change based upon things like changing keystate, etc.
- surface()->SetCursor( m_pDragDrop->m_hCurrentDrop->GetDropCursor( m_pDragDrop->m_DragData ) );
-
- if ( !m_pDragDrop->m_bDropMenuShown )
- {
- // See if the hover time has gotten larger
- float hoverSeconds = ( system()->GetTimeMillis() - m_pDragDrop->m_lDropHoverTime ) * 0.001f;
- DragDrop_t *dropInfo = m_pDragDrop->m_hCurrentDrop->GetDragDropInfo();
-
- if ( dropInfo->m_flHoverContextTime != 0.0f )
- {
- if ( hoverSeconds >= dropInfo->m_flHoverContextTime )
- {
- m_pDragDrop->m_bDropMenuShown = true;
-
- CUtlVector< KeyValues * > data;
-
- GetDragData( data );
-
- int x, y;
- input()->GetCursorPos( x, y );
-
- if ( m_pDragDrop->m_hDropContextMenu.Get() )
- {
- delete m_pDragDrop->m_hDropContextMenu.Get();
- }
-
- Menu *menu = new Menu( m_pDragDrop->m_hCurrentDrop.Get(), "DropContext" );
-
- bool useMenu = m_pDragDrop->m_hCurrentDrop->GetDropContextMenu( menu, data );
- if ( useMenu )
- {
- m_pDragDrop->m_hDropContextMenu = menu;
-
- menu->SetPos( x, y );
- menu->SetVisible( true );
- menu->MakePopup();
- surface()->MovePopupToFront( menu->GetVPanel() );
- if ( menu->GetItemCount() > 0 )
- {
- int id = menu->GetMenuID( 0 );
- menu->SetCurrentlyHighlightedItem( id );
- MenuItem *item = menu->GetMenuItem( id );
- item->SetArmed( true );
- }
- }
- else
- {
- delete menu;
- }
-
- m_pDragDrop->m_hCurrentDrop->OnDropContextHoverShow( data );
- }
- }
- }
- }
- }
-#endif
-}
-
-// input messages handlers (designed for override)
-void Panel::OnCursorMoved(int x, int y)
-{
- if( ParentNeedsCursorMoveEvents() )
- {
- // figure out x and y in parent space
- int thisX, thisY;
- ipanel()->GetPos( GetVPanel(), thisX, thisY );
- CallParentFunction( new KeyValues( "OnCursorMoved", "x", x + thisX, "y", y + thisY ) );
- }
-}
-
-void Panel::OnCursorEntered()
-{
-}
-
-void Panel::OnCursorExited()
-{
-}
-
-void Panel::OnMousePressed(MouseCode code)
-{
-}
-
-void Panel::OnMouseDoublePressed(MouseCode code)
-{
-}
-
-void Panel::OnMouseTriplePressed(MouseCode code)
-{
-}
-
-void Panel::OnMouseReleased(MouseCode code)
-{
-}
-
-void Panel::OnMouseWheeled(int delta)
-{
- CallParentFunction(new KeyValues("MouseWheeled", "delta", delta));
-}
-
-// base implementation forwards Key messages to the Panel's parent - override to 'swallow' the input
-void Panel::OnKeyCodePressed(KeyCode code)
-{
- static ConVarRef vgui_nav_lock( "vgui_nav_lock" );
-
- bool handled = false;
- switch( GetBaseButtonCode( code ) )
- {
- case KEY_XBUTTON_UP:
- case KEY_XSTICK1_UP:
- case KEY_XSTICK2_UP:
- case KEY_UP:
- if ( ( !vgui_nav_lock.IsValid() || vgui_nav_lock.GetInt() == 0 ) && NavigateUp() )
- {
- vgui_nav_lock.SetValue( 1 );
- vgui::surface()->PlaySound( "UI/menu_focus.wav" );
- handled = true;
- }
- break;
- case KEY_XBUTTON_DOWN:
- case KEY_XSTICK1_DOWN:
- case KEY_XSTICK2_DOWN:
- case KEY_DOWN:
- if ( ( !vgui_nav_lock.IsValid() || vgui_nav_lock.GetInt() == 0 ) && NavigateDown() )
- {
- vgui_nav_lock.SetValue( 1 );
- vgui::surface()->PlaySound( "UI/menu_focus.wav" );
- handled = true;
- }
- break;
- case KEY_XBUTTON_LEFT:
- case KEY_XSTICK1_LEFT:
- case KEY_XSTICK2_LEFT:
- case KEY_LEFT:
- if ( ( !vgui_nav_lock.IsValid() || vgui_nav_lock.GetInt() == 0 ) && NavigateLeft() )
- {
- vgui_nav_lock.SetValue( 1 );
- vgui::surface()->PlaySound( "UI/menu_focus.wav" );
- handled = true;
- }
- break;
- case KEY_XBUTTON_RIGHT:
- case KEY_XSTICK1_RIGHT:
- case KEY_XSTICK2_RIGHT:
- case KEY_RIGHT:
- if ( ( !vgui_nav_lock.IsValid() || vgui_nav_lock.GetInt() == 0 ) && NavigateRight() )
- {
- vgui_nav_lock.SetValue( 1 );
- vgui::surface()->PlaySound( "UI/menu_focus.wav" );
- handled = true;
- }
- break;
- case KEY_XBUTTON_B:
- if ( ( !vgui_nav_lock.IsValid() || vgui_nav_lock.GetInt() == 0 ) && NavigateBack() )
- {
- vgui_nav_lock.SetValue( 1 );
- vgui::surface()->PlaySound( "UI/menu_focus.wav" );
- handled = true;
- }
- break;
- }
-
- if( !handled && !m_PassUnhandledInput )
- return;
-
- CallParentFunction(new KeyValues("KeyCodePressed", "code", code));
-}
-
-void Panel::OnKeyCodeTyped(KeyCode keycode)
-{
- vgui::KeyCode code = GetBaseButtonCode( keycode );
-
- // handle focus change
- if ( IsX360() || IsConsoleStylePanel() )
- {
- // eat these typed codes, will get handled in OnKeyCodePressed
- switch ( code )
- {
- case KEY_XBUTTON_UP:
- case KEY_XSTICK1_UP:
- case KEY_XSTICK2_UP:
- case KEY_XBUTTON_DOWN:
- case KEY_XSTICK1_DOWN:
- case KEY_XSTICK2_DOWN:
- case KEY_XBUTTON_LEFT:
- case KEY_XSTICK1_LEFT:
- case KEY_XSTICK2_LEFT:
- case KEY_XBUTTON_RIGHT:
- case KEY_XSTICK1_RIGHT:
- case KEY_XSTICK2_RIGHT:
- case KEY_XBUTTON_A:
- case KEY_XBUTTON_B:
- case KEY_XBUTTON_X:
- case KEY_XBUTTON_Y:
- case KEY_XBUTTON_LEFT_SHOULDER:
- case KEY_XBUTTON_RIGHT_SHOULDER:
- case KEY_XBUTTON_BACK:
- case KEY_XBUTTON_START:
- case KEY_XBUTTON_STICK1:
- case KEY_XBUTTON_STICK2:
- case KEY_XBUTTON_LTRIGGER:
- case KEY_XBUTTON_RTRIGGER:
-
- case KEY_UP:
- case KEY_DOWN:
- case KEY_LEFT:
- case KEY_RIGHT:
- return;
- }
-
- // legacy handling - need to re-enable for older apps?
- /*
- if ( code == KEY_XSTICK1_RIGHT || code == KEY_XBUTTON_RIGHT )
- {
- RequestFocusNext();
- return;
- }
- else if ( code == KEY_XSTICK1_LEFT || code == KEY_XBUTTON_LEFT )
- {
- RequestFocusPrev();
- return;
- }
- */
- }
-
- if (code == KEY_TAB)
- {
- bool bShiftDown = input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT);
-
- if ( IsConsoleStylePanel() )
- {
- if ( bShiftDown )
- {
- NavigateUp();
- }
- else
- {
- NavigateDown();
- }
- }
- else
- {
- // if shift is down goto previous tab position, otherwise goto next
- if ( bShiftDown )
- {
- RequestFocusPrev();
- }
- else
- {
- RequestFocusNext();
- }
- }
- }
- else
- {
- // forward up
- if ( GetVPanel() == surface()->GetEmbeddedPanel() )
- {
- input()->OnKeyCodeUnhandled( keycode );
- }
- CallParentFunction(new KeyValues("KeyCodeTyped", "code", keycode));
- }
-}
-
-void Panel::OnKeyTyped(wchar_t unichar)
-{
- CallParentFunction(new KeyValues("KeyTyped", "unichar", unichar));
-}
-
-void Panel::OnKeyCodeReleased(KeyCode code)
-{
- CallParentFunction(new KeyValues("KeyCodeReleased", "code", code));
-}
-
-void Panel::OnKeyFocusTicked()
-{
- CallParentFunction(new KeyValues("KeyFocusTicked"));
-}
-
-void Panel::OnMouseFocusTicked()
-{
- CallParentFunction(new KeyValues("OnMouseFocusTicked"));
-}
-
-bool Panel::IsWithin(int x,int y)
-{
- // check against our clip rect
- int clipRect[4];
- ipanel()->GetClipRect(GetVPanel(), clipRect[0], clipRect[1], clipRect[2], clipRect[3]);
-
- if (x < clipRect[0])
- {
- return false;
- }
-
- if (y < clipRect[1])
- {
- return false;
- }
-
- if (x >= clipRect[2])
- {
- return false;
- }
-
- if (y >= clipRect[3])
- {
- return false;
- }
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: determines which is the topmost panel under the coordinates (x, y)
-//-----------------------------------------------------------------------------
-VPANEL Panel::IsWithinTraverse(int x, int y, bool traversePopups)
-{
- // if this one is not visible, its children won't be either
- // also if it doesn't want mouse input its children can't get it either
- if (!IsVisible() || !IsMouseInputEnabled())
- return NULL;
-
- if (traversePopups)
- {
- // check popups first
- int i;
- CUtlVector< VPANEL > &children = ipanel()->GetChildren( GetVPanel() );
- int childCount = children.Count();
- for (i = childCount - 1; i >= 0; i--)
- {
- VPANEL panel = children[ i ];
- if (ipanel()->IsPopup(panel))
- {
- panel = ipanel()->IsWithinTraverse(panel, x, y, true);
- if (panel != null)
- {
- return panel;
- }
- }
- }
-
- // check children recursive, if you find one, just return first one
- // this checks in backwards order so the last child drawn for this panel is chosen which
- // coincides to how it would be visibly displayed
- for (i = childCount - 1; i >= 0; i--)
- {
- VPANEL panel = children[ i ];
- // we've already checked popups so ignore
- if (!ipanel()->IsPopup(panel))
- {
- panel = ipanel()->IsWithinTraverse(panel, x, y, true);
- if (panel != 0)
- {
- return panel;
- }
- }
- }
-
- // check ourself
- if ( !IsMouseInputDisabledForThisPanel() && IsWithin(x, y) )
- {
- return GetVPanel();
- }
- }
- else
- {
- // since we're not checking popups, it must be within us, so we can check ourself first
- if (IsWithin(x, y))
- {
- // check children recursive, if you find one, just return first one
- // this checks in backwards order so the last child drawn for this panel is chosen which
- // coincides to how it would be visibly displayed
- CUtlVector< VPANEL > &children = ipanel()->GetChildren( GetVPanel() );
- int childCount = children.Count();
- for (int i = childCount - 1; i >= 0; i--)
- {
- VPANEL panel = children[ i ];
- // ignore popups
- if (!ipanel()->IsPopup(panel))
- {
- panel = ipanel()->IsWithinTraverse(panel, x, y, false);
- if (panel != 0)
- {
- return panel;
- }
- }
- }
-
- // not a child, must be us
- if ( !IsMouseInputDisabledForThisPanel() )
- return GetVPanel();
- }
- }
-
- return NULL;
-}
-
-void Panel::LocalToScreen(int& x,int& y)
-{
- int px, py;
- ipanel()->GetAbsPos(GetVPanel(), px, py);
-
- x = x + px;
- y = y + py;
-}
-
-void Panel::ScreenToLocal(int& x,int& y)
-{
- int px, py;
- ipanel()->GetAbsPos(GetVPanel(), px, py);
-
- x = x - px;
- y = y - py;
-}
-
-void Panel::ParentLocalToScreen(int &x, int &y)
-{
- int px, py;
- ipanel()->GetAbsPos(GetVParent(), px, py);
-
- x = x + px;
- y = y + py;
-}
-
-void Panel::MakePopup(bool showTaskbarIcon,bool disabled)
-{
- surface()->CreatePopup(GetVPanel(), false, showTaskbarIcon,disabled);
-}
-
-void Panel::SetCursor(HCursor cursor)
-{
- _cursor = cursor;
-}
-
-HCursor Panel::GetCursor()
-{
- return _cursor;
-}
-
-void Panel::SetCursorAlwaysVisible( bool visible )
-{
- surface()->SetCursorAlwaysVisible( visible );
-}
-
-void Panel::SetMinimumSize(int wide,int tall)
-{
- ipanel()->SetMinimumSize(GetVPanel(), wide, tall);
-}
-
-void Panel::GetMinimumSize(int& wide,int &tall)
-{
- ipanel()->GetMinimumSize(GetVPanel(), wide, tall);
-}
-
-bool Panel::IsBuildModeEditable()
-{
- return true;
-}
-
-void Panel::SetBuildModeEditable(bool state)
-{
- if (state)
- {
- _buildModeFlags |= BUILDMODE_EDITABLE;
- }
- else
- {
- _buildModeFlags &= ~BUILDMODE_EDITABLE;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: data accessor
-//-----------------------------------------------------------------------------
-bool Panel::IsBuildModeDeletable()
-{
- return (_buildModeFlags & BUILDMODE_DELETABLE);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: data accessor
-//-----------------------------------------------------------------------------
-void Panel::SetBuildModeDeletable(bool state)
-{
- if (state)
- {
- _buildModeFlags |= BUILDMODE_DELETABLE;
- }
- else
- {
- _buildModeFlags &= ~BUILDMODE_DELETABLE;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-bool Panel::IsBuildModeActive()
-{
- return _buildGroup ? _buildGroup->IsEnabled() : false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::GetClipRect(int& x0,int& y0,int& x1,int& y1)
-{
- ipanel()->GetClipRect(GetVPanel(), x0, y0, x1, y1);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-int Panel::GetChildCount()
-{
- if (ipanel())
- {
- return ipanel()->GetChildCount(GetVPanel());
- }
-
- return 0;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: returns a child by the specified index
-//-----------------------------------------------------------------------------
-Panel *Panel::GetChild(int index)
-{
- // get the child and cast it to a panel
- // this assumes that the child is from the same module as the this (precondition)
- return ipanel()->GetPanel(ipanel()->GetChild(GetVPanel(), index), GetControlsModuleName());
-}
-
-CUtlVector< VPANEL > &Panel::GetChildren()
-{
- return ipanel()->GetChildren(GetVPanel());
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: moves the key focus back
-//-----------------------------------------------------------------------------
-bool Panel::RequestFocusPrev(VPANEL panel)
-{
- // chain to parent
- if (GetVParent())
- {
- return ipanel()->RequestFocusPrev(GetVParent(), GetVPanel());
- }
- return false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-bool Panel::RequestFocusNext(VPANEL panel)
-{
- // chain to parent
- if (GetVParent())
- {
- return ipanel()->RequestFocusNext(GetVParent(), GetVPanel());
- }
- return false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Sets the panel to have the current sub focus
-// Input : direction - the direction in which focus travelled to arrive at this panel; forward = 1, back = -1
-//-----------------------------------------------------------------------------
-void Panel::RequestFocus(int direction)
-{
- // NOTE: This doesn't make any sense if we don't have keyboard input enabled
- Assert( ( IsX360() || IsConsoleStylePanel() ) || IsKeyBoardInputEnabled() );
- // ivgui()->DPrintf2("RequestFocus(%s, %s)\n", GetName(), GetClassName());
- OnRequestFocus(GetVPanel(), NULL);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Called after a panel requests focus to fix up the whole chain
-//-----------------------------------------------------------------------------
-void Panel::OnRequestFocus(VPANEL subFocus, VPANEL defaultPanel)
-{
- CallParentFunction(new KeyValues("OnRequestFocus", "subFocus", subFocus, "defaultPanel", defaultPanel));
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-VPANEL Panel::GetCurrentKeyFocus()
-{
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: returns true if the panel has focus
-//-----------------------------------------------------------------------------
-bool Panel::HasFocus()
-{
- if (input()->GetFocus() == GetVPanel())
- {
- return true;
- }
- return false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::SetTabPosition(int position)
-{
- _tabPosition = position;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-int Panel::GetTabPosition()
-{
- return _tabPosition;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::InternalFocusChanged(bool lost)
-{
- /*
- //if focus is gained tell the focusNavGroup about it so its current can be correct
- if( (!lost) && (_focusNavGroup!=null) )
- {
- _focusNavGroup->setCurrentPanel(this);
- }
- */
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Called when a panel loses it's mouse capture
-//-----------------------------------------------------------------------------
-void Panel::OnMouseCaptureLost()
-{
- if (m_pTooltips)
- {
- m_pTooltips->ResetDelay();
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::AddActionSignalTarget(Panel *messageTarget)
-{
- HPanel target = ivgui()->PanelToHandle(messageTarget->GetVPanel());
- if (!_actionSignalTargetDar.HasElement(target))
- {
- _actionSignalTargetDar.AddElement(target);
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::AddActionSignalTarget(VPANEL messageTarget)
-{
- HPanel target = ivgui()->PanelToHandle(messageTarget);
- if (!_actionSignalTargetDar.HasElement(target))
- {
- _actionSignalTargetDar.AddElement(target);
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::RemoveActionSignalTarget(Panel *oldTarget)
-{
- _actionSignalTargetDar.RemoveElement(ivgui()->PanelToHandle(oldTarget->GetVPanel()));
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Sends a message to all the panels that have requested action signals
-//-----------------------------------------------------------------------------
-void Panel::PostActionSignal( KeyValues *message )
-{
- if ( m_bIsSilent != true )
- {
- // add who it was from the message
- message->SetPtr("panel", this);
- int i;
- for (i = _actionSignalTargetDar.GetCount() - 1; i > 0; i--)
- {
- VPANEL panel = ivgui()->HandleToPanel(_actionSignalTargetDar[i]);
- if (panel)
- {
- ivgui()->PostMessage(panel, message->MakeCopy(), GetVPanel());
- }
- }
-
- // do this so we can save on one MakeCopy() call
- if (i == 0)
- {
- VPANEL panel = ivgui()->HandleToPanel(_actionSignalTargetDar[i]);
- if (panel)
- {
- ivgui()->PostMessage(panel, message, GetVPanel());
- return;
- }
- }
- }
- message->deleteThis();
-}
-
-void Panel::SetBorder(IBorder *border)
-{
- _border = border;
-
- if (border)
- {
- int x, y, x2, y2;
- border->GetInset(x, y, x2, y2);
- ipanel()->SetInset(GetVPanel(), x, y, x2, y2);
-
- // update our background type based on the bord
- SetPaintBackgroundType(border->GetBackgroundType());
- }
- else
- {
- ipanel()->SetInset(GetVPanel(), 0, 0, 0, 0);
- }
-}
-
-IBorder *Panel::GetBorder()
-{
- return _border;
-}
-
-
-void Panel::SetPaintBorderEnabled(bool state)
-{
- _flags.SetFlag( PAINT_BORDER_ENABLED, state );
-}
-
-void Panel::SetPaintBackgroundEnabled(bool state)
-{
- _flags.SetFlag( PAINT_BACKGROUND_ENABLED, state );
-}
-
-void Panel::SetPaintBackgroundType( int type )
-{
- // HACK only 0 through 2 supported for now
- m_nPaintBackgroundType = clamp( type, 0, 2 );
-}
-
-void Panel::SetPaintEnabled(bool state)
-{
- _flags.SetFlag( PAINT_ENABLED, state );
-}
-
-void Panel::SetPostChildPaintEnabled(bool state)
-{
- _flags.SetFlag( POST_CHILD_PAINT_ENABLED, state );
-}
-
-void Panel::GetInset(int& left,int& top,int& right,int& bottom)
-{
- ipanel()->GetInset(GetVPanel(), left, top, right, bottom);
-}
-
-void Panel::GetPaintSize(int& wide,int& tall)
-{
- GetSize(wide, tall);
- if (_border != null)
- {
- int left,top,right,bottom;
- _border->GetInset(left,top,right,bottom);
-
- wide -= (left+right);
- tall -= (top+bottom);
- }
-}
-
-int Panel::GetWide()
-{
- int wide, tall;
- ipanel()->GetSize(GetVPanel(), wide, tall);
- return wide;
-}
-
-void Panel::SetWide(int wide)
-{
- ipanel()->SetSize(GetVPanel(), wide, GetTall());
-}
-
-int Panel::GetTall()
-{
- int wide, tall;
- ipanel()->GetSize(GetVPanel(), wide, tall);
- return tall;
-}
-
-void Panel::SetTall(int tall)
-{
- ipanel()->SetSize(GetVPanel(), GetWide(), tall);
-}
-
-void Panel::SetBuildGroup(BuildGroup* buildGroup)
-{
- //TODO: remove from old group
-
- Assert(buildGroup != NULL);
-
- _buildGroup = buildGroup;
-
- _buildGroup->PanelAdded(this);
-}
-
-bool Panel::IsBuildGroupEnabled()
-{
- if ( !_buildGroup.IsValid() )
- return false;
-
- bool enabled = _buildGroup->IsEnabled();
- if ( enabled )
- return enabled;
-
- if ( GetParent() && GetParent()->IsBuildGroupEnabled() )
- return true;
-
- return false;
-}
-
-void Panel::SetBgColor(Color color)
-{
- _bgColor = color;
-}
-
-void Panel::SetFgColor(Color color)
-{
- _fgColor = color;
-}
-
-Color Panel::GetBgColor()
-{
- return _bgColor;
-}
-
-Color Panel::GetFgColor()
-{
- return _fgColor;
-}
-
-void Panel::InternalPerformLayout()
-{
- // Don't layout if we're still waiting for our scheme to be applied.
- // At worst, it leads to crashes, at best it does work that we'll redo as soon as the scheme has been applied.
- if ( _flags.IsFlagSet( NEEDS_SCHEME_UPDATE ) )
- return;
-
- _flags.SetFlag( IN_PERFORM_LAYOUT );
- // make sure the scheme has been applied
- _flags.ClearFlag( NEEDS_LAYOUT );
- PerformLayout();
- _flags.ClearFlag( IN_PERFORM_LAYOUT );
-}
-
-void Panel::PerformLayout()
-{
- // this should be overridden to relayout controls
-}
-
-void Panel::InvalidateLayout( bool layoutNow, bool reloadScheme )
-{
- _flags.SetFlag( NEEDS_LAYOUT );
-
- if (reloadScheme)
- {
- // make all our children reload the scheme
- _flags.SetFlag( NEEDS_SCHEME_UPDATE );
-
- for (int i = 0; i < GetChildCount(); i++)
- {
- vgui::Panel* panel = GetChild(i);
- if( panel )
- {
- panel->InvalidateLayout(layoutNow, true);
- }
- }
-
- PerformApplySchemeSettings();
- }
-
- if (layoutNow)
- {
- InternalPerformLayout();
- Repaint();
- }
-}
-
-bool Panel::IsCursorNone()
-{
- HCursor cursor = GetCursor();
-
- if (!cursor)
- {
- return true;
- }
-
- return false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: returns true if the cursor is currently over the panel
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool Panel::IsCursorOver(void)
-{
- int x, y;
- input()->GetCursorPos(x, y);
- return IsWithin(x, y);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Called when a panel receives a command message from another panel
-//-----------------------------------------------------------------------------
-void Panel::OnCommand(const char *command)
-{
- if ( !Q_stricmp( "performlayout", command ) )
- {
- InvalidateLayout();
- }
- else if ( !Q_stricmp( "reloadscheme", command ) )
- {
- InvalidateLayout( false, true );
- }
- else
- {
- // if noone else caught this, pass along to the listeners
- // (this is useful for generic dialogs - otherwise, commands just get ignored)
- KeyValues *msg = new KeyValues( command );
- PostActionSignal( msg );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: panel gained focus message
-//-----------------------------------------------------------------------------
-void Panel::OnSetFocus()
-{
- Repaint();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: panel lost focus message
-//-----------------------------------------------------------------------------
-void Panel::OnKillFocus()
-{
- Repaint();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Sets the object up to be deleted next frame
-//-----------------------------------------------------------------------------
-void Panel::MarkForDeletion()
-{
- if ( _flags.IsFlagSet( MARKED_FOR_DELETION ) )
- return;
-
- _flags.SetFlag( MARKED_FOR_DELETION );
- _flags.ClearFlag( AUTODELETE_ENABLED );
-
- if (ivgui()->IsRunning())
- {
- ivgui()->MarkPanelForDeletion(GetVPanel());
- }
- // direct delete is never safe because even if ivgui is shutdown we manually do RunFrame()
- // and we can enter here in a think traverse and then delete from underneath ourselves
- /*else
- {
- delete this;
- }*/
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: return true if this object require a perform layout
-//-----------------------------------------------------------------------------
-bool Panel::IsLayoutInvalid()
-{
- return _flags.IsFlagSet( NEEDS_LAYOUT );
-}
-
-
-//-----------------------------------------------------------------------------
-// Sets the pin corner + resize mode for resizing panels
-//-----------------------------------------------------------------------------
-void Panel::SetAutoResize( PinCorner_e pinCorner, AutoResize_e resizeDir,
- int nPinOffsetX, int nPinOffsetY, int nUnpinnedCornerOffsetX, int nUnpinnedCornerOffsetY )
-{
- _pinCorner = pinCorner;
- _autoResizeDirection = resizeDir;
- m_nPinDeltaX = nPinOffsetX;
- m_nPinDeltaY = nPinOffsetY;
- m_nResizeDeltaX = nUnpinnedCornerOffsetX;
- m_nResizeDeltaY = nUnpinnedCornerOffsetY;
-}
-
-
-//-----------------------------------------------------------------------------
-// Sets the pin corner for non-resizing panels
-//-----------------------------------------------------------------------------
-void Panel::SetPinCorner( PinCorner_e pinCorner, int nOffsetX, int nOffsetY )
-{
- _pinCorner = pinCorner;
- _autoResizeDirection = AUTORESIZE_NO;
- m_nPinDeltaX = nOffsetX;
- m_nPinDeltaY = nOffsetY;
- m_nResizeDeltaX = 0;
- m_nResizeDeltaY = 0;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: data accessor
-//-----------------------------------------------------------------------------
-Panel::PinCorner_e Panel::GetPinCorner()
-{
- return (PinCorner_e)_pinCorner;
-}
-
-
-//-----------------------------------------------------------------------------
-// Gets the relative offset of the control from the pin corner
-//-----------------------------------------------------------------------------
-void Panel::GetPinOffset( int &dx, int &dy )
-{
- dx = m_nPinDeltaX;
- dy = m_nPinDeltaY;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: data accessor
-//-----------------------------------------------------------------------------
-Panel::AutoResize_e Panel::GetAutoResize()
-{
- return (AutoResize_e)_autoResizeDirection;
-}
-
-
-//-----------------------------------------------------------------------------
-// Gets the relative offset of the control from the pin corner
-//-----------------------------------------------------------------------------
-void Panel::GetResizeOffset( int &dx, int &dy )
-{
- dx = m_nResizeDeltaX;
- dy = m_nResizeDeltaY;
-}
-
-//-----------------------------------------------------------------------------
-// Tells this panel that it should pin itself to the corner of a specified sibling panel
-//-----------------------------------------------------------------------------
-void Panel::PinToSibling( const char *pszSibling, PinCorner_e pinOurCorner, PinCorner_e pinSibling )
-{
- _pinCornerToSibling = pinOurCorner;
- _pinToSiblingCorner = pinSibling;
-
- if ( _pinToSibling && pszSibling && !Q_strcmp( _pinToSibling, pszSibling ) )
- return;
-
- if (_pinToSibling)
- {
- delete [] _pinToSibling;
- _pinToSibling = NULL;
- }
-
- if (pszSibling)
- {
- int len = Q_strlen(pszSibling) + 1;
- _pinToSibling = new char[ len ];
- Q_strncpy( _pinToSibling, pszSibling, len );
- }
- m_pinSibling = NULL;
-
- UpdateSiblingPin();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::UpdateSiblingPin( void )
-{
- if ( !_pinToSibling )
- {
- ipanel()->SetSiblingPin(GetVPanel(), NULL);
- return;
- }
-
- if ( !m_pinSibling.Get() )
- {
- // Resolve our sibling now
- m_pinSibling = FindSiblingByName( _pinToSibling );
- }
-
- if ( m_pinSibling.Get() )
- {
- ipanel()->SetSiblingPin( GetVPanel(), m_pinSibling->GetVPanel(), _pinCornerToSibling, _pinToSiblingCorner );
- }
- else
- {
- ipanel()->SetSiblingPin(GetVPanel(), NULL);
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::ApplySchemeSettings(IScheme *pScheme)
-{
- // get colors
- SetFgColor(GetSchemeColor("Panel.FgColor", pScheme));
- SetBgColor(GetSchemeColor("Panel.BgColor", pScheme));
-
-#if defined( VGUI_USEDRAGDROP )
- m_clrDragFrame = pScheme->GetColor("DragDrop.DragFrame", Color(255, 255, 255, 192));
- m_clrDropFrame = pScheme->GetColor("DragDrop.DropFrame", Color(150, 255, 150, 255));
-
- m_infoFont = pScheme->GetFont( "DefaultVerySmall" );
-#endif
- // mark us as no longer needing scheme settings applied
- _flags.ClearFlag( NEEDS_SCHEME_UPDATE );
-
- if ( IsBuildGroupEnabled() )
- {
- _buildGroup->ApplySchemeSettings(pScheme);
- return;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Checks to see if the panel needs it's scheme info setup
-//-----------------------------------------------------------------------------
-void Panel::PerformApplySchemeSettings()
-{
- if ( _flags.IsFlagSet( NEEDS_DEFAULT_SETTINGS_APPLIED ) )
- {
- InternalInitDefaultValues( GetAnimMap() );
- }
-
- if ( _flags.IsFlagSet( NEEDS_SCHEME_UPDATE ) )
- {
- VPROF( "ApplySchemeSettings" );
- IScheme *pScheme = scheme()->GetIScheme( GetScheme() );
- AssertOnce( pScheme );
- if ( pScheme ) // this should NEVER be null, but if it is bad things would happen in ApplySchemeSettings...
- {
- ApplySchemeSettings( pScheme );
- //_needsSchemeUpdate = false;
-
- ApplyOverridableColors();
-
- UpdateSiblingPin();
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Loads panel details related to autoresize from the resource info
-//-----------------------------------------------------------------------------
-#if defined( _DEBUG )
-static Panel *lastWarningParent = 0;
-#endif
-
-void Panel::ApplyAutoResizeSettings(KeyValues *inResourceData)
-{
- int x, y;
- GetPos(x, y);
-
- int wide, tall;
- GetSize( wide, tall );
-
- AutoResize_e autoResize = (AutoResize_e)inResourceData->GetInt( "AutoResize", AUTORESIZE_NO );
- PinCorner_e pinCorner = (PinCorner_e)inResourceData->GetInt( "PinCorner", PIN_TOPLEFT );
-
- // By default, measure unpinned corner for the offset
- int pw = wide, pt = tall;
- if ( GetParent() )
- {
- GetParent()->GetSize( pw, pt );
-#if defined( _DEBUG )
- if ( pw == 64 && pt == 24 )
- {
- if ( GetParent() != lastWarningParent )
- {
- lastWarningParent = GetParent();
- Warning( "Resize parent (panel(%s) -> parent(%s)) not sized yet!!!\n", GetName(), GetParent()->GetName() );
- }
- }
-#endif
- }
-
- int nPinnedCornerOffsetX = 0, nPinnedCornerOffsetY = 0;
- int nUnpinnedCornerOffsetX = 0, nUnpinnedCornerOffsetY = 0;
- switch( pinCorner )
- {
- case PIN_TOPLEFT:
- nPinnedCornerOffsetX = x;
- nPinnedCornerOffsetY = y;
- nUnpinnedCornerOffsetX = (x + wide) - pw;
- nUnpinnedCornerOffsetY = (y + tall) - pt;
- break;
-
- case PIN_TOPRIGHT:
- nPinnedCornerOffsetX = (x + wide) - pw;
- nPinnedCornerOffsetY = y;
- nUnpinnedCornerOffsetX = x;
- nUnpinnedCornerOffsetY = (y + tall) - pt;
- break;
-
- case PIN_BOTTOMLEFT:
- nPinnedCornerOffsetX = x;
- nPinnedCornerOffsetY = (y + tall) - pt;
- nUnpinnedCornerOffsetX = (x + wide) - pw;
- nUnpinnedCornerOffsetY = y;
- break;
-
- case PIN_BOTTOMRIGHT:
- nPinnedCornerOffsetX = (x + wide) - pw;
- nPinnedCornerOffsetY = (y + tall) - pt;
- nUnpinnedCornerOffsetX = x;
- nUnpinnedCornerOffsetY = y;
- break;
- }
-
- // Allow specific overrides in the resource file
- if ( IsProportional() )
- {
- if ( inResourceData->FindKey( "PinnedCornerOffsetX" ) )
- {
- nPinnedCornerOffsetX = scheme()->GetProportionalScaledValueEx( GetScheme(), inResourceData->GetInt( "PinnedCornerOffsetX" ) );
- }
- if ( inResourceData->FindKey( "PinnedCornerOffsetY" ) )
- {
- nPinnedCornerOffsetY = scheme()->GetProportionalScaledValueEx( GetScheme(), inResourceData->GetInt( "PinnedCornerOffsetY" ) );
- }
- if ( inResourceData->FindKey( "UnpinnedCornerOffsetX" ) )
- {
- nUnpinnedCornerOffsetX = scheme()->GetProportionalScaledValueEx( GetScheme(), inResourceData->GetInt( "UnpinnedCornerOffsetX" ) );
- }
- if ( inResourceData->FindKey( "UnpinnedCornerOffsetY" ) )
- {
- nUnpinnedCornerOffsetY = scheme()->GetProportionalScaledValueEx( GetScheme(), inResourceData->GetInt( "UnpinnedCornerOffsetY" ) );
- }
- }
- else
- {
- nPinnedCornerOffsetX = inResourceData->GetInt( "PinnedCornerOffsetX", nPinnedCornerOffsetX );
- nPinnedCornerOffsetY = inResourceData->GetInt( "PinnedCornerOffsetY", nPinnedCornerOffsetY );
- nUnpinnedCornerOffsetX = inResourceData->GetInt( "UnpinnedCornerOffsetX", nUnpinnedCornerOffsetX );
- nUnpinnedCornerOffsetY = inResourceData->GetInt( "UnpinnedCornerOffsetY", nUnpinnedCornerOffsetY );
- }
-
- if ( autoResize == AUTORESIZE_NO )
- {
- nUnpinnedCornerOffsetX = nUnpinnedCornerOffsetY = 0;
- }
-
- SetAutoResize( pinCorner, autoResize, nPinnedCornerOffsetX, nPinnedCornerOffsetY, nUnpinnedCornerOffsetX, nUnpinnedCornerOffsetY );
-}
-
-ConVar panel_test_title_safe( "panel_test_title_safe", "0", FCVAR_CHEAT, "Test vgui panel positioning with title safe indentation" );
-
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Loads panel details from the resource info
-//-----------------------------------------------------------------------------
-void Panel::ApplySettings(KeyValues *inResourceData)
-{
- // First restore to default values
- if ( _flags.IsFlagSet( NEEDS_DEFAULT_SETTINGS_APPLIED ) )
- {
- InternalInitDefaultValues( GetAnimMap() );
- }
-
- // Let PanelAnimationVars auto-retrieve settings (we restore defaults above
- // since a script might be missing certain values)
- InternalApplySettings( GetAnimMap(), inResourceData );
-
- // clear any alignment flags
- _buildModeFlags &= ~(BUILDMODE_SAVE_XPOS_RIGHTALIGNED | BUILDMODE_SAVE_XPOS_CENTERALIGNED | BUILDMODE_SAVE_YPOS_BOTTOMALIGNED | BUILDMODE_SAVE_YPOS_CENTERALIGNED | BUILDMODE_SAVE_WIDE_FULL | BUILDMODE_SAVE_TALL_FULL | BUILDMODE_SAVE_PROPORTIONAL_TO_PARENT);
-
- // get the position
- int alignScreenWide, alignScreenTall; // screen dimensions used for pinning in splitscreen
- surface()->GetScreenSize( alignScreenWide, alignScreenTall );
-
- int screenWide = alignScreenWide;
- int screenTall = alignScreenTall;
-
- // temporarily remove the override to get the fullscreen dimensions
- if ( surface()->IsScreenSizeOverrideActive() )
- {
- surface()->ForceScreenSizeOverride( false, 0, 0 );
- surface()->GetScreenSize( screenWide, screenTall );
-
- // restore the override
- surface()->ForceScreenSizeOverride( true, alignScreenWide, alignScreenTall );
- }
-
- int parentX = 0;
- int parentY = 0;
-
- // flag to cause windows to get screenWide and screenTall from their parents,
- // this allows children windows to use fill and right/bottom alignment even
- // if their parent does not use the full screen.
- if ( inResourceData->GetInt( "proportionalToParent", 0 ) == 1 )
- {
- _buildModeFlags |= BUILDMODE_SAVE_PROPORTIONAL_TO_PARENT;
- if ( GetParent() != NULL )
- {
- GetParent()->GetBounds( parentX, parentY, alignScreenWide, alignScreenTall );
- }
- }
-
- int x, y;
- GetPos(x, y);
- const char *xstr = inResourceData->GetString( "xpos", NULL );
- const char *ystr = inResourceData->GetString( "ypos", NULL );
-
- if (xstr)
- {
- // look for alignment flags
- if (xstr[0] == 'r' || xstr[0] == 'R')
- {
- _buildModeFlags |= BUILDMODE_SAVE_XPOS_RIGHTALIGNED;
- xstr++;
- }
- else if (xstr[0] == 'c' || xstr[0] == 'C')
- {
- _buildModeFlags |= BUILDMODE_SAVE_XPOS_CENTERALIGNED;
- xstr++;
- }
-
- // get the value
- x = atoi(xstr);
- // scale the x up to our screen co-ords
- if ( IsProportional() )
- {
- x = scheme()->GetProportionalScaledValueEx(GetScheme(), x);
- }
- // now correct the alignment
- if (_buildModeFlags & BUILDMODE_SAVE_XPOS_RIGHTALIGNED)
- {
- x = alignScreenWide - x;
- }
- else if (_buildModeFlags & BUILDMODE_SAVE_XPOS_CENTERALIGNED)
- {
- x = (alignScreenWide / 2) + x;
- }
- }
-
- if (ystr)
- {
- // look for alignment flags
- if (ystr[0] == 'r' || ystr[0] == 'R')
- {
- _buildModeFlags |= BUILDMODE_SAVE_YPOS_BOTTOMALIGNED;
- ystr++;
- }
- else if (ystr[0] == 'c' || ystr[0] == 'C')
- {
- _buildModeFlags |= BUILDMODE_SAVE_YPOS_CENTERALIGNED;
- ystr++;
- }
- y = atoi(ystr);
- if (IsProportional())
- {
- // scale the y up to our screen co-ords
- y = scheme()->GetProportionalScaledValueEx(GetScheme(), y);
- }
- // now correct the alignment
- if (_buildModeFlags & BUILDMODE_SAVE_YPOS_BOTTOMALIGNED)
- {
- y = alignScreenTall - y;
- }
- else if (_buildModeFlags & BUILDMODE_SAVE_YPOS_CENTERALIGNED)
- {
- y = (alignScreenTall / 2) + y;
- }
- }
-
- bool bUsesTitleSafeArea = false;
- int titleSafeWide = 0;
- int titleSafeTall = 0;
-
- Rect_t excludeEdgeFromTitleSafe; // if a side is set to != 0, don't title safe relative to that edge
- excludeEdgeFromTitleSafe.x = 0;
- excludeEdgeFromTitleSafe.y = 0;
- excludeEdgeFromTitleSafe.width = 0;
- excludeEdgeFromTitleSafe.height = 0;
-
- if ( IsX360() || panel_test_title_safe.GetBool() )
- {
- // "usetitlesafe" "1" - required inner 90%
- // "usetitlesafe" "2" - suggested inner 85%
-
- int iUseTitleSafeValue = 0;
- if ( inResourceData->FindKey( "usetitlesafe" ) )
- {
- iUseTitleSafeValue = inResourceData->GetInt( "usetitlesafe" );
- bUsesTitleSafeArea = ( iUseTitleSafeValue > 0 );
- }
-
- if( bUsesTitleSafeArea )
- {
- titleSafeWide = screenWide * ( iUseTitleSafeValue == 1 ? 0.05f : 0.075f );
- titleSafeTall = screenTall * ( iUseTitleSafeValue == 1 ? 0.05f : 0.075f );
-
- // Don't title safe internal boundaries for split screen viewports
- int splitX = 0;
- int splitY = 0;
- vgui::surface()->OffsetAbsPos( splitX, splitY );
-
- bool bHorizontalSplit = ( alignScreenTall != screenTall );
- bool bVerticalSplit = ( alignScreenWide != screenWide );
-
- if ( bHorizontalSplit )
- {
- // top or bottom?
- if ( splitY != parentY )
- {
- excludeEdgeFromTitleSafe.y = 1;
- }
- else
- {
- excludeEdgeFromTitleSafe.height = 1;
- }
- }
-
- if ( bVerticalSplit )
- {
- // left or right
- if ( splitX != parentX )
- {
- excludeEdgeFromTitleSafe.x = 1;
- }
- else
- {
- excludeEdgeFromTitleSafe.width = 1;
- }
- }
-
- if ( _buildModeFlags & BUILDMODE_SAVE_XPOS_RIGHTALIGNED )
- {
- if ( !excludeEdgeFromTitleSafe.width )
- {
- x -= titleSafeWide; // right edge
- }
- }
- else if (_buildModeFlags & BUILDMODE_SAVE_XPOS_CENTERALIGNED)
- {
- }
- else if ( !excludeEdgeFromTitleSafe.x )
- {
- x += titleSafeWide; // left edge
- }
-
- if ( _buildModeFlags & BUILDMODE_SAVE_YPOS_BOTTOMALIGNED )
- {
- if ( !excludeEdgeFromTitleSafe.height )
- {
- y -= titleSafeTall; // bottom edge
- }
- }
- else if (_buildModeFlags & BUILDMODE_SAVE_YPOS_CENTERALIGNED)
- {
- }
- else if ( !excludeEdgeFromTitleSafe.y )
- {
- y += titleSafeTall; // top edge
- }
- }
- }
- SetNavUp( inResourceData->GetString("navUp") );
- SetNavDown( inResourceData->GetString("navDown") );
- SetNavLeft( inResourceData->GetString("navLeft") );
- SetNavRight( inResourceData->GetString("navRight") );
- SetNavToRelay( inResourceData->GetString("navToRelay") );
- SetNavActivate( inResourceData->GetString("navActivate") );
- SetNavBack( inResourceData->GetString("navBack") );
-
- SetPos(x, y);
-
- if (inResourceData->FindKey( "zpos" ))
- {
- SetZPos( inResourceData->GetInt( "zpos" ) );
- }
-
- // size
- int wide, tall;
- GetSize( wide, tall );
-
- const char *wstr = inResourceData->GetString( "wide", NULL );
- if ( wstr )
- {
- if (wstr[0] == 'f' || wstr[0] == 'F')
- {
- _buildModeFlags |= BUILDMODE_SAVE_WIDE_FULL;
- wstr++;
- }
- wide = atoi(wstr);
- if ( IsProportional() )
- {
- // scale the width up to our screen co-ords
- wide = scheme()->GetProportionalScaledValueEx(GetScheme(), wide);
- }
- // now correct the alignment
- if (_buildModeFlags & BUILDMODE_SAVE_WIDE_FULL)
- {
- wide = alignScreenWide - wide;
- }
- }
-
- // allow tall to be use the "fill" option, set to the height of the parent/screen
- wstr = inResourceData->GetString( "tall", NULL );
- if ( wstr )
- {
- if (wstr[0] == 'f' || wstr[0] == 'F')
- {
- _buildModeFlags |= BUILDMODE_SAVE_TALL_FULL;
- wstr++;
- }
- tall = atoi(wstr);
- if ( IsProportional() )
- {
- // scale the height up to our screen co-ords
- tall = scheme()->GetProportionalScaledValueEx(GetScheme(), tall);
- }
- // now correct the alignment
- if (_buildModeFlags & BUILDMODE_SAVE_TALL_FULL)
- {
- tall = alignScreenTall - tall;
- }
- }
-
- if( bUsesTitleSafeArea )
- {
- if ( _buildModeFlags & BUILDMODE_SAVE_WIDE_FULL )
- {
- if ( !excludeEdgeFromTitleSafe.x )
- wide -= titleSafeWide;
-
- if ( !excludeEdgeFromTitleSafe.width )
- wide -= titleSafeWide;
- }
-
- if ( _buildModeFlags & BUILDMODE_SAVE_TALL_FULL )
- {
- if ( !excludeEdgeFromTitleSafe.y )
- tall -= titleSafeTall;
-
- if ( !excludeEdgeFromTitleSafe.height )
- tall -= titleSafeTall;
- }
- }
-
- SetSize( wide, tall );
-
- // NOTE: This has to happen after pos + size is set
- ApplyAutoResizeSettings( inResourceData );
-
- // only get colors if we're ignoring the scheme
- if (inResourceData->GetInt("IgnoreScheme", 0))
- {
- PerformApplySchemeSettings();
- }
-
- // state
- int state = inResourceData->GetInt("visible", 1);
- if (state == 0)
- {
- SetVisible(false);
- }
- else if (state == 1)
- {
- SetVisible(true);
- }
-
- SetEnabled( inResourceData->GetInt("enabled", true) );
-
- bool bMouseEnabled = inResourceData->GetInt( "mouseinputenabled", true );
- if ( !bMouseEnabled )
- {
- SetMouseInputEnabled( false );
- }
-
- // tab order
- SetTabPosition(inResourceData->GetInt("tabPosition", 0));
-
- const char *tooltip = inResourceData->GetString("tooltiptext", NULL);
- if (tooltip && *tooltip)
- {
- GetTooltip()->SetText(tooltip);
- }
-
- // paint background?
- int nPaintBackground = inResourceData->GetInt("paintbackground", -1);
- if (nPaintBackground >= 0)
- {
- SetPaintBackgroundEnabled( nPaintBackground != 0 );
- }
-
- // paint border?
- int nPaintBorder = inResourceData->GetInt("paintborder", -1);
- if (nPaintBorder >= 0)
- {
- SetPaintBorderEnabled( nPaintBorder != 0 );
- }
-
- // border?
- const char *pBorder = inResourceData->GetString( "border", "" );
- if ( *pBorder )
- {
- IScheme *pScheme = scheme()->GetIScheme( GetScheme() );
- SetBorder( pScheme->GetBorder( pBorder ) );
- }
-
- // check to see if we have a new name assigned
- const char *newName = inResourceData->GetString("fieldName", NULL);
- if ( newName )
- {
- // Only slam the name if the new one differs...
- SetName(newName);
- }
-
- // check to see if we need to render to the frame buffer even if
- // stereo mode is trying to render all of the ui to a render target
- m_bForceStereoRenderToFrameBuffer = inResourceData->GetBool( "ForceStereoRenderToFrameBuffer", false );
-
- //=============================================================================
- // HPE_BEGIN:
- // [pfreese] Support for reading rounded corner flags
- //=============================================================================
- int roundedCorners = inResourceData->GetInt( "RoundedCorners", -1 );
- if ( roundedCorners >= 0 )
- {
- m_roundedCorners = roundedCorners;
- }
- //=============================================================================
- // HPE_END
- //=============================================================================
-
- const char *pszSiblingName = inResourceData->GetString("pin_to_sibling", NULL);
- PinCorner_e pinOurCornerToSibling = (PinCorner_e)inResourceData->GetInt( "pin_corner_to_sibling", PIN_TOPLEFT );
- PinCorner_e pinSiblingCorner = (PinCorner_e)inResourceData->GetInt( "pin_to_sibling_corner", PIN_TOPLEFT );
- PinToSibling( pszSiblingName, pinOurCornerToSibling, pinSiblingCorner );
-
-
- // Allow overriding of colors. Used mostly by HUD elements, where scheme color usage is often undesired.
- IScheme *pScheme = vgui::scheme()->GetIScheme( GetScheme() );
- for ( int i = 0; i < m_OverridableColorEntries.Count(); i++ )
- {
- // Need to ensure the key exists, so we don't overwrite existing colors when it's not set.
- if ( inResourceData->FindKey( m_OverridableColorEntries[i].m_pszScriptName, false ) )
- {
- // Get the color as a string - test whether it is an actual color or a reference to a scheme color
- const char *pColorStr = inResourceData->GetString( m_OverridableColorEntries[i].m_pszScriptName );
- Color &clrDest = m_OverridableColorEntries[i].m_colFromScript;
- if ( pColorStr[0] == '.' || isdigit( pColorStr[0] ) )
- {
- float r = 0.0f, g = 0.0f, b = 0.0f, a = 0.0f;
- sscanf( pColorStr, "%f %f %f %f", &r, &g, &b, &a );
- clrDest[0] = (unsigned char)r;
- clrDest[1] = (unsigned char)g;
- clrDest[2] = (unsigned char)b;
- clrDest[3] = (unsigned char)a;
- }
- else
- {
- // First character wasn't a digit or a decimal - do a scheme color lookup
- clrDest = pScheme->GetColor( pColorStr, Color( 255, 255, 255, 255 ) );
- }
-
- (*m_OverridableColorEntries[i].m_pColor) = m_OverridableColorEntries[i].m_colFromScript;
- m_OverridableColorEntries[i].m_bOverridden = true;
- }
- }
-
- const char *pKeyboardInputEnabled = inResourceData->GetString( "keyboardinputenabled", NULL );
- if ( pKeyboardInputEnabled && pKeyboardInputEnabled[0] )
- {
- SetKeyBoardInputEnabled( atoi( pKeyboardInputEnabled ) );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Saves out a resource description of this panel
-//-----------------------------------------------------------------------------
-void Panel::GetSettings( KeyValues *outResourceData )
-{
- // control class name (so it can be recreated later if needed)
- outResourceData->SetString( "ControlName", GetClassName() );
-
- // name
- outResourceData->SetString( "fieldName", _panelName );
-
- // positioning
- int screenWide, screenTall;
- surface()->GetScreenSize(screenWide, screenTall);
- int x, y;
- GetPos( x, y );
- if ( IsProportional() )
- {
- x = scheme()->GetProportionalNormalizedValueEx( GetScheme(), x );
- y = scheme()->GetProportionalNormalizedValueEx( GetScheme(), y );
- }
- // correct for alignment
- if (_buildModeFlags & BUILDMODE_SAVE_XPOS_RIGHTALIGNED)
- {
- x = screenWide - x;
- char xstr[32];
- Q_snprintf(xstr, sizeof( xstr ), "r%d", x);
- outResourceData->SetString( "xpos", xstr );
- }
- else if (_buildModeFlags & BUILDMODE_SAVE_XPOS_CENTERALIGNED)
- {
- x = (screenWide / 2) + x;
- char xstr[32];
- Q_snprintf(xstr, sizeof( xstr ), "c%d", x);
- outResourceData->SetString( "xpos", xstr );
- }
- else
- {
- outResourceData->SetInt( "xpos", x );
- }
- if (_buildModeFlags & BUILDMODE_SAVE_YPOS_BOTTOMALIGNED)
- {
- y = screenTall - y;
- char ystr[32];
- Q_snprintf(ystr, sizeof( ystr ), "r%d", y);
- outResourceData->SetString( "ypos", ystr );
- }
- else if (_buildModeFlags & BUILDMODE_SAVE_YPOS_CENTERALIGNED)
- {
- y = (screenTall / 2) + y;
- char ystr[32];
- Q_snprintf(ystr, sizeof( ystr ), "c%d", y);
- outResourceData->SetString( "ypos", ystr );
- }
- else
- {
- outResourceData->SetInt( "ypos", y );
- }
- if (m_pTooltips)
- {
- if (strlen(m_pTooltips->GetText()) > 0)
- {
- outResourceData->SetString("tooltiptext", m_pTooltips->GetText());
- }
- }
- int wide, tall;
- GetSize( wide, tall );
- if ( IsProportional() )
- {
- wide = scheme()->GetProportionalNormalizedValueEx( GetScheme(), wide );
- tall = scheme()->GetProportionalNormalizedValueEx( GetScheme(), tall );
- }
-
- int z = ipanel()->GetZPos(GetVPanel());
- if (z)
- {
- outResourceData->SetInt("zpos", z);
- }
-
- // Correct for alignment
- if (_buildModeFlags & BUILDMODE_SAVE_WIDE_FULL )
- {
- wide = screenWide - wide;
- char wstr[32];
- Q_snprintf(wstr, sizeof( wstr ), "f%d", wide);
- outResourceData->SetString( "wide", wstr );
- }
- else
- {
- outResourceData->SetInt( "wide", wide );
- }
- outResourceData->SetInt( "tall", tall );
-
- outResourceData->SetInt("AutoResize", GetAutoResize());
- outResourceData->SetInt("PinCorner", GetPinCorner());
-
- //=============================================================================
- // HPE_BEGIN:
- // [pfreese] Support for writing out rounded corner flags
- //=============================================================================
- outResourceData->SetInt("RoundedCorners", m_roundedCorners);
- //=============================================================================
- // HPE_END
- //=============================================================================
-
- outResourceData->SetString( "pin_to_sibling", _pinToSibling );
- outResourceData->SetInt("pin_corner_to_sibling", _pinCornerToSibling );
- outResourceData->SetInt("pin_to_sibling_corner", _pinToSiblingCorner );
-
-
- // state
- outResourceData->SetInt( "visible", IsVisible() );
- outResourceData->SetInt( "enabled", IsEnabled() );
-
- outResourceData->SetInt( "tabPosition", GetTabPosition() );
-
- for ( int i = 0; i < m_OverridableColorEntries.Count(); i++ )
- {
- if ( m_OverridableColorEntries[i].m_bOverridden )
- {
- outResourceData->SetColor( m_OverridableColorEntries[i].m_pszScriptName, m_OverridableColorEntries[i].m_colFromScript );
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: After applying settings, apply overridable colors.
-// Done post apply settings, so that baseclass settings don't stomp
-// the script specified override colors.
-//-----------------------------------------------------------------------------
-void Panel::ApplyOverridableColors( void )
-{
- for ( int i = 0; i < m_OverridableColorEntries.Count(); i++ )
- {
- if ( m_OverridableColorEntries[i].m_bOverridden )
- {
- (*m_OverridableColorEntries[i].m_pColor) = m_OverridableColorEntries[i].m_colFromScript;
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::SetOverridableColor( Color *pColor, const Color &newColor )
-{
- for ( int i = 0; i < m_OverridableColorEntries.Count(); i++ )
- {
- if ( m_OverridableColorEntries[i].m_bOverridden )
- {
- if ( m_OverridableColorEntries[i].m_pColor == pColor )
- return;
- }
- }
-
- // Didn't find it, or it's not been overridden.
- *pColor = newColor;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-Color Panel::GetSchemeColor(const char *keyName, IScheme *pScheme)
-{
- return pScheme->GetColor(keyName, Color(255, 255, 255, 255));
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-Color Panel::GetSchemeColor(const char *keyName, Color defaultColor, IScheme *pScheme)
-{
- return pScheme->GetColor(keyName, defaultColor);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Returns a string description of the panel fields for use in the UI
-//-----------------------------------------------------------------------------
-const char *Panel::GetDescription( void )
-{
- static const char *panelDescription = "string fieldName, int xpos, int ypos, int wide, int tall, bool visible, bool enabled, int tabPosition, corner pinCorner, autoresize autoResize, string tooltiptext";
- return panelDescription;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: user configuration settings
-// this is used for any control details the user wants saved between sessions
-// eg. dialog positions, last directory opened, list column width
-//-----------------------------------------------------------------------------
-void Panel::ApplyUserConfigSettings(KeyValues *userConfig)
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: returns user config settings for this control
-//-----------------------------------------------------------------------------
-void Panel::GetUserConfigSettings(KeyValues *userConfig)
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: optimization, return true if this control has any user config settings
-//-----------------------------------------------------------------------------
-bool Panel::HasUserConfigSettings()
-{
- return false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::InternalInvalidateLayout()
-{
- InvalidateLayout(false, false);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: called whenever the panel moves
-//-----------------------------------------------------------------------------
-void Panel::OnMove()
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::InternalMove()
-{
- OnMove();
- for(int i=0;i<GetChildCount();i++)
- {
- // recursively apply to all children
- GetChild(i)->OnMove();
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: empty function
-//-----------------------------------------------------------------------------
-void Panel::OnTick()
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: versioning
-//-----------------------------------------------------------------------------
-void *Panel::QueryInterface(EInterfaceID id)
-{
- if (id == ICLIENTPANEL_STANDARD_INTERFACE)
- {
- return this;
- }
-
- return NULL;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Map all the base messages to functions
-// ordering from most -> least used improves speed
-//-----------------------------------------------------------------------------
-MessageMapItem_t Panel::m_MessageMap[] =
-{
- MAP_MESSAGE_INT( Panel, "RequestFocus", RequestFocus, "direction" )
-};
-
-// IMPLEMENT_PANELMAP( Panel, NULL )
-PanelMap_t Panel::m_PanelMap = { Panel::m_MessageMap, ARRAYSIZE(Panel::m_MessageMap), "Panel", NULL };
-PanelMap_t *Panel::GetPanelMap( void ) { return &m_PanelMap; }
-
-//-----------------------------------------------------------------------------
-// Purpose: !! Soon to replace existing prepare panel map
-//-----------------------------------------------------------------------------
-void PreparePanelMessageMap(PanelMessageMap *panelMap)
-{
- // iterate through the class hierarchy message maps
- while ( panelMap != NULL && !panelMap->processed )
- {
- // hash message map strings into symbols
- for (int i = 0; i < panelMap->entries.Count(); i++)
- {
- MessageMapItem_t *item = &panelMap->entries[i];
-
- if (item->name)
- {
- item->nameSymbol = KeyValuesSystem()->GetSymbolForString(item->name);
- }
- else
- {
- item->nameSymbol = INVALID_KEY_SYMBOL;
- }
- if (item->firstParamName)
- {
- item->firstParamSymbol = KeyValuesSystem()->GetSymbolForString(item->firstParamName);
- }
- else
- {
- item->firstParamSymbol = INVALID_KEY_SYMBOL;
- }
- if (item->secondParamName)
- {
- item->secondParamSymbol = KeyValuesSystem()->GetSymbolForString(item->secondParamName);
- }
- else
- {
- item->secondParamSymbol = INVALID_KEY_SYMBOL;
- }
- }
-
- panelMap->processed = true;
- panelMap = panelMap->baseMap;
- }
-}
-
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Handles a message
-// Dispatches the message to a set of message maps
-//-----------------------------------------------------------------------------
-void Panel::OnMessage(const KeyValues *params, VPANEL ifromPanel)
-{
- PanelMessageMap *panelMap = GetMessageMap();
- bool bFound = false;
- int iMessageName = params->GetNameSymbol();
-
- if ( !panelMap->processed )
- {
- PreparePanelMessageMap( panelMap );
- }
-
- // iterate through the class hierarchy message maps
- for ( ; panelMap != NULL && !bFound; panelMap = panelMap->baseMap )
- {
-#if defined( _DEBUG )
-// char const *className = panelMap->pfnClassName();
-// NOTE_UNUSED( className );
-#endif
-
- // iterate all the entries in the panel map
- for ( int i = 0; i < panelMap->entries.Count(); i++ )
- {
- MessageMapItem_t *pMap = &panelMap->entries[i];
-
- if (iMessageName == pMap->nameSymbol)
- {
- bFound = true;
-
- switch (pMap->numParams)
- {
- case 0:
- {
- (this->*(pMap->func))();
- break;
- }
-
- case 1:
- {
- KeyValues *param1 = params->FindKey(pMap->firstParamSymbol);
- if (!param1)
- {
- param1 = const_cast<KeyValues *>(params);
- }
-
- switch ( pMap->firstParamType )
- {
- case DATATYPE_INT:
- typedef void (Panel::*MessageFunc_Int_t)(int);
- (this->*((MessageFunc_Int_t)pMap->func))( param1->GetInt() );
- break;
-
- case DATATYPE_UINT64:
- typedef void (Panel::*MessageFunc_Uin64_t)(uint64);
- (this->*((MessageFunc_Uin64_t)pMap->func))( param1->GetUint64() );
- break;
-
- case DATATYPE_PTR:
- typedef void (Panel::*MessageFunc_Ptr_t)( void * );
- (this->*((MessageFunc_Ptr_t)pMap->func))( param1->GetPtr() );
- break;
-
- case DATATYPE_HANDLE:
- {
- typedef void (Panel::*MessageFunc_VPANEL_t)( VPANEL );
- VPANEL vpanel = ivgui()->HandleToPanel( param1->GetInt() );
- (this->*((MessageFunc_VPANEL_t)pMap->func))( vpanel );
- }
- break;
-
- case DATATYPE_FLOAT:
- typedef void (Panel::*MessageFunc_Float_t)( float );
- (this->*((MessageFunc_Float_t)pMap->func))( param1->GetFloat() );
- break;
-
- case DATATYPE_CONSTCHARPTR:
- typedef void (Panel::*MessageFunc_CharPtr_t)( const char * );
- (this->*((MessageFunc_CharPtr_t)pMap->func))( param1->GetString() );
- break;
-
- case DATATYPE_CONSTWCHARPTR:
- typedef void (Panel::*MessageFunc_WCharPtr_t)( const wchar_t * );
- (this->*((MessageFunc_WCharPtr_t)pMap->func))( param1->GetWString() );
- break;
-
- case DATATYPE_KEYVALUES:
- typedef void (Panel::*MessageFunc_KeyValues_t)(KeyValues *);
- if ( pMap->firstParamName )
- {
- (this->*((MessageFunc_KeyValues_t)pMap->func))( (KeyValues *)param1->GetPtr() );
- }
- else
- {
- // no param set, so pass in the whole thing
- (this->*((MessageFunc_KeyValues_t)pMap->func))( const_cast<KeyValues *>(params) );
- }
- break;
-
- default:
- Assert(!("No handler for vgui message function"));
- break;
- }
- break;
- }
-
- case 2:
- {
- KeyValues *param1 = params->FindKey(pMap->firstParamSymbol);
- if (!param1)
- {
- param1 = const_cast<KeyValues *>(params);
- }
- KeyValues *param2 = params->FindKey(pMap->secondParamSymbol);
- if (!param2)
- {
- param2 = const_cast<KeyValues *>(params);
- }
-
- if ( (DATATYPE_INT == pMap->firstParamType) && (DATATYPE_INT == pMap->secondParamType) )
- {
- typedef void (Panel::*MessageFunc_IntInt_t)(int, int);
- (this->*((MessageFunc_IntInt_t)pMap->func))( param1->GetInt(), param2->GetInt() );
- }
- else if ( (DATATYPE_PTR == pMap->firstParamType) && (DATATYPE_INT == pMap->secondParamType) )
- {
- typedef void (Panel::*MessageFunc_PtrInt_t)(void *, int);
- (this->*((MessageFunc_PtrInt_t)pMap->func))( param1->GetPtr(), param2->GetInt() );
- }
- else if ( (DATATYPE_CONSTCHARPTR == pMap->firstParamType) && (DATATYPE_INT == pMap->secondParamType) )
- {
- typedef void (Panel::*MessageFunc_ConstCharPtrInt_t)(const char *, int);
- (this->*((MessageFunc_ConstCharPtrInt_t)pMap->func))( param1->GetString(), param2->GetInt() );
- }
- else if ( (DATATYPE_CONSTCHARPTR == pMap->firstParamType) && (DATATYPE_CONSTCHARPTR == pMap->secondParamType) )
- {
- typedef void (Panel::*MessageFunc_ConstCharPtrConstCharPtr_t)(const char *, const char *);
- (this->*((MessageFunc_ConstCharPtrConstCharPtr_t)pMap->func))( param1->GetString(), param2->GetString() );
- }
- else if ( (DATATYPE_INT == pMap->firstParamType) && (DATATYPE_CONSTCHARPTR == pMap->secondParamType) )
- {
- typedef void (Panel::*MessageFunc_IntConstCharPtr_t)(int, const char *);
- (this->*((MessageFunc_IntConstCharPtr_t)pMap->func))( param1->GetInt(), param2->GetString() );
- }
- else if ( (DATATYPE_PTR == pMap->firstParamType) && (DATATYPE_CONSTCHARPTR == pMap->secondParamType) )
- {
- typedef void (Panel::*MessageFunc_PtrConstCharPtr_t)(void *, const char *);
- (this->*((MessageFunc_PtrConstCharPtr_t)pMap->func))( param1->GetPtr(), param2->GetString() );
- }
- else if ( (DATATYPE_PTR == pMap->firstParamType) && (DATATYPE_CONSTWCHARPTR == pMap->secondParamType) )
- {
- typedef void (Panel::*MessageFunc_PtrConstCharPtr_t)(void *, const wchar_t *);
- (this->*((MessageFunc_PtrConstCharPtr_t)pMap->func))( param1->GetPtr(), param2->GetWString() );
- }
- else if ( (DATATYPE_HANDLE == pMap->firstParamType) && (DATATYPE_CONSTCHARPTR == pMap->secondParamType) )
- {
- typedef void (Panel::*MessageFunc_HandleConstCharPtr_t)(VPANEL, const char *);
- VPANEL vp = ivgui()->HandleToPanel( param1->GetInt() );
- (this->*((MessageFunc_HandleConstCharPtr_t)pMap->func))( vp, param2->GetString() );
- }
- else if ( (DATATYPE_HANDLE == pMap->firstParamType) && (DATATYPE_CONSTWCHARPTR == pMap->secondParamType) )
- {
- typedef void (Panel::*MessageFunc_HandleConstCharPtr_t)(VPANEL, const wchar_t *);
- VPANEL vp = ivgui()->HandleToPanel( param1->GetInt() );
- (this->*((MessageFunc_HandleConstCharPtr_t)pMap->func))( vp, param2->GetWString() );
- }
- else
- {
- // the message isn't handled
- ivgui()->DPrintf( "Message '%s', sent to '%s', has invalid parameter types\n", params->GetName(), GetName() );
- }
- break;
- }
-
- default:
- Assert(!("Invalid number of parameters"));
- break;
- }
-
- // break the loop
- bFound = true;
- break;
- }
- }
- }
-
- if (!bFound)
- {
- OnOldMessage(const_cast<KeyValues *>(params), ifromPanel);
- }
-}
-
-void Panel::OnOldMessage(KeyValues *params, VPANEL ifromPanel)
-{
- bool bFound = false;
- // message map dispatch
- int iMessageName = params->GetNameSymbol();
-
- PanelMap_t *panelMap = GetPanelMap();
- if ( !panelMap->processed )
- {
- PreparePanelMap( panelMap );
- }
-
- // iterate through the class hierarchy message maps
- for ( ; panelMap != NULL && !bFound; panelMap = panelMap->baseMap )
- {
- MessageMapItem_t *pMessageMap = panelMap->dataDesc;
-
- for ( int i = 0; i < panelMap->dataNumFields; i++ )
- {
- if (iMessageName == pMessageMap[i].nameSymbol)
- {
- // call the mapped function
- switch ( pMessageMap[i].numParams )
- {
- case 2:
- if ( (DATATYPE_INT == pMessageMap[i].firstParamType) && (DATATYPE_INT == pMessageMap[i].secondParamType) )
- {
- typedef void (Panel::*MessageFunc_IntInt_t)(int, int);
- (this->*((MessageFunc_IntInt_t)pMessageMap[i].func))( params->GetInt(pMessageMap[i].firstParamName), params->GetInt(pMessageMap[i].secondParamName) );
- }
- else if ( (DATATYPE_PTR == pMessageMap[i].firstParamType) && (DATATYPE_INT == pMessageMap[i].secondParamType) )
- {
- typedef void (Panel::*MessageFunc_PtrInt_t)(void *, int);
- (this->*((MessageFunc_PtrInt_t)pMessageMap[i].func))( params->GetPtr(pMessageMap[i].firstParamName), params->GetInt(pMessageMap[i].secondParamName) );
- }
- else if ( (DATATYPE_CONSTCHARPTR == pMessageMap[i].firstParamType) && (DATATYPE_INT == pMessageMap[i].secondParamType) )
- {
- typedef void (Panel::*MessageFunc_ConstCharPtrInt_t)(const char *, int);
- (this->*((MessageFunc_ConstCharPtrInt_t)pMessageMap[i].func))( params->GetString(pMessageMap[i].firstParamName), params->GetInt(pMessageMap[i].secondParamName) );
- }
- else if ( (DATATYPE_CONSTCHARPTR == pMessageMap[i].firstParamType) && (DATATYPE_CONSTCHARPTR == pMessageMap[i].secondParamType) )
- {
- typedef void (Panel::*MessageFunc_ConstCharPtrConstCharPtr_t)(const char *, const char *);
- (this->*((MessageFunc_ConstCharPtrConstCharPtr_t)pMessageMap[i].func))( params->GetString(pMessageMap[i].firstParamName), params->GetString(pMessageMap[i].secondParamName) );
- }
- else if ( (DATATYPE_INT == pMessageMap[i].firstParamType) && (DATATYPE_CONSTCHARPTR == pMessageMap[i].secondParamType) )
- {
- typedef void (Panel::*MessageFunc_IntConstCharPtr_t)(int, const char *);
- (this->*((MessageFunc_IntConstCharPtr_t)pMessageMap[i].func))( params->GetInt(pMessageMap[i].firstParamName), params->GetString(pMessageMap[i].secondParamName) );
- }
- else if ( (DATATYPE_PTR == pMessageMap[i].firstParamType) && (DATATYPE_CONSTCHARPTR == pMessageMap[i].secondParamType) )
- {
- typedef void (Panel::*MessageFunc_PtrConstCharPtr_t)(void *, const char *);
- (this->*((MessageFunc_PtrConstCharPtr_t)pMessageMap[i].func))( params->GetPtr(pMessageMap[i].firstParamName), params->GetString(pMessageMap[i].secondParamName) );
- }
- else if ( (DATATYPE_PTR == pMessageMap[i].firstParamType) && (DATATYPE_CONSTWCHARPTR == pMessageMap[i].secondParamType) )
- {
- typedef void (Panel::*MessageFunc_PtrConstCharPtr_t)(void *, const wchar_t *);
- (this->*((MessageFunc_PtrConstCharPtr_t)pMessageMap[i].func))( params->GetPtr(pMessageMap[i].firstParamName), params->GetWString(pMessageMap[i].secondParamName) );
- }
- else if ( (DATATYPE_HANDLE == pMessageMap[i].firstParamType) && (DATATYPE_CONSTCHARPTR ==pMessageMap[i].secondParamType) )
- {
- typedef void (Panel::*MessageFunc_HandleConstCharPtr_t)(VPANEL, const char *);
- VPANEL vp = ivgui()->HandleToPanel( params->GetInt( pMessageMap[i].firstParamName ) );
- (this->*((MessageFunc_HandleConstCharPtr_t)pMessageMap[i].func))( vp, params->GetString(pMessageMap[i].secondParamName) );
- }
- else if ( (DATATYPE_HANDLE == pMessageMap[i].firstParamType) && (DATATYPE_CONSTWCHARPTR == pMessageMap[i].secondParamType) )
- {
- typedef void (Panel::*MessageFunc_HandleConstCharPtr_t)(VPANEL, const wchar_t *);
- VPANEL vp = ivgui()->HandleToPanel( params->GetInt( pMessageMap[i].firstParamName ) );
- (this->*((MessageFunc_HandleConstCharPtr_t)pMessageMap[i].func))( vp, params->GetWString(pMessageMap[i].secondParamName) );
- }
- else
- {
- // the message isn't handled
- ivgui()->DPrintf( "Message '%s', sent to '%s', has invalid parameter types\n", params->GetName(), GetName() );
- }
- break;
-
- case 1:
- switch ( pMessageMap[i].firstParamType )
- {
- case DATATYPE_BOOL:
- typedef void (Panel::*MessageFunc_Bool_t)(bool);
- (this->*((MessageFunc_Bool_t)pMessageMap[i].func))( (bool)params->GetInt(pMessageMap[i].firstParamName) );
- break;
-
- case DATATYPE_CONSTCHARPTR:
- typedef void (Panel::*MessageFunc_ConstCharPtr_t)(const char *);
- (this->*((MessageFunc_ConstCharPtr_t)pMessageMap[i].func))( (const char *)params->GetString(pMessageMap[i].firstParamName) );
- break;
-
- case DATATYPE_CONSTWCHARPTR:
- typedef void (Panel::*MessageFunc_ConstCharPtr_t)(const char *);
- (this->*((MessageFunc_ConstCharPtr_t)pMessageMap[i].func))( (const char *)params->GetWString(pMessageMap[i].firstParamName) );
- break;
-
- case DATATYPE_INT:
- typedef void (Panel::*MessageFunc_Int_t)(int);
- (this->*((MessageFunc_Int_t)pMessageMap[i].func))( params->GetInt(pMessageMap[i].firstParamName) );
- break;
-
- case DATATYPE_FLOAT:
- typedef void (Panel::*MessageFunc_Float_t)(float);
- (this->*((MessageFunc_Float_t)pMessageMap[i].func))( params->GetFloat(pMessageMap[i].firstParamName) );
- break;
-
- case DATATYPE_PTR:
- typedef void (Panel::*MessageFunc_Ptr_t)(void *);
- (this->*((MessageFunc_Ptr_t)pMessageMap[i].func))( (void *)params->GetPtr(pMessageMap[i].firstParamName) );
- break;
-
- case DATATYPE_HANDLE:
- {
- typedef void (Panel::*MessageFunc_Ptr_t)(void *);
- VPANEL vp = ivgui()->HandleToPanel( params->GetInt( pMessageMap[i].firstParamName ) );
- Panel *panel = ipanel()->GetPanel( vp, GetModuleName() );
- (this->*((MessageFunc_Ptr_t)pMessageMap[i].func))( (void *)panel );
- }
- break;
-
- case DATATYPE_KEYVALUES:
- typedef void (Panel::*MessageFunc_KeyValues_t)(KeyValues *);
- if ( pMessageMap[i].firstParamName )
- {
- (this->*((MessageFunc_KeyValues_t)pMessageMap[i].func))( (KeyValues *)params->GetPtr(pMessageMap[i].firstParamName) );
- }
- else
- {
- (this->*((MessageFunc_KeyValues_t)pMessageMap[i].func))( params );
- }
- break;
-
- default:
- // the message isn't handled
- ivgui()->DPrintf( "Message '%s', sent to '%s', has an invalid parameter type\n", params->GetName(), GetName() );
- break;
- }
-
- break;
-
- default:
- (this->*(pMessageMap[i].func))();
- break;
- };
-
- // break the loop
- bFound = true;
- break;
- }
- }
- }
-
- // message not handled
- // debug code
- if ( !bFound )
- {
- static int s_bDebugMessages = -1;
- if ( s_bDebugMessages == -1 )
- {
- s_bDebugMessages = CommandLine()->FindParm( "-vguimessages" ) ? 1 : 0;
- }
- if ( s_bDebugMessages == 1 )
- {
- ivgui()->DPrintf( "Message '%s' not handled by panel '%s'\n", params->GetName(), GetName() );
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Safe call to get info from child panel by name
-//-----------------------------------------------------------------------------
-bool Panel::RequestInfoFromChild(const char *childName, KeyValues *outputData)
-{
- Panel *panel = FindChildByName(childName);
- if (panel)
- {
- return panel->RequestInfo(outputData);
- }
- return false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Posts a message
-//-----------------------------------------------------------------------------
-void Panel::PostMessage(Panel *target, KeyValues *message, float delay)
-{
- ivgui()->PostMessage(target->GetVPanel(), message, GetVPanel(), delay);
-}
-
-void Panel::PostMessage(VPANEL target, KeyValues *message, float delaySeconds)
-{
- ivgui()->PostMessage(target, message, GetVPanel(), delaySeconds);
-}
-
-void Panel::PostMessageToAllSiblings( KeyValues *msg, float delaySeconds /*= 0.0f*/ )
-{
- VPANEL parent = GetVParent();
- if ( parent )
- {
- VPANEL vpanel = GetVPanel();
-
- CUtlVector< VPANEL > &children = ipanel()->GetChildren( parent );
- int nChildCount = children.Count();
- for ( int i = 0; i < nChildCount; ++i )
- {
- VPANEL sibling = children[ i ];
- if ( sibling == vpanel )
- continue;
-
- if ( sibling )
- {
- PostMessage( sibling, msg->MakeCopy(), delaySeconds );
- }
- }
- }
-
- msg->deleteThis();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Safe call to post a message to a child by name
-//-----------------------------------------------------------------------------
-void Panel::PostMessageToChild(const char *childName, KeyValues *message)
-{
- Panel *panel = FindChildByName(childName);
- if (panel)
- {
- ivgui()->PostMessage(panel->GetVPanel(), message, GetVPanel());
- }
- else
- {
- message->deleteThis();
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Requests some information from the panel
-// Look through the message map for the handler
-//-----------------------------------------------------------------------------
-bool Panel::RequestInfo( KeyValues *outputData )
-{
- if ( InternalRequestInfo( GetAnimMap(), outputData ) )
- {
- return true;
- }
-
- if (GetVParent())
- {
- return ipanel()->RequestInfo(GetVParent(), outputData);
- }
-
- return false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: sets a specified value in the control - inverse of RequestInfo
-//-----------------------------------------------------------------------------
-bool Panel::SetInfo(KeyValues *inputData)
-{
- if ( InternalSetInfo( GetAnimMap(), inputData ) )
- {
- return true;
- }
-
- // doesn't chain to parent
- return false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: change the panel's silent mode; if silent, the panel will not post
-// any action signals
-//-----------------------------------------------------------------------------
-
-void Panel::SetSilentMode( bool bSilent )
-{
- m_bIsSilent = bSilent;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: mouse events will be send to handler panel instead of this panel
-//-----------------------------------------------------------------------------
-void Panel::InstallMouseHandler( Panel *pHandler )
-{
- m_hMouseEventHandler = pHandler;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Prepares the hierarchy panel maps for use (with message maps etc)
-//-----------------------------------------------------------------------------
-void Panel::PreparePanelMap( PanelMap_t *panelMap )
-{
- // iterate through the class hierarchy message maps
- while ( panelMap != NULL && !panelMap->processed )
- {
- // fixup cross-dll boundary panel maps
- if ( panelMap->baseMap == (PanelMap_t*)0x00000001 )
- {
- panelMap->baseMap = &Panel::m_PanelMap;
- }
-
- // hash message map strings into symbols
- for (int i = 0; i < panelMap->dataNumFields; i++)
- {
- MessageMapItem_t *item = &panelMap->dataDesc[i];
-
- if (item->name)
- {
- item->nameSymbol = KeyValuesSystem()->GetSymbolForString(item->name);
- }
- else
- {
- item->nameSymbol = INVALID_KEY_SYMBOL;
- }
- if (item->firstParamName)
- {
- item->firstParamSymbol = KeyValuesSystem()->GetSymbolForString(item->firstParamName);
- }
- else
- {
- item->firstParamSymbol = INVALID_KEY_SYMBOL;
- }
- if (item->secondParamName)
- {
- item->secondParamSymbol = KeyValuesSystem()->GetSymbolForString(item->secondParamName);
- }
- else
- {
- item->secondParamSymbol = INVALID_KEY_SYMBOL;
- }
- }
-
- panelMap->processed = true;
- panelMap = panelMap->baseMap;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Called to delete the panel
-//-----------------------------------------------------------------------------
-void Panel::OnDelete()
-{
-#ifdef WIN32
- Assert( IsX360() || ( IsPC() && _heapchk() == _HEAPOK ) );
-#endif
- delete this;
-#ifdef WIN32
- Assert( IsX360() || ( IsPC() && _heapchk() == _HEAPOK ) );
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Panel handle implementation
-// Returns a pointer to a valid panel, NULL if the panel has been deleted
-//-----------------------------------------------------------------------------
-Panel *PHandle::Get()
-{
- if (m_iPanelID != INVALID_PANEL)
- {
- VPANEL panel = ivgui()->HandleToPanel(m_iPanelID);
- if (panel)
- {
- Panel *vguiPanel = ipanel()->GetPanel(panel, GetControlsModuleName());
- return vguiPanel;
- }
- }
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: sets the smart pointer
-//-----------------------------------------------------------------------------
-Panel *PHandle::Set(Panel *pent)
-{
- if (pent)
- {
- m_iPanelID = ivgui()->PanelToHandle(pent->GetVPanel());
- }
- else
- {
- m_iPanelID = INVALID_PANEL;
- }
- return pent;
-}
-
-Panel *PHandle::Set( HPanel hPanel )
-{
- m_iPanelID = hPanel;
- return Get();
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Returns a handle to a valid panel, NULL if the panel has been deleted
-//-----------------------------------------------------------------------------
-VPANEL VPanelHandle::Get()
-{
- if (m_iPanelID != INVALID_PANEL)
- {
- if (ivgui())
- {
- return ivgui()->HandleToPanel(m_iPanelID);
- }
- }
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: sets the smart pointer
-//-----------------------------------------------------------------------------
-VPANEL VPanelHandle::Set(VPANEL pent)
-{
- if (pent)
- {
- m_iPanelID = ivgui()->PanelToHandle(pent);
- }
- else
- {
- m_iPanelID = INVALID_PANEL;
- }
- return pent;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: returns a pointer to the tooltip object associated with the panel
-//-----------------------------------------------------------------------------
-BaseTooltip *Panel::GetTooltip()
-{
- if (!m_pTooltips)
- {
- m_pTooltips = new TextTooltip(this, NULL);
- m_bToolTipOverridden = false;
-
- if ( IsConsoleStylePanel() )
- {
- m_pTooltips->SetEnabled( false );
- }
- }
-
- return m_pTooltips;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::SetTooltip( BaseTooltip *pToolTip, const char *pszText )
-{
- if ( !m_bToolTipOverridden )
- {
- // Remove the one we made, we're being overridden.
- delete m_pTooltips;
- }
-
- m_pTooltips = pToolTip;
- m_bToolTipOverridden = true;
-
- if ( _tooltipText )
- {
- delete [] _tooltipText;
- _tooltipText = NULL;
- }
-
- if ( pszText )
- {
- int len = Q_strlen(pszText) + 1;
- _tooltipText = new char[ len ];
- Q_strncpy( _tooltipText, pszText, len );
- }
-}
-
-//-----------------------------------------------------------------------------
-const char *Panel::GetEffectiveTooltipText() const
-{
- if ( _tooltipText )
- {
- return _tooltipText;
- }
- if ( m_pTooltips )
- {
- const char *result = m_pTooltips->GetText();
- if ( result )
- {
- return result;
- }
- }
- return "";
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: sets the proportional flag on this panel and all it's children
-//-----------------------------------------------------------------------------
-void Panel::SetProportional(bool state)
-{
- // only do something if the state changes
- if( state != _flags.IsFlagSet( IS_PROPORTIONAL ) )
- {
- _flags.SetFlag( IS_PROPORTIONAL, state );
-
- for(int i=0;i<GetChildCount();i++)
- {
- // recursively apply to all children
- GetChild(i)->SetProportional( IsProportional() );
- }
- }
- InvalidateLayout();
-}
-
-
-void Panel::SetKeyBoardInputEnabled( bool state )
-{
- ipanel()->SetKeyBoardInputEnabled( GetVPanel(), state );
- for ( int i = 0; i < GetChildCount(); i++ )
- {
- Panel *child = GetChild( i );
- if ( !child )
- {
- continue;
- }
- child->SetKeyBoardInputEnabled( state );
- }
-
- // If turning off keyboard input enable, then make sure
- // this panel is not the current key focus of a parent panel
- if ( !state )
- {
- Panel *pParent = GetParent();
- if ( pParent )
- {
- if ( pParent->GetCurrentKeyFocus() == GetVPanel() )
- {
- pParent->RequestFocusNext();
- }
- }
- }
-}
-
-void Panel::SetMouseInputEnabled( bool state )
-{
- ipanel()->SetMouseInputEnabled( GetVPanel(), state );
- /* for(int i=0;i<GetChildCount();i++)
- {
- GetChild(i)->SetMouseInput(state);
- }*/
- vgui::surface()->CalculateMouseVisible();
-}
-
-bool Panel::IsKeyBoardInputEnabled()
-{
- return ipanel()->IsKeyBoardInputEnabled( GetVPanel() );
-}
-
-bool Panel::IsMouseInputEnabled()
-{
- return ipanel()->IsMouseInputEnabled( GetVPanel() );
-}
-
-class CFloatProperty : public vgui::IPanelAnimationPropertyConverter
-{
-public:
- virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- kv->SetFloat( entry->name(), *(float *)data );
- }
-
- virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- *(float *)data = kv->GetFloat( entry->name() );
- }
-
- virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- *(float *)data = atof( entry->defaultvalue() );
- }
-};
-
-class CProportionalFloatProperty : public vgui::IPanelAnimationPropertyConverter
-{
-public:
- virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- float f = *(float *)data;
- f = scheme()->GetProportionalNormalizedValueEx( panel->GetScheme(), f );
- kv->SetFloat( entry->name(), f );
- }
-
- virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- float f = kv->GetFloat( entry->name() );
- f = scheme()->GetProportionalScaledValueEx( panel->GetScheme(), f );
- *(float *)data = f;
- }
-
- virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- float f = atof( entry->defaultvalue() );
- f = scheme()->GetProportionalScaledValueEx( panel->GetScheme(), f );
- *(float *)data = f;
- }
-};
-
-class CIntProperty : public vgui::IPanelAnimationPropertyConverter
-{
-public:
- virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- kv->SetInt( entry->name(), *(int *)data );
- }
-
- virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- *(int *)data = kv->GetInt( entry->name() );
- }
-
- virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- *(int *)data = atoi( entry->defaultvalue() );
- }
-};
-
-class CProportionalIntProperty : public vgui::IPanelAnimationPropertyConverter
-{
-public:
- virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- int i = *(int *)data;
- i = scheme()->GetProportionalNormalizedValueEx( panel->GetScheme(), i );
- kv->SetInt( entry->name(), i );
- }
-
- virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- int i = kv->GetInt( entry->name() );
- i = scheme()->GetProportionalScaledValueEx( panel->GetScheme(), i );
- *(int *)data = i;
- }
- virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- int i = atoi( entry->defaultvalue() );
- i = scheme()->GetProportionalScaledValueEx( panel->GetScheme(), i );
- *(int *)data = i;
- }
-};
-
-class CProportionalIntWithScreenspacePropertyX : public vgui::IPanelAnimationPropertyConverter
-{
-public:
- int ExtractValue( Panel *panel, const char *pszKey )
- {
- int iValue = 0;
- bool bRightAlign = false;
- bool bCenterAlign = false;
- if (pszKey[0] == 'r' || pszKey[0] == 'R')
- {
- bRightAlign = true;
- pszKey++;
- }
- else if (pszKey[0] == 'c' || pszKey[0] == 'C')
- {
- bCenterAlign = true;
- pszKey++;
- }
-
- // get the value
- iValue = atoi(pszKey);
- iValue = scheme()->GetProportionalScaledValueEx(panel->GetScheme(), iValue);
-
- int screenSize = GetScreenSize();
- // now correct the alignment
- if ( bRightAlign )
- {
- iValue = screenSize - iValue;
- }
- else if ( bCenterAlign )
- {
- iValue = (screenSize / 2) + iValue;
- }
-
- return iValue;
- }
-
- virtual int GetScreenSize( void )
- {
- int screenWide, screenTall;
- surface()->GetScreenSize(screenWide, screenTall);
- return screenWide;
- }
-
- virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
- {
- // Won't work with this, don't use it.
- Assert(0);
- }
-
- virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- *(int *)data = ExtractValue( panel, kv->GetString( entry->name() ) );
- }
- virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- *(int *)data = ExtractValue( panel, entry->defaultvalue() );
- }
-};
-
-class CProportionalIntWithScreenspacePropertyY : public CProportionalIntWithScreenspacePropertyX
-{
-public:
- virtual int GetScreenSize( void )
- {
- int screenWide, screenTall;
- surface()->GetScreenSize(screenWide, screenTall);
- return screenTall;
- }
-};
-
-class CColorProperty : public vgui::IPanelAnimationPropertyConverter
-{
-public:
- virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- kv->SetColor( entry->name(), *(Color *)data );
- }
-
- virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
- {
- vgui::IScheme *scheme = vgui::scheme()->GetIScheme( panel->GetScheme() );
- Assert( scheme );
- if ( scheme )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
-
- char const *colorName = kv->GetString( entry->name() );
- if ( !colorName || !colorName[0] )
- {
- *(Color *)data = kv->GetColor( entry->name() );
- }
- else
- {
- *(Color *)data = scheme->GetColor( colorName, Color( 0, 0, 0, 0 ) );
- }
- }
- }
-
- virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
- {
- vgui::IScheme *scheme = vgui::scheme()->GetIScheme( panel->GetScheme() );
- Assert( scheme );
- if ( scheme )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- *(Color *)data = scheme->GetColor( entry->defaultvalue(), Color( 0, 0, 0, 0 ) );
- }
- }
-};
-
-class CBoolProperty : public vgui::IPanelAnimationPropertyConverter
-{
-public:
- virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- kv->SetInt( entry->name(), *(bool *)data ? 1 : 0 );
- }
-
- virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- *(bool *)data = kv->GetInt( entry->name() ) ? true : false;
- }
-
- virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- bool b = false;
- if ( !stricmp( entry->defaultvalue(), "true" )||
- atoi( entry->defaultvalue() )!= 0 )
- {
- b = true;
- }
-
- *(bool *)data = b;
- }
-};
-
-class CStringProperty : public vgui::IPanelAnimationPropertyConverter
-{
-public:
- virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- kv->SetString( entry->name(), (char *)data );
- }
-
- virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- strcpy( (char *)data, kv->GetString( entry->name() ) );
- }
-
- virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- strcpy( ( char * )data, entry->defaultvalue() );
- }
-};
-
-class CHFontProperty : public vgui::IPanelAnimationPropertyConverter
-{
-public:
- virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
- {
- vgui::IScheme *scheme = vgui::scheme()->GetIScheme( panel->GetScheme() );
- Assert( scheme );
- if ( scheme )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- char const *fontName = scheme->GetFontName( *(HFont *)data );
- kv->SetString( entry->name(), fontName );
- }
- }
-
- virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
- {
- vgui::IScheme *scheme = vgui::scheme()->GetIScheme( panel->GetScheme() );
- Assert( scheme );
- if ( scheme )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- char const *fontName = kv->GetString( entry->name() );
- *(HFont *)data = scheme->GetFont( fontName, panel->IsProportional() );
- }
- }
-
- virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
- {
- vgui::IScheme *scheme = vgui::scheme()->GetIScheme( panel->GetScheme() );
- Assert( scheme );
- if ( scheme )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- *(HFont *)data = scheme->GetFont( entry->defaultvalue(), panel->IsProportional() );
- }
- }
-};
-
-class CTextureIdProperty : public vgui::IPanelAnimationPropertyConverter
-{
-public:
- virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
- int currentId = *(int *)data;
-
- // lookup texture name for id
- char texturename[ 512 ];
- if ( currentId != -1 &&
- surface()->DrawGetTextureFile( currentId, texturename, sizeof( texturename ) ) )
- {
- kv->SetString( entry->name(), texturename );
- }
- else
- {
- kv->SetString( entry->name(), "" );
- }
- }
-
- virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
-
- int currentId = -1;
-
- char const *texturename = kv->GetString( entry->name() );
- if ( texturename && texturename[ 0 ] )
- {
- currentId = surface()->DrawGetTextureId( texturename );
- if ( currentId == -1 )
- {
- currentId = surface()->CreateNewTextureID();
- }
- surface()->DrawSetTextureFile( currentId, texturename, false, true );
- }
-
- *(int *)data = currentId;
- }
-
- virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
- {
- void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
-
- int currentId = -1;
-
- char const *texturename = entry->defaultvalue();
- if ( texturename && texturename[ 0 ] )
- {
- currentId = surface()->DrawGetTextureId( texturename );
- if ( currentId == -1 )
- {
- currentId = surface()->CreateNewTextureID();
- }
- surface()->DrawSetTextureFile( currentId, texturename, false, true );
- }
-
- *(int *)data = currentId;
- }
-};
-
-static CFloatProperty floatconverter;
-static CProportionalFloatProperty p_floatconverter;
-static CIntProperty intconverter;
-static CProportionalIntProperty p_intconverter;
-static CProportionalIntWithScreenspacePropertyX p_screenspace_intconverter_X;
-static CProportionalIntWithScreenspacePropertyY p_screenspace_intconverter_Y;
-static CColorProperty colorconverter;
-static CBoolProperty boolconverter;
-static CStringProperty stringconverter;
-static CHFontProperty fontconverter;
-static CTextureIdProperty textureidconverter;
-//static CProportionalXPosProperty xposconverter;
-//static CProportionalYPosProperty yposconverter;
-
-static CUtlDict< IPanelAnimationPropertyConverter *, int > g_AnimationPropertyConverters;
-
-static IPanelAnimationPropertyConverter *FindConverter( char const *typeName )
-{
- int lookup = g_AnimationPropertyConverters.Find( typeName );
- if ( lookup == g_AnimationPropertyConverters.InvalidIndex() )
- return NULL;
-
- IPanelAnimationPropertyConverter *converter = g_AnimationPropertyConverters[ lookup ];
- return converter;
-}
-
-void Panel::AddPropertyConverter( char const *typeName, IPanelAnimationPropertyConverter *converter )
-{
- int lookup = g_AnimationPropertyConverters.Find( typeName );
- if ( lookup != g_AnimationPropertyConverters.InvalidIndex() )
- {
- Msg( "Already have converter for type %s, ignoring...\n", typeName );
- return;
- }
-
- g_AnimationPropertyConverters.Insert( typeName, converter );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Static method to initialize all needed converters
-//-----------------------------------------------------------------------------
-void Panel::InitPropertyConverters( void )
-{
- static bool initialized = false;
- if ( initialized )
- return;
- initialized = true;
-
- AddPropertyConverter( "float", &floatconverter );
- AddPropertyConverter( "int", &intconverter );
- AddPropertyConverter( "Color", &colorconverter );
- //AddPropertyConverter( "vgui::Color", &colorconverter );
- AddPropertyConverter( "bool", &boolconverter );
- AddPropertyConverter( "char", &stringconverter );
- AddPropertyConverter( "string", &stringconverter );
- AddPropertyConverter( "HFont", &fontconverter );
- AddPropertyConverter( "vgui::HFont", &fontconverter );
-
- // This is an aliased type for proportional float
- AddPropertyConverter( "proportional_float", &p_floatconverter );
- AddPropertyConverter( "proportional_int", &p_intconverter );
-
- AddPropertyConverter( "proportional_xpos", &p_screenspace_intconverter_X );
- AddPropertyConverter( "proportional_ypos", &p_screenspace_intconverter_Y );
-
- AddPropertyConverter( "textureid", &textureidconverter );
-}
-
-bool Panel::InternalRequestInfo( PanelAnimationMap *map, KeyValues *outputData )
-{
- if ( !map )
- return false;
-
- Assert( outputData );
-
- char const *name = outputData->GetName();
-
- PanelAnimationMapEntry *e = FindPanelAnimationEntry( name, map );
- if ( e )
- {
- IPanelAnimationPropertyConverter *converter = FindConverter( e->type() );
- if ( converter )
- {
- converter->GetData( this, outputData, e );
- return true;
- }
- }
-
- return false;
-}
-
-bool Panel::InternalSetInfo( PanelAnimationMap *map, KeyValues *inputData )
-{
- if ( !map )
- return false;
-
- Assert( inputData );
-
- char const *name = inputData->GetName();
-
- PanelAnimationMapEntry *e = FindPanelAnimationEntry( name, map );
- if ( e )
- {
- IPanelAnimationPropertyConverter *converter = FindConverter( e->type() );
- if ( converter )
- {
- converter->SetData( this, inputData, e );
- return true;
- }
- }
-
- return false;
-}
-
-PanelAnimationMapEntry *Panel::FindPanelAnimationEntry( char const *scriptname, PanelAnimationMap *map )
-{
- if ( !map )
- return NULL;
-
- Assert( scriptname );
-
- // Look through mapping for entry
- int c = map->entries.Count();
- for ( int i = 0; i < c; i++ )
- {
- PanelAnimationMapEntry *e = &map->entries[ i ];
-
- if ( !stricmp( e->name(), scriptname ) )
- {
- return e;
- }
- }
-
- // Recurse
- if ( map->baseMap )
- {
- return FindPanelAnimationEntry( scriptname, map->baseMap );
- }
-
- return NULL;
-}
-
-// Recursively invoke settings for PanelAnimationVars
-void Panel::InternalApplySettings( PanelAnimationMap *map, KeyValues *inResourceData)
-{
- // Loop through keys
- KeyValues *kv;
-
- for ( kv = inResourceData->GetFirstSubKey(); kv; kv = kv->GetNextKey() )
- {
- char const *varname = kv->GetName();
-
- PanelAnimationMapEntry *entry = FindPanelAnimationEntry( varname, GetAnimMap() );
- if ( entry )
- {
- // Set value to value from script
- IPanelAnimationPropertyConverter *converter = FindConverter( entry->type() );
- if ( converter )
- {
- converter->SetData( this, inResourceData, entry );
- }
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: sets the default values of all CPanelAnimationVars
-//-----------------------------------------------------------------------------
-void Panel::InternalInitDefaultValues( PanelAnimationMap *map )
-{
- _flags.ClearFlag( NEEDS_DEFAULT_SETTINGS_APPLIED );
-
- // Look through mapping for entry
- int c = map->entries.Count();
- for ( int i = 0; i < c; i++ )
- {
- PanelAnimationMapEntry *e = &map->entries[ i ];
- Assert( e );
- IPanelAnimationPropertyConverter *converter = FindConverter( e->type() );
- if ( !converter )
- continue;
-
- converter->InitFromDefault( this, e );
- }
-
- if ( map->baseMap )
- {
- InternalInitDefaultValues( map->baseMap );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-//-----------------------------------------------------------------------------
-int Panel::GetPaintBackgroundType()
-{
- return m_nPaintBackgroundType;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : w -
-// h -
-//-----------------------------------------------------------------------------
-void Panel::GetCornerTextureSize( int& w, int& h )
-{
- if ( m_nBgTextureId1 == -1 )
- {
- w = h = 0;
- return;
- }
- surface()->DrawGetTextureSize(m_nBgTextureId1, w, h);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: draws a selection box
-//-----------------------------------------------------------------------------
-void Panel::DrawBox(int x, int y, int wide, int tall, Color color, float normalizedAlpha, bool hollow /*=false*/ )
-{
- if ( m_nBgTextureId1 == -1 ||
- m_nBgTextureId2 == -1 ||
- m_nBgTextureId3 == -1 ||
- m_nBgTextureId4 == -1 )
- {
- return;
- }
-
- color[3] *= normalizedAlpha;
-
- // work out our bounds
- int cornerWide, cornerTall;
- GetCornerTextureSize( cornerWide, cornerTall );
-
- // draw the background in the areas not occupied by the corners
- // draw it in three horizontal strips
- surface()->DrawSetColor(color);
- surface()->DrawFilledRect(x + cornerWide, y, x + wide - cornerWide, y + cornerTall);
- if ( !hollow )
- {
- surface()->DrawFilledRect(x, y + cornerTall, x + wide, y + tall - cornerTall);
- }
- else
- {
- surface()->DrawFilledRect(x, y + cornerTall, x + cornerWide, y + tall - cornerTall);
- surface()->DrawFilledRect(x + wide - cornerWide, y + cornerTall, x + wide, y + tall - cornerTall);
- }
- surface()->DrawFilledRect(x + cornerWide, y + tall - cornerTall, x + wide - cornerWide, y + tall);
-
- // draw the corners
-
- //=============================================================================
- // HPE_BEGIN:
- // [tj] We now check each individual corner and decide whether to draw it straight or rounded
- //=============================================================================
- //TOP-LEFT
- if (ShouldDrawTopLeftCornerRounded())
- {
- surface()->DrawSetTexture(m_nBgTextureId1);
- surface()->DrawTexturedRect(x, y, x + cornerWide, y + cornerTall);
- }
- else
- {
- surface()->DrawFilledRect(x, y, x + cornerWide, y + cornerTall);
- }
-
-
- //TOP-RIGHT
- if (ShouldDrawTopRightCornerRounded())
- {
- surface()->DrawSetTexture(m_nBgTextureId2);
- surface()->DrawTexturedRect(x + wide - cornerWide, y, x + wide, y + cornerTall);
- }
- else
- {
- surface()->DrawFilledRect(x + wide - cornerWide, y, x + wide, y + cornerTall);
- }
-
- //BOTTOM-LEFT
- if (ShouldDrawBottomLeftCornerRounded())
- {
- surface()->DrawSetTexture(m_nBgTextureId4);
- surface()->DrawTexturedRect(x + 0, y + tall - cornerTall, x + cornerWide, y + tall);
- }
- else
- {
- surface()->DrawFilledRect(x + 0, y + tall - cornerTall, x + cornerWide, y + tall);
- }
-
-
- //BOTTOM-RIGHT
- if (ShouldDrawBottomRightCornerRounded())
- {
- surface()->DrawSetTexture(m_nBgTextureId3);
- surface()->DrawTexturedRect(x + wide - cornerWide, y + tall - cornerTall, x + wide, y + tall);
- }
- else
- {
- surface()->DrawFilledRect(x + wide - cornerWide, y + tall - cornerTall, x + wide, y + tall);
- }
- //=============================================================================
- // HPE_END
- //=============================================================================
-}
-
-void Panel::DrawBoxFade(int x, int y, int wide, int tall, Color color, float normalizedAlpha, unsigned int alpha0, unsigned int alpha1, bool bHorizontal, bool hollow /*=false*/ )
-{
- if ( m_nBgTextureId1 == -1 ||
- m_nBgTextureId2 == -1 ||
- m_nBgTextureId3 == -1 ||
- m_nBgTextureId4 == -1 ||
- surface()->DrawGetAlphaMultiplier() == 0 )
- {
- return;
- }
-
- color[3] *= normalizedAlpha;
-
- // work out our bounds
- int cornerWide, cornerTall;
- GetCornerTextureSize( cornerWide, cornerTall );
-
- if ( !bHorizontal )
- {
- // draw the background in the areas not occupied by the corners
- // draw it in three horizontal strips
- surface()->DrawSetColor(color);
- surface()->DrawFilledRectFade(x + cornerWide, y, x + wide - cornerWide, y + cornerTall, alpha0, alpha0, bHorizontal );
- if ( !hollow )
- {
- surface()->DrawFilledRectFade(x, y + cornerTall, x + wide, y + tall - cornerTall, alpha0, alpha1, bHorizontal);
- }
- else
- {
- surface()->DrawFilledRectFade(x, y + cornerTall, x + cornerWide, y + tall - cornerTall, alpha0, alpha1, bHorizontal);
- surface()->DrawFilledRectFade(x + wide - cornerWide, y + cornerTall, x + wide, y + tall - cornerTall, alpha0, alpha1, bHorizontal);
- }
- surface()->DrawFilledRectFade(x + cornerWide, y + tall - cornerTall, x + wide - cornerWide, y + tall, alpha1, alpha1, bHorizontal);
- }
- else
- {
- // draw the background in the areas not occupied by the corners
- // draw it in three horizontal strips
- surface()->DrawSetColor(color);
- surface()->DrawFilledRectFade(x, y + cornerTall, x + cornerWide, y + tall - cornerTall, alpha0, alpha0, bHorizontal );
- if ( !hollow )
- {
- surface()->DrawFilledRectFade(x + cornerWide, y, x + wide - cornerWide, y + tall, alpha0, alpha1, bHorizontal);
- }
- else
- {
- // FIXME: Hollow horz version not implemented
- //surface()->DrawFilledRectFade(x, y + cornerTall, x + cornerWide, y + tall - cornerTall, alpha0, alpha1, bHorizontal);
- //surface()->DrawFilledRectFade(x + wide - cornerWide, y + cornerTall, x + wide, y + tall - cornerTall, alpha0, alpha1, bHorizontal);
- }
- surface()->DrawFilledRectFade(x + wide - cornerWide, y + cornerTall, x + wide, y + tall - cornerTall, alpha1, alpha1, bHorizontal);
- }
-
- float fOldAlpha = color[ 3 ];
- int iAlpha0 = fOldAlpha * ( static_cast<float>( alpha0 ) / 255.0f );
- int iAlpha1 = fOldAlpha * ( static_cast<float>( alpha1 ) / 255.0f );
-
- // draw the corners
- if ( !bHorizontal )
- {
- color[ 3 ] = iAlpha0;
- surface()->DrawSetColor( color );
- surface()->DrawSetTexture(m_nBgTextureId1);
- surface()->DrawTexturedRect(x, y, x + cornerWide, y + cornerTall);
- surface()->DrawSetTexture(m_nBgTextureId2);
- surface()->DrawTexturedRect(x + wide - cornerWide, y, x + wide, y + cornerTall);
-
- color[ 3 ] = iAlpha1;
- surface()->DrawSetColor( color );
- surface()->DrawSetTexture(m_nBgTextureId3);
- surface()->DrawTexturedRect(x + wide - cornerWide, y + tall - cornerTall, x + wide, y + tall);
- surface()->DrawSetTexture(m_nBgTextureId4);
- surface()->DrawTexturedRect(x + 0, y + tall - cornerTall, x + cornerWide, y + tall);
- }
- else
- {
- color[ 3 ] = iAlpha0;
- surface()->DrawSetColor( color );
- surface()->DrawSetTexture(m_nBgTextureId1);
- surface()->DrawTexturedRect(x, y, x + cornerWide, y + cornerTall);
- surface()->DrawSetTexture(m_nBgTextureId4);
- surface()->DrawTexturedRect(x + 0, y + tall - cornerTall, x + cornerWide, y + tall);
-
- color[ 3 ] = iAlpha1;
- surface()->DrawSetColor( color );
- surface()->DrawSetTexture(m_nBgTextureId2);
- surface()->DrawTexturedRect(x + wide - cornerWide, y, x + wide, y + cornerTall);
- surface()->DrawSetTexture(m_nBgTextureId3);
- surface()->DrawTexturedRect(x + wide - cornerWide, y + tall - cornerTall, x + wide, y + tall);
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : x -
-// y -
-// wide -
-// tall -
-// color -
-// normalizedAlpha -
-//-----------------------------------------------------------------------------
-void Panel::DrawHollowBox(int x, int y, int wide, int tall, Color color, float normalizedAlpha )
-{
- DrawBox( x, y, wide, tall, color, normalizedAlpha, true );
-}
-
-//=============================================================================
-// HPE_BEGIN:
-// [menglish] Draws a hollow box similar to the already existing draw hollow box function, but takes the indents as params
-//=============================================================================
-
-void Panel::DrawHollowBox( int x, int y, int wide, int tall, Color color, float normalizedAlpha, int cornerWide, int cornerTall )
-{
- if ( m_nBgTextureId1 == -1 ||
- m_nBgTextureId2 == -1 ||
- m_nBgTextureId3 == -1 ||
- m_nBgTextureId4 == -1 )
- {
- return;
- }
-
- color[3] *= normalizedAlpha;
-
- // draw the background in the areas not occupied by the corners
- // draw it in three horizontal strips
- surface()->DrawSetColor(color);
- surface()->DrawFilledRect(x + cornerWide, y, x + wide - cornerWide, y + cornerTall);
- surface()->DrawFilledRect(x, y + cornerTall, x + cornerWide, y + tall - cornerTall);
- surface()->DrawFilledRect(x + wide - cornerWide, y + cornerTall, x + wide, y + tall - cornerTall);
- surface()->DrawFilledRect(x + cornerWide, y + tall - cornerTall, x + wide - cornerWide, y + tall);
-
- // draw the corners
- surface()->DrawSetTexture(m_nBgTextureId1);
- surface()->DrawTexturedRect(x, y, x + cornerWide, y + cornerTall);
- surface()->DrawSetTexture(m_nBgTextureId2);
- surface()->DrawTexturedRect(x + wide - cornerWide, y, x + wide, y + cornerTall);
- surface()->DrawSetTexture(m_nBgTextureId3);
- surface()->DrawTexturedRect(x + wide - cornerWide, y + tall - cornerTall, x + wide, y + tall);
- surface()->DrawSetTexture(m_nBgTextureId4);
- surface()->DrawTexturedRect(x + 0, y + tall - cornerTall, x + cornerWide, y + tall);
-}
-
-//=============================================================================
-// HPE_END
-//=============================================================================
-
-//-----------------------------------------------------------------------------
-// Purpose: draws a selection box
-//-----------------------------------------------------------------------------
-void Panel::DrawTexturedBox(int x, int y, int wide, int tall, Color color, float normalizedAlpha )
-{
- if ( m_nBgTextureId1 == -1 )
- return;
-
- color[3] *= normalizedAlpha;
-
- surface()->DrawSetColor( color );
- surface()->DrawSetTexture(m_nBgTextureId1);
- surface()->DrawTexturedRect(x, y, x + wide, y + tall);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Marks this panel as draggable (note that children will chain to their parents to see if any parent is draggable)
-// Input : enabled -
-//-----------------------------------------------------------------------------
-void Panel::SetDragEnabled( bool enabled )
-{
-#if defined( VGUI_USEDRAGDROP )
- // If turning it off, quit dragging if mid-drag
- if ( !enabled &&
- m_pDragDrop->m_bDragging )
- {
- OnFinishDragging( false, (MouseCode)-1 );
- }
- m_pDragDrop->m_bDragEnabled = enabled;
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool Panel::IsDragEnabled() const
-{
-#if defined( VGUI_USEDRAGDROP )
- return m_pDragDrop->m_bDragEnabled;
-#endif
- return false;
-}
-
-void Panel::SetShowDragHelper( bool enabled )
-{
-#if defined( VGUI_USEDRAGDROP )
- m_pDragDrop->m_bShowDragHelper = enabled;
-#endif
-}
-
-// Use this to prevent chaining up from a parent which can mess with mouse functionality if you don't want to chain up from a child panel to the best
-// draggable parent.
-void Panel::SetBlockDragChaining( bool block )
-{
-#if defined( VGUI_USEDRAGDROP )
- m_pDragDrop->m_bPreventChaining = block;
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool Panel::IsBlockingDragChaining() const
-{
-#if defined( VGUI_USEDRAGDROP )
- return m_pDragDrop->m_bPreventChaining;
-#endif
- return true;
-}
-
-
-//-----------------------------------------------------------------------------
-// accessors for m_nDragStartTolerance
-//-----------------------------------------------------------------------------
-int Panel::GetDragStartTolerance() const
-{
-#if defined( VGUI_USEDRAGDROP )
- return m_pDragDrop->m_nDragStartTolerance;
-#endif
- return 0;
-}
-
-void Panel::SetDragSTartTolerance( int nTolerance )
-{
-#if defined( VGUI_USEDRAGDROP )
- m_pDragDrop->m_nDragStartTolerance = nTolerance;
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Marks this panel as droppable ( note that children will chain to their parents to see if any parent is droppable)
-// Input : enabled -
-//-----------------------------------------------------------------------------
-void Panel::SetDropEnabled( bool enabled, float flHoverContextTime /* = 0.0f */ )
-{
-#if defined( VGUI_USEDRAGDROP )
- m_pDragDrop->m_bDropEnabled = enabled;
- m_pDragDrop->m_flHoverContextTime = flHoverContextTime;
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool Panel::IsDropEnabled() const
-{
-#if defined( VGUI_USEDRAGDROP )
- return m_pDragDrop->m_bDropEnabled;
-#endif
- return false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Chains up to any parent
-// 1) marked DropEnabled; and
-// 2) willing to accept the drop payload
-// Input : -
-// Output : Panel
-//-----------------------------------------------------------------------------
-Panel *Panel::GetDropTarget( CUtlVector< KeyValues * >& msglist )
-{
-#if defined( VGUI_USEDRAGDROP )
- // Found one
- if ( m_pDragDrop->m_bDropEnabled &&
- IsDroppable( msglist ) )
- {
- return this;
- }
-
- // Chain up
- if ( GetParent() )
- {
- return GetParent()->GetDropTarget( msglist );
- }
-#endif
- // No luck
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Chains up to first parent marked DragEnabled
-// Input : -
-// Output : Panel
-//-----------------------------------------------------------------------------
-Panel *Panel::GetDragPanel()
-{
-#if defined( VGUI_USEDRAGDROP )
- // If we encounter a blocker, stop chaining
- if ( m_pDragDrop->m_bPreventChaining )
- return NULL;
-
- if ( m_pDragDrop->m_bDragEnabled )
- return this;
-
- // Chain up
- if ( GetParent() )
- {
- return GetParent()->GetDragPanel();
- }
-#endif
- // No luck
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-//-----------------------------------------------------------------------------
-void Panel::OnStartDragging()
-{
-#if defined( VGUI_USEDRAGDROP )
- // Only left mouse initiates drag/drop.
- // FIXME: Revisit?
- if ( !input()->IsMouseDown( MOUSE_LEFT ) )
- return;
-
- if ( !m_pDragDrop->m_bDragEnabled )
- return;
-
- if ( m_pDragDrop->m_bDragging )
- return;
-
- g_DragDropCapture = this;
-
- m_pDragDrop->m_bDragStarted = false;
- m_pDragDrop->m_bDragging = true;
- input()->GetCursorPos( m_pDragDrop->m_nStartPos[ 0 ], m_pDragDrop->m_nStartPos[ 1 ] );
- m_pDragDrop->m_nLastPos[ 0 ] = m_pDragDrop->m_nStartPos[ 0 ];
- m_pDragDrop->m_nLastPos[ 1 ] = m_pDragDrop->m_nStartPos[ 1 ];
-
- OnContinueDragging();
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Called if drag drop is started but not dropped on top of droppable panel...
-// Input : -
-//-----------------------------------------------------------------------------
-void Panel::OnDragFailed( CUtlVector< KeyValues * >& msglist )
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-//-----------------------------------------------------------------------------
-void Panel::OnFinishDragging( bool mousereleased, MouseCode code, bool abort /*= false*/ )
-{
-#if defined( VGUI_USEDRAGDROP )
- g_DragDropCapture = NULL;
-
- if ( !m_pDragDrop->m_bDragEnabled )
- return;
-
- Assert( m_pDragDrop->m_bDragging );
-
- if ( !m_pDragDrop->m_bDragging )
- return;
-
- int x, y;
- input()->GetCursorPos( x, y );
-
- m_pDragDrop->m_nLastPos[ 0 ] = x;
- m_pDragDrop->m_nLastPos[ 1 ] = y;
-
- if ( s_DragDropHelper.Get() )
- {
- s_DragDropHelper->RemovePanel( this );
- }
-
- m_pDragDrop->m_bDragging = false;
-
- CUtlVector< KeyValues * >& data = m_pDragDrop->m_DragData;
- int c = data.Count();
-
- Panel *target = NULL;
- bool shouldDrop = false;
-
- if ( m_pDragDrop->m_bDragStarted )
- {
- char cmd[ 256 ];
- Q_strncpy( cmd, "default", sizeof( cmd ) );
-
- if ( mousereleased &&
- m_pDragDrop->m_hCurrentDrop != 0 &&
- m_pDragDrop->m_hDropContextMenu.Get() )
- {
- Menu *menu = m_pDragDrop->m_hDropContextMenu;
-
- VPANEL hover = menu->IsWithinTraverse( x, y, false );
- if ( hover )
- {
- Panel *pHover = ipanel()->GetPanel( hover, GetModuleName() );
- if ( pHover )
- {
- // Figure out if it's a menu item...
- int c = menu->GetItemCount();
- for ( int i = 0; i < c; ++i )
- {
- int id = menu->GetMenuID( i );
- MenuItem *item = menu->GetMenuItem( id );
- if ( item == pHover )
- {
- KeyValues *command = item->GetCommand();
- if ( command )
- {
- char const *p = command->GetString( "command", "" );
- if ( p && p[ 0 ] )
- {
- Q_strncpy( cmd, p, sizeof( cmd ) );
- }
- }
- }
- }
- }
- }
-
- delete menu;
- m_pDragDrop->m_hDropContextMenu = NULL;
- }
-
- for ( int i = 0 ; i < c; ++i )
- {
- KeyValues *msg = data[ i ];
-
- msg->SetString( "command", cmd );
-
- msg->SetInt( "screenx", x );
- msg->SetInt( "screeny", y );
- }
-
- target = m_pDragDrop->m_hCurrentDrop.Get();
- if ( target && !abort )
- {
- int localmousex = x, localmousey = y;
- // Convert screen space coordintes to coordinates relative to drop window
- target->ScreenToLocal( localmousex, localmousey );
-
- for ( int i = 0 ; i < c; ++i )
- {
- KeyValues *msg = data[ i ];
-
- msg->SetInt( "x", localmousex );
- msg->SetInt( "y", localmousey );
- }
-
- shouldDrop = true;
- }
-
- if ( !shouldDrop )
- {
- OnDragFailed( data );
- }
- }
-
- m_pDragDrop->m_bDragStarted = false;
- m_pDragDrop->m_DragPanels.RemoveAll();
- m_pDragDrop->m_hCurrentDrop = NULL;
-
- // Copy data ptrs out of data because OnPanelDropped might cause this panel to be deleted
- // and our this ptr will be hosed...
- CUtlVector< KeyValues * > temp;
- for ( int i = 0 ; i < c; ++i )
- {
- temp.AddToTail( data[ i ] );
- }
- data.RemoveAll();
-
- if ( shouldDrop && target )
- {
- target->OnPanelDropped( temp );
- }
- for ( int i = 0 ; i < c ; ++i )
- {
- temp[ i ]->deleteThis();
- }
-#endif
-}
-
-void Panel::OnDropContextHoverShow( CUtlVector< KeyValues * >& msglist )
-{
-}
-
-void Panel::OnDropContextHoverHide( CUtlVector< KeyValues * >& msglist )
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *msg -
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool Panel::IsDroppable( CUtlVector< KeyValues * >& msglist )
-{
- return false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : startx -
-// starty -
-// mx -
-// my -
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool Panel::CanStartDragging( int startx, int starty, int mx, int my )
-{
-#if defined( VGUI_USEDRAGDROP )
- if ( IsStartDragWhenMouseExitsPanel() )
- {
- ScreenToLocal( mx, my );
- if ( mx < 0 || my < 0 )
- return true;
- if ( mx > GetWide() || my > GetTall() )
- return true;
-
- return false;
- }
-
- int deltax = abs( mx - startx );
- int deltay = abs( my - starty );
- if ( deltax > m_pDragDrop->m_nDragStartTolerance ||
- deltay > m_pDragDrop->m_nDragStartTolerance )
- {
- return true;
- }
-#endif
- return false;
-}
-
-HCursor Panel::GetDropCursor( CUtlVector< KeyValues * >& msglist )
-{
- return dc_arrow;
-}
-
-bool IsSelfDroppable( CUtlVector< KeyValues * > &dragData )
-{
- if ( dragData.Count() == 0 )
- return false;
-
- KeyValues *pKeyValues( dragData[ 0 ] );
- if ( !pKeyValues )
- return false;
-
- return pKeyValues->GetInt( "selfDroppable" ) != 0;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-//-----------------------------------------------------------------------------
-void Panel::OnContinueDragging()
-{
-#if defined( VGUI_USEDRAGDROP )
- if ( !m_pDragDrop->m_bDragEnabled )
- return;
-
- if ( !m_pDragDrop->m_bDragging )
- return;
-
- int x, y;
- input()->GetCursorPos( x, y );
-
- // Update last position
- m_pDragDrop->m_nLastPos[ 0 ] = x;
- m_pDragDrop->m_nLastPos[ 1 ] = y;
-
- if ( !m_pDragDrop->m_bDragStarted )
- {
- if ( CanStartDragging( m_pDragDrop->m_nStartPos[ 0 ], m_pDragDrop->m_nStartPos[ 1 ], x, y ) )
- {
- m_pDragDrop->m_bDragStarted = true;
- CreateDragData();
- }
- else
- {
- return;
- }
- }
-
- if ( !s_DragDropHelper.Get() && m_pDragDrop->m_bShowDragHelper )
- {
- s_DragDropHelper = new CDragDropHelperPanel();
- s_DragDropHelper->SetKeyBoardInputEnabled( false );
- s_DragDropHelper->SetMouseInputEnabled( false );
- Assert( s_DragDropHelper.Get() );
- }
-
- if ( !s_DragDropHelper.Get() )
- return;
-
- s_DragDropHelper->AddPanel( this );
-
- Assert( m_pDragDrop->m_DragData.Count() );
-
- vgui::PHandle oldDrop = m_pDragDrop->m_hCurrentDrop;
-
- // See what's under that
- m_pDragDrop->m_hCurrentDrop = NULL;
-
- // Search under mouse pos...
- Panel *dropTarget = FindDropTargetPanel();
- if ( dropTarget )
- {
- dropTarget = dropTarget->GetDropTarget( m_pDragDrop->m_DragData );
- }
-
- // it's not okay until we find a droppable panel
- surface()->SetCursor( dc_no );
-
- if ( dropTarget )
- {
- if ( dropTarget != this || IsSelfDroppable( m_pDragDrop->m_DragData ) )
- {
- m_pDragDrop->m_hCurrentDrop = dropTarget;
- surface()->SetCursor( dropTarget->GetDropCursor( m_pDragDrop->m_DragData ) );
- }
- }
-
- if ( m_pDragDrop->m_hCurrentDrop.Get() != oldDrop.Get() )
- {
- if ( oldDrop.Get() )
- {
- oldDrop->OnPanelExitedDroppablePanel( m_pDragDrop->m_DragData );
- }
-
- if ( m_pDragDrop->m_hCurrentDrop.Get() )
- {
- m_pDragDrop->m_hCurrentDrop->OnPanelEnteredDroppablePanel( m_pDragDrop->m_DragData );
- m_pDragDrop->m_hCurrentDrop->OnDropContextHoverHide( m_pDragDrop->m_DragData );
-
- // Reset hover time
- m_pDragDrop->m_lDropHoverTime = system()->GetTimeMillis();
- m_pDragDrop->m_bDropMenuShown = false;
- }
-
- // Discard any stale context menu...
- if ( m_pDragDrop->m_hDropContextMenu.Get() )
- {
- delete m_pDragDrop->m_hDropContextMenu.Get();
- }
- }
-
- if ( m_pDragDrop->m_hCurrentDrop != 0 &&
- m_pDragDrop->m_hDropContextMenu.Get() )
- {
- Menu *menu = m_pDragDrop->m_hDropContextMenu;
-
- VPANEL hover = menu->IsWithinTraverse( x, y, false );
- if ( hover )
- {
- Panel *pHover = ipanel()->GetPanel( hover, GetModuleName() );
- if ( pHover )
- {
- // Figure out if it's a menu item...
- int c = menu->GetItemCount();
- for ( int i = 0; i < c; ++i )
- {
- int id = menu->GetMenuID( i );
- MenuItem *item = menu->GetMenuItem( id );
- if ( item == pHover )
- {
- menu->SetCurrentlyHighlightedItem( id );
- }
- }
- }
- }
- else
- {
- menu->ClearCurrentlyHighlightedItem();
- }
- }
-#endif
-}
-
-#if defined( VGUI_USEDRAGDROP )
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-// Output : DragDrop_t
-//-----------------------------------------------------------------------------
-DragDrop_t *Panel::GetDragDropInfo()
-{
- Assert( m_pDragDrop );
- return m_pDragDrop;
-}
-#endif
-
-void Panel::OnGetAdditionalDragPanels( CUtlVector< Panel * >& dragabbles )
-{
- // Nothing here
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Virtual method to allow panels to add to the default values
-// Input : *msg -
-//-----------------------------------------------------------------------------
-void Panel::OnCreateDragData( KeyValues *msg )
-{
- // These values are filled in for you:
- // "panel" ptr to panel being dropped
- // "screenx", "screeny" - drop cursor pos in screen space
- // "x", "y" - drop coordinates relative to this window (the window being dropped upon)
-}
-
-// Called if m_flHoverContextTime was non-zero, allows droppee to preview the drop data and show an appropriate menu
-bool Panel::GetDropContextMenu( Menu *menu, CUtlVector< KeyValues * >& msglist )
-{
- return false;
-}
-
-void Panel::CreateDragData()
-{
-#if defined( VGUI_USEDRAGDROP )
- int i, c;
-
- if ( m_pDragDrop->m_DragData.Count() )
- {
- return;
- }
-
- PHandle h;
- h = this;
- m_pDragDrop->m_DragPanels.AddToTail( h );
-
- CUtlVector< Panel * > temp;
- OnGetAdditionalDragPanels( temp );
- c = temp.Count();
- for ( i = 0; i < c; ++i )
- {
- h = temp[ i ];
- m_pDragDrop->m_DragPanels.AddToTail( h );
- }
-
- c = m_pDragDrop->m_DragPanels.Count();
- for ( i = 0 ; i < c; ++i )
- {
- Panel *sibling = m_pDragDrop->m_DragPanels[ i ].Get();
- if ( !sibling )
- {
- continue;
- }
-
- KeyValues *msg = new KeyValues( "DragDrop" );
- msg->SetPtr( "panel", sibling );
-
- sibling->OnCreateDragData( msg );
-
- m_pDragDrop->m_DragData.AddToTail( msg );
- }
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-// Output : KeyValues
-//-----------------------------------------------------------------------------
-void Panel::GetDragData( CUtlVector< KeyValues * >& list )
-{
-#if defined( VGUI_USEDRAGDROP )
- int i, c;
-
- list.RemoveAll();
-
- c = m_pDragDrop->m_DragData.Count();
- for ( i = 0 ; i < c; ++i )
- {
- list.AddToTail( m_pDragDrop->m_DragData[ i ] );
- }
-#endif
-}
-
-#if defined( VGUI_USEDRAGDROP )
-CDragDropHelperPanel::CDragDropHelperPanel() : BaseClass( NULL, "DragDropHelper" )
-{
- SetVisible( true );
- SetPaintEnabled( false );
- SetPaintBackgroundEnabled( false );
- SetMouseInputEnabled( false );
- SetKeyBoardInputEnabled( false );
- // SetCursor( dc_none );
- ipanel()->SetTopmostPopup( GetVPanel(), true );
- int w, h;
- surface()->GetScreenSize( w, h );
- SetBounds( 0, 0, w, h );
-
- SetPostChildPaintEnabled( true );
-
- MakePopup( false );
-}
-
-VPANEL CDragDropHelperPanel::IsWithinTraverse(int x, int y, bool traversePopups)
-{
- return (VPANEL)0;
-}
-
-void CDragDropHelperPanel::PostChildPaint()
-{
- int c = m_PaintList.Count();
- for ( int i = c - 1; i >= 0 ; --i )
- {
- DragHelperPanel_t& data = m_PaintList[ i ];
-
- Panel *panel = data.m_hPanel.Get();
- if ( !panel )
- {
- m_PaintList.Remove( i );
- continue;
- }
-
- Panel *dropPanel = panel->GetDragDropInfo()->m_hCurrentDrop.Get();
- if ( panel )
- {
- if ( !dropPanel )
- {
- panel->OnDraggablePanelPaint();
- }
- else
- {
- CUtlVector< Panel * > temp;
- CUtlVector< PHandle >& data = panel->GetDragDropInfo()->m_DragPanels;
- CUtlVector< KeyValues * >& msglist = panel->GetDragDropInfo()->m_DragData;
- int i, c;
- c = data.Count();
- for ( i = 0; i < c ; ++i )
- {
- Panel *pPanel = data[ i ].Get();
- if ( pPanel )
- {
- temp.AddToTail( pPanel );
- }
- }
-
- dropPanel->OnDroppablePanelPaint( msglist, temp );
- }
- }
- }
-
- if ( c == 0 )
- {
- MarkForDeletion();
- }
-}
-
-void CDragDropHelperPanel::AddPanel( Panel *current )
-{
- if ( !current )
- return;
-
- Menu *hover = current->GetDragDropInfo()->m_hDropContextMenu.Get();
-
- surface()->MovePopupToFront( GetVPanel() );
- if ( hover && hover->IsPopup() )
- {
- surface()->MovePopupToFront( hover->GetVPanel() );
- }
-
- int c = m_PaintList.Count();
- for ( int i = 0; i < c; ++i )
- {
- if ( m_PaintList[ i ].m_hPanel.Get() == current )
- return;
- }
-
- DragHelperPanel_t data;
- data.m_hPanel = current;
- m_PaintList.AddToTail( data );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *search -
-//-----------------------------------------------------------------------------
-void CDragDropHelperPanel::RemovePanel( Panel *search )
-{
- int c = m_PaintList.Count();
- for ( int i = c - 1 ; i >= 0; --i )
- {
- if ( m_PaintList[ i ].m_hPanel.Get() == search )
- {
- m_PaintList.Remove( i );
- return;
- }
- }
-}
-#endif
-//-----------------------------------------------------------------------------
-// Purpose: Enumerates panels under mouse x,y
-// Input : panelList -
-// x -
-// y -
-// check -
-//-----------------------------------------------------------------------------
-void Panel::FindDropTargetPanel_R( CUtlVector< VPANEL >& panelList, int x, int y, VPANEL check )
-{
-#if defined( VGUI_USEDRAGDROP )
- if ( !ipanel()->IsFullyVisible( check ) )
- return;
-
- if ( ::ShouldHandleInputMessage( check ) && ipanel()->IsWithinTraverse( check, x, y, false ) )
- {
- panelList.AddToTail( check );
- }
-
- CUtlVector< VPANEL > &children = ipanel()->GetChildren( check );
- int childCount = children.Count();
- for ( int i = 0; i < childCount; i++ )
- {
- VPANEL child = children[ i ];
- FindDropTargetPanel_R( panelList, x, y, child );
- }
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-// Output : Panel
-//-----------------------------------------------------------------------------
-Panel *Panel::FindDropTargetPanel()
-{
-#if defined( VGUI_USEDRAGDROP )
- if ( !s_DragDropHelper.Get() )
- return NULL;
-
- CUtlVector< VPANEL > hits;
-
- int x, y;
- input()->GetCursorPos( x, y );
-
- VPANEL embedded = surface()->GetEmbeddedPanel();
- VPANEL helper = s_DragDropHelper.Get()->GetVPanel();
-
- if ( surface()->IsCursorVisible() && surface()->IsWithin(x, y) )
- {
- // faster version of code below
- // checks through each popup in order, top to bottom windows
- int c = surface()->GetPopupCount();
- for (int i = c - 1; i >= 0 && hits.Count() == 0; i--)
- {
- VPANEL popup = surface()->GetPopup(i);
- if ( popup == embedded )
- continue;
-
- // Don't return helper panel!!!
- if ( popup == helper )
- continue;
-
- if ( !ipanel()->IsFullyVisible( popup ) )
- continue;
-
- FindDropTargetPanel_R( hits, x, y, popup );
- }
-
- // Check embedded
- if ( !hits.Count() )
- {
- FindDropTargetPanel_R( hits, x, y, embedded );
- }
- }
-
- // Nothing under mouse...
- if ( !hits.Count() )
- return NULL;
-
- // Return topmost panel under mouse, if it's visible to this .dll
- Panel *panel = NULL;
- int nCount = hits.Count();
- while ( --nCount >= 0 )
- {
- panel = ipanel()->GetPanel( hits[ nCount ], GetModuleName() );
- if ( panel )
- return panel;
- }
-#endif
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Mouse is on draggable panel and has started moving, but is not over a droppable panel yet
-// Input : -
-//-----------------------------------------------------------------------------
-void Panel::OnDraggablePanelPaint()
-{
-#if defined( VGUI_USEDRAGDROP )
- int sw, sh;
- GetSize( sw, sh );
-
- int x, y;
- input()->GetCursorPos( x, y );
- int w, h;
-
- w = min( sw, 80 );
- h = min( sh, 80 );
- x -= ( w >> 1 );
- y -= ( h >> 1 );
-
- surface()->DrawSetColor( m_clrDragFrame );
- surface()->DrawOutlinedRect( x, y, x + w, y + h );
-
- if ( m_pDragDrop->m_DragPanels.Count() > 1 )
- {
- surface()->DrawSetTextColor( m_clrDragFrame );
- surface()->DrawSetTextFont( m_infoFont );
- surface()->DrawSetTextPos( x + 5, y + 2 );
-
- wchar_t sz[ 64 ];
- V_swprintf_safe( sz, L"[ %i ]", m_pDragDrop->m_DragPanels.Count() );
-
- surface()->DrawPrintText( sz, wcslen( sz ) );
- }
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Mouse is now over a droppable panel
-// Input : *dragPanel -
-//-----------------------------------------------------------------------------
-void Panel::OnDroppablePanelPaint( CUtlVector< KeyValues * >& msglist, CUtlVector< Panel * >& dragPanels )
-{
-#if defined( VGUI_USEDRAGDROP )
- if ( !dragPanels.Count() )
- return;
-
- // Convert this panel's bounds to screen space
- int w, h;
- GetSize( w, h );
-
- int x, y;
- x = y = 0;
- LocalToScreen( x, y );
-
- surface()->DrawSetColor( m_clrDropFrame );
- // Draw 2 pixel frame
- surface()->DrawOutlinedRect( x, y, x + w, y + h );
- surface()->DrawOutlinedRect( x+1, y+1, x + w-1, y + h-1 );
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-// Output : Color
-//-----------------------------------------------------------------------------
-Color Panel::GetDropFrameColor()
-{
-#if defined( VGUI_USEDRAGDROP )
- return m_clrDropFrame;
-#endif
- return Color(0, 0, 0, 0);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-// Output : Color
-//-----------------------------------------------------------------------------
-Color Panel::GetDragFrameColor()
-{
-#if defined( VGUI_USEDRAGDROP )
- return m_clrDragFrame;
-#endif
- return Color(0, 0, 0, 0);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *data -
-//-----------------------------------------------------------------------------
-void Panel::OnPanelDropped( CUtlVector< KeyValues * >& data )
-{
- // Empty. Derived classes would implement handlers here
-}
-
-//-----------------------------------------------------------------------------
-// called on droptarget when draggable panel enters droptarget
-//-----------------------------------------------------------------------------
-void Panel::OnPanelEnteredDroppablePanel( CUtlVector< KeyValues * >& msglist )
-{
- // Empty. Derived classes would implement handlers here
-}
-
-//-----------------------------------------------------------------------------
-// called on droptarget when draggable panel exits droptarget
-//-----------------------------------------------------------------------------
-void Panel::OnPanelExitedDroppablePanel ( CUtlVector< KeyValues * >& msglist )
-{
- // Empty. Derived classes would implement handlers here
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-//-----------------------------------------------------------------------------
-void Panel::DragDropStartDragging()
-{
-#if defined( VGUI_USEDRAGDROP )
- // We somehow missed a mouse release, cancel the previous drag
- if ( g_DragDropCapture.Get() )
- {
- if ( HasParent( g_DragDropCapture.Get()->GetVPanel() ) )
- return;
-
- bool started = g_DragDropCapture->GetDragDropInfo()->m_bDragStarted;
- g_DragDropCapture->OnFinishDragging( true, (MouseCode)-1 );
- if ( started )
- {
- return;
- }
- }
-
- // Find actual target panel
- Panel *panel = GetDragPanel();
- if ( !panel )
- return;
-
- DragDrop_t *data = panel->GetDragDropInfo();
- if ( !data )
- return;
-
- if ( !panel->IsDragEnabled() )
- return;
-
- if ( data->m_bDragging )
- return;
-
- panel->OnStartDragging();
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool Panel::IsBeingDragged()
-{
-#if defined( VGUI_USEDRAGDROP )
- if ( !g_DragDropCapture.Get() )
- return false;
-
- if ( g_DragDropCapture.Get() == this )
- return true;
-
- // If we encounter a blocker, stop chaining
- if ( m_pDragDrop->m_bPreventChaining )
- return false;
-
- // Chain up
- if ( GetParent() )
- {
- return GetParent()->IsBeingDragged();
- }
-#endif
- // No luck
- return false;
-}
-
-struct srect_t
-{
- int x0, y0;
- int x1, y1;
-
- bool IsDegenerate()
- {
- if ( x1 - x0 <= 0 )
- return true;
- if ( y1 - y0 <= 0 )
- return true;
- return false;
- }
-};
-
-// Draws a filled rect of specified bounds, but omits the bounds of the skip panel from those bounds
-void Panel::FillRectSkippingPanel( const Color &clr, int x, int y, int w, int h, Panel *skipPanel )
-{
- int sx = 0, sy = 0, sw, sh;
- skipPanel->GetSize( sw, sh );
- skipPanel->LocalToScreen( sx, sy );
- ScreenToLocal( sx, sy );
-
- surface()->DrawSetColor( clr );
-
- srect_t r1;
- r1.x0 = x;
- r1.y0 = y;
- r1.x1 = x + w;
- r1.y1 = y + h;
-
- srect_t r2;
- r2.x0 = sx;
- r2.y0 = sy;
- r2.x1 = sx + sw;
- r2.y1 = sy + sh;
-
- int topy = r1.y0;
- int bottomy = r1.y1;
-
- // We'll descend vertically and draw:
- // 1 a possible bar across the top
- // 2 a possible bar across the bottom
- // 3 possible left bar
- // 4 possible right bar
-
- // Room at top?
- if ( r2.y0 > r1.y0 )
- {
- topy = r2.y0;
-
- surface()->DrawFilledRect( r1.x0, r1.y0, r1.x1, topy );
- }
-
- // Room at bottom?
- if ( r2.y1 < r1.y1 )
- {
- bottomy = r2.y1;
-
- surface()->DrawFilledRect( r1.x0, bottomy, r1.x1, r1.y1 );
- }
-
- // Room on left side?
- if ( r2.x0 > r1.x0 )
- {
- int left = r2.x0;
-
- surface()->DrawFilledRect( r1.x0, topy, left, bottomy );
- }
-
- // Room on right side
- if ( r2.x1 < r1.x1 )
- {
- int right = r2.x1;
-
- surface()->DrawFilledRect( right, topy, r1.x1, bottomy );
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *child -
-//-----------------------------------------------------------------------------
-void Panel::SetSkipChildDuringPainting( Panel *child )
-{
- m_SkipChild = child;
-}
-
-HPanel Panel::ToHandle() const
-{
- return ivgui()->PanelToHandle( _vpanel );
-}
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-Panel* Panel::NavigateUp()
-{
- Panel *target = GetNavUp();
- if ( target )
- {
- NavigateFrom();
- target->m_LastNavDirection = ND_UP;
- target->NavigateTo();
- }
-
- return target;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-Panel* Panel::NavigateDown()
-{
- Panel *target = GetNavDown();
- if ( target )
- {
- NavigateFrom();
- target->m_LastNavDirection = ND_DOWN;
- target->NavigateTo();
- }
-
- return target;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-Panel* Panel::NavigateLeft()
-{
- Panel *target = GetNavLeft();
- if ( target )
- {
- NavigateFrom();
- target->m_LastNavDirection = ND_LEFT;
- target->NavigateTo();
- }
- return target;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-Panel* Panel::NavigateRight()
-{
- Panel *target = GetNavRight();
- if ( target )
- {
- NavigateFrom();
- target->m_LastNavDirection = ND_RIGHT;
- target->NavigateTo();
- }
- return target;
-}
-
-Panel* Panel::NavigateActivate()
-{
- Panel *target = GetNavActivate();
- if ( target )
- {
- NavigateFrom();
- target->m_LastNavDirection = ND_NONE;
- target->NavigateTo();
- }
- return target;
-}
-
-Panel* Panel::NavigateBack()
-{
- Panel *target = GetNavBack();
- if ( target )
- {
- NavigateFrom();
- target->m_LastNavDirection = ND_NONE;
- target->NavigateTo();
- }
- return target;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::NavigateTo()
-{
- if ( IsX360() )
- {
- RequestFocus( 0 );
- }
-
- CallParentFunction( new KeyValues( "OnNavigateTo", "panelName", GetName() ) );
-
- Panel *target = GetNavToRelay();
- if ( target )
- {
- NavigateFrom();
- target->m_LastNavDirection = ND_NONE;
- NavigateToChild( target );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::NavigateFrom()
-{
- for ( int i = 0; i < GetChildCount(); ++i )
- {
- Panel* currentNav = GetChild(i);
- if ( currentNav != 0 )
- {
- currentNav->NavigateFrom();
- }
- }
-
- CallParentFunction( new KeyValues( "OnNavigateFrom", "panelName", GetName() ) );
-
- if ( m_pTooltips )
- {
- m_pTooltips->HideTooltip();
- }
-
- m_LastNavDirection = ND_NONE;
-}
-
-void Panel::NavigateToChild( Panel *pNavigateTo )
-{
- for( int i = 0; i != GetChildCount(); ++i )
- {
- vgui::Panel *pChild = GetChild(i);
- if( pChild )
- pChild->NavigateFrom();
- }
- pNavigateTo->NavigateTo();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-Panel* Panel::SetNavUp( Panel* navUp )
-{
- Panel* lastNav = m_NavUp;
- m_NavUp = navUp;
-
- if( navUp )
- m_sNavUpName = navUp->GetName();
- else
- m_sNavUpName.Clear();
-
- return lastNav;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-Panel* Panel::SetNavDown( Panel* navDown )
-{
- Panel* lastNav = m_NavDown;
- m_NavDown = navDown;
-
- if( navDown )
- m_sNavDownName = navDown->GetName();
- else
- m_sNavDownName.Clear();
-
- return lastNav;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-Panel* Panel::SetNavLeft( Panel* navLeft )
-{
- Panel* lastNav = m_NavLeft;
- m_NavLeft = navLeft;
-
- if( navLeft )
- m_sNavLeftName = navLeft->GetName();
- else
- m_sNavLeftName.Clear();
-
- return lastNav;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-Panel* Panel::SetNavRight( Panel* navRight )
-{
- Panel* lastNav = m_NavRight;
- m_NavRight = navRight;
-
- if( navRight )
- m_sNavRightName = navRight->GetName();
- else
- m_sNavRightName.Clear();
-
- return lastNav;
-}
-
-Panel* Panel::SetNavToRelay( Panel* navToRelay )
-{
- Panel* lastNav = m_NavToRelay;
- m_NavToRelay = navToRelay;
-
- return lastNav;
-}
-
-Panel* Panel::SetNavActivate( Panel* navActivate )
-{
- Panel* lastNav = m_NavActivate;
- m_NavActivate = navActivate;
-
- return lastNav;
-}
-
-Panel* Panel::SetNavBack( Panel* navBack )
-{
- Panel* lastNav = m_NavBack;
- m_NavBack = navBack;
-
- return lastNav;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-Panel::NAV_DIRECTION Panel::GetLastNavDirection()
-{
- return m_LastNavDirection;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::OnNavigateTo( const char* panelName )
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::OnNavigateFrom( const char* panelName )
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::SetNavUp( const char* controlName )
-{
- if ( controlName && 0 < Q_strlen( controlName ) && GetParent() != 0 )
- {
- m_NavUp = NULL;
- m_sNavUpName = controlName;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::SetNavDown( const char* controlName )
-{
- if ( controlName && 0 < Q_strlen( controlName ) && GetParent() != 0 )
- {
- m_NavDown = NULL;
- m_sNavDownName = controlName;
- }
-}
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::SetNavLeft( const char* controlName )
-{
- if ( controlName && 0 < Q_strlen( controlName ) && GetParent() != 0 )
- {
- m_NavLeft = NULL;
- m_sNavLeftName = controlName;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void Panel::SetNavRight( const char* controlName )
-{
- if ( controlName && 0 < Q_strlen( controlName ) && GetParent() != 0 )
- {
- m_NavRight = NULL;
- m_sNavRightName = controlName;
- }
-}
-
-void Panel::SetNavToRelay( const char* controlName )
-{
- if ( controlName && 0 < Q_strlen( controlName ) && GetParent() != 0 )
- {
- m_NavToRelay = NULL;
- m_sNavToRelayName = controlName;
- }
-}
-
-void Panel::SetNavActivate( const char* controlName )
-{
- if ( controlName && 0 < Q_strlen( controlName ) && GetParent() != 0 )
- {
- m_NavActivate = NULL;
- m_sNavActivateName = controlName;
- }
-}
-
-void Panel::SetNavBack( const char* controlName )
-{
- if ( controlName && 0 < Q_strlen( controlName ) && GetParent() != 0 )
- {
- m_NavBack = NULL;
- m_sNavBackName = controlName;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-vgui::Panel* Panel::GetNavUp( Panel *first )
-{
- if ( !m_NavUp && m_sNavUpName.Length() > 0 )
- {
- Panel *pParent = GetParent();
- const char *pName = m_sNavUpName.String();
- while ( pParent && pName[ 0 ] == '<' )
- {
- pParent = pParent->GetParent();
- pName++;
- }
-
- if ( !pParent )
- {
- return NULL;
- }
-
- Panel *foundPanel = pParent->FindChildByName( pName, true );
- if ( foundPanel != 0 )
- {
- m_NavUp = foundPanel;
- }
- }
-
- vgui::Panel* nextPanel = m_NavUp;
- if( m_NavUp && m_NavUp != first && !m_NavUp->IsVisible() )
- {
- Panel *firstPanel = first == NULL ? this : first;
- nextPanel = nextPanel->GetNavUp( firstPanel );
- }
-
- return nextPanel;
-}
-
-vgui::Panel* Panel::GetNavDown( Panel *first )
-{
- if ( !m_NavDown && m_sNavDownName.Length() > 0 )
- {
- Panel *pParent = GetParent();
- const char *pName = m_sNavDownName.String();
- while ( pParent && pName[ 0 ] == '<' )
- {
- pParent = pParent->GetParent();
- pName++;
- }
-
- if ( !pParent )
- {
- return NULL;
- }
-
- Panel* foundPanel = pParent->FindChildByName( pName, true );
- if ( foundPanel != 0 )
- {
- m_NavDown = foundPanel->GetPanel();
- }
- }
-
- vgui::Panel* nextPanel = m_NavDown;
- if( m_NavDown && m_NavDown != first && !m_NavDown->IsVisible() )
- {
- Panel *firstPanel = first == NULL ? this : first;
- nextPanel = nextPanel->GetNavDown( firstPanel );
- }
-
- return nextPanel;
-}
-
-vgui::Panel* Panel::GetNavLeft( Panel *first )
-{
- if ( !m_NavLeft && m_sNavLeftName.Length() > 0 )
- {
- Panel *pParent = GetParent();
- const char *pName = m_sNavLeftName.String();
- while ( pParent && pName[ 0 ] == '<' )
- {
- pParent = pParent->GetParent();
- pName++;
- }
-
- if ( !pParent )
- {
- return NULL;
- }
-
- Panel* foundPanel = pParent->FindChildByName( pName, true );
- if ( foundPanel != 0 )
- {
- m_NavLeft = foundPanel->GetPanel();
- }
- }
-
- vgui::Panel* nextPanel = m_NavLeft;
- if( m_NavLeft && m_NavLeft != first && !m_NavLeft->IsVisible() )
- {
- Panel *firstPanel = first == NULL ? this : first;
- nextPanel = nextPanel->GetNavLeft( firstPanel );
- }
-
- return nextPanel;
-}
-
-vgui::Panel* Panel::GetNavRight( Panel *first )
-{
- if ( !m_NavRight && m_sNavRightName.Length() > 0 )
- {
- Panel *pParent = GetParent();
- const char *pName = m_sNavRightName.String();
- while ( pParent && pName[ 0 ] == '<' )
- {
- pParent = pParent->GetParent();
- pName++;
- }
-
- if ( !pParent )
- {
- return NULL;
- }
-
- Panel* foundPanel = pParent->FindChildByName( pName, true );
- if ( foundPanel != 0 )
- {
- m_NavRight = foundPanel->GetPanel();
- }
- }
-
- vgui::Panel* nextPanel = m_NavRight;
- if( m_NavRight && m_NavRight != first && !m_NavRight->IsVisible() )
- {
- Panel *firstPanel = first == NULL ? this : first;
- nextPanel = nextPanel->GetNavRight( firstPanel );
- }
-
- return nextPanel;
-}
-
-vgui::Panel* Panel::GetNavToRelay( Panel *first )
-{
- if ( !m_NavToRelay && m_sNavToRelayName.Length() > 0 )
- {
- Panel *pParent = this;
- const char *pName = m_sNavToRelayName.String();
- while ( pParent && pName[ 0 ] == '<' )
- {
- pParent = pParent->GetParent();
- pName++;
- }
-
- if ( !pParent )
- {
- return NULL;
- }
-
- Panel* foundPanel = pParent->FindChildByName( pName, true );
- if ( foundPanel != 0 )
- {
- m_NavToRelay = foundPanel->GetPanel();
- }
- }
-
- vgui::Panel* nextPanel = m_NavToRelay;
- if ( m_NavToRelay && m_NavToRelay != first && !m_NavToRelay->IsVisible() )
- {
- Panel *firstPanel = first == NULL ? this : first;
- nextPanel = nextPanel->GetNavToRelay( firstPanel );
- }
-
- return nextPanel;
-}
-
-vgui::Panel* Panel::GetNavActivate( Panel *first )
-{
- if ( !m_NavActivate && m_sNavActivateName.Length() > 0 )
- {
- Panel *pParent = GetParent();
- const char *pName = m_sNavActivateName.String();
- while ( pParent && pName[ 0 ] == '<' )
- {
- pParent = pParent->GetParent();
- pName++;
- }
-
- if ( !pParent )
- {
- return NULL;
- }
-
- Panel* foundPanel = pParent->FindChildByName( pName, true );
- if ( foundPanel != 0 )
- {
- m_NavActivate = foundPanel->GetPanel();
- }
- }
-
- vgui::Panel* nextPanel = m_NavActivate;
- if ( m_NavActivate && m_NavActivate != first && !m_NavActivate->IsVisible() )
- {
- Panel *firstPanel = first == NULL ? this : first;
- nextPanel = nextPanel->GetNavActivate( firstPanel );
- }
-
- return nextPanel;
-}
-
-vgui::Panel* Panel::GetNavBack( Panel *first )
-{
- if ( !m_NavBack && m_sNavBackName.Length() > 0 )
- {
- Panel *pParent = GetParent();
- const char *pName = m_sNavBackName.String();
- while ( pParent && pName[ 0 ] == '<' )
- {
- pParent = pParent->GetParent();
- pName++;
- }
-
- if ( !pParent )
- {
- return NULL;
- }
-
- Panel *foundPanel = pParent->FindChildByName( pName );
- if ( foundPanel )
- {
- m_NavBack = foundPanel;
- }
- }
-
- vgui::Panel* nextPanel = m_NavBack;
- if ( m_NavBack && m_NavBack != first && !m_NavBack->IsVisible() )
- {
- Panel *firstPanel = first == NULL ? this : first;
- nextPanel = nextPanel->GetNavBack( firstPanel );
- }
-
- return nextPanel;
-}
-
-vgui::Panel* Panel::GetNavUpPanel()
-{
- return m_NavUp;
-}
-
-vgui::Panel* Panel::GetNavDownPanel()
-{
- return m_NavDown;
-}
-
-vgui::Panel* Panel::GetNavLeftPanel()
-{
- return m_NavLeft;
-}
-
-vgui::Panel* Panel::GetNavRightPanel()
-{
- return m_NavRight;
-}
-
-vgui::Panel* Panel::GetNavToRelayPanel()
-{
- return m_NavToRelay;
-}
-
-vgui::Panel* Panel::GetNavActivatePanel()
-{
- return m_NavActivate;
-}
-
-vgui::Panel* Panel::GetNavBackPanel()
-{
- return m_NavBack;
-}
-
-void Panel::SetConsoleStylePanel( bool bConsoleStyle )
-{
- m_bIsConsoleStylePanel = bConsoleStyle;
-}
-
-bool Panel::IsConsoleStylePanel() const
-{
- return m_bIsConsoleStylePanel;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Utility class for handling message map allocation
-//-----------------------------------------------------------------------------
-class CPanelMessageMapDictionary
-{
-public:
- CPanelMessageMapDictionary() : m_PanelMessageMapPool( sizeof(PanelMessageMap), 32, CUtlMemoryPool::GROW_FAST, "CPanelMessageMapDictionary::m_PanelMessageMapPool" )
- {
- m_MessageMaps.RemoveAll();
- }
-
- PanelMessageMap *FindOrAddPanelMessageMap( char const *className );
- PanelMessageMap *FindPanelMessageMap( char const *className );
-private:
-
- struct PanelMessageMapDictionaryEntry
- {
- PanelMessageMap *map;
- };
-
- char const *StripNamespace( char const *className );
-
- CUtlDict< PanelMessageMapDictionaryEntry, int > m_MessageMaps;
- CUtlMemoryPool m_PanelMessageMapPool;
-};
-
-
-char const *CPanelMessageMapDictionary::StripNamespace( char const *className )
-{
- if ( !strnicmp( className, "vgui::", 6 ) )
- {
- return className + 6;
- }
- return className;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Find but don't add mapping
-//-----------------------------------------------------------------------------
-PanelMessageMap *CPanelMessageMapDictionary::FindPanelMessageMap( char const *className )
-{
- int lookup = m_MessageMaps.Find( StripNamespace( className ) );
- if ( lookup != m_MessageMaps.InvalidIndex() )
- {
- return m_MessageMaps[ lookup ].map;
- }
- return NULL;
-}
-
-#include <tier0/memdbgoff.h>
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-PanelMessageMap *CPanelMessageMapDictionary::FindOrAddPanelMessageMap( char const *className )
-{
- PanelMessageMap *map = FindPanelMessageMap( className );
- if ( map )
- return map;
-
- PanelMessageMapDictionaryEntry entry;
- // use the alloc in place method of new
- entry.map = new (m_PanelMessageMapPool.Alloc(sizeof(PanelMessageMap))) PanelMessageMap;
- Construct(entry.map);
- m_MessageMaps.Insert( StripNamespace( className ), entry );
- return entry.map;
-}
-#include <tier0/memdbgon.h>
-
-#if defined( VGUI_USEKEYBINDINGMAPS )
-//-----------------------------------------------------------------------------
-// Purpose: Utility class for handling keybinding map allocation
-//-----------------------------------------------------------------------------
-class CPanelKeyBindingMapDictionary
-{
-public:
- CPanelKeyBindingMapDictionary() : m_PanelKeyBindingMapPool( sizeof(PanelKeyBindingMap), 32, CUtlMemoryPool::GROW_FAST, "CPanelKeyBindingMapDictionary::m_PanelKeyBindingMapPool" )
- {
- m_MessageMaps.RemoveAll();
- }
-
- PanelKeyBindingMap *FindOrAddPanelKeyBindingMap( char const *className );
- PanelKeyBindingMap *FindPanelKeyBindingMap( char const *className );
-private:
-
- struct PanelKeyBindingMapDictionaryEntry
- {
- PanelKeyBindingMap *map;
- };
-
- char const *StripNamespace( char const *className );
-
- CUtlDict< PanelKeyBindingMapDictionaryEntry, int > m_MessageMaps;
- CUtlMemoryPool m_PanelKeyBindingMapPool;
-};
-
-
-char const *CPanelKeyBindingMapDictionary::StripNamespace( char const *className )
-{
- if ( !strnicmp( className, "vgui::", 6 ) )
- {
- return className + 6;
- }
- return className;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Find but don't add mapping
-//-----------------------------------------------------------------------------
-PanelKeyBindingMap *CPanelKeyBindingMapDictionary::FindPanelKeyBindingMap( char const *className )
-{
- int lookup = m_MessageMaps.Find( StripNamespace( className ) );
- if ( lookup != m_MessageMaps.InvalidIndex() )
- {
- return m_MessageMaps[ lookup ].map;
- }
- return NULL;
-}
-
-#include <tier0/memdbgoff.h>
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-PanelKeyBindingMap *CPanelKeyBindingMapDictionary::FindOrAddPanelKeyBindingMap( char const *className )
-{
- PanelKeyBindingMap *map = FindPanelKeyBindingMap( className );
- if ( map )
- return map;
-
- PanelKeyBindingMapDictionaryEntry entry;
- // use the alloc in place method of new
- entry.map = new (m_PanelKeyBindingMapPool.Alloc(sizeof(PanelKeyBindingMap))) PanelKeyBindingMap;
- Construct(entry.map);
- m_MessageMaps.Insert( StripNamespace( className ), entry );
- return entry.map;
-}
-
-#include <tier0/memdbgon.h>
-
-CPanelKeyBindingMapDictionary& GetPanelKeyBindingMapDictionary()
-{
- static CPanelKeyBindingMapDictionary dictionary;
- return dictionary;
-}
-
-#endif // VGUI_USEKEYBINDINGMAPS
-
-CPanelMessageMapDictionary& GetPanelMessageMapDictionary()
-{
- static CPanelMessageMapDictionary dictionary;
- return dictionary;
-}
-
-namespace vgui
-{
-
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- PanelMessageMap *FindOrAddPanelMessageMap( char const *className )
- {
- return GetPanelMessageMapDictionary().FindOrAddPanelMessageMap( className );
- }
-
- //-----------------------------------------------------------------------------
- // Purpose: Find but don't add mapping
- //-----------------------------------------------------------------------------
- PanelMessageMap *FindPanelMessageMap( char const *className )
- {
- return GetPanelMessageMapDictionary().FindPanelMessageMap( className );
- }
-
-#if defined( VGUI_USEKEYBINDINGMAPS )
- CPanelKeyBindingMapDictionary& GetPanelKeyBindingMapDictionary()
- {
- static CPanelKeyBindingMapDictionary dictionary;
- return dictionary;
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- PanelKeyBindingMap *FindOrAddPanelKeyBindingMap( char const *className )
- {
- return GetPanelKeyBindingMapDictionary().FindOrAddPanelKeyBindingMap( className );
- }
-
- //-----------------------------------------------------------------------------
- // Purpose: Find but don't add mapping
- //-----------------------------------------------------------------------------
- PanelKeyBindingMap *FindPanelKeyBindingMap( char const *className )
- {
- return GetPanelKeyBindingMapDictionary().FindPanelKeyBindingMap( className );
- }
-#endif // VGUI_USEKEYBINDINGMAPS
-
-SortedPanel_t::SortedPanel_t( Panel *panel )
-{
- pPanel = panel; pButton = dynamic_cast< Button* >( panel );
-}
-
-
-void VguiPanelGetSortedChildPanelList( Panel *pParentPanel, void *pSortedPanels )
-{
- CUtlSortVector< SortedPanel_t, CSortedPanelYLess > *pList = reinterpret_cast< CUtlSortVector< SortedPanel_t, CSortedPanelYLess >* >( pSortedPanels );
-
- for ( int i = 0; i < pParentPanel->GetChildCount(); i++ )
- {
- // perform auto-layout on the child panel
- Panel *pPanel = pParentPanel->GetChild( i );
- if ( !pPanel || !pPanel->IsVisible() )
- continue;
-
- pList->Insert( SortedPanel_t( static_cast< Panel* >( pPanel ) ) );
- }
-}
-
-void VguiPanelGetSortedChildButtonList( Panel *pParentPanel, void *pSortedPanels, char *pchFilter /*= NULL*/, int nFilterType /*= 0*/ )
-{
- CUtlSortVector< SortedPanel_t, CSortedPanelYLess > *pList = reinterpret_cast< CUtlSortVector< SortedPanel_t, CSortedPanelYLess >* >( pSortedPanels );
-
- for ( int i = 0; i < pParentPanel->GetChildCount(); i++ )
- {
- // perform auto-layout on the child panel
- Button *pPanel = dynamic_cast< Button* >( pParentPanel->GetChild( i ) );
- if ( !pPanel || !pPanel->IsVisible() )
- continue;
-
- if ( pchFilter && pchFilter[ 0 ] != '\0' )
- {
- char szBuff[ 128 ];
- pPanel->GetText( szBuff, sizeof( szBuff ) );
-
- // Prefix
- if ( nFilterType == 0 )
- {
- if ( !StringHasPrefix( szBuff, pchFilter ) )
- {
- continue;
- }
- }
- // Substring
- else if ( nFilterType == 1 )
- {
- if ( V_strstr( szBuff, pchFilter ) == NULL )
- {
- continue;
- }
- }
- }
-
- pList->Insert( SortedPanel_t( pPanel ) );
- }
-}
-
-int VguiPanelNavigateSortedChildButtonList( void *pSortedPanels, int nDir )
-{
- CUtlSortVector< SortedPanel_t, CSortedPanelYLess > *pList = reinterpret_cast< CUtlSortVector< SortedPanel_t, CSortedPanelYLess >* >( pSortedPanels );
-
- if ( pList->Count() <= 0 )
- return -1;
-
- if ( nDir != 0 )
- {
- int nArmed = -1;
- for ( int i = 0; i < pList->Count(); i++ )
- {
- if ( (*pList)[ i ].pButton->IsArmed() )
- {
- nArmed = i;
- break;
- }
- }
-
- if ( nArmed == -1 )
- {
- (*pList)[ 0 ].pButton->SetArmed( true );
- return 0;
- }
- else
- {
- int nNewArmed = clamp( nArmed + nDir, 0, pList->Count() - 1 );
- if ( nNewArmed != nArmed )
- {
- (*pList)[ nArmed ].pButton->SetArmed( false );
- }
-
- (*pList)[ nNewArmed ].pButton->RequestFocus();
- (*pList)[ nNewArmed ].pButton->SetArmed( true );
-
- return nNewArmed;
- }
- }
-
- return -1;
-}
-
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+
+#include <stdio.h>
+#include <assert.h>
+#include <utlvector.h>
+#include <vstdlib/IKeyValuesSystem.h>
+#include <ctype.h> // isdigit()
+
+#include <materialsystem/imaterial.h>
+
+#include <vgui/IBorder.h>
+#include <vgui/IInput.h>
+#include <vgui/IPanel.h>
+#include <vgui/IScheme.h>
+#include <vgui/ISurface.h>
+#include <vgui/ISystem.h>
+#include <vgui/ILocalize.h>
+#include <vgui/IVGui.h>
+#include <KeyValues.h>
+#include <vgui/MouseCode.h>
+
+#include <vgui_controls/Panel.h>
+#include <vgui_controls/BuildGroup.h>
+#include <vgui_controls/Tooltip.h>
+#include <vgui_controls/PHandle.h>
+#include <vgui_controls/Controls.h>
+#include "vgui_controls/Menu.h"
+#include "vgui_controls/MenuItem.h"
+
+#include "UtlSortVector.h"
+
+#include "tier1/utldict.h"
+#include "tier1/utlbuffer.h"
+#include "mempool.h"
+#include "filesystem.h"
+#include "tier0/icommandline.h"
+
+#include "tier0/vprof.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include <tier0/memdbgon.h>
+
+using namespace vgui;
+
+#define TRIPLE_PRESS_MSEC 300
+
+
+extern int GetBuildModeDialogCount();
+
+static char *CopyString( const char *in )
+{
+ if ( !in )
+ return NULL;
+
+ int len = strlen( in );
+ char *n = new char[ len + 1 ];
+ Q_strncpy( n, in, len + 1 );
+ return n;
+}
+
+#if defined( VGUI_USEDRAGDROP )
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+struct vgui::DragDrop_t
+{
+ DragDrop_t() :
+ m_bDragEnabled( false ),
+ m_bShowDragHelper( true ),
+ m_bDropEnabled( false ),
+ m_bDragStarted( false ),
+ m_nDragStartTolerance( 8 ),
+ m_bDragging( false ),
+ m_lDropHoverTime( 0 ),
+ m_bDropMenuShown( false ),
+ m_bPreventChaining( false )
+ {
+ m_nStartPos[ 0 ] = m_nStartPos[ 1 ] = 0;
+ m_nLastPos[ 0 ] = m_nLastPos[ 1 ] = 0;
+ }
+
+ // Drag related data
+ bool m_bDragEnabled;
+ bool m_bShowDragHelper;
+ bool m_bDragging;
+ bool m_bDragStarted;
+ // How many pixels the dragged box must move before showing the outline rect...
+ int m_nDragStartTolerance;
+ int m_nStartPos[ 2 ];
+ int m_nLastPos[ 2 ];
+ CUtlVector< KeyValues * > m_DragData;
+ CUtlVector< PHandle > m_DragPanels;
+
+ // Drop related data
+ bool m_bDropEnabled;
+ // A droppable panel can have a hover context menu, which will show up after m_flHoverContextTime of hovering
+ float m_flHoverContextTime;
+
+ PHandle m_hCurrentDrop;
+ // Amount of time hovering over current drop target
+ long m_lDropHoverTime;
+ bool m_bDropMenuShown;
+ DHANDLE< Menu > m_hDropContextMenu;
+
+ // Misc data
+ bool m_bPreventChaining;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: Helper for painting to the full screen...
+//-----------------------------------------------------------------------------
+class CDragDropHelperPanel : public Panel
+{
+ DECLARE_CLASS_SIMPLE( CDragDropHelperPanel, Panel );
+public:
+ CDragDropHelperPanel();
+
+ virtual VPANEL IsWithinTraverse(int x, int y, bool traversePopups);
+ virtual void PostChildPaint();
+
+ void AddPanel( Panel *current );
+
+ void RemovePanel( Panel *search );
+
+private:
+ struct DragHelperPanel_t
+ {
+ PHandle m_hPanel;
+ };
+
+ CUtlVector< DragHelperPanel_t > m_PaintList;
+};
+
+vgui::DHANDLE< CDragDropHelperPanel > s_DragDropHelper;
+#endif
+
+#if defined( VGUI_USEKEYBINDINGMAPS )
+
+BoundKey_t::BoundKey_t():
+ isbuiltin( true ),
+ bindingname( 0 ),
+ keycode( KEY_NONE ),
+ modifiers( 0 )
+{
+}
+
+BoundKey_t::BoundKey_t( const BoundKey_t& src )
+{
+ isbuiltin = src.isbuiltin;
+ bindingname = isbuiltin ? src.bindingname : CopyString( src.bindingname );
+ keycode = src.keycode;
+ modifiers = src.modifiers;
+}
+
+BoundKey_t& BoundKey_t::operator =( const BoundKey_t& src )
+{
+ if ( this == &src )
+ return *this;
+ isbuiltin = src.isbuiltin;
+ bindingname = isbuiltin ? src.bindingname : CopyString( src.bindingname );
+ keycode = src.keycode;
+ modifiers = src.modifiers;
+ return *this;
+}
+
+
+BoundKey_t::~BoundKey_t()
+{
+ if ( !isbuiltin )
+ {
+ delete[] bindingname;
+ }
+}
+
+KeyBindingMap_t::KeyBindingMap_t() :
+ bindingname( 0 ),
+ func( 0 ),
+ helpstring( 0 ),
+ docstring( 0 ),
+ passive( false )
+{
+}
+
+KeyBindingMap_t::KeyBindingMap_t( const KeyBindingMap_t& src )
+{
+ bindingname = src.bindingname;
+ helpstring = src.helpstring;
+ docstring = src.docstring;
+
+ func = src.func;
+ passive = src.passive;
+}
+
+KeyBindingMap_t::~KeyBindingMap_t()
+{
+}
+
+class CKeyBindingsMgr
+{
+public:
+
+ CKeyBindingsMgr() :
+ m_Bindings( 0, 0, KeyBindingContextHandleLessFunc ),
+ m_nKeyBindingContexts( 0 )
+ {
+ }
+
+ struct KBContext_t
+ {
+ KBContext_t() :
+ m_KeyBindingsFile( UTL_INVAL_SYMBOL ),
+ m_KeyBindingsPathID( UTL_INVAL_SYMBOL )
+ {
+ m_Handle = INVALID_KEYBINDINGCONTEXT_HANDLE;
+ }
+
+ KBContext_t( const KBContext_t& src )
+ {
+ m_Handle = src.m_Handle;
+ m_KeyBindingsFile = src.m_KeyBindingsFile;
+ m_KeyBindingsPathID = src.m_KeyBindingsPathID;
+ int c = src.m_Panels.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ m_Panels.AddToTail( src.m_Panels[ i ] );
+ }
+ }
+
+ KeyBindingContextHandle_t m_Handle;
+ CUtlSymbol m_KeyBindingsFile;
+ CUtlSymbol m_KeyBindingsPathID;
+ CUtlVector< Panel * > m_Panels;
+ };
+
+ static bool KeyBindingContextHandleLessFunc( const KBContext_t& lhs, const KBContext_t& rhs )
+ {
+ return lhs.m_Handle < rhs.m_Handle;
+ }
+
+ KeyBindingContextHandle_t CreateContext( char const *filename, char const *pathID )
+ {
+ KBContext_t entry;
+
+ entry.m_Handle = (KeyBindingContextHandle_t)++m_nKeyBindingContexts;
+ entry.m_KeyBindingsFile = filename;
+ if ( pathID )
+ {
+ entry.m_KeyBindingsPathID = pathID;
+ }
+ else
+ {
+ entry.m_KeyBindingsPathID = UTL_INVAL_SYMBOL;
+ }
+
+ m_Bindings.Insert( entry );
+
+ return entry.m_Handle;
+ }
+
+ void AddPanelToContext( KeyBindingContextHandle_t handle, Panel *panel )
+ {
+ if ( !panel->GetName() || !panel->GetName()[ 0 ] )
+ {
+ Warning( "Can't add Keybindings Context for unnamed panels\n" );
+ return;
+ }
+
+ KBContext_t *entry = Find( handle );
+ Assert( entry );
+ if ( entry )
+ {
+ int idx = entry->m_Panels.Find( panel );
+ if ( idx == entry->m_Panels.InvalidIndex() )
+ {
+ entry->m_Panels.AddToTail( panel );
+ }
+ }
+ }
+
+ void OnPanelDeleted( KeyBindingContextHandle_t handle, Panel *panel )
+ {
+ KBContext_t *kb = Find( handle );
+ if ( kb )
+ {
+ kb->m_Panels.FindAndRemove( panel );
+ }
+ }
+
+ KBContext_t *Find( KeyBindingContextHandle_t handle )
+ {
+ KBContext_t search;
+ search.m_Handle = handle;
+ int idx = m_Bindings.Find( search );
+ if ( idx == m_Bindings.InvalidIndex() )
+ {
+ return NULL;
+ }
+ return &m_Bindings[ idx ];
+ }
+
+ char const *GetKeyBindingsFile( KeyBindingContextHandle_t handle )
+ {
+ KBContext_t *kb = Find( handle );
+ if ( kb )
+ {
+ return kb->m_KeyBindingsFile.String();
+ }
+ Assert( 0 );
+ return "";
+ }
+
+ char const *GetKeyBindingsFilePathID( KeyBindingContextHandle_t handle )
+ {
+ KBContext_t *kb = Find( handle );
+ if ( kb )
+ {
+ return kb->m_KeyBindingsPathID.String();
+ }
+ Assert( 0 );
+ return NULL;
+ }
+
+ int GetPanelsWithKeyBindingsCount( KeyBindingContextHandle_t handle )
+ {
+ KBContext_t *kb = Find( handle );
+ if ( kb )
+ {
+ return kb->m_Panels.Count();
+ }
+ Assert( 0 );
+ return 0;
+ }
+
+ //-----------------------------------------------------------------------------
+ // Purpose: static method
+ // Input : index -
+ // Output : Panel
+ //-----------------------------------------------------------------------------
+ Panel *GetPanelWithKeyBindings( KeyBindingContextHandle_t handle, int index )
+ {
+ KBContext_t *kb = Find( handle );
+ if ( kb )
+ {
+ Assert( index >= 0 && index < kb->m_Panels.Count() );
+ return kb->m_Panels[ index ];
+ }
+ Assert( 0 );
+ return 0;
+ }
+
+ CUtlRBTree< KBContext_t, int > m_Bindings;
+ int m_nKeyBindingContexts;
+};
+
+static CKeyBindingsMgr g_KBMgr;
+
+//-----------------------------------------------------------------------------
+// Purpose: Static method to allocate a context
+// Input : -
+// Output : KeyBindingContextHandle_t
+//-----------------------------------------------------------------------------
+KeyBindingContextHandle_t Panel::CreateKeyBindingsContext( char const *filename, char const *pathID /*=0*/ )
+{
+ return g_KBMgr.CreateContext( filename, pathID );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: static method
+// Input : -
+// Output : int
+//-----------------------------------------------------------------------------
+int Panel::GetPanelsWithKeyBindingsCount( KeyBindingContextHandle_t handle )
+{
+ return g_KBMgr.GetPanelsWithKeyBindingsCount( handle );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: static method
+// Input : index -
+// Output : Panel
+//-----------------------------------------------------------------------------
+Panel *Panel::GetPanelWithKeyBindings( KeyBindingContextHandle_t handle, int index )
+{
+ return g_KBMgr.GetPanelWithKeyBindings( handle, index );
+}
+
+
+//-----------------------------------------------------------------------------
+// Returns the number of keybindings
+//-----------------------------------------------------------------------------
+int Panel::GetKeyMappingCount( )
+{
+ int nCount = 0;
+ PanelKeyBindingMap *map = GetKBMap();
+ while ( map )
+ {
+ nCount += map->entries.Count();
+ map = map->baseMap;
+ }
+ return nCount;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: static method. Reverts key bindings for all registered panels (panels with keybindings actually
+// loaded from file
+// Input : -
+//-----------------------------------------------------------------------------
+void Panel::RevertKeyBindings( KeyBindingContextHandle_t handle )
+{
+ int c = GetPanelsWithKeyBindingsCount( handle );
+ for ( int i = 0; i < c; ++i )
+ {
+ Panel *kbPanel = GetPanelWithKeyBindings( handle, i );
+ Assert( kbPanel );
+ kbPanel->RevertKeyBindingsToDefault();
+ }
+}
+
+static void BufPrint( CUtlBuffer& buf, int level, char const *fmt, ... )
+{
+ char string[ 2048 ];
+ va_list argptr;
+ va_start( argptr, fmt );
+ _vsnprintf( string, sizeof( string ) - 1, fmt, argptr );
+ va_end( argptr );
+ string[ sizeof( string ) - 1 ] = 0;
+
+ while ( --level >= 0 )
+ {
+ buf.Printf( " " );
+ }
+ buf.Printf( "%s", string );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : handle -
+//-----------------------------------------------------------------------------
+void Panel::SaveKeyBindings( KeyBindingContextHandle_t handle )
+{
+ char const *filename = g_KBMgr.GetKeyBindingsFile( handle );
+ char const *pathID = g_KBMgr.GetKeyBindingsFilePathID( handle );
+
+ SaveKeyBindingsToFile( handle, filename, pathID );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: static method. Saves key binding files out for all keybindings
+// Input : -
+//-----------------------------------------------------------------------------
+void Panel::SaveKeyBindingsToFile( KeyBindingContextHandle_t handle, char const *filename, char const *pathID /*= 0*/ )
+{
+ CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
+
+ BufPrint( buf, 0, "keybindings\n" );
+ BufPrint( buf, 0, "{\n" );
+
+ int c = GetPanelsWithKeyBindingsCount( handle );
+ for ( int i = 0; i < c; ++i )
+ {
+ Panel *kbPanel = GetPanelWithKeyBindings( handle, i );
+ Assert( kbPanel );
+ if ( !kbPanel )
+ continue;
+
+ Assert( kbPanel->GetName() );
+ Assert( kbPanel->GetName()[ 0 ] );
+
+ if ( !kbPanel->GetName() || !kbPanel->GetName()[ 0 ] )
+ continue;
+
+ BufPrint( buf, 1, "\"%s\"\n", kbPanel->GetName() );
+ BufPrint( buf, 1, "{\n" );
+
+ kbPanel->SaveKeyBindingsToBuffer( 2, buf );
+
+ BufPrint( buf, 1, "}\n" );
+ }
+
+ BufPrint( buf, 0, "}\n" );
+
+ if ( g_pFullFileSystem->FileExists( filename, pathID ) &&
+ !g_pFullFileSystem->IsFileWritable( filename, pathID ) )
+ {
+ Warning( "Panel::SaveKeyBindings '%s' is read-only!!!\n", filename );
+ }
+
+ FileHandle_t h = g_pFullFileSystem->Open( filename, "wb", pathID );
+ if ( FILESYSTEM_INVALID_HANDLE != h )
+ {
+ g_pFullFileSystem->Write( buf.Base(), buf.TellPut(), h );
+ g_pFullFileSystem->Close( h );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : handle -
+// *panelOfInterest -
+//-----------------------------------------------------------------------------
+void Panel::LoadKeyBindingsForOnePanel( KeyBindingContextHandle_t handle, Panel *panelOfInterest )
+{
+ if ( !panelOfInterest )
+ return;
+ if ( !panelOfInterest->GetName() )
+ return;
+ if ( !panelOfInterest->GetName()[ 0 ] )
+ return;
+
+ char const *filename = g_KBMgr.GetKeyBindingsFile( handle );
+ char const *pathID = g_KBMgr.GetKeyBindingsFilePathID( handle );
+
+ KeyValues *kv = new KeyValues( "keybindings" );
+ if ( kv->LoadFromFile( g_pFullFileSystem, filename, pathID ) )
+ {
+ int c = GetPanelsWithKeyBindingsCount( handle );
+ for ( int i = 0; i < c; ++i )
+ {
+ Panel *kbPanel = GetPanelWithKeyBindings( handle, i );
+ Assert( kbPanel );
+
+ char const *panelName = kbPanel->GetName();
+ if ( !panelName )
+ {
+ continue;
+ }
+
+ if ( Q_stricmp( panelOfInterest->GetName(), panelName ) )
+ continue;
+
+ KeyValues *subKey = kv->FindKey( panelName, false );
+ if ( !subKey )
+ {
+ Warning( "Panel::ReloadKeyBindings: Can't find entry for panel '%s'\n", panelName );
+ continue;
+ }
+
+ kbPanel->ParseKeyBindings( subKey );
+ }
+ }
+ kv->deleteThis();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: static method. Loads all key bindings again
+// Input : -
+//-----------------------------------------------------------------------------
+
+void Panel::ReloadKeyBindings( KeyBindingContextHandle_t handle )
+{
+ char const *filename = g_KBMgr.GetKeyBindingsFile( handle );
+ char const *pathID = g_KBMgr.GetKeyBindingsFilePathID( handle );
+
+ KeyValues *kv = new KeyValues( "keybindings" );
+ if ( kv->LoadFromFile( g_pFullFileSystem, filename, pathID ) )
+ {
+ int c = GetPanelsWithKeyBindingsCount( handle );
+ for ( int i = 0; i < c; ++i )
+ {
+ Panel *kbPanel = GetPanelWithKeyBindings( handle, i );
+ Assert( kbPanel );
+
+ char const *panelName = kbPanel->GetName();
+ if ( !panelName )
+ {
+ continue;
+ }
+
+ KeyValues *subKey = kv->FindKey( panelName, false );
+ if ( !subKey )
+ {
+ Warning( "Panel::ReloadKeyBindings: Can't find entry for panel '%s'\n", panelName );
+ continue;
+ }
+
+ kbPanel->ParseKeyBindings( subKey );
+ }
+ }
+ kv->deleteThis();
+}
+#endif // VGUI_USEKEYBINDINGMAPS
+
+DECLARE_BUILD_FACTORY( Panel );
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+Panel::Panel()
+{
+ Init(0, 0, 64, 24);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+Panel::Panel(Panel *parent)
+{
+ Init(0, 0, 64, 24);
+ SetParent(parent);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+Panel::Panel(Panel *parent, const char *panelName)
+{
+ Init(0, 0, 64, 24);
+ SetName(panelName);
+ SetParent(parent);
+ SetBuildModeEditable(true);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+Panel::Panel( Panel *parent, const char *panelName, HScheme scheme )
+{
+ Init(0, 0, 64, 24);
+ SetName(panelName);
+ SetParent(parent);
+ SetBuildModeEditable(true);
+ SetScheme( scheme );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Setup
+//-----------------------------------------------------------------------------
+void Panel::Init( int x, int y, int wide, int tall )
+{
+ _panelName = NULL;
+ _tooltipText = NULL;
+ _pinToSibling = NULL;
+ m_hMouseEventHandler = NULL;
+ _pinCornerToSibling = PIN_TOPLEFT;
+ _pinToSiblingCorner = PIN_TOPLEFT;
+
+ // get ourselves an internal panel
+ _vpanel = ivgui()->AllocPanel();
+ ipanel()->Init(_vpanel, this);
+
+ SetPos(x, y);
+ SetSize(wide, tall);
+ _flags.SetFlag( NEEDS_LAYOUT | NEEDS_SCHEME_UPDATE | NEEDS_DEFAULT_SETTINGS_APPLIED );
+ _flags.SetFlag( AUTODELETE_ENABLED | PAINT_BORDER_ENABLED | PAINT_BACKGROUND_ENABLED | PAINT_ENABLED );
+#if defined( VGUI_USEKEYBINDINGMAPS )
+ _flags.SetFlag( ALLOW_CHAIN_KEYBINDING_TO_PARENT );
+#endif
+ m_nPinDeltaX = m_nPinDeltaY = 0;
+ m_nResizeDeltaX = m_nResizeDeltaY = 0;
+ _autoResizeDirection = AUTORESIZE_NO;
+ _pinCorner = PIN_TOPLEFT;
+ _cursor = dc_arrow;
+ _border = NULL;
+ _buildGroup = UTLHANDLE_INVALID;
+ _tabPosition = 0;
+ m_iScheme = 0;
+ m_bIsSilent = false;
+ m_bParentNeedsCursorMoveEvents = false;
+
+ _buildModeFlags = 0; // not editable or deletable in buildmode dialog by default
+
+ m_pTooltips = NULL;
+ m_bToolTipOverridden = false;
+
+ m_flAlpha = 255.0f;
+ m_nPaintBackgroundType = 0;
+
+ //=============================================================================
+ // HPE_BEGIN:
+ // [tj] Default to rounding all corners (for draw style 2)
+ //=============================================================================
+ m_roundedCorners = PANEL_ROUND_CORNER_ALL;
+ //=============================================================================
+ // HPE_END
+ //=============================================================================
+
+ m_nBgTextureId1 = -1;
+ m_nBgTextureId2 = -1;
+ m_nBgTextureId3 = -1;
+ m_nBgTextureId4 = -1;
+#if defined( VGUI_USEDRAGDROP )
+ m_pDragDrop = new DragDrop_t;
+
+#endif
+
+ m_lLastDoublePressTime = 0L;
+
+#if defined( VGUI_USEKEYBINDINGMAPS )
+ m_hKeyBindingsContext = INVALID_KEYBINDINGCONTEXT_HANDLE;
+#endif
+
+ REGISTER_COLOR_AS_OVERRIDABLE( _fgColor, "fgcolor_override" );
+ REGISTER_COLOR_AS_OVERRIDABLE( _bgColor, "bgcolor_override" );
+
+ m_bIsConsoleStylePanel = false;
+ m_NavUp = NULL;
+ m_NavDown = NULL;
+ m_NavLeft = NULL;
+ m_NavRight = NULL;
+ m_NavToRelay = NULL;
+ m_NavActivate = NULL;
+ m_NavBack = NULL;
+ m_sNavUpName = NULL;
+ m_sNavDownName = NULL;
+ m_sNavLeftName = NULL;
+ m_sNavRightName = NULL;
+ m_sNavToRelayName = NULL;
+ m_sNavActivateName = NULL;
+ m_sNavBackName = NULL;
+
+ m_PassUnhandledInput = true;
+ m_LastNavDirection = ND_NONE;
+ m_bWorldPositionCurrentFrame = false;
+ m_bForceStereoRenderToFrameBuffer = false;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Destructor
+//-----------------------------------------------------------------------------
+Panel::~Panel()
+{
+ // @note Tom Bui: only cleanup if we've created it
+ if ( !m_bToolTipOverridden )
+ {
+ if ( m_pTooltips )
+ {
+ delete m_pTooltips;
+ }
+ }
+#if defined( VGUI_USEKEYBINDINGMAPS )
+ if ( IsValidKeyBindingsContext() )
+ {
+ g_KBMgr.OnPanelDeleted( m_hKeyBindingsContext, this );
+ }
+#endif // VGUI_USEKEYBINDINGMAPS
+#if defined( VGUI_USEDRAGDROP )
+ if ( m_pDragDrop->m_bDragging )
+ {
+ OnFinishDragging( false, (MouseCode)-1 );
+ }
+#endif // VGUI_USEDRAGDROP
+
+ _flags.ClearFlag( AUTODELETE_ENABLED );
+ _flags.SetFlag( MARKED_FOR_DELETION );
+
+ // remove panel from any list
+ SetParent((VPANEL)NULL);
+
+ // Stop our children from pointing at us, and delete them if possible
+ while (ipanel()->GetChildCount(GetVPanel()))
+ {
+ VPANEL child = ipanel()->GetChild(GetVPanel(), 0);
+ if (ipanel()->IsAutoDeleteSet(child))
+ {
+ ipanel()->DeletePanel(child);
+ }
+ else
+ {
+ ipanel()->SetParent(child, NULL);
+ }
+ }
+
+ // delete VPanel
+ ivgui()->FreePanel(_vpanel);
+ // free our name
+ delete [] _panelName;
+
+ if ( _tooltipText && _tooltipText[0] )
+ {
+ delete [] _tooltipText;
+ }
+
+ delete [] _pinToSibling;
+
+ _vpanel = NULL;
+#if defined( VGUI_USEDRAGDROP )
+ delete m_pDragDrop;
+#endif // VGUI_USEDRAGDROP
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: fully construct this panel so its ready for use right now (i.e fonts loaded, colors set, default label text set, ...)
+//-----------------------------------------------------------------------------
+void Panel::MakeReadyForUse()
+{
+// PerformApplySchemeSettings();
+ UpdateSiblingPin();
+ surface()->SolveTraverse( GetVPanel(), true );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::SetName( const char *panelName )
+{
+ // No change?
+ if ( _panelName &&
+ panelName &&
+ !Q_strcmp( _panelName, panelName ) )
+ {
+ return;
+ }
+
+ if (_panelName)
+ {
+ delete [] _panelName;
+ _panelName = NULL;
+ }
+
+ if (panelName)
+ {
+ int len = Q_strlen(panelName) + 1;
+ _panelName = new char[ len ];
+ Q_strncpy( _panelName, panelName, len );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: returns the given name of the panel
+//-----------------------------------------------------------------------------
+const char *Panel::GetName()
+{
+ if (_panelName)
+ return _panelName;
+
+ return "";
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: returns the name of the module that this instance of panel was compiled into
+//-----------------------------------------------------------------------------
+const char *Panel::GetModuleName()
+{
+ return vgui::GetControlsModuleName();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: returns the classname of the panel (as specified in the panelmaps)
+//-----------------------------------------------------------------------------
+const char *Panel::GetClassName()
+{
+ // loop up the panel map name
+ PanelMessageMap *panelMap = GetMessageMap();
+ if ( panelMap )
+ {
+ return panelMap->pfnClassName();
+ }
+
+ return "Panel";
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::SetPos(int x, int y)
+{
+ if (!CommandLine()->FindParm("-hushasserts"))
+ {
+ Assert( abs(x) < 32768 && abs(y) < 32768 );
+ }
+ ipanel()->SetPos(GetVPanel(), x, y);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::GetPos(int &x, int &y)
+{
+ ipanel()->GetPos(GetVPanel(), x, y);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::SetSize(int wide, int tall)
+{
+ Assert( abs(wide) < 32768 && abs(tall) < 32768 );
+ ipanel()->SetSize(GetVPanel(), wide, tall);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::GetSize(int &wide, int &tall)
+{
+ ipanel()->GetSize(GetVPanel(), wide, tall);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::SetBounds(int x, int y, int wide, int tall)
+{
+ SetPos(x,y);
+ SetSize(wide,tall);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::GetBounds(int &x, int &y, int &wide, int &tall)
+{
+ GetPos(x, y);
+ GetSize(wide, tall);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: returns safe handle to parent
+//-----------------------------------------------------------------------------
+VPANEL Panel::GetVParent()
+{
+ if ( ipanel() )
+ {
+ return ipanel()->GetParent(GetVPanel());
+ }
+
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: returns a pointer to a controls version of a Panel pointer
+//-----------------------------------------------------------------------------
+Panel *Panel::GetParent()
+{
+ // get the parent and convert it to a Panel *
+ // this is OK, the hierarchy is guaranteed to be all from the same module, except for the root node
+ // the root node always returns NULL when a GetParent() is done so everything is OK
+ if ( ipanel() )
+ {
+ VPANEL parent = ipanel()->GetParent(GetVPanel());
+ if (parent)
+ {
+ Panel *pParent = ipanel()->GetPanel(parent, GetControlsModuleName());
+ Assert(!pParent || !strcmp(pParent->GetModuleName(), GetControlsModuleName()));
+ return pParent;
+ }
+ }
+
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Screen size change notification handler
+//-----------------------------------------------------------------------------
+void Panel::OnScreenSizeChanged(int nOldWide, int nOldTall)
+{
+ // post to all children
+ for (int i = 0; i < ipanel()->GetChildCount(GetVPanel()); i++)
+ {
+ VPANEL child = ipanel()->GetChild(GetVPanel(), i);
+ PostMessage(child, new KeyValues("OnScreenSizeChanged", "oldwide", nOldWide, "oldtall", nOldTall), NULL);
+ }
+
+ // make any currently fullsize window stay fullsize
+ int x, y, wide, tall;
+ GetBounds(x, y, wide, tall);
+ int screenWide, screenTall;
+ surface()->GetScreenSize(screenWide, screenTall);
+ if (x == 0 && y == 0 && nOldWide == wide && tall == nOldTall)
+ {
+ // fullsize
+ surface()->GetScreenSize(wide, tall);
+ SetBounds(0, 0, wide, tall);
+ }
+
+ // panel needs to re-get it's scheme settings
+ _flags.SetFlag( NEEDS_SCHEME_UPDATE );
+
+ // invalidate our settings
+ InvalidateLayout();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::SetVisible(bool state)
+{
+ ipanel()->SetVisible(GetVPanel(), state);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool Panel::IsVisible()
+{
+ if (ipanel())
+ {
+ return ipanel()->IsVisible(GetVPanel());
+ }
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::SetEnabled(bool state)
+{
+ if (state != ipanel()->IsEnabled( GetVPanel()))
+ {
+ ipanel()->SetEnabled(GetVPanel(), state);
+ InvalidateLayout(false);
+ Repaint();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool Panel::IsEnabled()
+{
+ return ipanel()->IsEnabled(GetVPanel());
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool Panel::IsPopup()
+{
+ return ipanel()->IsPopup(GetVPanel());
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::Repaint()
+{
+ _flags.SetFlag( NEEDS_REPAINT );
+ if (surface())
+ {
+ surface()->Invalidate(GetVPanel());
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::Think()
+{
+ if (IsVisible())
+ {
+ // update any tooltips
+ if (m_pTooltips)
+ {
+ m_pTooltips->PerformLayout();
+ }
+ if ( _flags.IsFlagSet( NEEDS_LAYOUT ) )
+ {
+ InternalPerformLayout();
+ }
+ }
+
+ OnThink();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::PaintTraverse( bool repaint, bool allowForce )
+{
+ if ( m_bWorldPositionCurrentFrame )
+ {
+ surface()->SolveTraverse( GetVPanel() );
+ }
+
+ if ( !IsVisible() )
+ {
+ return;
+ }
+
+ float oldAlphaMultiplier = surface()->DrawGetAlphaMultiplier();
+ float newAlphaMultiplier = oldAlphaMultiplier * m_flAlpha * 1.0f/255.0f;
+
+ if ( IsXbox() && !newAlphaMultiplier )
+ {
+ // xbox optimization not suitable for pc
+ // xbox panels are compliant and can early out and not traverse their children
+ // when they have no opacity
+ return;
+ }
+
+ if ( !repaint &&
+ allowForce &&
+ _flags.IsFlagSet( NEEDS_REPAINT ) )
+ {
+ repaint = true;
+ _flags.ClearFlag( NEEDS_REPAINT );
+ }
+
+ VPANEL vpanel = GetVPanel();
+
+ bool bPushedViewport = false;
+ if( GetForceStereoRenderToFrameBuffer() )
+ {
+ CMatRenderContextPtr pRenderContext( materials );
+ if( pRenderContext->GetRenderTarget() )
+ {
+ surface()->PushFullscreenViewport();
+ bPushedViewport = true;
+ }
+ }
+
+ int clipRect[4];
+ ipanel()->GetClipRect( vpanel, clipRect[0], clipRect[1], clipRect[2], clipRect[3] );
+ if ( ( clipRect[2] <= clipRect[0] ) || ( clipRect[3] <= clipRect[1] ) )
+ {
+ repaint = false;
+ }
+
+ // set global alpha
+ surface()->DrawSetAlphaMultiplier( newAlphaMultiplier );
+
+ bool bBorderPaintFirst = _border ? _border->PaintFirst() : false;
+
+ // draw the border first if requested to
+ if ( bBorderPaintFirst && repaint && _flags.IsFlagSet( PAINT_BORDER_ENABLED ) && ( _border != null ) )
+ {
+ // Paint the border over the background with no inset
+ surface()->PushMakeCurrent( vpanel, false );
+ PaintBorder();
+ surface()->PopMakeCurrent( vpanel );
+ }
+
+ if ( repaint )
+ {
+ // draw the background with no inset
+ if ( _flags.IsFlagSet( PAINT_BACKGROUND_ENABLED ) )
+ {
+ surface()->PushMakeCurrent( vpanel, false );
+ PaintBackground();
+ surface()->PopMakeCurrent( vpanel );
+ }
+
+ // draw the front of the panel with the inset
+ if ( _flags.IsFlagSet( PAINT_ENABLED ) )
+ {
+ surface()->PushMakeCurrent( vpanel, true );
+ Paint();
+ surface()->PopMakeCurrent( vpanel );
+ }
+ }
+
+ // traverse and paint all our children
+ CUtlVector< VPANEL > &children = ipanel()->GetChildren( vpanel );
+ int childCount = children.Count();
+ for (int i = 0; i < childCount; i++)
+ {
+ VPANEL child = children[ i ];
+ bool bVisible = ipanel()->IsVisible( child );
+
+ if ( surface()->ShouldPaintChildPanel( child ) )
+ {
+ if ( bVisible )
+ {
+ ipanel()->PaintTraverse( child, repaint, allowForce );
+ }
+ }
+ else
+ {
+ // Invalidate the child panel so that it gets redrawn
+ surface()->Invalidate( child );
+
+ // keep traversing the tree, just don't allow anyone to paint after here
+ if ( bVisible )
+ {
+ ipanel()->PaintTraverse( child, false, false );
+ }
+ }
+ }
+
+ // draw the border last
+ if ( repaint )
+ {
+ if ( !bBorderPaintFirst && _flags.IsFlagSet( PAINT_BORDER_ENABLED ) && ( _border != null ) )
+ {
+ // Paint the border over the background with no inset
+ surface()->PushMakeCurrent( vpanel, false );
+ PaintBorder();
+ surface()->PopMakeCurrent( vpanel );
+ }
+
+#ifdef _DEBUG
+ // IsBuildGroupEnabled recurses up all the parents and ends up being very expensive as it wanders all over memory
+ if ( GetBuildModeDialogCount() && IsBuildGroupEnabled() ) //&& HasFocus() )
+ {
+ // outline all selected panels
+ CUtlVector<PHandle> *controlGroup = _buildGroup->GetControlGroup();
+ for (int i=0; i < controlGroup->Size(); ++i)
+ {
+ // outline all selected panels
+ CUtlVector<PHandle> *controlGroup = _buildGroup->GetControlGroup();
+ for (int i=0; i < controlGroup->Size(); ++i)
+ {
+ surface()->PushMakeCurrent( ((*controlGroup)[i].Get())->GetVPanel(), false );
+ ((*controlGroup)[i].Get())->PaintBuildOverlay();
+ surface()->PopMakeCurrent( ((*controlGroup)[i].Get())->GetVPanel() );
+ }
+
+ _buildGroup->DrawRulers();
+ }
+ }
+#endif
+
+ // All of our children have painted, etc, now allow painting in top of them
+ if ( _flags.IsFlagSet( POST_CHILD_PAINT_ENABLED ) )
+ {
+ surface()->PushMakeCurrent( vpanel, false );
+ PostChildPaint();
+ surface()->PopMakeCurrent( vpanel );
+ }
+ }
+
+ surface()->DrawSetAlphaMultiplier( oldAlphaMultiplier );
+
+ surface()->SwapBuffers( vpanel );
+
+ if( bPushedViewport )
+ {
+ surface()->PopFullscreenViewport();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::PaintBorder()
+{
+ _border->Paint(GetVPanel());
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::PaintBackground()
+{
+ int wide, tall;
+ GetSize( wide, tall );
+ if ( m_SkipChild.Get() && m_SkipChild->IsVisible() )
+ {
+ if ( GetPaintBackgroundType() == 2 )
+ {
+ int cornerWide, cornerTall;
+ GetCornerTextureSize( cornerWide, cornerTall );
+
+ Color col = GetBgColor();
+ DrawHollowBox( 0, 0, wide, tall, col, 1.0f );
+
+ wide -= 2 * cornerWide;
+ tall -= 2 * cornerTall;
+
+ FillRectSkippingPanel( GetBgColor(), cornerWide, cornerTall, wide, tall, m_SkipChild.Get() );
+ }
+ else
+ {
+ FillRectSkippingPanel( GetBgColor(), 0, 0, wide, tall, m_SkipChild.Get() );
+ }
+ }
+ else
+ {
+ Color col = GetBgColor();
+
+ switch ( m_nPaintBackgroundType )
+ {
+ default:
+ case 0:
+ {
+ surface()->DrawSetColor(col);
+ surface()->DrawFilledRect(0, 0, wide, tall);
+ }
+ break;
+ case 1:
+ {
+ DrawTexturedBox( 0, 0, wide, tall, col, 1.0f );
+ }
+ break;
+ case 2:
+ {
+ DrawBox( 0, 0, wide, tall, col, 1.0f );
+ }
+ break;
+ case 3:
+ {
+ DrawBoxFade( 0, 0, wide, tall, col, 1.0f, 255, 0, true );
+ }
+ break;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::Paint()
+{
+ // empty on purpose
+ // PaintBackground is painted and default behavior is for Paint to do nothing
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::PostChildPaint()
+{
+ // Empty on purpose
+ // This is called if _postChildPaintEnabled is true and allows painting to
+ // continue on the surface after all of the panel's children have painted
+ // themselves. Allows drawing an overlay on top of the children, etc.
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Draws a black rectangle around the panel.
+//-----------------------------------------------------------------------------
+void Panel::PaintBuildOverlay()
+{
+ int wide,tall;
+ GetSize(wide,tall);
+ surface()->DrawSetColor(0, 0, 0, 255);
+
+ surface()->DrawFilledRect(0,0,wide,2); //top
+ surface()->DrawFilledRect(0,tall-2,wide,tall); //bottom
+ surface()->DrawFilledRect(0,2,2,tall-2); //left
+ surface()->DrawFilledRect(wide-2,2,wide,tall-2); //right
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns true if the panel's draw code will fully cover it's area
+//-----------------------------------------------------------------------------
+bool Panel::IsOpaque()
+{
+ // FIXME: Add code to account for the 'SkipChild' functionality in Frame
+ if ( IsVisible() && _flags.IsFlagSet( PAINT_BACKGROUND_ENABLED ) && ( _bgColor[3] == 255 ) )
+ return true;
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: returns true if the settings are aligned to the right of the screen
+//-----------------------------------------------------------------------------
+bool Panel::IsRightAligned()
+{
+ return (_buildModeFlags & BUILDMODE_SAVE_XPOS_RIGHTALIGNED);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: returns true if the settings are aligned to the bottom of the screen
+//-----------------------------------------------------------------------------
+bool Panel::IsBottomAligned()
+{
+ return (_buildModeFlags & BUILDMODE_SAVE_YPOS_BOTTOMALIGNED);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: sets the parent
+//-----------------------------------------------------------------------------
+void Panel::SetParent(Panel *newParent)
+{
+ // Assert that the parent is from the same module as the child
+ // FIXME: !!! work out how to handle this properly!
+ // Assert(!newParent || !strcmp(newParent->GetModuleName(), GetControlsModuleName()));
+
+ if (newParent)
+ {
+ SetParent(newParent->GetVPanel());
+ }
+ else
+ {
+ SetParent((VPANEL)NULL);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::SetParent(VPANEL newParent)
+{
+ if (newParent)
+ {
+ ipanel()->SetParent(GetVPanel(), newParent);
+ }
+ else
+ {
+ ipanel()->SetParent(GetVPanel(), NULL);
+ }
+
+ if (GetVParent() && !IsPopup())
+ {
+ SetProportional(ipanel()->IsProportional(GetVParent()));
+
+ // most of the time KBInput == parents kbinput
+ if (ipanel()->IsKeyBoardInputEnabled(GetVParent()) != IsKeyBoardInputEnabled())
+ {
+ SetKeyBoardInputEnabled(ipanel()->IsKeyBoardInputEnabled(GetVParent()));
+ }
+
+ if (ipanel()->IsMouseInputEnabled(GetVParent()) != IsMouseInputEnabled())
+ {
+ SetMouseInputEnabled(ipanel()->IsMouseInputEnabled(GetVParent()));
+ }
+ }
+
+ UpdateSiblingPin();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::OnChildAdded(VPANEL child)
+{
+ Assert( !_flags.IsFlagSet( IN_PERFORM_LAYOUT ) );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: default message handler
+//-----------------------------------------------------------------------------
+void Panel::OnSizeChanged(int newWide, int newTall)
+{
+ InvalidateLayout(); // our size changed so force us to layout again
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: sets Z ordering - lower numbers are always behind higher z's
+//-----------------------------------------------------------------------------
+void Panel::SetZPos(int z)
+{
+ ipanel()->SetZPos(GetVPanel(), z);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: sets Z ordering - lower numbers are always behind higher z's
+//-----------------------------------------------------------------------------
+int Panel::GetZPos()
+{
+ return ( ipanel()->GetZPos( GetVPanel() ) );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: sets alpha modifier for panel and all child panels [0..255]
+//-----------------------------------------------------------------------------
+void Panel::SetAlpha(int alpha)
+{
+ m_flAlpha = alpha;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: data accessor
+//-----------------------------------------------------------------------------
+int Panel::GetAlpha()
+{
+ return (int)m_flAlpha;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Moves the panel to the front of the z-order
+//-----------------------------------------------------------------------------
+void Panel::MoveToFront(void)
+{
+ // FIXME: only use ipanel() as per src branch?
+ if (IsPopup())
+ {
+ surface()->BringToFront(GetVPanel());
+ }
+ else
+ {
+ ipanel()->MoveToFront(GetVPanel());
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Iterates up the hierarchy looking for a particular parent
+//-----------------------------------------------------------------------------
+bool Panel::HasParent(VPANEL potentialParent)
+{
+ if (!potentialParent)
+ return false;
+
+ return ipanel()->HasParent(GetVPanel(), potentialParent);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Finds the index of a child panel by string name
+// Output : int - -1 if no panel of that name is found
+//-----------------------------------------------------------------------------
+int Panel::FindChildIndexByName(const char *childName)
+{
+ for (int i = 0; i < GetChildCount(); i++)
+ {
+ Panel *pChild = GetChild(i);
+ if (!pChild)
+ continue;
+
+ if (!stricmp(pChild->GetName(), childName))
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Finds a child panel by string name
+// Output : Panel * - NULL if no panel of that name is found
+//-----------------------------------------------------------------------------
+Panel *Panel::FindChildByName(const char *childName, bool recurseDown)
+{
+ for (int i = 0; i < GetChildCount(); i++)
+ {
+ Panel *pChild = GetChild(i);
+ if (!pChild)
+ continue;
+
+ if (!V_stricmp(pChild->GetName(), childName))
+ {
+ return pChild;
+ }
+
+ if (recurseDown)
+ {
+ Panel *panel = pChild->FindChildByName(childName, recurseDown);
+ if ( panel )
+ {
+ return panel;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Finds a sibling panel by name
+//-----------------------------------------------------------------------------
+Panel *Panel::FindSiblingByName(const char *siblingName)
+{
+ if ( !GetVParent() )
+ return NULL;
+
+ int siblingCount = ipanel()->GetChildCount(GetVParent());
+ for (int i = 0; i < siblingCount; i++)
+ {
+ VPANEL sibling = ipanel()->GetChild(GetVParent(), i);
+ Panel *panel = ipanel()->GetPanel(sibling, GetControlsModuleName());
+ if (!stricmp(panel->GetName(), siblingName))
+ {
+ return panel;
+ }
+ }
+
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Dispatches immediately a message to the parent
+//-----------------------------------------------------------------------------
+void Panel::CallParentFunction(KeyValues *message)
+{
+ if (GetVParent())
+ {
+ ipanel()->SendMessage(GetVParent(), message, GetVPanel());
+ }
+ if (message)
+ {
+ message->deleteThis();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: if set to true, panel automatically frees itself when parent is deleted
+//-----------------------------------------------------------------------------
+void Panel::SetAutoDelete( bool state )
+{
+ _flags.SetFlag( AUTODELETE_ENABLED, state );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool Panel::IsAutoDeleteSet()
+{
+ return _flags.IsFlagSet( AUTODELETE_ENABLED );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Just calls 'delete this'
+//-----------------------------------------------------------------------------
+void Panel::DeletePanel()
+{
+ // Avoid re-entrancy
+ _flags.SetFlag( MARKED_FOR_DELETION );
+ _flags.ClearFlag( AUTODELETE_ENABLED );
+ delete this;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: data accessor
+//-----------------------------------------------------------------------------
+HScheme Panel::GetScheme()
+{
+ if (m_iScheme)
+ {
+ return m_iScheme; // return our internal scheme
+ }
+
+ if (GetVParent()) // recurse down the heirarchy
+ {
+ return ipanel()->GetScheme(GetVParent());
+ }
+
+ return scheme()->GetDefaultScheme();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: set the scheme to render this panel with by name
+//-----------------------------------------------------------------------------
+void Panel::SetScheme(const char *tag)
+{
+ if (strlen(tag) > 0 && scheme()->GetScheme(tag)) // check the scheme exists
+ {
+ SetScheme(scheme()->GetScheme(tag));
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: set the scheme to render this panel with
+//-----------------------------------------------------------------------------
+void Panel::SetScheme(HScheme scheme)
+{
+ if (scheme != m_iScheme)
+ {
+ m_iScheme = scheme;
+
+ // This will cause the new scheme to be applied at a later point
+// InvalidateLayout( false, true );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: returns the char of this panels hotkey
+//-----------------------------------------------------------------------------
+Panel *Panel::HasHotkey(wchar_t key)
+{
+ return NULL;
+}
+
+#if defined( VGUI_USEDRAGDROP )
+static vgui::PHandle g_DragDropCapture;
+#endif // VGUI_USEDRAGDROP
+
+void Panel::InternalCursorMoved(int x, int y)
+{
+#if defined( VGUI_USEDRAGDROP )
+ if ( g_DragDropCapture.Get() )
+ {
+ bool started = g_DragDropCapture->GetDragDropInfo()->m_bDragStarted;
+
+ g_DragDropCapture->OnContinueDragging();
+
+ if ( started )
+ {
+ bool isEscapeKeyDown = input()->IsKeyDown( KEY_ESCAPE );
+ if ( isEscapeKeyDown )
+ {
+ g_DragDropCapture->OnFinishDragging( true, (MouseCode)-1, true );
+ }
+ return;
+ }
+ }
+#endif // VGUI_USEDRAGDROP
+
+ if ( !ShouldHandleInputMessage() )
+ return;
+
+ if ( IsCursorNone() )
+ return;
+
+ if ( !IsMouseInputEnabled() )
+ {
+ return;
+ }
+
+ if (IsBuildGroupEnabled())
+ {
+ if ( _buildGroup->CursorMoved(x, y, this) )
+ {
+ return;
+ }
+ }
+
+ if (m_pTooltips)
+ {
+ if ( _tooltipText )
+ {
+ m_pTooltips->SetText( _tooltipText );
+ }
+ m_pTooltips->ShowTooltip(this);
+ }
+
+ ScreenToLocal(x, y);
+
+ OnCursorMoved(x, y);
+}
+
+void Panel::InternalCursorEntered()
+{
+ if (IsCursorNone() || !IsMouseInputEnabled())
+ return;
+
+ if (IsBuildGroupEnabled())
+ return;
+
+ if (m_pTooltips)
+ {
+ m_pTooltips->ResetDelay();
+
+ if ( _tooltipText )
+ {
+ m_pTooltips->SetText( _tooltipText );
+ }
+ m_pTooltips->ShowTooltip(this);
+ }
+
+ OnCursorEntered();
+}
+
+void Panel::InternalCursorExited()
+{
+ if (IsCursorNone() || !IsMouseInputEnabled())
+ return;
+
+ if (IsBuildGroupEnabled())
+ return;
+
+ if (m_pTooltips)
+ {
+ m_pTooltips->HideTooltip();
+ }
+
+ OnCursorExited();
+}
+
+bool Panel::IsChildOfSurfaceModalPanel()
+{
+ VPANEL appModalPanel = input()->GetAppModalSurface();
+ if ( !appModalPanel )
+ return true;
+
+ if ( ipanel()->HasParent( GetVPanel(), appModalPanel ) )
+ return true;
+
+ return false;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool Panel::IsChildOfModalSubTree()
+{
+ VPANEL subTree = input()->GetModalSubTree();
+ if ( !subTree )
+ return true;
+
+ if ( HasParent( subTree ) )
+ return true;
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Checks to see if message is being subverted due to modal subtree logic
+// Input : -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+static bool ShouldHandleInputMessage( VPANEL p )
+{
+ // If there is not modal subtree, then always handle the msg
+ if ( !input()->GetModalSubTree() )
+ return true;
+
+ // What state are we in?
+ bool bChildOfModal = false;
+ VPANEL subTree = input()->GetModalSubTree();
+ if ( !subTree )
+ {
+ bChildOfModal = true;
+ }
+ else if ( ipanel()->HasParent( p, subTree ) )
+ {
+ bChildOfModal = true;
+ }
+
+ if ( input()->ShouldModalSubTreeReceiveMessages() )
+ return bChildOfModal;
+
+ return !bChildOfModal;
+}
+
+bool Panel::ShouldHandleInputMessage()
+{
+ return ::ShouldHandleInputMessage( GetVPanel() );
+}
+
+void Panel::InternalMousePressed(int code)
+{
+ long curtime = system()->GetTimeMillis();
+ if ( IsTriplePressAllowed() )
+ {
+ long elapsed = curtime - m_lLastDoublePressTime;
+ if ( elapsed < TRIPLE_PRESS_MSEC )
+ {
+ InternalMouseTriplePressed( code );
+ return;
+ }
+ }
+
+ // The menu system passively watches for mouse released messages so it
+ // can clear any open menus if the release is somewhere other than on a menu
+ Menu::OnInternalMousePressed( this, (MouseCode)code );
+
+ if ( !ShouldHandleInputMessage() )
+ return;
+
+ if ( IsCursorNone() )
+ return;
+
+ if ( !IsMouseInputEnabled())
+ {
+#if defined( VGUI_USEDRAGDROP )
+ DragDropStartDragging();
+#endif
+ return;
+ }
+
+ if (IsBuildGroupEnabled())
+ {
+ if ( _buildGroup->MousePressed((MouseCode)code, this) )
+ {
+ return;
+ }
+ }
+
+ Panel *pMouseHandler = m_hMouseEventHandler.Get();
+ if ( pMouseHandler )
+ {
+ pMouseHandler->OnMousePressed( (MouseCode)code );
+ }
+ else
+ {
+ OnMousePressed( (MouseCode)code );
+ }
+
+#if defined( VGUI_USEDRAGDROP )
+ DragDropStartDragging();
+#endif
+}
+
+void Panel::InternalMouseDoublePressed(int code)
+{
+ m_lLastDoublePressTime = system()->GetTimeMillis();
+
+ if ( !ShouldHandleInputMessage() )
+ return;
+
+ if ( IsCursorNone() )
+ return;
+
+ if ( !IsMouseInputEnabled())
+ {
+ return;
+ }
+
+ if (IsBuildGroupEnabled())
+ {
+ if ( _buildGroup->MouseDoublePressed((MouseCode)code, this) )
+ {
+ return;
+ }
+ }
+
+ Panel *pMouseHandler = m_hMouseEventHandler.Get();
+ if ( pMouseHandler )
+ {
+ pMouseHandler->OnMouseDoublePressed( (MouseCode)code );
+ }
+ else
+ {
+ OnMouseDoublePressed( (MouseCode)code );
+ }
+}
+
+#if defined( VGUI_USEDRAGDROP )
+void Panel::SetStartDragWhenMouseExitsPanel( bool state )
+{
+ _flags.SetFlag( DRAG_REQUIRES_PANEL_EXIT, state );
+}
+
+bool Panel::IsStartDragWhenMouseExitsPanel() const
+{
+ return _flags.IsFlagSet( DRAG_REQUIRES_PANEL_EXIT );
+}
+#endif // VGUI_USEDRAGDROP
+
+void Panel::SetTriplePressAllowed( bool state )
+{
+ _flags.SetFlag( TRIPLE_PRESS_ALLOWED, state );
+}
+
+bool Panel::IsTriplePressAllowed() const
+{
+ return _flags.IsFlagSet( TRIPLE_PRESS_ALLOWED );
+}
+
+void Panel::InternalMouseTriplePressed( int code )
+{
+ Assert( IsTriplePressAllowed() );
+ m_lLastDoublePressTime = 0L;
+
+ if ( !ShouldHandleInputMessage() )
+ return;
+
+ if ( IsCursorNone() )
+ return;
+
+ if ( !IsMouseInputEnabled())
+ {
+#if defined( VGUI_USEDRAGDROP )
+ DragDropStartDragging();
+#endif
+ return;
+ }
+
+ if (IsBuildGroupEnabled())
+ {
+ return;
+ }
+
+ OnMouseTriplePressed((MouseCode)code);
+#if defined( VGUI_USEDRAGDROP )
+ DragDropStartDragging();
+#endif
+}
+
+void Panel::InternalMouseReleased(int code)
+{
+#if defined( VGUI_USEDRAGDROP )
+ if ( g_DragDropCapture.Get() )
+ {
+ bool started = g_DragDropCapture->GetDragDropInfo()->m_bDragStarted;
+ g_DragDropCapture->OnFinishDragging( true, (MouseCode)code );
+ if ( started )
+ {
+ return;
+ }
+ }
+#endif
+
+ if ( !ShouldHandleInputMessage() )
+ return;
+
+ if ( IsCursorNone() )
+ return;
+
+ if ( !IsMouseInputEnabled())
+ {
+ return;
+ }
+
+ if (IsBuildGroupEnabled())
+ {
+ if ( _buildGroup->MouseReleased((MouseCode)code, this) )
+ {
+ return;
+ }
+ }
+
+ OnMouseReleased((MouseCode)code);
+}
+
+void Panel::InternalMouseWheeled(int delta)
+{
+ if (IsBuildGroupEnabled() || !IsMouseInputEnabled())
+ {
+ return;
+ }
+
+ if ( !ShouldHandleInputMessage() )
+ return;
+
+ OnMouseWheeled(delta);
+}
+
+void Panel::InternalKeyCodePressed(int code)
+{
+ if ( !ShouldHandleInputMessage() )
+ return;
+
+ if (IsKeyBoardInputEnabled())
+ {
+ OnKeyCodePressed((KeyCode)code);
+ }
+ else
+ {
+ CallParentFunction(new KeyValues("KeyCodePressed", "code", code));
+ }
+}
+
+#if defined( VGUI_USEKEYBINDINGMAPS )
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *bindingName -
+// keycode -
+// modifiers -
+//-----------------------------------------------------------------------------
+void Panel::AddKeyBinding( char const *bindingName, int keycode, int modifiers )
+{
+ PanelKeyBindingMap *map = LookupMapForBinding( bindingName );
+ if ( !map )
+ {
+ Assert( 0 );
+ return;
+ }
+
+ BoundKey_t kb;
+ kb.isbuiltin = false;
+ kb.bindingname = CopyString( bindingName );
+ kb.keycode = keycode;
+ kb.modifiers = modifiers;
+
+ map->boundkeys.AddToTail( kb );
+}
+
+KeyBindingMap_t *Panel::LookupBinding( char const *bindingName )
+{
+ PanelKeyBindingMap *map = GetKBMap();
+ while( map )
+ {
+ int c = map->entries.Count();
+ for( int i = 0; i < c ; ++i )
+ {
+ KeyBindingMap_t *binding = &map->entries[ i ];
+ if ( !Q_stricmp( binding->bindingname, bindingName ) )
+ return binding;
+ }
+
+ map = map->baseMap;
+ }
+
+ return NULL;
+}
+
+PanelKeyBindingMap *Panel::LookupMapForBinding( char const *bindingName )
+{
+ PanelKeyBindingMap *map = GetKBMap();
+ while( map )
+ {
+ int c = map->entries.Count();
+ for( int i = 0; i < c ; ++i )
+ {
+ KeyBindingMap_t *binding = &map->entries[ i ];
+ if ( !Q_stricmp( binding->bindingname, bindingName ) )
+ return map;
+ }
+
+ map = map->baseMap;
+ }
+
+ return NULL;
+}
+
+KeyBindingMap_t *Panel::LookupBindingByKeyCode( KeyCode code, int modifiers )
+{
+ PanelKeyBindingMap *map = GetKBMap();
+ while( map )
+ {
+ int c = map->boundkeys.Count();
+ for( int i = 0; i < c ; ++i )
+ {
+ BoundKey_t *kb = &map->boundkeys[ i ];
+ if ( kb->keycode == code && kb->modifiers == modifiers )
+ {
+ KeyBindingMap_t *binding = LookupBinding( kb->bindingname );
+ Assert( binding );
+ if ( binding )
+ {
+ return binding;
+ }
+ }
+ }
+
+ map = map->baseMap;
+ }
+
+ return NULL;
+}
+
+BoundKey_t *Panel::LookupDefaultKey( char const *bindingName )
+{
+ PanelKeyBindingMap *map = GetKBMap();
+ while( map )
+ {
+ int c = map->defaultkeys.Count();
+ for( int i = 0; i < c ; ++i )
+ {
+ BoundKey_t *kb = &map->defaultkeys[ i ];
+ if ( !Q_stricmp( kb->bindingname, bindingName ) )
+ {
+ return kb;
+ }
+ }
+
+ map = map->baseMap;
+ }
+ return NULL;
+}
+
+void Panel::LookupBoundKeys( char const *bindingName, CUtlVector< BoundKey_t * >& list )
+{
+ PanelKeyBindingMap *map = GetKBMap();
+ while( map )
+ {
+ int c = map->boundkeys.Count();
+ for( int i = 0; i < c ; ++i )
+ {
+ BoundKey_t *kb = &map->boundkeys[ i ];
+ if ( !Q_stricmp( kb->bindingname, bindingName ) )
+ {
+ list.AddToTail( kb );
+ }
+ }
+
+ map = map->baseMap;
+ }
+}
+
+void Panel::RevertKeyBindingsToDefault()
+{
+ PanelKeyBindingMap *map = GetKBMap();
+ while( map )
+ {
+ map->boundkeys.RemoveAll();
+ map->boundkeys = map->defaultkeys;
+
+ map = map->baseMap;
+ }
+}
+
+void Panel::RemoveAllKeyBindings()
+{
+ PanelKeyBindingMap *map = GetKBMap();
+ while( map )
+ {
+ map->boundkeys.RemoveAll();
+ map = map->baseMap;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void Panel::ReloadKeyBindings()
+{
+ RevertKeyBindingsToDefault();
+ LoadKeyBindingsForOnePanel( GetKeyBindingsContext(), this );
+}
+
+#define MAKE_STRING( x ) #x
+#define KEY_NAME( str, disp ) { KEY_##str, MAKE_STRING( KEY_##str ), disp }
+
+struct KeyNames_t
+{
+ KeyCode code;
+ char const *string;
+ char const *displaystring;
+};
+
+static KeyNames_t g_KeyNames[] =
+{
+KEY_NAME( NONE, "None" ),
+KEY_NAME( 0, "0" ),
+KEY_NAME( 1, "1" ),
+KEY_NAME( 2, "2" ),
+KEY_NAME( 3, "3" ),
+KEY_NAME( 4, "4" ),
+KEY_NAME( 5, "5" ),
+KEY_NAME( 6, "6" ),
+KEY_NAME( 7, "7" ),
+KEY_NAME( 8, "8" ),
+KEY_NAME( 9, "9" ),
+KEY_NAME( A, "A" ),
+KEY_NAME( B, "B" ),
+KEY_NAME( C, "C" ),
+KEY_NAME( D, "D" ),
+KEY_NAME( E, "E" ),
+KEY_NAME( F, "F" ),
+KEY_NAME( G, "G" ),
+KEY_NAME( H, "H" ),
+KEY_NAME( I, "I" ),
+KEY_NAME( J, "J" ),
+KEY_NAME( K, "K" ),
+KEY_NAME( L, "L" ),
+KEY_NAME( M, "M" ),
+KEY_NAME( N, "N" ),
+KEY_NAME( O, "O" ),
+KEY_NAME( P, "P" ),
+KEY_NAME( Q, "Q" ),
+KEY_NAME( R, "R" ),
+KEY_NAME( S, "S" ),
+KEY_NAME( T, "T" ),
+KEY_NAME( U, "U" ),
+KEY_NAME( V, "V" ),
+KEY_NAME( W, "W" ),
+KEY_NAME( X, "X" ),
+KEY_NAME( Y, "Y" ),
+KEY_NAME( Z, "Z" ),
+KEY_NAME( PAD_0, "Key Pad 0" ),
+KEY_NAME( PAD_1, "Key Pad 1" ),
+KEY_NAME( PAD_2, "Key Pad 2" ),
+KEY_NAME( PAD_3, "Key Pad 3" ),
+KEY_NAME( PAD_4, "Key Pad 4" ),
+KEY_NAME( PAD_5, "Key Pad 5" ),
+KEY_NAME( PAD_6, "Key Pad 6" ),
+KEY_NAME( PAD_7, "Key Pad 7" ),
+KEY_NAME( PAD_8, "Key Pad 8" ),
+KEY_NAME( PAD_9, "Key Pad 9" ),
+KEY_NAME( PAD_DIVIDE, "Key Pad /" ),
+KEY_NAME( PAD_MULTIPLY, "Key Pad *" ),
+KEY_NAME( PAD_MINUS, "Key Pad -" ),
+KEY_NAME( PAD_PLUS, "Key Pad +" ),
+KEY_NAME( PAD_ENTER, "Key Pad Enter" ),
+KEY_NAME( PAD_DECIMAL, "Key Pad ." ),
+KEY_NAME( LBRACKET, "[" ),
+KEY_NAME( RBRACKET, "]" ),
+KEY_NAME( SEMICOLON, "," ),
+KEY_NAME( APOSTROPHE, "'" ),
+KEY_NAME( BACKQUOTE, "`" ),
+KEY_NAME( COMMA, "," ),
+KEY_NAME( PERIOD, "." ),
+KEY_NAME( SLASH, "/" ),
+KEY_NAME( BACKSLASH, "\\" ),
+KEY_NAME( MINUS, "-" ),
+KEY_NAME( EQUAL, "=" ),
+KEY_NAME( ENTER, "Enter" ),
+KEY_NAME( SPACE, "Space" ),
+KEY_NAME( BACKSPACE, "Backspace" ),
+KEY_NAME( TAB, "Tab" ),
+KEY_NAME( CAPSLOCK, "Caps Lock" ),
+KEY_NAME( NUMLOCK, "Num Lock" ),
+KEY_NAME( ESCAPE, "Escape" ),
+KEY_NAME( SCROLLLOCK, "Scroll Lock" ),
+KEY_NAME( INSERT, "Ins" ),
+KEY_NAME( DELETE, "Del" ),
+KEY_NAME( HOME, "Home" ),
+KEY_NAME( END, "End" ),
+KEY_NAME( PAGEUP, "PgUp" ),
+KEY_NAME( PAGEDOWN, "PgDn" ),
+KEY_NAME( BREAK, "Break" ),
+KEY_NAME( LSHIFT, "Shift" ),
+KEY_NAME( RSHIFT, "Shift" ),
+KEY_NAME( LALT, "Alt" ),
+KEY_NAME( RALT, "Alt" ),
+KEY_NAME( LCONTROL, "Ctrl" ),
+KEY_NAME( RCONTROL, "Ctrl" ),
+KEY_NAME( LWIN, "Windows" ),
+KEY_NAME( RWIN, "Windows" ),
+KEY_NAME( APP, "App" ),
+KEY_NAME( UP, "Up" ),
+KEY_NAME( LEFT, "Left" ),
+KEY_NAME( DOWN, "Down" ),
+KEY_NAME( RIGHT, "Right" ),
+KEY_NAME( F1, "F1" ),
+KEY_NAME( F2, "F2" ),
+KEY_NAME( F3, "F3" ),
+KEY_NAME( F4, "F4" ),
+KEY_NAME( F5, "F5" ),
+KEY_NAME( F6, "F6" ),
+KEY_NAME( F7, "F7" ),
+KEY_NAME( F8, "F8" ),
+KEY_NAME( F9, "F9" ),
+KEY_NAME( F10, "F10" ),
+KEY_NAME( F11, "F11" ),
+KEY_NAME( F12, "F12" ),
+KEY_NAME( CAPSLOCKTOGGLE, "Caps Lock Toggle" ),
+KEY_NAME( NUMLOCKTOGGLE, "Num Lock Toggle" ),
+KEY_NAME( SCROLLLOCKTOGGLE, "Scroll Lock Toggle" ),
+};
+
+char const *Panel::KeyCodeToString( KeyCode code )
+{
+ int c = ARRAYSIZE( g_KeyNames );
+ for ( int i = 0; i < c ; ++i )
+ {
+ if ( g_KeyNames[ i ].code == code )
+ return g_KeyNames[ i ].string;
+ }
+
+ return "";
+}
+
+wchar_t const *Panel::KeyCodeToDisplayString( KeyCode code )
+{
+ int c = ARRAYSIZE( g_KeyNames );
+ for ( int i = 0; i < c ; ++i )
+ {
+ if ( g_KeyNames[ i ].code == code )
+ {
+ char const *str = g_KeyNames[ i ].displaystring;
+ wchar_t *wstr = g_pVGuiLocalize->Find( str );
+ if ( wstr )
+ {
+ return wstr;
+ }
+
+ static wchar_t buf[ 64 ];
+ g_pVGuiLocalize->ConvertANSIToUnicode( str, buf, sizeof( buf ) );
+ return buf;
+ }
+ }
+
+ return L"";
+}
+
+static void AddModifierToString( char const *modifiername, char *buf, size_t bufsize )
+{
+ char add[ 32 ];
+ if ( Q_strlen( buf ) > 0 )
+ {
+ Q_snprintf( add, sizeof( add ), "+%s", modifiername );
+ }
+ else
+ {
+ Q_strncpy( add, modifiername, sizeof( add ) );
+ }
+
+ Q_strncat( buf, add, bufsize, COPY_ALL_CHARACTERS );
+
+}
+
+wchar_t const *Panel::KeyCodeModifiersToDisplayString( KeyCode code, int modifiers )
+{
+ char sz[ 256 ];
+ sz[ 0 ] = 0;
+
+ if ( modifiers & MODIFIER_SHIFT )
+ {
+ AddModifierToString( "Shift", sz, sizeof( sz ) );
+ }
+ if ( modifiers & MODIFIER_CONTROL )
+ {
+ AddModifierToString( "Ctrl", sz, sizeof( sz ) );
+ }
+ if ( modifiers & MODIFIER_ALT )
+ {
+ AddModifierToString( "Alt", sz, sizeof( sz ) );
+ }
+
+ if ( Q_strlen( sz ) > 0 )
+ {
+ Q_strncat( sz, "+", sizeof( sz ), COPY_ALL_CHARACTERS );
+ }
+
+ static wchar_t unicode[ 256 ];
+ V_swprintf_safe( unicode, L"%S%s", sz, Panel::KeyCodeToDisplayString( (KeyCode)code ) );
+ return unicode;
+}
+
+KeyCode Panel::StringToKeyCode( char const *str )
+{
+ int c = ARRAYSIZE( g_KeyNames );
+ for ( int i = 0; i < c ; ++i )
+ {
+ if ( !Q_stricmp( str, g_KeyNames[ i ].string ) )
+ return g_KeyNames[ i ].code;
+ }
+
+ return KEY_NONE;
+}
+
+static void WriteKeyBindingToBuffer( CUtlBuffer& buf, int level, const BoundKey_t& binding )
+{
+ BufPrint( buf, level, "\"keycode\"\t\"%s\"\n", Panel::KeyCodeToString( (KeyCode)binding.keycode ) );
+ if ( binding.modifiers & MODIFIER_SHIFT )
+ {
+ BufPrint( buf, level, "\"shift\"\t\"1\"\n" );
+ }
+ if ( binding.modifiers & MODIFIER_CONTROL )
+ {
+ BufPrint( buf, level, "\"ctrl\"\t\"1\"\n" );
+ }
+ if ( binding.modifiers & MODIFIER_ALT )
+ {
+ BufPrint( buf, level, "\"alt\"\t\"1\"\n" );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *filename -
+// *pathID -
+//-----------------------------------------------------------------------------
+void Panel::SaveKeyBindingsToBuffer( int level, CUtlBuffer& buf )
+{
+ Assert( IsValidKeyBindingsContext() );
+
+ Assert( buf.IsText() );
+
+ PanelKeyBindingMap *map = GetKBMap();
+ while( map )
+ {
+ int c = map->boundkeys.Count();
+ for( int i = 0; i < c ; ++i )
+ {
+ const BoundKey_t& binding = map->boundkeys[ i ];
+
+ // Spew to file
+ BufPrint( buf, level, "\"%s\"\n", binding.bindingname );
+ BufPrint( buf, level, "{\n" );
+
+ WriteKeyBindingToBuffer( buf, level + 1, binding );
+
+ BufPrint( buf, level, "}\n" );
+ }
+
+ map = map->baseMap;
+ }
+}
+
+bool Panel::ParseKeyBindings( KeyValues *kv )
+{
+ Assert( IsValidKeyBindingsContext() );
+ if ( !IsValidKeyBindingsContext() )
+ return false;
+
+ // To have KB the panel must have a name
+ Assert( GetName() && GetName()[ 0 ] );
+ if ( !GetName() || !GetName()[ 0 ] )
+ return false;
+
+ bool success = false;
+
+ g_KBMgr.AddPanelToContext( GetKeyBindingsContext(), this );
+
+ RemoveAllKeyBindings();
+
+ // Walk through bindings
+ for ( KeyValues *binding = kv->GetFirstSubKey(); binding != NULL; binding = binding->GetNextKey() )
+ {
+ char const *bindingName = binding->GetName();
+ if ( !bindingName || !bindingName[ 0 ] )
+ continue;
+
+ KeyBindingMap_t *b = LookupBinding( bindingName );
+ if ( b )
+ {
+ success = true;
+ const char *keycode = binding->GetString( "keycode", "" );
+ int modifiers = 0;
+ if ( binding->GetInt( "shift", 0 ) != 0 )
+ {
+ modifiers |= MODIFIER_SHIFT;
+ }
+ if ( binding->GetInt( "ctrl", 0 ) != 0 )
+ {
+ modifiers |= MODIFIER_CONTROL;
+ }
+ if ( binding->GetInt( "alt", 0 ) != 0 )
+ {
+ modifiers |= MODIFIER_ALT;
+ }
+
+ KeyBindingMap_t *bound = LookupBindingByKeyCode( StringToKeyCode( keycode ), modifiers );
+ if ( !bound )
+ {
+ AddKeyBinding( bindingName, StringToKeyCode( keycode ), modifiers );
+ }
+ }
+ else
+ {
+ Warning( "KeyBinding for panel '%s' contained unknown binding '%s'\n", GetName() ? GetName() : "???", bindingName );
+ }
+ }
+
+ // Now for each binding which is currently "unbound" to any key, use the default binding
+ PanelKeyBindingMap *map = GetKBMap();
+ while( map )
+ {
+ int c = map->entries.Count();
+ for( int i = 0; i < c ; ++i )
+ {
+ KeyBindingMap_t *binding = &map->entries[ i ];
+
+ // See if there is a bound key
+ CUtlVector< BoundKey_t * > list;
+ LookupBoundKeys( binding->bindingname, list );
+ if ( list.Count() == 0 )
+ {
+ // Assign the default binding to this key
+ BoundKey_t *defaultKey = LookupDefaultKey( binding->bindingname );
+ if ( defaultKey )
+ {
+ KeyBindingMap_t *alreadyBound = LookupBindingByKeyCode( (KeyCode)defaultKey->keycode, defaultKey->modifiers );
+ if ( alreadyBound )
+ {
+ Warning( "No binding for '%s', defautl key already bound to '%s'\n", binding->bindingname, alreadyBound->bindingname );
+ }
+ else
+ {
+ AddKeyBinding( defaultKey->bindingname, defaultKey->keycode, defaultKey->modifiers );
+ }
+ }
+ }
+ }
+
+ map = map->baseMap;
+ }
+
+ return success;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : handle -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+void Panel::SetKeyBindingsContext( KeyBindingContextHandle_t handle )
+{
+ Assert( !IsValidKeyBindingsContext() || handle == GetKeyBindingsContext() );
+ g_KBMgr.AddPanelToContext( handle, this );
+ m_hKeyBindingsContext = handle;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+// Output : KeyBindingContextHandle_t
+//-----------------------------------------------------------------------------
+KeyBindingContextHandle_t Panel::GetKeyBindingsContext() const
+{
+ return m_hKeyBindingsContext;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool Panel::IsValidKeyBindingsContext() const
+{
+ return GetKeyBindingsContext() != INVALID_KEYBINDINGCONTEXT_HANDLE;
+}
+
+char const *Panel::GetKeyBindingsFile() const
+{
+ Assert( IsValidKeyBindingsContext() );
+ return g_KBMgr.GetKeyBindingsFile( GetKeyBindingsContext() );
+}
+
+char const *Panel::GetKeyBindingsFilePathID() const
+{
+ Assert( IsValidKeyBindingsContext() );
+ return g_KBMgr.GetKeyBindingsFilePathID( GetKeyBindingsContext() );
+}
+
+void Panel::EditKeyBindings()
+{
+ Assert( 0 );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Set this to false to disallow IsKeyRebound chaining to GetParent() Panels...
+// Input : state -
+//-----------------------------------------------------------------------------
+void Panel::SetAllowKeyBindingChainToParent( bool state )
+{
+ _flags.SetFlag( ALLOW_CHAIN_KEYBINDING_TO_PARENT, state );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool Panel::IsKeyBindingChainToParentAllowed() const
+{
+ return _flags.IsFlagSet( ALLOW_CHAIN_KEYBINDING_TO_PARENT );
+}
+
+bool Panel::IsKeyOverridden( KeyCode code, int modifiers )
+{
+ // By default assume all keys should pass through binding system
+ return false;
+}
+
+bool Panel::IsKeyRebound( KeyCode code, int modifiers )
+{
+ if ( IsKeyBoardInputEnabled() )
+ {
+ KeyBindingMap_t* binding = LookupBindingByKeyCode( code, modifiers );
+ // Only dispatch if we're part of the current modal subtree
+ if ( binding && IsChildOfSurfaceModalPanel() )
+ {
+ // Found match, post message to panel
+ if ( binding->func )
+ {
+ // dispatch the func
+ (this->*binding->func)();
+ }
+ else
+ {
+ Assert( 0 );
+ }
+
+ if ( !binding->passive )
+ {
+ // Exit this function...
+ return true;
+ }
+ }
+ }
+
+ // Chain to parent
+ Panel* pParent = GetParent();
+ if ( IsKeyBindingChainToParentAllowed() && pParent && !IsKeyOverridden( code, modifiers ) )
+ return pParent->IsKeyRebound( code, modifiers );
+
+ // No suitable binding found
+ return false;
+}
+
+static bool s_bSuppressRebindChecks = false;
+#endif // VGUI_USEKEYBINDINGMAPS
+
+void Panel::InternalKeyCodeTyped( int code )
+{
+ if ( !ShouldHandleInputMessage() )
+ {
+ input()->OnKeyCodeUnhandled( code );
+ return;
+ }
+
+ if (IsKeyBoardInputEnabled())
+ {
+ bool shift = (input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT));
+ bool ctrl = (input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL));
+ bool alt = (input()->IsKeyDown(KEY_LALT) || input()->IsKeyDown(KEY_RALT));
+
+ int modifiers = 0;
+ if ( shift )
+ {
+ modifiers |= MODIFIER_SHIFT;
+ }
+ if ( ctrl )
+ {
+ modifiers |= MODIFIER_CONTROL;
+ }
+ if ( alt )
+ {
+ modifiers |= MODIFIER_ALT;
+ }
+
+ // Things in build mode don't have accelerators
+ if (IsBuildGroupEnabled())
+ {
+ _buildGroup->KeyCodeTyped((KeyCode)code, this);
+ return;
+ }
+
+ if ( !s_bSuppressRebindChecks && IsKeyRebound( (KeyCode)code, modifiers ) )
+ {
+ return;
+ }
+
+ bool oldVal = s_bSuppressRebindChecks;
+ s_bSuppressRebindChecks = true;
+ OnKeyCodeTyped((KeyCode)code);
+ s_bSuppressRebindChecks = oldVal;
+ }
+ else
+ {
+ if ( GetVPanel() == surface()->GetEmbeddedPanel() )
+ {
+ input()->OnKeyCodeUnhandled( code );
+ }
+ CallParentFunction(new KeyValues("KeyCodeTyped", "code", code));
+ }
+}
+
+void Panel::InternalKeyTyped(int unichar)
+{
+ if ( !ShouldHandleInputMessage() )
+ return;
+
+ if (IsKeyBoardInputEnabled())
+ {
+ if ( IsBuildGroupEnabled() )
+ {
+ if ( _buildGroup->KeyTyped( (wchar_t)unichar, this ) )
+ {
+ return;
+ }
+ }
+
+ OnKeyTyped((wchar_t)unichar);
+ }
+ else
+ {
+ CallParentFunction(new KeyValues("KeyTyped", "unichar", unichar));
+ }
+}
+
+void Panel::InternalKeyCodeReleased(int code)
+{
+ if ( !ShouldHandleInputMessage() )
+ return;
+
+ if (IsKeyBoardInputEnabled())
+ {
+ if (IsBuildGroupEnabled())
+ {
+ if ( _buildGroup->KeyCodeReleased((KeyCode)code, this) )
+ {
+ return;
+ }
+ }
+
+ OnKeyCodeReleased((KeyCode)code);
+ }
+ else
+ {
+ CallParentFunction(new KeyValues("KeyCodeReleased", "code", code));
+ }
+}
+
+void Panel::InternalKeyFocusTicked()
+{
+ if (IsBuildGroupEnabled())
+ return;
+
+ OnKeyFocusTicked();
+}
+
+void Panel::InternalMouseFocusTicked()
+{
+ if (IsBuildGroupEnabled())
+ {
+ // must repaint so the numbers will be accurate
+ if (_buildGroup->HasRulersOn())
+ {
+ PaintTraverse(true);
+ }
+ return;
+ }
+
+ // update cursor
+ InternalSetCursor();
+ OnMouseFocusTicked();
+}
+
+
+void Panel::InternalSetCursor()
+{
+ bool visible = IsVisible();
+
+ if (visible)
+ {
+#if defined( VGUI_USEDRAGDROP )
+ // Drag drop is overriding cursor?
+ if ( m_pDragDrop->m_bDragging ||
+ g_DragDropCapture.Get() != NULL )
+ return;
+#endif
+ // chain up and make sure all our parents are also visible
+ VPANEL p = GetVParent();
+ while (p)
+ {
+ visible &= ipanel()->IsVisible(p);
+ p = ipanel()->GetParent(p);
+ }
+
+ // only change the cursor if this panel is visible, and if its part of the main VGUI tree
+ if (visible && HasParent(surface()->GetEmbeddedPanel()))
+ {
+ HCursor cursor = GetCursor();
+
+ if (IsBuildGroupEnabled())
+ {
+ cursor = _buildGroup->GetCursor(this);
+ }
+
+ if (input()->GetCursorOveride())
+ {
+ cursor = input()->GetCursorOveride();
+ }
+
+ surface()->SetCursor(cursor);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Called every frame the panel is visible, designed to be overridden
+//-----------------------------------------------------------------------------
+void Panel::OnThink()
+{
+#if defined( VGUI_USEDRAGDROP )
+ if ( IsPC() &&
+ m_pDragDrop->m_bDragEnabled &&
+ m_pDragDrop->m_bDragging &&
+ m_pDragDrop->m_bDragStarted )
+ {
+ bool isEscapeKeyDown = input()->IsKeyDown( KEY_ESCAPE );
+ if ( isEscapeKeyDown )
+ {
+ OnContinueDragging();
+ OnFinishDragging( true, (MouseCode)-1, true );
+ return;
+ }
+
+ if ( m_pDragDrop->m_hCurrentDrop != 0 )
+ {
+ if ( !input()->IsMouseDown( MOUSE_LEFT ) )
+ {
+ OnContinueDragging();
+ OnFinishDragging( true, (MouseCode)-1 );
+ return;
+ }
+
+ // allow the cursor to change based upon things like changing keystate, etc.
+ surface()->SetCursor( m_pDragDrop->m_hCurrentDrop->GetDropCursor( m_pDragDrop->m_DragData ) );
+
+ if ( !m_pDragDrop->m_bDropMenuShown )
+ {
+ // See if the hover time has gotten larger
+ float hoverSeconds = ( system()->GetTimeMillis() - m_pDragDrop->m_lDropHoverTime ) * 0.001f;
+ DragDrop_t *dropInfo = m_pDragDrop->m_hCurrentDrop->GetDragDropInfo();
+
+ if ( dropInfo->m_flHoverContextTime != 0.0f )
+ {
+ if ( hoverSeconds >= dropInfo->m_flHoverContextTime )
+ {
+ m_pDragDrop->m_bDropMenuShown = true;
+
+ CUtlVector< KeyValues * > data;
+
+ GetDragData( data );
+
+ int x, y;
+ input()->GetCursorPos( x, y );
+
+ if ( m_pDragDrop->m_hDropContextMenu.Get() )
+ {
+ delete m_pDragDrop->m_hDropContextMenu.Get();
+ }
+
+ Menu *menu = new Menu( m_pDragDrop->m_hCurrentDrop.Get(), "DropContext" );
+
+ bool useMenu = m_pDragDrop->m_hCurrentDrop->GetDropContextMenu( menu, data );
+ if ( useMenu )
+ {
+ m_pDragDrop->m_hDropContextMenu = menu;
+
+ menu->SetPos( x, y );
+ menu->SetVisible( true );
+ menu->MakePopup();
+ surface()->MovePopupToFront( menu->GetVPanel() );
+ if ( menu->GetItemCount() > 0 )
+ {
+ int id = menu->GetMenuID( 0 );
+ menu->SetCurrentlyHighlightedItem( id );
+ MenuItem *item = menu->GetMenuItem( id );
+ item->SetArmed( true );
+ }
+ }
+ else
+ {
+ delete menu;
+ }
+
+ m_pDragDrop->m_hCurrentDrop->OnDropContextHoverShow( data );
+ }
+ }
+ }
+ }
+ }
+#endif
+}
+
+// input messages handlers (designed for override)
+void Panel::OnCursorMoved(int x, int y)
+{
+ if( ParentNeedsCursorMoveEvents() )
+ {
+ // figure out x and y in parent space
+ int thisX, thisY;
+ ipanel()->GetPos( GetVPanel(), thisX, thisY );
+ CallParentFunction( new KeyValues( "OnCursorMoved", "x", x + thisX, "y", y + thisY ) );
+ }
+}
+
+void Panel::OnCursorEntered()
+{
+}
+
+void Panel::OnCursorExited()
+{
+}
+
+void Panel::OnMousePressed(MouseCode code)
+{
+}
+
+void Panel::OnMouseDoublePressed(MouseCode code)
+{
+}
+
+void Panel::OnMouseTriplePressed(MouseCode code)
+{
+}
+
+void Panel::OnMouseReleased(MouseCode code)
+{
+}
+
+void Panel::OnMouseWheeled(int delta)
+{
+ CallParentFunction(new KeyValues("MouseWheeled", "delta", delta));
+}
+
+// base implementation forwards Key messages to the Panel's parent - override to 'swallow' the input
+void Panel::OnKeyCodePressed(KeyCode code)
+{
+ static ConVarRef vgui_nav_lock( "vgui_nav_lock" );
+
+ bool handled = false;
+ switch( GetBaseButtonCode( code ) )
+ {
+ case KEY_XBUTTON_UP:
+ case KEY_XSTICK1_UP:
+ case KEY_XSTICK2_UP:
+ case KEY_UP:
+ if ( ( !vgui_nav_lock.IsValid() || vgui_nav_lock.GetInt() == 0 ) && NavigateUp() )
+ {
+ vgui_nav_lock.SetValue( 1 );
+ vgui::surface()->PlaySound( "UI/menu_focus.wav" );
+ handled = true;
+ }
+ break;
+ case KEY_XBUTTON_DOWN:
+ case KEY_XSTICK1_DOWN:
+ case KEY_XSTICK2_DOWN:
+ case KEY_DOWN:
+ if ( ( !vgui_nav_lock.IsValid() || vgui_nav_lock.GetInt() == 0 ) && NavigateDown() )
+ {
+ vgui_nav_lock.SetValue( 1 );
+ vgui::surface()->PlaySound( "UI/menu_focus.wav" );
+ handled = true;
+ }
+ break;
+ case KEY_XBUTTON_LEFT:
+ case KEY_XSTICK1_LEFT:
+ case KEY_XSTICK2_LEFT:
+ case KEY_LEFT:
+ if ( ( !vgui_nav_lock.IsValid() || vgui_nav_lock.GetInt() == 0 ) && NavigateLeft() )
+ {
+ vgui_nav_lock.SetValue( 1 );
+ vgui::surface()->PlaySound( "UI/menu_focus.wav" );
+ handled = true;
+ }
+ break;
+ case KEY_XBUTTON_RIGHT:
+ case KEY_XSTICK1_RIGHT:
+ case KEY_XSTICK2_RIGHT:
+ case KEY_RIGHT:
+ if ( ( !vgui_nav_lock.IsValid() || vgui_nav_lock.GetInt() == 0 ) && NavigateRight() )
+ {
+ vgui_nav_lock.SetValue( 1 );
+ vgui::surface()->PlaySound( "UI/menu_focus.wav" );
+ handled = true;
+ }
+ break;
+ case KEY_XBUTTON_B:
+ if ( ( !vgui_nav_lock.IsValid() || vgui_nav_lock.GetInt() == 0 ) && NavigateBack() )
+ {
+ vgui_nav_lock.SetValue( 1 );
+ vgui::surface()->PlaySound( "UI/menu_focus.wav" );
+ handled = true;
+ }
+ break;
+ }
+
+ if( !handled && !m_PassUnhandledInput )
+ return;
+
+ CallParentFunction(new KeyValues("KeyCodePressed", "code", code));
+}
+
+void Panel::OnKeyCodeTyped(KeyCode keycode)
+{
+ vgui::KeyCode code = GetBaseButtonCode( keycode );
+
+ // handle focus change
+ if ( IsX360() || IsConsoleStylePanel() )
+ {
+ // eat these typed codes, will get handled in OnKeyCodePressed
+ switch ( code )
+ {
+ case KEY_XBUTTON_UP:
+ case KEY_XSTICK1_UP:
+ case KEY_XSTICK2_UP:
+ case KEY_XBUTTON_DOWN:
+ case KEY_XSTICK1_DOWN:
+ case KEY_XSTICK2_DOWN:
+ case KEY_XBUTTON_LEFT:
+ case KEY_XSTICK1_LEFT:
+ case KEY_XSTICK2_LEFT:
+ case KEY_XBUTTON_RIGHT:
+ case KEY_XSTICK1_RIGHT:
+ case KEY_XSTICK2_RIGHT:
+ case KEY_XBUTTON_A:
+ case KEY_XBUTTON_B:
+ case KEY_XBUTTON_X:
+ case KEY_XBUTTON_Y:
+ case KEY_XBUTTON_LEFT_SHOULDER:
+ case KEY_XBUTTON_RIGHT_SHOULDER:
+ case KEY_XBUTTON_BACK:
+ case KEY_XBUTTON_START:
+ case KEY_XBUTTON_STICK1:
+ case KEY_XBUTTON_STICK2:
+ case KEY_XBUTTON_LTRIGGER:
+ case KEY_XBUTTON_RTRIGGER:
+
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ return;
+ }
+
+ // legacy handling - need to re-enable for older apps?
+ /*
+ if ( code == KEY_XSTICK1_RIGHT || code == KEY_XBUTTON_RIGHT )
+ {
+ RequestFocusNext();
+ return;
+ }
+ else if ( code == KEY_XSTICK1_LEFT || code == KEY_XBUTTON_LEFT )
+ {
+ RequestFocusPrev();
+ return;
+ }
+ */
+ }
+
+ if (code == KEY_TAB)
+ {
+ bool bShiftDown = input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT);
+
+ if ( IsConsoleStylePanel() )
+ {
+ if ( bShiftDown )
+ {
+ NavigateUp();
+ }
+ else
+ {
+ NavigateDown();
+ }
+ }
+ else
+ {
+ // if shift is down goto previous tab position, otherwise goto next
+ if ( bShiftDown )
+ {
+ RequestFocusPrev();
+ }
+ else
+ {
+ RequestFocusNext();
+ }
+ }
+ }
+ else
+ {
+ // forward up
+ if ( GetVPanel() == surface()->GetEmbeddedPanel() )
+ {
+ input()->OnKeyCodeUnhandled( keycode );
+ }
+ CallParentFunction(new KeyValues("KeyCodeTyped", "code", keycode));
+ }
+}
+
+void Panel::OnKeyTyped(wchar_t unichar)
+{
+ CallParentFunction(new KeyValues("KeyTyped", "unichar", unichar));
+}
+
+void Panel::OnKeyCodeReleased(KeyCode code)
+{
+ CallParentFunction(new KeyValues("KeyCodeReleased", "code", code));
+}
+
+void Panel::OnKeyFocusTicked()
+{
+ CallParentFunction(new KeyValues("KeyFocusTicked"));
+}
+
+void Panel::OnMouseFocusTicked()
+{
+ CallParentFunction(new KeyValues("OnMouseFocusTicked"));
+}
+
+bool Panel::IsWithin(int x,int y)
+{
+ // check against our clip rect
+ int clipRect[4];
+ ipanel()->GetClipRect(GetVPanel(), clipRect[0], clipRect[1], clipRect[2], clipRect[3]);
+
+ if (x < clipRect[0])
+ {
+ return false;
+ }
+
+ if (y < clipRect[1])
+ {
+ return false;
+ }
+
+ if (x >= clipRect[2])
+ {
+ return false;
+ }
+
+ if (y >= clipRect[3])
+ {
+ return false;
+ }
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: determines which is the topmost panel under the coordinates (x, y)
+//-----------------------------------------------------------------------------
+VPANEL Panel::IsWithinTraverse(int x, int y, bool traversePopups)
+{
+ // if this one is not visible, its children won't be either
+ // also if it doesn't want mouse input its children can't get it either
+ if (!IsVisible() || !IsMouseInputEnabled())
+ return NULL;
+
+ if (traversePopups)
+ {
+ // check popups first
+ int i;
+ CUtlVector< VPANEL > &children = ipanel()->GetChildren( GetVPanel() );
+ int childCount = children.Count();
+ for (i = childCount - 1; i >= 0; i--)
+ {
+ VPANEL panel = children[ i ];
+ if (ipanel()->IsPopup(panel))
+ {
+ panel = ipanel()->IsWithinTraverse(panel, x, y, true);
+ if (panel != null)
+ {
+ return panel;
+ }
+ }
+ }
+
+ // check children recursive, if you find one, just return first one
+ // this checks in backwards order so the last child drawn for this panel is chosen which
+ // coincides to how it would be visibly displayed
+ for (i = childCount - 1; i >= 0; i--)
+ {
+ VPANEL panel = children[ i ];
+ // we've already checked popups so ignore
+ if (!ipanel()->IsPopup(panel))
+ {
+ panel = ipanel()->IsWithinTraverse(panel, x, y, true);
+ if (panel != 0)
+ {
+ return panel;
+ }
+ }
+ }
+
+ // check ourself
+ if ( !IsMouseInputDisabledForThisPanel() && IsWithin(x, y) )
+ {
+ return GetVPanel();
+ }
+ }
+ else
+ {
+ // since we're not checking popups, it must be within us, so we can check ourself first
+ if (IsWithin(x, y))
+ {
+ // check children recursive, if you find one, just return first one
+ // this checks in backwards order so the last child drawn for this panel is chosen which
+ // coincides to how it would be visibly displayed
+ CUtlVector< VPANEL > &children = ipanel()->GetChildren( GetVPanel() );
+ int childCount = children.Count();
+ for (int i = childCount - 1; i >= 0; i--)
+ {
+ VPANEL panel = children[ i ];
+ // ignore popups
+ if (!ipanel()->IsPopup(panel))
+ {
+ panel = ipanel()->IsWithinTraverse(panel, x, y, false);
+ if (panel != 0)
+ {
+ return panel;
+ }
+ }
+ }
+
+ // not a child, must be us
+ if ( !IsMouseInputDisabledForThisPanel() )
+ return GetVPanel();
+ }
+ }
+
+ return NULL;
+}
+
+void Panel::LocalToScreen(int& x,int& y)
+{
+ int px, py;
+ ipanel()->GetAbsPos(GetVPanel(), px, py);
+
+ x = x + px;
+ y = y + py;
+}
+
+void Panel::ScreenToLocal(int& x,int& y)
+{
+ int px, py;
+ ipanel()->GetAbsPos(GetVPanel(), px, py);
+
+ x = x - px;
+ y = y - py;
+}
+
+void Panel::ParentLocalToScreen(int &x, int &y)
+{
+ int px, py;
+ ipanel()->GetAbsPos(GetVParent(), px, py);
+
+ x = x + px;
+ y = y + py;
+}
+
+void Panel::MakePopup(bool showTaskbarIcon,bool disabled)
+{
+ surface()->CreatePopup(GetVPanel(), false, showTaskbarIcon,disabled);
+}
+
+void Panel::SetCursor(HCursor cursor)
+{
+ _cursor = cursor;
+}
+
+HCursor Panel::GetCursor()
+{
+ return _cursor;
+}
+
+void Panel::SetCursorAlwaysVisible( bool visible )
+{
+ surface()->SetCursorAlwaysVisible( visible );
+}
+
+void Panel::SetMinimumSize(int wide,int tall)
+{
+ ipanel()->SetMinimumSize(GetVPanel(), wide, tall);
+}
+
+void Panel::GetMinimumSize(int& wide,int &tall)
+{
+ ipanel()->GetMinimumSize(GetVPanel(), wide, tall);
+}
+
+bool Panel::IsBuildModeEditable()
+{
+ return true;
+}
+
+void Panel::SetBuildModeEditable(bool state)
+{
+ if (state)
+ {
+ _buildModeFlags |= BUILDMODE_EDITABLE;
+ }
+ else
+ {
+ _buildModeFlags &= ~BUILDMODE_EDITABLE;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: data accessor
+//-----------------------------------------------------------------------------
+bool Panel::IsBuildModeDeletable()
+{
+ return (_buildModeFlags & BUILDMODE_DELETABLE);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: data accessor
+//-----------------------------------------------------------------------------
+void Panel::SetBuildModeDeletable(bool state)
+{
+ if (state)
+ {
+ _buildModeFlags |= BUILDMODE_DELETABLE;
+ }
+ else
+ {
+ _buildModeFlags &= ~BUILDMODE_DELETABLE;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool Panel::IsBuildModeActive()
+{
+ return _buildGroup ? _buildGroup->IsEnabled() : false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::GetClipRect(int& x0,int& y0,int& x1,int& y1)
+{
+ ipanel()->GetClipRect(GetVPanel(), x0, y0, x1, y1);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int Panel::GetChildCount()
+{
+ if (ipanel())
+ {
+ return ipanel()->GetChildCount(GetVPanel());
+ }
+
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: returns a child by the specified index
+//-----------------------------------------------------------------------------
+Panel *Panel::GetChild(int index)
+{
+ // get the child and cast it to a panel
+ // this assumes that the child is from the same module as the this (precondition)
+ return ipanel()->GetPanel(ipanel()->GetChild(GetVPanel(), index), GetControlsModuleName());
+}
+
+CUtlVector< VPANEL > &Panel::GetChildren()
+{
+ return ipanel()->GetChildren(GetVPanel());
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: moves the key focus back
+//-----------------------------------------------------------------------------
+bool Panel::RequestFocusPrev(VPANEL panel)
+{
+ // chain to parent
+ if (GetVParent())
+ {
+ return ipanel()->RequestFocusPrev(GetVParent(), GetVPanel());
+ }
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool Panel::RequestFocusNext(VPANEL panel)
+{
+ // chain to parent
+ if (GetVParent())
+ {
+ return ipanel()->RequestFocusNext(GetVParent(), GetVPanel());
+ }
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Sets the panel to have the current sub focus
+// Input : direction - the direction in which focus travelled to arrive at this panel; forward = 1, back = -1
+//-----------------------------------------------------------------------------
+void Panel::RequestFocus(int direction)
+{
+ // NOTE: This doesn't make any sense if we don't have keyboard input enabled
+ Assert( ( IsX360() || IsConsoleStylePanel() ) || IsKeyBoardInputEnabled() );
+ // ivgui()->DPrintf2("RequestFocus(%s, %s)\n", GetName(), GetClassName());
+ OnRequestFocus(GetVPanel(), NULL);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Called after a panel requests focus to fix up the whole chain
+//-----------------------------------------------------------------------------
+void Panel::OnRequestFocus(VPANEL subFocus, VPANEL defaultPanel)
+{
+ CallParentFunction(new KeyValues("OnRequestFocus", "subFocus", subFocus, "defaultPanel", defaultPanel));
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+VPANEL Panel::GetCurrentKeyFocus()
+{
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: returns true if the panel has focus
+//-----------------------------------------------------------------------------
+bool Panel::HasFocus()
+{
+ if (input()->GetFocus() == GetVPanel())
+ {
+ return true;
+ }
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::SetTabPosition(int position)
+{
+ _tabPosition = position;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int Panel::GetTabPosition()
+{
+ return _tabPosition;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::InternalFocusChanged(bool lost)
+{
+ /*
+ //if focus is gained tell the focusNavGroup about it so its current can be correct
+ if( (!lost) && (_focusNavGroup!=null) )
+ {
+ _focusNavGroup->setCurrentPanel(this);
+ }
+ */
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Called when a panel loses it's mouse capture
+//-----------------------------------------------------------------------------
+void Panel::OnMouseCaptureLost()
+{
+ if (m_pTooltips)
+ {
+ m_pTooltips->ResetDelay();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::AddActionSignalTarget(Panel *messageTarget)
+{
+ HPanel target = ivgui()->PanelToHandle(messageTarget->GetVPanel());
+ if (!_actionSignalTargetDar.HasElement(target))
+ {
+ _actionSignalTargetDar.AddElement(target);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::AddActionSignalTarget(VPANEL messageTarget)
+{
+ HPanel target = ivgui()->PanelToHandle(messageTarget);
+ if (!_actionSignalTargetDar.HasElement(target))
+ {
+ _actionSignalTargetDar.AddElement(target);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::RemoveActionSignalTarget(Panel *oldTarget)
+{
+ _actionSignalTargetDar.RemoveElement(ivgui()->PanelToHandle(oldTarget->GetVPanel()));
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Sends a message to all the panels that have requested action signals
+//-----------------------------------------------------------------------------
+void Panel::PostActionSignal( KeyValues *message )
+{
+ if ( m_bIsSilent != true )
+ {
+ // add who it was from the message
+ message->SetPtr("panel", this);
+ int i;
+ for (i = _actionSignalTargetDar.GetCount() - 1; i > 0; i--)
+ {
+ VPANEL panel = ivgui()->HandleToPanel(_actionSignalTargetDar[i]);
+ if (panel)
+ {
+ ivgui()->PostMessage(panel, message->MakeCopy(), GetVPanel());
+ }
+ }
+
+ // do this so we can save on one MakeCopy() call
+ if (i == 0)
+ {
+ VPANEL panel = ivgui()->HandleToPanel(_actionSignalTargetDar[i]);
+ if (panel)
+ {
+ ivgui()->PostMessage(panel, message, GetVPanel());
+ return;
+ }
+ }
+ }
+ message->deleteThis();
+}
+
+void Panel::SetBorder(IBorder *border)
+{
+ _border = border;
+
+ if (border)
+ {
+ int x, y, x2, y2;
+ border->GetInset(x, y, x2, y2);
+ ipanel()->SetInset(GetVPanel(), x, y, x2, y2);
+
+ // update our background type based on the bord
+ SetPaintBackgroundType(border->GetBackgroundType());
+ }
+ else
+ {
+ ipanel()->SetInset(GetVPanel(), 0, 0, 0, 0);
+ }
+}
+
+IBorder *Panel::GetBorder()
+{
+ return _border;
+}
+
+
+void Panel::SetPaintBorderEnabled(bool state)
+{
+ _flags.SetFlag( PAINT_BORDER_ENABLED, state );
+}
+
+void Panel::SetPaintBackgroundEnabled(bool state)
+{
+ _flags.SetFlag( PAINT_BACKGROUND_ENABLED, state );
+}
+
+void Panel::SetPaintBackgroundType( int type )
+{
+ // HACK only 0 through 2 supported for now
+ m_nPaintBackgroundType = clamp( type, 0, 2 );
+}
+
+void Panel::SetPaintEnabled(bool state)
+{
+ _flags.SetFlag( PAINT_ENABLED, state );
+}
+
+void Panel::SetPostChildPaintEnabled(bool state)
+{
+ _flags.SetFlag( POST_CHILD_PAINT_ENABLED, state );
+}
+
+void Panel::GetInset(int& left,int& top,int& right,int& bottom)
+{
+ ipanel()->GetInset(GetVPanel(), left, top, right, bottom);
+}
+
+void Panel::GetPaintSize(int& wide,int& tall)
+{
+ GetSize(wide, tall);
+ if (_border != null)
+ {
+ int left,top,right,bottom;
+ _border->GetInset(left,top,right,bottom);
+
+ wide -= (left+right);
+ tall -= (top+bottom);
+ }
+}
+
+int Panel::GetWide()
+{
+ int wide, tall;
+ ipanel()->GetSize(GetVPanel(), wide, tall);
+ return wide;
+}
+
+void Panel::SetWide(int wide)
+{
+ ipanel()->SetSize(GetVPanel(), wide, GetTall());
+}
+
+int Panel::GetTall()
+{
+ int wide, tall;
+ ipanel()->GetSize(GetVPanel(), wide, tall);
+ return tall;
+}
+
+void Panel::SetTall(int tall)
+{
+ ipanel()->SetSize(GetVPanel(), GetWide(), tall);
+}
+
+void Panel::SetBuildGroup(BuildGroup* buildGroup)
+{
+ //TODO: remove from old group
+
+ Assert(buildGroup != NULL);
+
+ _buildGroup = buildGroup;
+
+ _buildGroup->PanelAdded(this);
+}
+
+bool Panel::IsBuildGroupEnabled()
+{
+ if ( !_buildGroup.IsValid() )
+ return false;
+
+ bool enabled = _buildGroup->IsEnabled();
+ if ( enabled )
+ return enabled;
+
+ if ( GetParent() && GetParent()->IsBuildGroupEnabled() )
+ return true;
+
+ return false;
+}
+
+void Panel::SetBgColor(Color color)
+{
+ _bgColor = color;
+}
+
+void Panel::SetFgColor(Color color)
+{
+ _fgColor = color;
+}
+
+Color Panel::GetBgColor()
+{
+ return _bgColor;
+}
+
+Color Panel::GetFgColor()
+{
+ return _fgColor;
+}
+
+void Panel::InternalPerformLayout()
+{
+ // Don't layout if we're still waiting for our scheme to be applied.
+ // At worst, it leads to crashes, at best it does work that we'll redo as soon as the scheme has been applied.
+ if ( _flags.IsFlagSet( NEEDS_SCHEME_UPDATE ) )
+ return;
+
+ _flags.SetFlag( IN_PERFORM_LAYOUT );
+ // make sure the scheme has been applied
+ _flags.ClearFlag( NEEDS_LAYOUT );
+ PerformLayout();
+ _flags.ClearFlag( IN_PERFORM_LAYOUT );
+}
+
+void Panel::PerformLayout()
+{
+ // this should be overridden to relayout controls
+}
+
+void Panel::InvalidateLayout( bool layoutNow, bool reloadScheme )
+{
+ _flags.SetFlag( NEEDS_LAYOUT );
+
+ if (reloadScheme)
+ {
+ // make all our children reload the scheme
+ _flags.SetFlag( NEEDS_SCHEME_UPDATE );
+
+ for (int i = 0; i < GetChildCount(); i++)
+ {
+ vgui::Panel* panel = GetChild(i);
+ if( panel )
+ {
+ panel->InvalidateLayout(layoutNow, true);
+ }
+ }
+
+ PerformApplySchemeSettings();
+ }
+
+ if (layoutNow)
+ {
+ InternalPerformLayout();
+ Repaint();
+ }
+}
+
+bool Panel::IsCursorNone()
+{
+ HCursor cursor = GetCursor();
+
+ if (!cursor)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: returns true if the cursor is currently over the panel
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool Panel::IsCursorOver(void)
+{
+ int x, y;
+ input()->GetCursorPos(x, y);
+ return IsWithin(x, y);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Called when a panel receives a command message from another panel
+//-----------------------------------------------------------------------------
+void Panel::OnCommand(const char *command)
+{
+ if ( !Q_stricmp( "performlayout", command ) )
+ {
+ InvalidateLayout();
+ }
+ else if ( !Q_stricmp( "reloadscheme", command ) )
+ {
+ InvalidateLayout( false, true );
+ }
+ else
+ {
+ // if noone else caught this, pass along to the listeners
+ // (this is useful for generic dialogs - otherwise, commands just get ignored)
+ KeyValues *msg = new KeyValues( command );
+ PostActionSignal( msg );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: panel gained focus message
+//-----------------------------------------------------------------------------
+void Panel::OnSetFocus()
+{
+ Repaint();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: panel lost focus message
+//-----------------------------------------------------------------------------
+void Panel::OnKillFocus()
+{
+ Repaint();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Sets the object up to be deleted next frame
+//-----------------------------------------------------------------------------
+void Panel::MarkForDeletion()
+{
+ if ( _flags.IsFlagSet( MARKED_FOR_DELETION ) )
+ return;
+
+ _flags.SetFlag( MARKED_FOR_DELETION );
+ _flags.ClearFlag( AUTODELETE_ENABLED );
+
+ if (ivgui()->IsRunning())
+ {
+ ivgui()->MarkPanelForDeletion(GetVPanel());
+ }
+ // direct delete is never safe because even if ivgui is shutdown we manually do RunFrame()
+ // and we can enter here in a think traverse and then delete from underneath ourselves
+ /*else
+ {
+ delete this;
+ }*/
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: return true if this object require a perform layout
+//-----------------------------------------------------------------------------
+bool Panel::IsLayoutInvalid()
+{
+ return _flags.IsFlagSet( NEEDS_LAYOUT );
+}
+
+
+//-----------------------------------------------------------------------------
+// Sets the pin corner + resize mode for resizing panels
+//-----------------------------------------------------------------------------
+void Panel::SetAutoResize( PinCorner_e pinCorner, AutoResize_e resizeDir,
+ int nPinOffsetX, int nPinOffsetY, int nUnpinnedCornerOffsetX, int nUnpinnedCornerOffsetY )
+{
+ _pinCorner = pinCorner;
+ _autoResizeDirection = resizeDir;
+ m_nPinDeltaX = nPinOffsetX;
+ m_nPinDeltaY = nPinOffsetY;
+ m_nResizeDeltaX = nUnpinnedCornerOffsetX;
+ m_nResizeDeltaY = nUnpinnedCornerOffsetY;
+}
+
+
+//-----------------------------------------------------------------------------
+// Sets the pin corner for non-resizing panels
+//-----------------------------------------------------------------------------
+void Panel::SetPinCorner( PinCorner_e pinCorner, int nOffsetX, int nOffsetY )
+{
+ _pinCorner = pinCorner;
+ _autoResizeDirection = AUTORESIZE_NO;
+ m_nPinDeltaX = nOffsetX;
+ m_nPinDeltaY = nOffsetY;
+ m_nResizeDeltaX = 0;
+ m_nResizeDeltaY = 0;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: data accessor
+//-----------------------------------------------------------------------------
+Panel::PinCorner_e Panel::GetPinCorner()
+{
+ return (PinCorner_e)_pinCorner;
+}
+
+
+//-----------------------------------------------------------------------------
+// Gets the relative offset of the control from the pin corner
+//-----------------------------------------------------------------------------
+void Panel::GetPinOffset( int &dx, int &dy )
+{
+ dx = m_nPinDeltaX;
+ dy = m_nPinDeltaY;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: data accessor
+//-----------------------------------------------------------------------------
+Panel::AutoResize_e Panel::GetAutoResize()
+{
+ return (AutoResize_e)_autoResizeDirection;
+}
+
+
+//-----------------------------------------------------------------------------
+// Gets the relative offset of the control from the pin corner
+//-----------------------------------------------------------------------------
+void Panel::GetResizeOffset( int &dx, int &dy )
+{
+ dx = m_nResizeDeltaX;
+ dy = m_nResizeDeltaY;
+}
+
+//-----------------------------------------------------------------------------
+// Tells this panel that it should pin itself to the corner of a specified sibling panel
+//-----------------------------------------------------------------------------
+void Panel::PinToSibling( const char *pszSibling, PinCorner_e pinOurCorner, PinCorner_e pinSibling )
+{
+ _pinCornerToSibling = pinOurCorner;
+ _pinToSiblingCorner = pinSibling;
+
+ if ( _pinToSibling && pszSibling && !Q_strcmp( _pinToSibling, pszSibling ) )
+ return;
+
+ if (_pinToSibling)
+ {
+ delete [] _pinToSibling;
+ _pinToSibling = NULL;
+ }
+
+ if (pszSibling)
+ {
+ int len = Q_strlen(pszSibling) + 1;
+ _pinToSibling = new char[ len ];
+ Q_strncpy( _pinToSibling, pszSibling, len );
+ }
+ m_pinSibling = NULL;
+
+ UpdateSiblingPin();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::UpdateSiblingPin( void )
+{
+ if ( !_pinToSibling )
+ {
+ ipanel()->SetSiblingPin(GetVPanel(), NULL);
+ return;
+ }
+
+ if ( !m_pinSibling.Get() )
+ {
+ // Resolve our sibling now
+ m_pinSibling = FindSiblingByName( _pinToSibling );
+ }
+
+ if ( m_pinSibling.Get() )
+ {
+ ipanel()->SetSiblingPin( GetVPanel(), m_pinSibling->GetVPanel(), _pinCornerToSibling, _pinToSiblingCorner );
+ }
+ else
+ {
+ ipanel()->SetSiblingPin(GetVPanel(), NULL);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::ApplySchemeSettings(IScheme *pScheme)
+{
+ // get colors
+ SetFgColor(GetSchemeColor("Panel.FgColor", pScheme));
+ SetBgColor(GetSchemeColor("Panel.BgColor", pScheme));
+
+#if defined( VGUI_USEDRAGDROP )
+ m_clrDragFrame = pScheme->GetColor("DragDrop.DragFrame", Color(255, 255, 255, 192));
+ m_clrDropFrame = pScheme->GetColor("DragDrop.DropFrame", Color(150, 255, 150, 255));
+
+ m_infoFont = pScheme->GetFont( "DefaultVerySmall" );
+#endif
+ // mark us as no longer needing scheme settings applied
+ _flags.ClearFlag( NEEDS_SCHEME_UPDATE );
+
+ if ( IsBuildGroupEnabled() )
+ {
+ _buildGroup->ApplySchemeSettings(pScheme);
+ return;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Checks to see if the panel needs it's scheme info setup
+//-----------------------------------------------------------------------------
+void Panel::PerformApplySchemeSettings()
+{
+ if ( _flags.IsFlagSet( NEEDS_DEFAULT_SETTINGS_APPLIED ) )
+ {
+ InternalInitDefaultValues( GetAnimMap() );
+ }
+
+ if ( _flags.IsFlagSet( NEEDS_SCHEME_UPDATE ) )
+ {
+ VPROF( "ApplySchemeSettings" );
+ IScheme *pScheme = scheme()->GetIScheme( GetScheme() );
+ AssertOnce( pScheme );
+ if ( pScheme ) // this should NEVER be null, but if it is bad things would happen in ApplySchemeSettings...
+ {
+ ApplySchemeSettings( pScheme );
+ //_needsSchemeUpdate = false;
+
+ ApplyOverridableColors();
+
+ UpdateSiblingPin();
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Loads panel details related to autoresize from the resource info
+//-----------------------------------------------------------------------------
+#if defined( _DEBUG )
+static Panel *lastWarningParent = 0;
+#endif
+
+void Panel::ApplyAutoResizeSettings(KeyValues *inResourceData)
+{
+ int x, y;
+ GetPos(x, y);
+
+ int wide, tall;
+ GetSize( wide, tall );
+
+ AutoResize_e autoResize = (AutoResize_e)inResourceData->GetInt( "AutoResize", AUTORESIZE_NO );
+ PinCorner_e pinCorner = (PinCorner_e)inResourceData->GetInt( "PinCorner", PIN_TOPLEFT );
+
+ // By default, measure unpinned corner for the offset
+ int pw = wide, pt = tall;
+ if ( GetParent() )
+ {
+ GetParent()->GetSize( pw, pt );
+#if defined( _DEBUG )
+ if ( pw == 64 && pt == 24 )
+ {
+ if ( GetParent() != lastWarningParent )
+ {
+ lastWarningParent = GetParent();
+ Warning( "Resize parent (panel(%s) -> parent(%s)) not sized yet!!!\n", GetName(), GetParent()->GetName() );
+ }
+ }
+#endif
+ }
+
+ int nPinnedCornerOffsetX = 0, nPinnedCornerOffsetY = 0;
+ int nUnpinnedCornerOffsetX = 0, nUnpinnedCornerOffsetY = 0;
+ switch( pinCorner )
+ {
+ case PIN_TOPLEFT:
+ nPinnedCornerOffsetX = x;
+ nPinnedCornerOffsetY = y;
+ nUnpinnedCornerOffsetX = (x + wide) - pw;
+ nUnpinnedCornerOffsetY = (y + tall) - pt;
+ break;
+
+ case PIN_TOPRIGHT:
+ nPinnedCornerOffsetX = (x + wide) - pw;
+ nPinnedCornerOffsetY = y;
+ nUnpinnedCornerOffsetX = x;
+ nUnpinnedCornerOffsetY = (y + tall) - pt;
+ break;
+
+ case PIN_BOTTOMLEFT:
+ nPinnedCornerOffsetX = x;
+ nPinnedCornerOffsetY = (y + tall) - pt;
+ nUnpinnedCornerOffsetX = (x + wide) - pw;
+ nUnpinnedCornerOffsetY = y;
+ break;
+
+ case PIN_BOTTOMRIGHT:
+ nPinnedCornerOffsetX = (x + wide) - pw;
+ nPinnedCornerOffsetY = (y + tall) - pt;
+ nUnpinnedCornerOffsetX = x;
+ nUnpinnedCornerOffsetY = y;
+ break;
+ }
+
+ // Allow specific overrides in the resource file
+ if ( IsProportional() )
+ {
+ if ( inResourceData->FindKey( "PinnedCornerOffsetX" ) )
+ {
+ nPinnedCornerOffsetX = scheme()->GetProportionalScaledValueEx( GetScheme(), inResourceData->GetInt( "PinnedCornerOffsetX" ) );
+ }
+ if ( inResourceData->FindKey( "PinnedCornerOffsetY" ) )
+ {
+ nPinnedCornerOffsetY = scheme()->GetProportionalScaledValueEx( GetScheme(), inResourceData->GetInt( "PinnedCornerOffsetY" ) );
+ }
+ if ( inResourceData->FindKey( "UnpinnedCornerOffsetX" ) )
+ {
+ nUnpinnedCornerOffsetX = scheme()->GetProportionalScaledValueEx( GetScheme(), inResourceData->GetInt( "UnpinnedCornerOffsetX" ) );
+ }
+ if ( inResourceData->FindKey( "UnpinnedCornerOffsetY" ) )
+ {
+ nUnpinnedCornerOffsetY = scheme()->GetProportionalScaledValueEx( GetScheme(), inResourceData->GetInt( "UnpinnedCornerOffsetY" ) );
+ }
+ }
+ else
+ {
+ nPinnedCornerOffsetX = inResourceData->GetInt( "PinnedCornerOffsetX", nPinnedCornerOffsetX );
+ nPinnedCornerOffsetY = inResourceData->GetInt( "PinnedCornerOffsetY", nPinnedCornerOffsetY );
+ nUnpinnedCornerOffsetX = inResourceData->GetInt( "UnpinnedCornerOffsetX", nUnpinnedCornerOffsetX );
+ nUnpinnedCornerOffsetY = inResourceData->GetInt( "UnpinnedCornerOffsetY", nUnpinnedCornerOffsetY );
+ }
+
+ if ( autoResize == AUTORESIZE_NO )
+ {
+ nUnpinnedCornerOffsetX = nUnpinnedCornerOffsetY = 0;
+ }
+
+ SetAutoResize( pinCorner, autoResize, nPinnedCornerOffsetX, nPinnedCornerOffsetY, nUnpinnedCornerOffsetX, nUnpinnedCornerOffsetY );
+}
+
+ConVar panel_test_title_safe( "panel_test_title_safe", "0", FCVAR_CHEAT, "Test vgui panel positioning with title safe indentation" );
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Loads panel details from the resource info
+//-----------------------------------------------------------------------------
+void Panel::ApplySettings(KeyValues *inResourceData)
+{
+ // First restore to default values
+ if ( _flags.IsFlagSet( NEEDS_DEFAULT_SETTINGS_APPLIED ) )
+ {
+ InternalInitDefaultValues( GetAnimMap() );
+ }
+
+ // Let PanelAnimationVars auto-retrieve settings (we restore defaults above
+ // since a script might be missing certain values)
+ InternalApplySettings( GetAnimMap(), inResourceData );
+
+ // clear any alignment flags
+ _buildModeFlags &= ~(BUILDMODE_SAVE_XPOS_RIGHTALIGNED | BUILDMODE_SAVE_XPOS_CENTERALIGNED | BUILDMODE_SAVE_YPOS_BOTTOMALIGNED | BUILDMODE_SAVE_YPOS_CENTERALIGNED | BUILDMODE_SAVE_WIDE_FULL | BUILDMODE_SAVE_TALL_FULL | BUILDMODE_SAVE_PROPORTIONAL_TO_PARENT);
+
+ // get the position
+ int alignScreenWide, alignScreenTall; // screen dimensions used for pinning in splitscreen
+ surface()->GetScreenSize( alignScreenWide, alignScreenTall );
+
+ int screenWide = alignScreenWide;
+ int screenTall = alignScreenTall;
+
+ // temporarily remove the override to get the fullscreen dimensions
+ if ( surface()->IsScreenSizeOverrideActive() )
+ {
+ surface()->ForceScreenSizeOverride( false, 0, 0 );
+ surface()->GetScreenSize( screenWide, screenTall );
+
+ // restore the override
+ surface()->ForceScreenSizeOverride( true, alignScreenWide, alignScreenTall );
+ }
+
+ int parentX = 0;
+ int parentY = 0;
+
+ // flag to cause windows to get screenWide and screenTall from their parents,
+ // this allows children windows to use fill and right/bottom alignment even
+ // if their parent does not use the full screen.
+ if ( inResourceData->GetInt( "proportionalToParent", 0 ) == 1 )
+ {
+ _buildModeFlags |= BUILDMODE_SAVE_PROPORTIONAL_TO_PARENT;
+ if ( GetParent() != NULL )
+ {
+ GetParent()->GetBounds( parentX, parentY, alignScreenWide, alignScreenTall );
+ }
+ }
+
+ int x, y;
+ GetPos(x, y);
+ const char *xstr = inResourceData->GetString( "xpos", NULL );
+ const char *ystr = inResourceData->GetString( "ypos", NULL );
+
+ if (xstr)
+ {
+ // look for alignment flags
+ if (xstr[0] == 'r' || xstr[0] == 'R')
+ {
+ _buildModeFlags |= BUILDMODE_SAVE_XPOS_RIGHTALIGNED;
+ xstr++;
+ }
+ else if (xstr[0] == 'c' || xstr[0] == 'C')
+ {
+ _buildModeFlags |= BUILDMODE_SAVE_XPOS_CENTERALIGNED;
+ xstr++;
+ }
+
+ // get the value
+ x = atoi(xstr);
+ // scale the x up to our screen co-ords
+ if ( IsProportional() )
+ {
+ x = scheme()->GetProportionalScaledValueEx(GetScheme(), x);
+ }
+ // now correct the alignment
+ if (_buildModeFlags & BUILDMODE_SAVE_XPOS_RIGHTALIGNED)
+ {
+ x = alignScreenWide - x;
+ }
+ else if (_buildModeFlags & BUILDMODE_SAVE_XPOS_CENTERALIGNED)
+ {
+ x = (alignScreenWide / 2) + x;
+ }
+ }
+
+ if (ystr)
+ {
+ // look for alignment flags
+ if (ystr[0] == 'r' || ystr[0] == 'R')
+ {
+ _buildModeFlags |= BUILDMODE_SAVE_YPOS_BOTTOMALIGNED;
+ ystr++;
+ }
+ else if (ystr[0] == 'c' || ystr[0] == 'C')
+ {
+ _buildModeFlags |= BUILDMODE_SAVE_YPOS_CENTERALIGNED;
+ ystr++;
+ }
+ y = atoi(ystr);
+ if (IsProportional())
+ {
+ // scale the y up to our screen co-ords
+ y = scheme()->GetProportionalScaledValueEx(GetScheme(), y);
+ }
+ // now correct the alignment
+ if (_buildModeFlags & BUILDMODE_SAVE_YPOS_BOTTOMALIGNED)
+ {
+ y = alignScreenTall - y;
+ }
+ else if (_buildModeFlags & BUILDMODE_SAVE_YPOS_CENTERALIGNED)
+ {
+ y = (alignScreenTall / 2) + y;
+ }
+ }
+
+ bool bUsesTitleSafeArea = false;
+ int titleSafeWide = 0;
+ int titleSafeTall = 0;
+
+ Rect_t excludeEdgeFromTitleSafe; // if a side is set to != 0, don't title safe relative to that edge
+ excludeEdgeFromTitleSafe.x = 0;
+ excludeEdgeFromTitleSafe.y = 0;
+ excludeEdgeFromTitleSafe.width = 0;
+ excludeEdgeFromTitleSafe.height = 0;
+
+ if ( IsX360() || panel_test_title_safe.GetBool() )
+ {
+ // "usetitlesafe" "1" - required inner 90%
+ // "usetitlesafe" "2" - suggested inner 85%
+
+ int iUseTitleSafeValue = 0;
+ if ( inResourceData->FindKey( "usetitlesafe" ) )
+ {
+ iUseTitleSafeValue = inResourceData->GetInt( "usetitlesafe" );
+ bUsesTitleSafeArea = ( iUseTitleSafeValue > 0 );
+ }
+
+ if( bUsesTitleSafeArea )
+ {
+ titleSafeWide = screenWide * ( iUseTitleSafeValue == 1 ? 0.05f : 0.075f );
+ titleSafeTall = screenTall * ( iUseTitleSafeValue == 1 ? 0.05f : 0.075f );
+
+ // Don't title safe internal boundaries for split screen viewports
+ int splitX = 0;
+ int splitY = 0;
+ vgui::surface()->OffsetAbsPos( splitX, splitY );
+
+ bool bHorizontalSplit = ( alignScreenTall != screenTall );
+ bool bVerticalSplit = ( alignScreenWide != screenWide );
+
+ if ( bHorizontalSplit )
+ {
+ // top or bottom?
+ if ( splitY != parentY )
+ {
+ excludeEdgeFromTitleSafe.y = 1;
+ }
+ else
+ {
+ excludeEdgeFromTitleSafe.height = 1;
+ }
+ }
+
+ if ( bVerticalSplit )
+ {
+ // left or right
+ if ( splitX != parentX )
+ {
+ excludeEdgeFromTitleSafe.x = 1;
+ }
+ else
+ {
+ excludeEdgeFromTitleSafe.width = 1;
+ }
+ }
+
+ if ( _buildModeFlags & BUILDMODE_SAVE_XPOS_RIGHTALIGNED )
+ {
+ if ( !excludeEdgeFromTitleSafe.width )
+ {
+ x -= titleSafeWide; // right edge
+ }
+ }
+ else if (_buildModeFlags & BUILDMODE_SAVE_XPOS_CENTERALIGNED)
+ {
+ }
+ else if ( !excludeEdgeFromTitleSafe.x )
+ {
+ x += titleSafeWide; // left edge
+ }
+
+ if ( _buildModeFlags & BUILDMODE_SAVE_YPOS_BOTTOMALIGNED )
+ {
+ if ( !excludeEdgeFromTitleSafe.height )
+ {
+ y -= titleSafeTall; // bottom edge
+ }
+ }
+ else if (_buildModeFlags & BUILDMODE_SAVE_YPOS_CENTERALIGNED)
+ {
+ }
+ else if ( !excludeEdgeFromTitleSafe.y )
+ {
+ y += titleSafeTall; // top edge
+ }
+ }
+ }
+ SetNavUp( inResourceData->GetString("navUp") );
+ SetNavDown( inResourceData->GetString("navDown") );
+ SetNavLeft( inResourceData->GetString("navLeft") );
+ SetNavRight( inResourceData->GetString("navRight") );
+ SetNavToRelay( inResourceData->GetString("navToRelay") );
+ SetNavActivate( inResourceData->GetString("navActivate") );
+ SetNavBack( inResourceData->GetString("navBack") );
+
+ SetPos(x, y);
+
+ if (inResourceData->FindKey( "zpos" ))
+ {
+ SetZPos( inResourceData->GetInt( "zpos" ) );
+ }
+
+ // size
+ int wide, tall;
+ GetSize( wide, tall );
+
+ const char *wstr = inResourceData->GetString( "wide", NULL );
+ if ( wstr )
+ {
+ if (wstr[0] == 'f' || wstr[0] == 'F')
+ {
+ _buildModeFlags |= BUILDMODE_SAVE_WIDE_FULL;
+ wstr++;
+ }
+ wide = atoi(wstr);
+ if ( IsProportional() )
+ {
+ // scale the width up to our screen co-ords
+ wide = scheme()->GetProportionalScaledValueEx(GetScheme(), wide);
+ }
+ // now correct the alignment
+ if (_buildModeFlags & BUILDMODE_SAVE_WIDE_FULL)
+ {
+ wide = alignScreenWide - wide;
+ }
+ }
+
+ // allow tall to be use the "fill" option, set to the height of the parent/screen
+ wstr = inResourceData->GetString( "tall", NULL );
+ if ( wstr )
+ {
+ if (wstr[0] == 'f' || wstr[0] == 'F')
+ {
+ _buildModeFlags |= BUILDMODE_SAVE_TALL_FULL;
+ wstr++;
+ }
+ tall = atoi(wstr);
+ if ( IsProportional() )
+ {
+ // scale the height up to our screen co-ords
+ tall = scheme()->GetProportionalScaledValueEx(GetScheme(), tall);
+ }
+ // now correct the alignment
+ if (_buildModeFlags & BUILDMODE_SAVE_TALL_FULL)
+ {
+ tall = alignScreenTall - tall;
+ }
+ }
+
+ if( bUsesTitleSafeArea )
+ {
+ if ( _buildModeFlags & BUILDMODE_SAVE_WIDE_FULL )
+ {
+ if ( !excludeEdgeFromTitleSafe.x )
+ wide -= titleSafeWide;
+
+ if ( !excludeEdgeFromTitleSafe.width )
+ wide -= titleSafeWide;
+ }
+
+ if ( _buildModeFlags & BUILDMODE_SAVE_TALL_FULL )
+ {
+ if ( !excludeEdgeFromTitleSafe.y )
+ tall -= titleSafeTall;
+
+ if ( !excludeEdgeFromTitleSafe.height )
+ tall -= titleSafeTall;
+ }
+ }
+
+ SetSize( wide, tall );
+
+ // NOTE: This has to happen after pos + size is set
+ ApplyAutoResizeSettings( inResourceData );
+
+ // only get colors if we're ignoring the scheme
+ if (inResourceData->GetInt("IgnoreScheme", 0))
+ {
+ PerformApplySchemeSettings();
+ }
+
+ // state
+ int state = inResourceData->GetInt("visible", 1);
+ if (state == 0)
+ {
+ SetVisible(false);
+ }
+ else if (state == 1)
+ {
+ SetVisible(true);
+ }
+
+ SetEnabled( inResourceData->GetInt("enabled", true) );
+
+ bool bMouseEnabled = inResourceData->GetInt( "mouseinputenabled", true );
+ if ( !bMouseEnabled )
+ {
+ SetMouseInputEnabled( false );
+ }
+
+ // tab order
+ SetTabPosition(inResourceData->GetInt("tabPosition", 0));
+
+ const char *tooltip = inResourceData->GetString("tooltiptext", NULL);
+ if (tooltip && *tooltip)
+ {
+ GetTooltip()->SetText(tooltip);
+ }
+
+ // paint background?
+ int nPaintBackground = inResourceData->GetInt("paintbackground", -1);
+ if (nPaintBackground >= 0)
+ {
+ SetPaintBackgroundEnabled( nPaintBackground != 0 );
+ }
+
+ // paint border?
+ int nPaintBorder = inResourceData->GetInt("paintborder", -1);
+ if (nPaintBorder >= 0)
+ {
+ SetPaintBorderEnabled( nPaintBorder != 0 );
+ }
+
+ // border?
+ const char *pBorder = inResourceData->GetString( "border", "" );
+ if ( *pBorder )
+ {
+ IScheme *pScheme = scheme()->GetIScheme( GetScheme() );
+ SetBorder( pScheme->GetBorder( pBorder ) );
+ }
+
+ // check to see if we have a new name assigned
+ const char *newName = inResourceData->GetString("fieldName", NULL);
+ if ( newName )
+ {
+ // Only slam the name if the new one differs...
+ SetName(newName);
+ }
+
+ // check to see if we need to render to the frame buffer even if
+ // stereo mode is trying to render all of the ui to a render target
+ m_bForceStereoRenderToFrameBuffer = inResourceData->GetBool( "ForceStereoRenderToFrameBuffer", false );
+
+ //=============================================================================
+ // HPE_BEGIN:
+ // [pfreese] Support for reading rounded corner flags
+ //=============================================================================
+ int roundedCorners = inResourceData->GetInt( "RoundedCorners", -1 );
+ if ( roundedCorners >= 0 )
+ {
+ m_roundedCorners = roundedCorners;
+ }
+ //=============================================================================
+ // HPE_END
+ //=============================================================================
+
+ const char *pszSiblingName = inResourceData->GetString("pin_to_sibling", NULL);
+ PinCorner_e pinOurCornerToSibling = (PinCorner_e)inResourceData->GetInt( "pin_corner_to_sibling", PIN_TOPLEFT );
+ PinCorner_e pinSiblingCorner = (PinCorner_e)inResourceData->GetInt( "pin_to_sibling_corner", PIN_TOPLEFT );
+ PinToSibling( pszSiblingName, pinOurCornerToSibling, pinSiblingCorner );
+
+
+ // Allow overriding of colors. Used mostly by HUD elements, where scheme color usage is often undesired.
+ IScheme *pScheme = vgui::scheme()->GetIScheme( GetScheme() );
+ for ( int i = 0; i < m_OverridableColorEntries.Count(); i++ )
+ {
+ // Need to ensure the key exists, so we don't overwrite existing colors when it's not set.
+ if ( inResourceData->FindKey( m_OverridableColorEntries[i].m_pszScriptName, false ) )
+ {
+ // Get the color as a string - test whether it is an actual color or a reference to a scheme color
+ const char *pColorStr = inResourceData->GetString( m_OverridableColorEntries[i].m_pszScriptName );
+ Color &clrDest = m_OverridableColorEntries[i].m_colFromScript;
+ if ( pColorStr[0] == '.' || isdigit( pColorStr[0] ) )
+ {
+ float r = 0.0f, g = 0.0f, b = 0.0f, a = 0.0f;
+ sscanf( pColorStr, "%f %f %f %f", &r, &g, &b, &a );
+ clrDest[0] = (unsigned char)r;
+ clrDest[1] = (unsigned char)g;
+ clrDest[2] = (unsigned char)b;
+ clrDest[3] = (unsigned char)a;
+ }
+ else
+ {
+ // First character wasn't a digit or a decimal - do a scheme color lookup
+ clrDest = pScheme->GetColor( pColorStr, Color( 255, 255, 255, 255 ) );
+ }
+
+ (*m_OverridableColorEntries[i].m_pColor) = m_OverridableColorEntries[i].m_colFromScript;
+ m_OverridableColorEntries[i].m_bOverridden = true;
+ }
+ }
+
+ const char *pKeyboardInputEnabled = inResourceData->GetString( "keyboardinputenabled", NULL );
+ if ( pKeyboardInputEnabled && pKeyboardInputEnabled[0] )
+ {
+ SetKeyBoardInputEnabled( atoi( pKeyboardInputEnabled ) );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Saves out a resource description of this panel
+//-----------------------------------------------------------------------------
+void Panel::GetSettings( KeyValues *outResourceData )
+{
+ // control class name (so it can be recreated later if needed)
+ outResourceData->SetString( "ControlName", GetClassName() );
+
+ // name
+ outResourceData->SetString( "fieldName", _panelName );
+
+ // positioning
+ int screenWide, screenTall;
+ surface()->GetScreenSize(screenWide, screenTall);
+ int x, y;
+ GetPos( x, y );
+ if ( IsProportional() )
+ {
+ x = scheme()->GetProportionalNormalizedValueEx( GetScheme(), x );
+ y = scheme()->GetProportionalNormalizedValueEx( GetScheme(), y );
+ }
+ // correct for alignment
+ if (_buildModeFlags & BUILDMODE_SAVE_XPOS_RIGHTALIGNED)
+ {
+ x = screenWide - x;
+ char xstr[32];
+ Q_snprintf(xstr, sizeof( xstr ), "r%d", x);
+ outResourceData->SetString( "xpos", xstr );
+ }
+ else if (_buildModeFlags & BUILDMODE_SAVE_XPOS_CENTERALIGNED)
+ {
+ x = (screenWide / 2) + x;
+ char xstr[32];
+ Q_snprintf(xstr, sizeof( xstr ), "c%d", x);
+ outResourceData->SetString( "xpos", xstr );
+ }
+ else
+ {
+ outResourceData->SetInt( "xpos", x );
+ }
+ if (_buildModeFlags & BUILDMODE_SAVE_YPOS_BOTTOMALIGNED)
+ {
+ y = screenTall - y;
+ char ystr[32];
+ Q_snprintf(ystr, sizeof( ystr ), "r%d", y);
+ outResourceData->SetString( "ypos", ystr );
+ }
+ else if (_buildModeFlags & BUILDMODE_SAVE_YPOS_CENTERALIGNED)
+ {
+ y = (screenTall / 2) + y;
+ char ystr[32];
+ Q_snprintf(ystr, sizeof( ystr ), "c%d", y);
+ outResourceData->SetString( "ypos", ystr );
+ }
+ else
+ {
+ outResourceData->SetInt( "ypos", y );
+ }
+ if (m_pTooltips)
+ {
+ if (strlen(m_pTooltips->GetText()) > 0)
+ {
+ outResourceData->SetString("tooltiptext", m_pTooltips->GetText());
+ }
+ }
+ int wide, tall;
+ GetSize( wide, tall );
+ if ( IsProportional() )
+ {
+ wide = scheme()->GetProportionalNormalizedValueEx( GetScheme(), wide );
+ tall = scheme()->GetProportionalNormalizedValueEx( GetScheme(), tall );
+ }
+
+ int z = ipanel()->GetZPos(GetVPanel());
+ if (z)
+ {
+ outResourceData->SetInt("zpos", z);
+ }
+
+ // Correct for alignment
+ if (_buildModeFlags & BUILDMODE_SAVE_WIDE_FULL )
+ {
+ wide = screenWide - wide;
+ char wstr[32];
+ Q_snprintf(wstr, sizeof( wstr ), "f%d", wide);
+ outResourceData->SetString( "wide", wstr );
+ }
+ else
+ {
+ outResourceData->SetInt( "wide", wide );
+ }
+ outResourceData->SetInt( "tall", tall );
+
+ outResourceData->SetInt("AutoResize", GetAutoResize());
+ outResourceData->SetInt("PinCorner", GetPinCorner());
+
+ //=============================================================================
+ // HPE_BEGIN:
+ // [pfreese] Support for writing out rounded corner flags
+ //=============================================================================
+ outResourceData->SetInt("RoundedCorners", m_roundedCorners);
+ //=============================================================================
+ // HPE_END
+ //=============================================================================
+
+ outResourceData->SetString( "pin_to_sibling", _pinToSibling );
+ outResourceData->SetInt("pin_corner_to_sibling", _pinCornerToSibling );
+ outResourceData->SetInt("pin_to_sibling_corner", _pinToSiblingCorner );
+
+
+ // state
+ outResourceData->SetInt( "visible", IsVisible() );
+ outResourceData->SetInt( "enabled", IsEnabled() );
+
+ outResourceData->SetInt( "tabPosition", GetTabPosition() );
+
+ for ( int i = 0; i < m_OverridableColorEntries.Count(); i++ )
+ {
+ if ( m_OverridableColorEntries[i].m_bOverridden )
+ {
+ outResourceData->SetColor( m_OverridableColorEntries[i].m_pszScriptName, m_OverridableColorEntries[i].m_colFromScript );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: After applying settings, apply overridable colors.
+// Done post apply settings, so that baseclass settings don't stomp
+// the script specified override colors.
+//-----------------------------------------------------------------------------
+void Panel::ApplyOverridableColors( void )
+{
+ for ( int i = 0; i < m_OverridableColorEntries.Count(); i++ )
+ {
+ if ( m_OverridableColorEntries[i].m_bOverridden )
+ {
+ (*m_OverridableColorEntries[i].m_pColor) = m_OverridableColorEntries[i].m_colFromScript;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::SetOverridableColor( Color *pColor, const Color &newColor )
+{
+ for ( int i = 0; i < m_OverridableColorEntries.Count(); i++ )
+ {
+ if ( m_OverridableColorEntries[i].m_bOverridden )
+ {
+ if ( m_OverridableColorEntries[i].m_pColor == pColor )
+ return;
+ }
+ }
+
+ // Didn't find it, or it's not been overridden.
+ *pColor = newColor;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+Color Panel::GetSchemeColor(const char *keyName, IScheme *pScheme)
+{
+ return pScheme->GetColor(keyName, Color(255, 255, 255, 255));
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+Color Panel::GetSchemeColor(const char *keyName, Color defaultColor, IScheme *pScheme)
+{
+ return pScheme->GetColor(keyName, defaultColor);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns a string description of the panel fields for use in the UI
+//-----------------------------------------------------------------------------
+const char *Panel::GetDescription( void )
+{
+ static const char *panelDescription = "string fieldName, int xpos, int ypos, int wide, int tall, bool visible, bool enabled, int tabPosition, corner pinCorner, autoresize autoResize, string tooltiptext";
+ return panelDescription;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: user configuration settings
+// this is used for any control details the user wants saved between sessions
+// eg. dialog positions, last directory opened, list column width
+//-----------------------------------------------------------------------------
+void Panel::ApplyUserConfigSettings(KeyValues *userConfig)
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: returns user config settings for this control
+//-----------------------------------------------------------------------------
+void Panel::GetUserConfigSettings(KeyValues *userConfig)
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: optimization, return true if this control has any user config settings
+//-----------------------------------------------------------------------------
+bool Panel::HasUserConfigSettings()
+{
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::InternalInvalidateLayout()
+{
+ InvalidateLayout(false, false);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: called whenever the panel moves
+//-----------------------------------------------------------------------------
+void Panel::OnMove()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::InternalMove()
+{
+ OnMove();
+ for(int i=0;i<GetChildCount();i++)
+ {
+ // recursively apply to all children
+ GetChild(i)->OnMove();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: empty function
+//-----------------------------------------------------------------------------
+void Panel::OnTick()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: versioning
+//-----------------------------------------------------------------------------
+void *Panel::QueryInterface(EInterfaceID id)
+{
+ if (id == ICLIENTPANEL_STANDARD_INTERFACE)
+ {
+ return this;
+ }
+
+ return NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Map all the base messages to functions
+// ordering from most -> least used improves speed
+//-----------------------------------------------------------------------------
+MessageMapItem_t Panel::m_MessageMap[] =
+{
+ MAP_MESSAGE_INT( Panel, "RequestFocus", RequestFocus, "direction" )
+};
+
+// IMPLEMENT_PANELMAP( Panel, NULL )
+PanelMap_t Panel::m_PanelMap = { Panel::m_MessageMap, ARRAYSIZE(Panel::m_MessageMap), "Panel", NULL };
+PanelMap_t *Panel::GetPanelMap( void ) { return &m_PanelMap; }
+
+//-----------------------------------------------------------------------------
+// Purpose: !! Soon to replace existing prepare panel map
+//-----------------------------------------------------------------------------
+void PreparePanelMessageMap(PanelMessageMap *panelMap)
+{
+ // iterate through the class hierarchy message maps
+ while ( panelMap != NULL && !panelMap->processed )
+ {
+ // hash message map strings into symbols
+ for (int i = 0; i < panelMap->entries.Count(); i++)
+ {
+ MessageMapItem_t *item = &panelMap->entries[i];
+
+ if (item->name)
+ {
+ item->nameSymbol = KeyValuesSystem()->GetSymbolForString(item->name);
+ }
+ else
+ {
+ item->nameSymbol = INVALID_KEY_SYMBOL;
+ }
+ if (item->firstParamName)
+ {
+ item->firstParamSymbol = KeyValuesSystem()->GetSymbolForString(item->firstParamName);
+ }
+ else
+ {
+ item->firstParamSymbol = INVALID_KEY_SYMBOL;
+ }
+ if (item->secondParamName)
+ {
+ item->secondParamSymbol = KeyValuesSystem()->GetSymbolForString(item->secondParamName);
+ }
+ else
+ {
+ item->secondParamSymbol = INVALID_KEY_SYMBOL;
+ }
+ }
+
+ panelMap->processed = true;
+ panelMap = panelMap->baseMap;
+ }
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles a message
+// Dispatches the message to a set of message maps
+//-----------------------------------------------------------------------------
+void Panel::OnMessage(const KeyValues *params, VPANEL ifromPanel)
+{
+ PanelMessageMap *panelMap = GetMessageMap();
+ bool bFound = false;
+ int iMessageName = params->GetNameSymbol();
+
+ if ( !panelMap->processed )
+ {
+ PreparePanelMessageMap( panelMap );
+ }
+
+ // iterate through the class hierarchy message maps
+ for ( ; panelMap != NULL && !bFound; panelMap = panelMap->baseMap )
+ {
+#if defined( _DEBUG )
+// char const *className = panelMap->pfnClassName();
+// NOTE_UNUSED( className );
+#endif
+
+ // iterate all the entries in the panel map
+ for ( int i = 0; i < panelMap->entries.Count(); i++ )
+ {
+ MessageMapItem_t *pMap = &panelMap->entries[i];
+
+ if (iMessageName == pMap->nameSymbol)
+ {
+ bFound = true;
+
+ switch (pMap->numParams)
+ {
+ case 0:
+ {
+ (this->*(pMap->func))();
+ break;
+ }
+
+ case 1:
+ {
+ KeyValues *param1 = params->FindKey(pMap->firstParamSymbol);
+ if (!param1)
+ {
+ param1 = const_cast<KeyValues *>(params);
+ }
+
+ switch ( pMap->firstParamType )
+ {
+ case DATATYPE_INT:
+ typedef void (Panel::*MessageFunc_Int_t)(int);
+ (this->*((MessageFunc_Int_t)pMap->func))( param1->GetInt() );
+ break;
+
+ case DATATYPE_UINT64:
+ typedef void (Panel::*MessageFunc_Uin64_t)(uint64);
+ (this->*((MessageFunc_Uin64_t)pMap->func))( param1->GetUint64() );
+ break;
+
+ case DATATYPE_PTR:
+ typedef void (Panel::*MessageFunc_Ptr_t)( void * );
+ (this->*((MessageFunc_Ptr_t)pMap->func))( param1->GetPtr() );
+ break;
+
+ case DATATYPE_HANDLE:
+ {
+ typedef void (Panel::*MessageFunc_VPANEL_t)( VPANEL );
+ VPANEL vpanel = ivgui()->HandleToPanel( param1->GetInt() );
+ (this->*((MessageFunc_VPANEL_t)pMap->func))( vpanel );
+ }
+ break;
+
+ case DATATYPE_FLOAT:
+ typedef void (Panel::*MessageFunc_Float_t)( float );
+ (this->*((MessageFunc_Float_t)pMap->func))( param1->GetFloat() );
+ break;
+
+ case DATATYPE_CONSTCHARPTR:
+ typedef void (Panel::*MessageFunc_CharPtr_t)( const char * );
+ (this->*((MessageFunc_CharPtr_t)pMap->func))( param1->GetString() );
+ break;
+
+ case DATATYPE_CONSTWCHARPTR:
+ typedef void (Panel::*MessageFunc_WCharPtr_t)( const wchar_t * );
+ (this->*((MessageFunc_WCharPtr_t)pMap->func))( param1->GetWString() );
+ break;
+
+ case DATATYPE_KEYVALUES:
+ typedef void (Panel::*MessageFunc_KeyValues_t)(KeyValues *);
+ if ( pMap->firstParamName )
+ {
+ (this->*((MessageFunc_KeyValues_t)pMap->func))( (KeyValues *)param1->GetPtr() );
+ }
+ else
+ {
+ // no param set, so pass in the whole thing
+ (this->*((MessageFunc_KeyValues_t)pMap->func))( const_cast<KeyValues *>(params) );
+ }
+ break;
+
+ default:
+ Assert(!("No handler for vgui message function"));
+ break;
+ }
+ break;
+ }
+
+ case 2:
+ {
+ KeyValues *param1 = params->FindKey(pMap->firstParamSymbol);
+ if (!param1)
+ {
+ param1 = const_cast<KeyValues *>(params);
+ }
+ KeyValues *param2 = params->FindKey(pMap->secondParamSymbol);
+ if (!param2)
+ {
+ param2 = const_cast<KeyValues *>(params);
+ }
+
+ if ( (DATATYPE_INT == pMap->firstParamType) && (DATATYPE_INT == pMap->secondParamType) )
+ {
+ typedef void (Panel::*MessageFunc_IntInt_t)(int, int);
+ (this->*((MessageFunc_IntInt_t)pMap->func))( param1->GetInt(), param2->GetInt() );
+ }
+ else if ( (DATATYPE_PTR == pMap->firstParamType) && (DATATYPE_INT == pMap->secondParamType) )
+ {
+ typedef void (Panel::*MessageFunc_PtrInt_t)(void *, int);
+ (this->*((MessageFunc_PtrInt_t)pMap->func))( param1->GetPtr(), param2->GetInt() );
+ }
+ else if ( (DATATYPE_CONSTCHARPTR == pMap->firstParamType) && (DATATYPE_INT == pMap->secondParamType) )
+ {
+ typedef void (Panel::*MessageFunc_ConstCharPtrInt_t)(const char *, int);
+ (this->*((MessageFunc_ConstCharPtrInt_t)pMap->func))( param1->GetString(), param2->GetInt() );
+ }
+ else if ( (DATATYPE_CONSTCHARPTR == pMap->firstParamType) && (DATATYPE_CONSTCHARPTR == pMap->secondParamType) )
+ {
+ typedef void (Panel::*MessageFunc_ConstCharPtrConstCharPtr_t)(const char *, const char *);
+ (this->*((MessageFunc_ConstCharPtrConstCharPtr_t)pMap->func))( param1->GetString(), param2->GetString() );
+ }
+ else if ( (DATATYPE_INT == pMap->firstParamType) && (DATATYPE_CONSTCHARPTR == pMap->secondParamType) )
+ {
+ typedef void (Panel::*MessageFunc_IntConstCharPtr_t)(int, const char *);
+ (this->*((MessageFunc_IntConstCharPtr_t)pMap->func))( param1->GetInt(), param2->GetString() );
+ }
+ else if ( (DATATYPE_PTR == pMap->firstParamType) && (DATATYPE_CONSTCHARPTR == pMap->secondParamType) )
+ {
+ typedef void (Panel::*MessageFunc_PtrConstCharPtr_t)(void *, const char *);
+ (this->*((MessageFunc_PtrConstCharPtr_t)pMap->func))( param1->GetPtr(), param2->GetString() );
+ }
+ else if ( (DATATYPE_PTR == pMap->firstParamType) && (DATATYPE_CONSTWCHARPTR == pMap->secondParamType) )
+ {
+ typedef void (Panel::*MessageFunc_PtrConstCharPtr_t)(void *, const wchar_t *);
+ (this->*((MessageFunc_PtrConstCharPtr_t)pMap->func))( param1->GetPtr(), param2->GetWString() );
+ }
+ else if ( (DATATYPE_HANDLE == pMap->firstParamType) && (DATATYPE_CONSTCHARPTR == pMap->secondParamType) )
+ {
+ typedef void (Panel::*MessageFunc_HandleConstCharPtr_t)(VPANEL, const char *);
+ VPANEL vp = ivgui()->HandleToPanel( param1->GetInt() );
+ (this->*((MessageFunc_HandleConstCharPtr_t)pMap->func))( vp, param2->GetString() );
+ }
+ else if ( (DATATYPE_HANDLE == pMap->firstParamType) && (DATATYPE_CONSTWCHARPTR == pMap->secondParamType) )
+ {
+ typedef void (Panel::*MessageFunc_HandleConstCharPtr_t)(VPANEL, const wchar_t *);
+ VPANEL vp = ivgui()->HandleToPanel( param1->GetInt() );
+ (this->*((MessageFunc_HandleConstCharPtr_t)pMap->func))( vp, param2->GetWString() );
+ }
+ else
+ {
+ // the message isn't handled
+ ivgui()->DPrintf( "Message '%s', sent to '%s', has invalid parameter types\n", params->GetName(), GetName() );
+ }
+ break;
+ }
+
+ default:
+ Assert(!("Invalid number of parameters"));
+ break;
+ }
+
+ // break the loop
+ bFound = true;
+ break;
+ }
+ }
+ }
+
+ if (!bFound)
+ {
+ OnOldMessage(const_cast<KeyValues *>(params), ifromPanel);
+ }
+}
+
+void Panel::OnOldMessage(KeyValues *params, VPANEL ifromPanel)
+{
+ bool bFound = false;
+ // message map dispatch
+ int iMessageName = params->GetNameSymbol();
+
+ PanelMap_t *panelMap = GetPanelMap();
+ if ( !panelMap->processed )
+ {
+ PreparePanelMap( panelMap );
+ }
+
+ // iterate through the class hierarchy message maps
+ for ( ; panelMap != NULL && !bFound; panelMap = panelMap->baseMap )
+ {
+ MessageMapItem_t *pMessageMap = panelMap->dataDesc;
+
+ for ( int i = 0; i < panelMap->dataNumFields; i++ )
+ {
+ if (iMessageName == pMessageMap[i].nameSymbol)
+ {
+ // call the mapped function
+ switch ( pMessageMap[i].numParams )
+ {
+ case 2:
+ if ( (DATATYPE_INT == pMessageMap[i].firstParamType) && (DATATYPE_INT == pMessageMap[i].secondParamType) )
+ {
+ typedef void (Panel::*MessageFunc_IntInt_t)(int, int);
+ (this->*((MessageFunc_IntInt_t)pMessageMap[i].func))( params->GetInt(pMessageMap[i].firstParamName), params->GetInt(pMessageMap[i].secondParamName) );
+ }
+ else if ( (DATATYPE_PTR == pMessageMap[i].firstParamType) && (DATATYPE_INT == pMessageMap[i].secondParamType) )
+ {
+ typedef void (Panel::*MessageFunc_PtrInt_t)(void *, int);
+ (this->*((MessageFunc_PtrInt_t)pMessageMap[i].func))( params->GetPtr(pMessageMap[i].firstParamName), params->GetInt(pMessageMap[i].secondParamName) );
+ }
+ else if ( (DATATYPE_CONSTCHARPTR == pMessageMap[i].firstParamType) && (DATATYPE_INT == pMessageMap[i].secondParamType) )
+ {
+ typedef void (Panel::*MessageFunc_ConstCharPtrInt_t)(const char *, int);
+ (this->*((MessageFunc_ConstCharPtrInt_t)pMessageMap[i].func))( params->GetString(pMessageMap[i].firstParamName), params->GetInt(pMessageMap[i].secondParamName) );
+ }
+ else if ( (DATATYPE_CONSTCHARPTR == pMessageMap[i].firstParamType) && (DATATYPE_CONSTCHARPTR == pMessageMap[i].secondParamType) )
+ {
+ typedef void (Panel::*MessageFunc_ConstCharPtrConstCharPtr_t)(const char *, const char *);
+ (this->*((MessageFunc_ConstCharPtrConstCharPtr_t)pMessageMap[i].func))( params->GetString(pMessageMap[i].firstParamName), params->GetString(pMessageMap[i].secondParamName) );
+ }
+ else if ( (DATATYPE_INT == pMessageMap[i].firstParamType) && (DATATYPE_CONSTCHARPTR == pMessageMap[i].secondParamType) )
+ {
+ typedef void (Panel::*MessageFunc_IntConstCharPtr_t)(int, const char *);
+ (this->*((MessageFunc_IntConstCharPtr_t)pMessageMap[i].func))( params->GetInt(pMessageMap[i].firstParamName), params->GetString(pMessageMap[i].secondParamName) );
+ }
+ else if ( (DATATYPE_PTR == pMessageMap[i].firstParamType) && (DATATYPE_CONSTCHARPTR == pMessageMap[i].secondParamType) )
+ {
+ typedef void (Panel::*MessageFunc_PtrConstCharPtr_t)(void *, const char *);
+ (this->*((MessageFunc_PtrConstCharPtr_t)pMessageMap[i].func))( params->GetPtr(pMessageMap[i].firstParamName), params->GetString(pMessageMap[i].secondParamName) );
+ }
+ else if ( (DATATYPE_PTR == pMessageMap[i].firstParamType) && (DATATYPE_CONSTWCHARPTR == pMessageMap[i].secondParamType) )
+ {
+ typedef void (Panel::*MessageFunc_PtrConstCharPtr_t)(void *, const wchar_t *);
+ (this->*((MessageFunc_PtrConstCharPtr_t)pMessageMap[i].func))( params->GetPtr(pMessageMap[i].firstParamName), params->GetWString(pMessageMap[i].secondParamName) );
+ }
+ else if ( (DATATYPE_HANDLE == pMessageMap[i].firstParamType) && (DATATYPE_CONSTCHARPTR ==pMessageMap[i].secondParamType) )
+ {
+ typedef void (Panel::*MessageFunc_HandleConstCharPtr_t)(VPANEL, const char *);
+ VPANEL vp = ivgui()->HandleToPanel( params->GetInt( pMessageMap[i].firstParamName ) );
+ (this->*((MessageFunc_HandleConstCharPtr_t)pMessageMap[i].func))( vp, params->GetString(pMessageMap[i].secondParamName) );
+ }
+ else if ( (DATATYPE_HANDLE == pMessageMap[i].firstParamType) && (DATATYPE_CONSTWCHARPTR == pMessageMap[i].secondParamType) )
+ {
+ typedef void (Panel::*MessageFunc_HandleConstCharPtr_t)(VPANEL, const wchar_t *);
+ VPANEL vp = ivgui()->HandleToPanel( params->GetInt( pMessageMap[i].firstParamName ) );
+ (this->*((MessageFunc_HandleConstCharPtr_t)pMessageMap[i].func))( vp, params->GetWString(pMessageMap[i].secondParamName) );
+ }
+ else
+ {
+ // the message isn't handled
+ ivgui()->DPrintf( "Message '%s', sent to '%s', has invalid parameter types\n", params->GetName(), GetName() );
+ }
+ break;
+
+ case 1:
+ switch ( pMessageMap[i].firstParamType )
+ {
+ case DATATYPE_BOOL:
+ typedef void (Panel::*MessageFunc_Bool_t)(bool);
+ (this->*((MessageFunc_Bool_t)pMessageMap[i].func))( (bool)params->GetInt(pMessageMap[i].firstParamName) );
+ break;
+
+ case DATATYPE_CONSTCHARPTR:
+ typedef void (Panel::*MessageFunc_ConstCharPtr_t)(const char *);
+ (this->*((MessageFunc_ConstCharPtr_t)pMessageMap[i].func))( (const char *)params->GetString(pMessageMap[i].firstParamName) );
+ break;
+
+ case DATATYPE_CONSTWCHARPTR:
+ typedef void (Panel::*MessageFunc_ConstCharPtr_t)(const char *);
+ (this->*((MessageFunc_ConstCharPtr_t)pMessageMap[i].func))( (const char *)params->GetWString(pMessageMap[i].firstParamName) );
+ break;
+
+ case DATATYPE_INT:
+ typedef void (Panel::*MessageFunc_Int_t)(int);
+ (this->*((MessageFunc_Int_t)pMessageMap[i].func))( params->GetInt(pMessageMap[i].firstParamName) );
+ break;
+
+ case DATATYPE_FLOAT:
+ typedef void (Panel::*MessageFunc_Float_t)(float);
+ (this->*((MessageFunc_Float_t)pMessageMap[i].func))( params->GetFloat(pMessageMap[i].firstParamName) );
+ break;
+
+ case DATATYPE_PTR:
+ typedef void (Panel::*MessageFunc_Ptr_t)(void *);
+ (this->*((MessageFunc_Ptr_t)pMessageMap[i].func))( (void *)params->GetPtr(pMessageMap[i].firstParamName) );
+ break;
+
+ case DATATYPE_HANDLE:
+ {
+ typedef void (Panel::*MessageFunc_Ptr_t)(void *);
+ VPANEL vp = ivgui()->HandleToPanel( params->GetInt( pMessageMap[i].firstParamName ) );
+ Panel *panel = ipanel()->GetPanel( vp, GetModuleName() );
+ (this->*((MessageFunc_Ptr_t)pMessageMap[i].func))( (void *)panel );
+ }
+ break;
+
+ case DATATYPE_KEYVALUES:
+ typedef void (Panel::*MessageFunc_KeyValues_t)(KeyValues *);
+ if ( pMessageMap[i].firstParamName )
+ {
+ (this->*((MessageFunc_KeyValues_t)pMessageMap[i].func))( (KeyValues *)params->GetPtr(pMessageMap[i].firstParamName) );
+ }
+ else
+ {
+ (this->*((MessageFunc_KeyValues_t)pMessageMap[i].func))( params );
+ }
+ break;
+
+ default:
+ // the message isn't handled
+ ivgui()->DPrintf( "Message '%s', sent to '%s', has an invalid parameter type\n", params->GetName(), GetName() );
+ break;
+ }
+
+ break;
+
+ default:
+ (this->*(pMessageMap[i].func))();
+ break;
+ };
+
+ // break the loop
+ bFound = true;
+ break;
+ }
+ }
+ }
+
+ // message not handled
+ // debug code
+ if ( !bFound )
+ {
+ static int s_bDebugMessages = -1;
+ if ( s_bDebugMessages == -1 )
+ {
+ s_bDebugMessages = CommandLine()->FindParm( "-vguimessages" ) ? 1 : 0;
+ }
+ if ( s_bDebugMessages == 1 )
+ {
+ ivgui()->DPrintf( "Message '%s' not handled by panel '%s'\n", params->GetName(), GetName() );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Safe call to get info from child panel by name
+//-----------------------------------------------------------------------------
+bool Panel::RequestInfoFromChild(const char *childName, KeyValues *outputData)
+{
+ Panel *panel = FindChildByName(childName);
+ if (panel)
+ {
+ return panel->RequestInfo(outputData);
+ }
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Posts a message
+//-----------------------------------------------------------------------------
+void Panel::PostMessage(Panel *target, KeyValues *message, float delay)
+{
+ ivgui()->PostMessage(target->GetVPanel(), message, GetVPanel(), delay);
+}
+
+void Panel::PostMessage(VPANEL target, KeyValues *message, float delaySeconds)
+{
+ ivgui()->PostMessage(target, message, GetVPanel(), delaySeconds);
+}
+
+void Panel::PostMessageToAllSiblings( KeyValues *msg, float delaySeconds /*= 0.0f*/ )
+{
+ VPANEL parent = GetVParent();
+ if ( parent )
+ {
+ VPANEL vpanel = GetVPanel();
+
+ CUtlVector< VPANEL > &children = ipanel()->GetChildren( parent );
+ int nChildCount = children.Count();
+ for ( int i = 0; i < nChildCount; ++i )
+ {
+ VPANEL sibling = children[ i ];
+ if ( sibling == vpanel )
+ continue;
+
+ if ( sibling )
+ {
+ PostMessage( sibling, msg->MakeCopy(), delaySeconds );
+ }
+ }
+ }
+
+ msg->deleteThis();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Safe call to post a message to a child by name
+//-----------------------------------------------------------------------------
+void Panel::PostMessageToChild(const char *childName, KeyValues *message)
+{
+ Panel *panel = FindChildByName(childName);
+ if (panel)
+ {
+ ivgui()->PostMessage(panel->GetVPanel(), message, GetVPanel());
+ }
+ else
+ {
+ message->deleteThis();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Requests some information from the panel
+// Look through the message map for the handler
+//-----------------------------------------------------------------------------
+bool Panel::RequestInfo( KeyValues *outputData )
+{
+ if ( InternalRequestInfo( GetAnimMap(), outputData ) )
+ {
+ return true;
+ }
+
+ if (GetVParent())
+ {
+ return ipanel()->RequestInfo(GetVParent(), outputData);
+ }
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: sets a specified value in the control - inverse of RequestInfo
+//-----------------------------------------------------------------------------
+bool Panel::SetInfo(KeyValues *inputData)
+{
+ if ( InternalSetInfo( GetAnimMap(), inputData ) )
+ {
+ return true;
+ }
+
+ // doesn't chain to parent
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: change the panel's silent mode; if silent, the panel will not post
+// any action signals
+//-----------------------------------------------------------------------------
+
+void Panel::SetSilentMode( bool bSilent )
+{
+ m_bIsSilent = bSilent;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: mouse events will be send to handler panel instead of this panel
+//-----------------------------------------------------------------------------
+void Panel::InstallMouseHandler( Panel *pHandler )
+{
+ m_hMouseEventHandler = pHandler;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Prepares the hierarchy panel maps for use (with message maps etc)
+//-----------------------------------------------------------------------------
+void Panel::PreparePanelMap( PanelMap_t *panelMap )
+{
+ // iterate through the class hierarchy message maps
+ while ( panelMap != NULL && !panelMap->processed )
+ {
+ // fixup cross-dll boundary panel maps
+ if ( panelMap->baseMap == (PanelMap_t*)0x00000001 )
+ {
+ panelMap->baseMap = &Panel::m_PanelMap;
+ }
+
+ // hash message map strings into symbols
+ for (int i = 0; i < panelMap->dataNumFields; i++)
+ {
+ MessageMapItem_t *item = &panelMap->dataDesc[i];
+
+ if (item->name)
+ {
+ item->nameSymbol = KeyValuesSystem()->GetSymbolForString(item->name);
+ }
+ else
+ {
+ item->nameSymbol = INVALID_KEY_SYMBOL;
+ }
+ if (item->firstParamName)
+ {
+ item->firstParamSymbol = KeyValuesSystem()->GetSymbolForString(item->firstParamName);
+ }
+ else
+ {
+ item->firstParamSymbol = INVALID_KEY_SYMBOL;
+ }
+ if (item->secondParamName)
+ {
+ item->secondParamSymbol = KeyValuesSystem()->GetSymbolForString(item->secondParamName);
+ }
+ else
+ {
+ item->secondParamSymbol = INVALID_KEY_SYMBOL;
+ }
+ }
+
+ panelMap->processed = true;
+ panelMap = panelMap->baseMap;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Called to delete the panel
+//-----------------------------------------------------------------------------
+void Panel::OnDelete()
+{
+#ifdef WIN32
+ Assert( IsX360() || ( IsPC() && _heapchk() == _HEAPOK ) );
+#endif
+ delete this;
+#ifdef WIN32
+ Assert( IsX360() || ( IsPC() && _heapchk() == _HEAPOK ) );
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Panel handle implementation
+// Returns a pointer to a valid panel, NULL if the panel has been deleted
+//-----------------------------------------------------------------------------
+Panel *PHandle::Get()
+{
+ if (m_iPanelID != INVALID_PANEL)
+ {
+ VPANEL panel = ivgui()->HandleToPanel(m_iPanelID);
+ if (panel)
+ {
+ Panel *vguiPanel = ipanel()->GetPanel(panel, GetControlsModuleName());
+ return vguiPanel;
+ }
+ }
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: sets the smart pointer
+//-----------------------------------------------------------------------------
+Panel *PHandle::Set(Panel *pent)
+{
+ if (pent)
+ {
+ m_iPanelID = ivgui()->PanelToHandle(pent->GetVPanel());
+ }
+ else
+ {
+ m_iPanelID = INVALID_PANEL;
+ }
+ return pent;
+}
+
+Panel *PHandle::Set( HPanel hPanel )
+{
+ m_iPanelID = hPanel;
+ return Get();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns a handle to a valid panel, NULL if the panel has been deleted
+//-----------------------------------------------------------------------------
+VPANEL VPanelHandle::Get()
+{
+ if (m_iPanelID != INVALID_PANEL)
+ {
+ if (ivgui())
+ {
+ return ivgui()->HandleToPanel(m_iPanelID);
+ }
+ }
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: sets the smart pointer
+//-----------------------------------------------------------------------------
+VPANEL VPanelHandle::Set(VPANEL pent)
+{
+ if (pent)
+ {
+ m_iPanelID = ivgui()->PanelToHandle(pent);
+ }
+ else
+ {
+ m_iPanelID = INVALID_PANEL;
+ }
+ return pent;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: returns a pointer to the tooltip object associated with the panel
+//-----------------------------------------------------------------------------
+BaseTooltip *Panel::GetTooltip()
+{
+ if (!m_pTooltips)
+ {
+ m_pTooltips = new TextTooltip(this, NULL);
+ m_bToolTipOverridden = false;
+
+ if ( IsConsoleStylePanel() )
+ {
+ m_pTooltips->SetEnabled( false );
+ }
+ }
+
+ return m_pTooltips;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::SetTooltip( BaseTooltip *pToolTip, const char *pszText )
+{
+ if ( !m_bToolTipOverridden )
+ {
+ // Remove the one we made, we're being overridden.
+ delete m_pTooltips;
+ }
+
+ m_pTooltips = pToolTip;
+ m_bToolTipOverridden = true;
+
+ if ( _tooltipText )
+ {
+ delete [] _tooltipText;
+ _tooltipText = NULL;
+ }
+
+ if ( pszText )
+ {
+ int len = Q_strlen(pszText) + 1;
+ _tooltipText = new char[ len ];
+ Q_strncpy( _tooltipText, pszText, len );
+ }
+}
+
+//-----------------------------------------------------------------------------
+const char *Panel::GetEffectiveTooltipText() const
+{
+ if ( _tooltipText )
+ {
+ return _tooltipText;
+ }
+ if ( m_pTooltips )
+ {
+ const char *result = m_pTooltips->GetText();
+ if ( result )
+ {
+ return result;
+ }
+ }
+ return "";
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: sets the proportional flag on this panel and all it's children
+//-----------------------------------------------------------------------------
+void Panel::SetProportional(bool state)
+{
+ // only do something if the state changes
+ if( state != _flags.IsFlagSet( IS_PROPORTIONAL ) )
+ {
+ _flags.SetFlag( IS_PROPORTIONAL, state );
+
+ for(int i=0;i<GetChildCount();i++)
+ {
+ // recursively apply to all children
+ GetChild(i)->SetProportional( IsProportional() );
+ }
+ }
+ InvalidateLayout();
+}
+
+
+void Panel::SetKeyBoardInputEnabled( bool state )
+{
+ ipanel()->SetKeyBoardInputEnabled( GetVPanel(), state );
+ for ( int i = 0; i < GetChildCount(); i++ )
+ {
+ Panel *child = GetChild( i );
+ if ( !child )
+ {
+ continue;
+ }
+ child->SetKeyBoardInputEnabled( state );
+ }
+
+ // If turning off keyboard input enable, then make sure
+ // this panel is not the current key focus of a parent panel
+ if ( !state )
+ {
+ Panel *pParent = GetParent();
+ if ( pParent )
+ {
+ if ( pParent->GetCurrentKeyFocus() == GetVPanel() )
+ {
+ pParent->RequestFocusNext();
+ }
+ }
+ }
+}
+
+void Panel::SetMouseInputEnabled( bool state )
+{
+ ipanel()->SetMouseInputEnabled( GetVPanel(), state );
+ /* for(int i=0;i<GetChildCount();i++)
+ {
+ GetChild(i)->SetMouseInput(state);
+ }*/
+ vgui::surface()->CalculateMouseVisible();
+}
+
+bool Panel::IsKeyBoardInputEnabled()
+{
+ return ipanel()->IsKeyBoardInputEnabled( GetVPanel() );
+}
+
+bool Panel::IsMouseInputEnabled()
+{
+ return ipanel()->IsMouseInputEnabled( GetVPanel() );
+}
+
+class CFloatProperty : public vgui::IPanelAnimationPropertyConverter
+{
+public:
+ virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ kv->SetFloat( entry->name(), *(float *)data );
+ }
+
+ virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ *(float *)data = kv->GetFloat( entry->name() );
+ }
+
+ virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ *(float *)data = atof( entry->defaultvalue() );
+ }
+};
+
+class CProportionalFloatProperty : public vgui::IPanelAnimationPropertyConverter
+{
+public:
+ virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ float f = *(float *)data;
+ f = scheme()->GetProportionalNormalizedValueEx( panel->GetScheme(), f );
+ kv->SetFloat( entry->name(), f );
+ }
+
+ virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ float f = kv->GetFloat( entry->name() );
+ f = scheme()->GetProportionalScaledValueEx( panel->GetScheme(), f );
+ *(float *)data = f;
+ }
+
+ virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ float f = atof( entry->defaultvalue() );
+ f = scheme()->GetProportionalScaledValueEx( panel->GetScheme(), f );
+ *(float *)data = f;
+ }
+};
+
+class CIntProperty : public vgui::IPanelAnimationPropertyConverter
+{
+public:
+ virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ kv->SetInt( entry->name(), *(int *)data );
+ }
+
+ virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ *(int *)data = kv->GetInt( entry->name() );
+ }
+
+ virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ *(int *)data = atoi( entry->defaultvalue() );
+ }
+};
+
+class CProportionalIntProperty : public vgui::IPanelAnimationPropertyConverter
+{
+public:
+ virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ int i = *(int *)data;
+ i = scheme()->GetProportionalNormalizedValueEx( panel->GetScheme(), i );
+ kv->SetInt( entry->name(), i );
+ }
+
+ virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ int i = kv->GetInt( entry->name() );
+ i = scheme()->GetProportionalScaledValueEx( panel->GetScheme(), i );
+ *(int *)data = i;
+ }
+ virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ int i = atoi( entry->defaultvalue() );
+ i = scheme()->GetProportionalScaledValueEx( panel->GetScheme(), i );
+ *(int *)data = i;
+ }
+};
+
+class CProportionalIntWithScreenspacePropertyX : public vgui::IPanelAnimationPropertyConverter
+{
+public:
+ int ExtractValue( Panel *panel, const char *pszKey )
+ {
+ int iValue = 0;
+ bool bRightAlign = false;
+ bool bCenterAlign = false;
+ if (pszKey[0] == 'r' || pszKey[0] == 'R')
+ {
+ bRightAlign = true;
+ pszKey++;
+ }
+ else if (pszKey[0] == 'c' || pszKey[0] == 'C')
+ {
+ bCenterAlign = true;
+ pszKey++;
+ }
+
+ // get the value
+ iValue = atoi(pszKey);
+ iValue = scheme()->GetProportionalScaledValueEx(panel->GetScheme(), iValue);
+
+ int screenSize = GetScreenSize();
+ // now correct the alignment
+ if ( bRightAlign )
+ {
+ iValue = screenSize - iValue;
+ }
+ else if ( bCenterAlign )
+ {
+ iValue = (screenSize / 2) + iValue;
+ }
+
+ return iValue;
+ }
+
+ virtual int GetScreenSize( void )
+ {
+ int screenWide, screenTall;
+ surface()->GetScreenSize(screenWide, screenTall);
+ return screenWide;
+ }
+
+ virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
+ {
+ // Won't work with this, don't use it.
+ Assert(0);
+ }
+
+ virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ *(int *)data = ExtractValue( panel, kv->GetString( entry->name() ) );
+ }
+ virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ *(int *)data = ExtractValue( panel, entry->defaultvalue() );
+ }
+};
+
+class CProportionalIntWithScreenspacePropertyY : public CProportionalIntWithScreenspacePropertyX
+{
+public:
+ virtual int GetScreenSize( void )
+ {
+ int screenWide, screenTall;
+ surface()->GetScreenSize(screenWide, screenTall);
+ return screenTall;
+ }
+};
+
+class CColorProperty : public vgui::IPanelAnimationPropertyConverter
+{
+public:
+ virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ kv->SetColor( entry->name(), *(Color *)data );
+ }
+
+ virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
+ {
+ vgui::IScheme *scheme = vgui::scheme()->GetIScheme( panel->GetScheme() );
+ Assert( scheme );
+ if ( scheme )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+
+ char const *colorName = kv->GetString( entry->name() );
+ if ( !colorName || !colorName[0] )
+ {
+ *(Color *)data = kv->GetColor( entry->name() );
+ }
+ else
+ {
+ *(Color *)data = scheme->GetColor( colorName, Color( 0, 0, 0, 0 ) );
+ }
+ }
+ }
+
+ virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
+ {
+ vgui::IScheme *scheme = vgui::scheme()->GetIScheme( panel->GetScheme() );
+ Assert( scheme );
+ if ( scheme )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ *(Color *)data = scheme->GetColor( entry->defaultvalue(), Color( 0, 0, 0, 0 ) );
+ }
+ }
+};
+
+class CBoolProperty : public vgui::IPanelAnimationPropertyConverter
+{
+public:
+ virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ kv->SetInt( entry->name(), *(bool *)data ? 1 : 0 );
+ }
+
+ virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ *(bool *)data = kv->GetInt( entry->name() ) ? true : false;
+ }
+
+ virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ bool b = false;
+ if ( !stricmp( entry->defaultvalue(), "true" )||
+ atoi( entry->defaultvalue() )!= 0 )
+ {
+ b = true;
+ }
+
+ *(bool *)data = b;
+ }
+};
+
+class CStringProperty : public vgui::IPanelAnimationPropertyConverter
+{
+public:
+ virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ kv->SetString( entry->name(), (char *)data );
+ }
+
+ virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ strcpy( (char *)data, kv->GetString( entry->name() ) );
+ }
+
+ virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ strcpy( ( char * )data, entry->defaultvalue() );
+ }
+};
+
+class CHFontProperty : public vgui::IPanelAnimationPropertyConverter
+{
+public:
+ virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
+ {
+ vgui::IScheme *scheme = vgui::scheme()->GetIScheme( panel->GetScheme() );
+ Assert( scheme );
+ if ( scheme )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ char const *fontName = scheme->GetFontName( *(HFont *)data );
+ kv->SetString( entry->name(), fontName );
+ }
+ }
+
+ virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
+ {
+ vgui::IScheme *scheme = vgui::scheme()->GetIScheme( panel->GetScheme() );
+ Assert( scheme );
+ if ( scheme )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ char const *fontName = kv->GetString( entry->name() );
+ *(HFont *)data = scheme->GetFont( fontName, panel->IsProportional() );
+ }
+ }
+
+ virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
+ {
+ vgui::IScheme *scheme = vgui::scheme()->GetIScheme( panel->GetScheme() );
+ Assert( scheme );
+ if ( scheme )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ *(HFont *)data = scheme->GetFont( entry->defaultvalue(), panel->IsProportional() );
+ }
+ }
+};
+
+class CTextureIdProperty : public vgui::IPanelAnimationPropertyConverter
+{
+public:
+ virtual void GetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+ int currentId = *(int *)data;
+
+ // lookup texture name for id
+ char texturename[ 512 ];
+ if ( currentId != -1 &&
+ surface()->DrawGetTextureFile( currentId, texturename, sizeof( texturename ) ) )
+ {
+ kv->SetString( entry->name(), texturename );
+ }
+ else
+ {
+ kv->SetString( entry->name(), "" );
+ }
+ }
+
+ virtual void SetData( Panel *panel, KeyValues *kv, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+
+ int currentId = -1;
+
+ char const *texturename = kv->GetString( entry->name() );
+ if ( texturename && texturename[ 0 ] )
+ {
+ currentId = surface()->DrawGetTextureId( texturename );
+ if ( currentId == -1 )
+ {
+ currentId = surface()->CreateNewTextureID();
+ }
+ surface()->DrawSetTextureFile( currentId, texturename, false, true );
+ }
+
+ *(int *)data = currentId;
+ }
+
+ virtual void InitFromDefault( Panel *panel, PanelAnimationMapEntry *entry )
+ {
+ void *data = ( void * )( (*entry->m_pfnLookup)( panel ) );
+
+ int currentId = -1;
+
+ char const *texturename = entry->defaultvalue();
+ if ( texturename && texturename[ 0 ] )
+ {
+ currentId = surface()->DrawGetTextureId( texturename );
+ if ( currentId == -1 )
+ {
+ currentId = surface()->CreateNewTextureID();
+ }
+ surface()->DrawSetTextureFile( currentId, texturename, false, true );
+ }
+
+ *(int *)data = currentId;
+ }
+};
+
+static CFloatProperty floatconverter;
+static CProportionalFloatProperty p_floatconverter;
+static CIntProperty intconverter;
+static CProportionalIntProperty p_intconverter;
+static CProportionalIntWithScreenspacePropertyX p_screenspace_intconverter_X;
+static CProportionalIntWithScreenspacePropertyY p_screenspace_intconverter_Y;
+static CColorProperty colorconverter;
+static CBoolProperty boolconverter;
+static CStringProperty stringconverter;
+static CHFontProperty fontconverter;
+static CTextureIdProperty textureidconverter;
+//static CProportionalXPosProperty xposconverter;
+//static CProportionalYPosProperty yposconverter;
+
+static CUtlDict< IPanelAnimationPropertyConverter *, int > g_AnimationPropertyConverters;
+
+static IPanelAnimationPropertyConverter *FindConverter( char const *typeName )
+{
+ int lookup = g_AnimationPropertyConverters.Find( typeName );
+ if ( lookup == g_AnimationPropertyConverters.InvalidIndex() )
+ return NULL;
+
+ IPanelAnimationPropertyConverter *converter = g_AnimationPropertyConverters[ lookup ];
+ return converter;
+}
+
+void Panel::AddPropertyConverter( char const *typeName, IPanelAnimationPropertyConverter *converter )
+{
+ int lookup = g_AnimationPropertyConverters.Find( typeName );
+ if ( lookup != g_AnimationPropertyConverters.InvalidIndex() )
+ {
+ Msg( "Already have converter for type %s, ignoring...\n", typeName );
+ return;
+ }
+
+ g_AnimationPropertyConverters.Insert( typeName, converter );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Static method to initialize all needed converters
+//-----------------------------------------------------------------------------
+void Panel::InitPropertyConverters( void )
+{
+ static bool initialized = false;
+ if ( initialized )
+ return;
+ initialized = true;
+
+ AddPropertyConverter( "float", &floatconverter );
+ AddPropertyConverter( "int", &intconverter );
+ AddPropertyConverter( "Color", &colorconverter );
+ //AddPropertyConverter( "vgui::Color", &colorconverter );
+ AddPropertyConverter( "bool", &boolconverter );
+ AddPropertyConverter( "char", &stringconverter );
+ AddPropertyConverter( "string", &stringconverter );
+ AddPropertyConverter( "HFont", &fontconverter );
+ AddPropertyConverter( "vgui::HFont", &fontconverter );
+
+ // This is an aliased type for proportional float
+ AddPropertyConverter( "proportional_float", &p_floatconverter );
+ AddPropertyConverter( "proportional_int", &p_intconverter );
+
+ AddPropertyConverter( "proportional_xpos", &p_screenspace_intconverter_X );
+ AddPropertyConverter( "proportional_ypos", &p_screenspace_intconverter_Y );
+
+ AddPropertyConverter( "textureid", &textureidconverter );
+}
+
+bool Panel::InternalRequestInfo( PanelAnimationMap *map, KeyValues *outputData )
+{
+ if ( !map )
+ return false;
+
+ Assert( outputData );
+
+ char const *name = outputData->GetName();
+
+ PanelAnimationMapEntry *e = FindPanelAnimationEntry( name, map );
+ if ( e )
+ {
+ IPanelAnimationPropertyConverter *converter = FindConverter( e->type() );
+ if ( converter )
+ {
+ converter->GetData( this, outputData, e );
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool Panel::InternalSetInfo( PanelAnimationMap *map, KeyValues *inputData )
+{
+ if ( !map )
+ return false;
+
+ Assert( inputData );
+
+ char const *name = inputData->GetName();
+
+ PanelAnimationMapEntry *e = FindPanelAnimationEntry( name, map );
+ if ( e )
+ {
+ IPanelAnimationPropertyConverter *converter = FindConverter( e->type() );
+ if ( converter )
+ {
+ converter->SetData( this, inputData, e );
+ return true;
+ }
+ }
+
+ return false;
+}
+
+PanelAnimationMapEntry *Panel::FindPanelAnimationEntry( char const *scriptname, PanelAnimationMap *map )
+{
+ if ( !map )
+ return NULL;
+
+ Assert( scriptname );
+
+ // Look through mapping for entry
+ int c = map->entries.Count();
+ for ( int i = 0; i < c; i++ )
+ {
+ PanelAnimationMapEntry *e = &map->entries[ i ];
+
+ if ( !stricmp( e->name(), scriptname ) )
+ {
+ return e;
+ }
+ }
+
+ // Recurse
+ if ( map->baseMap )
+ {
+ return FindPanelAnimationEntry( scriptname, map->baseMap );
+ }
+
+ return NULL;
+}
+
+// Recursively invoke settings for PanelAnimationVars
+void Panel::InternalApplySettings( PanelAnimationMap *map, KeyValues *inResourceData)
+{
+ // Loop through keys
+ KeyValues *kv;
+
+ for ( kv = inResourceData->GetFirstSubKey(); kv; kv = kv->GetNextKey() )
+ {
+ char const *varname = kv->GetName();
+
+ PanelAnimationMapEntry *entry = FindPanelAnimationEntry( varname, GetAnimMap() );
+ if ( entry )
+ {
+ // Set value to value from script
+ IPanelAnimationPropertyConverter *converter = FindConverter( entry->type() );
+ if ( converter )
+ {
+ converter->SetData( this, inResourceData, entry );
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: sets the default values of all CPanelAnimationVars
+//-----------------------------------------------------------------------------
+void Panel::InternalInitDefaultValues( PanelAnimationMap *map )
+{
+ _flags.ClearFlag( NEEDS_DEFAULT_SETTINGS_APPLIED );
+
+ // Look through mapping for entry
+ int c = map->entries.Count();
+ for ( int i = 0; i < c; i++ )
+ {
+ PanelAnimationMapEntry *e = &map->entries[ i ];
+ Assert( e );
+ IPanelAnimationPropertyConverter *converter = FindConverter( e->type() );
+ if ( !converter )
+ continue;
+
+ converter->InitFromDefault( this, e );
+ }
+
+ if ( map->baseMap )
+ {
+ InternalInitDefaultValues( map->baseMap );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+int Panel::GetPaintBackgroundType()
+{
+ return m_nPaintBackgroundType;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : w -
+// h -
+//-----------------------------------------------------------------------------
+void Panel::GetCornerTextureSize( int& w, int& h )
+{
+ if ( m_nBgTextureId1 == -1 )
+ {
+ w = h = 0;
+ return;
+ }
+ surface()->DrawGetTextureSize(m_nBgTextureId1, w, h);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: draws a selection box
+//-----------------------------------------------------------------------------
+void Panel::DrawBox(int x, int y, int wide, int tall, Color color, float normalizedAlpha, bool hollow /*=false*/ )
+{
+ if ( m_nBgTextureId1 == -1 ||
+ m_nBgTextureId2 == -1 ||
+ m_nBgTextureId3 == -1 ||
+ m_nBgTextureId4 == -1 )
+ {
+ return;
+ }
+
+ color[3] *= normalizedAlpha;
+
+ // work out our bounds
+ int cornerWide, cornerTall;
+ GetCornerTextureSize( cornerWide, cornerTall );
+
+ // draw the background in the areas not occupied by the corners
+ // draw it in three horizontal strips
+ surface()->DrawSetColor(color);
+ surface()->DrawFilledRect(x + cornerWide, y, x + wide - cornerWide, y + cornerTall);
+ if ( !hollow )
+ {
+ surface()->DrawFilledRect(x, y + cornerTall, x + wide, y + tall - cornerTall);
+ }
+ else
+ {
+ surface()->DrawFilledRect(x, y + cornerTall, x + cornerWide, y + tall - cornerTall);
+ surface()->DrawFilledRect(x + wide - cornerWide, y + cornerTall, x + wide, y + tall - cornerTall);
+ }
+ surface()->DrawFilledRect(x + cornerWide, y + tall - cornerTall, x + wide - cornerWide, y + tall);
+
+ // draw the corners
+
+ //=============================================================================
+ // HPE_BEGIN:
+ // [tj] We now check each individual corner and decide whether to draw it straight or rounded
+ //=============================================================================
+ //TOP-LEFT
+ if (ShouldDrawTopLeftCornerRounded())
+ {
+ surface()->DrawSetTexture(m_nBgTextureId1);
+ surface()->DrawTexturedRect(x, y, x + cornerWide, y + cornerTall);
+ }
+ else
+ {
+ surface()->DrawFilledRect(x, y, x + cornerWide, y + cornerTall);
+ }
+
+
+ //TOP-RIGHT
+ if (ShouldDrawTopRightCornerRounded())
+ {
+ surface()->DrawSetTexture(m_nBgTextureId2);
+ surface()->DrawTexturedRect(x + wide - cornerWide, y, x + wide, y + cornerTall);
+ }
+ else
+ {
+ surface()->DrawFilledRect(x + wide - cornerWide, y, x + wide, y + cornerTall);
+ }
+
+ //BOTTOM-LEFT
+ if (ShouldDrawBottomLeftCornerRounded())
+ {
+ surface()->DrawSetTexture(m_nBgTextureId4);
+ surface()->DrawTexturedRect(x + 0, y + tall - cornerTall, x + cornerWide, y + tall);
+ }
+ else
+ {
+ surface()->DrawFilledRect(x + 0, y + tall - cornerTall, x + cornerWide, y + tall);
+ }
+
+
+ //BOTTOM-RIGHT
+ if (ShouldDrawBottomRightCornerRounded())
+ {
+ surface()->DrawSetTexture(m_nBgTextureId3);
+ surface()->DrawTexturedRect(x + wide - cornerWide, y + tall - cornerTall, x + wide, y + tall);
+ }
+ else
+ {
+ surface()->DrawFilledRect(x + wide - cornerWide, y + tall - cornerTall, x + wide, y + tall);
+ }
+ //=============================================================================
+ // HPE_END
+ //=============================================================================
+}
+
+void Panel::DrawBoxFade(int x, int y, int wide, int tall, Color color, float normalizedAlpha, unsigned int alpha0, unsigned int alpha1, bool bHorizontal, bool hollow /*=false*/ )
+{
+ if ( m_nBgTextureId1 == -1 ||
+ m_nBgTextureId2 == -1 ||
+ m_nBgTextureId3 == -1 ||
+ m_nBgTextureId4 == -1 ||
+ surface()->DrawGetAlphaMultiplier() == 0 )
+ {
+ return;
+ }
+
+ color[3] *= normalizedAlpha;
+
+ // work out our bounds
+ int cornerWide, cornerTall;
+ GetCornerTextureSize( cornerWide, cornerTall );
+
+ if ( !bHorizontal )
+ {
+ // draw the background in the areas not occupied by the corners
+ // draw it in three horizontal strips
+ surface()->DrawSetColor(color);
+ surface()->DrawFilledRectFade(x + cornerWide, y, x + wide - cornerWide, y + cornerTall, alpha0, alpha0, bHorizontal );
+ if ( !hollow )
+ {
+ surface()->DrawFilledRectFade(x, y + cornerTall, x + wide, y + tall - cornerTall, alpha0, alpha1, bHorizontal);
+ }
+ else
+ {
+ surface()->DrawFilledRectFade(x, y + cornerTall, x + cornerWide, y + tall - cornerTall, alpha0, alpha1, bHorizontal);
+ surface()->DrawFilledRectFade(x + wide - cornerWide, y + cornerTall, x + wide, y + tall - cornerTall, alpha0, alpha1, bHorizontal);
+ }
+ surface()->DrawFilledRectFade(x + cornerWide, y + tall - cornerTall, x + wide - cornerWide, y + tall, alpha1, alpha1, bHorizontal);
+ }
+ else
+ {
+ // draw the background in the areas not occupied by the corners
+ // draw it in three horizontal strips
+ surface()->DrawSetColor(color);
+ surface()->DrawFilledRectFade(x, y + cornerTall, x + cornerWide, y + tall - cornerTall, alpha0, alpha0, bHorizontal );
+ if ( !hollow )
+ {
+ surface()->DrawFilledRectFade(x + cornerWide, y, x + wide - cornerWide, y + tall, alpha0, alpha1, bHorizontal);
+ }
+ else
+ {
+ // FIXME: Hollow horz version not implemented
+ //surface()->DrawFilledRectFade(x, y + cornerTall, x + cornerWide, y + tall - cornerTall, alpha0, alpha1, bHorizontal);
+ //surface()->DrawFilledRectFade(x + wide - cornerWide, y + cornerTall, x + wide, y + tall - cornerTall, alpha0, alpha1, bHorizontal);
+ }
+ surface()->DrawFilledRectFade(x + wide - cornerWide, y + cornerTall, x + wide, y + tall - cornerTall, alpha1, alpha1, bHorizontal);
+ }
+
+ float fOldAlpha = color[ 3 ];
+ int iAlpha0 = fOldAlpha * ( static_cast<float>( alpha0 ) / 255.0f );
+ int iAlpha1 = fOldAlpha * ( static_cast<float>( alpha1 ) / 255.0f );
+
+ // draw the corners
+ if ( !bHorizontal )
+ {
+ color[ 3 ] = iAlpha0;
+ surface()->DrawSetColor( color );
+ surface()->DrawSetTexture(m_nBgTextureId1);
+ surface()->DrawTexturedRect(x, y, x + cornerWide, y + cornerTall);
+ surface()->DrawSetTexture(m_nBgTextureId2);
+ surface()->DrawTexturedRect(x + wide - cornerWide, y, x + wide, y + cornerTall);
+
+ color[ 3 ] = iAlpha1;
+ surface()->DrawSetColor( color );
+ surface()->DrawSetTexture(m_nBgTextureId3);
+ surface()->DrawTexturedRect(x + wide - cornerWide, y + tall - cornerTall, x + wide, y + tall);
+ surface()->DrawSetTexture(m_nBgTextureId4);
+ surface()->DrawTexturedRect(x + 0, y + tall - cornerTall, x + cornerWide, y + tall);
+ }
+ else
+ {
+ color[ 3 ] = iAlpha0;
+ surface()->DrawSetColor( color );
+ surface()->DrawSetTexture(m_nBgTextureId1);
+ surface()->DrawTexturedRect(x, y, x + cornerWide, y + cornerTall);
+ surface()->DrawSetTexture(m_nBgTextureId4);
+ surface()->DrawTexturedRect(x + 0, y + tall - cornerTall, x + cornerWide, y + tall);
+
+ color[ 3 ] = iAlpha1;
+ surface()->DrawSetColor( color );
+ surface()->DrawSetTexture(m_nBgTextureId2);
+ surface()->DrawTexturedRect(x + wide - cornerWide, y, x + wide, y + cornerTall);
+ surface()->DrawSetTexture(m_nBgTextureId3);
+ surface()->DrawTexturedRect(x + wide - cornerWide, y + tall - cornerTall, x + wide, y + tall);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : x -
+// y -
+// wide -
+// tall -
+// color -
+// normalizedAlpha -
+//-----------------------------------------------------------------------------
+void Panel::DrawHollowBox(int x, int y, int wide, int tall, Color color, float normalizedAlpha )
+{
+ DrawBox( x, y, wide, tall, color, normalizedAlpha, true );
+}
+
+//=============================================================================
+// HPE_BEGIN:
+// [menglish] Draws a hollow box similar to the already existing draw hollow box function, but takes the indents as params
+//=============================================================================
+
+void Panel::DrawHollowBox( int x, int y, int wide, int tall, Color color, float normalizedAlpha, int cornerWide, int cornerTall )
+{
+ if ( m_nBgTextureId1 == -1 ||
+ m_nBgTextureId2 == -1 ||
+ m_nBgTextureId3 == -1 ||
+ m_nBgTextureId4 == -1 )
+ {
+ return;
+ }
+
+ color[3] *= normalizedAlpha;
+
+ // draw the background in the areas not occupied by the corners
+ // draw it in three horizontal strips
+ surface()->DrawSetColor(color);
+ surface()->DrawFilledRect(x + cornerWide, y, x + wide - cornerWide, y + cornerTall);
+ surface()->DrawFilledRect(x, y + cornerTall, x + cornerWide, y + tall - cornerTall);
+ surface()->DrawFilledRect(x + wide - cornerWide, y + cornerTall, x + wide, y + tall - cornerTall);
+ surface()->DrawFilledRect(x + cornerWide, y + tall - cornerTall, x + wide - cornerWide, y + tall);
+
+ // draw the corners
+ surface()->DrawSetTexture(m_nBgTextureId1);
+ surface()->DrawTexturedRect(x, y, x + cornerWide, y + cornerTall);
+ surface()->DrawSetTexture(m_nBgTextureId2);
+ surface()->DrawTexturedRect(x + wide - cornerWide, y, x + wide, y + cornerTall);
+ surface()->DrawSetTexture(m_nBgTextureId3);
+ surface()->DrawTexturedRect(x + wide - cornerWide, y + tall - cornerTall, x + wide, y + tall);
+ surface()->DrawSetTexture(m_nBgTextureId4);
+ surface()->DrawTexturedRect(x + 0, y + tall - cornerTall, x + cornerWide, y + tall);
+}
+
+//=============================================================================
+// HPE_END
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Purpose: draws a selection box
+//-----------------------------------------------------------------------------
+void Panel::DrawTexturedBox(int x, int y, int wide, int tall, Color color, float normalizedAlpha )
+{
+ if ( m_nBgTextureId1 == -1 )
+ return;
+
+ color[3] *= normalizedAlpha;
+
+ surface()->DrawSetColor( color );
+ surface()->DrawSetTexture(m_nBgTextureId1);
+ surface()->DrawTexturedRect(x, y, x + wide, y + tall);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Marks this panel as draggable (note that children will chain to their parents to see if any parent is draggable)
+// Input : enabled -
+//-----------------------------------------------------------------------------
+void Panel::SetDragEnabled( bool enabled )
+{
+#if defined( VGUI_USEDRAGDROP )
+ // If turning it off, quit dragging if mid-drag
+ if ( !enabled &&
+ m_pDragDrop->m_bDragging )
+ {
+ OnFinishDragging( false, (MouseCode)-1 );
+ }
+ m_pDragDrop->m_bDragEnabled = enabled;
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool Panel::IsDragEnabled() const
+{
+#if defined( VGUI_USEDRAGDROP )
+ return m_pDragDrop->m_bDragEnabled;
+#endif
+ return false;
+}
+
+void Panel::SetShowDragHelper( bool enabled )
+{
+#if defined( VGUI_USEDRAGDROP )
+ m_pDragDrop->m_bShowDragHelper = enabled;
+#endif
+}
+
+// Use this to prevent chaining up from a parent which can mess with mouse functionality if you don't want to chain up from a child panel to the best
+// draggable parent.
+void Panel::SetBlockDragChaining( bool block )
+{
+#if defined( VGUI_USEDRAGDROP )
+ m_pDragDrop->m_bPreventChaining = block;
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool Panel::IsBlockingDragChaining() const
+{
+#if defined( VGUI_USEDRAGDROP )
+ return m_pDragDrop->m_bPreventChaining;
+#endif
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// accessors for m_nDragStartTolerance
+//-----------------------------------------------------------------------------
+int Panel::GetDragStartTolerance() const
+{
+#if defined( VGUI_USEDRAGDROP )
+ return m_pDragDrop->m_nDragStartTolerance;
+#endif
+ return 0;
+}
+
+void Panel::SetDragSTartTolerance( int nTolerance )
+{
+#if defined( VGUI_USEDRAGDROP )
+ m_pDragDrop->m_nDragStartTolerance = nTolerance;
+#endif
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Marks this panel as droppable ( note that children will chain to their parents to see if any parent is droppable)
+// Input : enabled -
+//-----------------------------------------------------------------------------
+void Panel::SetDropEnabled( bool enabled, float flHoverContextTime /* = 0.0f */ )
+{
+#if defined( VGUI_USEDRAGDROP )
+ m_pDragDrop->m_bDropEnabled = enabled;
+ m_pDragDrop->m_flHoverContextTime = flHoverContextTime;
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool Panel::IsDropEnabled() const
+{
+#if defined( VGUI_USEDRAGDROP )
+ return m_pDragDrop->m_bDropEnabled;
+#endif
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Chains up to any parent
+// 1) marked DropEnabled; and
+// 2) willing to accept the drop payload
+// Input : -
+// Output : Panel
+//-----------------------------------------------------------------------------
+Panel *Panel::GetDropTarget( CUtlVector< KeyValues * >& msglist )
+{
+#if defined( VGUI_USEDRAGDROP )
+ // Found one
+ if ( m_pDragDrop->m_bDropEnabled &&
+ IsDroppable( msglist ) )
+ {
+ return this;
+ }
+
+ // Chain up
+ if ( GetParent() )
+ {
+ return GetParent()->GetDropTarget( msglist );
+ }
+#endif
+ // No luck
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Chains up to first parent marked DragEnabled
+// Input : -
+// Output : Panel
+//-----------------------------------------------------------------------------
+Panel *Panel::GetDragPanel()
+{
+#if defined( VGUI_USEDRAGDROP )
+ // If we encounter a blocker, stop chaining
+ if ( m_pDragDrop->m_bPreventChaining )
+ return NULL;
+
+ if ( m_pDragDrop->m_bDragEnabled )
+ return this;
+
+ // Chain up
+ if ( GetParent() )
+ {
+ return GetParent()->GetDragPanel();
+ }
+#endif
+ // No luck
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void Panel::OnStartDragging()
+{
+#if defined( VGUI_USEDRAGDROP )
+ // Only left mouse initiates drag/drop.
+ // FIXME: Revisit?
+ if ( !input()->IsMouseDown( MOUSE_LEFT ) )
+ return;
+
+ if ( !m_pDragDrop->m_bDragEnabled )
+ return;
+
+ if ( m_pDragDrop->m_bDragging )
+ return;
+
+ g_DragDropCapture = this;
+
+ m_pDragDrop->m_bDragStarted = false;
+ m_pDragDrop->m_bDragging = true;
+ input()->GetCursorPos( m_pDragDrop->m_nStartPos[ 0 ], m_pDragDrop->m_nStartPos[ 1 ] );
+ m_pDragDrop->m_nLastPos[ 0 ] = m_pDragDrop->m_nStartPos[ 0 ];
+ m_pDragDrop->m_nLastPos[ 1 ] = m_pDragDrop->m_nStartPos[ 1 ];
+
+ OnContinueDragging();
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Called if drag drop is started but not dropped on top of droppable panel...
+// Input : -
+//-----------------------------------------------------------------------------
+void Panel::OnDragFailed( CUtlVector< KeyValues * >& msglist )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void Panel::OnFinishDragging( bool mousereleased, MouseCode code, bool abort /*= false*/ )
+{
+#if defined( VGUI_USEDRAGDROP )
+ g_DragDropCapture = NULL;
+
+ if ( !m_pDragDrop->m_bDragEnabled )
+ return;
+
+ Assert( m_pDragDrop->m_bDragging );
+
+ if ( !m_pDragDrop->m_bDragging )
+ return;
+
+ int x, y;
+ input()->GetCursorPos( x, y );
+
+ m_pDragDrop->m_nLastPos[ 0 ] = x;
+ m_pDragDrop->m_nLastPos[ 1 ] = y;
+
+ if ( s_DragDropHelper.Get() )
+ {
+ s_DragDropHelper->RemovePanel( this );
+ }
+
+ m_pDragDrop->m_bDragging = false;
+
+ CUtlVector< KeyValues * >& data = m_pDragDrop->m_DragData;
+ int c = data.Count();
+
+ Panel *target = NULL;
+ bool shouldDrop = false;
+
+ if ( m_pDragDrop->m_bDragStarted )
+ {
+ char cmd[ 256 ];
+ Q_strncpy( cmd, "default", sizeof( cmd ) );
+
+ if ( mousereleased &&
+ m_pDragDrop->m_hCurrentDrop != 0 &&
+ m_pDragDrop->m_hDropContextMenu.Get() )
+ {
+ Menu *menu = m_pDragDrop->m_hDropContextMenu;
+
+ VPANEL hover = menu->IsWithinTraverse( x, y, false );
+ if ( hover )
+ {
+ Panel *pHover = ipanel()->GetPanel( hover, GetModuleName() );
+ if ( pHover )
+ {
+ // Figure out if it's a menu item...
+ int c = menu->GetItemCount();
+ for ( int i = 0; i < c; ++i )
+ {
+ int id = menu->GetMenuID( i );
+ MenuItem *item = menu->GetMenuItem( id );
+ if ( item == pHover )
+ {
+ KeyValues *command = item->GetCommand();
+ if ( command )
+ {
+ char const *p = command->GetString( "command", "" );
+ if ( p && p[ 0 ] )
+ {
+ Q_strncpy( cmd, p, sizeof( cmd ) );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ delete menu;
+ m_pDragDrop->m_hDropContextMenu = NULL;
+ }
+
+ for ( int i = 0 ; i < c; ++i )
+ {
+ KeyValues *msg = data[ i ];
+
+ msg->SetString( "command", cmd );
+
+ msg->SetInt( "screenx", x );
+ msg->SetInt( "screeny", y );
+ }
+
+ target = m_pDragDrop->m_hCurrentDrop.Get();
+ if ( target && !abort )
+ {
+ int localmousex = x, localmousey = y;
+ // Convert screen space coordintes to coordinates relative to drop window
+ target->ScreenToLocal( localmousex, localmousey );
+
+ for ( int i = 0 ; i < c; ++i )
+ {
+ KeyValues *msg = data[ i ];
+
+ msg->SetInt( "x", localmousex );
+ msg->SetInt( "y", localmousey );
+ }
+
+ shouldDrop = true;
+ }
+
+ if ( !shouldDrop )
+ {
+ OnDragFailed( data );
+ }
+ }
+
+ m_pDragDrop->m_bDragStarted = false;
+ m_pDragDrop->m_DragPanels.RemoveAll();
+ m_pDragDrop->m_hCurrentDrop = NULL;
+
+ // Copy data ptrs out of data because OnPanelDropped might cause this panel to be deleted
+ // and our this ptr will be hosed...
+ CUtlVector< KeyValues * > temp;
+ for ( int i = 0 ; i < c; ++i )
+ {
+ temp.AddToTail( data[ i ] );
+ }
+ data.RemoveAll();
+
+ if ( shouldDrop && target )
+ {
+ target->OnPanelDropped( temp );
+ }
+ for ( int i = 0 ; i < c ; ++i )
+ {
+ temp[ i ]->deleteThis();
+ }
+#endif
+}
+
+void Panel::OnDropContextHoverShow( CUtlVector< KeyValues * >& msglist )
+{
+}
+
+void Panel::OnDropContextHoverHide( CUtlVector< KeyValues * >& msglist )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *msg -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool Panel::IsDroppable( CUtlVector< KeyValues * >& msglist )
+{
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : startx -
+// starty -
+// mx -
+// my -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool Panel::CanStartDragging( int startx, int starty, int mx, int my )
+{
+#if defined( VGUI_USEDRAGDROP )
+ if ( IsStartDragWhenMouseExitsPanel() )
+ {
+ ScreenToLocal( mx, my );
+ if ( mx < 0 || my < 0 )
+ return true;
+ if ( mx > GetWide() || my > GetTall() )
+ return true;
+
+ return false;
+ }
+
+ int deltax = abs( mx - startx );
+ int deltay = abs( my - starty );
+ if ( deltax > m_pDragDrop->m_nDragStartTolerance ||
+ deltay > m_pDragDrop->m_nDragStartTolerance )
+ {
+ return true;
+ }
+#endif
+ return false;
+}
+
+HCursor Panel::GetDropCursor( CUtlVector< KeyValues * >& msglist )
+{
+ return dc_arrow;
+}
+
+bool IsSelfDroppable( CUtlVector< KeyValues * > &dragData )
+{
+ if ( dragData.Count() == 0 )
+ return false;
+
+ KeyValues *pKeyValues( dragData[ 0 ] );
+ if ( !pKeyValues )
+ return false;
+
+ return pKeyValues->GetInt( "selfDroppable" ) != 0;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void Panel::OnContinueDragging()
+{
+#if defined( VGUI_USEDRAGDROP )
+ if ( !m_pDragDrop->m_bDragEnabled )
+ return;
+
+ if ( !m_pDragDrop->m_bDragging )
+ return;
+
+ int x, y;
+ input()->GetCursorPos( x, y );
+
+ // Update last position
+ m_pDragDrop->m_nLastPos[ 0 ] = x;
+ m_pDragDrop->m_nLastPos[ 1 ] = y;
+
+ if ( !m_pDragDrop->m_bDragStarted )
+ {
+ if ( CanStartDragging( m_pDragDrop->m_nStartPos[ 0 ], m_pDragDrop->m_nStartPos[ 1 ], x, y ) )
+ {
+ m_pDragDrop->m_bDragStarted = true;
+ CreateDragData();
+ }
+ else
+ {
+ return;
+ }
+ }
+
+ if ( !s_DragDropHelper.Get() && m_pDragDrop->m_bShowDragHelper )
+ {
+ s_DragDropHelper = new CDragDropHelperPanel();
+ s_DragDropHelper->SetKeyBoardInputEnabled( false );
+ s_DragDropHelper->SetMouseInputEnabled( false );
+ Assert( s_DragDropHelper.Get() );
+ }
+
+ if ( !s_DragDropHelper.Get() )
+ return;
+
+ s_DragDropHelper->AddPanel( this );
+
+ Assert( m_pDragDrop->m_DragData.Count() );
+
+ vgui::PHandle oldDrop = m_pDragDrop->m_hCurrentDrop;
+
+ // See what's under that
+ m_pDragDrop->m_hCurrentDrop = NULL;
+
+ // Search under mouse pos...
+ Panel *dropTarget = FindDropTargetPanel();
+ if ( dropTarget )
+ {
+ dropTarget = dropTarget->GetDropTarget( m_pDragDrop->m_DragData );
+ }
+
+ // it's not okay until we find a droppable panel
+ surface()->SetCursor( dc_no );
+
+ if ( dropTarget )
+ {
+ if ( dropTarget != this || IsSelfDroppable( m_pDragDrop->m_DragData ) )
+ {
+ m_pDragDrop->m_hCurrentDrop = dropTarget;
+ surface()->SetCursor( dropTarget->GetDropCursor( m_pDragDrop->m_DragData ) );
+ }
+ }
+
+ if ( m_pDragDrop->m_hCurrentDrop.Get() != oldDrop.Get() )
+ {
+ if ( oldDrop.Get() )
+ {
+ oldDrop->OnPanelExitedDroppablePanel( m_pDragDrop->m_DragData );
+ }
+
+ if ( m_pDragDrop->m_hCurrentDrop.Get() )
+ {
+ m_pDragDrop->m_hCurrentDrop->OnPanelEnteredDroppablePanel( m_pDragDrop->m_DragData );
+ m_pDragDrop->m_hCurrentDrop->OnDropContextHoverHide( m_pDragDrop->m_DragData );
+
+ // Reset hover time
+ m_pDragDrop->m_lDropHoverTime = system()->GetTimeMillis();
+ m_pDragDrop->m_bDropMenuShown = false;
+ }
+
+ // Discard any stale context menu...
+ if ( m_pDragDrop->m_hDropContextMenu.Get() )
+ {
+ delete m_pDragDrop->m_hDropContextMenu.Get();
+ }
+ }
+
+ if ( m_pDragDrop->m_hCurrentDrop != 0 &&
+ m_pDragDrop->m_hDropContextMenu.Get() )
+ {
+ Menu *menu = m_pDragDrop->m_hDropContextMenu;
+
+ VPANEL hover = menu->IsWithinTraverse( x, y, false );
+ if ( hover )
+ {
+ Panel *pHover = ipanel()->GetPanel( hover, GetModuleName() );
+ if ( pHover )
+ {
+ // Figure out if it's a menu item...
+ int c = menu->GetItemCount();
+ for ( int i = 0; i < c; ++i )
+ {
+ int id = menu->GetMenuID( i );
+ MenuItem *item = menu->GetMenuItem( id );
+ if ( item == pHover )
+ {
+ menu->SetCurrentlyHighlightedItem( id );
+ }
+ }
+ }
+ }
+ else
+ {
+ menu->ClearCurrentlyHighlightedItem();
+ }
+ }
+#endif
+}
+
+#if defined( VGUI_USEDRAGDROP )
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+// Output : DragDrop_t
+//-----------------------------------------------------------------------------
+DragDrop_t *Panel::GetDragDropInfo()
+{
+ Assert( m_pDragDrop );
+ return m_pDragDrop;
+}
+#endif
+
+void Panel::OnGetAdditionalDragPanels( CUtlVector< Panel * >& dragabbles )
+{
+ // Nothing here
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Virtual method to allow panels to add to the default values
+// Input : *msg -
+//-----------------------------------------------------------------------------
+void Panel::OnCreateDragData( KeyValues *msg )
+{
+ // These values are filled in for you:
+ // "panel" ptr to panel being dropped
+ // "screenx", "screeny" - drop cursor pos in screen space
+ // "x", "y" - drop coordinates relative to this window (the window being dropped upon)
+}
+
+// Called if m_flHoverContextTime was non-zero, allows droppee to preview the drop data and show an appropriate menu
+bool Panel::GetDropContextMenu( Menu *menu, CUtlVector< KeyValues * >& msglist )
+{
+ return false;
+}
+
+void Panel::CreateDragData()
+{
+#if defined( VGUI_USEDRAGDROP )
+ int i, c;
+
+ if ( m_pDragDrop->m_DragData.Count() )
+ {
+ return;
+ }
+
+ PHandle h;
+ h = this;
+ m_pDragDrop->m_DragPanels.AddToTail( h );
+
+ CUtlVector< Panel * > temp;
+ OnGetAdditionalDragPanels( temp );
+ c = temp.Count();
+ for ( i = 0; i < c; ++i )
+ {
+ h = temp[ i ];
+ m_pDragDrop->m_DragPanels.AddToTail( h );
+ }
+
+ c = m_pDragDrop->m_DragPanels.Count();
+ for ( i = 0 ; i < c; ++i )
+ {
+ Panel *sibling = m_pDragDrop->m_DragPanels[ i ].Get();
+ if ( !sibling )
+ {
+ continue;
+ }
+
+ KeyValues *msg = new KeyValues( "DragDrop" );
+ msg->SetPtr( "panel", sibling );
+
+ sibling->OnCreateDragData( msg );
+
+ m_pDragDrop->m_DragData.AddToTail( msg );
+ }
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+// Output : KeyValues
+//-----------------------------------------------------------------------------
+void Panel::GetDragData( CUtlVector< KeyValues * >& list )
+{
+#if defined( VGUI_USEDRAGDROP )
+ int i, c;
+
+ list.RemoveAll();
+
+ c = m_pDragDrop->m_DragData.Count();
+ for ( i = 0 ; i < c; ++i )
+ {
+ list.AddToTail( m_pDragDrop->m_DragData[ i ] );
+ }
+#endif
+}
+
+#if defined( VGUI_USEDRAGDROP )
+CDragDropHelperPanel::CDragDropHelperPanel() : BaseClass( NULL, "DragDropHelper" )
+{
+ SetVisible( true );
+ SetPaintEnabled( false );
+ SetPaintBackgroundEnabled( false );
+ SetMouseInputEnabled( false );
+ SetKeyBoardInputEnabled( false );
+ // SetCursor( dc_none );
+ ipanel()->SetTopmostPopup( GetVPanel(), true );
+ int w, h;
+ surface()->GetScreenSize( w, h );
+ SetBounds( 0, 0, w, h );
+
+ SetPostChildPaintEnabled( true );
+
+ MakePopup( false );
+}
+
+VPANEL CDragDropHelperPanel::IsWithinTraverse(int x, int y, bool traversePopups)
+{
+ return (VPANEL)0;
+}
+
+void CDragDropHelperPanel::PostChildPaint()
+{
+ int c = m_PaintList.Count();
+ for ( int i = c - 1; i >= 0 ; --i )
+ {
+ DragHelperPanel_t& data = m_PaintList[ i ];
+
+ Panel *panel = data.m_hPanel.Get();
+ if ( !panel )
+ {
+ m_PaintList.Remove( i );
+ continue;
+ }
+
+ Panel *dropPanel = panel->GetDragDropInfo()->m_hCurrentDrop.Get();
+ if ( panel )
+ {
+ if ( !dropPanel )
+ {
+ panel->OnDraggablePanelPaint();
+ }
+ else
+ {
+ CUtlVector< Panel * > temp;
+ CUtlVector< PHandle >& data = panel->GetDragDropInfo()->m_DragPanels;
+ CUtlVector< KeyValues * >& msglist = panel->GetDragDropInfo()->m_DragData;
+ int i, c;
+ c = data.Count();
+ for ( i = 0; i < c ; ++i )
+ {
+ Panel *pPanel = data[ i ].Get();
+ if ( pPanel )
+ {
+ temp.AddToTail( pPanel );
+ }
+ }
+
+ dropPanel->OnDroppablePanelPaint( msglist, temp );
+ }
+ }
+ }
+
+ if ( c == 0 )
+ {
+ MarkForDeletion();
+ }
+}
+
+void CDragDropHelperPanel::AddPanel( Panel *current )
+{
+ if ( !current )
+ return;
+
+ Menu *hover = current->GetDragDropInfo()->m_hDropContextMenu.Get();
+
+ surface()->MovePopupToFront( GetVPanel() );
+ if ( hover && hover->IsPopup() )
+ {
+ surface()->MovePopupToFront( hover->GetVPanel() );
+ }
+
+ int c = m_PaintList.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ if ( m_PaintList[ i ].m_hPanel.Get() == current )
+ return;
+ }
+
+ DragHelperPanel_t data;
+ data.m_hPanel = current;
+ m_PaintList.AddToTail( data );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *search -
+//-----------------------------------------------------------------------------
+void CDragDropHelperPanel::RemovePanel( Panel *search )
+{
+ int c = m_PaintList.Count();
+ for ( int i = c - 1 ; i >= 0; --i )
+ {
+ if ( m_PaintList[ i ].m_hPanel.Get() == search )
+ {
+ m_PaintList.Remove( i );
+ return;
+ }
+ }
+}
+#endif
+//-----------------------------------------------------------------------------
+// Purpose: Enumerates panels under mouse x,y
+// Input : panelList -
+// x -
+// y -
+// check -
+//-----------------------------------------------------------------------------
+void Panel::FindDropTargetPanel_R( CUtlVector< VPANEL >& panelList, int x, int y, VPANEL check )
+{
+#if defined( VGUI_USEDRAGDROP )
+ if ( !ipanel()->IsFullyVisible( check ) )
+ return;
+
+ if ( ::ShouldHandleInputMessage( check ) && ipanel()->IsWithinTraverse( check, x, y, false ) )
+ {
+ panelList.AddToTail( check );
+ }
+
+ CUtlVector< VPANEL > &children = ipanel()->GetChildren( check );
+ int childCount = children.Count();
+ for ( int i = 0; i < childCount; i++ )
+ {
+ VPANEL child = children[ i ];
+ FindDropTargetPanel_R( panelList, x, y, child );
+ }
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+// Output : Panel
+//-----------------------------------------------------------------------------
+Panel *Panel::FindDropTargetPanel()
+{
+#if defined( VGUI_USEDRAGDROP )
+ if ( !s_DragDropHelper.Get() )
+ return NULL;
+
+ CUtlVector< VPANEL > hits;
+
+ int x, y;
+ input()->GetCursorPos( x, y );
+
+ VPANEL embedded = surface()->GetEmbeddedPanel();
+ VPANEL helper = s_DragDropHelper.Get()->GetVPanel();
+
+ if ( surface()->IsCursorVisible() && surface()->IsWithin(x, y) )
+ {
+ // faster version of code below
+ // checks through each popup in order, top to bottom windows
+ int c = surface()->GetPopupCount();
+ for (int i = c - 1; i >= 0 && hits.Count() == 0; i--)
+ {
+ VPANEL popup = surface()->GetPopup(i);
+ if ( popup == embedded )
+ continue;
+
+ // Don't return helper panel!!!
+ if ( popup == helper )
+ continue;
+
+ if ( !ipanel()->IsFullyVisible( popup ) )
+ continue;
+
+ FindDropTargetPanel_R( hits, x, y, popup );
+ }
+
+ // Check embedded
+ if ( !hits.Count() )
+ {
+ FindDropTargetPanel_R( hits, x, y, embedded );
+ }
+ }
+
+ // Nothing under mouse...
+ if ( !hits.Count() )
+ return NULL;
+
+ // Return topmost panel under mouse, if it's visible to this .dll
+ Panel *panel = NULL;
+ int nCount = hits.Count();
+ while ( --nCount >= 0 )
+ {
+ panel = ipanel()->GetPanel( hits[ nCount ], GetModuleName() );
+ if ( panel )
+ return panel;
+ }
+#endif
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Mouse is on draggable panel and has started moving, but is not over a droppable panel yet
+// Input : -
+//-----------------------------------------------------------------------------
+void Panel::OnDraggablePanelPaint()
+{
+#if defined( VGUI_USEDRAGDROP )
+ int sw, sh;
+ GetSize( sw, sh );
+
+ int x, y;
+ input()->GetCursorPos( x, y );
+ int w, h;
+
+ w = min( sw, 80 );
+ h = min( sh, 80 );
+ x -= ( w >> 1 );
+ y -= ( h >> 1 );
+
+ surface()->DrawSetColor( m_clrDragFrame );
+ surface()->DrawOutlinedRect( x, y, x + w, y + h );
+
+ if ( m_pDragDrop->m_DragPanels.Count() > 1 )
+ {
+ surface()->DrawSetTextColor( m_clrDragFrame );
+ surface()->DrawSetTextFont( m_infoFont );
+ surface()->DrawSetTextPos( x + 5, y + 2 );
+
+ wchar_t sz[ 64 ];
+ V_swprintf_safe( sz, L"[ %i ]", m_pDragDrop->m_DragPanels.Count() );
+
+ surface()->DrawPrintText( sz, wcslen( sz ) );
+ }
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Mouse is now over a droppable panel
+// Input : *dragPanel -
+//-----------------------------------------------------------------------------
+void Panel::OnDroppablePanelPaint( CUtlVector< KeyValues * >& msglist, CUtlVector< Panel * >& dragPanels )
+{
+#if defined( VGUI_USEDRAGDROP )
+ if ( !dragPanels.Count() )
+ return;
+
+ // Convert this panel's bounds to screen space
+ int w, h;
+ GetSize( w, h );
+
+ int x, y;
+ x = y = 0;
+ LocalToScreen( x, y );
+
+ surface()->DrawSetColor( m_clrDropFrame );
+ // Draw 2 pixel frame
+ surface()->DrawOutlinedRect( x, y, x + w, y + h );
+ surface()->DrawOutlinedRect( x+1, y+1, x + w-1, y + h-1 );
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+// Output : Color
+//-----------------------------------------------------------------------------
+Color Panel::GetDropFrameColor()
+{
+#if defined( VGUI_USEDRAGDROP )
+ return m_clrDropFrame;
+#endif
+ return Color(0, 0, 0, 0);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+// Output : Color
+//-----------------------------------------------------------------------------
+Color Panel::GetDragFrameColor()
+{
+#if defined( VGUI_USEDRAGDROP )
+ return m_clrDragFrame;
+#endif
+ return Color(0, 0, 0, 0);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *data -
+//-----------------------------------------------------------------------------
+void Panel::OnPanelDropped( CUtlVector< KeyValues * >& data )
+{
+ // Empty. Derived classes would implement handlers here
+}
+
+//-----------------------------------------------------------------------------
+// called on droptarget when draggable panel enters droptarget
+//-----------------------------------------------------------------------------
+void Panel::OnPanelEnteredDroppablePanel( CUtlVector< KeyValues * >& msglist )
+{
+ // Empty. Derived classes would implement handlers here
+}
+
+//-----------------------------------------------------------------------------
+// called on droptarget when draggable panel exits droptarget
+//-----------------------------------------------------------------------------
+void Panel::OnPanelExitedDroppablePanel ( CUtlVector< KeyValues * >& msglist )
+{
+ // Empty. Derived classes would implement handlers here
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void Panel::DragDropStartDragging()
+{
+#if defined( VGUI_USEDRAGDROP )
+ // We somehow missed a mouse release, cancel the previous drag
+ if ( g_DragDropCapture.Get() )
+ {
+ if ( HasParent( g_DragDropCapture.Get()->GetVPanel() ) )
+ return;
+
+ bool started = g_DragDropCapture->GetDragDropInfo()->m_bDragStarted;
+ g_DragDropCapture->OnFinishDragging( true, (MouseCode)-1 );
+ if ( started )
+ {
+ return;
+ }
+ }
+
+ // Find actual target panel
+ Panel *panel = GetDragPanel();
+ if ( !panel )
+ return;
+
+ DragDrop_t *data = panel->GetDragDropInfo();
+ if ( !data )
+ return;
+
+ if ( !panel->IsDragEnabled() )
+ return;
+
+ if ( data->m_bDragging )
+ return;
+
+ panel->OnStartDragging();
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool Panel::IsBeingDragged()
+{
+#if defined( VGUI_USEDRAGDROP )
+ if ( !g_DragDropCapture.Get() )
+ return false;
+
+ if ( g_DragDropCapture.Get() == this )
+ return true;
+
+ // If we encounter a blocker, stop chaining
+ if ( m_pDragDrop->m_bPreventChaining )
+ return false;
+
+ // Chain up
+ if ( GetParent() )
+ {
+ return GetParent()->IsBeingDragged();
+ }
+#endif
+ // No luck
+ return false;
+}
+
+struct srect_t
+{
+ int x0, y0;
+ int x1, y1;
+
+ bool IsDegenerate()
+ {
+ if ( x1 - x0 <= 0 )
+ return true;
+ if ( y1 - y0 <= 0 )
+ return true;
+ return false;
+ }
+};
+
+// Draws a filled rect of specified bounds, but omits the bounds of the skip panel from those bounds
+void Panel::FillRectSkippingPanel( const Color &clr, int x, int y, int w, int h, Panel *skipPanel )
+{
+ int sx = 0, sy = 0, sw, sh;
+ skipPanel->GetSize( sw, sh );
+ skipPanel->LocalToScreen( sx, sy );
+ ScreenToLocal( sx, sy );
+
+ surface()->DrawSetColor( clr );
+
+ srect_t r1;
+ r1.x0 = x;
+ r1.y0 = y;
+ r1.x1 = x + w;
+ r1.y1 = y + h;
+
+ srect_t r2;
+ r2.x0 = sx;
+ r2.y0 = sy;
+ r2.x1 = sx + sw;
+ r2.y1 = sy + sh;
+
+ int topy = r1.y0;
+ int bottomy = r1.y1;
+
+ // We'll descend vertically and draw:
+ // 1 a possible bar across the top
+ // 2 a possible bar across the bottom
+ // 3 possible left bar
+ // 4 possible right bar
+
+ // Room at top?
+ if ( r2.y0 > r1.y0 )
+ {
+ topy = r2.y0;
+
+ surface()->DrawFilledRect( r1.x0, r1.y0, r1.x1, topy );
+ }
+
+ // Room at bottom?
+ if ( r2.y1 < r1.y1 )
+ {
+ bottomy = r2.y1;
+
+ surface()->DrawFilledRect( r1.x0, bottomy, r1.x1, r1.y1 );
+ }
+
+ // Room on left side?
+ if ( r2.x0 > r1.x0 )
+ {
+ int left = r2.x0;
+
+ surface()->DrawFilledRect( r1.x0, topy, left, bottomy );
+ }
+
+ // Room on right side
+ if ( r2.x1 < r1.x1 )
+ {
+ int right = r2.x1;
+
+ surface()->DrawFilledRect( right, topy, r1.x1, bottomy );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *child -
+//-----------------------------------------------------------------------------
+void Panel::SetSkipChildDuringPainting( Panel *child )
+{
+ m_SkipChild = child;
+}
+
+HPanel Panel::ToHandle() const
+{
+ return ivgui()->PanelToHandle( _vpanel );
+}
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+Panel* Panel::NavigateUp()
+{
+ Panel *target = GetNavUp();
+ if ( target )
+ {
+ NavigateFrom();
+ target->m_LastNavDirection = ND_UP;
+ target->NavigateTo();
+ }
+
+ return target;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+Panel* Panel::NavigateDown()
+{
+ Panel *target = GetNavDown();
+ if ( target )
+ {
+ NavigateFrom();
+ target->m_LastNavDirection = ND_DOWN;
+ target->NavigateTo();
+ }
+
+ return target;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+Panel* Panel::NavigateLeft()
+{
+ Panel *target = GetNavLeft();
+ if ( target )
+ {
+ NavigateFrom();
+ target->m_LastNavDirection = ND_LEFT;
+ target->NavigateTo();
+ }
+ return target;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+Panel* Panel::NavigateRight()
+{
+ Panel *target = GetNavRight();
+ if ( target )
+ {
+ NavigateFrom();
+ target->m_LastNavDirection = ND_RIGHT;
+ target->NavigateTo();
+ }
+ return target;
+}
+
+Panel* Panel::NavigateActivate()
+{
+ Panel *target = GetNavActivate();
+ if ( target )
+ {
+ NavigateFrom();
+ target->m_LastNavDirection = ND_NONE;
+ target->NavigateTo();
+ }
+ return target;
+}
+
+Panel* Panel::NavigateBack()
+{
+ Panel *target = GetNavBack();
+ if ( target )
+ {
+ NavigateFrom();
+ target->m_LastNavDirection = ND_NONE;
+ target->NavigateTo();
+ }
+ return target;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::NavigateTo()
+{
+ if ( IsX360() )
+ {
+ RequestFocus( 0 );
+ }
+
+ CallParentFunction( new KeyValues( "OnNavigateTo", "panelName", GetName() ) );
+
+ Panel *target = GetNavToRelay();
+ if ( target )
+ {
+ NavigateFrom();
+ target->m_LastNavDirection = ND_NONE;
+ NavigateToChild( target );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::NavigateFrom()
+{
+ for ( int i = 0; i < GetChildCount(); ++i )
+ {
+ Panel* currentNav = GetChild(i);
+ if ( currentNav != 0 )
+ {
+ currentNav->NavigateFrom();
+ }
+ }
+
+ CallParentFunction( new KeyValues( "OnNavigateFrom", "panelName", GetName() ) );
+
+ if ( m_pTooltips )
+ {
+ m_pTooltips->HideTooltip();
+ }
+
+ m_LastNavDirection = ND_NONE;
+}
+
+void Panel::NavigateToChild( Panel *pNavigateTo )
+{
+ for( int i = 0; i != GetChildCount(); ++i )
+ {
+ vgui::Panel *pChild = GetChild(i);
+ if( pChild )
+ pChild->NavigateFrom();
+ }
+ pNavigateTo->NavigateTo();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+Panel* Panel::SetNavUp( Panel* navUp )
+{
+ Panel* lastNav = m_NavUp;
+ m_NavUp = navUp;
+
+ if( navUp )
+ m_sNavUpName = navUp->GetName();
+ else
+ m_sNavUpName.Clear();
+
+ return lastNav;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+Panel* Panel::SetNavDown( Panel* navDown )
+{
+ Panel* lastNav = m_NavDown;
+ m_NavDown = navDown;
+
+ if( navDown )
+ m_sNavDownName = navDown->GetName();
+ else
+ m_sNavDownName.Clear();
+
+ return lastNav;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+Panel* Panel::SetNavLeft( Panel* navLeft )
+{
+ Panel* lastNav = m_NavLeft;
+ m_NavLeft = navLeft;
+
+ if( navLeft )
+ m_sNavLeftName = navLeft->GetName();
+ else
+ m_sNavLeftName.Clear();
+
+ return lastNav;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+Panel* Panel::SetNavRight( Panel* navRight )
+{
+ Panel* lastNav = m_NavRight;
+ m_NavRight = navRight;
+
+ if( navRight )
+ m_sNavRightName = navRight->GetName();
+ else
+ m_sNavRightName.Clear();
+
+ return lastNav;
+}
+
+Panel* Panel::SetNavToRelay( Panel* navToRelay )
+{
+ Panel* lastNav = m_NavToRelay;
+ m_NavToRelay = navToRelay;
+
+ return lastNav;
+}
+
+Panel* Panel::SetNavActivate( Panel* navActivate )
+{
+ Panel* lastNav = m_NavActivate;
+ m_NavActivate = navActivate;
+
+ return lastNav;
+}
+
+Panel* Panel::SetNavBack( Panel* navBack )
+{
+ Panel* lastNav = m_NavBack;
+ m_NavBack = navBack;
+
+ return lastNav;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+Panel::NAV_DIRECTION Panel::GetLastNavDirection()
+{
+ return m_LastNavDirection;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::OnNavigateTo( const char* panelName )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::OnNavigateFrom( const char* panelName )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::SetNavUp( const char* controlName )
+{
+ if ( controlName && 0 < Q_strlen( controlName ) && GetParent() != 0 )
+ {
+ m_NavUp = NULL;
+ m_sNavUpName = controlName;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::SetNavDown( const char* controlName )
+{
+ if ( controlName && 0 < Q_strlen( controlName ) && GetParent() != 0 )
+ {
+ m_NavDown = NULL;
+ m_sNavDownName = controlName;
+ }
+}
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::SetNavLeft( const char* controlName )
+{
+ if ( controlName && 0 < Q_strlen( controlName ) && GetParent() != 0 )
+ {
+ m_NavLeft = NULL;
+ m_sNavLeftName = controlName;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void Panel::SetNavRight( const char* controlName )
+{
+ if ( controlName && 0 < Q_strlen( controlName ) && GetParent() != 0 )
+ {
+ m_NavRight = NULL;
+ m_sNavRightName = controlName;
+ }
+}
+
+void Panel::SetNavToRelay( const char* controlName )
+{
+ if ( controlName && 0 < Q_strlen( controlName ) && GetParent() != 0 )
+ {
+ m_NavToRelay = NULL;
+ m_sNavToRelayName = controlName;
+ }
+}
+
+void Panel::SetNavActivate( const char* controlName )
+{
+ if ( controlName && 0 < Q_strlen( controlName ) && GetParent() != 0 )
+ {
+ m_NavActivate = NULL;
+ m_sNavActivateName = controlName;
+ }
+}
+
+void Panel::SetNavBack( const char* controlName )
+{
+ if ( controlName && 0 < Q_strlen( controlName ) && GetParent() != 0 )
+ {
+ m_NavBack = NULL;
+ m_sNavBackName = controlName;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+vgui::Panel* Panel::GetNavUp( Panel *first )
+{
+ if ( !m_NavUp && m_sNavUpName.Length() > 0 )
+ {
+ Panel *pParent = GetParent();
+ const char *pName = m_sNavUpName.String();
+ while ( pParent && pName[ 0 ] == '<' )
+ {
+ pParent = pParent->GetParent();
+ pName++;
+ }
+
+ if ( !pParent )
+ {
+ return NULL;
+ }
+
+ Panel *foundPanel = pParent->FindChildByName( pName, true );
+ if ( foundPanel != 0 )
+ {
+ m_NavUp = foundPanel;
+ }
+ }
+
+ vgui::Panel* nextPanel = m_NavUp;
+ if( m_NavUp && m_NavUp != first && !m_NavUp->IsVisible() )
+ {
+ Panel *firstPanel = first == NULL ? this : first;
+ nextPanel = nextPanel->GetNavUp( firstPanel );
+ }
+
+ return nextPanel;
+}
+
+vgui::Panel* Panel::GetNavDown( Panel *first )
+{
+ if ( !m_NavDown && m_sNavDownName.Length() > 0 )
+ {
+ Panel *pParent = GetParent();
+ const char *pName = m_sNavDownName.String();
+ while ( pParent && pName[ 0 ] == '<' )
+ {
+ pParent = pParent->GetParent();
+ pName++;
+ }
+
+ if ( !pParent )
+ {
+ return NULL;
+ }
+
+ Panel* foundPanel = pParent->FindChildByName( pName, true );
+ if ( foundPanel != 0 )
+ {
+ m_NavDown = foundPanel->GetPanel();
+ }
+ }
+
+ vgui::Panel* nextPanel = m_NavDown;
+ if( m_NavDown && m_NavDown != first && !m_NavDown->IsVisible() )
+ {
+ Panel *firstPanel = first == NULL ? this : first;
+ nextPanel = nextPanel->GetNavDown( firstPanel );
+ }
+
+ return nextPanel;
+}
+
+vgui::Panel* Panel::GetNavLeft( Panel *first )
+{
+ if ( !m_NavLeft && m_sNavLeftName.Length() > 0 )
+ {
+ Panel *pParent = GetParent();
+ const char *pName = m_sNavLeftName.String();
+ while ( pParent && pName[ 0 ] == '<' )
+ {
+ pParent = pParent->GetParent();
+ pName++;
+ }
+
+ if ( !pParent )
+ {
+ return NULL;
+ }
+
+ Panel* foundPanel = pParent->FindChildByName( pName, true );
+ if ( foundPanel != 0 )
+ {
+ m_NavLeft = foundPanel->GetPanel();
+ }
+ }
+
+ vgui::Panel* nextPanel = m_NavLeft;
+ if( m_NavLeft && m_NavLeft != first && !m_NavLeft->IsVisible() )
+ {
+ Panel *firstPanel = first == NULL ? this : first;
+ nextPanel = nextPanel->GetNavLeft( firstPanel );
+ }
+
+ return nextPanel;
+}
+
+vgui::Panel* Panel::GetNavRight( Panel *first )
+{
+ if ( !m_NavRight && m_sNavRightName.Length() > 0 )
+ {
+ Panel *pParent = GetParent();
+ const char *pName = m_sNavRightName.String();
+ while ( pParent && pName[ 0 ] == '<' )
+ {
+ pParent = pParent->GetParent();
+ pName++;
+ }
+
+ if ( !pParent )
+ {
+ return NULL;
+ }
+
+ Panel* foundPanel = pParent->FindChildByName( pName, true );
+ if ( foundPanel != 0 )
+ {
+ m_NavRight = foundPanel->GetPanel();
+ }
+ }
+
+ vgui::Panel* nextPanel = m_NavRight;
+ if( m_NavRight && m_NavRight != first && !m_NavRight->IsVisible() )
+ {
+ Panel *firstPanel = first == NULL ? this : first;
+ nextPanel = nextPanel->GetNavRight( firstPanel );
+ }
+
+ return nextPanel;
+}
+
+vgui::Panel* Panel::GetNavToRelay( Panel *first )
+{
+ if ( !m_NavToRelay && m_sNavToRelayName.Length() > 0 )
+ {
+ Panel *pParent = this;
+ const char *pName = m_sNavToRelayName.String();
+ while ( pParent && pName[ 0 ] == '<' )
+ {
+ pParent = pParent->GetParent();
+ pName++;
+ }
+
+ if ( !pParent )
+ {
+ return NULL;
+ }
+
+ Panel* foundPanel = pParent->FindChildByName( pName, true );
+ if ( foundPanel != 0 )
+ {
+ m_NavToRelay = foundPanel->GetPanel();
+ }
+ }
+
+ vgui::Panel* nextPanel = m_NavToRelay;
+ if ( m_NavToRelay && m_NavToRelay != first && !m_NavToRelay->IsVisible() )
+ {
+ Panel *firstPanel = first == NULL ? this : first;
+ nextPanel = nextPanel->GetNavToRelay( firstPanel );
+ }
+
+ return nextPanel;
+}
+
+vgui::Panel* Panel::GetNavActivate( Panel *first )
+{
+ if ( !m_NavActivate && m_sNavActivateName.Length() > 0 )
+ {
+ Panel *pParent = GetParent();
+ const char *pName = m_sNavActivateName.String();
+ while ( pParent && pName[ 0 ] == '<' )
+ {
+ pParent = pParent->GetParent();
+ pName++;
+ }
+
+ if ( !pParent )
+ {
+ return NULL;
+ }
+
+ Panel* foundPanel = pParent->FindChildByName( pName, true );
+ if ( foundPanel != 0 )
+ {
+ m_NavActivate = foundPanel->GetPanel();
+ }
+ }
+
+ vgui::Panel* nextPanel = m_NavActivate;
+ if ( m_NavActivate && m_NavActivate != first && !m_NavActivate->IsVisible() )
+ {
+ Panel *firstPanel = first == NULL ? this : first;
+ nextPanel = nextPanel->GetNavActivate( firstPanel );
+ }
+
+ return nextPanel;
+}
+
+vgui::Panel* Panel::GetNavBack( Panel *first )
+{
+ if ( !m_NavBack && m_sNavBackName.Length() > 0 )
+ {
+ Panel *pParent = GetParent();
+ const char *pName = m_sNavBackName.String();
+ while ( pParent && pName[ 0 ] == '<' )
+ {
+ pParent = pParent->GetParent();
+ pName++;
+ }
+
+ if ( !pParent )
+ {
+ return NULL;
+ }
+
+ Panel *foundPanel = pParent->FindChildByName( pName );
+ if ( foundPanel )
+ {
+ m_NavBack = foundPanel;
+ }
+ }
+
+ vgui::Panel* nextPanel = m_NavBack;
+ if ( m_NavBack && m_NavBack != first && !m_NavBack->IsVisible() )
+ {
+ Panel *firstPanel = first == NULL ? this : first;
+ nextPanel = nextPanel->GetNavBack( firstPanel );
+ }
+
+ return nextPanel;
+}
+
+vgui::Panel* Panel::GetNavUpPanel()
+{
+ return m_NavUp;
+}
+
+vgui::Panel* Panel::GetNavDownPanel()
+{
+ return m_NavDown;
+}
+
+vgui::Panel* Panel::GetNavLeftPanel()
+{
+ return m_NavLeft;
+}
+
+vgui::Panel* Panel::GetNavRightPanel()
+{
+ return m_NavRight;
+}
+
+vgui::Panel* Panel::GetNavToRelayPanel()
+{
+ return m_NavToRelay;
+}
+
+vgui::Panel* Panel::GetNavActivatePanel()
+{
+ return m_NavActivate;
+}
+
+vgui::Panel* Panel::GetNavBackPanel()
+{
+ return m_NavBack;
+}
+
+void Panel::SetConsoleStylePanel( bool bConsoleStyle )
+{
+ m_bIsConsoleStylePanel = bConsoleStyle;
+}
+
+bool Panel::IsConsoleStylePanel() const
+{
+ return m_bIsConsoleStylePanel;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Utility class for handling message map allocation
+//-----------------------------------------------------------------------------
+class CPanelMessageMapDictionary
+{
+public:
+ CPanelMessageMapDictionary() : m_PanelMessageMapPool( sizeof(PanelMessageMap), 32, CUtlMemoryPool::GROW_FAST, "CPanelMessageMapDictionary::m_PanelMessageMapPool" )
+ {
+ m_MessageMaps.RemoveAll();
+ }
+
+ PanelMessageMap *FindOrAddPanelMessageMap( char const *className );
+ PanelMessageMap *FindPanelMessageMap( char const *className );
+private:
+
+ struct PanelMessageMapDictionaryEntry
+ {
+ PanelMessageMap *map;
+ };
+
+ char const *StripNamespace( char const *className );
+
+ CUtlDict< PanelMessageMapDictionaryEntry, int > m_MessageMaps;
+ CUtlMemoryPool m_PanelMessageMapPool;
+};
+
+
+char const *CPanelMessageMapDictionary::StripNamespace( char const *className )
+{
+ if ( !strnicmp( className, "vgui::", 6 ) )
+ {
+ return className + 6;
+ }
+ return className;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Find but don't add mapping
+//-----------------------------------------------------------------------------
+PanelMessageMap *CPanelMessageMapDictionary::FindPanelMessageMap( char const *className )
+{
+ int lookup = m_MessageMaps.Find( StripNamespace( className ) );
+ if ( lookup != m_MessageMaps.InvalidIndex() )
+ {
+ return m_MessageMaps[ lookup ].map;
+ }
+ return NULL;
+}
+
+#include <tier0/memdbgoff.h>
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+PanelMessageMap *CPanelMessageMapDictionary::FindOrAddPanelMessageMap( char const *className )
+{
+ PanelMessageMap *map = FindPanelMessageMap( className );
+ if ( map )
+ return map;
+
+ PanelMessageMapDictionaryEntry entry;
+ // use the alloc in place method of new
+ entry.map = new (m_PanelMessageMapPool.Alloc(sizeof(PanelMessageMap))) PanelMessageMap;
+ Construct(entry.map);
+ m_MessageMaps.Insert( StripNamespace( className ), entry );
+ return entry.map;
+}
+#include <tier0/memdbgon.h>
+
+#if defined( VGUI_USEKEYBINDINGMAPS )
+//-----------------------------------------------------------------------------
+// Purpose: Utility class for handling keybinding map allocation
+//-----------------------------------------------------------------------------
+class CPanelKeyBindingMapDictionary
+{
+public:
+ CPanelKeyBindingMapDictionary() : m_PanelKeyBindingMapPool( sizeof(PanelKeyBindingMap), 32, CUtlMemoryPool::GROW_FAST, "CPanelKeyBindingMapDictionary::m_PanelKeyBindingMapPool" )
+ {
+ m_MessageMaps.RemoveAll();
+ }
+
+ PanelKeyBindingMap *FindOrAddPanelKeyBindingMap( char const *className );
+ PanelKeyBindingMap *FindPanelKeyBindingMap( char const *className );
+private:
+
+ struct PanelKeyBindingMapDictionaryEntry
+ {
+ PanelKeyBindingMap *map;
+ };
+
+ char const *StripNamespace( char const *className );
+
+ CUtlDict< PanelKeyBindingMapDictionaryEntry, int > m_MessageMaps;
+ CUtlMemoryPool m_PanelKeyBindingMapPool;
+};
+
+
+char const *CPanelKeyBindingMapDictionary::StripNamespace( char const *className )
+{
+ if ( !strnicmp( className, "vgui::", 6 ) )
+ {
+ return className + 6;
+ }
+ return className;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Find but don't add mapping
+//-----------------------------------------------------------------------------
+PanelKeyBindingMap *CPanelKeyBindingMapDictionary::FindPanelKeyBindingMap( char const *className )
+{
+ int lookup = m_MessageMaps.Find( StripNamespace( className ) );
+ if ( lookup != m_MessageMaps.InvalidIndex() )
+ {
+ return m_MessageMaps[ lookup ].map;
+ }
+ return NULL;
+}
+
+#include <tier0/memdbgoff.h>
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+PanelKeyBindingMap *CPanelKeyBindingMapDictionary::FindOrAddPanelKeyBindingMap( char const *className )
+{
+ PanelKeyBindingMap *map = FindPanelKeyBindingMap( className );
+ if ( map )
+ return map;
+
+ PanelKeyBindingMapDictionaryEntry entry;
+ // use the alloc in place method of new
+ entry.map = new (m_PanelKeyBindingMapPool.Alloc(sizeof(PanelKeyBindingMap))) PanelKeyBindingMap;
+ Construct(entry.map);
+ m_MessageMaps.Insert( StripNamespace( className ), entry );
+ return entry.map;
+}
+
+#include <tier0/memdbgon.h>
+
+CPanelKeyBindingMapDictionary& GetPanelKeyBindingMapDictionary()
+{
+ static CPanelKeyBindingMapDictionary dictionary;
+ return dictionary;
+}
+
+#endif // VGUI_USEKEYBINDINGMAPS
+
+CPanelMessageMapDictionary& GetPanelMessageMapDictionary()
+{
+ static CPanelMessageMapDictionary dictionary;
+ return dictionary;
+}
+
+namespace vgui
+{
+
+ //-----------------------------------------------------------------------------
+ // Purpose:
+ //-----------------------------------------------------------------------------
+ PanelMessageMap *FindOrAddPanelMessageMap( char const *className )
+ {
+ return GetPanelMessageMapDictionary().FindOrAddPanelMessageMap( className );
+ }
+
+ //-----------------------------------------------------------------------------
+ // Purpose: Find but don't add mapping
+ //-----------------------------------------------------------------------------
+ PanelMessageMap *FindPanelMessageMap( char const *className )
+ {
+ return GetPanelMessageMapDictionary().FindPanelMessageMap( className );
+ }
+
+#if defined( VGUI_USEKEYBINDINGMAPS )
+ CPanelKeyBindingMapDictionary& GetPanelKeyBindingMapDictionary()
+ {
+ static CPanelKeyBindingMapDictionary dictionary;
+ return dictionary;
+ }
+ //-----------------------------------------------------------------------------
+ // Purpose:
+ //-----------------------------------------------------------------------------
+ PanelKeyBindingMap *FindOrAddPanelKeyBindingMap( char const *className )
+ {
+ return GetPanelKeyBindingMapDictionary().FindOrAddPanelKeyBindingMap( className );
+ }
+
+ //-----------------------------------------------------------------------------
+ // Purpose: Find but don't add mapping
+ //-----------------------------------------------------------------------------
+ PanelKeyBindingMap *FindPanelKeyBindingMap( char const *className )
+ {
+ return GetPanelKeyBindingMapDictionary().FindPanelKeyBindingMap( className );
+ }
+#endif // VGUI_USEKEYBINDINGMAPS
+
+SortedPanel_t::SortedPanel_t( Panel *panel )
+{
+ pPanel = panel; pButton = dynamic_cast< Button* >( panel );
+}
+
+
+void VguiPanelGetSortedChildPanelList( Panel *pParentPanel, void *pSortedPanels )
+{
+ CUtlSortVector< SortedPanel_t, CSortedPanelYLess > *pList = reinterpret_cast< CUtlSortVector< SortedPanel_t, CSortedPanelYLess >* >( pSortedPanels );
+
+ for ( int i = 0; i < pParentPanel->GetChildCount(); i++ )
+ {
+ // perform auto-layout on the child panel
+ Panel *pPanel = pParentPanel->GetChild( i );
+ if ( !pPanel || !pPanel->IsVisible() )
+ continue;
+
+ pList->Insert( SortedPanel_t( static_cast< Panel* >( pPanel ) ) );
+ }
+}
+
+void VguiPanelGetSortedChildButtonList( Panel *pParentPanel, void *pSortedPanels, char *pchFilter /*= NULL*/, int nFilterType /*= 0*/ )
+{
+ CUtlSortVector< SortedPanel_t, CSortedPanelYLess > *pList = reinterpret_cast< CUtlSortVector< SortedPanel_t, CSortedPanelYLess >* >( pSortedPanels );
+
+ for ( int i = 0; i < pParentPanel->GetChildCount(); i++ )
+ {
+ // perform auto-layout on the child panel
+ Button *pPanel = dynamic_cast< Button* >( pParentPanel->GetChild( i ) );
+ if ( !pPanel || !pPanel->IsVisible() )
+ continue;
+
+ if ( pchFilter && pchFilter[ 0 ] != '\0' )
+ {
+ char szBuff[ 128 ];
+ pPanel->GetText( szBuff, sizeof( szBuff ) );
+
+ // Prefix
+ if ( nFilterType == 0 )
+ {
+ if ( !StringHasPrefix( szBuff, pchFilter ) )
+ {
+ continue;
+ }
+ }
+ // Substring
+ else if ( nFilterType == 1 )
+ {
+ if ( V_strstr( szBuff, pchFilter ) == NULL )
+ {
+ continue;
+ }
+ }
+ }
+
+ pList->Insert( SortedPanel_t( pPanel ) );
+ }
+}
+
+int VguiPanelNavigateSortedChildButtonList( void *pSortedPanels, int nDir )
+{
+ CUtlSortVector< SortedPanel_t, CSortedPanelYLess > *pList = reinterpret_cast< CUtlSortVector< SortedPanel_t, CSortedPanelYLess >* >( pSortedPanels );
+
+ if ( pList->Count() <= 0 )
+ return -1;
+
+ if ( nDir != 0 )
+ {
+ int nArmed = -1;
+ for ( int i = 0; i < pList->Count(); i++ )
+ {
+ if ( (*pList)[ i ].pButton->IsArmed() )
+ {
+ nArmed = i;
+ break;
+ }
+ }
+
+ if ( nArmed == -1 )
+ {
+ (*pList)[ 0 ].pButton->SetArmed( true );
+ return 0;
+ }
+ else
+ {
+ int nNewArmed = clamp( nArmed + nDir, 0, pList->Count() - 1 );
+ if ( nNewArmed != nArmed )
+ {
+ (*pList)[ nArmed ].pButton->SetArmed( false );
+ }
+
+ (*pList)[ nNewArmed ].pButton->RequestFocus();
+ (*pList)[ nNewArmed ].pButton->SetArmed( true );
+
+ return nNewArmed;
+ }
+ }
+
+ return -1;
+}
+
+}