diff options
Diffstat (limited to 'mp/src/vgui2/vgui_controls/Panel.cpp')
| -rw-r--r-- | mp/src/vgui2/vgui_controls/Panel.cpp | 170 |
1 files changed, 163 insertions, 7 deletions
diff --git a/mp/src/vgui2/vgui_controls/Panel.cpp b/mp/src/vgui2/vgui_controls/Panel.cpp index 499296d9..5291c437 100644 --- a/mp/src/vgui2/vgui_controls/Panel.cpp +++ b/mp/src/vgui2/vgui_controls/Panel.cpp @@ -40,6 +40,7 @@ #include "mempool.h" #include "filesystem.h" #include "tier0/icommandline.h" +#include "tier0/minidump.h" #include "tier0/vprof.h" @@ -50,7 +51,38 @@ using namespace vgui; #define TRIPLE_PRESS_MSEC 300 +const char *g_PinCornerStrings [] = +{ + "PIN_TOPLEFT", + "PIN_TOPRIGHT", + "PIN_BOTTOMLEFT", + "PIN_BOTTOMRIGHT", + + "PIN_CENTER_TOP", + "PIN_CENTER_RIGHT", + "PIN_CENTER_BOTTOM", + "PIN_CENTER_LEFT", +}; +COMPILE_TIME_ASSERT( Panel::PIN_LAST == ARRAYSIZE( g_PinCornerStrings ) ); + +static const char *COM_GetModDirectory() +{ + static char modDir[MAX_PATH]; + if ( Q_strlen( modDir ) == 0 ) + { + const char *gamedir = CommandLine()->ParmValue("-game", CommandLine()->ParmValue( "-defaultgamedir", "hl2" ) ); + Q_strncpy( modDir, gamedir, sizeof(modDir) ); + if ( strchr( modDir, '/' ) || strchr( modDir, '\\' ) ) + { + Q_StripLastDir( modDir, sizeof(modDir) ); + int dirlen = Q_strlen( modDir ); + Q_strncpy( modDir, gamedir + dirlen, sizeof(modDir) - dirlen ); + } + } + + return modDir; +} extern int GetBuildModeDialogCount(); static char *CopyString( const char *in ) @@ -64,6 +96,13 @@ static char *CopyString( const char *in ) return n; } +#ifdef STAGING_ONLY +ConVar tf_strict_mouse_up_events( "tf_strict_mouse_up_events", "0", FCVAR_ARCHIVE, "Only allow Mouse-Release events to happens on panels we also Mouse-Downed in" ); +#endif + +// Temporary convar to help debug why the MvMVictoryMannUpPanel TabContainer is sometimes way off to the left. +ConVar tf_debug_tabcontainer( "tf_debug_tabcontainer", "0", FCVAR_HIDDEN, "Spew TabContainer dimensions." ); + #if defined( VGUI_USEDRAGDROP ) //----------------------------------------------------------------------------- // Purpose: @@ -370,6 +409,8 @@ KeyBindingContextHandle_t Panel::CreateKeyBindingsContext( char const *filename, return g_KBMgr.CreateContext( filename, pathID ); } +COMPILE_TIME_ASSERT( ( MOUSE_MIDDLE - MOUSE_LEFT ) == 2 ); +Panel* Panel::m_sMousePressedPanels[] = { NULL, NULL, NULL }; //----------------------------------------------------------------------------- // Purpose: static method @@ -722,7 +763,6 @@ void Panel::Init( int x, int y, int wide, int tall ) m_bForceStereoRenderToFrameBuffer = false; } - //----------------------------------------------------------------------------- // Purpose: Destructor //----------------------------------------------------------------------------- @@ -732,7 +772,7 @@ Panel::~Panel() if ( !m_bToolTipOverridden ) { if ( m_pTooltips ) - { + { delete m_pTooltips; } } @@ -785,6 +825,13 @@ Panel::~Panel() #if defined( VGUI_USEDRAGDROP ) delete m_pDragDrop; #endif // VGUI_USEDRAGDROP + +#if defined( VGUI_PANEL_VERIFY_DELETES ) + // Zero out our vtbl pointer. This should hopefully help us catch bad guys using + // this panel after it has been deleted. + uintp *panel_vtbl = (uintp *)this; + *panel_vtbl = NULL; +#endif } //----------------------------------------------------------------------------- @@ -864,7 +911,7 @@ const char *Panel::GetClassName() //----------------------------------------------------------------------------- void Panel::SetPos(int x, int y) { - if (!CommandLine()->FindParm("-hushasserts")) + if ( !HushAsserts() ) { Assert( abs(x) < 32768 && abs(y) < 32768 ); } @@ -882,6 +929,26 @@ void Panel::GetPos(int &x, int &y) //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- +int Panel::GetXPos() +{ + int x,y; + GetPos( x, y ); + return x; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int Panel::GetYPos() +{ + int x,y; + GetPos( x, y ); + return y; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- void Panel::SetSize(int wide, int tall) { Assert( abs(wide) < 32768 && abs(tall) < 32768 ); @@ -1063,6 +1130,15 @@ void Panel::Think() OnThink(); } +void Panel::OnChildSettingsApplied( KeyValues *pInResourceData, Panel *pChild ) +{ + Panel* pParent = GetParent(); + if( pParent ) + { + pParent->OnChildSettingsApplied( pInResourceData, pChild ); + } +} + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -1577,7 +1653,6 @@ void Panel::CallParentFunction(KeyValues *message) } } - //----------------------------------------------------------------------------- // Purpose: if set to true, panel automatically frees itself when parent is deleted //----------------------------------------------------------------------------- @@ -1867,6 +1942,17 @@ void Panel::InternalMousePressed(int code) } #endif +#ifdef STAGING_ONLY + const char *pGameDir = COM_GetModDirectory(); + if ( Q_stristr( pGameDir, "tf" ) ) + { + if ( code >= MOUSE_LEFT && code <= MOUSE_MIDDLE ) + { + m_sMousePressedPanels[ code - MOUSE_LEFT ] = this; + } + } +#endif + Panel *pMouseHandler = m_hMouseEventHandler.Get(); if ( pMouseHandler ) { @@ -2001,6 +2087,26 @@ void Panel::InternalMouseReleased(int code) } } +#ifdef STAGING_ONLY + const char *pGameDir = COM_GetModDirectory(); + if ( Q_stristr( pGameDir, "tf" ) && tf_strict_mouse_up_events.GetBool() ) + { + // Only allow mouse release events to go to panels that we also + // first clicked into + if ( code >= MOUSE_LEFT && code <= MOUSE_MIDDLE ) + { + const int nIndex = code - MOUSE_LEFT; + Panel* pPressedPanel = m_sMousePressedPanels[ nIndex ]; + m_sMousePressedPanels[ nIndex ] = NULL; // Clear out pressed panel + if ( pPressedPanel != this ) + { + OnMouseMismatchedRelease( (MouseCode)code, pPressedPanel ); + return; + } + } + } +#endif + OnMouseReleased((MouseCode)code); } @@ -2951,6 +3057,10 @@ void Panel::OnMouseReleased(MouseCode code) { } +void Panel::OnMouseMismatchedRelease( MouseCode code, Panel* pPressedPanel ) +{ +} + void Panel::OnMouseWheeled(int delta) { CallParentFunction(new KeyValues("MouseWheeled", "delta", delta)); @@ -4281,6 +4391,7 @@ int Panel::ComputePos( const char *pszInput, int &nPos, const int& nSize, const const int nFlagProportionalParent = bX ? BUILDMODE_SAVE_XPOS_PROPORTIONAL_PARENT : BUILDMODE_SAVE_YPOS_PROPORTIONAL_PARENT; int nFlags = 0; + int nPosDelta = 0; if ( pszInput ) { // look for alignment flags @@ -4319,7 +4430,6 @@ int Panel::ComputePos( const char *pszInput, int &nPos, const int& nSize, const flProportion = (float)nPos / (float)nOldPos; } - int nPosDelta = 0; if ( nFlags & nFlagProportionalSlef ) { nPosDelta = nSize * flPos; @@ -4348,9 +4458,40 @@ int Panel::ComputePos( const char *pszInput, int &nPos, const int& nSize, const } } + if ( tf_debug_tabcontainer.GetBool() && !Q_stricmp( "TabContainer", GetName() ) ) + { + Msg( "TabContainer nFlags:%x nPos:%d nParentSize:%d nPosDelta:%d nSize:%d GetParent:%p (%s) pszInput:'%s'\n", + nFlags, nPos, nParentSize, nPosDelta, nSize, GetParent(), GetParent() ? GetParent()->GetName() : "??", + pszInput ? pszInput : "??" ); + } + return nFlags; } +Panel::PinCorner_e GetPinCornerFromString( const char* pszCornerName ) +{ + if ( pszCornerName == NULL ) + { + return Panel::PIN_TOPLEFT; + } + + // Optimize for all the old entries of a single digit + if ( strlen( pszCornerName ) == 1 ) + { + return (Panel::PinCorner_e)atoi( pszCornerName ); + } + + for( int i=0; i<ARRAYSIZE( g_PinCornerStrings ); ++i ) + { + if ( !Q_stricmp( g_PinCornerStrings[i], pszCornerName ) ) + { + return (Panel::PinCorner_e)i; + } + } + + return Panel::PIN_TOPLEFT; +} + //----------------------------------------------------------------------------- // Purpose: Loads panel details from the resource info //----------------------------------------------------------------------------- @@ -4622,6 +4763,19 @@ void Panel::ApplySettings(KeyValues *inResourceData) SetName(newName); } + // Automatically add an action signal target if one is specified. This allows for + // nested child buttons to add their distant parents as action signal targets. + int nActionSignalLevel = inResourceData->GetInt( "actionsignallevel", -1 ); + if ( nActionSignalLevel != -1 ) + { + Panel *pActionSignalTarget = this; + while( nActionSignalLevel-- ) + { + pActionSignalTarget = pActionSignalTarget->GetParent(); + } + AddActionSignalTarget( pActionSignalTarget ); + } + // 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 ); @@ -4640,8 +4794,8 @@ void Panel::ApplySettings(KeyValues *inResourceData) //============================================================================= 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 ); + PinCorner_e pinOurCornerToSibling = GetPinCornerFromString( inResourceData->GetString( "pin_corner_to_sibling", NULL ) ); + PinCorner_e pinSiblingCorner = GetPinCornerFromString( inResourceData->GetString( "pin_to_sibling_corner", NULL ) ); PinToSibling( pszSiblingName, pinOurCornerToSibling, pinSiblingCorner ); @@ -4680,6 +4834,8 @@ void Panel::ApplySettings(KeyValues *inResourceData) { SetKeyBoardInputEnabled( atoi( pKeyboardInputEnabled ) ); } + + OnChildSettingsApplied( inResourceData, this ); } //----------------------------------------------------------------------------- |