mirror of
https://github.com/nillerusr/source-engine.git
synced 2025-05-02 10:18:07 +00:00
325 lines
12 KiB
C++
325 lines
12 KiB
C++
|
|
#include "gamepadui_button.h"
|
|
#include "gamepadui_frame.h"
|
|
#include "gamepadui_scroll.h"
|
|
#include "gamepadui_interface.h"
|
|
#include "gamepadui_image.h"
|
|
|
|
#include "ienginevgui.h"
|
|
#include "vgui/ILocalize.h"
|
|
#include "vgui/ISurface.h"
|
|
#include "vgui/IVGui.h"
|
|
#include "fmtstr.h"
|
|
|
|
#include "vgui_controls/ComboBox.h"
|
|
#include "vgui_controls/ImagePanel.h"
|
|
#include "vgui_controls/ScrollBar.h"
|
|
|
|
#include "KeyValues.h"
|
|
#include "filesystem.h"
|
|
|
|
#include "tier0/memdbgon.h"
|
|
|
|
class GamepadUIAchievement;
|
|
|
|
class GamepadUIAchievementsPanel : public GamepadUIFrame
|
|
{
|
|
DECLARE_CLASS_SIMPLE( GamepadUIAchievementsPanel, GamepadUIFrame );
|
|
|
|
public:
|
|
GamepadUIAchievementsPanel( vgui::Panel *pParent, const char* pPanelName );
|
|
|
|
void UpdateGradients() OVERRIDE;
|
|
|
|
void OnThink() OVERRIDE;
|
|
void OnCommand( char const* pCommand ) OVERRIDE;
|
|
|
|
MESSAGE_FUNC_HANDLE( OnGamepadUIButtonNavigatedTo, "OnGamepadUIButtonNavigatedTo", button );
|
|
|
|
void LayoutAchievementPanels();
|
|
|
|
void OnMouseWheeled( int nDelta ) OVERRIDE;
|
|
|
|
private:
|
|
CUtlVector< GamepadUIAchievement* > m_pAchievementPanels;
|
|
|
|
GamepadUIScrollState m_ScrollState;
|
|
|
|
int m_nTotalAchievements = 0;
|
|
int m_nUnlockedAchievements = 0;
|
|
|
|
GAMEPADUI_PANEL_PROPERTY( float, m_AchievementsFade, "Achievements.Fade", "0", SchemeValueTypes::ProportionalFloat );
|
|
GAMEPADUI_PANEL_PROPERTY( float, m_AchievementsOffsetX, "Achievements.OffsetX", "0", SchemeValueTypes::ProportionalFloat );
|
|
GAMEPADUI_PANEL_PROPERTY( float, m_AchievementsOffsetY, "Achievements.OffsetY", "0", SchemeValueTypes::ProportionalFloat );
|
|
GAMEPADUI_PANEL_PROPERTY( float, m_flAchievementsSpacing, "Achievements.Spacing", "0", SchemeValueTypes::ProportionalFloat );
|
|
};
|
|
|
|
class GamepadUIAchievement : public GamepadUIButton
|
|
{
|
|
public:
|
|
DECLARE_CLASS_SIMPLE( GamepadUIAchievement, GamepadUIButton );
|
|
|
|
GamepadUIAchievement( vgui::Panel* pParent, vgui::Panel* pActionSignalTarget, const char* pSchemeFile, const char* pCommand, const char* pText, const char* pDescription, const char *pChapterImage )
|
|
: BaseClass( pParent, pActionSignalTarget, pSchemeFile, pCommand, pText, pDescription )
|
|
, m_Image( pChapterImage )
|
|
{
|
|
}
|
|
|
|
GamepadUIAchievement( vgui::Panel* pParent, vgui::Panel* pActionSignalTarget, const char* pSchemeFile, const char* pCommand, const wchar* pText, const wchar* pDescription, const char *pChapterImage )
|
|
: BaseClass( pParent, pActionSignalTarget, pSchemeFile, pCommand, pText, pDescription )
|
|
, m_Image( pChapterImage )
|
|
{
|
|
}
|
|
|
|
void ApplySchemeSettings( vgui::IScheme* pScheme ) OVERRIDE
|
|
{
|
|
BaseClass::ApplySchemeSettings( pScheme );
|
|
|
|
m_hProgressFont = pScheme->GetFont( "Button.Progress.Font", true );
|
|
}
|
|
|
|
void Paint() OVERRIDE
|
|
{
|
|
int x, y, w, t;
|
|
GetBounds( x, y, w, t );
|
|
|
|
PaintButton();
|
|
|
|
vgui::surface()->DrawSetColor( m_colProgressColor );
|
|
vgui::surface()->DrawFilledRect( 0, GetDrawHeight() - m_flProgressHeight, m_flWidth * m_flProgress, GetDrawHeight() );
|
|
|
|
if ( m_nGoal > 1 && m_flProgress > 0.0f )
|
|
{
|
|
vgui::surface()->DrawSetColor( m_colUnprogressColor );
|
|
vgui::surface()->DrawFilledRect( m_flWidth * m_flProgress, GetDrawHeight() - m_flProgressHeight, m_flWidth, GetDrawHeight() );
|
|
}
|
|
|
|
vgui::surface()->DrawSetColor( Color( 255, 255, 255, 255 ) );
|
|
vgui::surface()->DrawSetTexture( m_Image );
|
|
int nImageSize = m_flHeight - m_flIconInset * 2;
|
|
vgui::surface()->DrawTexturedRect( m_flIconInset, m_flIconInset, m_flIconInset + nImageSize, m_flIconInset + nImageSize );
|
|
vgui::surface()->DrawSetTexture( 0 );
|
|
|
|
PaintText();
|
|
|
|
if ( m_nGoal > 1 )
|
|
{
|
|
wchar_t wcsProgress[32];
|
|
int nLength = V_swprintf_safe( wcsProgress, L"%d/%d", m_nCount, m_nGoal );
|
|
vgui::surface()->DrawSetTextColor( m_colTextColor );
|
|
vgui::surface()->DrawSetTextFont( m_hProgressFont );
|
|
|
|
int32 textSizeX = 0, textSizeY = 0;
|
|
vgui::surface()->GetTextSize( m_hProgressFont, wcsProgress, textSizeX, textSizeY );
|
|
int textPosX = m_flWidth - textSizeX - m_flProgressOffsetX;
|
|
int textPosY = GetDrawHeight() / 2 - textSizeY / 2;
|
|
|
|
vgui::surface()->DrawSetTextPos( textPosX, textPosY );
|
|
vgui::surface()->DrawPrintText( wcsProgress, nLength );
|
|
}
|
|
}
|
|
|
|
void SetProgress( bool bAchieved, int nCount, int nGoal )
|
|
{
|
|
m_nCount = nCount;
|
|
m_nGoal = nGoal;
|
|
|
|
if (bAchieved)
|
|
{
|
|
m_flProgress = 1.0f;
|
|
m_nCount = m_nGoal;
|
|
}
|
|
else
|
|
m_flProgress = min( float( nCount ) / float( nGoal ), 1.0f );
|
|
}
|
|
|
|
private:
|
|
GamepadUIImage m_Image;
|
|
|
|
float m_flProgress = 0.0f;
|
|
int m_nCount = 0;
|
|
int m_nGoal = 0;
|
|
|
|
vgui::HFont m_hProgressFont = vgui::INVALID_FONT;
|
|
|
|
GAMEPADUI_PANEL_PROPERTY( Color, m_colProgressColor, "Button.Background.Progress", "255 0 0 255", SchemeValueTypes::Color );
|
|
GAMEPADUI_PANEL_PROPERTY( Color, m_colUnprogressColor, "Button.Background.Unprogress", "255 0 0 255", SchemeValueTypes::Color );
|
|
|
|
GAMEPADUI_PANEL_PROPERTY( float, m_flProgressHeight, "Button.Progress.Height", "1", SchemeValueTypes::ProportionalFloat );
|
|
GAMEPADUI_PANEL_PROPERTY( float, m_flIconInset, "Button.Icon.Inset", "0", SchemeValueTypes::ProportionalFloat );
|
|
GAMEPADUI_PANEL_PROPERTY( float, m_flProgressOffsetX, "Button.Progress.OffsetX", "0", SchemeValueTypes::ProportionalFloat );
|
|
};
|
|
|
|
GamepadUIAchievementsPanel::GamepadUIAchievementsPanel( vgui::Panel *pParent, const char* pPanelName ) : BaseClass( pParent, pPanelName )
|
|
{
|
|
vgui::HScheme hScheme = vgui::scheme()->LoadSchemeFromFileEx( GamepadUI::GetInstance().GetSizingVPanel(), GAMEPADUI_DEFAULT_PANEL_SCHEME, "SchemePanel" );
|
|
SetScheme( hScheme );
|
|
|
|
GetFrameTitle() = GamepadUIString( "#GameUI_Achievements_Title" );
|
|
SetFooterButtons( FooterButtons::Back );
|
|
|
|
Activate();
|
|
|
|
GamepadUI::GetInstance().GetAchievementMgr()->EnsureGlobalStateLoaded();
|
|
int nAllAchievements = GamepadUI::GetInstance().GetAchievementMgr()->GetAchievementCount();
|
|
for ( int i = 0; i < nAllAchievements; i++ )
|
|
{
|
|
IAchievement *pCurAchievement = GamepadUI::GetInstance().GetAchievementMgr()->GetAchievementByIndex( i );
|
|
if ( !pCurAchievement )
|
|
continue;
|
|
|
|
if ( pCurAchievement->IsAchieved() )
|
|
m_nUnlockedAchievements++;
|
|
|
|
// Don't show hidden achievements if not achieved.
|
|
if ( pCurAchievement->ShouldHideUntilAchieved() && !pCurAchievement->IsAchieved() )
|
|
continue;
|
|
|
|
char szIconName[MAX_PATH];
|
|
V_sprintf_safe( szIconName, "gamepadui/achievements/%s%s.vmt", pCurAchievement->GetName(), pCurAchievement->IsAchieved() ? "" : "_bw" );
|
|
|
|
char szMaterialName[MAX_PATH];
|
|
V_sprintf_safe( szMaterialName, "materials/%s", szIconName );
|
|
if ( !g_pFullFileSystem->FileExists( szMaterialName ) )
|
|
V_sprintf_safe( szIconName, "vgui/achievements/%s%s.vmt", pCurAchievement->GetName(), pCurAchievement->IsAchieved() ? "" : "_bw" );
|
|
|
|
V_sprintf_safe( szMaterialName, "materials/%s", szIconName );
|
|
if ( !g_pFullFileSystem->FileExists( szMaterialName ) )
|
|
V_strcpy_safe( szIconName, "vgui/hud/icon_locked.vmt" );
|
|
|
|
auto pAchievementPanel = new GamepadUIAchievement(
|
|
this, this,
|
|
GAMEPADUI_RESOURCE_FOLDER "schemeachievement.res",
|
|
"",
|
|
ACHIEVEMENT_LOCALIZED_NAME( pCurAchievement ),
|
|
ACHIEVEMENT_LOCALIZED_DESC( pCurAchievement ),
|
|
szIconName );
|
|
pAchievementPanel->SetProgress( pCurAchievement->IsAchieved(), pCurAchievement->GetCount(), pCurAchievement->GetGoal() );
|
|
pAchievementPanel->SetPriority( m_nTotalAchievements );
|
|
m_pAchievementPanels.AddToTail( pAchievementPanel );
|
|
|
|
m_nTotalAchievements++;
|
|
}
|
|
|
|
if ( m_pAchievementPanels.Count() )
|
|
m_pAchievementPanels[0]->NavigateTo();
|
|
|
|
for ( int i = 1; i < m_pAchievementPanels.Count(); i++ )
|
|
{
|
|
m_pAchievementPanels[i]->SetNavUp( m_pAchievementPanels[i - 1] );
|
|
m_pAchievementPanels[i - 1]->SetNavDown( m_pAchievementPanels[i] );
|
|
}
|
|
|
|
UpdateGradients();
|
|
}
|
|
|
|
void GamepadUIAchievementsPanel::UpdateGradients()
|
|
{
|
|
const float flTime = GamepadUI::GetInstance().GetTime();
|
|
GamepadUI::GetInstance().GetGradientHelper()->ResetTargets( flTime );
|
|
GamepadUI::GetInstance().GetGradientHelper()->SetTargetGradient( GradientSide::Up, { 1.0f, 1.0f }, flTime );
|
|
GamepadUI::GetInstance().GetGradientHelper()->SetTargetGradient( GradientSide::Down, { 1.0f, 0.5f }, flTime );
|
|
}
|
|
|
|
void GamepadUIAchievementsPanel::OnThink()
|
|
{
|
|
BaseClass::OnThink();
|
|
|
|
LayoutAchievementPanels();
|
|
}
|
|
|
|
void GamepadUIAchievementsPanel::OnGamepadUIButtonNavigatedTo( vgui::VPANEL button )
|
|
{
|
|
GamepadUIButton *pButton = dynamic_cast< GamepadUIButton * >( vgui::ipanel()->GetPanel( button, GetModuleName() ) );
|
|
if ( pButton )
|
|
{
|
|
if ( pButton->GetAlpha() != 255 )
|
|
{
|
|
int nParentW, nParentH;
|
|
GetParent()->GetSize( nParentW, nParentH );
|
|
|
|
int nX, nY;
|
|
pButton->GetPos( nX, nY );
|
|
|
|
int nTargetY = pButton->GetPriority() * (pButton->m_flHeightAnimationValue[ButtonStates::Out] + m_flAchievementsSpacing);
|
|
|
|
if ( nY < nParentH / 2 )
|
|
{
|
|
nTargetY += nParentH - m_AchievementsOffsetY;
|
|
// Add a bit of spacing to make this more visually appealing :)
|
|
nTargetY -= m_flAchievementsSpacing;
|
|
}
|
|
else
|
|
{
|
|
nTargetY += pButton->GetMaxHeight();
|
|
// Add a bit of spacing to make this more visually appealing :)
|
|
nTargetY += (pButton->GetMaxHeight() / 2) + 2 * m_flAchievementsSpacing;
|
|
}
|
|
|
|
|
|
m_ScrollState.SetScrollTarget( nTargetY - ( nParentH - m_AchievementsOffsetY ), GamepadUI::GetInstance().GetTime() );
|
|
}
|
|
}
|
|
}
|
|
|
|
void GamepadUIAchievementsPanel::LayoutAchievementPanels()
|
|
{
|
|
int nParentW, nParentH;
|
|
GetParent()->GetSize( nParentW, nParentH );
|
|
|
|
float flScrollClamp = 0.0f;
|
|
for ( int i = 0; i < m_pAchievementPanels.Count(); i++ )
|
|
{
|
|
int size = ( m_pAchievementPanels[i]->GetTall() + m_flAchievementsSpacing );
|
|
|
|
if ( i < m_pAchievementPanels.Count() - 2 )
|
|
flScrollClamp += size;
|
|
}
|
|
|
|
m_ScrollState.UpdateScrollBounds( 0.0f, flScrollClamp );
|
|
|
|
int previousSizes = 0;
|
|
for ( int i = 0; i < m_pAchievementPanels.Count(); i++ )
|
|
{
|
|
int tall = m_pAchievementPanels[i]->GetTall();
|
|
int size = ( tall + m_flAchievementsSpacing );
|
|
|
|
int y = m_AchievementsOffsetY + previousSizes - m_ScrollState.GetScrollProgress();
|
|
int fade = 255;
|
|
if ( y < m_AchievementsOffsetY )
|
|
fade = ( 1.0f - clamp( -( y - m_AchievementsOffsetY ) / m_AchievementsFade, 0.0f, 1.0f ) ) * 255.0f;
|
|
if ( y > nParentH - m_AchievementsFade )
|
|
fade = ( 1.0f - clamp(( y - ( nParentH - m_AchievementsFade - size ) ) / m_AchievementsFade, 0.0f, 1.0f ) ) * 255.0f;
|
|
if ( m_pAchievementPanels[i]->HasFocus() && fade != 0 )
|
|
fade = 255;
|
|
m_pAchievementPanels[i]->SetAlpha( fade );
|
|
m_pAchievementPanels[i]->SetPos( m_AchievementsOffsetX, y );
|
|
m_pAchievementPanels[i]->SetVisible( true );
|
|
previousSizes += size;
|
|
}
|
|
|
|
m_ScrollState.UpdateScrolling( 2.0f, GamepadUI::GetInstance().GetTime() );
|
|
}
|
|
|
|
void GamepadUIAchievementsPanel::OnCommand( char const* pCommand )
|
|
{
|
|
if ( !V_strcmp( pCommand, "action_back" ) )
|
|
{
|
|
Close();
|
|
}
|
|
else
|
|
{
|
|
BaseClass::OnCommand( pCommand );
|
|
}
|
|
}
|
|
|
|
void GamepadUIAchievementsPanel::OnMouseWheeled( int nDelta )
|
|
{
|
|
m_ScrollState.OnMouseWheeled( nDelta * 160.0f, GamepadUI::GetInstance().GetTime() );
|
|
}
|
|
|
|
CON_COMMAND( gamepadui_openachievementsdialog, "" )
|
|
{
|
|
new GamepadUIAchievementsPanel( GamepadUI::GetInstance().GetBasePanel(), "AchievementsPanel" );
|
|
}
|