2005-03-09 01:31:56 +00:00
//======== (C) Copyright 2002 Charles G. Cleveland All rights reserved. =========
//
// The copyright to the contents herein is the property of Charles G. Cleveland.
// The contents may be used and/or copied only with the written permission of
// Charles G. Cleveland, or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose:
//
// $Workfile: FadingImageLabel.cpp $
// $Date: 2002/09/09 19:46:34 $
//
//-------------------------------------------------------------------------------
// $Log: FadingImageLabel.cpp,v $
// Revision 1.16 2002/09/09 19:46:34 Flayra
// - Changes to try to make this draw properly in software
//
// Revision 1.15 2002/08/31 18:04:32 Flayra
// - Work at VALVe
//
// Revision 1.14 2002/07/23 16:52:59 Flayra
// - Added support for multiple sprite frames (for pie nodes and max sprite problem), added document headers
//
//===============================================================================
# include "ui/FadingImageLabel.h"
# include "ui/UIUtil.h"
# include "util/STLUtil.h"
# include <assert.h>
# include "cl_dll/hud.h"
# include "cl_dll/cl_util.h"
# include "common/const.h"
# include "common/com_model.h"
# include "engine/studio.h"
# include "common/entity_state.h"
# include "common/cl_entity.h"
# include "common/dlight.h"
# include "common/triangleapi.h"
# include <stdio.h>
# include <string.h>
# include <memory.h>
# include <math.h>
# include "cl_dll/studio_util.h"
# include "cl_dll/r_studioint.h"
# include "cl_dll/StudioModelRenderer.h"
# include "cl_dll/GameStudioModelRenderer.h"
extern engine_studio_api_t IEngineStudio ;
const char * kFrameIndicator = " -frame " ;
//FadingImageLabel::FadingImageLabel(const char* inImageName, int inX, int inY)/*, int inWidth, int inHeight)*/ : CImageLabel(inImageName, inX, inY, 64, 32), mTextImage("Default text")
//{
// this->Init();
//}
FadingImageLabel : : FadingImageLabel ( int inX , int inY ) /*, int inWidth, int inHeight)*/ : /*Panel(inX, inY, 64, 32),*/ mTextImage ( " Default text " )
{
this - > Init ( ) ;
this - > mImageMode = false ;
}
FadingImageLabel : : ~ FadingImageLabel ( )
{
}
void FadingImageLabel : : DoPaint ( )
{
//const float thePercentToChopOffXEdge = .1f;
//const float thePercentToChopOffYEdge = 0.0f;
int theX , theY ;
this - > getPos ( theX , theY ) ;
//if(!IEngineStudio.IsHardware())
//{
// theX += ScreenWidth/2;
// theY += ScreenHeight/2;
//}
int theWidth , theHeight ;
this - > getSize ( theWidth , theHeight ) ;
//ASSERT(this->mVisibleWidth <= theWidth);
//ASSERT(this->mVisibleHeight <= theHeight);
if ( ( this - > mVisibleWidth < = theWidth ) & & ( this - > mVisibleHeight < = theHeight ) )
{
int r , g , b , a ;
this - > getBgColor ( r , g , b , a ) ;
float theGammaSlope = gHUD . GetGammaSlope ( ) ;
r = r / theGammaSlope ;
g = g / theGammaSlope ;
b = b / theGammaSlope ;
// Don't take gamma slope into account for alpha
a = 255 - a ;
////int theXBorder = thePercentToChopOffXEdge*ScreenWidth;
////int theYBorder = thePercentToChopOffYEdge*ScreenHeight;
int theXBorder = ( theWidth - this - > mVisibleWidth ) / 2 ;
int theYBorder = ( theHeight - this - > mVisibleHeight ) / 2 ;
//vguiSimpleBox(theXBorder, theYBorder, theWidth - theXBorder*2 + theXBorder, theHeight - theYBorder*2 + theYBorder, r, g, b, a);
if ( ! this - > mImageMode )
{
//FillRGBA(theXBorder, theYBorder, theWidth - theXBorder*2, theHeight - theYBorder*2, r, g, b, a);
//int theSprite = Safe_SPR_Load("sprites/marinenode.spr");
//DrawScaledHUDSprite(theSprite, kRenderTransAdd, 1, theX, theY, theWidth, theHeight, 0);
gEngfuncs . pTriAPI - > RenderMode ( kRenderTransAlpha ) ;
gEngfuncs . pTriAPI - > CullFace ( TRI_NONE ) ;
//gEngfuncs.pTriAPI->Brightness(1);
theX = theXBorder ;
theY = theYBorder ;
theWidth = theWidth - theXBorder * 2 ;
theHeight = theHeight - theYBorder * 2 ;
// 0 = selectable, valid
// 1 = selectable, valid, current
// 2 = selectable, invalid
// 3 = selectable, invalid, current
int theFrame = 0 ;
if ( this - > GetEnabled ( ) & & this - > GetDrawHighlighted ( ) )
{
theFrame = 1 ;
}
else if ( ! this - > GetEnabled ( ) )
{
theFrame = this - > GetFadeState ( ) ? 3 : 2 ;
}
//char theFrameNumber[64];
//sprintf(theFrameNumber, "Frame %d", theFrame);
//this->mTextImage.setText(theFrameNumber);
if ( ! this - > mSprite )
{
this - > mSprite = Safe_SPR_Load ( this - > mImageName . c_str ( ) ) ;
this - > mSpriteWidth = SPR_Width ( this - > mSprite , this - > mSpriteFrame ) ;
this - > mSpriteHeight = SPR_Height ( this - > mSprite , this - > mSpriteFrame ) ;
ASSERT ( this - > mSprite > 0 ) ;
}
if ( this - > mSprite & & gEngfuncs . pTriAPI - > SpriteTexture ( ( struct model_s * ) gEngfuncs . GetSpritePointer ( this - > mSprite ) , theFrame ) )
{
gEngfuncs . pTriAPI - > Begin ( TRI_TRIANGLE_STRIP ) ;
vec3_t theVertex ;
gEngfuncs . pTriAPI - > TexCoord2f ( 0 , 1 ) ;
theVertex . x = theX ;
theVertex . y = theY + theHeight ;
theVertex . z = 0 ;
//gEngfuncs.pTriAPI->Color4ub(255, 255, 255, a);
gEngfuncs . pTriAPI - > Vertex3fv ( ( float * ) & theVertex ) ;
gEngfuncs . pTriAPI - > TexCoord2f ( 0 , 0 ) ;
theVertex . x = theX ;
theVertex . y = theY ;
//gEngfuncs.pTriAPI->Color4ub(255, 255, 255, a);
gEngfuncs . pTriAPI - > Vertex3fv ( ( float * ) & theVertex ) ;
gEngfuncs . pTriAPI - > TexCoord2f ( 1 , 1 ) ;
theVertex . x = theX + theWidth ;
theVertex . y = theY + theHeight ;
//gEngfuncs.pTriAPI->Color4ub(255, 255, 255, a);
gEngfuncs . pTriAPI - > Vertex3fv ( ( float * ) & theVertex ) ;
gEngfuncs . pTriAPI - > TexCoord2f ( 1 , 0 ) ;
theVertex . x = theX + theWidth ;
theVertex . y = theY ;
//gEngfuncs.pTriAPI->Color4ub(255, 255, 255, a);
gEngfuncs . pTriAPI - > Vertex3fv ( ( float * ) & theVertex ) ;
gEngfuncs . pTriAPI - > End ( ) ;
}
gEngfuncs . pTriAPI - > RenderMode ( kRenderNormal ) ;
}
else
{
SPR_Set ( this - > mSprite , a , a , a ) ;
int theSpriteWidth = SPR_Width ( this - > mSprite , this - > mSpriteFrame ) ;
int theSpriteHeight = SPR_Height ( this - > mSprite , this - > mSpriteFrame ) ;
//SPR_DrawAdditive(theFrame, (theWidth - theSpriteWidth)/2, (theHeight - theSpriteHeight)/2, NULL);
SPR_DrawHoles ( this - > mSpriteFrame , ( theWidth - theSpriteWidth ) / 2 , ( theHeight - theSpriteHeight ) / 2 , NULL ) ;
}
}
}
void FadingImageLabel : : FadedIn ( )
{
Panel : : setVisible ( true ) ;
}
void FadingImageLabel : : FadedOut ( )
{
Panel : : setVisible ( false ) ;
}
//vgui::Color FadingImageLabel::GetColor() const
//{
// return vgui::Color(255, 255, 255, this->GetValveAlpha());
//}
void FadingImageLabel : : getBgColor ( int & r , int & g , int & b , int & a )
{
Panel : : getBgColor ( r , g , b , a ) ;
a = this - > GetValveAlpha ( ) ;
}
void FadingImageLabel : : getBgColor ( Color & outColor )
{
Panel : : getBgColor ( outColor ) ;
int r , g , b , a ;
outColor . getColor ( r , g , b , a ) ;
a = this - > GetValveAlpha ( ) ;
outColor . setColor ( r , g , b , a ) ;
}
void FadingImageLabel : : getContentSize ( int & wide , int & tall )
{
if ( ! this - > mImageMode )
{
this - > getTextSize ( wide , tall ) ;
}
else
{
wide = this - > mSpriteWidth ;
tall = this - > mSpriteHeight ;
}
}
bool FadingImageLabel : : GetDrawHighlighted ( ) const
{
return false ;
}
bool FadingImageLabel : : GetEnabled ( ) const
{
return true ;
}
bool FadingImageLabel : : GetFadeState ( ) const
{
return this - > mFadeToVisibiltyState ;
}
void FadingImageLabel : : getTextSize ( int & wide , int & tall )
{
int theTextWidth , theTextHeight ;
this - > mTextImage . getTextSize ( theTextWidth , theTextHeight ) ;
wide = theTextWidth ;
tall = theTextHeight ;
if ( this - > mSpriteWidth > theTextWidth )
{
theTextWidth = this - > mSpriteWidth ;
}
if ( this - > mSpriteHeight > theTextHeight )
{
theTextHeight = this - > mSpriteHeight ;
}
}
int FadingImageLabel : : GetValveAlpha ( ) const
{
return this - > mValveAlpha ;
}
void FadingImageLabel : : GetVisibleSize ( int & outWidth , int & outHeight )
{
outWidth = this - > mVisibleWidth ;
outHeight = this - > mVisibleHeight ;
}
void FadingImageLabel : : Init ( )
{
// default time to fade in or out
this - > mBaseFadeTime = .3f ;
this - > mTimeToFade = this - > mBaseFadeTime ;
this - > mTimeVisChanged = - 1 ;
this - > mTimeScalar = 0.0f ;
this - > mMaxAlpha = 1.0f ;
this - > mVisibleWidth = 0 ;
this - > mVisibleHeight = 0 ;
// this needs to be set to our visibility
this - > mFadeToVisibiltyState = false ;
this - > mAlwaysDrawText = false ;
// Valve keeps alpha backwards
this - > mValveAlpha = ( this - > isVisible ( ) ? 0 : 255 ) ;
this - > mImageMode = false ;
this - > mSprite = 0 ;
this - > mSpriteWidth = this - > mSpriteHeight = 0 ;
this - > mSpriteFrame = 0 ;
}
void FadingImageLabel : : paint ( )
{
// Calculate current translucency
float theAlphaToUse = ( this - > mFadeToVisibiltyState ? this - > mTimeScalar : 1.0f - this - > mTimeScalar ) ;
// Bias in accelerated fashion for dramatic effect (maps to sin(0-pi/2) so it fades fast then slows down)
theAlphaToUse = sin ( theAlphaToUse * 3.141519 / 2.0f ) ;
// For some reason Valve thinks alpha of 255 is transparent
this - > mValveAlpha = 255 - ( int ) ( 255.0f * theAlphaToUse ) ;
//int r, g, b, a;
//theColor.getColor(r, g, b, a);
//this->setFgColor(r, g, b, a);
// Set translucency
//if(this->m_pTGA)
//{
// //this->m_pTGA->setColor(this->GetColor());
// vgui::Color theColor;
// this->getBgColor(theColor);
// //this->setBgColor(theColor);
// this->m_pTGA->setColor(theColor);
//
// //int r, g, b, a;
// //theColor.getColor(r, g, b, a);
// //this->setFgColor(r, g, b, a);
//}
//else
//{
// ASSERT(false);
//}
// Figure out whether we're in image mode or not
this - > DoPaint ( ) ;
// Draw text on top when faded in (check < 2 in case rounding makes it negative)
if ( ( this - > mValveAlpha < 2 | | this - > mAlwaysDrawText ) & & ( ! this - > mImageMode ) )
{
// Fade text out as well
Color theColor ;
this - > mTextImage . getColor ( theColor ) ;
int r , g , b , a ;
theColor . getColor ( r , g , b , a ) ;
//theColor.setColor(r, g, b, this->mValveAlpha);
//this->mTextImage.setColor(theColor);
//this->mTextImage.doPaint(this);
int theX , theY ;
this - > getPos ( theX , theY ) ;
int theWidth , theHeight ;
this - > getSize ( theWidth , theHeight ) ;
const AvHFont & theFont = gHUD . GetSmallFont ( ) ;
float theTextX = ( theWidth - theFont . GetStringWidth ( mText . c_str ( ) ) ) / 2 ;
float theTextY = ( theHeight - theFont . GetStringHeight ( ) ) / 2 ;
theFont . DrawString ( theTextX , theTextY , mText . c_str ( ) , r , g , b ) ;
}
}
void FadingImageLabel : : paintBackground ( )
{
// Do nothing, we don't draw in our bg color anymore, we only draw in FillRGBA
}
// Called
void FadingImageLabel : : RecalculateTextPosition ( )
{
int theLabelWidth , theLabelHeight ;
this - > getSize ( theLabelWidth , theLabelHeight ) ;
int theTextWidth , theTextHeight ;
this - > mTextImage . getTextSize ( theTextWidth , theTextHeight ) ;
// Center text in middle of label
if ( ( theTextWidth < = theLabelWidth ) & & ( theTextHeight < = theLabelHeight ) )
{
this - > mTextImage . setPos ( theLabelWidth / 2 - theTextWidth / 2 , theLabelHeight / 2 - theTextHeight / 2 ) ;
}
// If it can't be centered on image, align with upper left corner
else
{
this - > mTextImage . setPos ( 0 , 0 ) ;
}
// Center image now
//int theImageWidth = this->getImageWide();
//int theImageHeight = this->getImageTall();
//int theImageX = theLabelWidth/2 - theImageWidth/2;
//int theImageY = theLabelHeight/2 - theImageHeight/2;
//this->m_pTGA->setPos(theImageX, theImageY);
}
void FadingImageLabel : : SetAlwaysDrawText ( bool inState )
{
this - > mAlwaysDrawText = inState ;
}
void FadingImageLabel : : SetBaseFadeTime ( float inSeconds )
{
this - > mBaseFadeTime = inSeconds ;
}
void FadingImageLabel : : SetFadeState ( bool inNewState )
{
// if new state is different
if ( this - > mFadeToVisibiltyState ! = inNewState )
{
// set fade to state
this - > mFadeToVisibiltyState = inNewState ;
float theCurrentTime = : : gHUD . m_flTime ;
// set new fade to time in case a change was specified during a change
this - > mTimeToFade = min ( this - > mBaseFadeTime , ( theCurrentTime - this - > mTimeVisChanged ) ) ;
this - > mMaxAlpha = min ( 1.0f , ( theCurrentTime - this - > mTimeVisChanged ) / this - > mBaseFadeTime ) ;
// remember time that it was set
this - > mTimeVisChanged = theCurrentTime ;
// if new state is visible, set vgui::Panel::setVisible(true)
if ( ! this - > isVisible ( ) & & inNewState )
{
this - > FadedIn ( ) ;
}
}
}
void FadingImageLabel : : setFont ( Scheme : : SchemeFont inSchemeFont )
{
this - > mTextImage . setFont ( inSchemeFont ) ;
}
void FadingImageLabel : : setFont ( Font * inFont )
{
ASSERT ( inFont ! = NULL ) ;
this - > mTextImage . setFont ( inFont ) ;
// Sanity check
Font * theFont = this - > mTextImage . getFont ( ) ;
}
void FadingImageLabel : : setPos ( int x , int y )
{
// Don't set size smaller than we need for out text though!
Panel : : setPos ( x , y ) ;
this - > RecalculateTextPosition ( ) ;
}
void FadingImageLabel : : setSize ( int wide , int tall )
{
//int theTextWidth, theTextHeight;
//this->mTextImage.getTextSize(theTextWidth, theTextHeight);
//int theNewWidth = max(wide, theTextWidth);
//int theNewHeight = max(tall, theTextHeight);
//CImageLabel::setSize(theNewWidth, theNewHeight);
Panel : : setSize ( wide , tall ) ;
this - > RecalculateTextPosition ( ) ;
}
void FadingImageLabel : : SetSizeKeepCenter ( int inWidth , int inHeight )
{
int theX , theY ;
this - > getPos ( theX , theY ) ;
int theOldWidth , theOldHeight ;
this - > getSize ( theOldWidth , theOldHeight ) ;
// Calculate center of label
int theCenterX = theX + theOldWidth / 2 ;
int theCenterY = theY + theOldHeight / 2 ;
int theXDiff = ( theOldWidth - inWidth ) / 2 ;
int theYDiff = ( theOldHeight - inHeight ) / 2 ;
this - > setSize ( inWidth , inHeight ) ;
this - > setPos ( theX + theXDiff , theY + theYDiff ) ;
// Did it work?
int theNewX , theNewY ;
this - > getPos ( theNewX , theNewY ) ;
int theNewCenterX = theNewX + inWidth / 2 ;
int theNewCenterY = theNewY + inHeight / 2 ;
// Does the new center equal the old center?
ASSERT ( abs ( theNewCenterX - theCenterX ) < = 1 ) ;
ASSERT ( abs ( theNewCenterY - theCenterY ) < = 1 ) ;
}
void FadingImageLabel : : SetSpriteName ( const string & inSpriteName )
{
this - > mImageName = inSpriteName ;
}
void FadingImageLabel : : setText ( const char * inText )
{
//if(this->mSprite == 0)
//{
if ( * inText = = ' ! ' )
{
this - > mImageMode = true ;
this - > mTextImage . setText ( " " ) ;
this - > mText = " " ;
// If image name has '-frame' in it, then we draw a frame out of the sprite
string theImageName = string ( inText + 1 ) ;
2005-04-01 03:04:57 +00:00
size_t theIndex = theImageName . find ( kFrameIndicator ) ;
2005-03-09 01:31:56 +00:00
if ( theIndex ! = std : : string : : npos )
{
// Parse out frame number
string theFrameString = theImageName . substr ( theIndex + strlen ( kFrameIndicator ) ) ;
this - > mSpriteFrame = MakeIntFromString ( theFrameString ) ;
// Set theImageName
theImageName = theImageName . substr ( 0 , theIndex ) ;
}
this - > SetSpriteName ( theImageName ) ;
}
else
{
this - > mTextImage . setText ( inText ) ;
this - > mText = inText ;
this - > RecalculateTextPosition ( ) ;
}
//}
}
void FadingImageLabel : : setVisible ( bool inVisibility )
{
Panel : : setVisible ( inVisibility ) ;
this - > mValveAlpha = ( this - > isVisible ( ) ? 0 : 255 ) ;
}
void FadingImageLabel : : SetVisibleSize ( int inVisWidth , int inVisHeight )
{
int theWidth , theHeight ;
this - > getSize ( theWidth , theHeight ) ;
this - > mVisibleWidth = min ( inVisWidth , theWidth ) ;
this - > mVisibleHeight = min ( inVisHeight , theHeight ) ;
}
void FadingImageLabel : : setVisibleWithoutFading ( bool inNewState )
{
this - > mFadeToVisibiltyState = inNewState ;
this - > mTimeToFade = 0.0f ;
Panel : : setVisible ( inNewState ) ;
// TODO: Call FadedIn or FadedOut?
}
void FadingImageLabel : : Update ( float theCurrentTime )
{
bool theIsVisible = this - > isVisible ( ) ;
// if fade-to state different than our current state
//if((theIsVisible != this->mFadeToVisibiltyState) && (this->mTimeVisChanged != -1))
if ( this - > mTimeVisChanged ! = - 1 )
{
// set current alpha scalar depending on time since fade invoked
this - > mTimeScalar = min ( ( theCurrentTime - this - > mTimeVisChanged ) / this - > mTimeToFade , 1 ) ;
// if fade-to time has passed and we were fading out, set vgui::Panel::setVisible(false);
if ( ! this - > mFadeToVisibiltyState & & this - > mTimeScalar > = 1.0f )
{
if ( theIsVisible )
{
this - > FadedOut ( ) ;
}
}
}
}
void FadingImageLabel : : VidInit ( void )
{
// Can we unload the sprite?
this - > mSprite = 0 ;
this - > mSpriteWidth = this - > mSpriteHeight = 0 ;
}