You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
318 lines
7.5 KiB
318 lines
7.5 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
//=======================================================================================// |
|
|
|
#include "cbase.h" |
|
#include "game_controls/slideshowpanel.h" |
|
#include "vgui/IVGui.h" |
|
#include "filesystem.h" |
|
#include "fmtstr.h" |
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
using namespace vgui; |
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
DECLARE_BUILD_FACTORY( CCrossfadableImagePanel ); |
|
DECLARE_BUILD_FACTORY( CSlideshowPanel ); |
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
CCrossfadableImagePanel::CCrossfadableImagePanel( Panel* pParent, const char *pName ) |
|
: EditablePanel( pParent, pName ), |
|
m_iSrcImg( 0 ), |
|
m_flBlend( 0.0f ), |
|
m_flBlendTime( 0.0f ), |
|
m_flStartBlendTime( 0.0f ), |
|
m_bBlending( false ) |
|
{ |
|
m_pImages[ 0 ] = new ImagePanel( this, "Image0" ); |
|
m_pImages[ 1 ] = new ImagePanel( this, "Image1" ); |
|
|
|
ivgui()->AddTickSignal( GetVPanel(), 10 ); |
|
} |
|
|
|
CCrossfadableImagePanel::~CCrossfadableImagePanel() |
|
{ |
|
ivgui()->RemoveTickSignal( GetVPanel() ); |
|
} |
|
|
|
|
|
void CCrossfadableImagePanel::ApplySettings( KeyValues *pInResourceData ) |
|
{ |
|
BaseClass::ApplySettings( pInResourceData ); |
|
} |
|
|
|
void CCrossfadableImagePanel::ApplySchemeSettings( IScheme *pScheme ) |
|
{ |
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
|
|
SrcImg()->SetTileImage( false ); |
|
DstImg()->SetTileImage( false ); |
|
} |
|
|
|
void CCrossfadableImagePanel::PerformLayout() |
|
{ |
|
BaseClass::PerformLayout(); |
|
|
|
for ( int i = 0; i < 2; ++i ) |
|
{ |
|
m_pImages[ i ]->SetBounds( 0, 0, GetWide(), GetTall() ); |
|
m_pImages[ i ]->SetVisible( true ); |
|
} |
|
} |
|
|
|
// Helper macro to perform a call on both images |
|
#define CALL_FUNC_ON_BOTH_IMAGES( _call ) \ |
|
AssertMsg( m_pImages[ 0 ], "m_pImages[ 0 ] is NULL!" ); \ |
|
AssertMsg( m_pImages[ 1 ], "m_pImages[ 1 ] is NULL!" ); \ |
|
m_pImages[0]->_call; \ |
|
m_pImages[1]->_call; |
|
|
|
void CCrossfadableImagePanel::SetShouldScaleImage( bool bState ) |
|
{ |
|
CALL_FUNC_ON_BOTH_IMAGES( SetShouldScaleImage( bState ) ); |
|
} |
|
|
|
void CCrossfadableImagePanel::SetScaleAmount( float flScale ) |
|
{ |
|
CALL_FUNC_ON_BOTH_IMAGES( SetScaleAmount( flScale ) ); |
|
} |
|
|
|
void CCrossfadableImagePanel::SetFillColor( Color c ) |
|
{ |
|
CALL_FUNC_ON_BOTH_IMAGES( SetFillColor( c ) ); |
|
} |
|
|
|
void CCrossfadableImagePanel::SetDrawColor( Color clrDrawColor ) |
|
{ |
|
CALL_FUNC_ON_BOTH_IMAGES( SetDrawColor( clrDrawColor ) ); |
|
} |
|
|
|
void CCrossfadableImagePanel::InstallMouseHandler( Panel *pHandler ) |
|
{ |
|
CALL_FUNC_ON_BOTH_IMAGES( InstallMouseHandler( pHandler ) ); |
|
} |
|
|
|
IImage *CCrossfadableImagePanel::GetImage() |
|
{ |
|
return SrcImg()->GetImage(); |
|
} |
|
|
|
const char *CCrossfadableImagePanel::GetImageName() |
|
{ |
|
return SrcImg()->GetImageName(); |
|
} |
|
|
|
float CCrossfadableImagePanel::GetScaleAmount() |
|
{ |
|
return SrcImg()->GetScaleAmount(); |
|
} |
|
|
|
bool CCrossfadableImagePanel::GetShouldScaleImage() |
|
{ |
|
return SrcImg()->GetShouldScaleImage(); |
|
} |
|
|
|
Color CCrossfadableImagePanel::GetFillColor() |
|
{ |
|
return SrcImg()->GetFillColor(); |
|
} |
|
|
|
Color CCrossfadableImagePanel::GetDrawColor() |
|
{ |
|
return SrcImg()->GetDrawColor(); |
|
} |
|
|
|
void CCrossfadableImagePanel::SetImage( IImage *pImage, float flBlendTime/*=0.0f*/ ) |
|
{ |
|
DstImg()->SetImage( pImage ); |
|
SetupImageBlend( flBlendTime ); |
|
} |
|
|
|
void CCrossfadableImagePanel::SetImage( const char *pImageName, float flBlendTime/*=0.0f*/ ) |
|
{ |
|
DstImg()->SetImage( pImageName ); |
|
SetupImageBlend( flBlendTime ); |
|
} |
|
|
|
void CCrossfadableImagePanel::SetupImageBlend( float flBlendTime ) |
|
{ |
|
m_bBlending = true; |
|
m_flBlendTime = flBlendTime; |
|
m_flStartBlendTime = gpGlobals->realtime; |
|
m_flBlend = 0.0f; |
|
} |
|
|
|
void CCrossfadableImagePanel::OnSizeChanged( int nWide, int nTall ) |
|
{ |
|
m_pImages[ 0 ]->SetSize( nWide, nTall ); |
|
m_pImages[ 1 ]->SetSize( nWide, nTall ); |
|
} |
|
|
|
void CCrossfadableImagePanel::OnTick() |
|
{ |
|
if ( m_bBlending ) |
|
{ |
|
// Compute current blend value |
|
if ( m_flBlendTime == 0.0f ) |
|
{ |
|
m_flBlend = 1.0f; |
|
} |
|
else |
|
{ |
|
float t = clamp( ( gpGlobals->realtime - m_flStartBlendTime ) / m_flBlendTime, 0.0f, 1.0f ); |
|
m_flBlend = clamp( t * t * (3 - 2*t), 0.0f, 1.0f ); // S-curve |
|
} |
|
|
|
// Set alpha channel on source image |
|
Color clrDraw; |
|
clrDraw = SrcImg()->GetDrawColor(); |
|
clrDraw[ 3 ] = ( int )( 255 * ( 1 - m_flBlend ) ); |
|
SrcImg()->SetDrawColor( clrDraw ); |
|
|
|
// Set alpha channel on destination image |
|
clrDraw = DstImg()->GetDrawColor(); |
|
clrDraw[ 3 ] = ( int )( 255 * m_flBlend ); |
|
DstImg()->SetDrawColor( clrDraw ); |
|
|
|
// If we're done, don't blend next think |
|
if ( m_flBlend >= 1.0f ) |
|
{ |
|
m_bBlending = false; |
|
m_iSrcImg = !m_iSrcImg; |
|
m_flBlend = 0.0f; |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
CSlideshowPanel::CSlideshowPanel( Panel *pParent, const char *pName ) |
|
: EditablePanel( pParent, pName ), |
|
m_iCurImg( 0 ), |
|
m_flInterval( 3.0f ), |
|
m_flTransitionLength( 0.5f ) |
|
{ |
|
m_pImagePanel = new CCrossfadableImagePanel( this, "CrossfadableImage" ); |
|
|
|
// Setup the first transition time |
|
UpdateNextTransitionTime(); |
|
|
|
// Add tick signal |
|
ivgui()->AddTickSignal( GetVPanel(), 10 ); |
|
} |
|
|
|
CSlideshowPanel::~CSlideshowPanel() |
|
{ |
|
// Remove tick signal |
|
ivgui()->RemoveTickSignal( GetVPanel() ); |
|
} |
|
|
|
void CSlideshowPanel::SetInterval( float flInterval ) |
|
{ |
|
m_flInterval = flInterval; |
|
UpdateNextTransitionTime(); |
|
} |
|
|
|
void CSlideshowPanel::SetTransitionTime( float flTransitionLength ) |
|
{ |
|
m_flTransitionLength = flTransitionLength; |
|
UpdateNextTransitionTime(); |
|
} |
|
|
|
void CSlideshowPanel::UpdateNextTransitionTime() |
|
{ |
|
m_flNextTransitionTime = gpGlobals->realtime + m_flInterval; |
|
} |
|
|
|
void CSlideshowPanel::AddImage( const char *pImageName ) |
|
{ |
|
if ( pImageName && strlen( pImageName ) > 0 ) |
|
{ |
|
AddImage( scheme()->GetImage( pImageName, m_pImagePanel->GetShouldScaleImage() ) ); |
|
} |
|
} |
|
|
|
void CSlideshowPanel::AddImage( IImage *pImage ) |
|
{ |
|
// Cache a pointer to the image |
|
m_vecImages.AddToTail( pImage ); |
|
|
|
if ( m_vecImages.Count() == 1 ) |
|
{ |
|
GetImagePanel()->SetImage( pImage ); |
|
} |
|
} |
|
|
|
void CSlideshowPanel::FillWithImages( const char *pBasePath ) |
|
{ |
|
int i = 0; |
|
while ( 1 ) |
|
{ |
|
CFmtStr fmtImagePath( "materials/vgui/%s%i.vmt", pBasePath, i ); |
|
V_FixDoubleSlashes( fmtImagePath.Access() ); |
|
if ( !g_pFullFileSystem->FileExists( fmtImagePath.Access() ) ) |
|
break; |
|
|
|
fmtImagePath.sprintf( "%s%i.vmt", pBasePath, i ); |
|
AddImage( fmtImagePath.Access() ); |
|
|
|
++i; |
|
} |
|
} |
|
|
|
void CSlideshowPanel::ApplySettings( KeyValues *pInResourceData ) |
|
{ |
|
BaseClass::ApplySettings( pInResourceData ); |
|
|
|
int iDefaultImage = pInResourceData->GetInt( "default_index", 0 ); |
|
|
|
int i = 0; |
|
while ( 1 ) |
|
{ |
|
CFmtStr fmtImageKeyName( "image_%i", i ); |
|
const char *pImagePath = pInResourceData->GetString( fmtImageKeyName.Access(), NULL ); |
|
if ( !pImagePath ) |
|
break; |
|
|
|
AddImage( pImagePath ); |
|
|
|
if ( iDefaultImage == i ) |
|
{ |
|
GetImagePanel()->SetImage( pImagePath ); |
|
} |
|
|
|
++i; |
|
} |
|
|
|
GetImagePanel()->SetSize( |
|
XRES( pInResourceData->GetInt( "wide" ) ), |
|
YRES( pInResourceData->GetInt( "tall" ) ) |
|
); |
|
|
|
GetImagePanel()->SetShouldScaleImage( pInResourceData->GetBool( "scaleImage" ) ); |
|
GetImagePanel()->SetScaleAmount( pInResourceData->GetFloat( "scaleAmount" ) ); |
|
} |
|
|
|
void CSlideshowPanel::OnSizeChanged( int nWide, int nTall ) |
|
{ |
|
GetImagePanel()->SetSize( nWide, nTall ); |
|
} |
|
|
|
void CSlideshowPanel::OnTick() |
|
{ |
|
if ( GetImageCount() > 1 && gpGlobals->realtime >= m_flNextTransitionTime ) |
|
{ |
|
// Iterate to next image |
|
m_iCurImg = ( m_iCurImg + 1 ) % GetImageCount(); |
|
|
|
// Setup new image |
|
GetImagePanel()->SetImage( m_vecImages[ m_iCurImg ], m_flTransitionLength ); |
|
|
|
// Set transition time to be the end of the blend |
|
m_flNextTransitionTime = gpGlobals->realtime + m_flInterval; |
|
} |
|
} |
|
|
|
|