Modified source engine (2017) developed by valve and leaked in 2020. Not for commercial purporses
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.
 
 
 
 
 
 

1094 lines
25 KiB

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "hud.h"
#include "c_tf2rootpanel.h"
#include "paneleffect.h"
#include <vgui_controls/Controls.h>
#include <vgui/ISurface.h>
#define EFFECT_FLASH_TIME 0.7f
#define EFFECT_R 100
#define EFFECT_G 150
#define EFFECT_B 220
#define EFFECT_A 255
#define ARROW_R 130
#define ARROW_G 190
#define ARROW_B 240
#define ARROW_A 255
#define AXIALLINE_R 220
#define AXIALLINE_G 220
#define AXIALLINE_B 255
#define AXIALLINE_A 255
//-----------------------------------------------------------------------------
// Purpose: Helper for drawing line segments
//-----------------------------------------------------------------------------
class CConnectingLine
{
public:
int m_ptStart[ 2 ];
int m_ptEnd[ 2 ];
};
//-----------------------------------------------------------------------------
// Purpose: Fill in the intersection between the two rectangles.
// Input : *pRect1 -
// *pRect2 -
// *pOut -
// Output : inline bool
//-----------------------------------------------------------------------------
inline bool GetRectIntersection( wrect_t const *pRect1, wrect_t const *pRect2, wrect_t *pOut )
{
pOut->left = MAX( pRect1->left, pRect2->left );
pOut->right = MIN( pRect1->right, pRect2->right );
if( pOut->left >= pOut->right )
return false;
pOut->bottom = MIN( pRect1->bottom, pRect2->bottom );
pOut->top = MAX( pRect1->top, pRect2->top );
if( pOut->top >= pOut->bottom )
return false;
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Edge to use
//-----------------------------------------------------------------------------
typedef enum
{
TOPCENTER = 0,
RIGHTCENTER,
BOTTOMCENTER,
LEFTCENTER
} LINEEDGE_t;
//-----------------------------------------------------------------------------
// Purpose:
// Input : x -
// y -
// rect -
// edge -
// border -
//-----------------------------------------------------------------------------
static void GetCenterPoint( int& x, int& y, const wrect_t& rect, LINEEDGE_t edge, int border )
{
int xcenter;
int ycenter;
xcenter = ( rect.left + rect.right ) / 2;
ycenter = ( rect.top + rect.bottom ) / 2;
switch ( edge )
{
default:
case TOPCENTER:
x = xcenter;
y = rect.top - border;
break;
case RIGHTCENTER:
x = rect.right + border;
y = ycenter;
break;
case BOTTOMCENTER:
x = xcenter;
y = rect.bottom + border;
break;
case LEFTCENTER:
x = rect.left - border;
y = ycenter;
break;
}
}
//-----------------------------------------------------------------------------
// Purpose: Given two rectangles, finds a direct line between the two rectangles, unless
// they overlap, in which case no line is output.
// Input : x1 -
// y1 -
// w1 -
// h1 -
// x2 -
// y2 -
// w2 -
// h2 -
// output -
//-----------------------------------------------------------------------------
static void FindConnectingLines_Straight(
int x1, int y1, int w1, int h1,
int x2, int y2, int w2, int h2,
CUtlVector< CConnectingLine >& output )
{
// Reset output
output.RemoveAll();
// If the rectangles intersect, no line needed
wrect_t r1;
r1.left = x1;
r1.top = y1;
r1.right = x1 + w1;
r1.bottom = y1 + h1;
wrect_t r2;
r2.left = x2;
r2.top = y2;
r2.right = x2 + w2;
r2.bottom = y2 + h2;
wrect_t dummy;
if ( GetRectIntersection( &r1, &r2, &dummy ) )
return;
int center1[2];
int center2[2];
center1[ 0 ] = x1 + w1/2;
center1[ 1 ] = y1 + h1/2;
center2[ 0 ] = x2 + w2/2;
center2[ 1 ] = y2 + h2/2;
int gaph;
int gapv;
LINEEDGE_t edge1 = TOPCENTER;
LINEEDGE_t edge2 = BOTTOMCENTER;
// Top
gaph = MAX( r2.left - r1.right, r1.left - r2.right );
gapv = MAX( r1.top - r2.bottom, r2.top - r1.bottom );
if ( gapv > gaph )
{
// vertical
if ( ( r1.top - r2.bottom ) > ( r2.top - r1.bottom ) )
{
edge2 = BOTTOMCENTER;
edge1 = TOPCENTER;
}
else
{
edge2 = TOPCENTER;
edge1 = BOTTOMCENTER;
}
}
else
{
if ( ( r1.left - r2.right ) > ( r2.left - r1.right ) )
{
// horizontal
edge2 = RIGHTCENTER;
edge1 = LEFTCENTER;
}
else
{
edge2 = LEFTCENTER;
edge1 = RIGHTCENTER;
}
}
int pt1[ 2 ];
int pt2[ 2 ];
GetCenterPoint( pt1[ 0 ], pt1[ 1 ], r1, edge1, 3 );
GetCenterPoint( pt2[ 0 ], pt2[ 1 ], r2, edge2, 3 );
CConnectingLine line;
line.m_ptStart[ 0 ] = pt1[ 0 ];
line.m_ptStart[ 1 ] = pt1[ 1 ];
line.m_ptEnd[ 0 ] = pt2[ 0 ];
line.m_ptEnd[ 1 ] = pt2[ 1 ];
output.AddToTail( line );
}
//-----------------------------------------------------------------------------
// Purpose: Given two non-intersecting rectangles, finds one, two or three segments
// which connect the midpoints of two of the sides of the items together with only
// axial lines.
// Input : x1 -
// y1 -
// w1 -
// h1 -
// x2 -
// y2 -
// w2 -
// h2 -
// output -
//-----------------------------------------------------------------------------
static void FindConnectingLines_Axial(
int x1, int y1, int w1, int h1,
int x2, int y2, int w2, int h2,
CUtlVector< CConnectingLine >& output )
{
// Reset output
output.RemoveAll();
// If the rectangles intersect, no line needed
wrect_t r1;
r1.left = x1;
r1.top = y1;
r1.right = x1 + w1;
r1.bottom = y1 + h1;
wrect_t r2;
r2.left = x2;
r2.top = y2;
r2.right = x2 + w2;
r2.bottom = y2 + h2;
wrect_t dummy;
if ( GetRectIntersection( &r1, &r2, &dummy ) )
return;
int center1[2];
int center2[2];
center1[ 0 ] = x1 + w1/2;
center1[ 1 ] = y1 + h1/2;
center2[ 0 ] = x2 + w2/2;
center2[ 1 ] = y2 + h2/2;
int gaph;
int gapv;
LINEEDGE_t edge1 = TOPCENTER;
LINEEDGE_t edge2 = BOTTOMCENTER;
// Top
gaph = MAX( r2.left - r1.right, r1.left - r2.right );
gapv = MAX( r1.top - r2.bottom, r2.top - r1.bottom );
if ( gapv > gaph )
{
// vertical
if ( ( r1.top - r2.bottom ) > ( r2.top - r1.bottom ) )
{
edge2 = BOTTOMCENTER;
edge1 = TOPCENTER;
}
else
{
edge2 = TOPCENTER;
edge1 = BOTTOMCENTER;
}
}
else
{
if ( ( r1.left - r2.right ) > ( r2.left - r1.right ) )
{
// horizontal
edge2 = RIGHTCENTER;
edge1 = LEFTCENTER;
}
else
{
edge2 = LEFTCENTER;
edge1 = RIGHTCENTER;
}
}
int pt1[ 2 ];
int pt2[ 2 ];
GetCenterPoint( pt1[ 0 ], pt1[ 1 ], r1, edge1, 3 );
GetCenterPoint( pt2[ 0 ], pt2[ 1 ], r2, edge2, 3 );
CConnectingLine line;
int mid[ 2 ];
int size1[ 2 ];
int size2[ 2 ];
mid[ 0 ] = ( pt1[ 0 ] + pt2[ 0 ] ) / 2;
mid[ 1 ] = ( pt1[ 1 ] + pt2[ 1 ] ) / 2;
size1[ 0 ] = r1.right - r1.left;
size1[ 1 ] = r1.bottom - r1.top;
size2[ 0 ] = r2.right - r2.left;
size2[ 1 ] = r2.bottom - r2.top;
float sizefrac = 0.25f;
if ( edge1 == TOPCENTER || edge1 == BOTTOMCENTER )
{
int dx = abs( mid[ 0 ] - pt1[ 0 ] );
if ( dx < ( sizefrac * size1[ 0 ] ) &&
dx < ( sizefrac * size2[ 0 ] ) )
{
// Gap is small, just use midpoint to align both
line.m_ptStart[ 0 ] = mid[ 0 ];
line.m_ptStart[ 1 ] = pt1[ 1 ];
line.m_ptEnd[ 0 ] = mid[ 0 ];
line.m_ptEnd[ 1 ] = pt2[ 1 ];
output.AddToTail( line );
}
else
{
// Draw an L
line.m_ptStart[ 0 ] = pt1[ 0 ];
line.m_ptStart[ 1 ] = pt1[ 1 ];
line.m_ptEnd[ 0 ] = pt1[ 0 ];
line.m_ptEnd[ 1 ] = mid[ 1 ];
output.AddToTail( line );
line.m_ptStart[ 0 ] = pt1[ 0 ];
line.m_ptStart[ 1 ] = mid[ 1 ];
line.m_ptEnd[ 0 ] = pt2[ 0 ];
line.m_ptEnd[ 1 ] = mid[ 1 ];
output.AddToTail( line );
line.m_ptStart[ 0 ] = pt2[ 0 ];
line.m_ptStart[ 1 ] = mid[ 1 ];
line.m_ptEnd[ 0 ] = pt2[ 0 ];
line.m_ptEnd[ 1 ] = pt2[ 1 ];
output.AddToTail( line );
}
}
else
{
int dy = abs( mid[ 1 ] - pt1[ 1 ] );
if ( dy < ( sizefrac * size1[ 1] ) &&
dy < ( sizefrac * size2[ 1 ] ) )
{
// Gap is small, just use midpoint to align both
line.m_ptStart[ 0 ] = pt1[ 0 ];
line.m_ptStart[ 1 ] = mid[ 1 ];
line.m_ptEnd[ 0 ] = pt2[ 0 ];
line.m_ptEnd[ 1 ] = mid[ 1 ];
output.AddToTail( line );
}
else
{
// Draw an L
line.m_ptStart[ 0 ] = pt1[ 0 ];
line.m_ptStart[ 1 ] = pt1[ 1 ];
line.m_ptEnd[ 0 ] = mid[ 0 ];
line.m_ptEnd[ 1 ] = pt1[ 1 ];
output.AddToTail( line );
line.m_ptStart[ 0 ] = mid[ 0 ];
line.m_ptStart[ 1 ] = pt1[ 1 ];
line.m_ptEnd[ 0 ] = mid[ 0 ];
line.m_ptEnd[ 1 ] = pt2[ 1 ];
output.AddToTail( line );
line.m_ptStart[ 0 ] = mid[ 0 ];
line.m_ptStart[ 1 ] = pt2[ 1 ];
line.m_ptEnd[ 0 ] = pt2[ 0 ];
line.m_ptEnd[ 1 ] = pt2[ 1 ];
output.AddToTail( line );
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Map input panel rectangle into space of output panel and return extents in xywh
// Input : x -
// y -
// w -
// h -
// *output -
// *input -
//-----------------------------------------------------------------------------
void PanelToPanelRectangle( int& x, int& y, int& w, int& h, vgui::Panel *output, vgui::Panel *input )
{
input->GetSize( w, h );
w += 2;
h += 2;
x = y = 0;
input->LocalToScreen( x, y );
output->ScreenToLocal( x, y );
x--;
y--;
}
//-----------------------------------------------------------------------------
// Purpose: Cycle between in/2 and in centered at 3/4in
// Input : in -
// f - ranges from -1 to 1
// Output : static int
//-----------------------------------------------------------------------------
static int EffectResampleColor( int in, float f )
{
int base = in / 2;
int midpoint = ( in + base ) / 2;
float range = (float)( in - midpoint );
int color = midpoint + (int)( f * range );
return clamp( color, 0, 255 );
}
//-----------------------------------------------------------------------------
// Purpose: Border flashing effect
//-----------------------------------------------------------------------------
class CFlashBorderPanelEffect : public CPanelEffect
{
DECLARE_CLASS( CFlashBorderPanelEffect, CPanelEffect );
public:
CFlashBorderPanelEffect( ITFHintItem *owner );
virtual void doPaint( vgui::Panel *panel );
};
//-----------------------------------------------------------------------------
// Purpose:
// Input : *owner -
//-----------------------------------------------------------------------------
CFlashBorderPanelEffect::CFlashBorderPanelEffect( ITFHintItem *owner )
: CPanelEffect( owner )
{
// Mark type field
SetType( FLASHBORDER );
}
//-----------------------------------------------------------------------------
// Purpose: Paint the effect
// Input : *panel -
//-----------------------------------------------------------------------------
void CFlashBorderPanelEffect::doPaint( vgui::Panel *panel )
{
vgui::Panel *p = m_hPanel;
if ( !p || !IsVisibleIncludingParent( p ) )
return;
int w, h;
p->GetSize( w, h );
// Convert top,left to local coordinates
int x = 0, y = 0;
p->LocalToScreen( x, y );
panel->ScreenToLocal( x, y );
x--;
y--;
w+=2;
h+=2;
float frac = fmod( gpGlobals->curtime, EFFECT_FLASH_TIME );
frac *= 2 * M_PI;
frac = cos( frac );
int r, g, b;
r = EffectResampleColor( m_r, frac );
g = EffectResampleColor( m_g, frac );
b = EffectResampleColor( m_b, frac );
vgui::surface()->DrawSetColor( r, g, b, m_a );
for ( int gap = 0; gap < 3; gap++ )
{
vgui::surface()->DrawOutlinedRect( x - gap, y - gap, x + w + gap, y + h + gap );
}
}
//-----------------------------------------------------------------------------
// Purpose: Creates an arry from m_hPanel to m_hOtherPanel
//-----------------------------------------------------------------------------
class CArrowPanelEffect : public CPanelEffect
{
DECLARE_CLASS( CArrowPanelEffect, CPanelEffect );
public:
CArrowPanelEffect( ITFHintItem *owner );
virtual void doPaint( vgui::Panel *panel );
void SetDrawBorder( bool drawborder );
void SetFlashing( bool flashing );
protected:
void DrawArrow( int startx, int starty, int endx, int endy, int r, int g, int b, int a );
void DrawLine( int startx, int starty, int endx, int endy, int r, int g, int b, int a );
void ComputeBestPoint( int& px, int &py, vgui::Panel *output, vgui::Panel *from, vgui::Panel *to );
protected:
bool m_bDrawBorder;
bool m_bFlashing;
};
//-----------------------------------------------------------------------------
// Purpose:
// Input : *owner -
//-----------------------------------------------------------------------------
CArrowPanelEffect::CArrowPanelEffect( ITFHintItem *owner )
: CPanelEffect( owner )
{
SetType( ARROW );
m_bDrawBorder = true;
m_bFlashing = true;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : drawborder -
//-----------------------------------------------------------------------------
void CArrowPanelEffect::SetDrawBorder( bool drawborder )
{
m_bDrawBorder = drawborder;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : flashing -
//-----------------------------------------------------------------------------
void CArrowPanelEffect::SetFlashing( bool flashing )
{
m_bFlashing = flashing;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : startx -
// starty -
// endx -
// endy -
// r -
// g -
// b -
// a -
//-----------------------------------------------------------------------------
void CArrowPanelEffect::DrawArrow( int startx, int starty, int endx, int endy, int r, int g, int b, int a )
{
vgui::surface()->DrawSetColor( r, g, b, a );
// Draw an arrow
Vector start( startx, starty, 0.0f );
Vector end( endx, endy, 0.0f );
Vector delta = end - start;
Vector right;
right.x = delta.y;
right.y = -delta.x;
right.z = 0.0f;
VectorNormalize( right );
Vector base;
float length = VectorNormalize( delta );
float size = MIN( length / 2.0f, 15.0f );
base = start + ( length - size ) * delta;
Vector baseLeft = base + size * 0.25f * right;
Vector baseRight = base - size * 0.25f * right;
vgui::surface()->DrawLine( end.x, end.y, baseLeft.x, baseLeft.y );
vgui::surface()->DrawLine( end.x, end.y, baseRight.x, baseRight.y );
base = start + ( length - size + size * 0.3f ) * delta;
vgui::surface()->DrawLine( base.x, base.y, baseLeft.x, baseLeft.y );
vgui::surface()->DrawLine( base.x, base.y, baseRight.x, baseRight.y );
vgui::surface()->DrawLine( startx, starty, base.x, base.y );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : startx -
// starty -
// endx -
// endy -
// r -
// g -
// b -
// a -
//-----------------------------------------------------------------------------
void CArrowPanelEffect::DrawLine( int startx, int starty, int endx, int endy, int r, int g, int b, int a )
{
vgui::surface()->DrawSetColor( r, g, b, a );
vgui::surface()->DrawLine( startx, starty, endx, endy );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *panel -
//-----------------------------------------------------------------------------
void CArrowPanelEffect::doPaint( vgui::Panel *panel )
{
vgui::Panel *from = m_hPanel;
if ( !from || !IsVisibleIncludingParent( from ) )
return;
int r, g, b;
// Determine flash amount
if ( m_bFlashing )
{
float frac = fmod( gpGlobals->curtime, EFFECT_FLASH_TIME );
frac *= 2 * M_PI;
frac = cos( frac );
// Resample color
r = EffectResampleColor( m_r, frac );
g = EffectResampleColor( m_g, frac );
b = EffectResampleColor( m_b, frac );
}
else
{
r = m_r;
g = m_g;
b = m_b;
}
int startx, starty, startw, starth;
int endx, endy, endw, endh;
PanelToPanelRectangle( startx, starty, startw, starth, panel, from );
if ( !GetTargetRectangle( panel, endx, endy, endw, endh ) )
return;
CUtlVector< CConnectingLine > lines;
FindConnectingLines_Straight( startx, starty, startw, starth, endx, endy, endw, endh, lines );
int i;
if ( m_bDrawBorder )
{
for ( i = 0; i < lines.Size(); i++ )
{
CConnectingLine *l = &lines[ i ];
// Make it thicker
int hstep = 0;
int vstep = 0;
if ( abs( l->m_ptEnd[ 1 ] - l->m_ptStart[ 1 ] ) > abs( l->m_ptEnd[ 0 ] - l->m_ptStart[ 0 ] ) )
{
// Taller so draw horizontally
hstep = 1;
}
else
{
vstep = 1;
}
// Draw a black border
for ( int x = -1; x <= 1 + hstep; x ++ )
{
for ( int y = -1; y <= 1 + vstep; y ++ )
{
if ( !x && !y )
continue;
if ( i == lines.Size() - 1 )
{
DrawArrow( l->m_ptStart[ 0 ] + x, l->m_ptStart[1] + y, l->m_ptEnd[0] + x, l->m_ptEnd[1] + y, 0, 0, 0, m_a );
}
else
{
DrawLine( l->m_ptStart[ 0 ] + x, l->m_ptStart[1] + y, l->m_ptEnd[0] + x, l->m_ptEnd[1] + y, 0, 0, 0, m_a );
}
}
}
}
}
for ( i = 0; i < lines.Size(); i++ )
{
CConnectingLine *l = &lines[ i ];
// Make it thicker
int hstep = 0;
int vstep = 0;
if ( abs( l->m_ptEnd[ 1 ] - l->m_ptStart[ 1 ] ) > abs( l->m_ptEnd[ 0 ] - l->m_ptStart[ 0 ] ) )
{
// Taller so draw horizontally
hstep = 1;
}
else
{
vstep = 1;
}
if ( i == lines.Size() - 1 )
{
// Draw arrow
DrawArrow( l->m_ptStart[ 0 ], l->m_ptStart[ 1 ], l->m_ptEnd[ 0 ], l->m_ptEnd[ 1 ], r, g, b, m_a );
// Draw a second time, but thicker
DrawArrow( l->m_ptStart[ 0 ] + hstep, l->m_ptStart[ 1 ] + vstep, l->m_ptEnd[ 0 ] + hstep, l->m_ptEnd[ 1 ] + vstep, r, g, b, m_a );
}
else
{
// Draw arrow
DrawLine( l->m_ptStart[ 0 ], l->m_ptStart[ 1 ], l->m_ptEnd[ 0 ], l->m_ptEnd[ 1 ], r, g, b, m_a );
// Draw a second time, but thicker
DrawLine( l->m_ptStart[ 0 ] + hstep, l->m_ptStart[ 1 ] + vstep, l->m_ptEnd[ 0 ] + hstep, l->m_ptEnd[ 1 ] + vstep, r, g, b, m_a );
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : px -
// &py -
// *output -
// *from -
// *to -
//-----------------------------------------------------------------------------
void CArrowPanelEffect::ComputeBestPoint( int& px, int &py, vgui::Panel *output, vgui::Panel *from, vgui::Panel *to )
{
int fw, fh;
int tw, th;
from->GetSize( fw, fh );
to->GetSize( tw, th );
// Convert top,left to local coordinates
int fx = 0, fy = 0;
int tx = 0, ty = 0;
from->LocalToScreen( fx, fy );
output->ScreenToLocal( fx, fy );
to->LocalToScreen( tx, ty );
output->ScreenToLocal( tx, ty );
fx--;
fy--;
tx--;
ty--;
fw+=2;
fh+=2;
tw+=2;
th+=2;
int type = 0;
// is to totally below from
if ( ty > ( fy + fh ) )
{
type = 0;
}
// is to totally above from
else if ( ty + th < fy )
{
type = 2;
}
// is to totally to the left of from
else if ( tx + tw < fx )
{
type = 3;
}
// is to totally to the rigth of from
else if ( tx > fx + fw )
{
type = 1;
}
else
{
type = 2;
}
int border = 1;
switch ( type )
{
// unknown, just use object center point
default:
case 4:
//
px = fx + fw / 2;
py = fy + fh / 2;
break;
//bottom
case 0:
px = fx + fw / 2;
py = fy + fh + border;
break;
// right
case 1:
px = fx + fw + border;
py = fy + fh / 2;
break;
// top
case 2:
px = fx + fw / 2;
py = fy - border;
break;
// left
case 3:
px = fx - border;
py = fy + fh / 2;
break;
}
}
//-----------------------------------------------------------------------------
// Purpose: Creates an axial line effect between the two specified panels
//-----------------------------------------------------------------------------
class CAxialLinePanelEffect : public CArrowPanelEffect
{
DECLARE_CLASS( CAxialLinePanelEffect, CArrowPanelEffect );
public:
CAxialLinePanelEffect( ITFHintItem *owner );
virtual void doPaint( vgui::Panel *panel );
};
//-----------------------------------------------------------------------------
// Purpose:
// Input : *owner -
//-----------------------------------------------------------------------------
CAxialLinePanelEffect::CAxialLinePanelEffect( ITFHintItem *owner )
: CArrowPanelEffect( owner )
{
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *panel -
//-----------------------------------------------------------------------------
void CAxialLinePanelEffect::doPaint( vgui::Panel *panel )
{
vgui::Panel *from = m_hPanel;
if ( !from || !IsVisibleIncludingParent( from ) )
return;
int r, g, b;
if ( m_bFlashing )
{
// Determine flash amount
float frac = fmod( gpGlobals->curtime, EFFECT_FLASH_TIME );
frac *= 2 * M_PI;
frac = cos( frac );
// Resample color
r = EffectResampleColor( m_r, frac );
g = EffectResampleColor( m_g, frac );
b = EffectResampleColor( m_b, frac );
}
else
{
r = m_r;
g = m_g;
b = m_b;
}
int startx, starty, startw, starth;
int endx, endy, endw, endh;
PanelToPanelRectangle( startx, starty, startw, starth, panel, from );
if ( !GetTargetRectangle( panel, endx, endy, endw, endh ) )
return;
CUtlVector< CConnectingLine > lines;
FindConnectingLines_Axial( startx, starty, startw, starth, endx, endy, endw, endh, lines );
int i;
if ( m_bDrawBorder )
{
for ( i = 0; i < lines.Size(); i++ )
{
CConnectingLine *l = &lines[ i ];
// Draw a black border
for ( int x = -1; x <= 1; x ++ )
{
for ( int y = -1; y <= 1; y ++ )
{
if ( !x && !y )
continue;
DrawLine( l->m_ptStart[ 0 ] + x, l->m_ptStart[1] + y, l->m_ptEnd[0] + x, l->m_ptEnd[1] + y, 0, 0, 0, m_a );
}
}
}
}
// Draw actual lines
for ( i = 0; i < lines.Size(); i++ )
{
CConnectingLine *l = &lines[ i ];
DrawLine( l->m_ptStart[ 0 ], l->m_ptStart[ 1 ], l->m_ptEnd[ 0 ], l->m_ptEnd[ 1 ], r, g, b, m_a );
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *owner -
// *target -
// Output : EFFECT_HANDLE
//-----------------------------------------------------------------------------
EFFECT_HANDLE CreateFlashEffect( ITFHintItem *owner, vgui::Panel *target )
{
if ( !g_pTF2RootPanel )
return EFFECT_INVALID_HANDLE;
CFlashBorderPanelEffect *e = new CFlashBorderPanelEffect( owner );
e->SetColor( EFFECT_R, EFFECT_G, EFFECT_B, EFFECT_A );
// e->SetEndTime( gpGlobals->curtime + 15.0f );
e->SetPanel( target );
g_pTF2RootPanel->AddEffect( e );
return e->GetHandle();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *owner -
// *from -
// *to -
// Output : EFFECT_HANDLE
//-----------------------------------------------------------------------------
EFFECT_HANDLE CreateArrowEffect( ITFHintItem *owner, vgui::Panel *from, vgui::Panel *to )
{
if ( !g_pTF2RootPanel )
return EFFECT_INVALID_HANDLE;
CArrowPanelEffect *e = new CArrowPanelEffect( owner );
e->SetColor( ARROW_R, ARROW_G, ARROW_B, ARROW_A );
e->SetPanel( from );
e->SetPanelOther( to );
g_pTF2RootPanel->AddEffect( e );
return e->GetHandle();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *owner -
// *from -
// *to -
// Output : EFFECT_HANDLE
//-----------------------------------------------------------------------------
EFFECT_HANDLE CreateAxialLineEffect( ITFHintItem *owner, vgui::Panel *from, vgui::Panel *to )
{
if ( !g_pTF2RootPanel )
return EFFECT_INVALID_HANDLE;
CAxialLinePanelEffect *e = new CAxialLinePanelEffect( owner );
e->SetColor( AXIALLINE_R, AXIALLINE_G, AXIALLINE_B, AXIALLINE_A );
e->SetPanel( from );
e->SetPanelOther( to );
e->SetFlashing( false );
e->SetDrawBorder( false );
g_pTF2RootPanel->AddEffect( e );
return e->GetHandle();
}
EFFECT_HANDLE CreateArrowEffectToPoint( ITFHintItem *owner, vgui::Panel *from, int x, int y )
{
if ( !g_pTF2RootPanel )
return EFFECT_INVALID_HANDLE;
CArrowPanelEffect *e = new CArrowPanelEffect( owner );
e->SetColor( ARROW_R, ARROW_G, ARROW_B, ARROW_A );
e->SetPanel( from );
e->SetTargetPoint( x, y );
g_pTF2RootPanel->AddEffect( e );
return e->GetHandle();
}
EFFECT_HANDLE CreateAxialLineEffectToPoint( ITFHintItem *owner, vgui::Panel *from, int x, int y )
{
if ( !g_pTF2RootPanel )
return EFFECT_INVALID_HANDLE;
CAxialLinePanelEffect *e = new CAxialLinePanelEffect( owner );
e->SetColor( AXIALLINE_R, AXIALLINE_G, AXIALLINE_B, AXIALLINE_A );
e->SetPanel( from );
e->SetTargetPoint( x, y );
e->SetFlashing( false );
e->SetDrawBorder( false );
g_pTF2RootPanel->AddEffect( e );
return e->GetHandle();
}
EFFECT_HANDLE CreateArrowEffectToRect( ITFHintItem *owner, vgui::Panel *from, int x, int y, int w, int h )
{
if ( !g_pTF2RootPanel )
return EFFECT_INVALID_HANDLE;
CArrowPanelEffect *e = new CArrowPanelEffect( owner );
e->SetColor( ARROW_R, ARROW_G, ARROW_B, ARROW_A );
e->SetPanel( from );
e->SetTargetRect( x, y, w, h );
g_pTF2RootPanel->AddEffect( e );
return e->GetHandle();
}
EFFECT_HANDLE CreateAxialLineEffectToRect( ITFHintItem *owner, vgui::Panel *from, int x, int y, int w, int h )
{
if ( !g_pTF2RootPanel )
return EFFECT_INVALID_HANDLE;
CAxialLinePanelEffect *e = new CAxialLinePanelEffect( owner );
e->SetColor( AXIALLINE_R, AXIALLINE_G, AXIALLINE_B, AXIALLINE_A );
e->SetPanel( from );
e->SetTargetRect( x, y, w, h );
e->SetFlashing( false );
e->SetDrawBorder( false );
g_pTF2RootPanel->AddEffect( e );
return e->GetHandle();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *owner -
//-----------------------------------------------------------------------------
void DestroyPanelEffects( ITFHintItem *owner )
{
if ( !g_pTF2RootPanel )
return;
g_pTF2RootPanel->DestroyPanelEffects( owner );
}