diff options
Diffstat (limited to 'game/client/tf/vgui/tf_item_card_panel.cpp')
| -rw-r--r-- | game/client/tf/vgui/tf_item_card_panel.cpp | 767 |
1 files changed, 767 insertions, 0 deletions
diff --git a/game/client/tf/vgui/tf_item_card_panel.cpp b/game/client/tf/vgui/tf_item_card_panel.cpp new file mode 100644 index 0000000..0852db4 --- /dev/null +++ b/game/client/tf/vgui/tf_item_card_panel.cpp @@ -0,0 +1,767 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "cbase.h" +#include "tf_item_card_panel.h" +#include "econ_item_description.h" +#include "vgui_controls/TextImage.h" +#include "VGuiMatSurface/IMatSystemSurface.h" +#include "navigationpanel.h" +#include "IconPanel.h" +#include "vgui_controls/ScrollBar.h" +#include "vgui_controls/ScrollBarSlider.h" +#include <vgui_controls/Label.h> +#include <vgui_controls/ImagePanel.h> +#include <vgui_controls/Tooltip.h> +#include <vgui_controls/AnimationController.h> +#include "clientmode_tf.h" + +using namespace vgui; + +#ifdef STAGING_ONLY +extern ConVar tf_use_card_tooltips; +#endif // STAGING_ONLY + +//----------------------------------------------------------------------------- +// Purpose: A label that can have multiple fonts specified and will try to use +// them in order specified, using the first one that fits. +//----------------------------------------------------------------------------- +class CAutoFittingLabel : public Label +{ + DECLARE_CLASS_SIMPLE( CAutoFittingLabel, Label ); +public: + + CAutoFittingLabel( Panel *parent, const char *name ) + : Label( parent, name, (const char*)NULL ) + {} + + virtual void ApplySettings( KeyValues *inResourceData ) + { + BaseClass::ApplySettings( inResourceData ); + + KeyValues *pFonts = inResourceData->FindKey( "fonts" ); + if ( pFonts ) + { + vgui::IScheme *pScheme = scheme()->GetIScheme( GetScheme() ); + + // Get all the fonts + FOR_EACH_SUBKEY( pFonts, pFont ) + { + const HFont& font = pScheme->GetFont( pFont->GetString( "font" ), true ); + m_vecFonts.AddToTail( font ); + } + } + } + + virtual void PerformLayout() + { + BaseClass::PerformLayout(); + + SetFont( m_vecFonts.Head() ); + + // Go through all the fonts and try to find one that fits + int nIndex = 0; + GetTextImage()->ResizeImageToContentMaxWidth( GetWide() ); + while ( ( GetTextImage()->IsWrapping() || GetTextImage()->GetEllipsesPosition() ) && nIndex < m_vecFonts.Count() ) + { + SetFont( m_vecFonts[ nIndex ] ); + GetTextImage()->ResizeImageToContentMaxWidth( GetWide() ); + + ++nIndex; + } + } + +private: + + CUtlVector< HFont > m_vecFonts; +}; + +DECLARE_BUILD_FACTORY( CAutoFittingLabel ); + + +DECLARE_BUILD_FACTORY( CRepeatingContainer ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CRepeatingContainer::CRepeatingContainer( Panel *pParent, const char *pszName ) + : EditablePanel( pParent, pszName ) + , m_eLayoutMethod( METHOD_EVEN ) +{} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CRepeatingContainer::~CRepeatingContainer() +{} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CRepeatingContainer::ApplySettings( KeyValues *inResourceData ) +{ + BaseClass::ApplySettings( inResourceData ); + + KeyValues* pCommonSettings = inResourceData->FindKey( "CommonSettings" ); + KeyValues* pIndividualSettings = inResourceData->FindKey( "IndividualSettings" ); + + // Delete old panels + m_vecChildren.PurgeAndDeleteElements(); + + if ( pIndividualSettings && pCommonSettings ) + { + // Go through every individual panel + FOR_EACH_SUBKEY( pIndividualSettings, pSubKey ) + { + // Merge the individual keys onto the common keys, keeping "individual" values if there's a conflict + pSubKey->RecursiveMergeKeyValues( pCommonSettings ); + + // Create each panel + Panel *pNewPanel = CreateControlByName( pSubKey->GetString( "ControlName" ) ); + if ( pNewPanel ) + { + pNewPanel->SetParent( this ); + pNewPanel->SetBuildGroup( GetBuildGroup() ); + pNewPanel->ApplySettings( pSubKey ); + m_vecChildren.AddToTail( pNewPanel ); + } + } + } + + const char *pszSpacingMethod = inResourceData->GetString( "spacing_method", NULL ); + if ( pszSpacingMethod ) + { + // Figure out how we're going to layout all these panels + if ( FStrEq( pszSpacingMethod, "METHOD_STEP" ) ) + { + m_eLayoutMethod = METHOD_STEP; + } + else // Default to event + { + m_eLayoutMethod = METHOD_EVEN; + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CRepeatingContainer::PerformLayout() +{ + BaseClass::PerformLayout(); + + // No children? We're done. + if ( m_vecChildren.IsEmpty() ) + return; + + // Fixed step gaps + if ( m_eLayoutMethod == METHOD_STEP ) + { + FOR_EACH_VEC( m_vecChildren, i ) + { + m_vecChildren[i]->SetPos( m_iXStep * i , 0 ); + } + } + else // default METHOD_EVEN + { + // Evently spaced + int nParentWide = GetWide(); + int nTotalChildWide = 0; + + FOR_EACH_VEC( m_vecChildren, i ) + { + nTotalChildWide += m_vecChildren[i]->GetWide(); + } + + int nXStep = 0; + if ( nTotalChildWide < nParentWide ) + { + nXStep = ( nParentWide - nTotalChildWide ) / ( m_vecChildren.Count() - 1 ); + } + + int nXPos = 0; + FOR_EACH_VEC( m_vecChildren, i ) + { + m_vecChildren[i]->SetPos( nXPos, 0 ); + nXPos += m_vecChildren[i]->GetWide() + nXStep; + } + } +} + + +DECLARE_BUILD_FACTORY( CTFItemCardPanel ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CTFItemCardPanel::CTFItemCardPanel( Panel *pParent, const char *pszName ) + : BaseClass( pParent, pszName ) + , m_pItem( NULL ) + , m_bAllControlsValid( false ) + , m_bPinned( false ) + , m_pDropShadow( NULL ) + , m_pRarityBackgroundOverlay( NULL ) + , m_pCardTop( NULL ) + , m_pItemModel( NULL ) + , m_pRarityContainer( NULL ) + , m_pItemName( NULL ) + , m_pRarityName( NULL ) + , m_pInfoContainer( NULL ) + , m_pClassLabel( NULL ) + , m_pClassIconContainer( NULL ) + , m_pTypeLabel( NULL ) + , m_pTypeLabelValue( NULL ) + , m_pExteriorLabel( NULL ) + , m_pExteriorLabelValue( NULL ) + , m_pBottomContainer( NULL ) + , m_pBottomScrollingContainer( NULL ) + , m_pAttribsLabel( NULL ) + , m_pEquipSlotLabel( NULL ) +{ + m_pDropShadow = new ImagePanel( pParent, "ItemCardShadow" ); + m_pDropShadow->SetVisible( false ); + m_pDropShadow->SetAutoDelete( false ); // We'll delete this panel +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CTFItemCardPanel::~CTFItemCardPanel() +{ + m_pDropShadow->MarkForDeletion(); + m_pDropShadow = NULL; +} + +//----------------------------------------------------------------------------- +// Purpose: Do FindControl() but also verify that we got what we were looking for +//----------------------------------------------------------------------------- +template < class T > +T* CTFItemCardPanel::FindAndVerifyControl( Panel* pParent, const char* pszPanelName ) +{ + if ( !m_bAllControlsValid ) + return NULL; + + // Find the panel + T* pChild = pParent->FindControl< T >( pszPanelName, true ); + // Make sure it's still there + m_bAllControlsValid &= pChild != NULL; + + return pChild; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFItemCardPanel::ApplySchemeSettings( IScheme *pScheme ) +{ + BaseClass::ApplySchemeSettings( pScheme ); + + LoadResFileForCurrentItem(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFItemCardPanel::ApplySettings( KeyValues *inResourceData ) +{ + BaseClass::ApplySettings( inResourceData ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFItemCardPanel::PerformLayout() +{ + BaseClass::PerformLayout(); + + if ( !m_pItem ) + { + return; + } + + if ( !m_bAllControlsValid ) + { + return; + } + + m_pBottomScrollingContainer->InvalidateLayout(); + + UpdateDescription(); + UpdateModelOrIcon(); + + // Position grime + { + // Randomize based on our original item ID, if we have one. If not, just use defindex + RandomSeed( m_pItem->GetSOCData() ? m_pItem->GetSOCData()->GetOriginalID() : m_pItem->GetItemDefIndex() ); + + // Randomize X/Y + int nGrimeX = RandomInt( -abs( m_pGrime->GetWide() - GetWide() ), 0 ); + int nGrimeY = RandomInt( -abs( m_pGrime->GetTall() - GetTall() ), 0 ); + m_pGrime->SetPos( nGrimeX, nGrimeY ); + // Randomize 0,90,180,270 rotation + m_pGrime->GetImage()->SetRotation( RandomInt( 0, 3 ) ); // Have to GetImage()->SetRotation because ImagePanel::SetRotation does nothing! + } + + // Update our shadow's settings + { + m_pDropShadow->SetZPos( GetZPos() - 1 ); + m_pDropShadow->SetShouldScaleImage( true ); + m_pDropShadow->SetMouseInputEnabled( false ); + m_pDropShadow->SetImage( "item_card/standard_background_dropshadow" ); + } + +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFItemCardPanel::SetVisible( bool bVisible ) +{ + // Update the position of our external shadow panel + if ( m_bAllControlsValid ) + { + int x=0,y=0,wide,tall,xTemp,yTemp; + m_pBackground->GetBounds( xTemp, yTemp, wide, tall ); + x += xTemp; y += yTemp; + m_pMainContainer->GetPos( xTemp, yTemp ); + x += xTemp; y += yTemp; + GetPos( xTemp, yTemp ); + x += xTemp; y += yTemp; + + m_pDropShadow->SetBounds( x + m_iShadowOffset, y + m_iShadowOffset, wide * 1.15f, tall * 1.15f ); + } + + BaseClass::SetVisible( bVisible ); + + m_pDropShadow->SetVisible( bVisible ); +} + +//----------------------------------------------------------------------------- +// Purpose: Force the scrolling container to have mouse input matching the panel's +//----------------------------------------------------------------------------- +void CTFItemCardPanel::SetMouseInputEnabled( bool state ) +{ + BaseClass::SetVisible( state ); + + if ( m_bAllControlsValid ) + { + m_pBottomScrollingContainer->SetMouseInputEnabled( state ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFItemCardPanel::SetItem( CEconItemView* pItem ) +{ + m_pItem = pItem; + + // Update the panels + LoadResFileForCurrentItem(); + MakeReadyForUse(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFItemCardPanel::PinCard( bool bPin ) +{ +#ifdef STAGING_ONLY + if ( !tf_use_card_tooltips.GetBool() ) + { + return; + } +#endif // STAGING_ONLY + + bool bDiff = bPin != m_bPinned; + m_bPinned = bPin; + + if ( bDiff && bPin ) + { + g_pClientMode->GetViewportAnimationController()->CancelAnimationsForPanel( this ); + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "ItemCard_HidePinHint" ); + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "ItemCard_ShowCloseButton" ); + SetVisible( true ); + } + else if ( bDiff && !bPin ) + { + g_pClientMode->GetViewportAnimationController()->CancelAnimationsForPanel( this ); + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "ItemCard_ShowPinHint" ); + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "ItemCard_HideCloseButton" ); + SetVisible( false ); + } + + // Force mouse input + SetMouseInputEnabled( bPin ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFItemCardPanel::UpdateDescription() +{ + const GameItemDefinition_t *pItemDef = m_pItem->GetItemDefinition(); + if ( !pItemDef ) + return; + + // Itm name + m_pItemName->SetText( m_pItem->GetItemName() ); + + // If we dont have a rarity, then we assume we're an "old" item. + if ( !GetItemSchema()->GetRarityColor(pItemDef->GetRarity() ) ) + { + // Grab the item quality (ie. strange, unusual) + const char *pszQualityColorString = EconQuality_GetColorString( (EEconItemQuality)m_pItem->GetItemQuality() ); + if ( m_pItem->IsValid() && pszQualityColorString ) + { + IScheme *pScheme = scheme()->GetIScheme( GetScheme() ); + Color colorName = pScheme->GetColor( pszQualityColorString, Color( 0, 255, 0, 255 ) ); + m_pItemName->SetFgColor( colorName ); + } + } + + + // Set highlighting on the class icons + { + for ( int i = TF_FIRST_NORMAL_CLASS; i < TF_LAST_NORMAL_CLASS; i++ ) + { + CExImageButton *pExImage = dynamic_cast< CExImageButton* >( m_pClassIconContainer->GetRepeatingChild( GetRemappedMenuIndexForClass(i) - 1 ) ); + if ( pExImage ) + { + pExImage->SetSelected( pItemDef->CanBeUsedByClass( i ) ); + } + } + } + + // Set type name into the label + { + const locchar_t *locTypename = g_pVGuiLocalize->Find( pItemDef->GetItemTypeName() ); + m_pTypeLabelValue->SetText( locTypename ); + } + + const CEconItemRarityDefinition* pItemRarity = GetItemSchema()->GetRarityDefinition( pItemDef->GetRarity() ); + + // Setup the rarity color overlay + { + attrib_colors_t attribColor = ATTRIB_COL_RARITY_DEFAULT; + + if ( pItemRarity ) + { + attribColor = pItemRarity->GetAttribColor(); + } + + vgui::IScheme *pScheme = scheme()->GetIScheme( GetScheme() ); + Color color = pScheme->GetColor( GetColorNameForAttribColor( attribColor ), Color( 255, 255, 255, 255 ) ); + m_pRarityBackgroundOverlay->SetDrawColor( color ); + m_pRarityName->SetFgColor( color ); + } + + // Rarity name into the label + { + const char *pszRarityName = "#Rarity_Default"; + if ( pItemRarity ) + { + pszRarityName = pItemRarity->GetLocKey(); + } + + m_pRarityName->SetText( g_pVGuiLocalize->Find( pszRarityName ) ); + } + + enum { kAttribBufferSize = 4 * 1024 }; + wchar_t wszAttribBuffer[ kAttribBufferSize ] = L""; + + // Space out the attributes + const CEconItemDescription *pDescription = m_pItem->GetDescription(); + if ( pDescription ) + { + unsigned int unWrittenLines = 0; + for ( unsigned int i = 0; i < pDescription->GetLineCount(); i++ ) + { + const econ_item_description_line_t& line = pDescription->GetLine(i); + if ( (line.unMetaType & ( kDescLineFlag_Name ) ) == 0 ) + { + V_wcscat_safe( wszAttribBuffer, L"\n" ); // add empty lines everywhere + V_wcscat_safe( wszAttribBuffer, line.sText.Get() ); + ++unWrittenLines; + } + } + + // Get all the attributes + Assert( m_pItem->GetDescription() ); + if ( m_pAttribsLabel->GetTextImage() && m_pItem->GetDescription() ) + { + m_pAttribsLabel->SetText( wszAttribBuffer ); + + TextImage *pTextImage = m_pAttribsLabel->GetTextImage(); + Assert( pTextImage ); + + pTextImage->ClearColorChangeStream(); + + IScheme *pScheme = scheme()->GetIScheme( GetScheme() ); + + Color prevCol; + unsigned int unCurrentTextStreamIndex = 0; + for ( unsigned int i = 0; i < pDescription->GetLineCount(); i++ ) + { + const econ_item_description_line_t& line = pDescription->GetLine(i); + + // Ignore the name line, it was added above + if ( ( line.unMetaType & ( kDescLineFlag_Name ) ) != 0 ) + { + continue; + } + + Color col = pScheme->GetColor( GetColorNameForAttribColor( line.eColor ), Color( 255, 255, 255, 255 ) ); + + // Output a color change if necessary. + if ( i == 0 || prevCol != col ) + { + pTextImage->AddColorChange( col, unCurrentTextStreamIndex ); + prevCol = col; + } + + unCurrentTextStreamIndex += StringFuncs<locchar_t>::Length( line.sText.Get() ) + 1; // add one character to deal with newlines + } + + int nWide, nTall; + pTextImage->GetContentSize( nWide, nTall ); + m_pAttribsLabel->SetTall( nTall ); + } + } + + // Set equip slot + { + int nEquipSlot = pItemDef->GetDefaultLoadoutSlot(); + if ( nEquipSlot != -1 ) + { + m_pEquipSlotLabel->SetText( g_pVGuiLocalize->Find( GetItemSchema()->GetLoadoutStringsForDisplay( pItemDef->GetEquipType() )[ nEquipSlot ] ) ); + } + else + { + m_pEquipSlotLabel->SetText( "" ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFItemCardPanel::UpdateModelOrIcon() +{ + if ( !m_pItem ) + { + return; + } + + m_pItemModel->SetItem( m_pItem ); + + const char *pszModelName = m_pItem->GetPlayerDisplayModel( 0, 0 ); + if ( pszModelName ) + { + MDLHandle_t hMDL = mdlcache->FindMDL( pszModelName ); + m_pItemModel->SetMDL( hMDL, static_cast<IClientRenderable*>(m_pItem) ); + mdlcache->Release( hMDL ); // counterbalance addref from within FindMDL + m_pItemModel->SetForceModelUsage( true ); + } + else + { + m_pItemModel->SetInventoryImageType( CEmbeddedItemModelPanel::IMAGETYPE_LARGE ); + m_pItemModel->LoadInventoryImage(); + m_pItemModel->SetForceModelUsage( false ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFItemCardPanel::LoadResFileForCurrentItem() +{ + // Temp hack. New items get the new cards + const char *pszResFile = "Resource/UI/econ/ItemCardPanel_Series1.res"; + if ( m_pItem ) + { + const GameItemDefinition_t *pItemDef = m_pItem->GetItemDefinition(); + if ( pItemDef ) + { + const CEconItemRarityDefinition* pItemRarity = GetItemSchema()->GetRarityDefinition( pItemDef->GetRarity() ); + if ( pItemRarity && pItemRarity->GetDBValue() > 0 ) + { + pszResFile = "Resource/UI/econ/ItemCardPanel_Series2.res"; + } + } + } + + m_bAllControlsValid = false; + + LoadControlSettings( pszResFile ); + + m_bAllControlsValid = true; + // Grab all the controls... + m_pMainContainer = FindAndVerifyControl< EditablePanel >( this, "MainContainer" ); + m_pRarityBackgroundOverlay = FindAndVerifyControl< ImagePanel >( m_pMainContainer, "RarityBackgroundOverlay" ); + m_pBackground = FindAndVerifyControl< ImagePanel >( m_pMainContainer, "Background" ); + m_pGrime = FindAndVerifyControl< ImagePanel >( m_pMainContainer, "GrimeLayer" ); + m_pCardTop = FindAndVerifyControl< EditablePanel >( m_pMainContainer, "CardTop" ); + m_pItemModel = FindAndVerifyControl< CEmbeddedItemModelPanel >( m_pCardTop, "ItemModel" ); + m_pRarityContainer = FindAndVerifyControl< EditablePanel >( m_pMainContainer, "RarityContainer" ); + m_pItemName = FindAndVerifyControl< Label >( m_pRarityContainer, "ItemNameLabel" ); + m_pRarityName = FindAndVerifyControl< Label >( m_pRarityContainer, "ItemRarityLabel" ); + m_pClassIconContainer = FindAndVerifyControl< CRepeatingContainer >( m_pMainContainer, "ClassIconContainer" ); + m_pInfoContainer = FindAndVerifyControl< EditablePanel >( m_pMainContainer, "InfoContainer" ); + m_pClassLabel = FindAndVerifyControl< Label >( m_pInfoContainer, "ClassLabel" ); + m_pTypeLabel = FindAndVerifyControl< Label >( m_pInfoContainer, "TypeLabel" ); + m_pTypeLabelValue = FindAndVerifyControl< Label >( m_pInfoContainer, "TypeValueLabel" ); + m_pExteriorLabel = FindAndVerifyControl< Label >( m_pInfoContainer, "ExteriorLabel" ); + m_pExteriorLabelValue = FindAndVerifyControl< Label >( m_pInfoContainer, "ExteriorValueLabel" ); + m_pBottomContainer = FindAndVerifyControl< EditablePanel >( m_pMainContainer, "BottomContainer" ); + m_pBottomScrollingContainer = FindAndVerifyControl< CExScrollingEditablePanel >( m_pBottomContainer, "ScrollableBottomContainer" ); + m_pAttribsLabel = FindAndVerifyControl< Label >( m_pBottomScrollingContainer, "AttribsLabel" ); + m_pEquipSlotLabel = FindAndVerifyControl< Label >( this, "EquipSlotLabel" ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CItemCardPanelToolTip::CItemCardPanelToolTip( Panel *parent, const char *text ) +: BaseTooltip( parent, text ) +, m_pMouseOverItemPanel( NULL ) +, m_iPositioningStrategy( IPTTP_BOTTOM_SIDE ) +{ + m_hCurrentPanel = NULL; + SetTooltipDelay( 100 ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CItemCardPanelToolTip::GetPosition( itempanel_tooltippos_t iTooltipPosition, CItemModelPanel *pItemPanel, int iItemX, int iItemY, int *iXPos, int *iYPos ) +{ + switch ( iTooltipPosition ) + { + case IPTTP_LEFT: + *iXPos = ( iItemX - m_pMouseOverItemPanel->GetWide() ); + *iYPos = ( iItemY + pItemPanel->GetTall() * 0.5f ) - ( m_pMouseOverItemPanel->GetTall() * 0.5f ); + break; + case IPTTP_RIGHT: + *iXPos = ( iItemX + pItemPanel->GetWide() ); + *iYPos = ( iItemY + pItemPanel->GetTall() * 0.5f ) - ( m_pMouseOverItemPanel->GetTall() * 0.5f ); + break; + } + + *iYPos = Clamp( *iYPos, (int)YRES( -30 ), int( m_pParentPanel->GetTall() - m_pMouseOverItemPanel->GetTall() - YRES( 30 ) ) ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CItemCardPanelToolTip::ValidatePosition( CItemModelPanel *pItemPanel, int iItemX, int iItemY, int *iXPos, int *iYPos ) +{ + if ( *iXPos < 0 ) + return false; + + if ( ( *iXPos + m_pMouseOverItemPanel->GetWide() ) > m_pParentPanel->GetWide() ) + return false; + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CItemCardPanelToolTip::PerformLayout() +{ + BaseClass::PerformLayout(); + + if ( !ShouldLayout() ) + return; + + _isDirty = false; + + CItemModelPanel *pItemPanel = m_hCurrentPanel.Get(); + if ( m_pMouseOverItemPanel && pItemPanel && !m_pMouseOverItemPanel->IsPinned() ) + { + CEconItemView *pItem = pItemPanel->GetItem(); + if ( pItem ) + { + m_pMouseOverItemPanel->SetItem( pItem ); + + + int x,y; + + // If the panel is somewhere in a derived class, we need to get its position in our space + if ( pItemPanel->GetParent() != m_pMouseOverItemPanel->GetParent() ) + { + int iItemAbsX, iItemAbsY; + ipanel()->GetAbsPos( pItemPanel->GetVPanel(), iItemAbsX, iItemAbsY ); + int iParentAbsX, iParentAbsY; + ipanel()->GetAbsPos( m_pMouseOverItemPanel->GetParent()->GetVPanel(), iParentAbsX, iParentAbsY ); + + x = (iItemAbsX - iParentAbsX); + y = (iItemAbsY - iParentAbsY); + } + else + { + pItemPanel->GetPos( x, y ); + } + + int iXPos = 0; + int iYPos = 0; + + // Loop through the positions in our strategy, and hope we find a valid spot + for ( int i = 0; i < NUM_POSITIONS_PER_STRATEGY; i++ ) + { + itempanel_tooltippos_t iPos = g_iTooltipStrategies[m_iPositioningStrategy][i]; + if ( iPos != IPTTP_LEFT && iPos != IPTTP_RIGHT ) + continue; + + GetPosition( iPos, pItemPanel, x, y, &iXPos, &iYPos ); + + if ( ValidatePosition( pItemPanel, x, y, &iXPos, &iYPos ) ) + break; + } + + m_pMouseOverItemPanel->SetPos( iXPos, iYPos ); + m_pMouseOverItemPanel->SetVisible( true ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CItemCardPanelToolTip::ShowTooltip( Panel *currentPanel ) +{ + if ( m_pMouseOverItemPanel && currentPanel != m_hCurrentPanel.Get() ) + { + CItemModelPanel *pItemPanel = assert_cast<CItemModelPanel *>(currentPanel); + m_hCurrentPanel.Set( pItemPanel ); + pItemPanel->PostActionSignal( new KeyValues("ItemPanelEntered") ); + vgui::surface()->PlaySound( "ui/item_info_mouseover.wav" ); + } + BaseClass::ShowTooltip( currentPanel ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CItemCardPanelToolTip::HideTooltip() +{ + if ( m_pMouseOverItemPanel ) + { + if ( m_pMouseOverItemPanel->IsPinned() ) + return; + + m_pMouseOverItemPanel->SetVisible( false ); + } + + if ( m_hCurrentPanel ) + { + m_hCurrentPanel.Get()->PostActionSignal( new KeyValues("ItemPanelExited") ); + m_hCurrentPanel = NULL; + } +} |