1
0
mirror of https://github.com/alliedmodders/hl2sdk.git synced 2025-09-19 20:16:10 +08:00

Added most recent version of unmodified HL2 SDK for Episode 1 engine

This commit is contained in:
Scott Ehlert
2008-09-15 01:00:17 -05:00
commit cb8fd25d1f
3052 changed files with 1217106 additions and 0 deletions

View File

@ -0,0 +1,186 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <stdio.h>
#define PROTECTED_THINGS_DISABLE
#include <vgui/IScheme.h>
#include <vgui/ISurface.h>
#include <vgui/ISystem.h>
#include <vgui/IImage.h>
#include <vgui/IVGui.h>
#include <KeyValues.h>
#include <vgui_controls/AnimatingImagePanel.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
DECLARE_BUILD_FACTORY( AnimatingImagePanel );
//-----------------------------------------------------------------------------
// Purpose: Contructor
//-----------------------------------------------------------------------------
AnimatingImagePanel::AnimatingImagePanel(Panel *parent, const char *name) : Panel(parent, name)
{
m_iCurrentImage = 0;
m_iFrameTimeMillis = 100; // 10Hz frame rate
m_iNextFrameTime = 0;
m_pImageName = NULL;
m_bFiltered = false;
ivgui()->AddTickSignal(GetVPanel());
}
//-----------------------------------------------------------------------------
// Purpose: Layout the panel for drawing.
//-----------------------------------------------------------------------------
void AnimatingImagePanel::PerformLayout()
{
Panel::PerformLayout();
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: Add an image to the end of the list of animations
//-----------------------------------------------------------------------------
void AnimatingImagePanel::AddImage(IImage *image)
{
m_Frames.AddToTail(image);
if (image != NULL)
{
int wide,tall;
image->GetSize(wide,tall);
SetSize(wide,tall);
}
}
//-----------------------------------------------------------------------------
// Purpose: Load a set of animations by name.
// Input:
// baseName: is the name of the animations without thier frame number or
// file extension, (e.g. c1.tga becomes just c.)
// framecount: number of frames in the animation
//-----------------------------------------------------------------------------
void AnimatingImagePanel::LoadAnimation(const char *baseName, int frameCount)
{
m_Frames.RemoveAll();
for (int i = 1; i <= frameCount; i++)
{
char imageName[512];
Q_snprintf(imageName, sizeof( imageName ), "%s%d", baseName, i);
AddImage(scheme()->GetImage(imageName, m_bFiltered));
}
}
//-----------------------------------------------------------------------------
// Purpose: Draw the current image
//-----------------------------------------------------------------------------
void AnimatingImagePanel::PaintBackground()
{
if (m_Frames.IsValidIndex(m_iCurrentImage) && m_Frames[m_iCurrentImage] !=NULL)
{
surface()->DrawSetColor(255, 255, 255, 255);
m_Frames[m_iCurrentImage]->Paint();
}
}
//-----------------------------------------------------------------------------
// Purpose: Called every frame the panel is visible
//-----------------------------------------------------------------------------
void AnimatingImagePanel::OnTick()
{
if (m_bAnimating && system()->GetTimeMillis() >= m_iNextFrameTime)
{
m_iNextFrameTime = system()->GetTimeMillis() + 100;
m_iCurrentImage++;
if (!m_Frames.IsValidIndex(m_iCurrentImage))
{
m_iCurrentImage = 0;
}
Repaint();
}
}
//-----------------------------------------------------------------------------
// Purpose: Get control settings for editing
// Output: outResourceData- a set of keyvalues of imagenames.
//-----------------------------------------------------------------------------
void AnimatingImagePanel::GetSettings(KeyValues *outResourceData)
{
BaseClass::GetSettings(outResourceData);
if (m_pImageName)
{
outResourceData->SetString("image", m_pImageName);
}
}
//-----------------------------------------------------------------------------
// Purpose: Applies resouce settings
//-----------------------------------------------------------------------------
void AnimatingImagePanel::ApplySettings(KeyValues *inResourceData)
{
BaseClass::ApplySettings(inResourceData);
const char *imageName = inResourceData->GetString("image", NULL);
if (imageName)
{
delete [] m_pImageName;
int len = Q_strlen(imageName) + 1;
m_pImageName = new char[len];
Q_strncpy(m_pImageName, imageName, len);
// add in the command
LoadAnimation(m_pImageName, inResourceData->GetInt("frames"));
}
}
//-----------------------------------------------------------------------------
// Purpose: Get editing details
//-----------------------------------------------------------------------------
const char *AnimatingImagePanel::GetDescription()
{
static char buf[1024];
Q_snprintf(buf, sizeof(buf), "%s, string image", BaseClass::GetDescription());
return buf;
}
//-----------------------------------------------------------------------------
// Purpose: Starts the image doing its animation
//-----------------------------------------------------------------------------
void AnimatingImagePanel::StartAnimation()
{
m_bAnimating = true;
// ivgui()->AddTickSignal(GetVPanel());
}
//-----------------------------------------------------------------------------
// Purpose: Stops the images animation
//-----------------------------------------------------------------------------
void AnimatingImagePanel::StopAnimation()
{
m_bAnimating = false;
// ivgui()->RemoveTickSignal(GetVPanel());
}
//-----------------------------------------------------------------------------
// Purpose: Resets the animation to the start of the sequence.
//-----------------------------------------------------------------------------
void AnimatingImagePanel::ResetAnimation(int frame)
{
if(m_Frames.IsValidIndex(frame))
{
m_iCurrentImage = frame;
}
else
{
m_iCurrentImage = 0;
}
Repaint();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,358 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <stdio.h>
#include "vgui_controls/BitmapImagePanel.h"
#include "vgui/ISurface.h"
#include "vgui/IScheme.h"
#include "vgui/IBorder.h"
#include "KeyValues.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#ifndef min
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
using namespace vgui;
//-----------------------------------------------------------------------------
/**
* Simple utility function to allocate memory and duplicate a string
*/
static inline char *CloneString( const char *str )
{
char *cloneStr = new char [ strlen(str)+1 ];
strcpy( cloneStr, str );
return cloneStr;
}
DECLARE_BUILD_FACTORY_DEFAULT_TEXT( CBitmapImagePanel, BitmapImagePanel );
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CBitmapImagePanel::CBitmapImagePanel( Panel *parent, char const *panelName,
char const *filename /*= NULL*/ ) : Panel( parent, panelName )
{
m_pImage = NULL;
SetBounds( 0, 0, 100, 100 );
m_pszImageName = NULL;
m_pszColorName = NULL;
m_hardwareFiltered = false;
m_preserveAspectRatio = false;
m_contentAlignment = Label::a_center;
if ( filename && filename[ 0 ] )
{
m_pImage = scheme()->GetImage( filename, NULL );
m_pszImageName = CloneString( filename );
}
m_bgColor = Color(255, 255, 255, 255);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBitmapImagePanel::ComputeImagePosition(int &x, int &y, int &w, int &h)
{
if (!m_pImage)
{
x = y = w = h = 0;
return;
}
if ( !m_preserveAspectRatio )
{
x = y = 0;
GetSize( w, h );
return;
}
int panelWide, panelTall;
GetSize( panelWide, panelTall );
int imageWide, imageTall;
m_pImage->GetSize( imageWide, imageTall );
if ( panelWide > 0 && panelTall > 0 && imageWide > 0 && imageTall > 0 )
{
float xScale = (float)panelWide / (float)imageWide;
float yScale = (float)panelTall / (float)imageTall;
float scale = min( xScale, yScale );
w = (int) (imageWide * scale);
h = (int) (imageTall * scale);
switch (m_contentAlignment)
{
case Label::a_northwest:
x = y = 0;
break;
case Label::a_north:
x = (panelWide - w) / 2;
y = 0;
break;
case Label::a_northeast:
x = (panelWide - w);
y = 0;
break;
case Label::a_west:
x = 0;
y = (panelTall - h) / 2;
break;
case Label::a_center:
x = (panelWide - w) / 2;
y = (panelTall - h) / 2;
break;
case Label::a_east:
x = (panelWide - w);
y = (panelTall - h) / 2;
break;
case Label::a_southwest:
x = (panelWide - w);
y = 0;
break;
case Label::a_south:
x = (panelWide - w);
y = (panelTall - h) / 2;
break;
case Label::a_southeast:
x = (panelWide - w);
y = (panelTall - h);
break;
default:
x = y = 0;
break;
}
}
else
{
x = y = 0;
w = panelWide;
h = panelTall;
return;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBitmapImagePanel::PaintBorder()
{
int x, y, w, h;
ComputeImagePosition(x, y, w, h);
IBorder *pBorder = GetBorder();
if ( pBorder )
pBorder->Paint( x, y, x+w, y+h, -1, 0, 0 );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBitmapImagePanel::PaintBackground()
{
if (!m_pImage)
return;
int x, y, w, h;
ComputeImagePosition(x, y, w, h);
m_pImage->SetPos(x, y);
m_pImage->SetSize( w, h );
m_pImage->SetColor( m_bgColor );
surface()->DrawSetColor( m_bgColor );
m_pImage->Paint();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBitmapImagePanel::setTexture( char const *filename, bool hardwareFiltered )
{
m_hardwareFiltered = hardwareFiltered;
if ( m_pszImageName )
{
delete[] m_pszImageName;
m_pszImageName = NULL;
}
if ( filename && filename[ 0 ] )
{
m_pImage = scheme()->GetImage( filename, m_hardwareFiltered );
m_pszImageName = CloneString( filename );
}
else
{
m_pImage = NULL;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBitmapImagePanel::SetContentAlignment(Label::Alignment alignment)
{
m_contentAlignment=alignment;
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: Gets control settings for editing
//-----------------------------------------------------------------------------
void CBitmapImagePanel::GetSettings(KeyValues *outResourceData)
{
BaseClass::GetSettings(outResourceData);
if (m_pszImageName)
{
outResourceData->SetString("image", m_pszImageName);
}
if (m_pszColorName)
{
outResourceData->SetString("imagecolor", m_pszColorName);
}
const char *alignmentString = "";
switch ( m_contentAlignment )
{
case Label::a_northwest: alignmentString = "north-west"; break;
case Label::a_north: alignmentString = "north"; break;
case Label::a_northeast: alignmentString = "north-east"; break;
case Label::a_center: alignmentString = "center"; break;
case Label::a_east: alignmentString = "east"; break;
case Label::a_southwest: alignmentString = "south-west"; break;
case Label::a_south: alignmentString = "south"; break;
case Label::a_southeast: alignmentString = "south-east"; break;
case Label::a_west:
default: alignmentString = "center"; break;
}
outResourceData->SetString( "imageAlignment", alignmentString );
outResourceData->SetInt("preserveAspectRatio", m_preserveAspectRatio);
outResourceData->SetInt("filtered", m_hardwareFiltered);
}
//-----------------------------------------------------------------------------
// Purpose: Applies designer settings from res file
//-----------------------------------------------------------------------------
void CBitmapImagePanel::ApplySettings(KeyValues *inResourceData)
{
if ( m_pszImageName )
{
delete[] m_pszImageName;
m_pszImageName = NULL;
}
if ( m_pszColorName )
{
delete[] m_pszColorName;
m_pszColorName = NULL;
}
const char *imageName = inResourceData->GetString("image", "");
if (*imageName)
{
setTexture( imageName );
}
const char *colorName = inResourceData->GetString("imagecolor", "");
if (*colorName)
{
m_pszColorName = CloneString( colorName );
InvalidateLayout(false,true); // force ApplySchemeSettings to run
}
const char *keyString = inResourceData->GetString("imageAlignment", "");
if (keyString && *keyString)
{
int align = -1;
if ( !stricmp(keyString, "north-west") )
{
align = Label::a_northwest;
}
else if ( !stricmp(keyString, "north") )
{
align = Label::a_north;
}
else if ( !stricmp(keyString, "north-east") )
{
align = Label::a_northeast;
}
else if ( !stricmp(keyString, "west") )
{
align = Label::a_west;
}
else if ( !stricmp(keyString, "center") )
{
align = Label::a_center;
}
else if ( !stricmp(keyString, "east") )
{
align = Label::a_east;
}
else if ( !stricmp(keyString, "south-west") )
{
align = Label::a_southwest;
}
else if ( !stricmp(keyString, "south") )
{
align = Label::a_south;
}
else if ( !stricmp(keyString, "south-east") )
{
align = Label::a_southeast;
}
if ( align != -1 )
{
SetContentAlignment( (Label::Alignment)align );
}
}
keyString = inResourceData->GetString("preserveAspectRatio", "");
if (keyString && *keyString)
{
m_preserveAspectRatio = atoi( keyString ) != 0;
}
keyString = inResourceData->GetString("filtered", "");
if (keyString && *keyString)
{
m_hardwareFiltered = atoi( keyString ) != 0;
}
BaseClass::ApplySettings(inResourceData);
}
//-----------------------------------------------------------------------------
// Purpose: load the image, this is done just before this control is displayed
//-----------------------------------------------------------------------------
void CBitmapImagePanel::ApplySchemeSettings( IScheme *pScheme )
{
BaseClass::ApplySchemeSettings(pScheme);
if ( m_pszColorName )
{
setImageColor( pScheme->GetColor( m_pszColorName, m_bgColor ) );
}
}
//-----------------------------------------------------------------------------
// Purpose: Describes editing details
//-----------------------------------------------------------------------------
const char *CBitmapImagePanel::GetDescription()
{
static char buf[1024];
_snprintf(buf, sizeof(buf), "%s, string image, string imagecolor, alignment imageAlignment, int preserveAspectRatio, int filtered", BaseClass::GetDescription());
return buf;
}

View File

@ -0,0 +1,104 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Helper for the CHudElement class to add themselves to the list of hud elements
//
// $NoKeywords: $
//=============================================================================//
#include "vgui/IVGui.h"
#include "vgui_controls/MessageMap.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
using namespace vgui;
// Start with empty list
CBuildFactoryHelper *CBuildFactoryHelper::m_sHelpers = NULL;
//-----------------------------------------------------------------------------
// Purpose: Constructs a panel factory
// Input : pfnCreate - fn Ptr to a function which generates a panel
//-----------------------------------------------------------------------------
CBuildFactoryHelper::CBuildFactoryHelper( char const *className, PANELCREATEFUNC func )
{
// Make this fatal
if ( HasFactory( className ) )
{
Error( "CBuildFactoryHelper: Factory for '%s' already exists!!!!\n", className );
}
//List is empty, or element belongs at front, insert here
m_pNext = m_sHelpers;
m_sHelpers = this;
Assert( func );
m_CreateFunc = func;
Assert( className );
m_pClassName = className;
}
//-----------------------------------------------------------------------------
// Purpose: Returns next object in list
// Output : CBuildFactoryHelper
//-----------------------------------------------------------------------------
CBuildFactoryHelper *CBuildFactoryHelper::GetNext( void )
{
return m_pNext;
}
char const *CBuildFactoryHelper::GetClassName() const
{
return m_pClassName;
}
vgui::Panel *CBuildFactoryHelper::CreatePanel()
{
if ( !m_CreateFunc )
return NULL;
return ( *m_CreateFunc )();
}
// private static meethod
bool CBuildFactoryHelper::HasFactory( char const *className )
{
CBuildFactoryHelper *p = m_sHelpers;
while ( p )
{
if ( !Q_stricmp( className, p->GetClassName() ) )
return true;
p = p->GetNext();
}
return false;
}
// static method
vgui::Panel *CBuildFactoryHelper::InstancePanel( char const *className )
{
CBuildFactoryHelper *p = m_sHelpers;
while ( p )
{
if ( !Q_stricmp( className, p->GetClassName() ) )
return p->CreatePanel();
p = p->GetNext();
}
return NULL;
}
// static method
void CBuildFactoryHelper::GetFactoryNames( CUtlVector< char const * >& list )
{
list.RemoveAll();
CBuildFactoryHelper *p = m_sHelpers;
while ( p )
{
list.AddToTail( p->GetClassName() );
p = p->GetNext();
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

899
vgui2/controls/Button.cpp Normal file
View File

@ -0,0 +1,899 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Basic button control
//
// $NoKeywords: $
//=============================================================================//
#include <stdio.h>
#include <UtlSymbol.h>
#include <vgui/IBorder.h>
#include <vgui/IInput.h>
#include <vgui/IScheme.h>
#include <vgui/ISurface.h>
#include <vgui/ISystem.h>
#include <vgui/IVGui.h>
#include <vgui/MouseCode.h>
#include <vgui/KeyCode.h>
#include <KeyValues.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/FocusNavGroup.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
// global list of all the names of all the sounds played by buttons
CUtlSymbolTable g_ButtonSoundNames;
DECLARE_BUILD_FACTORY_DEFAULT_TEXT( Button, Button );
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
Button::Button(Panel *parent, const char *panelName, const char *text, Panel *pActionSignalTarget, const char *pCmd ) : Label(parent, panelName, text)
{
Init();
if ( pActionSignalTarget && pCmd )
{
AddActionSignalTarget( pActionSignalTarget );
SetCommand( pCmd );
}
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
Button::Button(Panel *parent, const char *panelName, const wchar_t *wszText, Panel *pActionSignalTarget, const char *pCmd ) : Label(parent, panelName, wszText)
{
Init();
if ( pActionSignalTarget && pCmd )
{
AddActionSignalTarget( pActionSignalTarget );
SetCommand( pCmd );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Button::Init()
{
_buttonFlags.SetFlag( USE_CAPTURE_MOUSE | BUTTON_BORDER_ENABLED );
_mouseClickMask = 0;
_actionMessage = NULL;
_defaultBorder = NULL;
_depressedBorder = NULL;
_keyFocusBorder = NULL;
m_bSelectionStateSaved = false;
m_sArmedSoundName = UTL_INVAL_SYMBOL;
m_sDepressedSoundName = UTL_INVAL_SYMBOL;
m_sReleasedSoundName = UTL_INVAL_SYMBOL;
SetTextInset(6, 0);
SetMouseClickEnabled( MOUSE_LEFT, true );
SetButtonActivationType(ACTIVATE_ONPRESSEDANDRELEASED);
// labels have this off by default, but we need it on
SetPaintBackgroundEnabled( true );
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
Button::~Button()
{
if (_actionMessage)
{
_actionMessage->deleteThis();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Button::SetButtonActivationType(ActivationType_t activationType)
{
_activationType = activationType;
}
//-----------------------------------------------------------------------------
// Purpose: Set button border attribute enabled.
//-----------------------------------------------------------------------------
void Button::SetButtonBorderEnabled( bool state )
{
if ( state != _buttonFlags.IsFlagSet( BUTTON_BORDER_ENABLED ) )
{
_buttonFlags.SetFlag( BUTTON_BORDER_ENABLED, state );
InvalidateLayout(false);
}
}
//-----------------------------------------------------------------------------
// Purpose: Set button selected state.
//-----------------------------------------------------------------------------
void Button::SetSelected( bool state )
{
if ( _buttonFlags.IsFlagSet( SELECTED ) != state )
{
_buttonFlags.SetFlag( SELECTED, state );
RecalculateDepressedState();
InvalidateLayout(false);
}
}
//-----------------------------------------------------------------------------
// Purpose: Set button force depressed state.
//-----------------------------------------------------------------------------
void Button::ForceDepressed(bool state)
{
if ( _buttonFlags.IsFlagSet( FORCE_DEPRESSED ) != state )
{
_buttonFlags.SetFlag( FORCE_DEPRESSED, state );
RecalculateDepressedState();
InvalidateLayout(false);
}
}
//-----------------------------------------------------------------------------
// Purpose: Set button depressed state with respect to the force depressed state.
//-----------------------------------------------------------------------------
void Button::RecalculateDepressedState( void )
{
bool newState;
if (!IsEnabled())
{
newState = false;
}
else
{
newState = _buttonFlags.IsFlagSet( FORCE_DEPRESSED ) ? true : (_buttonFlags.IsFlagSet(ARMED) && _buttonFlags.IsFlagSet( SELECTED ) );
}
_buttonFlags.SetFlag( DEPRESSED, newState );
}
//-----------------------------------------------------------------------------
// Purpose: Sets whether or not the button captures all mouse input when depressed
// Defaults to true
// Should be set to false for things like menu items where there is a higher-level mouse capture
//-----------------------------------------------------------------------------
void Button::SetUseCaptureMouse( bool state )
{
_buttonFlags.SetFlag( USE_CAPTURE_MOUSE, state );
}
//-----------------------------------------------------------------------------
// Purpose: Check if mouse capture is enabled.
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool Button::IsUseCaptureMouseEnabled( void )
{
return _buttonFlags.IsFlagSet( USE_CAPTURE_MOUSE );
}
//-----------------------------------------------------------------------------
// Purpose: Set armed state.
//-----------------------------------------------------------------------------
void Button::SetArmed(bool state)
{
if ( _buttonFlags.IsFlagSet( ARMED ) != state )
{
_buttonFlags.SetFlag( ARMED, state );
RecalculateDepressedState();
InvalidateLayout(false);
// play any sounds specified
if (state && m_sArmedSoundName != UTL_INVAL_SYMBOL)
{
surface()->PlaySound(g_ButtonSoundNames.String(m_sArmedSoundName));
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Check armed state
//-----------------------------------------------------------------------------
bool Button::IsArmed()
{
return _buttonFlags.IsFlagSet( ARMED );
}
//-----------------------------------------------------------------------------
// Purpose: Activate a button click.
//-----------------------------------------------------------------------------
void Button::DoClick()
{
SetSelected(true);
FireActionSignal();
// check for playing a transition sound
if (m_sReleasedSoundName != UTL_INVAL_SYMBOL)
{
surface()->PlaySound(g_ButtonSoundNames.String(m_sReleasedSoundName));
}
SetSelected(false);
}
//-----------------------------------------------------------------------------
// Purpose: Check selected state
//-----------------------------------------------------------------------------
bool Button::IsSelected()
{
return _buttonFlags.IsFlagSet( SELECTED );
}
//-----------------------------------------------------------------------------
// Purpose: Check depressed state
//-----------------------------------------------------------------------------
bool Button::IsDepressed()
{
return _buttonFlags.IsFlagSet( DEPRESSED );
}
//-----------------------------------------------------------------------------
// Drawing focus box?
//-----------------------------------------------------------------------------
bool Button::IsDrawingFocusBox()
{
return _buttonFlags.IsFlagSet( DRAW_FOCUS_BOX );
}
void Button::DrawFocusBox( bool bEnable )
{
_buttonFlags.SetFlag( DRAW_FOCUS_BOX, bEnable );
}
//-----------------------------------------------------------------------------
// Purpose: Paint button on screen
//-----------------------------------------------------------------------------
void Button::Paint(void)
{
BaseClass::Paint();
if ( HasFocus() && IsEnabled() && IsDrawingFocusBox() )
{
int x0, y0, x1, y1;
int wide, tall;
GetSize(wide, tall);
x0 = 3, y0 = 3, x1 = wide - 4 , y1 = tall - 2;
DrawFocusBorder(x0, y0, x1, y1);
}
}
//-----------------------------------------------------------------------------
// Purpose: Perform graphical layout of button.
//-----------------------------------------------------------------------------
void Button::PerformLayout()
{
// reset our border
SetBorder( GetBorder(_buttonFlags.IsFlagSet( DEPRESSED ), _buttonFlags.IsFlagSet( ARMED ), _buttonFlags.IsFlagSet( SELECTED ), HasFocus() ) );
// set our color
SetFgColor(GetButtonFgColor());
SetBgColor(GetButtonBgColor());
BaseClass::PerformLayout();
}
//-----------------------------------------------------------------------------
// Purpose: Get button foreground color
// Output : Color
//-----------------------------------------------------------------------------
Color Button::GetButtonFgColor()
{
if (_buttonFlags.IsFlagSet( DEPRESSED ))
return _depressedFgColor;
if (_buttonFlags.IsFlagSet( ARMED ))
return _armedFgColor;
return _defaultFgColor;
}
//-----------------------------------------------------------------------------
// Purpose: Get button background color
//-----------------------------------------------------------------------------
Color Button::GetButtonBgColor()
{
if (_buttonFlags.IsFlagSet( DEPRESSED ))
return _depressedBgColor;
if (_buttonFlags.IsFlagSet( ARMED ))
return _armedBgColor;
return _defaultBgColor;
}
//-----------------------------------------------------------------------------
// Purpose: Called when key focus is received
//-----------------------------------------------------------------------------
void Button::OnSetFocus()
{
InvalidateLayout(false);
BaseClass::OnSetFocus();
}
//-----------------------------------------------------------------------------
// Purpose: Respond when focus is killed
//-----------------------------------------------------------------------------
void Button::OnKillFocus()
{
InvalidateLayout(false);
BaseClass::OnKillFocus();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Button::ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
// get the borders we need
_defaultBorder = pScheme->GetBorder("ButtonBorder");
_depressedBorder = pScheme->GetBorder("ButtonDepressedBorder");
_keyFocusBorder = pScheme->GetBorder("ButtonKeyFocusBorder");
_defaultFgColor = GetSchemeColor("Button.TextColor", Color(255, 255, 255, 255), pScheme);
_defaultBgColor = GetSchemeColor("Button.BgColor", Color(0, 0, 0, 255), pScheme);
_armedFgColor = GetSchemeColor("Button.ArmedTextColor", _defaultFgColor, pScheme);
_armedBgColor = GetSchemeColor("Button.ArmedBgColor", _defaultBgColor, pScheme);
_depressedFgColor = GetSchemeColor("Button.DepressedTextColor", _defaultFgColor, pScheme);
_depressedBgColor = GetSchemeColor("Button.DepressedBgColor", _defaultBgColor, pScheme);
_keyboardFocusColor = GetSchemeColor("Button.FocusBorderColor", Color(0,0,0,255), pScheme);
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: Set default button colors.
//-----------------------------------------------------------------------------
void Button::SetDefaultColor(Color fgColor, Color bgColor)
{
if (!(_defaultFgColor == fgColor && _defaultBgColor == bgColor))
{
_defaultFgColor = fgColor;
_defaultBgColor = bgColor;
InvalidateLayout(false);
}
}
//-----------------------------------------------------------------------------
// Purpose: Set armed button colors
//-----------------------------------------------------------------------------
void Button::SetArmedColor(Color fgColor, Color bgColor)
{
if (!(_armedFgColor == fgColor && _armedBgColor == bgColor))
{
_armedFgColor = fgColor;
_armedBgColor = bgColor;
InvalidateLayout(false);
}
}
//-----------------------------------------------------------------------------
// Purpose: Set depressed button colors
//-----------------------------------------------------------------------------
void Button::SetDepressedColor(Color fgColor, Color bgColor)
{
if (!(_depressedFgColor == fgColor && _depressedBgColor == bgColor))
{
_depressedFgColor = fgColor;
_depressedBgColor = bgColor;
InvalidateLayout(false);
}
}
//-----------------------------------------------------------------------------
// Purpose: Set default button border attributes.
//-----------------------------------------------------------------------------
void Button::SetDefaultBorder(IBorder *border)
{
_defaultBorder = border;
InvalidateLayout(false);
}
//-----------------------------------------------------------------------------
// Purpose: Set depressed button border attributes.
//-----------------------------------------------------------------------------
void Button::SetDepressedBorder(IBorder *border)
{
_depressedBorder = border;
InvalidateLayout(false);
}
//-----------------------------------------------------------------------------
// Purpose: Set key focus button border attributes.
//-----------------------------------------------------------------------------
void Button::SetKeyFocusBorder(IBorder *border)
{
_keyFocusBorder = border;
InvalidateLayout(false);
}
//-----------------------------------------------------------------------------
// Purpose: Get button border attributes.
//-----------------------------------------------------------------------------
IBorder *Button::GetBorder(bool depressed, bool armed, bool selected, bool keyfocus)
{
if ( _buttonFlags.IsFlagSet( BUTTON_BORDER_ENABLED ) )
{
// raised buttons with no armed state
if (depressed)
return _depressedBorder;
if (keyfocus)
return _keyFocusBorder;
if (IsEnabled() && _buttonFlags.IsFlagSet( DEFAULT_BUTTON ))
return _keyFocusBorder;
return _defaultBorder;
}
else
{
// flat buttons that raise
if (depressed)
return _depressedBorder;
if (armed)
return _defaultBorder;
}
return _defaultBorder;
}
//-----------------------------------------------------------------------------
// Purpose: sets this button to be the button that is accessed by default
// when the user hits ENTER or SPACE
//-----------------------------------------------------------------------------
void Button::SetAsCurrentDefaultButton(int state)
{
if ( _buttonFlags.IsFlagSet( DEFAULT_BUTTON ) != (bool)state )
{
_buttonFlags.SetFlag( DEFAULT_BUTTON, state );
if (state)
{
// post a message up notifying our nav group that we're now the default button
if (GetVParent())
{
KeyValues *msg = new KeyValues("CurrentDefaultButtonSet");
msg->SetPtr("button", this);
ivgui()->PostMessage(GetVParent(), msg, GetVPanel());
}
}
InvalidateLayout();
Repaint();
}
}
//-----------------------------------------------------------------------------
// Purpose: sets this button to be the button that is accessed by default
// when the user hits ENTER or SPACE
//-----------------------------------------------------------------------------
void Button::SetAsDefaultButton(int state)
{
if ( _buttonFlags.IsFlagSet( DEFAULT_BUTTON ) != (bool)state )
{
_buttonFlags.SetFlag( DEFAULT_BUTTON, state );
if (state)
{
// post a message up notifying our nav group that we're now the default button
if (GetVParent())
{
KeyValues *msg = new KeyValues("DefaultButtonSet");
msg->SetPtr("button", this);
ivgui()->PostMessage(GetVParent(), msg, GetVPanel());
}
}
InvalidateLayout();
Repaint();
}
}
//-----------------------------------------------------------------------------
// Purpose: sets rollover sound
//-----------------------------------------------------------------------------
void Button::SetArmedSound(const char *sound)
{
if (sound)
{
m_sArmedSoundName = g_ButtonSoundNames.AddString(sound);
}
else
{
m_sArmedSoundName = UTL_INVAL_SYMBOL;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Button::SetDepressedSound(const char *sound)
{
if (sound)
{
m_sDepressedSoundName = g_ButtonSoundNames.AddString(sound);
}
else
{
m_sDepressedSoundName = UTL_INVAL_SYMBOL;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Button::SetReleasedSound(const char *sound)
{
if (sound)
{
m_sReleasedSoundName = g_ButtonSoundNames.AddString(sound);
}
else
{
m_sReleasedSoundName = UTL_INVAL_SYMBOL;
}
}
//-----------------------------------------------------------------------------
// Purpose: Set button to be mouse clickable or not.
//-----------------------------------------------------------------------------
void Button::SetMouseClickEnabled(MouseCode code,bool state)
{
if(state)
{
//set bit to 1
_mouseClickMask|=1<<((int)(code+1));
}
else
{
//set bit to 0
_mouseClickMask&=~(1<<((int)(code+1)));
}
}
//-----------------------------------------------------------------------------
// Purpose: Check if button is mouse clickable
//-----------------------------------------------------------------------------
bool Button::IsMouseClickEnabled(MouseCode code)
{
if(_mouseClickMask&(1<<((int)(code+1))))
{
return true;
}
return false;
}
//-----------------------------------------------------------------------------
// Purpose: sets the command to send when the button is pressed
//-----------------------------------------------------------------------------
void Button::SetCommand( const char *command )
{
SetCommand(new KeyValues("Command", "command", command));
}
//-----------------------------------------------------------------------------
// Purpose: sets the message to send when the button is pressed
//-----------------------------------------------------------------------------
void Button::SetCommand( KeyValues *message )
{
// delete the old message
if (_actionMessage)
{
_actionMessage->deleteThis();
}
_actionMessage = message;
}
//-----------------------------------------------------------------------------
// Purpose: Peeks at the message to send when button is pressed
// Input : -
// Output : KeyValues
//-----------------------------------------------------------------------------
KeyValues *Button::GetCommand()
{
return _actionMessage;
}
//-----------------------------------------------------------------------------
// Purpose: Message targets that the button has been pressed
//-----------------------------------------------------------------------------
void Button::FireActionSignal()
{
// message-based action signal
if (_actionMessage)
{
// see if it's a url
if (!stricmp(_actionMessage->GetName(), "command")
&& !strnicmp(_actionMessage->GetString("command", ""), "url ", strlen("url "))
&& strstr(_actionMessage->GetString("command", ""), "://"))
{
// it's a command to launch a url, run it
system()->ShellExecute("open", _actionMessage->GetString("command", " ") + 4);
}
PostActionSignal(_actionMessage->MakeCopy());
}
}
//-----------------------------------------------------------------------------
// Purpose: gets info about the button
//-----------------------------------------------------------------------------
bool Button::RequestInfo(KeyValues *outputData)
{
if (!stricmp(outputData->GetName(), "CanBeDefaultButton"))
{
outputData->SetInt("result", CanBeDefaultButton() ? 1 : 0);
return true;
}
else if (!stricmp(outputData->GetName(), "GetState"))
{
outputData->SetInt("state", IsSelected());
return true;
}
else if ( !stricmp( outputData->GetName(), "GetCommand" ))
{
if ( _actionMessage )
{
outputData->SetString( "command", _actionMessage->GetString( "command", "" ) );
}
else
{
outputData->SetString( "command", "" );
}
return true;
}
return BaseClass::RequestInfo(outputData);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool Button::CanBeDefaultButton(void)
{
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Get control settings for editing
//-----------------------------------------------------------------------------
void Button::GetSettings( KeyValues *outResourceData )
{
BaseClass::GetSettings(outResourceData);
if (_actionMessage)
{
outResourceData->SetString("command", _actionMessage->GetString("command", ""));
}
outResourceData->SetInt("default", _buttonFlags.IsFlagSet( DEFAULT_BUTTON ) );
if ( m_bSelectionStateSaved )
{
outResourceData->SetInt( "selected", IsSelected() );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Button::ApplySettings( KeyValues *inResourceData )
{
BaseClass::ApplySettings(inResourceData);
const char *cmd = inResourceData->GetString("command", "");
if (*cmd)
{
// add in the command
SetCommand(cmd);
}
// set default button state
int defaultButton = inResourceData->GetInt("default");
if (defaultButton && CanBeDefaultButton())
{
SetAsDefaultButton(true);
}
// saved selection state
int iSelected = inResourceData->GetInt( "selected", -1 );
if ( iSelected != -1 )
{
SetSelected( iSelected != 0 );
m_bSelectionStateSaved = true;
}
}
//-----------------------------------------------------------------------------
// Purpose: Describes editing details
//-----------------------------------------------------------------------------
const char *Button::GetDescription( void )
{
static char buf[1024];
Q_snprintf(buf, sizeof(buf), "%s, string command, int default", BaseClass::GetDescription());
return buf;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Button::OnSetState(int state)
{
SetSelected((bool)state);
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Button::OnCursorEntered()
{
if (IsEnabled())
{
SetArmed(true);
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Button::OnCursorExited()
{
if ( !_buttonFlags.IsFlagSet( BUTTON_KEY_DOWN ) )
{
SetArmed(false);
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Button::OnMousePressed(MouseCode code)
{
if (!IsEnabled())
return;
if (!IsMouseClickEnabled(code))
return;
if (_activationType == ACTIVATE_ONPRESSED)
{
RequestFocus();
DoClick();
return;
}
// play activation sound
if (m_sDepressedSoundName != UTL_INVAL_SYMBOL)
{
surface()->PlaySound(g_ButtonSoundNames.String(m_sDepressedSoundName));
}
if (IsUseCaptureMouseEnabled() && _activationType == ACTIVATE_ONPRESSEDANDRELEASED)
{
{
RequestFocus();
SetSelected(true);
Repaint();
}
// lock mouse input to going to this button
input()->SetMouseCapture(GetVPanel());
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Button::OnMouseDoublePressed(MouseCode code)
{
OnMousePressed(code);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Button::OnMouseReleased(MouseCode code)
{
// ensure mouse capture gets released
if (IsUseCaptureMouseEnabled())
{
input()->SetMouseCapture(NULL);
}
if (_activationType == ACTIVATE_ONPRESSED)
return;
if (!IsMouseClickEnabled(code))
return;
if (!IsSelected() && _activationType == ACTIVATE_ONPRESSEDANDRELEASED)
return;
// it has to be both enabled and (mouse over the button or using a key) to fire
if ( IsEnabled() && ( GetVPanel() == input()->GetMouseOver() || _buttonFlags.IsFlagSet( BUTTON_KEY_DOWN ) ) )
{
DoClick();
}
else
{
SetSelected(false);
}
// make sure the button gets unselected
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Button::OnKeyCodePressed(KeyCode code)
{
if (code == KEY_SPACE || code == KEY_ENTER)
{
SetArmed(true);
_buttonFlags.SetFlag( BUTTON_KEY_DOWN );
OnMousePressed(MOUSE_LEFT);
if (IsUseCaptureMouseEnabled()) // undo the mouse capture since its a fake mouse click!
{
input()->SetMouseCapture(NULL);
}
}
else
{
_buttonFlags.ClearFlag( BUTTON_KEY_DOWN );
BaseClass::OnKeyCodePressed(code);
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Button::OnKeyCodeReleased(KeyCode code)
{
if (_buttonFlags.IsFlagSet( BUTTON_KEY_DOWN ) && (code == KEY_SPACE || code == KEY_ENTER))
{
SetArmed(true);
OnMouseReleased(MOUSE_LEFT);
}
else
{
BaseClass::OnKeyCodeReleased(code);
}
_buttonFlags.ClearFlag( BUTTON_KEY_DOWN );
SetArmed(false);
}
//-----------------------------------------------------------------------------
// Purpose: Override this to draw different focus border
//-----------------------------------------------------------------------------
void Button::DrawFocusBorder(int tx0, int ty0, int tx1, int ty1)
{
surface()->DrawSetColor(_keyboardFocusColor);
DrawDashedLine(tx0, ty0, tx1, ty0+1, 1, 1); // top
DrawDashedLine(tx0, ty0, tx0+1, ty1, 1, 1); // left
DrawDashedLine(tx0, ty1-1, tx1, ty1, 1, 1); // bottom
DrawDashedLine(tx1-1, ty0, tx1, ty1, 1, 1); // right
}
//-----------------------------------------------------------------------------
// Purpose: Size the object to its button and text. - only works from in ApplySchemeSettings or PerformLayout()
//-----------------------------------------------------------------------------
void Button::SizeToContents()
{
int wide, tall;
GetContentSize(wide, tall);
SetSize(wide + Label::Content, tall + Label::Content);
}

View File

@ -0,0 +1,178 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <stdarg.h>
#include <stdio.h>
#include <vgui/ISurface.h>
#include <vgui/IScheme.h>
#include <KeyValues.h>
#include <vgui_controls/Image.h>
#include <vgui_controls/CheckButton.h>
#include <vgui_controls/TextImage.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Check box image
//-----------------------------------------------------------------------------
class CheckImage : public TextImage
{
public:
CheckImage(CheckButton *CheckButton) : TextImage( "g" )
{
_CheckButton = CheckButton;
SetSize(20, 13);
}
virtual void Paint()
{
DrawSetTextFont(GetFont());
// draw background
if (_CheckButton->IsEnabled() && _CheckButton->m_bCheckButtonCheckable)
{
DrawSetTextColor(_bgColor);
}
else
{
DrawSetTextColor(_CheckButton->GetBgColor());
}
DrawPrintChar(0, 1, 'g');
// draw border box
DrawSetTextColor(_borderColor1);
DrawPrintChar(0, 1, 'e');
DrawSetTextColor(_borderColor2);
DrawPrintChar(0, 1, 'f');
// draw selected check
if (_CheckButton->IsSelected())
{
DrawSetTextColor(_checkColor);
DrawPrintChar(0, 2, 'b');
}
}
Color _borderColor1;
Color _borderColor2;
Color _checkColor;
Color _bgColor;
private:
CheckButton *_CheckButton;
};
DECLARE_BUILD_FACTORY_DEFAULT_TEXT( CheckButton, CheckButton );
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CheckButton::CheckButton(Panel *parent, const char *panelName, const char *text) : ToggleButton(parent, panelName, text)
{
SetContentAlignment(a_west);
m_bCheckButtonCheckable = true;
// create the image
_checkBoxImage = new CheckImage(this);
SetTextImageIndex(1);
SetImageAtIndex(0, _checkBoxImage, CHECK_INSET);
_selectedFgColor = Color( 196, 181, 80, 255 );
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CheckButton::~CheckButton()
{
delete _checkBoxImage;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CheckButton::ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
SetDefaultColor( GetSchemeColor("CheckButton.TextColor", pScheme), GetBgColor() );
_checkBoxImage->_bgColor = GetSchemeColor("CheckButton.BgColor", Color(62, 70, 55, 255), pScheme);
_checkBoxImage->_borderColor1 = GetSchemeColor("CheckButton.Border1", Color(20, 20, 20, 255), pScheme);
_checkBoxImage->_borderColor2 = GetSchemeColor("CheckButton.Border2", Color(90, 90, 90, 255), pScheme);
_checkBoxImage->_checkColor = GetSchemeColor("CheckButton.Check", Color(20, 20, 20, 255), pScheme);
_selectedFgColor = GetSchemeColor("CheckButton.SelectedTextColor", GetSchemeColor("ControlText", pScheme), pScheme);
SetContentAlignment(Label::a_west);
_checkBoxImage->SetFont( pScheme->GetFont("Marlett", IsProportional()) );
_checkBoxImage->ResizeImageToContent();
SetImageAtIndex(0, _checkBoxImage, CHECK_INSET);
// don't draw a background
SetPaintBackgroundEnabled(false);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
IBorder *CheckButton::GetBorder(bool depressed, bool armed, bool selected, bool keyfocus)
{
return NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Check the button
//-----------------------------------------------------------------------------
void CheckButton::SetSelected(bool state)
{
if (m_bCheckButtonCheckable)
{
// send a message saying we've been checked
KeyValues *msg = new KeyValues("CheckButtonChecked", "state", (int)state);
PostActionSignal(msg);
BaseClass::SetSelected(state);
}
}
//-----------------------------------------------------------------------------
// Purpose: sets whether or not the state of the check can be changed
//-----------------------------------------------------------------------------
void CheckButton::SetCheckButtonCheckable(bool state)
{
m_bCheckButtonCheckable = state;
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: Gets a different foreground text color if we are selected
//-----------------------------------------------------------------------------
Color CheckButton::GetButtonFgColor()
{
if (IsSelected())
{
return _selectedFgColor;
}
return BaseClass::GetButtonFgColor();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CheckButton::OnCheckButtonChecked(Panel *panel)
{
}

View File

@ -0,0 +1,214 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include <vgui_controls/CheckButtonList.h>
#include <vgui_controls/CheckButton.h>
#include <vgui_controls/ScrollBar.h>
#include <KeyValues.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CheckButtonList::CheckButtonList(Panel *parent, const char *name) : BaseClass(parent, name)
{
m_pScrollBar = new ScrollBar(this, NULL, true);
m_bIgnoreCheckSignals = false;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CheckButtonList::~CheckButtonList()
{
RemoveAll();
}
//-----------------------------------------------------------------------------
// Purpose: adds a check button to the list
//-----------------------------------------------------------------------------
int CheckButtonList::AddItem(const char *itemText, bool startsSelected, KeyValues *userData)
{
m_bIgnoreCheckSignals = true;
CheckItem_t newItem;
newItem.checkButton = new vgui::CheckButton(this, NULL, itemText);
newItem.checkButton->SetSelected(startsSelected);
newItem.checkButton->AddActionSignalTarget(this);
newItem.userData = userData;
InvalidateLayout();
return m_CheckItems.AddToTail(newItem);
}
//-----------------------------------------------------------------------------
// Purpose: clears the list
//-----------------------------------------------------------------------------
void CheckButtonList::RemoveAll()
{
for (int i = 0; i < m_CheckItems.Count(); i++)
{
m_CheckItems[i].checkButton->MarkForDeletion();
if (m_CheckItems[i].userData)
{
m_CheckItems[i].userData->deleteThis();
}
}
m_CheckItems.RemoveAll();
}
//-----------------------------------------------------------------------------
// Purpose: returns the number of items in list that are checked
//-----------------------------------------------------------------------------
int CheckButtonList::GetCheckedItemCount()
{
int count = 0;
for (int i = 0; i < m_CheckItems.Count(); i++)
{
if (m_CheckItems[i].checkButton->IsSelected())
{
count++;
}
}
return count;
}
//-----------------------------------------------------------------------------
// Purpose: lays out buttons
//-----------------------------------------------------------------------------
void CheckButtonList::PerformLayout()
{
m_bIgnoreCheckSignals = false;
BaseClass::PerformLayout();
// get sizes
int x = 4, y = 4, wide = GetWide() - ((x * 2) + m_pScrollBar->GetWide()), tall = 22;
// set scrollbar
int totalHeight = y + (m_CheckItems.Count() * tall);
if (totalHeight > GetTall())
{
m_pScrollBar->SetRange(0, totalHeight + 1);
m_pScrollBar->SetRangeWindow(GetTall());
m_pScrollBar->SetVisible(true);
m_pScrollBar->SetBounds(GetWide() - 21, 0, 19, GetTall() - 2);
SetPaintBorderEnabled(true);
y -= m_pScrollBar->GetValue();
}
else
{
m_pScrollBar->SetVisible(false);
SetPaintBorderEnabled(false);
}
// position the items
for (int i = 0; i < m_CheckItems.Count(); i++)
{
CheckButton *btn = m_CheckItems[i].checkButton;
btn->SetBounds(x, y, wide, tall);
y += tall;
}
}
//-----------------------------------------------------------------------------
// Purpose: Sets the border on the window
//-----------------------------------------------------------------------------
void CheckButtonList::ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
SetBorder(pScheme->GetBorder("ButtonDepressedBorder"));
}
//-----------------------------------------------------------------------------
// Purpose: iteration
//-----------------------------------------------------------------------------
bool CheckButtonList::IsItemIDValid(int itemID)
{
return m_CheckItems.IsValidIndex(itemID);
}
//-----------------------------------------------------------------------------
// Purpose: iteration
//-----------------------------------------------------------------------------
int CheckButtonList::GetHighestItemID()
{
return m_CheckItems.Count() - 1;
}
//-----------------------------------------------------------------------------
// Purpose: iteration
//-----------------------------------------------------------------------------
KeyValues *CheckButtonList::GetItemData(int itemID)
{
return m_CheckItems[itemID].userData;
}
//-----------------------------------------------------------------------------
// Purpose: data accessor
//-----------------------------------------------------------------------------
int CheckButtonList::GetItemCount()
{
return m_CheckItems.Count();
}
//-----------------------------------------------------------------------------
// Purpose: data accessor
//-----------------------------------------------------------------------------
bool CheckButtonList::IsItemChecked(int itemID)
{
return m_CheckItems[itemID].checkButton->IsSelected();
}
//-----------------------------------------------------------------------------
// Purpose: Sets the state of the check button
//-----------------------------------------------------------------------------
void CheckButtonList::SetItemCheckable(int itemID, bool state)
{
m_CheckItems[itemID].checkButton->SetCheckButtonCheckable(state);
}
//-----------------------------------------------------------------------------
// Purpose: Forwards up check button selected message
//-----------------------------------------------------------------------------
void CheckButtonList::OnCheckButtonChecked( KeyValues *pParams )
{
if ( !m_bIgnoreCheckSignals )
{
vgui::Panel *pPanel = (vgui::Panel *)pParams->GetPtr( "panel" );
int c = m_CheckItems.Count();
for ( int i = 0; i < c; ++i )
{
if ( pPanel == m_CheckItems[i].checkButton )
{
PostActionSignal( new KeyValues( "CheckButtonChecked", "itemid", i ) );
break;
}
}
}
}
//-----------------------------------------------------------------------------
// Purpose: updates from scrollbar movement
//-----------------------------------------------------------------------------
void CheckButtonList::OnScrollBarSliderMoved()
{
InvalidateLayout();
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: Mouse wheeled
//-----------------------------------------------------------------------------
void CheckButtonList::OnMouseWheeled(int delta)
{
int val = m_pScrollBar->GetValue();
val -= (delta * 15);
m_pScrollBar->SetValue(val);
}

866
vgui2/controls/ComboBox.cpp Normal file
View File

@ -0,0 +1,866 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#define PROTECTED_THINGS_DISABLE
#include "vgui/Cursor.h"
#include "vgui/IInput.h"
#include "vgui/ILocalize.h"
#include "vgui/IScheme.h"
#include "vgui/ISurface.h"
#include "vgui/IPanel.h"
#include "KeyValues.h"
#include "vgui_controls/Button.h"
#include "vgui_controls/ComboBox.h"
#include "vgui_controls/Menu.h"
#include "vgui_controls/MenuItem.h"
#include <ctype.h>
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
using namespace vgui;
namespace vgui
{
//-----------------------------------------------------------------------------
// Purpose: Scroll bar button
//-----------------------------------------------------------------------------
class ComboBoxButton : public Button
{
public:
ComboBoxButton(ComboBox *parent, const char *panelName, const char *text);
virtual void ApplySchemeSettings(IScheme *pScheme);
virtual IBorder *GetBorder(bool depressed, bool armed, bool selected, bool keyfocus);
virtual void OnCursorExited();
virtual Color GetButtonBgColor()
{
if (IsEnabled())
return Button::GetButtonBgColor();
return m_DisabledBgColor;
}
private:
Color m_DisabledBgColor;
};
ComboBoxButton::ComboBoxButton(ComboBox *parent, const char *panelName, const char *text) : Button(parent, panelName, text)
{
SetButtonActivationType(ACTIVATE_ONPRESSED);
}
void ComboBoxButton::ApplySchemeSettings(IScheme *pScheme)
{
Button::ApplySchemeSettings(pScheme);
SetFont(pScheme->GetFont("Marlett", IsProportional()));
SetContentAlignment(Label::a_west);
SetTextInset(3, 0);
SetDefaultBorder(pScheme->GetBorder("ScrollBarButtonBorder"));
// arrow changes color but the background doesnt.
SetDefaultColor(GetSchemeColor("ComboBoxButton.ArrowColor", pScheme), GetSchemeColor("ComboBoxButton.BgColor", pScheme));
SetArmedColor(GetSchemeColor("ComboBoxButton.ArmedArrowColor", pScheme), GetSchemeColor("ComboBoxButton.BgColor", pScheme));
SetDepressedColor(GetSchemeColor("ComboBoxButton.ArmedArrowColor", pScheme), GetSchemeColor("ComboBoxButton.BgColor", pScheme));
m_DisabledBgColor = GetSchemeColor("ComboBoxButton.DisabledBgColor", pScheme);
}
IBorder * ComboBoxButton::GetBorder(bool depressed, bool armed, bool selected, bool keyfocus)
{
return NULL;
// return Button::GetBorder(depressed, armed, selected, keyfocus);
}
//-----------------------------------------------------------------------------
// Purpose: Dim the arrow on the button when exiting the box
// only if the menu is closed, so let the parent handle this.
//-----------------------------------------------------------------------------
void ComboBoxButton::OnCursorExited()
{
// want the arrow to go grey when we exit the box if the menu is not open
CallParentFunction(new KeyValues("CursorExited"));
}
} // namespace vgui
vgui::Panel *ComboBox_Factory()
{
return new ComboBox( NULL, NULL, 5, true );
}
DECLARE_BUILD_FACTORY_CUSTOM( ComboBox, ComboBox_Factory );
//-----------------------------------------------------------------------------
// Purpose: Constructor
// Input : parent - parent class
// panelName
// numLines - number of lines in dropdown menu
// allowEdit - whether combobox is editable or not
//-----------------------------------------------------------------------------
ComboBox::ComboBox(Panel *parent, const char *panelName, int numLines, bool allowEdit ) : TextEntry(parent, panelName)
{
SetEditable(allowEdit);
SetHorizontalScrolling(false); // do not scroll, always Start at the beginning of the text.
// create the drop-down menu
m_pDropDown = new Menu(this, NULL);
m_pDropDown->AddActionSignalTarget(this);
// button to Activate menu
m_pButton = new ComboBoxButton(this, NULL, "u");
m_pButton->SetCommand("ButtonClicked");
m_pButton->AddActionSignalTarget(this);
SetNumberOfEditLines(numLines);
m_bHighlight = false;
m_iDirection = Menu::DOWN;
m_iOpenOffsetY = 0;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
ComboBox::~ComboBox()
{
m_pDropDown->DeletePanel();
m_pButton->DeletePanel();
}
//-----------------------------------------------------------------------------
// Purpose: Set the number of items in the dropdown menu.
// Input : numLines - number of items in dropdown menu
//-----------------------------------------------------------------------------
void ComboBox::SetNumberOfEditLines( int numLines )
{
m_pDropDown->SetNumberOfVisibleItems( numLines );
}
//-----------------------------------------------------------------------------
// Purpose: Add an item to the drop down
// Input : char *itemText - name of dropdown menu item
//-----------------------------------------------------------------------------
int ComboBox::AddItem(const char *itemText, const KeyValues *userData)
{
// when the menu item is selected it will send the custom message "SetText"
return m_pDropDown->AddMenuItem( itemText, new KeyValues("SetText", "text", itemText), this, userData );
}
//-----------------------------------------------------------------------------
// Purpose: Add an item to the drop down
// Input : char *itemText - name of dropdown menu item
//-----------------------------------------------------------------------------
int ComboBox::AddItem(const wchar_t *itemText, const KeyValues *userData)
{
// add the element to the menu
// when the menu item is selected it will send the custom message "SetText"
KeyValues *kv = new KeyValues("SetText");
kv->SetWString("text", itemText);
// get an ansi version for the menuitem name
char ansi[128];
localize()->ConvertUnicodeToANSI(itemText, ansi, sizeof(ansi));
return m_pDropDown->AddMenuItem(ansi, kv, this, userData);
}
//-----------------------------------------------------------------------------
// Removes a single item
//-----------------------------------------------------------------------------
void ComboBox::DeleteItem( int itemID )
{
if ( !m_pDropDown->IsValidMenuID(itemID))
return;
m_pDropDown->DeleteItem( itemID );
}
//-----------------------------------------------------------------------------
// Purpose: Updates a current item to the drop down
// Input : char *itemText - name of dropdown menu item
//-----------------------------------------------------------------------------
bool ComboBox::UpdateItem(int itemID, const char *itemText, const KeyValues *userData)
{
if ( !m_pDropDown->IsValidMenuID(itemID))
return false;
// when the menu item is selected it will send the custom message "SetText"
m_pDropDown->UpdateMenuItem(itemID, itemText, new KeyValues("SetText", "text", itemText), userData);
InvalidateLayout();
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Updates a current item to the drop down
// Input : wchar_t *itemText - name of dropdown menu item
//-----------------------------------------------------------------------------
bool ComboBox::UpdateItem(int itemID, const wchar_t *itemText, const KeyValues *userData)
{
if ( !m_pDropDown->IsValidMenuID(itemID))
return false;
// when the menu item is selected it will send the custom message "SetText"
KeyValues *kv = new KeyValues("SetText");
kv->SetWString("text", itemText);
m_pDropDown->UpdateMenuItem(itemID, itemText, kv, userData);
InvalidateLayout();
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Updates a current item to the drop down
// Input : wchar_t *itemText - name of dropdown menu item
//-----------------------------------------------------------------------------
bool ComboBox::IsItemIDValid( int itemID )
{
return m_pDropDown->IsValidMenuID(itemID);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ComboBox::SetItemEnabled(const char *itemText, bool state)
{
m_pDropDown->SetItemEnabled(itemText, state);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ComboBox::SetItemEnabled(int itemID, bool state)
{
m_pDropDown->SetItemEnabled(itemID, state);
}
//-----------------------------------------------------------------------------
// Purpose: Remove all items from the drop down menu
//-----------------------------------------------------------------------------
void ComboBox::RemoveAll()
{
m_pDropDown->DeleteAllItems();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int ComboBox::GetItemCount()
{
return m_pDropDown->GetItemCount();
}
//-----------------------------------------------------------------------------
// Purpose: Activate the item in the menu list, as if that menu item had been selected by the user
// Input : itemID - itemID from AddItem in list of dropdown items
//-----------------------------------------------------------------------------
void ComboBox::ActivateItem(int itemID)
{
m_pDropDown->ActivateItem(itemID);
}
//-----------------------------------------------------------------------------
// Purpose: Activate the item in the menu list, as if that menu item had been selected by the user
// Input : itemID - itemID from AddItem in list of dropdown items
//-----------------------------------------------------------------------------
void ComboBox::ActivateItemByRow(int row)
{
m_pDropDown->ActivateItemByRow(row);
}
//-----------------------------------------------------------------------------
// Purpose: Allows a custom menu to be used with the combo box
//-----------------------------------------------------------------------------
void ComboBox::SetMenu( Menu *menu )
{
if ( m_pDropDown )
{
m_pDropDown->MarkForDeletion();
}
m_pDropDown = menu;
if ( m_pDropDown )
{
m_pDropDown->SetParent( this );
}
}
//-----------------------------------------------------------------------------
// Purpose: Layout the format of the combo box for drawing on screen
//-----------------------------------------------------------------------------
void ComboBox::PerformLayout()
{
int wide, tall;
GetPaintSize(wide, tall);
BaseClass::PerformLayout();
HFont buttonFont = m_pButton->GetFont();
int fontTall = surface()->GetFontTall( buttonFont );
int buttonSize = min( tall, fontTall );
int buttonY = ( ( tall - 1 ) - buttonSize ) / 2;
m_pButton->SetBounds( wide - buttonSize - 4, buttonY, buttonSize, buttonSize );
if ( IsEditable() )
{
SetCursor(dc_ibeam);
}
else
{
SetCursor(dc_arrow);
}
m_pButton->SetEnabled(IsEnabled());
DoMenuLayout();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ComboBox::DoMenuLayout()
{
m_pDropDown->PositionRelativeToPanel( this, m_iDirection, m_iOpenOffsetY );
// reset the width of the drop down menu to be the width of the combo box
m_pDropDown->SetFixedWidth(GetWide());
m_pDropDown->ForceCalculateWidth();
}
//-----------------------------------------------------------------------------
// Purpose: Sorts the items in the list
//-----------------------------------------------------------------------------
void ComboBox::SortItems( void )
{
}
//-----------------------------------------------------------------------------
// Purpose: return the index of the last selected item
//-----------------------------------------------------------------------------
int ComboBox::GetActiveItem()
{
return m_pDropDown->GetActiveItem();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
KeyValues *ComboBox::GetActiveItemUserData()
{
return m_pDropDown->GetItemUserData(GetActiveItem());
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
KeyValues *ComboBox::GetItemUserData(int itemID)
{
return m_pDropDown->GetItemUserData(itemID);
}
//-----------------------------------------------------------------------------
// Purpose: data accessor
//-----------------------------------------------------------------------------
void ComboBox::GetItemText( int itemID, wchar_t *text, int bufLenInBytes )
{
m_pDropDown->GetItemText( itemID, text, bufLenInBytes );
}
void ComboBox::GetItemText( int itemID, char *text, int bufLenInBytes )
{
m_pDropDown->GetItemText( itemID, text, bufLenInBytes );
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool ComboBox::IsDropdownVisible()
{
return m_pDropDown->IsVisible();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *inResourceData -
//-----------------------------------------------------------------------------
void ComboBox::ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
SetBorder(pScheme->GetBorder("ComboBoxBorder"));
}
//-----------------------------------------------------------------------------
// Purpose: Set the visiblity of the drop down menu button.
//-----------------------------------------------------------------------------
void ComboBox::SetDropdownButtonVisible(bool state)
{
m_pButton->SetVisible(state);
}
//-----------------------------------------------------------------------------
// Purpose: overloads TextEntry MousePressed
//-----------------------------------------------------------------------------
void ComboBox::OnMousePressed(MouseCode code)
{
if ( !m_pDropDown )
return;
if ( !IsEnabled() )
return;
// make sure it's getting pressed over us (it may not be due to mouse capture)
if ( !IsCursorOver() )
{
HideMenu();
return;
}
if ( IsEditable() )
{
BaseClass::OnMousePressed(code);
HideMenu();
}
else
{
// clicking on a non-editable text box just activates the drop down menu
RequestFocus();
DoClick();
}
}
//-----------------------------------------------------------------------------
// Purpose: Double-click acts the same as a single-click
//-----------------------------------------------------------------------------
void ComboBox::OnMouseDoublePressed(MouseCode code)
{
if (IsEditable())
{
BaseClass::OnMouseDoublePressed(code);
}
else
{
OnMousePressed(code);
}
}
//-----------------------------------------------------------------------------
// Purpose: Called when a command is received from the menu
// Changes the label text to be that of the command
// Input : char *command -
//-----------------------------------------------------------------------------
void ComboBox::OnCommand( const char *command )
{
if (!stricmp(command, "ButtonClicked"))
{
// hide / show the menu underneath
DoClick();
}
Panel::OnCommand(command);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ComboBox::OnSetText(const wchar_t *newtext)
{
// see if the combobox text has changed, and if so, post a message detailing the new text
const wchar_t *text = newtext;
// check if the new text is a localized string, if so undo it
if (*text == '#')
{
char cbuf[255];
localize()->ConvertUnicodeToANSI(text, cbuf, 255);
// try lookup in localization tables
StringIndex_t unlocalizedTextSymbol = localize()->FindIndex(cbuf + 1);
if (unlocalizedTextSymbol != INVALID_STRING_INDEX)
{
// we have a new text value
text = localize()->GetValueByIndex(unlocalizedTextSymbol);
}
}
wchar_t wbuf[255];
GetText(wbuf, 254);
if ( wcscmp(wbuf, text) )
{
// text has changed
SetText(text);
// fire off that things have changed
PostActionSignal(new KeyValues("TextChanged", "text", text));
Repaint();
}
// close the box
HideMenu();
}
//-----------------------------------------------------------------------------
// Purpose: hides the menu
//-----------------------------------------------------------------------------
void ComboBox::HideMenu(void)
{
if ( !m_pDropDown )
return;
// hide the menu
m_pDropDown->SetVisible(false);
Repaint();
OnHideMenu(m_pDropDown);
}
//-----------------------------------------------------------------------------
// Purpose: shows the menu
//-----------------------------------------------------------------------------
void ComboBox::ShowMenu(void)
{
if ( !m_pDropDown )
return;
// hide the menu
m_pDropDown->SetVisible(false);
DoClick();
}
//-----------------------------------------------------------------------------
// Purpose: Called when the window loses focus; hides the menu
//-----------------------------------------------------------------------------
void ComboBox::OnKillFocus()
{
SelectNoText();
}
//-----------------------------------------------------------------------------
// Purpose: Called when the menu is closed
//-----------------------------------------------------------------------------
void ComboBox::OnMenuClose()
{
HideMenu();
if ( HasFocus() )
{
SelectAllText(false);
}
else if ( m_bHighlight )
{
m_bHighlight = false;
// we want the text to be highlighted when we request the focus
// SelectAllOnFirstFocus(true);
RequestFocus();
}
// if cursor is in this box or the arrow box
else if ( IsCursorOver() )// make sure it's getting pressed over us (it may not be due to mouse capture)
{
SelectAllText(false);
OnCursorEntered();
// Get focus so the box will unhighlight if we click somewhere else.
RequestFocus();
}
else
{
m_pButton->SetArmed(false);
}
}
//-----------------------------------------------------------------------------
// Purpose: Handles hotkey accesses
// FIXME: make this open different directions as necessary see menubutton.
//-----------------------------------------------------------------------------
void ComboBox::DoClick()
{
// menu is already visible, hide the menu
if ( m_pDropDown->IsVisible() )
{
HideMenu();
return;
}
// do nothing if menu is not enabled
if ( !m_pDropDown->IsEnabled() )
{
return;
}
// force the menu to Think
m_pDropDown->PerformLayout();
// make sure we're at the top of the draw order (and therefore our children as well)
// RequestFocus();
// We want the item that is shown in the combo box to show as selected
int itemToSelect = -1;
int i;
wchar_t comboBoxContents[255];
GetText(comboBoxContents, 255);
for ( i = 0 ; i < m_pDropDown->GetItemCount() ; i++ )
{
wchar_t menuItemName[255];
int menuID = m_pDropDown->GetMenuID(i);
m_pDropDown->GetMenuItem(menuID)->GetText(menuItemName, 255);
if (!wcscmp(menuItemName, comboBoxContents))
{
itemToSelect = i;
break;
}
}
// if we found a match, highlight it on opening the menu
if ( itemToSelect >= 0 )
{
m_pDropDown->SetCurrentlyHighlightedItem(i);
}
// reset the dropdown's position
DoMenuLayout();
// make sure we're at the top of the draw order (and therefore our children as well)
// this important to make sure the menu will be drawn in the foreground
MoveToFront();
// notify
OnShowMenu(m_pDropDown);
// show the menu
m_pDropDown->SetVisible(true);
// bring to focus
m_pDropDown->RequestFocus();
// no text is highlighted when the menu is opened
SelectNoText();
// highlight the arrow while menu is open
m_pButton->SetArmed(true);
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: Brighten the arrow on the button when entering the box
//-----------------------------------------------------------------------------
void ComboBox::OnCursorEntered()
{
// want the arrow to go white when we enter the box
m_pButton->OnCursorEntered();
TextEntry::OnCursorEntered();
}
//-----------------------------------------------------------------------------
// Purpose: Dim the arrow on the button when exiting the box
//-----------------------------------------------------------------------------
void ComboBox::OnCursorExited()
{
// want the arrow to go grey when we exit the box if the menu is not open
if ( !m_pDropDown->IsVisible() )
{
m_pButton->SetArmed(false);
TextEntry::OnCursorExited();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ComboBox::OnMenuItemSelected()
{
m_bHighlight = true;
// For editable cbs, fill in the text field from whatever is chosen from the dropdown...
if ( m_bAllowEdit )
{
int idx = GetActiveItem();
if ( idx >= 0 )
{
wchar_t name[ 256 ];
GetItemText( idx, name, sizeof( name ) );
OnSetText( name );
}
}
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ComboBox::OnSizeChanged(int wide, int tall)
{
BaseClass::OnSizeChanged( wide, tall);
// set the drawwidth.
int bwide, btall;
PerformLayout();
m_pButton->GetSize( bwide, btall);
SetDrawWidth( wide - bwide );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ComboBox::OnSetFocus()
{
BaseClass::OnSetFocus();
GotoTextEnd();
SelectAllText(false);
}
//-----------------------------------------------------------------------------
// Purpose: Handles up/down arrows
//-----------------------------------------------------------------------------
void ComboBox::OnKeyCodeTyped(KeyCode code)
{
switch (code)
{
case KEY_UP:
{
MoveAlongMenuItemList(-1);
break;
}
case KEY_DOWN:
{
MoveAlongMenuItemList(1);
break;
}
default:
{
BaseClass::OnKeyCodeTyped(code);
break;
}
}
}
//-----------------------------------------------------------------------------
// Purpose: handles key input
//-----------------------------------------------------------------------------
void ComboBox::OnKeyTyped(wchar_t unichar)
{
if ( IsEditable() ) // don't play with key presses in edit mode
{
BaseClass::OnKeyTyped( unichar );
return;
}
int itemToSelect = m_pDropDown->GetActiveItem();
if ( itemToSelect < 0 )
{
itemToSelect = 0;
}
int i;
wchar_t menuItemName[255];
i = itemToSelect + 1;
if ( i >= m_pDropDown->GetItemCount() )
{
i = 0;
}
while ( i != itemToSelect )
{
int menuID = m_pDropDown->GetMenuID(i);
m_pDropDown->GetMenuItem(menuID)->GetText(menuItemName, 254);
if ( towlower(menuItemName[0]) == towlower(unichar) )
{
itemToSelect = i;
break;
}
i++;
if ( i >= m_pDropDown->GetItemCount() )
{
i = 0;
}
}
if ( itemToSelect >= 0 && itemToSelect < m_pDropDown->GetItemCount() )
{
int menuID = m_pDropDown->GetMenuID(itemToSelect);
m_pDropDown->GetMenuItem(menuID)->GetText(menuItemName, 255);
OnSetText(menuItemName);
SelectAllText(false);
m_pDropDown->ActivateItem(itemToSelect);
}
else
{
BaseClass::OnKeyTyped( unichar );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ComboBox::MoveAlongMenuItemList(int direction)
{
// We want the item that is shown in the combo box to show as selected
int itemToSelect = -1;
wchar_t menuItemName[255];
int i;
wchar_t comboBoxContents[255];
GetText(comboBoxContents, 254);
for ( i = 0 ; i < m_pDropDown->GetItemCount() ; i++ )
{
int menuID = m_pDropDown->GetMenuID(i);
m_pDropDown->GetMenuItem(menuID)->GetText(menuItemName, 254);
if ( !wcscmp(menuItemName, comboBoxContents) )
{
itemToSelect = i;
break;
}
}
// if we found this item, then we scroll up or down
if ( itemToSelect >= 0 )
{
int newItem = itemToSelect + direction;
if ( newItem < 0 )
{
newItem = 0;
}
else if ( newItem >= m_pDropDown->GetItemCount() )
{
newItem = m_pDropDown->GetItemCount() - 1;
}
int menuID = m_pDropDown->GetMenuID(newItem);
m_pDropDown->GetMenuItem(menuID)->GetText(menuItemName, 255);
OnSetText(menuItemName);
SelectAllText(false);
m_pDropDown->ActivateItem(newItem);
}
}
//-----------------------------------------------------------------------------
// Purpose: Sets the direction from the menu button the menu should open
//-----------------------------------------------------------------------------
void ComboBox::SetOpenDirection(Menu::MenuDirection_e direction)
{
m_iDirection = direction;
}
void ComboBox::SetFont( HFont font )
{
BaseClass::SetFont( font );
m_pDropDown->SetFont( font );
}

View File

@ -0,0 +1,607 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#define PROTECTED_THINGS_DISABLE
#include <vgui_controls/Button.h>
#include <vgui_controls/ComboBox.h>
#include <vgui_controls/DirectorySelectDialog.h>
#include <vgui_controls/TreeView.h>
#include <vgui_controls/ImageList.h>
#include <vgui_controls/MessageBox.h>
#include <vgui/Cursor.h>
#include <KeyValues.h>
#include <vgui/IInput.h>
#include <vgui/ISurface.h>
#include <vgui/ISystem.h>
#include <direct.h>
#include <stdio.h>
#include <io.h>
#include <sys/types.h>
#include <sys/stat.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Used to handle dynamically populating the tree view
//-----------------------------------------------------------------------------
class DirectoryTreeView : public TreeView
{
public:
DirectoryTreeView(DirectorySelectDialog *parent, const char *name) : TreeView(parent, name)
{
m_pParent = parent;
}
virtual void GenerateChildrenOfNode(int itemIndex)
{
m_pParent->GenerateChildrenOfDirectoryNode(itemIndex);
}
private:
DirectorySelectDialog *m_pParent;
};
//-----------------------------------------------------------------------------
// Purpose: Used to prompt the user to create a directory
//-----------------------------------------------------------------------------
class CreateDirectoryDialog : public Frame
{
DECLARE_CLASS_SIMPLE(CreateDirectoryDialog, Frame);
public:
CreateDirectoryDialog(Panel *parent, const char *defaultCreateDirName) : BaseClass(parent, NULL)
{
SetSize(320, 100);
SetSizeable(false);
SetTitle("Choose directory name", false);
MoveToCenterOfScreen();
m_pOKButton = new Button(this, "OKButton", "#vgui_ok");
m_pCancelButton = new Button(this, "OKButton", "#vgui_cancel");
m_pNameEntry = new TextEntry(this, "NameEntry");
m_pOKButton->SetCommand("OK");
m_pCancelButton->SetCommand("Close");
m_pNameEntry->SetText(defaultCreateDirName);
m_pNameEntry->RequestFocus();
m_pNameEntry->SelectAllText(true);
// If some other window was hogging the input focus, then we have to hog it or else we'll never get input.
m_PrevAppFocusPanel = vgui::input()->GetAppModalSurface();
if ( m_PrevAppFocusPanel )
vgui::input()->SetAppModalSurface( GetVPanel() );
}
~CreateDirectoryDialog()
{
if ( m_PrevAppFocusPanel )
vgui::input()->SetAppModalSurface( m_PrevAppFocusPanel );
}
virtual void PerformLayout()
{
BaseClass::PerformLayout();
m_pNameEntry->SetBounds(24, 32, GetWide() - 48, 24);
m_pOKButton->SetBounds(GetWide() - 176, 64, 72, 24);
m_pCancelButton->SetBounds(GetWide() - 94, 64, 72, 24);
}
virtual void OnCommand(const char *command)
{
if (!stricmp(command, "OK"))
{
PostActionSignal(new KeyValues("CreateDirectory", "dir", GetControlString("NameEntry")));
Close();
}
else
{
BaseClass::OnCommand(command);
}
}
virtual void OnClose()
{
BaseClass::OnClose();
MarkForDeletion();
}
private:
vgui::Button *m_pOKButton;
vgui::Button *m_pCancelButton;
vgui::TextEntry *m_pNameEntry;
vgui::VPANEL m_PrevAppFocusPanel;
};
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
DirectorySelectDialog::DirectorySelectDialog(vgui::Panel *parent, const char *title) : Frame(parent, NULL)
{
SetTitle(title, true);
SetSize(320, 360);
SetMinimumSize(300, 240);
m_szCurrentDir[0] = 0;
m_szDefaultCreateDirName[0] = 0;
m_pDirTree = new DirectoryTreeView(this, "DirTree");
m_pDriveCombo = new ComboBox(this, "DriveCombo", 6, false);
m_pCancelButton = new Button(this, "CancelButton", "#VGui_Cancel");
m_pSelectButton = new Button(this, "SelectButton", "#VGui_Select");
m_pCreateButton = new Button(this, "CreateButton", "#VGui_CreateFolder");
m_pCancelButton->SetCommand("Cancel");
m_pSelectButton->SetCommand("Select");
m_pCreateButton->SetCommand("Create");
}
//-----------------------------------------------------------------------------
// Purpose: lays out controls
//-----------------------------------------------------------------------------
void DirectorySelectDialog::PerformLayout()
{
BaseClass::PerformLayout();
// lay out all the controls
m_pDriveCombo->SetBounds(24, 30, GetWide() - 48, 24);
m_pDirTree->SetBounds(24, 64, GetWide() - 48, GetTall() - 128);
m_pCreateButton->SetBounds(24, GetTall() - 48, 104, 24);
m_pSelectButton->SetBounds(GetWide() - 172, GetTall() - 48, 72, 24);
m_pCancelButton->SetBounds(GetWide() - 96, GetTall() - 48, 72, 24);
}
//-----------------------------------------------------------------------------
// Purpose: lays out controls
//-----------------------------------------------------------------------------
void DirectorySelectDialog::ApplySchemeSettings(IScheme *pScheme)
{
ImageList *imageList = new ImageList(false);
imageList->AddImage(scheme()->GetImage("Resource/icon_folder", false));
imageList->AddImage(scheme()->GetImage("Resource/icon_folder_selected", false));
m_pDirTree->SetImageList(imageList, true);
BaseClass::ApplySchemeSettings(pScheme);
}
//-----------------------------------------------------------------------------
// Purpose: Move the start string forward until we hit a slash and return the
// the first character past the trailing slash
//-----------------------------------------------------------------------------
inline const char *MoveToNextSubDir( const char *pStart, int *nCount )
{
int nMoved = 0;
// Move past pre-pended slash
if ( pStart[nMoved] == '\\' )
{
nMoved++;
}
// Move past the current block of text until we've hit the next path seperator (or end)
while ( pStart[nMoved] != '\\' && pStart[nMoved] != '\0' )
{
nMoved++;
}
// Move past trailing slash
if ( pStart[nMoved] == '\\' )
{
nMoved++;
}
// Give back a count if they've supplied a pointer
if ( nCount != NULL )
{
*nCount = nMoved;
}
// The beginning of the next string, past slash
return (pStart+nMoved);
}
//-----------------------------------------------------------------------------
// Purpose: Walk through our directory structure given a path as our guide, while expanding
// and populating the nodes of the tree view to match
// Input : *path - path (with drive letter) to show
//-----------------------------------------------------------------------------
void DirectorySelectDialog::ExpandTreeToPath( const char *lpszPath, bool bSelectFinalDirectory /*= true*/ )
{
// Make sure our slashes are correct!
char workPath[MAX_PATH];
Q_strncpy( workPath, lpszPath, sizeof(workPath) );
Q_FixSlashes( workPath );
// Set us to the work drive
SetStartDirectory( workPath );
// Check that the path is valid
if ( workPath[0] == '\0' || DoesDirectoryHaveSubdirectories( m_szCurrentDrive, "" ) == false )
{
// Failing, start in C:
SetStartDirectory( "C:\\" );
}
// Start at the root of our tree
int nItemIndex = m_pDirTree->GetRootItemIndex();
// Move past the drive letter to the first subdir
int nPathPos = 0;
const char *lpszSubDirName = MoveToNextSubDir( workPath, &nPathPos );
const char *lpszLastSubDirName = NULL;
int nPathIncr = 0;
char subDirName[MAX_PATH];
// While there are subdirectory names present, expand and populate the tree with their subdirectories
while ( lpszSubDirName[0] != '\0' )
{
// Move our string pointer forward while keeping where our last subdir started off
lpszLastSubDirName = lpszSubDirName;
lpszSubDirName = MoveToNextSubDir( lpszSubDirName, &nPathIncr );
// Get the span between the last subdir and the new one
Q_StrLeft( lpszLastSubDirName, nPathIncr, subDirName, sizeof(subDirName) );
Q_StripTrailingSlash( subDirName );
// Increment where we are in the string for use later
nPathPos += nPathIncr;
// Run through the list and expand to our currently selected directory
for ( int i = 0; i < m_pDirTree->GetNumChildren( nItemIndex ); i++ )
{
// Get the child and data for it
int nChild = m_pDirTree->GetChild( nItemIndex, i );
KeyValues *pValues = m_pDirTree->GetItemData( nChild );
// See if this matches
if ( Q_stricmp( pValues->GetString( "Text" ), subDirName ) == 0 )
{
// This is the new root item
nItemIndex = nChild;
// Get the full path (starting from the drive letter) up to our current subdir
Q_strncpy( subDirName, workPath, nPathPos );
Q_AppendSlash( subDirName, sizeof(subDirName) );
// Expand the tree node and populate its subdirs for our next iteration
ExpandTreeNode( subDirName, nItemIndex );
break;
}
}
}
// Select our last directory if we've been asked to (and it's valid)
if ( bSelectFinalDirectory && m_pDirTree->IsItemIDValid( nItemIndex ) )
{
// If we don't call this once before selecting an item, the tree will not be properly expanded
// before it calculates how to show the selected item in the view
PerformLayout();
// Select that item
m_pDirTree->AddSelectedItem( nItemIndex, true );
}
}
//-----------------------------------------------------------------------------
// Purpose: sets where it should start searching
//-----------------------------------------------------------------------------
void DirectorySelectDialog::SetStartDirectory(const char *path)
{
strncpy(m_szCurrentDir, path, sizeof(m_szCurrentDir));
strncpy(m_szCurrentDrive, path, sizeof(m_szCurrentDrive));
m_szCurrentDrive[sizeof(m_szCurrentDrive) - 1] = 0;
char *firstSlash = strstr(m_szCurrentDrive, "\\");
if (firstSlash)
{
firstSlash[1] = 0;
}
BuildDirTree();
BuildDriveChoices();
// update state of create directory button
int selectedIndex = m_pDirTree->GetFirstSelectedItem();
if (m_pDirTree->IsItemIDValid(selectedIndex))
{
m_pCreateButton->SetEnabled(true);
}
else
{
m_pCreateButton->SetEnabled(false);
}
}
//-----------------------------------------------------------------------------
// Purpose: sets what name should show up by default in the create directory dialog
//-----------------------------------------------------------------------------
void DirectorySelectDialog::SetDefaultCreateDirectoryName(const char *defaultCreateDirName)
{
strncpy(m_szDefaultCreateDirName, defaultCreateDirName, sizeof(m_szDefaultCreateDirName));
m_szDefaultCreateDirName[sizeof(m_szDefaultCreateDirName) - 1] = 0;
}
//-----------------------------------------------------------------------------
// Purpose: opens the dialog
//-----------------------------------------------------------------------------
void DirectorySelectDialog::DoModal()
{
input()->SetAppModalSurface(GetVPanel());
BaseClass::Activate();
MoveToCenterOfScreen();
}
//-----------------------------------------------------------------------------
// Purpose: Builds drive choices
//-----------------------------------------------------------------------------
void DirectorySelectDialog::BuildDriveChoices()
{
m_pDriveCombo->DeleteAllItems();
char drives[256] = { 0 };
int len = system()->GetAvailableDrives(drives, sizeof(drives));
char *pBuf = drives;
KeyValues *kv = new KeyValues("drive");
for (int i = 0; i < len / 4; i++)
{
kv->SetString("drive", pBuf);
int itemID = m_pDriveCombo->AddItem(pBuf, kv);
if (!stricmp(pBuf, m_szCurrentDrive))
{
m_pDriveCombo->ActivateItem(itemID);
}
pBuf += 4;
}
kv->deleteThis();
}
//-----------------------------------------------------------------------------
// Purpose: Builds the base tree directory
//-----------------------------------------------------------------------------
void DirectorySelectDialog::BuildDirTree()
{
// clear current tree
m_pDirTree->RemoveAll();
// add in a root
int rootIndex = m_pDirTree->AddItem(new KeyValues("root", "Text", m_szCurrentDrive), -1);
// build first level of the tree
ExpandTreeNode(m_szCurrentDrive, rootIndex);
// start the root expanded
m_pDirTree->ExpandItem(rootIndex, true);
}
//-----------------------------------------------------------------------------
// Purpose: expands a path
//-----------------------------------------------------------------------------
void DirectorySelectDialog::ExpandTreeNode(const char *path, int parentNodeIndex)
{
// set the small wait cursor
surface()->SetCursor(dc_waitarrow);
// get all the subfolders of the current drive
char searchString[512];
sprintf(searchString, "%s*.*", path);
_finddata_t wfd;
memset(&wfd, 0, sizeof(_finddata_t));
long hResult = _findfirst(searchString, &wfd);
if (hResult != -1)
{
do
{
if ((wfd.attrib & _A_SUBDIR) && wfd.name[0] != '.')
{
KeyValues *kv = new KeyValues("item");
kv->SetString("Text", wfd.name);
// set the folder image
kv->SetInt("Image", 1);
kv->SetInt("SelectedImage", 1);
kv->SetInt("Expand", DoesDirectoryHaveSubdirectories(path, wfd.name));
m_pDirTree->AddItem(kv, parentNodeIndex);
}
} while (_findnext(hResult, &wfd) == 0);
_findclose(hResult);
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool DirectorySelectDialog::DoesDirectoryHaveSubdirectories(const char *path, const char *dir)
{
char searchString[512];
sprintf(searchString, "%s%s\\*.*", path, dir);
_finddata_t wfd;
memset(&wfd, 0, sizeof(_finddata_t));
long hResult = _findfirst(searchString, &wfd);
if (hResult != -1)
{
do
{
if ((wfd.attrib & _A_SUBDIR) && wfd.name[0] != '.')
{
_findclose(hResult);
return true;
}
} while (_findnext(hResult, &wfd) == 0);
_findclose(hResult);
}
return false;
}
//-----------------------------------------------------------------------------
// Purpose: Generates the children for the specified node
//-----------------------------------------------------------------------------
void DirectorySelectDialog::GenerateChildrenOfDirectoryNode(int nodeIndex)
{
// generate path
char path[512];
GenerateFullPathForNode(nodeIndex, path, sizeof(path));
// expand out
ExpandTreeNode(path, nodeIndex);
}
//-----------------------------------------------------------------------------
// Purpose: creates the full path for a node
//-----------------------------------------------------------------------------
void DirectorySelectDialog::GenerateFullPathForNode(int nodeIndex, char *path, int pathBufferSize)
{
// get all the nodes
CUtlLinkedList<int, int> nodes;
nodes.AddToTail(nodeIndex);
int parentIndex = nodeIndex;
while (1)
{
parentIndex = m_pDirTree->GetItemParent(parentIndex);
if (parentIndex == -1)
break;
nodes.AddToHead(parentIndex);
}
// walk the nodes, adding to the path
path[0] = 0;
bool bFirst = true;
FOR_EACH_LL( nodes, i )
{
KeyValues *kv = m_pDirTree->GetItemData( nodes[i] );
strcat(path, kv->GetString("Text"));
if (!bFirst)
{
strcat(path, "\\");
}
bFirst = false;
}
}
//-----------------------------------------------------------------------------
// Purpose: Handles combo box changes
//-----------------------------------------------------------------------------
void DirectorySelectDialog::OnTextChanged()
{
KeyValues *kv = m_pDriveCombo->GetActiveItemUserData();
if (!kv)
return;
const char *newDrive = kv->GetString("drive");
if (stricmp(newDrive, m_szCurrentDrive))
{
// drive changed, reset
SetStartDirectory(newDrive);
}
}
//-----------------------------------------------------------------------------
// Purpose: creates a directory
//-----------------------------------------------------------------------------
void DirectorySelectDialog::OnCreateDirectory(const char *dir)
{
int selectedIndex = m_pDirTree->GetFirstSelectedItem();
if (m_pDirTree->IsItemIDValid(selectedIndex))
{
char fullPath[512];
GenerateFullPathForNode(selectedIndex, fullPath, sizeof(fullPath));
// create the new directory underneath
strcat(fullPath, dir);
if (_mkdir(fullPath) == 0)
{
// add new path to tree view
KeyValues *kv = new KeyValues("item");
kv->SetString("Text", dir);
// set the folder image
kv->SetInt("Image", 1);
kv->SetInt("SelectedImage", 1);
int itemID = m_pDirTree->AddItem(kv, selectedIndex);
// select the item
m_pDirTree->AddSelectedItem( itemID, true );
}
else
{
// print error message
MessageBox *box = new MessageBox("#vgui_CreateDirectoryFail_Title", "#vgui_CreateDirectoryFail_Info");
box->DoModal(this);
}
}
}
//-----------------------------------------------------------------------------
// Purpose: dialog closes
//-----------------------------------------------------------------------------
void DirectorySelectDialog::OnClose()
{
BaseClass::OnClose();
MarkForDeletion();
}
//-----------------------------------------------------------------------------
// Purpose: handles button commands
//-----------------------------------------------------------------------------
void DirectorySelectDialog::OnCommand(const char *command)
{
if (!stricmp(command, "Cancel"))
{
Close();
}
else if (!stricmp(command, "Select"))
{
// path selected
int selectedIndex = m_pDirTree->GetFirstSelectedItem();
if (m_pDirTree->IsItemIDValid(selectedIndex))
{
char fullPath[512];
GenerateFullPathForNode(selectedIndex, fullPath, sizeof(fullPath));
PostActionSignal(new KeyValues("DirectorySelected", "dir", fullPath));
Close();
}
}
else if (!stricmp(command, "Create"))
{
int selectedIndex = m_pDirTree->GetFirstSelectedItem();
if (m_pDirTree->IsItemIDValid(selectedIndex))
{
CreateDirectoryDialog *dlg = new CreateDirectoryDialog(this, m_szDefaultCreateDirName);
dlg->AddActionSignalTarget(this);
dlg->Activate();
}
}
else
{
BaseClass::OnCommand(command);
}
}
//-----------------------------------------------------------------------------
// Purpose: Update the text in the combo
//-----------------------------------------------------------------------------
void DirectorySelectDialog::OnTreeViewItemSelected()
{
int selectedIndex = m_pDirTree->GetFirstSelectedItem();
if (!m_pDirTree->IsItemIDValid(selectedIndex))
{
m_pCreateButton->SetEnabled(false);
return;
}
m_pCreateButton->SetEnabled(true);
// build the string
char fullPath[512];
GenerateFullPathForNode(selectedIndex, fullPath, sizeof(fullPath));
int itemID = m_pDriveCombo->GetActiveItem();
m_pDriveCombo->UpdateItem(itemID, fullPath, NULL);
m_pDriveCombo->SetText(fullPath);
}

View File

@ -0,0 +1,41 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <vgui/IScheme.h>
#include <vgui_controls/Divider.h>
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
using namespace vgui;
DECLARE_BUILD_FACTORY( Divider );
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
Divider::Divider(Panel *parent, const char *name) : Panel(parent, name)
{
SetSize(128, 2);
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
Divider::~Divider()
{
}
//-----------------------------------------------------------------------------
// Purpose: sets up the border as the line to draw as a divider
//-----------------------------------------------------------------------------
void Divider::ApplySchemeSettings(IScheme *pScheme)
{
SetBorder(pScheme->GetBorder("ButtonDepressedBorder"));
BaseClass::ApplySchemeSettings(pScheme);
}

View File

@ -0,0 +1,987 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <vgui/IPanel.h>
#include <vgui/ISurface.h>
#include <vgui/ISystem.h>
#include <vgui/ILocalize.h>
#include <KeyValues.h>
#include <vgui_controls/BuildGroup.h>
#include <vgui_controls/BuildModeDialog.h>
#include <vgui_controls/EditablePanel.h>
// these includes are all for the virtual contruction factory Dialog::CreateControlByName()
#include <vgui_controls/Button.h>
#include <vgui_controls/Label.h>
#include <vgui_controls/CheckButton.h>
#include <vgui_controls/ComboBox.h>
#include <vgui_controls/Menu.h>
#include <vgui_controls/MenuItem.h>
#include <vgui_controls/MessageBox.h>
#include <vgui_controls/ProgressBar.h>
#include <vgui_controls/RadioButton.h>
#include <vgui_controls/ScrollBar.h>
#include <vgui_controls/ToggleButton.h>
#include <vgui_controls/ImagePanel.h>
#include <vgui_controls/AnimatingImagePanel.h>
#include <vgui_controls/Divider.h>
#include <vgui_controls/URLLabel.h>
#include <vgui_controls/RichText.h>
#include <vgui_controls/BitmapImagePanel.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
DECLARE_BUILD_FACTORY( EditablePanel );
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
EditablePanel::EditablePanel(Panel *parent, const char *panelName) : Panel(parent, panelName), m_NavGroup(this)
{
_buildGroup = new BuildGroup(this, this);
m_pszConfigName = NULL;
m_iConfigID = 0;
m_pDialogVariables = NULL;
// add ourselves to the build group
SetBuildGroup(GetBuildGroup());
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
EditablePanel::EditablePanel(Panel *parent, const char *panelName, HScheme hScheme) : Panel(parent, panelName, hScheme), m_NavGroup(this)
{
_buildGroup = new BuildGroup(this, this);
m_pszConfigName = NULL;
m_iConfigID = 0;
m_pDialogVariables = NULL;
// add ourselves to the build group
SetBuildGroup(GetBuildGroup());
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
EditablePanel::~EditablePanel()
{
delete [] m_pszConfigName;
delete _buildGroup;
if (m_pDialogVariables)
{
m_pDialogVariables->deleteThis();
}
}
//-----------------------------------------------------------------------------
// Purpose: Called when a child is added to the panel.
//-----------------------------------------------------------------------------
void EditablePanel::OnChildAdded(VPANEL child)
{
BaseClass::OnChildAdded(child);
// add only if we're in the same module
Panel *panel = ipanel()->GetPanel(child, GetModuleName());
if (panel)
{
panel->SetBuildGroup(_buildGroup);
panel->AddActionSignalTarget(this);
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void EditablePanel::OnKeyCodeTyped(KeyCode code)
{
if (code == KEY_ENTER)
{
// check for a default button
VPANEL panel = GetFocusNavGroup().GetCurrentDefaultButton();
if (panel && ipanel()->IsVisible( panel ) && ipanel()->IsEnabled( panel ))
{
// Activate the button
PostMessage(panel, new KeyValues("Hotkey"));
}
else
{
BaseClass::OnKeyCodeTyped(code);
}
}
else
{
BaseClass::OnKeyCodeTyped(code);
}
}
//-----------------------------------------------------------------------------
// Purpose: Callback for when the panel size has been changed
//-----------------------------------------------------------------------------
void EditablePanel::OnSizeChanged(int wide, int tall)
{
BaseClass::OnSizeChanged(wide, tall);
InvalidateLayout();
for (int i = 0; i < GetChildCount(); i++)
{
// perform auto-layout on the child panel
Panel *child = GetChild(i);
if ( !child )
continue;
int x, y, w, h;
child->GetBounds( x, y, w, h );
int px, py;
child->GetPinOffset( px, py );
int ox, oy;
child->GetResizeOffset( ox, oy );
int ex;
int ey;
AutoResize_e resize = child->GetAutoResize();
bool bResizeHoriz = ( resize == AUTORESIZE_RIGHT || resize == AUTORESIZE_DOWNANDRIGHT );
bool bResizeVert = ( resize == AUTORESIZE_DOWN || resize == AUTORESIZE_DOWNANDRIGHT );
PinCorner_e pinCorner = child->GetPinCorner();
if ( pinCorner == PIN_TOPRIGHT || pinCorner == PIN_BOTTOMRIGHT )
{
// move along with the right edge
ex = wide + px;
x = bResizeHoriz ? ox : ex - w;
}
else
{
x = px;
ex = bResizeHoriz ? wide + ox : px + w;
}
if ( pinCorner == PIN_BOTTOMLEFT || pinCorner == PIN_BOTTOMRIGHT )
{
// move along with the right edge
ey = tall + py;
y = bResizeVert ? oy : ey - h;
}
else
{
y = py;
ey = bResizeVert ? tall + oy : py + h;
}
// Clamp..
if ( ex < x )
{
ex = x;
}
if ( ey < y )
{
ey = y;
}
child->SetBounds( x, y, ex - x, ey - y );
child->InvalidateLayout();
}
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void EditablePanel::OnCurrentDefaultButtonSet(Panel *defaultButton)
{
m_NavGroup.SetCurrentDefaultButton(defaultButton->GetVPanel(), false);
// forward the message up
if (GetVParent())
{
KeyValues *msg = new KeyValues("CurrentDefaultButtonSet");
msg->SetPtr("button", defaultButton);
PostMessage(GetVParent(), msg);
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void EditablePanel::OnDefaultButtonSet(Panel *defaultButton)
{
m_NavGroup.SetDefaultButton(defaultButton);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void EditablePanel::OnFindDefaultButton()
{
if (m_NavGroup.GetDefaultButton())
{
m_NavGroup.SetCurrentDefaultButton(m_NavGroup.GetDefaultButton());
}
else
{
if (GetVParent())
{
PostMessage(GetVParent(), new KeyValues("FindDefaultButton"));
}
}
}
struct leaf_t
{
short x, y, wide, tall;
unsigned char split; // 0 no split; 1 x-axis, 2 y-axis
bool filled; // true if this is already filled
short splitpos; // place of split
leaf_t *left;
leaf_t *right;
};
leaf_t g_Leaves[256];
int g_iNextLeaf;
inline leaf_t *AllocLeaf()
{
Assert(g_iNextLeaf < 255);
return &g_Leaves[g_iNextLeaf++];
}
void AddSolidToTree(leaf_t *leaf, int x, int y, int wide, int tall)
{
// clip to this leaf
if (x < leaf->x)
{
wide -= (leaf->x - x);
if (wide < 1)
return;
x = leaf->x;
}
if (y < leaf->y)
{
tall -= (leaf->y - y);
if (tall < 1)
return;
y = leaf->y;
}
if (x + wide > leaf->x + leaf->wide)
{
wide -= ((x + wide) - (leaf->x + leaf->wide));
if (wide < 1)
return;
}
if (y + tall > leaf->y + leaf->tall)
{
tall -= ((y + tall) - (leaf->y + leaf->tall));
if (tall < 1)
return;
}
// the rect should now be completely within the leaf
if (leaf->split == 1)
{
// see if it is to the left or the right of the split
if (x < leaf->splitpos)
{
// it's to the left
AddSolidToTree(leaf->left, x, y, wide, tall);
}
else if (x + wide > leaf->splitpos)
{
// it's to the right
AddSolidToTree(leaf->right, x, y, wide, tall);
}
}
else if (leaf->split == 2)
{
// check y
// see if it is to the left (above) or the right (below) of the split
if (y < leaf->splitpos)
{
// it's above
AddSolidToTree(leaf->left, x, y, wide, tall);
}
else if (y + tall > leaf->splitpos)
{
// it's below
AddSolidToTree(leaf->right, x, y, wide, tall);
}
}
else
{
// this leaf is unsplit, make the first split against the first edge we find
if (x > leaf->x)
{
// split the left side of the rect
leaf->split = 1;
leaf->splitpos = (short)x;
// create 2 new leaves
leaf_t *left = AllocLeaf();
leaf_t *right = AllocLeaf();
memset(left, 0, sizeof(leaf_t));
memset(right, 0, sizeof(leaf_t));
leaf->left = left;
leaf->right = right;
left->x = leaf->x;
left->y = leaf->y;
left->wide = (short)(leaf->splitpos - leaf->x);
left->tall = leaf->tall;
right->x = leaf->splitpos;
right->y = leaf->y;
right->wide = (short)(leaf->wide - left->wide);
right->tall = leaf->tall;
// split the right leaf by the current rect
AddSolidToTree(leaf->right, x, y, wide, tall);
}
else if (y > leaf->y)
{
// split the top edge
leaf->split = 2;
leaf->splitpos = (short)y;
// create 2 new leaves (facing to the east)
leaf_t *left = AllocLeaf();
leaf_t *right = AllocLeaf();
memset(left, 0, sizeof(leaf_t));
memset(right, 0, sizeof(leaf_t));
leaf->left = left;
leaf->right = right;
left->x = leaf->x;
left->y = leaf->y;
left->wide = leaf->wide;
left->tall = (short)(y - leaf->y);
right->x = leaf->x;
right->y = leaf->splitpos;
right->wide = leaf->wide;
right->tall = (short)(leaf->tall + leaf->y - right->y);
// split the right leaf by the current rect
AddSolidToTree(leaf->right, x, y, wide, tall);
}
else if (x + wide < leaf->x + leaf->wide)
{
// split the right edge
leaf->split = 1;
leaf->splitpos = (short)(x + wide);
// create 2 new leaves
leaf_t *left = AllocLeaf();
leaf_t *right = AllocLeaf();
memset(left, 0, sizeof(leaf_t));
memset(right, 0, sizeof(leaf_t));
leaf->left = left;
leaf->right = right;
left->x = leaf->x;
left->y = leaf->y;
left->wide = (short)(leaf->splitpos - leaf->x);
left->tall = leaf->tall;
right->x = leaf->splitpos;
right->y = leaf->y;
right->wide = (short)(leaf->wide - left->wide);
right->tall = leaf->tall;
// split the left leaf by the current rect
AddSolidToTree(leaf->left, x, y, wide, tall);
}
else if (y + tall < leaf->y + leaf->tall)
{
// split the bottom edge
leaf->split = 2;
leaf->splitpos = (short)(y + tall);
// create 2 new leaves (facing to the east)
leaf_t *left = AllocLeaf();
leaf_t *right = AllocLeaf();
memset(left, 0, sizeof(leaf_t));
memset(right, 0, sizeof(leaf_t));
leaf->left = left;
leaf->right = right;
left->x = leaf->x;
left->y = leaf->y;
left->wide = leaf->wide;
left->tall = (short)(leaf->splitpos - leaf->y);
right->x = leaf->x;
right->y = leaf->splitpos;
right->wide = leaf->wide;
right->tall = (short)(leaf->tall - left->tall);
// split the left leaf by the current rect
AddSolidToTree(leaf->left, x, y, wide, tall);
}
else
{
// this is the exact same rect! don't draw this leaf
leaf->filled = true;
return;
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Fills the panel background, clipping if possible
//-----------------------------------------------------------------------------
void EditablePanel::PaintBackground()
{
BaseClass::PaintBackground();
return;
/*
test code, using a screenspace bsp tree to reduce overdraw in vgui
not yet fully functional
// test: fill background with obnoxious color to show holes
// surface()->DrawSetColor(Color(255, 0, 0, 255));
// surface()->DrawFilledRect(0, 0, GetWide(), GetTall());
// return;
// reset the leaf memory
g_iNextLeaf = 0;
leaf_t *headNode = AllocLeaf();
memset(headNode, 0, sizeof(leaf_t));
headNode->wide = (short)GetWide();
headNode->tall = (short)GetTall();
// split the leaf by the first child
for (int i = 0; i < GetChildCount(); i++)
{
Panel *child = GetChild(i);
if (child->IsOpaque())
{
int x, y, wide, tall;
child->GetBounds(x, y, wide, tall);
// ignore small children
if (wide + tall < 100)
continue;
AddSolidToTree(headNode, x, y, wide, tall);
}
}
// walk the built tree, painting the background
Color col = GetBgColor();
surface()->DrawSetColor(col);
for (i = 0; i < g_iNextLeaf; i++)
{
leaf_t *leaf = g_Leaves + i;
if (leaf->splitpos || leaf->filled)
continue;
surface()->DrawFilledRect(leaf->x, leaf->y, leaf->x + leaf->wide, leaf->y + leaf->tall);
}
*/
}
//-----------------------------------------------------------------------------
// Purpose: Activates the build mode dialog for editing panels.
//-----------------------------------------------------------------------------
void EditablePanel::ActivateBuildMode()
{
_buildGroup->SetEnabled(true);
}
//-----------------------------------------------------------------------------
// Purpose: Loads panel settings from a resource file.
//-----------------------------------------------------------------------------
void EditablePanel::LoadControlSettings(const char *resourceName, const char *pathID, KeyValues *pKeyValues)
{
_buildGroup->LoadControlSettings(resourceName, pathID, pKeyValues);
ForceSubPanelsToUpdateWithNewDialogVariables();
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: registers a file in the list of control settings, so the vgui dialog can choose between them to edit
//-----------------------------------------------------------------------------
void EditablePanel::RegisterControlSettingsFile(const char *resourceName, const char *pathID)
{
_buildGroup->RegisterControlSettingsFile(resourceName, pathID);
}
//-----------------------------------------------------------------------------
// Purpose: sets the name of this dialog so it can be saved in the user config area
//-----------------------------------------------------------------------------
void EditablePanel::LoadUserConfig(const char *configName, int dialogID)
{
KeyValues *data = system()->GetUserConfigFileData(configName, dialogID);
delete [] m_pszConfigName;
int len = Q_strlen(configName) + 1;
m_pszConfigName = new char[ len ];
Q_strncpy(m_pszConfigName, configName, len );
m_iConfigID = dialogID;
// apply our user config settings (this will recurse through our children)
if (data)
{
ApplyUserConfigSettings(data);
}
}
//-----------------------------------------------------------------------------
// Purpose: saves all the settings to the document
//-----------------------------------------------------------------------------
void EditablePanel::SaveUserConfig()
{
if (m_pszConfigName)
{
KeyValues *data = system()->GetUserConfigFileData(m_pszConfigName, m_iConfigID);
// get our user config settings (this will recurse through our children)
if (data)
{
GetUserConfigSettings(data);
}
}
}
//-----------------------------------------------------------------------------
// Purpose: combines both of the above, LoadControlSettings & LoadUserConfig
//-----------------------------------------------------------------------------
void EditablePanel::LoadControlSettingsAndUserConfig(const char *dialogResourceName, int dialogID)
{
LoadControlSettings(dialogResourceName);
LoadUserConfig(dialogResourceName, dialogID);
}
//-----------------------------------------------------------------------------
// Purpose: applies the user config settings to all the children
//-----------------------------------------------------------------------------
void EditablePanel::ApplyUserConfigSettings(KeyValues *userConfig)
{
for (int i = 0; i < GetChildCount(); i++)
{
Panel *child = GetChild(i);
if (child->HasUserConfigSettings())
{
const char *name = child->GetName();
if (name && *name)
{
child->ApplyUserConfigSettings(userConfig->FindKey(name, true));
}
}
}
}
//-----------------------------------------------------------------------------
// Purpose: gets all the children's user config settings
//-----------------------------------------------------------------------------
void EditablePanel::GetUserConfigSettings(KeyValues *userConfig)
{
for (int i = 0; i < GetChildCount(); i++)
{
Panel *child = GetChild(i);
if (child->HasUserConfigSettings())
{
const char *name = child->GetName();
if (name && *name)
{
child->GetUserConfigSettings(userConfig->FindKey(name, true));
}
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Save user config settings
//-----------------------------------------------------------------------------
void EditablePanel::OnClose()
{
SaveUserConfig();
}
//-----------------------------------------------------------------------------
// Purpose: Handle information requests
//-----------------------------------------------------------------------------
bool EditablePanel::RequestInfo(KeyValues *data)
{
#ifndef _XBOX
if (!stricmp(data->GetName(), "BuildDialog"))
{
// a build dialog is being requested, give it one
// a bit hacky, but this is a case where vgui.dll needs to reach out
data->SetPtr("PanelPtr", new BuildModeDialog( (BuildGroup *)data->GetPtr("BuildGroupPtr")));
return true;
}
else if (!stricmp(data->GetName(), "ControlFactory"))
{
Panel *newPanel = CreateControlByName(data->GetString("ControlName"));
if (newPanel)
{
data->SetPtr("PanelPtr", newPanel);
return true;
}
}
#endif
return BaseClass::RequestInfo(data);
}
//-----------------------------------------------------------------------------
// Purpose: Return the buildgroup that this panel is part of.
// Input :
// Output : BuildGroup
//-----------------------------------------------------------------------------
BuildGroup *EditablePanel::GetBuildGroup()
{
return _buildGroup;
}
//-----------------------------------------------------------------------------
// Purpose: Return a pointer to the nav group
// Output : FocusNavGroup
//-----------------------------------------------------------------------------
FocusNavGroup &EditablePanel::GetFocusNavGroup()
{
return m_NavGroup;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool EditablePanel::RequestFocusNext(VPANEL panel)
{
return m_NavGroup.RequestFocusNext(panel);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool EditablePanel::RequestFocusPrev(VPANEL panel)
{
return m_NavGroup.RequestFocusPrev(panel);
}
//-----------------------------------------------------------------------------
// Purpose: Delegates focus to a sub panel
// Input : direction - the direction in which focus travelled to arrive at this panel; forward = 1, back = -1
//-----------------------------------------------------------------------------
void EditablePanel::RequestFocus(int direction)
{
// we must be a sub panel for this to be called
// delegate focus
if (direction == 1)
{
RequestFocusNext(NULL);
}
else if (direction == -1)
{
RequestFocusPrev(NULL);
}
else
{
BaseClass::RequestFocus();
}
}
//-----------------------------------------------------------------------------
// Purpose: Pass the focus down onto the last used panel
//-----------------------------------------------------------------------------
void EditablePanel::OnSetFocus()
{
Panel *focus = m_NavGroup.GetCurrentFocus();
if (focus && focus != this)
{
focus->RequestFocus();
}
else
{
focus = m_NavGroup.GetDefaultPanel();
if (focus)
{
focus->RequestFocus();
focus->OnSetFocus();
}
}
BaseClass::OnSetFocus();
}
//-----------------------------------------------------------------------------
// Purpose: Called when the resource file is loaded to set up the panel state
// Input : *inResourceData -
//-----------------------------------------------------------------------------
void EditablePanel::ApplySettings(KeyValues *inResourceData)
{
Panel::ApplySettings(inResourceData);
_buildGroup->ApplySettings(inResourceData);
}
//-----------------------------------------------------------------------------
// Purpose: Update focus info for navigation
//-----------------------------------------------------------------------------
void EditablePanel::OnRequestFocus(VPANEL subFocus, VPANEL defaultPanel)
{
if (!ipanel()->IsPopup(subFocus))
{
defaultPanel = m_NavGroup.SetCurrentFocus(subFocus, defaultPanel);
}
BaseClass::OnRequestFocus(GetVPanel(), defaultPanel);
}
//-----------------------------------------------------------------------------
// Purpose: Get the panel that currently has keyfocus
//-----------------------------------------------------------------------------
VPANEL EditablePanel::GetCurrentKeyFocus()
{
Panel *focus = m_NavGroup.GetCurrentFocus();
if (focus == this)
return NULL;
if (focus)
{
if (focus->IsPopup())
return BaseClass::GetCurrentKeyFocus();
// chain down the editpanel hierarchy
VPANEL subFocus = focus->GetCurrentKeyFocus();
if (subFocus)
return subFocus;
// hit a leaf panel, return that
return focus->GetVPanel();
}
return BaseClass::GetCurrentKeyFocus();
}
//-----------------------------------------------------------------------------
// Purpose: Gets the panel with the specified hotkey
//-----------------------------------------------------------------------------
Panel *EditablePanel::HasHotkey(wchar_t key)
{
if( !IsVisible() || !IsEnabled()) // not visible, so can't respond to a hot key
{
return NULL;
}
for (int i = 0; i < GetChildCount(); i++)
{
Panel *hot = GetChild(i)->HasHotkey(key);
if (hot && hot->IsVisible() && hot->IsEnabled())
{
return hot;
}
}
return NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Shortcut function to setting enabled state of control
//-----------------------------------------------------------------------------
void EditablePanel::SetControlEnabled(const char *controlName, bool enabled)
{
Panel *control = FindChildByName(controlName);
if (control)
{
control->SetEnabled(enabled);
}
}
//-----------------------------------------------------------------------------
// Purpose: Shortcut function to setting visibility state of control
//-----------------------------------------------------------------------------
void EditablePanel::SetControlVisible(const char *controlName, bool visible)
{
Panel *control = FindChildByName(controlName);
if (control)
{
control->SetVisible(visible);
}
}
//-----------------------------------------------------------------------------
// Purpose: Shortcut function to set data in child controls
//-----------------------------------------------------------------------------
void EditablePanel::SetControlString(const char *controlName, const char *string)
{
Panel *control = FindChildByName(controlName);
if (control)
{
if (string[0] == '#')
{
const wchar_t *wszText = localize()->Find(string);
if (wszText)
{
PostMessage(control, new KeyValues("SetText", "text", wszText));
}
}
else
{
PostMessage(control, new KeyValues("SetText", "text", string));
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Shortcut function to set data in child controls
//-----------------------------------------------------------------------------
void EditablePanel::SetControlInt(const char *controlName, int state)
{
Panel *control = FindChildByName(controlName);
if (control)
{
PostMessage(control, new KeyValues("SetState", "state", state));
}
}
//-----------------------------------------------------------------------------
// Purpose: Shortcut function to get data in child controls
//-----------------------------------------------------------------------------
int EditablePanel::GetControlInt(const char *controlName, int defaultState)
{
Panel *control = FindChildByName(controlName);
if (control)
{
KeyValues *data = new KeyValues("GetState");
if (control->RequestInfo(data))
{
int state = data->GetInt("state", defaultState);
data->deleteThis();
return state;
}
}
return defaultState;
}
//-----------------------------------------------------------------------------
// Purpose: Shortcut function to get data in child controls
//-----------------------------------------------------------------------------
const char *EditablePanel::GetControlString(const char *controlName, const char *defaultString)
{
static char buf[512];
GetControlString(controlName, buf, sizeof(buf) - 1, defaultString);
return buf;
}
//-----------------------------------------------------------------------------
// Purpose: Shortcut function to get data in child controls
//-----------------------------------------------------------------------------
void EditablePanel::GetControlString(const char *controlName, char *buf, int bufSize, const char *defaultString)
{
Panel *control = FindChildByName(controlName);
KeyValues *data = new KeyValues("GetText");
if (control && control->RequestInfo(data))
{
Q_strncpy(buf, data->GetString("text", defaultString), bufSize);
}
else
{
// no value found, copy in default text
Q_strncpy(buf, defaultString, bufSize);
}
// ensure null termination of string
buf[bufSize - 1] = 0;
// free
data->deleteThis();
}
//-----------------------------------------------------------------------------
// Purpose: localization variables (used in constructing UI strings)
//-----------------------------------------------------------------------------
void EditablePanel::SetDialogVariable(const char *varName, const char *value)
{
GetDialogVariables()->SetString(varName, value);
ForceSubPanelsToUpdateWithNewDialogVariables();
}
//-----------------------------------------------------------------------------
// Purpose: localization variables (used in constructing UI strings)
//-----------------------------------------------------------------------------
void EditablePanel::SetDialogVariable(const char *varName, const wchar_t *value)
{
GetDialogVariables()->SetWString(varName, value);
ForceSubPanelsToUpdateWithNewDialogVariables();
}
//-----------------------------------------------------------------------------
// Purpose: localization variables (used in constructing UI strings)
//-----------------------------------------------------------------------------
void EditablePanel::SetDialogVariable(const char *varName, int value)
{
GetDialogVariables()->SetInt(varName, value);
ForceSubPanelsToUpdateWithNewDialogVariables();
}
//-----------------------------------------------------------------------------
// Purpose: localization variables (used in constructing UI strings)
//-----------------------------------------------------------------------------
void EditablePanel::SetDialogVariable(const char *varName, float value)
{
GetDialogVariables()->SetFloat(varName, value);
ForceSubPanelsToUpdateWithNewDialogVariables();
}
//-----------------------------------------------------------------------------
// Purpose: redraws child panels with new localization vars
//-----------------------------------------------------------------------------
void EditablePanel::ForceSubPanelsToUpdateWithNewDialogVariables()
{
if (m_pDialogVariables)
{
ipanel()->SendMessage(GetVPanel(), m_pDialogVariables, GetVPanel());
for (int i = 0; i < ipanel()->GetChildCount(GetVPanel()); i++)
{
ipanel()->SendMessage(ipanel()->GetChild(GetVPanel(), i), m_pDialogVariables, GetVPanel());
}
}
}
//-----------------------------------------------------------------------------
// Purpose: lazy creation of localization vars object
//-----------------------------------------------------------------------------
KeyValues *EditablePanel::GetDialogVariables()
{
if (m_pDialogVariables)
return m_pDialogVariables;
m_pDialogVariables = new KeyValues("DialogVariables");
return m_pDialogVariables;
}
//-----------------------------------------------------------------------------
// Purpose: Virtual factory for control creation
//-----------------------------------------------------------------------------
Panel *EditablePanel::CreateControlByName(const char *controlName)
{
#ifndef _XBOX
Panel *fromFactory = CBuildFactoryHelper::InstancePanel( controlName );
if ( fromFactory )
{
return fromFactory;
}
#endif
return NULL;
}

View File

@ -0,0 +1,113 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#include <stdarg.h>
#include <stdio.h>
#include <vgui/ISurface.h>
#include <vgui/IScheme.h>
#include <KeyValues.h>
#include <vgui_controls/Image.h>
#include <vgui_controls/ExpandButton.h>
#include <vgui_controls/TextImage.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
DECLARE_BUILD_FACTORY( ExpandButton );
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
ExpandButton::ExpandButton( Panel *parent, const char *panelName ) : ToggleButton( parent, panelName, "" )
{
m_bExpandable = true;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
ExpandButton::~ExpandButton()
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ExpandButton::ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
m_Color = GetSchemeColor( "ExpandButton.Color", pScheme );
m_hFont = pScheme->GetFont("Marlett", IsProportional() );
// don't draw a background
SetPaintBackgroundEnabled(false);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
IBorder *ExpandButton::GetBorder(bool depressed, bool armed, bool selected, bool keyfocus)
{
return NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Expand the button
//-----------------------------------------------------------------------------
void ExpandButton::SetSelected(bool state)
{
if ( m_bExpandable && ( state != IsSelected() ) )
{
// send a message saying we've been checked
KeyValues *msg = new KeyValues("Expanded", "state", (int)state);
PostActionSignal(msg);
BaseClass::SetSelected(state);
}
}
//-----------------------------------------------------------------------------
// Purpose: sets whether or not the state of the check can be changed
//-----------------------------------------------------------------------------
void ExpandButton::SetExpandable(bool state)
{
m_bExpandable = state;
Repaint();
}
void ExpandButton::Paint()
{
surface()->DrawSetTextFont( m_hFont );
wchar_t code = IsSelected( ) ? L'6' : L'4';
wchar_t pString[2] = { code, 0 };
// draw selected check
int tw, th, w, h;
GetSize( w, h );
surface()->GetTextSize( m_hFont, pString, tw, th );
surface()->DrawSetTextColor( m_Color );
surface()->DrawSetTextPos( ( w - tw ) / 2, ( h - th ) / 2 );
surface()->DrawUnicodeChar( code );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ExpandButton::OnExpanded(Panel *panel)
{
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,429 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <assert.h>
#include <vgui/ISurface.h>
#include <vgui/IVGui.h>
#include <vgui/IPanel.h>
#include <vgui/VGUI.h>
#include <KeyValues.h>
#include <tier0/dbg.h>
#include <vgui_controls/Controls.h>
#include <vgui_controls/FocusNavGroup.h>
#include <vgui_controls/Panel.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
// Input : *panel - parent panel
//-----------------------------------------------------------------------------
FocusNavGroup::FocusNavGroup(Panel *panel) : _mainPanel(panel)
{
_currentFocus = NULL;
_topLevelFocus = false;
_defaultButton = NULL;
_currentDefaultButton = NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
FocusNavGroup::~FocusNavGroup()
{
}
//-----------------------------------------------------------------------------
// Purpose: Sets the focus to the previous panel in the tab order
// Input : *panel - panel currently with focus
//-----------------------------------------------------------------------------
bool FocusNavGroup::RequestFocusPrev(VPANEL panel)
{
if(panel==NULL)
return false;
_currentFocus = NULL;
int newPosition = 9999999;
if (panel)
{
newPosition = ipanel()->GetTabPosition(panel);
}
bool bFound = false;
bool bRepeat = true;
Panel *best = NULL;
while (1)
{
newPosition--;
if (newPosition > 0)
{
int bestPosition = 0;
// look for the next tab position
for (int i = 0; i < _mainPanel->GetChildCount(); i++)
{
Panel *child = _mainPanel->GetChild(i);
if (child && child->IsVisible() && child->IsEnabled() && child->GetTabPosition())
{
int tabPosition = child->GetTabPosition();
if (tabPosition == newPosition)
{
// we've found the right tab
best = child;
bestPosition = newPosition;
// don't loop anymore since we've found the correct panel
break;
}
else if (tabPosition < newPosition && tabPosition > bestPosition)
{
// record the match since this is the closest so far
bestPosition = tabPosition;
best = child;
}
}
}
if (!bRepeat)
break;
if (best)
break;
}
else
{
// reset new position for next loop
newPosition = 9999999;
}
// haven't found an item
if (!_topLevelFocus)
{
// check to see if we should push the focus request up
if (_mainPanel->GetVParent() && _mainPanel->GetVParent() != surface()->GetEmbeddedPanel())
{
// we're not a top level panel, so forward up the request instead of looping
if (ipanel()->RequestFocusPrev(_mainPanel->GetVParent(), _mainPanel->GetVPanel()))
{
bFound = true;
SetCurrentDefaultButton(NULL);
break;
}
}
}
// not found an item, loop back
newPosition = 9999999;
bRepeat = false;
}
if (best)
{
_currentFocus = best->GetVPanel();
best->RequestFocus(-1);
bFound = true;
if (!CanButtonBeDefault(best->GetVPanel()))
{
if (_defaultButton)
{
SetCurrentDefaultButton(_defaultButton);
}
else
{
SetCurrentDefaultButton(NULL);
// we need to ask the parent to set its default button
if (_mainPanel->GetVParent())
{
ivgui()->PostMessage(_mainPanel->GetVParent(), new KeyValues("FindDefaultButton"), NULL);
}
}
}
else
{
SetCurrentDefaultButton(best->GetVPanel());
}
}
return bFound;
}
//-----------------------------------------------------------------------------
// Purpose: Sets the focus to the previous panel in the tab order
// Input : *panel - panel currently with focus
//-----------------------------------------------------------------------------
bool FocusNavGroup::RequestFocusNext(VPANEL panel)
{
// basic recursion guard, in case user has set up a bad focus hierarchy
static int stack_depth = 0;
stack_depth++;
_currentFocus = NULL;
int newPosition = 0;
if (panel)
{
newPosition = ipanel()->GetTabPosition(panel);
}
bool bFound = false;
bool bRepeat = true;
Panel *best = NULL;
while (1)
{
newPosition++;
int bestPosition = 999999;
// look for the next tab position
for (int i = 0; i < _mainPanel->GetChildCount(); i++)
{
Panel *child = _mainPanel->GetChild(i);
if ( !child )
continue;
if (child && child->IsVisible() && child->IsEnabled() && child->GetTabPosition())
{
int tabPosition = child->GetTabPosition();
if (tabPosition == newPosition)
{
// we've found the right tab
best = child;
bestPosition = newPosition;
// don't loop anymore since we've found the correct panel
break;
}
else if (tabPosition > newPosition && tabPosition < bestPosition)
{
// record the match since this is the closest so far
bestPosition = tabPosition;
best = child;
}
}
}
if (!bRepeat)
break;
if (best)
break;
// haven't found an item
// check to see if we should push the focus request up
if (!_topLevelFocus)
{
if (_mainPanel->GetVParent() && _mainPanel->GetVParent() != surface()->GetEmbeddedPanel())
{
// we're not a top level panel, so forward up the request instead of looping
if (stack_depth < 15)
{
if (ipanel()->RequestFocusNext(_mainPanel->GetVParent(), _mainPanel->GetVPanel()))
{
bFound = true;
SetCurrentDefaultButton(NULL);
break;
}
// if we find one then we break, otherwise we loop
}
}
}
// loop back
newPosition = 0;
bRepeat = false;
}
if (best)
{
_currentFocus = best->GetVPanel();
best->RequestFocus(1);
bFound = true;
if (!CanButtonBeDefault(best->GetVPanel()))
{
if (_defaultButton)
{
SetCurrentDefaultButton(_defaultButton);
}
else
{
SetCurrentDefaultButton(NULL);
// we need to ask the parent to set its default button
if (_mainPanel->GetVParent())
{
ivgui()->PostMessage(_mainPanel->GetVParent(), new KeyValues("FindDefaultButton"), NULL);
}
}
}
else
{
SetCurrentDefaultButton(best->GetVPanel());
}
}
stack_depth--;
return bFound;
}
//-----------------------------------------------------------------------------
// Purpose: sets the panel that owns this FocusNavGroup to be the root in the focus traversal heirarchy
//-----------------------------------------------------------------------------
void FocusNavGroup::SetFocusTopLevel(bool state)
{
_topLevelFocus = state;
}
//-----------------------------------------------------------------------------
// Purpose: sets panel which receives input when ENTER is hit
//-----------------------------------------------------------------------------
void FocusNavGroup::SetDefaultButton(Panel *panel)
{
if ((panel == NULL && _defaultButton.Get() == NULL) || panel->GetVPanel() == _defaultButton.Get())
return;
Assert(CanButtonBeDefault(panel->GetVPanel()));
_defaultButton = panel->GetVPanel();
SetCurrentDefaultButton(_defaultButton);
}
//-----------------------------------------------------------------------------
// Purpose: sets panel which receives input when ENTER is hit
//-----------------------------------------------------------------------------
void FocusNavGroup::SetCurrentDefaultButton(VPANEL panel, bool sendCurrentDefaultButtonMessage)
{
if (panel == _currentDefaultButton.Get())
return;
if ( sendCurrentDefaultButtonMessage && _currentDefaultButton.Get() != NULL)
{
ivgui()->PostMessage(_currentDefaultButton, new KeyValues("SetAsCurrentDefaultButton", "state", 0), NULL);
}
_currentDefaultButton = panel;
if ( sendCurrentDefaultButtonMessage && _currentDefaultButton.Get() != NULL)
{
ivgui()->PostMessage(_currentDefaultButton, new KeyValues("SetAsCurrentDefaultButton", "state", 1), NULL);
}
}
//-----------------------------------------------------------------------------
// Purpose: sets panel which receives input when ENTER is hit
//-----------------------------------------------------------------------------
VPANEL FocusNavGroup::GetCurrentDefaultButton()
{
return _currentDefaultButton;
}
//-----------------------------------------------------------------------------
// Purpose: sets panel which receives input when ENTER is hit
//-----------------------------------------------------------------------------
VPANEL FocusNavGroup::GetDefaultButton()
{
return _defaultButton;
}
//-----------------------------------------------------------------------------
// Purpose: finds the panel which is activated by the specified key
// Input : code - the keycode of the hotkey
// Output : Panel * - NULL if no panel found
//-----------------------------------------------------------------------------
Panel *FocusNavGroup::FindPanelByHotkey(wchar_t key)
{
for (int i = 0; i < _mainPanel->GetChildCount(); i++)
{
Panel *child = _mainPanel->GetChild(i);
if ( !child )
continue;
Panel *hot = child->HasHotkey(key);
if (hot && hot->IsVisible() && hot->IsEnabled())
{
return hot;
}
}
return NULL;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
Panel *FocusNavGroup::GetDefaultPanel()
{
for (int i = 0; i < _mainPanel->GetChildCount(); i++)
{
Panel *child = _mainPanel->GetChild(i);
if ( !child )
continue;
if (child->GetTabPosition() == 1)
{
return child;
}
}
return NULL; // no specific panel set
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
Panel *FocusNavGroup::GetCurrentFocus()
{
return _currentFocus ? ipanel()->GetPanel(_currentFocus, vgui::GetControlsModuleName()) : NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Sets the current focus
//-----------------------------------------------------------------------------
VPANEL FocusNavGroup::SetCurrentFocus(VPANEL focus, VPANEL defaultPanel)
{
_currentFocus = focus;
// if we haven't found a default panel yet, let's see if we know of one
if (defaultPanel == NULL)
{
// can this focus itself by the default
if (CanButtonBeDefault(focus))
{
defaultPanel = focus;
}
else if (_defaultButton) // do we know of a default button
{
defaultPanel = _defaultButton;
}
}
SetCurrentDefaultButton(defaultPanel);
return defaultPanel;
}
//-----------------------------------------------------------------------------
// Purpose: Returns true if the specified panel can be the default
//-----------------------------------------------------------------------------
bool FocusNavGroup::CanButtonBeDefault(VPANEL panel)
{
KeyValues *data = new KeyValues("CanBeDefaultButton");
bool bResult = false;
if (ipanel()->RequestInfo(panel, data))
{
bResult = (data->GetInt("result") == 1);
}
data->deleteThis();
return bResult;
}

2164
vgui2/controls/Frame.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,308 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include <math.h>
#include <vgui_controls/GraphPanel.h>
#include <vgui/IScheme.h>
#include <vgui/ISurface.h>
#include <vgui/IVGui.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
DECLARE_BUILD_FACTORY( GraphPanel );
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
GraphPanel::GraphPanel(Panel *parent, const char *name) : BaseClass(parent, name)
{
m_flDomainSize = 100.0f;
m_flLowRange = 0.0f;
m_flHighRange = 1.0f;
m_bUseDynamicRange = true;
m_flMinDomainSize = 0.0f;
m_flMaxDomainSize = 0.0f;
m_bMaxDomainSizeSet = false;
// rendering, need to pull these from scheme/res file
m_iGraphBarWidth = 2;
m_iGraphBarGapWidth = 2;
}
//-----------------------------------------------------------------------------
// Purpose: domain settings (x-axis settings)
//-----------------------------------------------------------------------------
void GraphPanel::SetDisplayDomainSize(float size)
{
m_flDomainSize = size;
// set the max domain size if it hasn't been set yet
if (!m_bMaxDomainSizeSet)
{
SetMaxDomainSize(size);
}
}
//-----------------------------------------------------------------------------
// Purpose: sets the smallest domain that will be displayed
//-----------------------------------------------------------------------------
void GraphPanel::SetMinDomainSize(float size)
{
m_flMinDomainSize = size;
}
//-----------------------------------------------------------------------------
// Purpose: sets the samples to keep
//-----------------------------------------------------------------------------
void GraphPanel::SetMaxDomainSize(float size)
{
m_flMaxDomainSize = size;
m_bMaxDomainSizeSet = true;
}
//-----------------------------------------------------------------------------
// Purpose: range settings (y-axis settings)
//-----------------------------------------------------------------------------
void GraphPanel::SetUseFixedRange(float lowRange, float highRange)
{
m_bUseDynamicRange = false;
m_flLowRange = lowRange;
m_flHighRange = highRange;
}
//-----------------------------------------------------------------------------
// Purpose: Sets the graph to dynamically determine the range
//-----------------------------------------------------------------------------
void GraphPanel::SetUseDynamicRange(float *rangeList, int numRanges)
{
m_bUseDynamicRange = true;
m_RangeList.CopyArray(rangeList, numRanges);
}
//-----------------------------------------------------------------------------
// Purpose: Gets the currently displayed range
//-----------------------------------------------------------------------------
void GraphPanel::GetDisplayedRange(float &lowRange, float &highRange)
{
lowRange = m_flLowRange;
highRange = m_flHighRange;
}
//-----------------------------------------------------------------------------
// Purpose: adds an item to the end of the list
//-----------------------------------------------------------------------------
void GraphPanel::AddItem(float sampleEnd, float sampleValue)
{
if (m_Samples.Count() && m_Samples[m_Samples.Tail()].value == sampleValue)
{
// collapse identical samples
m_Samples[m_Samples.Tail()].sampleEnd = sampleEnd;
}
else
{
// add to the end of the samples list
Sample_t item;
item.value = sampleValue;
item.sampleEnd = sampleEnd;
m_Samples.AddToTail(item);
}
// see if this frees up any samples past the end
if (m_bMaxDomainSizeSet)
{
float freePoint = sampleEnd - m_flMaxDomainSize;
while (m_Samples[m_Samples.Head()].sampleEnd < freePoint)
{
m_Samples.Remove(m_Samples.Head());
}
}
/*
// see the max number of samples necessary to display this information reasonably precisely
static const int MAX_LIKELY_GRAPH_WIDTH = 800;
int maxSamplesNeeded = 2 * MAX_LIKELY_GRAPH_WIDTH / (m_iGraphBarWidth + m_iGraphBarGapWidth);
if (m_Samples.Count() > 2)
{
// see if we can collapse some items
float highestSample = m_Samples[m_Samples.Tail()].sampleEnd;
// iterate the items
// always keep the head around so we have something to go against
int sampleIndex = m_Samples.Next(m_Samples.Head());
int nextSampleIndex = m_Samples.Next(sampleIndex);
while (m_Samples.IsInList(nextSampleIndex))
{
// calculate what sampling precision is actually needed to display this data
float distanceFromEnd = highestSample - m_Samples[sampleIndex].sampleEnd;
// if (distanceFromEnd < m_flDomainSize)
// break;
//!! this calculation is very incorrect
float minNeededSampleSize = distanceFromEnd / (m_flMinDomainSize * maxSamplesNeeded);
float sampleSize = m_Samples[nextSampleIndex].sampleEnd - m_Samples[sampleIndex].sampleEnd;
if (sampleSize < minNeededSampleSize)
{
// collapse the item into the next index
m_Samples[nextSampleIndex].value = 0.5f * (m_Samples[nextSampleIndex].value + m_Samples[sampleIndex].value);
// remove the item from the list
m_Samples.Remove(sampleIndex);
// move to the next item
sampleIndex = nextSampleIndex;
nextSampleIndex = m_Samples.Next(sampleIndex);
}
else
{
// this item didn't need collapsing, so assume the next item won't
break;
}
}
}
*/
InvalidateLayout();
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: returns number of items that can be displayed
//-----------------------------------------------------------------------------
int GraphPanel::GetVisibleItemCount()
{
return GetWide() / (m_iGraphBarWidth + m_iGraphBarGapWidth);
}
//-----------------------------------------------------------------------------
// Purpose: lays out the graph
//-----------------------------------------------------------------------------
void GraphPanel::PerformLayout()
{
BaseClass::PerformLayout();
}
//-----------------------------------------------------------------------------
// Purpose: draws the graph
//-----------------------------------------------------------------------------
void GraphPanel::Paint()
{
if (!m_Samples.Count())
return;
// walk from right to left drawing the resampled data
int sampleIndex = m_Samples.Tail();
int x = GetWide() - (m_iGraphBarWidth + m_iGraphBarGapWidth);
// calculate how big each sample should be
float sampleSize = m_flDomainSize / GetVisibleItemCount();
// calculate where in the domain we start resampling
float resampleStart = m_Samples[sampleIndex].sampleEnd - sampleSize;
// always resample from a sample point that is a multiple of the sampleSize
resampleStart -= (float)fmod(resampleStart, sampleSize);
// bar size multiplier
float barSizeMultiplier = GetTall() / (m_flHighRange - m_flLowRange);
// set render color
surface()->DrawSetColor(GetFgColor());
// recalculate the sample range for dynamic resizing
float flMinValue = m_Samples[m_Samples.Head()].value;
float flMaxValue = m_Samples[m_Samples.Head()].value;
// iterate the bars to draw
while (x > 0 && m_Samples.IsInList(sampleIndex))
{
// move back the drawing point
x -= (m_iGraphBarWidth + m_iGraphBarGapWidth);
// collect the samples
float value = 0.0f;
float maxValue = 0.0f;
int samplesTouched = 0;
int prevSampleIndex = m_Samples.Previous(sampleIndex);
while (m_Samples.IsInList(prevSampleIndex))
{
// take the value
value += m_Samples[sampleIndex].value;
samplesTouched++;
// do some work to calculate the sample range
if (m_Samples[sampleIndex].value < flMinValue)
{
flMinValue = m_Samples[sampleIndex].value;
}
if (m_Samples[sampleIndex].value > flMaxValue)
{
flMaxValue = m_Samples[sampleIndex].value;
}
if (m_Samples[sampleIndex].value > maxValue)
{
maxValue = m_Samples[sampleIndex].value;
}
if (resampleStart < m_Samples[prevSampleIndex].sampleEnd)
{
// we're out of the sampling range, we need to move on to the next sample
sampleIndex = prevSampleIndex;
prevSampleIndex = m_Samples.Previous(sampleIndex);
}
else
{
// we're done with this resample
// move back the resample start
resampleStart -= sampleSize;
// draw the current item
break;
}
}
// draw the item
// show the max value in the sample, not the average
int size = (int)(maxValue * barSizeMultiplier);
// int size = (int)((value * barSizeMultiplier) / samplesTouched);
surface()->DrawFilledRect(x, GetTall() - size, x + m_iGraphBarWidth, GetTall());
}
// calculate our final range (for use next frame)
if (m_bUseDynamicRange)
{
flMinValue = 0;
// find the range that fits
for (int i = 0; i < m_RangeList.Count(); i++)
{
if (m_RangeList[i] > flMaxValue)
{
flMaxValue = m_RangeList[i];
break;
}
}
m_flLowRange = flMinValue;
m_flHighRange = flMaxValue;
}
}
//-----------------------------------------------------------------------------
// Purpose: sets up colors
//-----------------------------------------------------------------------------
void GraphPanel::ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
SetFgColor(GetSchemeColor("GraphPanel.FgColor", pScheme));
SetBgColor(GetSchemeColor("GraphPanel.BgColor", pScheme));
SetBorder(pScheme->GetBorder("ButtonDepressedBorder"));
}

756
vgui2/controls/HTML.cpp Normal file
View File

@ -0,0 +1,756 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
// This class is a message box that has two buttons, ok and cancel instead of
// just the ok button of a message box. We use a message box class for the ok button
// and implement another button here.
//
// $NoKeywords: $
//=============================================================================//
#include "OfflineMode.h"
#include "vgui/Cursor.h"
#include "vgui/IScheme.h"
#include "vgui/ISystem.h"
#include "vgui/ISurface.h"
#include "vgui/IVGUI.h"
#include "vgui/IBorder.h"
#include "filesystem.h"
#include "vgui_controls/HTML.h"
#include "vgui_controls/Controls.h"
#include "vgui_controls/Label.h"
#include "vgui_controls/Image.h"
#include "vgui_controls/ScrollBar.h"
#include "KeyValues.h"
#include <stdio.h>
#include "tier0/memdbgon.h"
using namespace vgui;
enum
{
WINDOW_BORDER_WIDTH=1
};
vgui::Panel *HTML_NoJavascript_Factory()
{
return new HTML( NULL, NULL, false );
}
vgui::Panel *HTML_Javascript_Factory()
{
return new HTML( NULL, NULL, true );
}
//DECLARE_BUILD_FACTORY_CUSTOM_ALIAS( HTML, HTML_NoJavascript, HTML_NoJavascript_Factory );
//DECLARE_BUILD_FACTORY_CUSTOM_ALIAS( HTML, HTML_Javascript, HTML_Javascript_Factory );
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
HTML::HTML(Panel *parent, const char *name, bool allowJavaScript) : Panel(parent, name)
{
browser = surface()->CreateHTMLWindow(this, GetVPanel());
Assert(browser != NULL);
m_iNextFrameTime=0;
m_iAnimTime=0;
loading=NULL;
picture=NULL;
m_iScrollBorderX=m_iScrollBorderY=0;
m_iScrollX=m_iScrollY=0;
m_bScrollBarEnabled = true;
m_bContextMenuEnabled = true;
m_bNewWindowsOnly = false;
m_bSetVisibleOnPerformLayout = false;
if ( surface()->SupportsFeature( ISurface::DIRECT_HWND_RENDER ) )
{
SetCursor( dc_blank );
}
_hbar = new ScrollBar(this, "HorizScrollBar", false);
_hbar->SetVisible(false);
_hbar->AddActionSignalTarget(this);
_vbar = new ScrollBar(this, "VertScrollBar", true);
_vbar->SetVisible(false);
_vbar->AddActionSignalTarget(this);
m_bRegenerateHTMLBitmap = true;
SetEnabled(true);
SetVisible(true);
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
HTML::~HTML()
{
surface()->DeleteHTMLWindow(browser);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void HTML::ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
SetBgColor(pScheme->GetColor("HTML.BgColor", GetBgColor()));
SetBorder(pScheme->GetBorder( "BrowserBorder"));
BrowserResize();
}
//-----------------------------------------------------------------------------
// Purpose: Causes the HTML window to repaint itself every 100ms, to allow animaited gifs and the like
//-----------------------------------------------------------------------------
void HTML::StartAnimate(int time)
{
// a tick signal to let the web page re-render itself, in case of animated images
//ivgui()->AddTickSignal(GetVPanel());
m_iAnimTime=time;
}
//-----------------------------------------------------------------------------
// Purpose: stops the repainting
//-----------------------------------------------------------------------------
void HTML::StopAnimate()
{
m_iNextFrameTime=0xffffffff; // next update is at infinity :)
m_iAnimTime=0;
}
//-----------------------------------------------------------------------------
// Purpose: overrides panel class, paints a texture of the HTML window as a background
//-----------------------------------------------------------------------------
void HTML::PaintBackground()
{
BaseClass::PaintBackground();
if (m_bRegenerateHTMLBitmap)
{
if ( !surface()->SupportsFeature( ISurface::DIRECT_HWND_RENDER ) )
{
surface()->PaintHTMLWindow(browser);
}
m_bRegenerateHTMLBitmap = false;
int w, h;
GetSize(w, h);
CalcScrollBars(w, h);
}
if ( surface()->SupportsFeature( ISurface::DIRECT_HWND_RENDER ) )
{
}
else
{
// the window is a textured background
picture = browser->GetBitmap();
if (picture)
{
surface()->DrawSetColor(GetBgColor());
picture->SetPos(0,0);
picture->Paint();
}
// If we have scrollbars, we need to draw the bg color under them, since the browser
// bitmap is a checkerboard under them, and they are transparent in the in-game client
if ( m_iScrollBorderX > 0 || m_iScrollBorderY > 0 )
{
int w, h;
GetSize( w, h );
IBorder *border = GetBorder();
int left = 0, top = 0, right = 0, bottom = 0;
if ( border )
{
border->GetInset( left, top, right, bottom );
}
surface()->DrawSetColor( GetBgColor() );
if ( m_iScrollBorderX )
{
surface()->DrawFilledRect( w-m_iScrollBorderX - right, top, w - right, h - bottom );
}
if ( m_iScrollBorderY )
{
surface()->DrawFilledRect( left, h-m_iScrollBorderY - bottom, w-m_iScrollBorderX - right, h - bottom );
}
}
}
}
//-----------------------------------------------------------------------------
// Purpose: causes a repaint when the layout changes
//-----------------------------------------------------------------------------
void HTML::PerformLayout()
{
BaseClass::PerformLayout();
Repaint();
if ( m_bSetVisibleOnPerformLayout )
{
browser->SetVisible( true );
m_bSetVisibleOnPerformLayout= false;
}
}
//-----------------------------------------------------------------------------
// Purpose: passthru to the HTML surface widget
//-----------------------------------------------------------------------------
void HTML::SetVisible( bool state )
{
BaseClass::SetVisible( state );
int w, h;
GetSize(w, h);
CalcScrollBars(w, h);
BrowserResize();
if ( !state ) // allow the visibleonlayout flag to be turned off
{
m_bSetVisibleOnPerformLayout = false;
}
if ( IsLayoutInvalid() && state ) // only set visible on performlayout IF you are setting it visible
{
m_bSetVisibleOnPerformLayout = true;
}
else
{
browser->SetVisible( state );
}
}
//-----------------------------------------------------------------------------
// Purpose: updates the underlying HTML surface widgets position
//-----------------------------------------------------------------------------
void HTML::OnMove()
{
BaseClass::OnMove();
BrowserResize();
}
//-----------------------------------------------------------------------------
// Purpose: calculates the need for and position of both horizontal and vertical scroll bars
//-----------------------------------------------------------------------------
void HTML::CalcScrollBars(int w, int h)
{
int img_w, img_h;
if (m_bScrollBarEnabled )
{
browser->GetHTMLSize(img_w, img_h);
if ( img_w < 0 || img_h < 0 )
{
m_iScrollBorderX = 0;
m_iScrollBorderY=0;
_vbar->SetVisible(false);
_hbar->SetVisible(false);
BrowserResize();
return;
}
if (img_h > h)
{
if (!_vbar->IsVisible())
{
_vbar->SetVisible(true);
// displayable area has changed, need to force an update
PostMessage(this, new KeyValues("ScrollBarSliderMoved"), 0.02f);
}
_vbar->SetEnabled(false);
_vbar->SetRangeWindow( h/2-5 );
_vbar->SetRange( 0, img_h);
_vbar->SetButtonPressedScrollValue( 5 );
_vbar->SetPos(w - (_vbar->GetWide()+WINDOW_BORDER_WIDTH), WINDOW_BORDER_WIDTH);
if(img_w>w)
{
_vbar->SetSize(_vbar->GetWide(), h-_vbar->GetWide()-1-WINDOW_BORDER_WIDTH);
}
else
{
_vbar->SetSize(_vbar->GetWide(), h-1-WINDOW_BORDER_WIDTH);
}
m_iScrollBorderX=_vbar->GetWide()+WINDOW_BORDER_WIDTH;
}
else
{
m_iScrollBorderX=0;
_vbar->SetVisible(false);
BrowserResize();
}
if (img_w > w)
{
_hbar->SetVisible(true);
_hbar->SetEnabled(false);
_hbar->SetRangeWindow( w/2-5 );
_hbar->SetRange( 0, img_w);
_hbar->SetButtonPressedScrollValue( 5 );
_hbar->SetPos(WINDOW_BORDER_WIDTH,h-(_vbar->GetWide()+WINDOW_BORDER_WIDTH));
if(img_h>h)
{
_hbar->SetSize(w-_vbar->GetWide()-WINDOW_BORDER_WIDTH,_vbar->GetWide());
}
else
{
_hbar->SetSize(w-WINDOW_BORDER_WIDTH,_vbar->GetWide());
}
m_iScrollBorderY=_vbar->GetWide()+WINDOW_BORDER_WIDTH+1;
}
else
{
m_iScrollBorderY=0;
_hbar->SetVisible(false);
BrowserResize();
}
}
else
{
_vbar->SetVisible(false);
_hbar->SetVisible(false);
BrowserResize();
}
}
//-----------------------------------------------------------------------------
// Purpose: opens the URL, will accept any URL that IE accepts
//-----------------------------------------------------------------------------
void HTML::OpenURL(const char *URL, bool force)
{
if ( IsSteamInOfflineMode() && !force )
{
const char *baseDir = getenv("HTML_OFFLINE_DIR");
if ( baseDir )
{
// get the app we need to run
char htmlLocation[_MAX_PATH];
char otherName[128];
char fileLocation[_MAX_PATH];
if ( ! vgui::filesystem()->FileExists( baseDir ) )
{
_snprintf( otherName, sizeof(otherName), "%senglish.html", OFFLINE_FILE );
baseDir = otherName;
}
vgui::filesystem()->GetLocalCopy( baseDir ); // put this file on disk for IE to load
vgui::filesystem()->GetLocalPath( baseDir, fileLocation, sizeof(fileLocation) );
_snprintf(htmlLocation, sizeof(htmlLocation), "file://%s", fileLocation);
browser->OpenURL( htmlLocation );
}
else
{
browser->OpenURL(URL);
}
}
else
{
browser->OpenURL(URL);
}
}
//-----------------------------------------------------------------------------
// Purpose: opens the URL, will accept any URL that IE accepts
//-----------------------------------------------------------------------------
bool HTML::StopLoading()
{
return browser->StopLoading();
}
//-----------------------------------------------------------------------------
// Purpose: refreshes the current page
//-----------------------------------------------------------------------------
bool HTML::Refresh()
{
return browser->Refresh();
}
//-----------------------------------------------------------------------------
// Purpose: empties the current HTML container of any HTML text (used in conjunction with AddText)
//-----------------------------------------------------------------------------
void HTML::Clear()
{
browser->Clear();
}
//-----------------------------------------------------------------------------
// Purpose: appends "text" to the end of the current page. "text" should be a HTML formatted string
//-----------------------------------------------------------------------------
void HTML::AddText(const char *text)
{
browser->AddText(text);
}
//-----------------------------------------------------------------------------
// Purpose: handle resizing
//-----------------------------------------------------------------------------
void HTML::OnSizeChanged(int wide,int tall)
{
BaseClass::OnSizeChanged(wide,tall);
CalcScrollBars(wide,tall);
BrowserResize();
m_bRegenerateHTMLBitmap = true;
if ( !surface()->SupportsFeature( ISurface::DIRECT_HWND_RENDER ) )
{
Repaint();
}
}
//-----------------------------------------------------------------------------
// Purpose: used for the animation calls above, to repaint the screen
// periodically. ( NOT USED !!!)
//-----------------------------------------------------------------------------
void HTML::OnTick()
{
if (IsVisible() && m_iAnimTime && system()->GetTimeMillis() >= m_iNextFrameTime)
{
m_iNextFrameTime = system()->GetTimeMillis() + m_iAnimTime;
m_bRegenerateHTMLBitmap = true;
if ( !surface()->SupportsFeature( ISurface::DIRECT_HWND_RENDER ) )
{
Repaint();
}
}
}
//-----------------------------------------------------------------------------
// Purpose: passes mouse clicks to the control
//-----------------------------------------------------------------------------
void HTML::OnMousePressed(MouseCode code)
{
// ask for the focus to come to this window
RequestFocus();
// now tell the browser about the click
// ignore right clicks if context menu has been disabled
if (code != MOUSE_RIGHT || m_bContextMenuEnabled)
{
if (browser)
{
browser->OnMouse(code,IHTML::DOWN,m_iMouseX,m_iMouseY);
}
}
m_bRegenerateHTMLBitmap = true;
if ( !surface()->SupportsFeature( ISurface::DIRECT_HWND_RENDER ) )
{
Repaint();
}
}
//-----------------------------------------------------------------------------
// Purpose: passes mouse up events
//-----------------------------------------------------------------------------
void HTML::OnMouseReleased(MouseCode code)
{
if (browser)
{
browser->OnMouse(code, IHTML::UP, m_iMouseX, m_iMouseY);
}
m_bRegenerateHTMLBitmap = true;
if ( !surface()->SupportsFeature( ISurface::DIRECT_HWND_RENDER ) )
{
Repaint();
}
}
//-----------------------------------------------------------------------------
// Purpose: keeps track of where the cursor is
//-----------------------------------------------------------------------------
void HTML::OnCursorMoved(int x,int y)
{
MouseCode code=MOUSE_LEFT;
m_iMouseX=x;
m_iMouseY=y;
if(browser) browser->OnMouse(code,IHTML::MOVE,x,y);
}
//-----------------------------------------------------------------------------
// Purpose: passes double click events to the browser
//-----------------------------------------------------------------------------
void HTML::OnMouseDoublePressed(MouseCode code)
{
if (browser)
{
browser->OnMouse(code, IHTML::DOWN, m_iMouseX, m_iMouseY);
}
m_bRegenerateHTMLBitmap = true;
if ( !surface()->SupportsFeature( ISurface::DIRECT_HWND_RENDER ) )
{
Repaint();
}
}
//-----------------------------------------------------------------------------
// Purpose: passes key presses to the browser (we don't current do this)
//-----------------------------------------------------------------------------
void HTML::OnKeyTyped(wchar_t unichar)
{
// the OnKeyCodeDown member handles this
}
//-----------------------------------------------------------------------------
// Purpose: passes key presses to the browser
//-----------------------------------------------------------------------------
void HTML::OnKeyCodePressed(KeyCode code)
{
RequestFocus();
if( code == KEY_PAGEDOWN || code == KEY_SPACE)
{
int val = _vbar->GetValue();
val += 200;
_vbar->SetValue(val);
}
else if ( code == KEY_PAGEUP )
{
int val = _vbar->GetValue();
val -= 200;
_vbar->SetValue(val);
}
if(browser) browser->OnKeyDown(code);
m_bRegenerateHTMLBitmap = true;
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: scrolls the vertical scroll bar on a web page
//-----------------------------------------------------------------------------
void HTML::OnMouseWheeled(int delta)
{
if (_vbar)
{
int val = _vbar->GetValue();
val -= (delta * 25);
_vbar->SetValue(val);
}
}
//-----------------------------------------------------------------------------
// Purpose: Inserts a custom URL handler
//-----------------------------------------------------------------------------
void HTML::AddCustomURLHandler(const char *customProtocolName, vgui::Panel *target)
{
int index = m_CustomURLHandlers.AddToTail();
m_CustomURLHandlers[index].hPanel = target;
strncpy(m_CustomURLHandlers[index].url, customProtocolName, sizeof(m_CustomURLHandlers[index].url));
}
//-----------------------------------------------------------------------------
// Purpose: gets called when a URL is first being loaded
// Return: return TRUE to continue loading, FALSE to stop this URL loading.
//-----------------------------------------------------------------------------
bool HTML::OnStartURL(const char *url, const char *target, bool first)
{
if ( IsVisible() && !surface()->SupportsFeature( ISurface::DIRECT_HWND_RENDER ) )
{
SetCursor( dc_arrow );
}
// see if we have a custom handler for this
bool bURLHandled = false;
for (int i = 0; i < m_CustomURLHandlers.Count(); i++)
{
if (!strnicmp(m_CustomURLHandlers[i].url, url, strlen(m_CustomURLHandlers[i].url)))
{
// we have a custom handler
Panel *target = m_CustomURLHandlers[i].hPanel;
if (target)
{
PostMessage(target, new KeyValues("CustomURL", "url", url + strlen(m_CustomURLHandlers[i].url) + 3, "protocol", m_CustomURLHandlers[i].url));
}
bURLHandled = true;
}
}
if (bURLHandled)
return false;
if ( m_bNewWindowsOnly )
{
if ( target && ( !stricmp( target, "_blank" ) || !stricmp( target, "_new" ) ) ) // only allow NEW windows (_blank ones)
{
return true;
}
else
{
return false;
}
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose: shared code for sizing the HTML surface window
//-----------------------------------------------------------------------------
void HTML::BrowserResize()
{
int w,h;
GetSize( w, h );
IBorder *border;
border = scheme()->GetIScheme(GetScheme())->GetBorder( "BrowserBorder");
int left = 0, top = 0, right = 0, bottom = 0;
if ( border )
{
border->GetInset( left, top, right, bottom );
}
// TODO: does the win32 surface still need this offset when direct rendering?
//left += 1;
//top += 1;
//right += 1;
//bottom += 1;
if(browser)
{
browser->OnSize(m_iScrollX + left, m_iScrollY + top, w-m_iScrollBorderX - right, h-m_iScrollBorderY - bottom);
}
}
//-----------------------------------------------------------------------------
// Purpose: gets called when a URL is finished loading
//-----------------------------------------------------------------------------
void HTML::OnFinishURL(const char *url)
{
// reset the scroll bar positions
_vbar->SetValue(0);
_hbar->SetValue(0);
m_iScrollX = m_iScrollY = 0;
int w, h;
GetSize(w, h);
CalcScrollBars(w, h);
BrowserResize();
m_bRegenerateHTMLBitmap = true; // repaint the window, as we have a new picture to show
if ( !surface()->SupportsFeature( ISurface::DIRECT_HWND_RENDER ) )
{
Repaint();
}
}
//-----------------------------------------------------------------------------
// Purpose: gets called while a URL is loading
//-----------------------------------------------------------------------------
void HTML::OnProgressURL(long current, long maximum)
{
}
//-----------------------------------------------------------------------------
// Purpose: gets called with status text from IE as the page loads
//-----------------------------------------------------------------------------
void HTML::OnSetStatusText(const char *text)
{
}
//-----------------------------------------------------------------------------
// Purpose: get called when IE wants us to redraw
//-----------------------------------------------------------------------------
void HTML::OnUpdate()
{
// only let it redraw every m_iAnimTime milliseconds, so stop it sucking up all the CPU time
if (m_iAnimTime && system()->GetTimeMillis() >= m_iNextFrameTime)
{
m_iNextFrameTime = system()->GetTimeMillis() + m_iAnimTime;
m_bRegenerateHTMLBitmap = true;
if ( !surface()->SupportsFeature( ISurface::DIRECT_HWND_RENDER ) )
{
Repaint();
}
}
int w, h;
GetSize(w, h);
CalcScrollBars(w, h);
BrowserResize();
}
//-----------------------------------------------------------------------------
// Purpose: get called when the cursor moved over a valid URL on the page
//-----------------------------------------------------------------------------
void HTML::OnLink()
{
if( IsVisible() && !surface()->SupportsFeature( ISurface::DIRECT_HWND_RENDER ))
{
SetCursor(dc_hand);
}
}
//-----------------------------------------------------------------------------
// Purpose: get called when the cursor leaves a valid URL
//-----------------------------------------------------------------------------
void HTML::OffLink()
{
if( IsVisible() && !surface()->SupportsFeature( ISurface::DIRECT_HWND_RENDER ))
{
SetCursor(dc_arrow);
}
}
//-----------------------------------------------------------------------------
// Purpose: when a slider moves causes the IE images to re-render itself
//-----------------------------------------------------------------------------
void HTML::OnSliderMoved()
{
if(_hbar->IsVisible())
{
m_iScrollX=_hbar->GetValue();
}
else
{
m_iScrollX=0;
}
if(_vbar->IsVisible())
{
m_iScrollY=_vbar->GetValue();
}
else
{
m_iScrollY=0;
}
BrowserResize();
m_bRegenerateHTMLBitmap = true;
if ( !surface()->SupportsFeature( ISurface::DIRECT_HWND_RENDER ) )
{
Repaint();
}
}
//-----------------------------------------------------------------------------
// Purpose: data accessor
//-----------------------------------------------------------------------------
void HTML::SetScrollbarsEnabled(bool state)
{
m_bScrollBarEnabled = state;
}
//-----------------------------------------------------------------------------
// Purpose: data accessor
//-----------------------------------------------------------------------------
void HTML::SetContextMenuEnabled(bool state)
{
m_bContextMenuEnabled = state;
}
//-----------------------------------------------------------------------------
// Purpose: data accessor
//-----------------------------------------------------------------------------
void HTML::NewWindowsOnly( bool state )
{
m_bNewWindowsOnly = state;
}

265
vgui2/controls/Image.cpp Normal file
View File

@ -0,0 +1,265 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <Color.h>
#include <vgui/IPanel.h>
#include <vgui/ISurface.h>
#include <vgui_controls/Image.h>
#include <vgui_controls/Controls.h>
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Conctructor. Start with default position and default color.
//-----------------------------------------------------------------------------
Image::Image()
{
SetPos(0,0);
SetSize(0,0);
SetColor(Color(255,255,255,255));
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
Image::~Image()
{
}
//-----------------------------------------------------------------------------
// Purpose: Set the position of the image, you need to reset this every time you
// call Paint()
//-----------------------------------------------------------------------------
void Image::SetPos(int x,int y)
{
_pos[0]=x;
_pos[1]=y;
}
//-----------------------------------------------------------------------------
// Purpose: Get the position of the image
//-----------------------------------------------------------------------------
void Image::GetPos(int& x,int& y)
{
x=_pos[0];
y=_pos[1];
}
//-----------------------------------------------------------------------------
// Purpose: Get the size of the image
//-----------------------------------------------------------------------------
void Image::GetSize(int &wide, int &tall)
{
wide = _size[0];
tall = _size[1];
}
//-----------------------------------------------------------------------------
// Purpose: Gets the size of the image contents (by default the set size)
//-----------------------------------------------------------------------------
void Image::GetContentSize(int &wide, int &tall)
{
GetSize(wide, tall);
}
//-----------------------------------------------------------------------------
// Purpose: Set the size of the image
//-----------------------------------------------------------------------------
void Image::SetSize(int wide, int tall)
{
_size[0]=wide;
_size[1]=tall;
}
//-----------------------------------------------------------------------------
// Purpose: Set the draw color using a Color struct.
//-----------------------------------------------------------------------------
void Image::DrawSetColor(Color col)
{
surface()->DrawSetColor(col[0], col[1], col[2], col[3]);
}
//-----------------------------------------------------------------------------
// Purpose: Set the draw color using RGBA ints
//-----------------------------------------------------------------------------
void Image::DrawSetColor(int r,int g,int b,int a)
{
surface()->DrawSetColor(r,g,b,a);
}
//-----------------------------------------------------------------------------
// Purpose: Draw a filled rectangle
//-----------------------------------------------------------------------------
void Image::DrawFilledRect(int x0,int y0,int x1,int y1)
{
x0+=_pos[0];
y0+=_pos[1];
x1+=_pos[0];
y1+=_pos[1];
surface()->DrawFilledRect(x0,y0,x1,y1);
}
//-----------------------------------------------------------------------------
// Purpose: Draw an outlined rectangle
//-----------------------------------------------------------------------------
void Image::DrawOutlinedRect(int x0,int y0,int x1,int y1)
{
x0+=_pos[0];
y0+=_pos[1];
x1+=_pos[0];
y1+=_pos[1];
surface()->DrawOutlinedRect(x0,y0,x1,y1);
}
//-----------------------------------------------------------------------------
// Purpose: Draw a line between two points
//-----------------------------------------------------------------------------
void Image::DrawLine(int x0,int y0,int x1,int y1)
{
x0+=_pos[0];
y0+=_pos[1];
x1+=_pos[0];
y1+=_pos[1];
surface()->DrawLine(x0,y0,x1,y1);
}
//-----------------------------------------------------------------------------
// Purpose: Draw a line between a list of 'numPoints' points
//-----------------------------------------------------------------------------
void Image::DrawPolyLine(int *px, int *py, int numPoints)
{
// update the positions to be relative to this panel
for(int i=0;i<numPoints;i++)
{
px[i] += _pos[0];
py[i] += _pos[1];
}
surface()->DrawPolyLine(px, py, numPoints);
}
//-----------------------------------------------------------------------------
// Purpose: Set the font
//-----------------------------------------------------------------------------
void Image::DrawSetTextFont(HFont font)
{
surface()->DrawSetTextFont(font);
}
//-----------------------------------------------------------------------------
// Purpose: Set the text color using a color struct
//-----------------------------------------------------------------------------
void Image::DrawSetTextColor(Color sc)
{
surface()->DrawSetTextColor(sc[0], sc[1], sc[2], sc[3]);
}
//-----------------------------------------------------------------------------
// Purpose: Set the text color useing RGBA ints
//-----------------------------------------------------------------------------
void Image::DrawSetTextColor(int r,int g,int b,int a)
{
surface()->DrawSetTextColor(r,g,b,a);
}
//-----------------------------------------------------------------------------
// Purpose: Set the text position
//-----------------------------------------------------------------------------
void Image::DrawSetTextPos(int x,int y)
{
x+=_pos[0];
y+=_pos[1];
surface()->DrawSetTextPos(x,y);
}
//-----------------------------------------------------------------------------
// Purpose: Draw a text string
//-----------------------------------------------------------------------------
void Image::DrawPrintText(const wchar_t *str,int strlen)
{
surface()->DrawPrintText(str, strlen);
}
//-----------------------------------------------------------------------------
// Purpose: Draw a text string at the given coords.
//-----------------------------------------------------------------------------
void Image::DrawPrintText(int x, int y, const wchar_t *str, int strlen)
{
x += _pos[0];
y += _pos[1];
surface()->DrawSetTextPos(x, y);
surface()->DrawPrintText(str, strlen);
}
//-----------------------------------------------------------------------------
// Purpose: Draw a character
//-----------------------------------------------------------------------------
void Image::DrawPrintChar(wchar_t ch)
{
surface()->DrawUnicodeChar(ch);
}
//-----------------------------------------------------------------------------
// Purpose: Draw a character at the given coords
//-----------------------------------------------------------------------------
void Image::DrawPrintChar(int x, int y, wchar_t ch)
{
x+=_pos[0];
y+=_pos[1];
surface()->DrawSetTextPos(x, y);
surface()->DrawUnicodeChar(ch);
}
//-----------------------------------------------------------------------------
// Purpose: Set a texture
//-----------------------------------------------------------------------------
void Image::DrawSetTexture(int id)
{
surface()->DrawSetTexture(id);
}
//-----------------------------------------------------------------------------
// Purpose: Draw a rectangle filled with the current texture
//-----------------------------------------------------------------------------
void Image::DrawTexturedRect(int x0,int y0,int x1,int y1)
{
surface()->DrawTexturedRect(x0,y0,x1,y1);
}
//-----------------------------------------------------------------------------
// Purpose: Paint the contents of the image on screen.
// You must call this explicitly each frame.
//-----------------------------------------------------------------------------
void Image::Paint()
{
}
//-----------------------------------------------------------------------------
// Purpose: Set the current color using a color struct
//-----------------------------------------------------------------------------
void Image::SetColor(Color color)
{
_color=color;
DrawSetTextColor(color); // now update the device context underneath us :)
}
//-----------------------------------------------------------------------------
// Purpose: Get the current color as a color struct
//-----------------------------------------------------------------------------
Color Image::GetColor()
{
return _color;
}

View File

@ -0,0 +1,101 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <vgui/VGUI.h>
#include <Color.h>
#include <vgui_controls/ImageList.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: blank image, intentially draws nothing
//-----------------------------------------------------------------------------
class BlankImage : public IImage
{
public:
virtual void Paint() {}
virtual void SetPos(int x, int y) {}
virtual void GetContentSize(int &wide, int &tall) { wide = 0; tall = 0; }
virtual void GetSize(int &wide, int &tall) { wide = 0; tall = 0; }
virtual void SetSize(int wide, int tall) {}
virtual void SetColor(Color col) {}
};
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
ImageList::ImageList(bool deleteImagesWhenDone)
{
m_bDeleteImagesWhenDone = deleteImagesWhenDone;
AddImage(new BlankImage());
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
ImageList::~ImageList()
{
if (m_bDeleteImagesWhenDone)
{
// delete all the images, except for the first image (which is always the blank image)
for (int i = 1; i < m_Images.Count(); i++)
{
delete m_Images[i];
}
}
}
//-----------------------------------------------------------------------------
// Purpose: adds a new image to the list, returning the index it was placed at
//-----------------------------------------------------------------------------
int ImageList::AddImage(vgui::IImage *image)
{
return m_Images.AddToTail(image);
}
//-----------------------------------------------------------------------------
// Purpose: sets an image at a specified index, growing and adding NULL images if necessary
//-----------------------------------------------------------------------------
void ImageList::SetImageAtIndex(int index, vgui::IImage *image)
{
// allocate more images if necessary
while (m_Images.Count() <= index)
{
m_Images.AddToTail(NULL);
}
m_Images[index] = image;
}
//-----------------------------------------------------------------------------
// Purpose: returns the number of images
//-----------------------------------------------------------------------------
int ImageList::GetImageCount()
{
return m_Images.Count();
}
//-----------------------------------------------------------------------------
// Purpose: gets an image, imageIndex is of range [0, GetImageCount)
//-----------------------------------------------------------------------------
vgui::IImage *ImageList::GetImage(int imageIndex)
{
return m_Images[imageIndex];
}
//-----------------------------------------------------------------------------
// Purpose: returns true if an index is valid
//-----------------------------------------------------------------------------
bool ImageList::IsValidIndex(int imageIndex)
{
return m_Images.IsValidIndex(imageIndex);
}

View File

@ -0,0 +1,248 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <stdio.h>
#include <vgui/IBorder.h>
#include <vgui/ISurface.h>
#include <vgui/IScheme.h>
#include <vgui/IBorder.h>
#include <KeyValues.h>
#include <vgui_controls/ImagePanel.h>
#include <vgui_controls/Image.h>
#include <vgui_controls/Controls.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
DECLARE_BUILD_FACTORY( ImagePanel );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
ImagePanel::ImagePanel(Panel *parent, const char *name) : Panel(parent, name)
{
m_pImage = NULL;
m_pszImageName = NULL;
m_pszColorName = NULL;
m_bScaleImage = false;
m_FillColor = Color(0, 0, 0, 0);
SetImage(m_pImage);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
ImagePanel::~ImagePanel()
{
delete [] m_pszImageName;
delete [] m_pszColorName;
}
//-----------------------------------------------------------------------------
// Purpose: handles size changing
//-----------------------------------------------------------------------------
void ImagePanel::OnSizeChanged(int newWide, int newTall)
{
if (m_bScaleImage && m_pImage)
{
// scaling, force the image size to be our size
m_pImage->SetSize(newWide, newTall);
}
BaseClass::OnSizeChanged(newWide, newTall);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ImagePanel::SetImage(IImage *image)
{
m_pImage = image;
if (m_pImage)
{
int wide, tall;
if (m_bScaleImage)
{
// scaling, force the image size to be our size
GetSize(wide, tall);
m_pImage->SetSize(wide, tall);
}
else
{
// not scaling, so set our size to the image size
m_pImage->GetSize(wide, tall);
SetSize(wide, tall);
}
}
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: sets an image by file name
//-----------------------------------------------------------------------------
void ImagePanel::SetImage(const char *imageName)
{
int len = Q_strlen(imageName) + 1;
m_pszImageName = new char[ len ];
Q_strncpy(m_pszImageName, imageName, len );
InvalidateLayout(false, true); // forrce applyschemesettings to run
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
IImage *ImagePanel::GetImage()
{
return m_pImage;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ImagePanel::PaintBackground()
{
if (m_FillColor[3] > 0)
{
// draw the specified fill color
int wide, tall;
GetSize(wide, tall);
surface()->DrawSetColor(m_FillColor);
surface()->DrawFilledRect(0, 0, wide, tall);
}
if (m_pImage)
{
surface()->DrawSetColor(255, 255, 255, 255);
m_pImage->SetPos(0, 0);
m_pImage->Paint();
}
}
//-----------------------------------------------------------------------------
// Purpose: Gets control settings for editing
//-----------------------------------------------------------------------------
void ImagePanel::GetSettings(KeyValues *outResourceData)
{
BaseClass::GetSettings(outResourceData);
if (m_pszImageName)
{
outResourceData->SetString("image", m_pszImageName);
}
if (m_pszColorName)
{
outResourceData->SetString("fillcolor", m_pszColorName);
}
if (GetBorder())
{
outResourceData->SetString("border", GetBorder()->GetName());
}
outResourceData->SetInt("scaleImage", m_bScaleImage);
}
//-----------------------------------------------------------------------------
// Purpose: Applies designer settings from res file
//-----------------------------------------------------------------------------
void ImagePanel::ApplySettings(KeyValues *inResourceData)
{
delete [] m_pszImageName;
delete [] m_pszColorName;
m_pszImageName = NULL;
m_pszColorName = NULL;
m_bScaleImage = inResourceData->GetInt("scaleImage", 0);
const char *imageName = inResourceData->GetString("image", "");
if (*imageName)
{
SetImage( imageName );
}
const char *pszFillColor = inResourceData->GetString("fillcolor", "");
if (*pszFillColor)
{
int r = 0, g = 0, b = 0, a = 255;
int len = Q_strlen(pszFillColor) + 1;
m_pszColorName = new char[ len ];
Q_strncpy( m_pszColorName, pszFillColor, len );
if (sscanf(pszFillColor, "%d %d %d %d", &r, &g, &b, &a) >= 3)
{
// it's a direct color
m_FillColor = Color(r, g, b, a);
}
else
{
IScheme *pScheme = scheme()->GetIScheme( GetScheme() );
m_FillColor = pScheme->GetColor(pszFillColor, Color(0, 0, 0, 0));
}
}
const char *pszBorder = inResourceData->GetString("border", "");
if (*pszBorder)
{
IScheme *pScheme = scheme()->GetIScheme( GetScheme() );
SetBorder(pScheme->GetBorder(pszBorder));
}
BaseClass::ApplySettings(inResourceData);
}
//-----------------------------------------------------------------------------
// Purpose: load the image, this is done just before this control is displayed
//-----------------------------------------------------------------------------
void ImagePanel::ApplySchemeSettings( IScheme *pScheme )
{
BaseClass::ApplySchemeSettings(pScheme);
if ( m_pszImageName && strlen( m_pszImageName ) > 0 )
{
SetImage(scheme()->GetImage(m_pszImageName, m_bScaleImage));
}
}
//-----------------------------------------------------------------------------
// Purpose: Describes editing details
//-----------------------------------------------------------------------------
const char *ImagePanel::GetDescription()
{
static char buf[1024];
_snprintf(buf, sizeof(buf), "%s, string image, string border, string fillcolor, bool scaleImage", BaseClass::GetDescription());
return buf;
}
//-----------------------------------------------------------------------------
// Purpose: sets whether or not the image should scale to fit the size of the ImagePanel (defaults to false)
//-----------------------------------------------------------------------------
void ImagePanel::SetShouldScaleImage( bool state )
{
m_bScaleImage = state;
}
//-----------------------------------------------------------------------------
// Purpose: set the color to fill with, if no Image is specified
//-----------------------------------------------------------------------------
void ImagePanel::SetFillColor( Color col )
{
m_FillColor = col;
}
//-----------------------------------------------------------------------------
// Purpose: data accessor
//-----------------------------------------------------------------------------
Color ImagePanel::GetFillColor()
{
return m_FillColor;
}
char *ImagePanel::GetImageName()
{
return m_pszImageName;
}

View File

@ -0,0 +1,158 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include <vgui_controls/InputDialog.h>
#include <vgui_controls/Label.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/TextEntry.h>
#include "tier1/KeyValues.h"
#include "vgui/IInput.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
InputDialog::InputDialog(vgui::Panel *parent, const char *title, char const *prompt, char const *defaultValue /*=""*/ ) :
BaseClass(parent, NULL)
{
m_pContextKeyValues = NULL;
SetDeleteSelfOnClose( true );
SetTitle(title, true);
SetSize(320, 120);
SetSizeable( false );
m_pPrompt = new Label( this, "Prompt", prompt );
m_pInput = new TextEntry( this, "Text" );
m_pInput->SetText( defaultValue );
m_pInput->SelectAllText( true );
m_pInput->RequestFocus();
m_pCancelButton = new Button(this, "CancelButton", "#VGui_Cancel");
m_pOKButton = new Button(this, "OKButton", "#VGui_OK");
m_pCancelButton->SetCommand("Cancel");
m_pOKButton->SetCommand("OK");
m_pOKButton->SetAsDefaultButton( true );
if ( parent )
{
AddActionSignalTarget( parent );
}
}
InputDialog::~InputDialog()
{
CleanUpContextKeyValues();
}
//-----------------------------------------------------------------------------
// Purpose: Cleans up the keyvalues
//-----------------------------------------------------------------------------
void InputDialog::CleanUpContextKeyValues()
{
if ( m_pContextKeyValues )
{
m_pContextKeyValues->deleteThis();
m_pContextKeyValues = NULL;
}
}
//-----------------------------------------------------------------------------
// Sets the dialog to be multiline
//-----------------------------------------------------------------------------
void InputDialog::SetMultiline( bool state )
{
m_pInput->SetMultiline( state );
m_pInput->SetCatchEnterKey( state );
}
//-----------------------------------------------------------------------------
// Allow numeric input only
//-----------------------------------------------------------------------------
void InputDialog::AllowNumericInputOnly( bool bOnlyNumeric )
{
if ( m_pInput )
{
m_pInput->SetAllowNumericInputOnly( bOnlyNumeric );
}
}
//-----------------------------------------------------------------------------
// Purpose: lays out controls
//-----------------------------------------------------------------------------
void InputDialog::DoModal( KeyValues *pContextKeyValues )
{
CleanUpContextKeyValues();
m_pContextKeyValues = pContextKeyValues;
BaseClass::DoModal();
}
//-----------------------------------------------------------------------------
// Purpose: lays out controls
//-----------------------------------------------------------------------------
void InputDialog::PerformLayout()
{
BaseClass::PerformLayout();
int w, h;
GetSize( w, h );
// lay out all the controls
int topy = IsSmallCaption() ? 15 : 30;
m_pPrompt->SetBounds(24, topy, w - 48, 24);
m_pInput->SetBounds(24, topy + 30, w - 48, h - 100 );
m_pOKButton->SetBounds(w - 172, h - 30, 72, 24);
m_pCancelButton->SetBounds(w - 96, h - 30, 72, 24);
}
//-----------------------------------------------------------------------------
// Purpose: handles button commands
//-----------------------------------------------------------------------------
void InputDialog::OnCommand(const char *command)
{
if (!stricmp(command, "OK"))
{
int nTextLength = m_pInput->GetTextLength() + 1;
char* txt = (char*)_alloca( nTextLength * sizeof(char) );
m_pInput->GetText( txt, nTextLength );
KeyValues *kv = new KeyValues( "InputCompleted", "text", txt );
if ( m_pContextKeyValues )
{
kv->AddSubKey( m_pContextKeyValues );
m_pContextKeyValues = NULL;
}
PostActionSignal( kv );
CloseModal();
}
else if (!stricmp(command, "Cancel"))
{
KeyValues *kv = new KeyValues( "InputCanceled" );
if ( m_pContextKeyValues )
{
kv->AddSubKey( m_pContextKeyValues );
m_pContextKeyValues = NULL;
}
PostActionSignal( kv );
CloseModal();
}
else
{
BaseClass::OnCommand(command);
}
}

View File

@ -0,0 +1,350 @@
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#include "vgui_controls/KeyBindingHelpDialog.h"
#include "vgui_controls/ListPanel.h"
#include "vgui/ISurface.h"
#include "vgui/IVGui.h"
#include "vgui/ILocalize.h"
#include "vgui/IInput.h"
#include "vgui/ISystem.h"
#include "KeyValues.h"
#include "vgui/Cursor.h"
#include "tier1/UtlDict.h"
#include "vgui_controls/KeyBoardEditorDialog.h"
using namespace vgui;
// If the user holds the key bound to help down for this long, then the dialog will stay on automatically
#define KB_HELP_CONTINUE_SHOWING_TIME 1.0
static bool BindingLessFunc( KeyValues * const & lhs, KeyValues * const &rhs )
{
KeyValues *p1, *p2;
p1 = const_cast< KeyValues * >( lhs );
p2 = const_cast< KeyValues * >( rhs );
return ( Q_stricmp( p1->GetString( "Action" ), p2->GetString( "Action" ) ) < 0 ) ? true : false;
}
CKeyBindingHelpDialog::CKeyBindingHelpDialog( Panel *parent, Panel *panelToView, KeyBindingContextHandle_t handle, KeyCode code, int modifiers )
: BaseClass( parent, "KeyBindingHelpDialog" ),
m_Handle( handle ),
m_KeyCode( code ),
m_Modifiers( modifiers ),
m_bPermanent( false )
{
Assert( panelToView );
m_hPanel = panelToView;
m_pList = new ListPanel( this, "KeyBindings" );
m_pList->SetIgnoreDoubleClick( true );
m_pList->AddColumnHeader(0, "Action", "#KBEditorBindingName", 175, 0);
m_pList->AddColumnHeader(1, "Binding", "#KBEditorBinding", 175, 0);
m_pList->AddColumnHeader(2, "Description", "#KBEditorDescription", 300, 0);
LoadControlSettings( "resource/KeyBindingHelpDialog.res" );
if ( panelToView && panelToView->GetName() && panelToView->GetName()[0] )
{
SetTitle( panelToView->GetName(), true );
}
else
{
SetTitle( "#KBHelpDialogTitle", true );
}
SetSmallCaption( true );
SetMinimumSize( 400, 400 );
SetMinimizeButtonVisible( false );
SetMaximizeButtonVisible( false );
SetSizeable( true );
SetMoveable( true );
SetMenuButtonVisible( false );
SetVisible( true );
MoveToCenterOfScreen();
PopulateList();
m_flShowTime = system()->GetCurrentTime();
ivgui()->AddTickSignal( GetVPanel(), 0 );
input()->SetAppModalSurface( GetVPanel() );
}
CKeyBindingHelpDialog::~CKeyBindingHelpDialog()
{
if ( input()->GetAppModalSurface() == GetVPanel() )
{
input()->SetAppModalSurface( 0 );
}
}
void CKeyBindingHelpDialog::OnTick()
{
BaseClass::OnTick();
bool keyStillDown = IsHelpKeyStillBeingHeld();
double curtime = system()->GetCurrentTime();
double elapsed = curtime - m_flShowTime;
// After a second of holding the key, releasing the key will close the dialog
if ( elapsed > KB_HELP_CONTINUE_SHOWING_TIME )
{
if ( !keyStillDown )
{
MarkForDeletion();
return;
}
}
// Otherwise, if they tapped the key within a second and now have released...
else if ( !keyStillDown )
{
// Continue showing dialog indefinitely
ivgui()->RemoveTickSignal( GetVPanel() );
m_bPermanent = true;
}
}
// The key originally bound to help was pressed
void CKeyBindingHelpDialog::HelpKeyPressed()
{
// Don't kill while editor is being shown...
if ( m_hKeyBindingsEditor.Get() )
return;
if ( m_bPermanent )
{
MarkForDeletion();
}
}
bool CKeyBindingHelpDialog::IsHelpKeyStillBeingHeld()
{
bool keyDown = input()->IsKeyDown( m_KeyCode );
if ( !keyDown )
return false;
bool shift = (input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT));
bool ctrl = (input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL));
bool alt = (input()->IsKeyDown(KEY_LALT) || input()->IsKeyDown(KEY_RALT));
int modifiers = 0;
if ( shift )
{
modifiers |= MODIFIER_SHIFT;
}
if ( ctrl )
{
modifiers |= MODIFIER_CONTROL;
}
if ( alt )
{
modifiers |= MODIFIER_ALT;
}
if ( modifiers != m_Modifiers )
{
return false;
}
return true;
}
void CKeyBindingHelpDialog::OnCommand( char const *cmd )
{
if ( !Q_stricmp( cmd, "OK" ) ||
!Q_stricmp( cmd, "cancel" ) ||
!Q_stricmp( cmd, "Close" ) )
{
MarkForDeletion();
}
else if ( !Q_stricmp( cmd, "edit" ) )
{
// Show the keybindings edit dialog
if ( m_hKeyBindingsEditor.Get() )
{
delete m_hKeyBindingsEditor.Get();
}
// Don't delete panel if H key is released...
m_hKeyBindingsEditor = new CKeyBoardEditorDialog( this, m_hPanel, m_Handle );
m_hKeyBindingsEditor->DoModal();
ivgui()->RemoveTickSignal( GetVPanel() );
m_bPermanent = true;
}
else
{
BaseClass::OnCommand( cmd );
}
}
void CKeyBindingHelpDialog::OnKeyCodeTyped(vgui::KeyCode code)
{
BaseClass::OnKeyCodeTyped( code );
}
void CKeyBindingHelpDialog::GetMappingList( Panel *panel, CUtlVector< PanelKeyBindingMap * >& maps )
{
PanelKeyBindingMap *map = panel->GetKBMap();
while ( map )
{
maps.AddToTail( map );
map = map->baseMap;
}
}
void CKeyBindingHelpDialog::AnsiText( char const *token, char *out, size_t buflen )
{
out[ 0 ] = 0;
wchar_t *str = vgui::localize()->Find( token );
if ( !str )
{
Q_strncpy( out, token, buflen );
}
else
{
localize()->ConvertUnicodeToANSI( str, out, buflen );
}
}
struct ListInfo_t
{
PanelKeyBindingMap *m_pMap;
Panel *m_pPanel;
};
void CKeyBindingHelpDialog::PopulateList()
{
m_pList->DeleteAllItems();
int i, j;
CUtlVector< ListInfo_t > maps;
vgui::Panel *pPanel = m_hPanel;
while ( pPanel->IsKeyBindingChainToParentAllowed() )
{
PanelKeyBindingMap *map = pPanel->GetKBMap();
while ( map )
{
int k;
int c = maps.Count();
for ( k = 0; k < c; ++k )
{
if ( maps[k].m_pMap == map )
break;
}
if ( k == c )
{
int k = maps.AddToTail( );
maps[k].m_pMap = map;
maps[k].m_pPanel = pPanel;
}
map = map->baseMap;
}
pPanel = pPanel->GetParent();
if ( !pPanel )
break;
}
CUtlRBTree< KeyValues *, int > sorted( 0, 0, BindingLessFunc );
// add header item
int c = maps.Count();
for ( i = 0; i < c; ++i )
{
PanelKeyBindingMap *m = maps[ i ].m_pMap;
Panel *pPanel = maps[i].m_pPanel;
Assert( m );
int bindings = m->boundkeys.Count();
for ( j = 0; j < bindings; ++j )
{
BoundKey_t *kbMap = &m->boundkeys[ j ];
Assert( kbMap );
// Create a new: blank item
KeyValues *item = new KeyValues( "Item" );
// Fill in data
char loc[ 128 ];
Q_snprintf( loc, sizeof( loc ), "#%s", kbMap->bindingname );
char ansi[ 256 ];
AnsiText( loc, ansi, sizeof( ansi ) );
item->SetString( "Action", ansi );
item->SetWString( "Binding", Panel::KeyCodeModifiersToDisplayString( (KeyCode)kbMap->keycode, kbMap->modifiers ) );
// Find the binding
KeyBindingMap_t *bindingMap = pPanel->LookupBinding( kbMap->bindingname );
if ( bindingMap &&
bindingMap->helpstring )
{
AnsiText( bindingMap->helpstring, ansi, sizeof( ansi ) );
item->SetString( "Description", ansi );
}
item->SetPtr( "Item", kbMap );
sorted.Insert( item );
}
// Now try and find any "unbound" keys...
int mappings = m->entries.Count();
for ( j = 0; j < mappings; ++j )
{
KeyBindingMap_t *kbMap = &m->entries[ j ];
// See if it's bound
CUtlVector< BoundKey_t * > list;
pPanel->LookupBoundKeys( kbMap->bindingname, list );
if ( list.Count() > 0 )
continue;
// Not bound, add a placeholder entry
// Create a new: blank item
KeyValues *item = new KeyValues( "Item" );
// fill in data
char loc[ 128 ];
Q_snprintf( loc, sizeof( loc ), "#%s", kbMap->bindingname );
char ansi[ 256 ];
AnsiText( loc, ansi, sizeof( ansi ) );
item->SetString( "Action", ansi );
item->SetWString( "Binding", L"" );
if ( kbMap->helpstring )
{
AnsiText( kbMap->helpstring, ansi, sizeof( ansi ) );
item->SetString( "Description", ansi );
}
item->SetPtr( "Unbound", kbMap );
sorted.Insert( item );
}
}
for ( j = sorted.FirstInorder() ; j != sorted.InvalidIndex(); j = sorted.NextInorder( j ) )
{
KeyValues *item = sorted[ j ];
// Add to list
m_pList->AddItem( item, 0, false, false );
item->deleteThis();
}
sorted.RemoveAll();
}

View File

@ -0,0 +1,848 @@
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#include "vgui_controls/KeyBoardEditorDialog.h"
#include "vgui_controls/ListPanel.h"
#include "vgui_controls/Button.h"
#include "vgui_controls/TextEntry.h"
#include "vgui/ISurface.h"
#include "vgui/IInput.h"
#include "vgui/IVGui.h"
#include "vgui/ILocalize.h"
#include "KeyValues.h"
#include "vgui/Cursor.h"
#include "tier1/UtlDict.h"
using namespace vgui;
static char *CopyString( const char *in )
{
if ( !in )
return NULL;
int len = strlen( in );
char *n = new char[ len + 1 ];
Q_strncpy( n, in, len + 1 );
return n;
}
CKeyBoardEditorPage::SaveMapping_t::SaveMapping_t() : map( 0 )
{
}
CKeyBoardEditorPage::SaveMapping_t::SaveMapping_t( const SaveMapping_t& src )
{
map = src.map;
current = src.current;
original = src.original;
}
//-----------------------------------------------------------------------------
// Purpose: Special list subclass to handle drawing of trap mode prompt on top of
// lists client area
//-----------------------------------------------------------------------------
class VControlsListPanel : public ListPanel
{
DECLARE_CLASS_SIMPLE( VControlsListPanel, ListPanel );
public:
// Construction
VControlsListPanel( vgui::Panel *parent, const char *listName );
virtual ~VControlsListPanel();
// Start/end capturing
virtual void StartCaptureMode(vgui::HCursor hCursor = NULL);
virtual void EndCaptureMode(vgui::HCursor hCursor = NULL);
virtual bool IsCapturing();
// Set which item should be associated with the prompt
virtual void SetItemOfInterest(int itemID);
virtual int GetItemOfInterest();
virtual void OnMousePressed(vgui::MouseCode code);
virtual void OnMouseDoublePressed(vgui::MouseCode code);
KEYBINDING_FUNC( clearbinding, KEY_DELETE, 0, OnClearBinding, 0, 0 );
private:
void ApplySchemeSettings(vgui::IScheme *pScheme );
// Are we showing the prompt?
bool m_bCaptureMode;
// If so, where?
int m_nClickRow;
// Font to use for showing the prompt
vgui::HFont m_hFont;
// panel used to edit
class CInlineEditPanel *m_pInlineEditPanel;
int m_iMouseX, m_iMouseY;
};
//-----------------------------------------------------------------------------
// Purpose: panel used for inline editing of key bindings
//-----------------------------------------------------------------------------
class CInlineEditPanel : public vgui::Panel
{
DECLARE_CLASS_SIMPLE( CInlineEditPanel, vgui::Panel );
public:
CInlineEditPanel() : vgui::Panel(NULL, "InlineEditPanel")
{
}
virtual void Paint()
{
int wide, tall;
GetSize(wide, tall);
// Draw a white rectangle around that cell
vgui::surface()->DrawSetColor( 63, 63, 63, 255 );
vgui::surface()->DrawFilledRect( 0, 0, wide, tall );
vgui::surface()->DrawSetColor( 0, 255, 0, 255 );
vgui::surface()->DrawOutlinedRect( 0, 0, wide, tall );
}
virtual void OnKeyCodeTyped(KeyCode code)
{
// forward up
if (GetParent())
{
GetParent()->OnKeyCodeTyped(code);
}
}
virtual void ApplySchemeSettings(IScheme *pScheme)
{
Panel::ApplySchemeSettings(pScheme);
SetBorder(pScheme->GetBorder("DepressedButtonBorder"));
}
void OnMousePressed(vgui::MouseCode code)
{
// forward up mouse pressed messages to be handled by the key options
if (GetParent())
{
GetParent()->OnMousePressed(code);
}
}
};
//-----------------------------------------------------------------------------
// Purpose: Construction
//-----------------------------------------------------------------------------
VControlsListPanel::VControlsListPanel( vgui::Panel *parent, const char *listName ) : BaseClass( parent, listName )
{
m_bCaptureMode = false;
m_nClickRow = 0;
m_pInlineEditPanel = new CInlineEditPanel();
m_hFont = INVALID_FONT;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
VControlsListPanel::~VControlsListPanel()
{
m_pInlineEditPanel->MarkForDeletion();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void VControlsListPanel::ApplySchemeSettings(IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
m_hFont = pScheme->GetFont("DefaultVerySmall", IsProportional() );
}
//-----------------------------------------------------------------------------
// Purpose: Start capture prompt display
//-----------------------------------------------------------------------------
void VControlsListPanel::StartCaptureMode( HCursor hCursor )
{
m_bCaptureMode = true;
EnterEditMode(m_nClickRow, 1, m_pInlineEditPanel);
input()->SetMouseFocus(m_pInlineEditPanel->GetVPanel());
input()->SetMouseCapture(m_pInlineEditPanel->GetVPanel());
if (hCursor)
{
m_pInlineEditPanel->SetCursor(hCursor);
// save off the cursor position so we can restore it
vgui::input()->GetCursorPos( m_iMouseX, m_iMouseY );
}
}
void VControlsListPanel::OnClearBinding()
{
if ( m_bCaptureMode )
return;
if ( GetItemOfInterest() < 0 )
return;
PostMessage( GetParent()->GetVPanel(), new KeyValues( "ClearBinding", "item", GetItemOfInterest() ) );
}
//-----------------------------------------------------------------------------
// Purpose: Finish capture prompt display
//-----------------------------------------------------------------------------
void VControlsListPanel::EndCaptureMode( HCursor hCursor )
{
m_bCaptureMode = false;
input()->SetMouseCapture(NULL);
LeaveEditMode();
RequestFocus();
input()->SetMouseFocus(GetVPanel());
if (hCursor)
{
m_pInlineEditPanel->SetCursor(hCursor);
surface()->SetCursor(hCursor);
if ( hCursor != dc_none )
{
vgui::input()->SetCursorPos ( m_iMouseX, m_iMouseY );
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Set active row column
//-----------------------------------------------------------------------------
void VControlsListPanel::SetItemOfInterest(int itemID)
{
m_nClickRow = itemID;
}
//-----------------------------------------------------------------------------
// Purpose: Retrieve row, column of interest
//-----------------------------------------------------------------------------
int VControlsListPanel::GetItemOfInterest()
{
return m_nClickRow;
}
//-----------------------------------------------------------------------------
// Purpose: returns true if we're currently waiting to capture a key
//-----------------------------------------------------------------------------
bool VControlsListPanel::IsCapturing( void )
{
return m_bCaptureMode;
}
//-----------------------------------------------------------------------------
// Purpose: Forwards mouse pressed message up to keyboard page when in capture
//-----------------------------------------------------------------------------
void VControlsListPanel::OnMousePressed(vgui::MouseCode code)
{
if (IsCapturing())
{
// forward up mouse pressed messages to be handled by the key options
if (GetParent())
{
GetParent()->OnMousePressed(code);
}
}
else
{
BaseClass::OnMousePressed(code);
}
}
//-----------------------------------------------------------------------------
// Purpose: input handler
//-----------------------------------------------------------------------------
void VControlsListPanel::OnMouseDoublePressed( vgui::MouseCode code )
{
int c = GetSelectedItemsCount();
if ( c > 0 )
{
// enter capture mode
OnKeyCodeTyped(KEY_ENTER);
}
else
{
BaseClass::OnMouseDoublePressed(code);
}
}
CKeyBoardEditorPage::CKeyBoardEditorPage( Panel *parent, Panel *panelToEdit, KeyBindingContextHandle_t handle )
: BaseClass( parent, "KeyBoardEditorPage" ),
m_pPanel( panelToEdit ),
m_Handle( handle )
{
Assert( m_pPanel );
m_pList = new VControlsListPanel( this, "KeyBindings" );
m_pList->SetIgnoreDoubleClick( true );
m_pList->AddColumnHeader(0, "Action", "#KBEditorBindingName", 175, 0);
m_pList->AddColumnHeader(1, "Binding", "#KBEditorBinding", 175, 0);
m_pList->AddColumnHeader(2, "Description", "#KBEditorDescription", 300, 0);
LoadControlSettings( "resource/KeyBoardEditorPage.res" );
SaveMappings();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : -
//-----------------------------------------------------------------------------
CKeyBoardEditorPage::~CKeyBoardEditorPage()
{
int c = m_Save.Count();
for ( int i = 0 ; i < c; ++i )
{
delete m_Save[ i ];
}
m_Save.RemoveAll();
}
void CKeyBoardEditorPage::ApplySchemeSettings( IScheme *scheme )
{
BaseClass::ApplySchemeSettings( scheme );
PopulateList();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : -
//-----------------------------------------------------------------------------
void CKeyBoardEditorPage::SaveMappings()
{
Assert( m_Save.Count() == 0 );
CUtlVector< PanelKeyBindingMap * > maps;
GetMappingList( m_pPanel, maps );
// add header item
int c = maps.Count();
for ( int i = 0; i < c; ++i )
{
PanelKeyBindingMap *m = maps[ i ];
SaveMapping_t *sm = new SaveMapping_t;
sm->map = m;
sm->current = m->boundkeys;
sm->original = m->boundkeys;
m_Save.AddToTail( sm );
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : -
//-----------------------------------------------------------------------------
void CKeyBoardEditorPage::UpdateCurrentMappings()
{
int c = m_Save.Count();
for ( int i = 0 ; i < c; ++i )
{
PanelKeyBindingMap *m = m_Save[ i ]->map;
Assert( m );
m_Save[ i ]->current = m->boundkeys;
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : -
//-----------------------------------------------------------------------------
void CKeyBoardEditorPage::RestoreMappings()
{
int c = m_Save.Count();
for ( int i = 0; i < c; ++i )
{
SaveMapping_t *sm = m_Save[ i ];
sm->current = sm->original;
}
}
void CKeyBoardEditorPage::ApplyMappings()
{
int c = m_Save.Count();
for ( int i = 0; i < c; ++i )
{
SaveMapping_t *sm = m_Save[ i ];
sm->map->boundkeys = sm->current;
}
}
//-----------------------------------------------------------------------------
// Purpose: User clicked on item: remember where last active row/column was
//-----------------------------------------------------------------------------
void CKeyBoardEditorPage::ItemSelected()
{
int c = m_pList->GetSelectedItemsCount();
if ( c > 0 )
{
m_pList->SetItemOfInterest( m_pList->GetSelectedItem( 0 ) );
}
}
void CKeyBoardEditorPage::BindKey( KeyCode code )
{
bool shift = (input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT));
bool ctrl = (input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL));
bool alt = (input()->IsKeyDown(KEY_LALT) || input()->IsKeyDown(KEY_RALT));
int modifiers = 0;
if ( shift )
{
modifiers |= MODIFIER_SHIFT;
}
if ( ctrl )
{
modifiers |= MODIFIER_CONTROL;
}
if ( alt )
{
modifiers |= MODIFIER_ALT;
}
int r = m_pList->GetItemOfInterest();
// Retrieve clicked row and column
m_pList->EndCaptureMode(dc_arrow);
// Find item for this row
KeyValues *item = m_pList->GetItem(r);
if ( item )
{
BoundKey_t *kbMap = reinterpret_cast< BoundKey_t * >( item->GetPtr( "Item", 0 ) );
if ( kbMap )
{
KeyBindingMap_t *binding = m_pPanel->LookupBindingByKeyCode( code, modifiers );
if ( binding && Q_stricmp( kbMap->bindingname, binding->bindingname ) )
{
// Key is already rebound!!!
char warning[ 512 ];
Q_snprintf( warning, sizeof( warning ), "Can't bind to '%S', key is already bound to '%s'\n",
Panel::KeyCodeToDisplayString( code ), binding->bindingname );
Warning( warning );
return;
}
kbMap->keycode = code;
kbMap->modifiers = modifiers;
PopulateList();
}
KeyBindingMap_t *bindingMap = reinterpret_cast< KeyBindingMap_t * >( item->GetPtr( "Unbound", 0 ) );
if ( bindingMap )
{
KeyBindingMap_t *binding = m_pPanel->LookupBindingByKeyCode( code, modifiers );
if ( binding && Q_stricmp( bindingMap->bindingname, binding->bindingname ) )
{
// Key is already rebound!!!
char warning[ 512 ];
Q_snprintf( warning, sizeof( warning ), "Can't bind to '%S', key is already bound to '%s'\n",
Panel::KeyCodeToDisplayString( code ), binding->bindingname );
Warning( warning );
return;
}
// Need to add to current entries
m_pPanel->AddKeyBinding( bindingMap->bindingname, code, modifiers );
UpdateCurrentMappings();
PopulateList();
}
}
}
void CKeyBoardEditorPage::OnPageHide()
{
if ( m_pList->IsCapturing() )
{
// Cancel capturing
m_pList->EndCaptureMode(dc_arrow);
}
}
//-----------------------------------------------------------------------------
// Purpose: binds double-clicking or hitting enter in the keybind list to changing the key
//-----------------------------------------------------------------------------
void CKeyBoardEditorPage::OnKeyCodeTyped(vgui::KeyCode code)
{
switch ( code )
{
case KEY_ENTER:
{
if ( !m_pList->IsCapturing() )
{
OnCommand( "ChangeKey" );
}
else
{
BindKey( code );
}
}
break;
case KEY_LSHIFT:
case KEY_RSHIFT:
case KEY_LALT:
case KEY_RALT:
case KEY_LCONTROL:
case KEY_RCONTROL:
{
// Swallow these
break;
}
break;
default:
{
if ( m_pList->IsCapturing() )
{
BindKey( code );
}
else
{
BaseClass::OnKeyCodeTyped(code);
}
}
}
}
void CKeyBoardEditorPage::OnCommand( char const *cmd )
{
if ( !m_pList->IsCapturing() && !Q_stricmp( cmd, "ChangeKey" ) )
{
m_pList->StartCaptureMode(dc_blank);
}
else
{
BaseClass::OnCommand( cmd );
}
}
void CKeyBoardEditorPage::OnSaveChanges()
{
ApplyMappings();
}
void CKeyBoardEditorPage::OnRevert()
{
RestoreMappings();
PopulateList();
}
void CKeyBoardEditorPage::OnUseDefaults()
{
m_pPanel->RevertKeyBindingsToDefault();
UpdateCurrentMappings();
PopulateList();
}
void CKeyBoardEditorPage::GetMappingList( Panel *panel, CUtlVector< PanelKeyBindingMap * >& maps )
{
PanelKeyBindingMap *map = panel->GetKBMap();
while ( map )
{
maps.AddToTail( map );
map = map->baseMap;
}
}
static bool BindingLessFunc( KeyValues * const & lhs, KeyValues * const &rhs )
{
KeyValues *p1, *p2;
p1 = const_cast< KeyValues * >( lhs );
p2 = const_cast< KeyValues * >( rhs );
return ( Q_stricmp( p1->GetString( "Action" ), p2->GetString( "Action" ) ) < 0 ) ? true : false;
}
void CKeyBoardEditorPage::AnsiText( char const *token, char *out, size_t buflen )
{
out[ 0 ] = 0;
wchar_t *str = vgui::localize()->Find( token );
if ( !str )
{
Q_strncpy( out, token, buflen );
}
else
{
localize()->ConvertUnicodeToANSI( str, out, buflen );
}
}
void CKeyBoardEditorPage::PopulateList()
{
m_pList->DeleteAllItems();
int i, j;
CUtlRBTree< KeyValues *, int > sorted( 0, 0, BindingLessFunc );
// add header item
int c = m_Save.Count();
for ( i = 0; i < c; ++i )
{
SaveMapping_t* sm = m_Save[ i ];
PanelKeyBindingMap *m = sm->map;
Assert( m );
int bindings = sm->current.Count();
for ( j = 0; j < bindings; ++j )
{
BoundKey_t *kbMap = &sm->current[ j ];
Assert( kbMap );
// Create a new: blank item
KeyValues *item = new KeyValues( "Item" );
// Fill in data
char loc[ 128 ];
Q_snprintf( loc, sizeof( loc ), "#%s", kbMap->bindingname );
char ansi[ 256 ];
AnsiText( loc, ansi, sizeof( ansi ) );
item->SetString( "Action", ansi );
item->SetWString( "Binding", Panel::KeyCodeModifiersToDisplayString( (KeyCode)kbMap->keycode, kbMap->modifiers ) );
// Find the binding
KeyBindingMap_t *bindingMap = m_pPanel->LookupBinding( kbMap->bindingname );
if ( bindingMap &&
bindingMap->helpstring )
{
AnsiText( bindingMap->helpstring, ansi, sizeof( ansi ) );
item->SetString( "Description", ansi);
}
item->SetPtr( "Item", kbMap );
sorted.Insert( item );
}
// Now try and find any "unbound" keys...
int mappings = m->entries.Count();
for ( j = 0; j < mappings; ++j )
{
KeyBindingMap_t *kbMap = &m->entries[ j ];
// See if it's bound
CUtlVector< BoundKey_t * > list;
m_pPanel->LookupBoundKeys( kbMap->bindingname, list );
if ( list.Count() > 0 )
continue;
// Not bound, add a placeholder entry
// Create a new: blank item
KeyValues *item = new KeyValues( "Item" );
// fill in data
char loc[ 128 ];
Q_snprintf( loc, sizeof( loc ), "#%s", kbMap->bindingname );
char ansi[ 256 ];
AnsiText( loc, ansi, sizeof( ansi ) );
item->SetString( "Action", ansi );
item->SetWString( "Binding", L"" );
if ( kbMap->helpstring )
{
AnsiText( kbMap->helpstring, ansi, sizeof( ansi ) );
item->SetString( "Description", ansi );
}
item->SetPtr( "Unbound", kbMap );
sorted.Insert( item );
}
}
for ( j = sorted.FirstInorder() ; j != sorted.InvalidIndex(); j = sorted.NextInorder( j ) )
{
KeyValues *item = sorted[ j ];
// Add to list
m_pList->AddItem( item, 0, false, false );
item->deleteThis();
}
sorted.RemoveAll();
}
void CKeyBoardEditorPage::OnClearBinding( int item )
{
// Find item for this row
KeyValues *kv = m_pList->GetItem(item );
if ( !kv )
{
return;
}
BoundKey_t *kbMap = reinterpret_cast< BoundKey_t * >( kv->GetPtr( "Item", 0 ) );
if ( !kbMap )
{
return;
}
kbMap->keycode = KEY_NONE;
kbMap->modifiers = 0;
PopulateList();
}
CKeyBoardEditorSheet::CKeyBoardEditorSheet( Panel *parent, Panel *panelToEdit, KeyBindingContextHandle_t handle )
: BaseClass( parent, "KeyBoardEditorSheet" ),
m_bSaveToExternalFile( false ),
m_Handle( handle ),
m_SaveFileName( UTL_INVAL_SYMBOL ),
m_SaveFilePathID( UTL_INVAL_SYMBOL )
{
m_hPanel = panelToEdit;
SetSmallTabs( true );
// Create this sheet and add the subcontrols
CKeyBoardEditorPage *active = NULL;
int subCount = Panel::GetPanelsWithKeyBindingsCount( handle );
for ( int i = 0; i < subCount; ++i )
{
Panel *p = Panel::GetPanelWithKeyBindings( handle, i );
if ( !p )
continue;
// Don't display panels with no keymappings
if ( p->GetKeyMappingCount() == 0 )
continue;
CKeyBoardEditorPage *newPage = new CKeyBoardEditorPage( this, p, handle );
AddPage( newPage, p->GetName() );
if ( p == panelToEdit )
{
active = newPage;
}
}
if ( active )
{
SetActivePage( active );
}
LoadControlSettings( "resource/KeyBoardEditorSheet.res" );
}
void CKeyBoardEditorSheet::SetKeybindingsSaveFile( char const *filename, char const *pathID /*= 0*/ )
{
Assert( filename );
m_bSaveToExternalFile = true;
m_SaveFileName = filename;
if ( pathID != NULL )
{
m_SaveFilePathID = pathID;
}
else
{
m_SaveFilePathID = UTL_INVAL_SYMBOL;
}
}
void CKeyBoardEditorSheet::OnSaveChanges()
{
int c = GetNumPages();
for ( int i = 0 ; i < c; ++i )
{
CKeyBoardEditorPage *page = static_cast< CKeyBoardEditorPage * >( GetPage( i ) );
page->OnSaveChanges();
}
if ( m_bSaveToExternalFile )
{
m_hPanel->SaveKeyBindingsToFile( m_Handle, m_SaveFileName.String(), m_SaveFilePathID.IsValid() ? m_SaveFilePathID.String() : NULL );
}
else
{
m_hPanel->SaveKeyBindings( m_Handle );
}
}
void CKeyBoardEditorSheet::OnRevert()
{
int c = GetNumPages();
for ( int i = 0 ; i < c; ++i )
{
CKeyBoardEditorPage *page = static_cast< CKeyBoardEditorPage * >( GetPage( i ) );
page->OnRevert();
}
}
void CKeyBoardEditorSheet::OnUseDefaults()
{
int c = GetNumPages();
for ( int i = 0 ; i < c; ++i )
{
CKeyBoardEditorPage *page = static_cast< CKeyBoardEditorPage * >( GetPage( i ) );
page->OnUseDefaults();
}
}
CKeyBoardEditorDialog::CKeyBoardEditorDialog( Panel *parent, Panel *panelToEdit, KeyBindingContextHandle_t handle )
: BaseClass( parent, "KeyBoardEditorDialog" )
{
m_pSave = new Button( this, "Save", "#KBEditorSave", this, "save" );
m_pCancel = new Button( this, "Cancel", "#KBEditorCancel", this, "cancel" );
m_pRevert = new Button( this, "Revert", "#KBEditorRevert", this, "revert" );
m_pUseDefaults = new Button( this, "Defaults", "#KBEditorUseDefaults", this, "defaults" );
m_pKBEditor = new CKeyBoardEditorSheet( this, panelToEdit, handle );
LoadControlSettings( "resource/KeyBoardEditorDialog.res" );
SetTitle( "#KBEditorTitle", true );
SetSmallCaption( true );
SetMinimumSize( 640, 200 );
SetMinimizeButtonVisible( false );
SetMaximizeButtonVisible( false );
SetSizeable( true );
SetMoveable( true );
SetMenuButtonVisible( false );
SetVisible( true );
MoveToCenterOfScreen();
}
void CKeyBoardEditorDialog::OnCommand( char const *cmd )
{
if ( !Q_stricmp( cmd, "save" ) )
{
m_pKBEditor->OnSaveChanges();
MarkForDeletion();
}
else if ( !Q_stricmp( cmd, "cancel" ) ||
!Q_stricmp( cmd, "Close" ) )
{
m_pKBEditor->OnRevert();
MarkForDeletion();
}
else if ( !Q_stricmp( cmd, "revert" ) )
{
m_pKBEditor->OnRevert();
}
else if ( !Q_stricmp( cmd, "defaults" ) )
{
m_pKBEditor->OnUseDefaults();
}
else
{
BaseClass::OnCommand( cmd );
}
}
void CKeyBoardEditorDialog::SetKeybindingsSaveFile( char const *filename, char const *pathID /*= 0*/ )
{
m_pKBEditor->SetKeybindingsSaveFile( filename, pathID );
}

1280
vgui2/controls/Label.cpp Normal file

File diff suppressed because it is too large Load Diff

3016
vgui2/controls/ListPanel.cpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2481
vgui2/controls/Menu.cpp Normal file

File diff suppressed because it is too large Load Diff

252
vgui2/controls/MenuBar.cpp Normal file
View File

@ -0,0 +1,252 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <vgui/IInput.h>
#include <vgui/IPanel.h>
#include <vgui/IScheme.h>
#include <vgui/IBorder.h>
#include <vgui/ISurface.h>
#include <vgui/KeyCode.h>
#include <KeyValues.h>
#include <vgui_controls/MenuBar.h>
#include <vgui_controls/MenuButton.h>
#include <vgui_controls/Label.h>
#include <vgui_controls/Controls.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
enum
{
MENUBARINDENT = 4, // indent from top and bottom of panel.
};
DECLARE_BUILD_FACTORY( MenuBar );
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
MenuBar::MenuBar(Panel *parent, const char *panelName) :
Panel(parent, panelName),
m_nRightEdge( 0 )
{
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
MenuBar::~MenuBar()
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void MenuBar::AddButton(MenuButton *button)
{
button->SetParent(this);
button->AddActionSignalTarget(this);
m_pMenuButtons.AddToTail(button);
}
//-----------------------------------------------------------------------------
// This will add the menu to the menu bar
//-----------------------------------------------------------------------------
void MenuBar::AddMenu( const char *pButtonName, Menu *pMenu )
{
MenuButton *pMenuButton = new MenuButton(this, pButtonName, pButtonName);
pMenuButton->SetMenu(pMenu);
AddButton(pMenuButton);
}
//-----------------------------------------------------------------------------
// Purpose: Handle key presses, Activate shortcuts
//-----------------------------------------------------------------------------
void MenuBar::OnKeyCodeTyped(KeyCode code)
{
switch(code)
{
case KEY_RIGHT:
{
// iterate the menu items looking for one that is open
// if we find one open, open the one to the right
for (int i = 0; i < m_pMenuButtons.Count() - 1; i++)
{
MenuButton *panel = m_pMenuButtons[i];
if (panel->IsDepressed())
{
m_pMenuButtons[i]->DoClick();
m_pMenuButtons[i+1]->DoClick();
break;
}
}
break;
}
case KEY_LEFT:
{
// iterate the menu items looking for one that is open
// if we find one open, open the one to the left
for (int i = 1; i < m_pMenuButtons.Count(); i++)
{
MenuButton *panel = m_pMenuButtons[i];
if (panel->IsDepressed())
{
m_pMenuButtons[i]->DoClick();
m_pMenuButtons[i-1]->DoClick();
break;
}
}
break;
}
default:
{
break;
}
}
// don't chain back
}
//-----------------------------------------------------------------------------
// Purpose: Handle key presses, Activate shortcuts
// Input : code -
//-----------------------------------------------------------------------------
void MenuBar::OnKeyTyped(wchar_t unichar)
{
if (unichar)
{
// iterate the menu items looking for one with the matching hotkey
for (int i = 0; i < m_pMenuButtons.Count(); i++)
{
MenuButton *panel = m_pMenuButtons[i];
if (panel->IsVisible())
{
Panel *hot = panel->HasHotkey(unichar);
if (hot)
{
// post a message to the menuitem telling it it's hotkey was pressed
PostMessage(hot, new KeyValues("Hotkey"));
return;
}
}
}
}
// don't chain back
}
void MenuBar::Paint()
{
IScheme *pScheme = scheme()->GetIScheme( GetScheme() );
for ( int i = 0; i < m_pMenuButtons.Count(); i++)
{
if (!m_pMenuButtons[i]->IsArmed())
m_pMenuButtons[i]->SetDefaultBorder(NULL);
else
{
m_pMenuButtons[i]->SetDefaultBorder(pScheme->GetBorder( "ButtonBorder"));
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Message map
//-----------------------------------------------------------------------------
void MenuBar::ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
// get the borders we need
SetBorder(pScheme->GetBorder("ButtonBorder"));
// get the background color
SetBgColor(pScheme->GetColor( "MenuBar.BgColor", GetBgColor() ));
}
//-----------------------------------------------------------------------------
// Purpose: Reformat according to the new layout
//-----------------------------------------------------------------------------
void MenuBar::PerformLayout()
{
int nBarWidth, nBarHeight;
GetSize( nBarWidth, nBarHeight );
// Now position + resize all buttons
int x = MENUBARINDENT;
for ( int i = 0; i < m_pMenuButtons.Count(); ++i )
{
int nWide, nTall;
m_pMenuButtons[i]->GetContentSize(nWide, nTall);
m_pMenuButtons[i]->SetPos( x, MENUBARINDENT );
m_pMenuButtons[i]->SetSize( nWide + Label::Content, nBarHeight - 2 * MENUBARINDENT );
x += nWide + MENUBARINDENT;
}
m_nRightEdge = x;
}
//-----------------------------------------------------------------------------
// Purpose: Get the size of the menus in the bar (so other children can be added to menu bar)
// Input : w -
// int&h -
//-----------------------------------------------------------------------------
void MenuBar::GetContentSize( int& w, int&h )
{
w = m_nRightEdge + 2;
h = GetTall();
}
//-----------------------------------------------------------------------------
// Purpose: Message map
//-----------------------------------------------------------------------------
void MenuBar::OnMenuClose()
{
RequestFocus();
}
//-----------------------------------------------------------------------------
// Purpose: Message map
//-----------------------------------------------------------------------------
void MenuBar::OnCursorEnteredMenuButton(int VPanel)
{
VPANEL menuButton = (VPANEL)VPanel;
// see if we had a menu open
for ( int i = 0; i < m_pMenuButtons.Count(); i++)
{
// one of our buttons was pressed.
if (m_pMenuButtons[i]->IsDepressed())
{
int oldbutton = i;
// now see if menuButton is one of ours.
for ( int j = 0; j < m_pMenuButtons.Count(); j++)
{
MenuButton *button = static_cast<MenuButton *>(ipanel()->GetPanel(menuButton, GetModuleName()));
// it is one of ours.
if ( button == m_pMenuButtons[j])
{
// if its a different button than the one we already had open,
if (j != oldbutton)
{
// close this menu and open the one we just entered
m_pMenuButtons[oldbutton]->DoClick();
button->DoClick();
}
}
}
}
}
}

View File

@ -0,0 +1,346 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#define PROTECTED_THINGS_DISABLE
#include <vgui/IPanel.h>
#include <vgui/IInput.h>
#include <vgui/ISurface.h>
#include <KeyValues.h>
#include <vgui/IVGui.h>
#include <vgui_controls/Controls.h>
#include <vgui_controls/MenuButton.h>
#include <vgui_controls/Menu.h>
#include <vgui_controls/TextImage.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
DECLARE_BUILD_FACTORY_DEFAULT_TEXT( MenuButton, MenuButton );
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
MenuButton::MenuButton(Panel *parent, const char *panelName, const char *text) : Button(parent, panelName, text)
{
m_pMenu = NULL;
m_iDirection = Menu::DOWN;
m_pDropMenuImage = NULL;
m_nImageIndex = -1;
SetDropMenuButtonStyle( false );
SetUseCaptureMouse( false );
SetButtonActivationType( ACTIVATE_ONPRESSED );
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
MenuButton::~MenuButton()
{
delete m_pDropMenuImage;
}
//-----------------------------------------------------------------------------
// Purpose: attaches a menu to the menu button
//-----------------------------------------------------------------------------
void MenuButton::SetMenu(Menu *menu)
{
m_pMenu = menu;
if (menu)
{
m_pMenu->SetVisible(false);
m_pMenu->AddActionSignalTarget(this);
m_pMenu->SetParent(this);
}
}
//-----------------------------------------------------------------------------
// Purpose: Never draw a focus border
//-----------------------------------------------------------------------------
void MenuButton::DrawFocusBorder(int tx0, int ty0, int tx1, int ty1)
{
}
//-----------------------------------------------------------------------------
// Purpose: Sets the direction from the menu button the menu should open
//-----------------------------------------------------------------------------
void MenuButton::SetOpenDirection(Menu::MenuDirection_e direction)
{
m_iDirection = direction;
}
//-----------------------------------------------------------------------------
// Purpose: hides the menu
//-----------------------------------------------------------------------------
void MenuButton::HideMenu(void)
{
if (!m_pMenu)
return;
// hide the menu
m_pMenu->SetVisible(false);
// unstick the button
BaseClass::ForceDepressed(false);
Repaint();
OnHideMenu(m_pMenu);
}
//-----------------------------------------------------------------------------
// Purpose: Called when the menu button loses focus; hides the menu
//-----------------------------------------------------------------------------
void MenuButton::OnKillFocus()
{
if ( m_pMenu && !m_pMenu->HasFocus() )
{
HideMenu();
}
BaseClass::OnKillFocus();
}
//-----------------------------------------------------------------------------
// Purpose: Called when the menu is closed
//-----------------------------------------------------------------------------
void MenuButton::OnMenuClose()
{
HideMenu();
PostActionSignal(new KeyValues("MenuClose"));
}
//-----------------------------------------------------------------------------
// Purpose: Sets the offset from where menu would normally be placed
// Only is used if menu is ALIGN_WITH_PARENT
//-----------------------------------------------------------------------------
void MenuButton::SetOpenOffsetY(int yOffset)
{
_openOffsetY = yOffset;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool MenuButton::CanBeDefaultButton(void)
{
return false;
}
//-----------------------------------------------------------------------------
// Purpose: Handles hotkey accesses
//-----------------------------------------------------------------------------
void MenuButton::DoClick()
{
if ( IsDropMenuButtonStyle() &&
m_pDropMenuImage )
{
int mx, my;
// force the menu to appear where the mouse button was pressed
input()->GetCursorPos( mx, my );
ScreenToLocal( mx, my );
int contentW, contentH;
m_pDropMenuImage->GetContentSize( contentW, contentH );
int drawX = GetWide() - contentW - 2;
if ( mx <= drawX || !OnCheckMenuItemCount() )
{
// Treat it like a "regular" button click
BaseClass::DoClick();
return;
}
}
if ( !m_pMenu )
{
return;
}
// menu is already visible, hide the menu
if (m_pMenu->IsVisible())
{
HideMenu();
return;
}
// do nothing if menu is not enabled
if (!m_pMenu->IsEnabled())
{
return;
}
// force the menu to compute required width/height
m_pMenu->PerformLayout();
// Now position it so it can fit in the workspace
m_pMenu->PositionRelativeToPanel(this, m_iDirection, _openOffsetY );
// make sure we're at the top of the draw order (and therefore our children as well)
MoveToFront();
// notify
OnShowMenu(m_pMenu);
// keep the button depressed
BaseClass::ForceDepressed(true);
// show the menu
m_pMenu->SetVisible(true);
// bring to focus
m_pMenu->RequestFocus();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void MenuButton::OnKeyCodeTyped(KeyCode code)
{
bool shift = (input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT));
bool ctrl = (input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL));
bool alt = (input()->IsKeyDown(KEY_LALT) || input()->IsKeyDown(KEY_RALT));
if (!shift && !ctrl && !alt)
{
switch (code)
{
case KEY_ENTER:
{
if ( !IsDropMenuButtonStyle() )
{
DoClick();
}
break;
}
}
}
BaseClass::OnKeyCodeTyped(code);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void MenuButton::OnCursorEntered()
{
Button::OnCursorEntered();
// post a message to the parent menu.
// forward the message on to the parent of this menu.
KeyValues *msg = new KeyValues ("CursorEnteredMenuButton");
// tell the parent this menuitem is the one that was entered so it can open the menu if it wants
msg->SetInt("VPanel", GetVPanel());
ivgui()->PostMessage(GetVParent(), msg, NULL);
}
// This style is like the IE "back" button where the left side acts like a regular button, the the right side has a little
// combo box dropdown indicator and presents and submenu
void MenuButton::SetDropMenuButtonStyle( bool state )
{
bool changed = m_bDropMenuButtonStyle != state;
m_bDropMenuButtonStyle = state;
if ( !changed )
return;
if ( state )
{
m_pDropMenuImage = new TextImage( "u" );
IScheme *pScheme = scheme()->GetIScheme( GetScheme() );
m_pDropMenuImage->SetFont(pScheme->GetFont("Marlett", IsProportional()));
// m_pDropMenuImage->SetContentAlignment(Label::a_west);
// m_pDropMenuImage->SetTextInset(3, 0);
m_nImageIndex = AddImage( m_pDropMenuImage, 0 );
}
else
{
ResetToSimpleTextImage();
delete m_pDropMenuImage;
m_pDropMenuImage = NULL;
m_nImageIndex = -1;
}
}
void MenuButton::ApplySchemeSettings( IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
if ( m_pDropMenuImage )
{
SetImageAtIndex( 1, m_pDropMenuImage, 0 );
}
}
void MenuButton::PerformLayout()
{
BaseClass::PerformLayout();
if ( !IsDropMenuButtonStyle() )
return;
Assert( m_nImageIndex >= 0 );
if ( m_nImageIndex < 0 || !m_pDropMenuImage )
return;
int w, h;
GetSize( w, h );
int contentW, contentH;
m_pDropMenuImage->ResizeImageToContent();
m_pDropMenuImage->GetContentSize( contentW, contentH );
SetImageBounds( m_nImageIndex, w - contentW - 2, contentW );
}
bool MenuButton::IsDropMenuButtonStyle() const
{
return m_bDropMenuButtonStyle;
}
void MenuButton::Paint(void)
{
BaseClass::Paint();
if ( !IsDropMenuButtonStyle() )
return;
int contentW, contentH;
m_pDropMenuImage->GetContentSize( contentW, contentH );
m_pDropMenuImage->SetColor( IsEnabled() ? GetButtonFgColor() : GetDisabledFgColor1() );
int drawX = GetWide() - contentW - 2;
surface()->DrawSetColor( IsEnabled() ? GetButtonFgColor() : GetDisabledFgColor1() );
surface()->DrawFilledRect( drawX, 3, drawX + 1, GetTall() - 3 );
}
void MenuButton::OnCursorMoved( int x, int y )
{
BaseClass::OnCursorMoved( x, y );
if ( !IsDropMenuButtonStyle() )
return;
int contentW, contentH;
m_pDropMenuImage->GetContentSize( contentW, contentH );
int drawX = GetWide() - contentW - 2;
if ( x <= drawX || !OnCheckMenuItemCount() )
{
SetButtonActivationType(ACTIVATE_ONPRESSEDANDRELEASED);
SetUseCaptureMouse(true);
}
else
{
SetButtonActivationType(ACTIVATE_ONPRESSED);
SetUseCaptureMouse(false);
}
}
Menu *MenuButton::GetMenu()
{
Assert( m_pMenu );
return m_pMenu;
}

647
vgui2/controls/MenuItem.cpp Normal file
View File

@ -0,0 +1,647 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <vgui/IScheme.h>
#include <vgui/IVGui.h>
#include "vgui/ISurface.h"
#include <KeyValues.h>
#include <vgui_controls/Controls.h>
#include <vgui_controls/Menu.h>
#include <vgui_controls/MenuItem.h>
#include <vgui_controls/TextImage.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Check box image
//-----------------------------------------------------------------------------
class MenuItemCheckImage : public TextImage
{
public:
MenuItemCheckImage(MenuItem *item) : TextImage( "g" )
{
_menuItem = item;
SetSize(20, 13);
}
virtual void Paint()
{
DrawSetTextFont(GetFont());
// draw background
DrawSetTextColor(_menuItem->GetBgColor());
DrawPrintChar(0, 0, 'g');
// draw check
if (_menuItem->IsChecked())
{
if (_menuItem->IsEnabled())
{
DrawSetTextColor(_menuItem->GetButtonFgColor());
DrawPrintChar(0, 2, 'a');
}
else if (!_menuItem->IsEnabled())
{
// draw disabled version, with embossed look
// offset image
DrawSetTextColor(_menuItem->GetDisabledFgColor1());
DrawPrintChar(1, 3, 'a');
// overlayed image
DrawSetTextColor(_menuItem->GetDisabledFgColor2());
DrawPrintChar(0, 2, 'a');
}
}
}
private:
MenuItem *_menuItem;
};
DECLARE_BUILD_FACTORY_DEFAULT_TEXT( MenuItem, MenuItem );
//-----------------------------------------------------------------------------
// Purpose: Constructor
// Input: parent - the parent of this menu item, usually a menu
// text - the name of the menu item as it appears in the menu
// cascadeMenu - if this item triggers the opening of a cascading menu
// provide a pointer to it.
// MenuItems cannot be both checkable and trigger a cascade menu.
//-----------------------------------------------------------------------------
MenuItem::MenuItem(Menu *parent, const char *panelName, const char *text, Menu *cascadeMenu, bool checkable) : Button(parent, panelName, text)
{
m_pCascadeMenu = cascadeMenu;
m_bCheckable = checkable;
SetButtonActivationType(ACTIVATE_ONRELEASED);
m_pUserData = NULL;
m_pCurrentKeyBinding = NULL;
// only one arg should be passed in.
Assert (!(cascadeMenu && checkable));
Init();
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
// Input: parent - the parent of this menu item, usually a menu
// text - the name of the menu item as it appears in the menu
// cascadeMenu - if this item triggers the opening of a cascading menu
// provide a pointer to it.
// MenuItems cannot be both checkable and trigger a cascade menu.
//-----------------------------------------------------------------------------
MenuItem::MenuItem(Menu *parent, const char *panelName, const wchar_t *wszText, Menu *cascadeMenu, bool checkable) : Button(parent, panelName, wszText)
{
m_pCascadeMenu = cascadeMenu;
m_bCheckable = checkable;
SetButtonActivationType(ACTIVATE_ONRELEASED);
m_pUserData = NULL;
m_pCurrentKeyBinding = NULL;
// only one arg should be passed in.
Assert (!(cascadeMenu && checkable));
Init();
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
MenuItem::~MenuItem()
{
delete m_pCascadeMenu;
delete m_pCascadeArrow;
delete m_pCheck;
if (m_pUserData)
{
m_pUserData->deleteThis();
}
delete m_pCurrentKeyBinding;
}
//-----------------------------------------------------------------------------
// Purpose: Basic initializer
//-----------------------------------------------------------------------------
void MenuItem::Init( void )
{
m_pCascadeArrow = NULL;
m_pCheck = NULL;
if (m_pCascadeMenu)
{
m_pCascadeMenu->SetParent(this);
m_pCascadeArrow = new TextImage (" 4"); // this makes a right pointing arrow.
m_pCascadeMenu->AddActionSignalTarget(this);
}
else if (m_bCheckable)
{
// move the text image over so we have room for the check
SetTextImageIndex(1);
m_pCheck = new MenuItemCheckImage(this);
SetImageAtIndex(0, m_pCheck, CHECK_INSET);
SetChecked(false);
}
SetButtonBorderEnabled( false );
SetUseCaptureMouse( false );
SetContentAlignment( Label::a_west );
// note menus handle all the sizing of menuItem panels
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
Menu *MenuItem::GetParentMenu()
{
return (Menu *)GetParent();
}
//-----------------------------------------------------------------------------
// Purpose: Layout the Textimage and the Arrow part of the menuItem
//-----------------------------------------------------------------------------
void MenuItem::PerformLayout()
{
Button::PerformLayout();
// make the arrow image match the button layout.
// this will make it brighten and dim like the menu buttons.
if (m_pCascadeArrow)
{
m_pCascadeArrow->SetColor(GetButtonFgColor());
}
}
//-----------------------------------------------------------------------------
// Purpose: Close the cascading menu if we have one.
//-----------------------------------------------------------------------------
void MenuItem::CloseCascadeMenu()
{
if (m_pCascadeMenu)
{
if (m_pCascadeMenu->IsVisible())
{
m_pCascadeMenu->SetVisible(false);
}
// disarm even if menu wasn't visible!
SetArmed(false);
}
}
//-----------------------------------------------------------------------------
// Purpose: Handle cursor moving in a menuItem.
//-----------------------------------------------------------------------------
void MenuItem::OnCursorMoved(int x, int y)
{
// if menu is in keymode and we moved the mouse
// highlight this item
if (GetParentMenu()->GetMenuMode() == Menu::KEYBOARD)
{
OnCursorEntered();
}
// chain up to parent
CallParentFunction(new KeyValues("OnCursorMoved", "x", x, "y", y));
}
//-----------------------------------------------------------------------------
// Purpose: Handle mouse cursor entering a menuItem.
//-----------------------------------------------------------------------------
void MenuItem::OnCursorEntered()
{
// post a message to the parent menu.
// forward the message on to the parent of this menu.
KeyValues *msg = new KeyValues ("CursorEnteredMenuItem");
// tell the parent this menuitem is the one that was entered so it can highlight it
msg->SetInt("VPanel", GetVPanel());
ivgui()->PostMessage(GetVParent(), msg, NULL);
}
//-----------------------------------------------------------------------------
// Purpose: Handle mouse cursor exiting a menuItem.
//-----------------------------------------------------------------------------
void MenuItem::OnCursorExited()
{
// post a message to the parent menu.
// forward the message on to the parent of this menu.
KeyValues *msg = new KeyValues ("CursorExitedMenuItem");
// tell the parent this menuitem is the one that was entered so it can unhighlight it
msg->SetInt("VPanel", GetVPanel());
ivgui()->PostMessage(GetVParent(), msg, NULL);
}
//-----------------------------------------------------------------------------
// Purpose: Handle mouse cursor exiting a menuItem.
//-----------------------------------------------------------------------------
void MenuItem::OnKeyCodeReleased(KeyCode code)
{
if (GetParentMenu()->GetMenuMode() == Menu::KEYBOARD && m_pCascadeMenu)
{
return;
}
// only disarm if we are not opening a cascading menu using keys.
Button::OnKeyCodeReleased(code);
}
//-----------------------------------------------------------------------------
// Purpose: Highlight a menu item
// Menu item buttons highlight if disabled, but won't activate.
//-----------------------------------------------------------------------------
void MenuItem::ArmItem()
{
// close all other menus
GetParentMenu()->CloseOtherMenus(this);
// arm the menuItem.
Button::SetArmed(true);
// When you have a submenu with no scroll bar the menu
// border will not be drawn correctly. This fixes it.
Menu *parent = GetParentMenu();
if ( parent )
{
parent->ForceCalculateWidth();
}
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: Unhighlight a menu item
//-----------------------------------------------------------------------------
void MenuItem::DisarmItem()
{
// normal behaviour is that the button becomes unarmed
// do not unarm if there is a cascading menu. CloseCascadeMenu handles this.
// and the menu handles it since we close at different times depending
// on whether menu is handling mouse or key events.
if (!m_pCascadeMenu)
{
Button::OnCursorExited();
}
// When you have a submenu with no scroll bar the menu
// border will not be drawn correctly. This fixes it.
Menu *parent = GetParentMenu();
if ( parent )
{
parent->ForceCalculateWidth();
}
Repaint();
}
bool MenuItem::IsItemArmed()
{
return Button::IsArmed();
}
//-----------------------------------------------------------------------------
// Purpose: Pass kill focus events up to parent, This will tell all panels
// in the hierarchy to hide themselves, and enables cascading menus to
// all disappear on selecting an item at the end of the tree.
//-----------------------------------------------------------------------------
void MenuItem::OnKillFocus()
{
GetParentMenu()->OnKillFocus();
}
//-----------------------------------------------------------------------------
// Purpose: fire the menu item as if it has been selected and
// Tell the owner that it is closing
//-----------------------------------------------------------------------------
void MenuItem::FireActionSignal()
{
// cascading menus items don't trigger the parent menu to disappear
// (they trigger the cascading menu to open/close when cursor is moved over/off them)
if (!m_pCascadeMenu)
{
KeyValues *kv = new KeyValues("MenuItemSelected");
kv->SetPtr("panel", this);
ivgui()->PostMessage(GetVParent(), kv, GetVPanel());
// ivgui()->PostMessage(GetVParent(), new KeyValues("MenuItemSelected"), GetVPanel());
Button::FireActionSignal();
// toggle the check next to the item if it is checkable
if (m_bCheckable)
{
SetChecked( !m_bChecked );
}
}
else
{
// if we are in keyboard mode, open the child menu.
if (GetParentMenu()->GetMenuMode() == Menu::KEYBOARD)
{
OpenCascadeMenu();
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Opens the cascading menu.
//-----------------------------------------------------------------------------
void MenuItem::OpenCascadeMenu()
{
if (m_pCascadeMenu)
{
// perform layout on menu, this way it will open in the right spot
// if the window's been moved
m_pCascadeMenu->PerformLayout();
m_pCascadeMenu->SetVisible(true);
ArmItem();
}
}
//-----------------------------------------------------------------------------
// Purpse: Return true if this item triggers a cascading menu
//-----------------------------------------------------------------------------
bool MenuItem::HasMenu()
{
return (m_pCascadeMenu != NULL);
}
//-----------------------------------------------------------------------------
// Purpose: Apply the resource scheme to the menu.
//-----------------------------------------------------------------------------
void MenuItem::ApplySchemeSettings(IScheme *pScheme)
{
// chain back first
Button::ApplySchemeSettings(pScheme);
// get color settings
SetDefaultColor(GetSchemeColor("Menu.TextColor", GetFgColor(), pScheme), GetSchemeColor("Menu.BgColor", GetBgColor(), pScheme));
SetArmedColor(GetSchemeColor("Menu.ArmedTextColor", GetFgColor(), pScheme), GetSchemeColor("Menu.ArmedBgColor", GetBgColor(), pScheme));
SetDepressedColor(GetSchemeColor("Menu.ArmedTextColor", GetFgColor(), pScheme), GetSchemeColor("Menu.ArmedBgColor", GetBgColor(), pScheme));
SetTextInset(atoi(pScheme->GetResourceString("Menu.TextInset")), 0);
// reload images since applyschemesettings in label wipes them out.
if ( m_pCascadeArrow )
{
m_pCascadeArrow->SetFont(pScheme->GetFont("Marlett", IsProportional() ));
m_pCascadeArrow->ResizeImageToContent();
AddImage(m_pCascadeArrow, 0);
}
else if (m_bCheckable)
{
( static_cast<MenuItemCheckImage *>(m_pCheck) )->SetFont( pScheme->GetFont("Marlett", IsProportional()));
SetImageAtIndex(0, m_pCheck, CHECK_INSET);
( static_cast<MenuItemCheckImage *>(m_pCheck) )->ResizeImageToContent();
}
if ( m_pCurrentKeyBinding )
{
m_pCurrentKeyBinding->SetFont(pScheme->GetFont("Default", IsProportional() ));
m_pCurrentKeyBinding->ResizeImageToContent();
}
// Have the menu redo the layout
// Get the parent to resize
Menu * parent = GetParentMenu();
if ( parent )
{
parent->ForceCalculateWidth();
}
}
//-----------------------------------------------------------------------------
// Purpose: Return the size of the text portion of the label.
// for normal menu items this is the same as the label size, but for
// cascading menus it gives you the size of the text portion only, without
// the arrow.
//-----------------------------------------------------------------------------
void MenuItem::GetTextImageSize(int &wide, int &tall)
{
GetTextImage()->GetSize(wide, tall);
}
//-----------------------------------------------------------------------------
// Purpose: Set the size of the text portion of the label.
// For normal menu items this is the same as the label size, but for
// cascading menus it sizes textImage portion only, without
// the arrow.
//-----------------------------------------------------------------------------
void MenuItem::SetTextImageSize(int wide, int tall)
{
GetTextImage()->SetSize(wide, tall);
}
//-----------------------------------------------------------------------------
// Purpose: Return the size of the arrow portion of the label.
// If the menuItem is not a cascading menu, 0 is returned.
//-----------------------------------------------------------------------------
void MenuItem::GetArrowImageSize(int &wide, int &tall)
{
wide = 0, tall = 0;
if (m_pCascadeArrow)
{
m_pCascadeArrow->GetSize(wide, tall);
return;
}
}
//-----------------------------------------------------------------------------
// Purpose: Return the size of the check portion of the label.
//-----------------------------------------------------------------------------
void MenuItem::GetCheckImageSize(int &wide, int &tall)
{
wide = 0, tall = 0;
if (m_pCheck)
{
// resize the image to the contents size
( static_cast<MenuItemCheckImage *>(m_pCheck) )->ResizeImageToContent();
m_pCheck->GetSize(wide, tall);
// include the inset for the check, since nobody but us know about the inset
wide += CHECK_INSET;
return;
}
}
//-----------------------------------------------------------------------------
// Purpose: Return a the menu that this menuItem contains
// This is useful when the parent menu's commands must be
// sent through all menus that are open as well (like hotkeys)
//-----------------------------------------------------------------------------
Menu *MenuItem::GetMenu()
{
return m_pCascadeMenu;
}
//-----------------------------------------------------------------------------
// Purpose: Get the border style for the button. Menu items have no border so
// return null.
//-----------------------------------------------------------------------------
IBorder *MenuItem::GetBorder(bool depressed, bool armed, bool selected, bool keyfocus)
{
return NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Set the menu to key mode if a child menu goes into keymode
//-----------------------------------------------------------------------------
void MenuItem::OnKeyModeSet()
{
// send the message to this parent in case this is a cascading menu
ivgui()->PostMessage(GetVParent(), new KeyValues("KeyModeSet"), GetVPanel());
}
//-----------------------------------------------------------------------------
// Purpose: Return if this menuitem is checkable or not
// This is used by menus to perform the layout properly.
//-----------------------------------------------------------------------------
bool MenuItem::IsCheckable()
{
return m_bCheckable;
}
//-----------------------------------------------------------------------------
// Purpose: Return if this menuitem is checked or not
//-----------------------------------------------------------------------------
bool MenuItem::IsChecked()
{
return m_bChecked;
}
//-----------------------------------------------------------------------------
// Purpose: Set the checked state of a checkable menuitem
// Does nothing if item is not checkable
//-----------------------------------------------------------------------------
void MenuItem::SetChecked(bool state)
{
if (m_bCheckable)
{
m_bChecked = state;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool MenuItem::CanBeDefaultButton(void)
{
return false;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
KeyValues *MenuItem::GetUserData()
{
if ( HasMenu() )
{
return m_pCascadeMenu->GetItemUserData( m_pCascadeMenu->GetActiveItem() );
}
else
{
return m_pUserData;
}
}
//-----------------------------------------------------------------------------
// Purpose: sets the user data
//-----------------------------------------------------------------------------
void MenuItem::SetUserData(const KeyValues *kv)
{
if (m_pUserData)
{
m_pUserData->deleteThis();
m_pUserData = NULL;
}
if ( kv )
{
m_pUserData = kv->MakeCopy();
}
}
//-----------------------------------------------------------------------------
// Purpose: Passing in NULL removes this object
// Input : *keyName -
//-----------------------------------------------------------------------------
void MenuItem::SetCurrentKeyBinding( char const *keyName )
{
if ( !keyName )
{
delete m_pCurrentKeyBinding;
m_pCurrentKeyBinding = NULL;
return;
}
if ( !m_pCurrentKeyBinding )
{
m_pCurrentKeyBinding = new TextImage( keyName );
}
else
{
char curtext[ 256 ];
m_pCurrentKeyBinding->GetText( curtext, sizeof( curtext ) );
if ( !Q_strcmp( curtext, keyName ) )
return;
m_pCurrentKeyBinding->SetText( keyName );
}
InvalidateLayout( false, true );
}
#define KEYBINDING_INSET 5
void MenuItem::Paint()
{
BaseClass::Paint();
if ( !m_pCurrentKeyBinding )
return;
int w, h;
GetSize( w, h );
int iw, ih;
m_pCurrentKeyBinding->GetSize( iw, ih );
int x = w - iw - KEYBINDING_INSET;
int y = ( h - ih ) / 2;
if ( IsEnabled() )
{
m_pCurrentKeyBinding->SetPos( x, y );
m_pCurrentKeyBinding->SetColor( GetButtonFgColor() );
m_pCurrentKeyBinding->Paint();
}
else
{
m_pCurrentKeyBinding->SetPos( x + 1 , y + 1 );
m_pCurrentKeyBinding->SetColor( GetDisabledFgColor1() );
m_pCurrentKeyBinding->Paint();
surface()->DrawFlushText();
m_pCurrentKeyBinding->SetPos( x, y );
m_pCurrentKeyBinding->SetColor( GetDisabledFgColor2() );
m_pCurrentKeyBinding->Paint();
}
}
void MenuItem::GetContentSize( int& cw, int &ch )
{
BaseClass::GetContentSize( cw, ch );
if ( !m_pCurrentKeyBinding )
return;
int iw, ih;
m_pCurrentKeyBinding->GetSize( iw, ih );
cw += iw + KEYBINDING_INSET;
ch = max( ch, ih );
}

View File

@ -0,0 +1,374 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <vgui/ISurface.h>
#include <KeyValues.h>
#include <vgui/IInput.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/Controls.h>
#include <vgui_controls/Label.h>
#include <vgui_controls/MessageBox.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
vgui::Panel *MessageBox_Factory()
{
return new MessageBox("MessageBox", "MessageBoxText");
}
DECLARE_BUILD_FACTORY_CUSTOM( MessageBox, MessageBox_Factory );
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
MessageBox::MessageBox(const char *title, const char *text, Panel *parent) : Frame(parent, NULL, false)
{
SetTitle(title, true);
m_pMessageLabel = new Label(this, NULL, text);
Init();
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
MessageBox::MessageBox(const wchar_t *wszTitle, const wchar_t *wszText, Panel *parent) : Frame(parent, NULL, false)
{
SetTitle(wszTitle, true);
m_pMessageLabel = new Label(this, NULL, wszText);
Init();
}
//-----------------------------------------------------------------------------
// Purpose: Constructor Helper
//-----------------------------------------------------------------------------
void MessageBox::Init()
{
SetDeleteSelfOnClose(true);
m_pFrameOver = NULL;
SetMenuButtonResponsive(false);
SetMinimizeButtonVisible(false);
SetCloseButtonVisible(false);
SetSizeable(false);
m_pOkButton = new Button(this, NULL, "#MessageBox_OK");
m_pOkButton->SetCommand( "OnOk" );
m_pOkButton->AddActionSignalTarget(this);
m_pCancelButton = new Button(this, NULL, "#MessageBox_Cancel");
m_pCancelButton->SetCommand( "OnCancel" );
m_pCancelButton->AddActionSignalTarget(this);
m_pCancelButton->SetVisible( false );
m_OkCommand = m_CancelCommand = NULL;
m_bNoAutoClose = false;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
MessageBox::~MessageBox()
{
if ( m_OkCommand )
{
m_OkCommand->deleteThis();
}
if ( m_CancelCommand )
{
m_CancelCommand->deleteThis();
}
}
//-----------------------------------------------------------------------------
// Purpose: size the message label properly
//-----------------------------------------------------------------------------
void MessageBox::OnCommand( const char *pCommand )
{
if ( !Q_stricmp( pCommand, "OnOk" ) )
{
if ( m_OkCommand )
{
PostActionSignal(m_OkCommand->MakeCopy());
}
}
else if ( !Q_stricmp( pCommand, "OnCancel" ) )
{
if ( m_CancelCommand )
{
PostActionSignal(m_CancelCommand->MakeCopy());
}
}
if ( !m_bNoAutoClose )
{
OnShutdownRequest();
}
}
//-----------------------------------------------------------------------------
// Purpose: size the message label properly
//-----------------------------------------------------------------------------
void MessageBox::ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
int wide, tall;
m_pMessageLabel->GetContentSize(wide, tall);
m_pMessageLabel->SetSize(wide, tall);
wide += 100;
tall += 100;
SetSize(wide, tall);
// move to the middle of the screen
if ( m_pFrameOver )
{
int frameX, frameY;
int frameWide, frameTall;
m_pFrameOver->GetPos(frameX, frameY);
m_pFrameOver->GetSize(frameWide, frameTall);
SetPos((frameWide - wide) / 2 + frameX, (frameTall - tall) / 2 + frameY);
}
else
{
int swide, stall;
surface()->GetScreenSize(swide, stall);
// put the dialog in the middle of the screen
SetPos((swide - wide) / 2, (stall - tall) / 2);
}
}
//-----------------------------------------------------------------------------
// Purpose: Put the message box into a modal state
// Does not suspend execution - use addActionSignal to get return value
//-----------------------------------------------------------------------------
void MessageBox::DoModal(Frame* pFrameOver)
{
ShowWindow(pFrameOver);
/*
// move to the middle of the screen
// get the screen size
int wide, tall;
// get our dialog size
GetSize(wide, tall);
if (pFrameOver)
{
int frameX, frameY;
int frameWide, frameTall;
pFrameOver->GetPos(frameX, frameY);
pFrameOver->GetSize(frameWide, frameTall);
SetPos((frameWide - wide) / 2 + frameX, (frameTall - tall) / 2 + frameY);
}
else
{
int swide, stall;
surface()->GetScreenSize(swide, stall);
// put the dialog in the middle of the screen
SetPos((swide - wide) / 2, (stall - tall) / 2);
}
SetVisible( true );
SetEnabled( true );
MoveToFront();
if (m_pOkButton->IsVisible())
m_pOkButton->RequestFocus();
else // handle message boxes with no button
RequestFocus();
*/
input()->SetAppModalSurface(GetVPanel());
}
void MessageBox::ShowWindow(Frame *pFrameOver)
{
m_pFrameOver = pFrameOver;
SetVisible( true );
SetEnabled( true );
MoveToFront();
if ( m_pOkButton->IsVisible() )
{
m_pOkButton->RequestFocus();
}
else // handle message boxes with no button
{
RequestFocus();
}
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: Put the text and OK buttons in correct place
//-----------------------------------------------------------------------------
void MessageBox::PerformLayout()
{
int x, y, wide, tall;
GetClientArea(x, y, wide, tall);
wide += x;
tall += y;
int boxWidth, boxTall;
GetSize(boxWidth, boxTall);
int oldWide, oldTall;
m_pOkButton->GetSize(oldWide, oldTall);
int btnWide, btnTall;
m_pOkButton->GetContentSize(btnWide, btnTall);
btnWide = max(oldWide, btnWide + 10);
btnTall = max(oldTall, btnTall + 10);
m_pOkButton->SetSize(btnWide, btnTall);
int btnWide2 = 0, btnTall2 = 0;
if ( m_pCancelButton->IsVisible() )
{
m_pCancelButton->GetSize(oldWide, oldTall);
m_pCancelButton->GetContentSize(btnWide2, btnTall2);
btnWide2 = max(oldWide, btnWide2 + 10);
btnTall2 = max(oldTall, btnTall2 + 10);
m_pCancelButton->SetSize(btnWide2, btnTall2);
}
boxWidth = max(boxWidth, m_pMessageLabel->GetWide() + 100);
boxWidth = max(boxWidth, (btnWide + btnWide2) * 2 + 30);
SetSize(boxWidth, boxTall);
GetSize(boxWidth, boxTall);
m_pMessageLabel->SetPos((wide/2)-(m_pMessageLabel->GetWide()/2) + x, y + 15);
if ( !m_pCancelButton->IsVisible() )
{
m_pOkButton->SetPos((wide/2)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15);
}
else
{
m_pOkButton->SetPos((wide/4)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15);
m_pCancelButton->SetPos((3*wide/4)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15);
}
BaseClass::PerformLayout();
GetSize(boxWidth, boxTall);
}
//-----------------------------------------------------------------------------
// Purpose: Set a string command to be sent when the OK button is pressed.
//-----------------------------------------------------------------------------
void MessageBox::SetCommand(const char *command)
{
if (m_OkCommand)
{
m_OkCommand->deleteThis();
}
m_OkCommand = new KeyValues("Command", "command", command);
}
//-----------------------------------------------------------------------------
// Purpose: Sets the command
//-----------------------------------------------------------------------------
void MessageBox::SetCommand(KeyValues *command)
{
if (m_OkCommand)
{
m_OkCommand->deleteThis();
}
m_OkCommand = command;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void MessageBox::OnShutdownRequest()
{
// Shutdown the dialog
PostMessage(this, new KeyValues("Close"));
}
//-----------------------------------------------------------------------------
// Purpose: Set the visibility of the OK button.
//-----------------------------------------------------------------------------
void MessageBox::SetOKButtonVisible(bool state)
{
m_pOkButton->SetVisible(state);
}
//-----------------------------------------------------------------------------
// Purpose: Sets the Text on the OK button
//-----------------------------------------------------------------------------
void MessageBox::SetOKButtonText(const char *buttonText)
{
m_pOkButton->SetText(buttonText);
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: Sets the Text on the OK button
//-----------------------------------------------------------------------------
void MessageBox::SetOKButtonText(const wchar_t *wszButtonText)
{
m_pOkButton->SetText(wszButtonText);
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Cancel button (off by default)
//-----------------------------------------------------------------------------
void MessageBox::SetCancelButtonVisible(bool state)
{
m_pCancelButton->SetVisible(state);
InvalidateLayout();
}
void MessageBox::SetCancelButtonText(const char *buttonText)
{
m_pCancelButton->SetText(buttonText);
InvalidateLayout();
}
void MessageBox::SetCancelButtonText(const wchar_t *wszButtonText)
{
m_pCancelButton->SetText(wszButtonText);
InvalidateLayout();
}
void MessageBox::SetCancelCommand( KeyValues *command )
{
if (m_CancelCommand)
{
m_CancelCommand->deleteThis();
}
m_CancelCommand = command;
}
//-----------------------------------------------------------------------------
// Purpose: Toggles visibility of the close box.
//-----------------------------------------------------------------------------
void MessageBox::DisableCloseButton(bool state)
{
BaseClass::SetCloseButtonVisible(state);
m_bNoAutoClose = true;
}

6577
vgui2/controls/Panel.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,366 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "vgui/MouseCode.h"
#include "vgui/IInput.h"
#include "vgui/IScheme.h"
#include "vgui/ISurface.h"
#include "vgui_controls/EditablePanel.h"
#include "vgui_controls/ScrollBar.h"
#include "vgui_controls/Label.h"
#include "vgui_controls/Button.h"
#include "vgui_controls/Controls.h"
#include "vgui_controls/PanelListPanel.h"
#include "KeyValues.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
PanelListPanel::PanelListPanel( vgui::Panel *parent, char const *panelName ) : Panel( parent, panelName )
{
SetBounds( 0, 0, 100, 100 );
m_vbar = new ScrollBar(this, "PanelListPanelVScroll", true);
m_vbar->SetVisible(false);
m_vbar->AddActionSignalTarget( this );
m_pPanelEmbedded = new EditablePanel(this, "PanelListEmbedded");
m_pPanelEmbedded->SetBounds(0, 0, 20, 20);
m_pPanelEmbedded->SetPaintBackgroundEnabled( false );
m_pPanelEmbedded->SetPaintBorderEnabled(false);
m_iFirstColumnWidth = 100; // default width
if ( IsProportional() )
{
m_iDefaultHeight = scheme()->GetProportionalScaledValueEx( GetScheme(), DEFAULT_HEIGHT );
m_iPanelBuffer = scheme()->GetProportionalScaledValueEx( GetScheme(), PANELBUFFER );
}
else
{
m_iDefaultHeight = DEFAULT_HEIGHT;
m_iPanelBuffer = PANELBUFFER;
}
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
PanelListPanel::~PanelListPanel()
{
// free data from table
DeleteAllItems();
}
void PanelListPanel::SetVerticalBufferPixels( int buffer )
{
m_iPanelBuffer = buffer;
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: counts the total vertical pixels
//-----------------------------------------------------------------------------
int PanelListPanel::ComputeVPixelsNeeded()
{
int pixels = 0;
for ( int i = 0; i < m_SortedItems.Count(); i++ )
{
Panel *panel = m_DataItems[ m_SortedItems[i] ].panel;
if ( !panel )
continue;
int w, h;
panel->GetSize( w, h );
pixels += m_iPanelBuffer; // add in buffer. between items.
pixels += h;
}
pixels += m_iPanelBuffer; // add in buffer below last item
return pixels;
}
//-----------------------------------------------------------------------------
// Purpose: Returns the panel to use to render a cell
//-----------------------------------------------------------------------------
Panel *PanelListPanel::GetCellRenderer( int row )
{
if ( !m_SortedItems.IsValidIndex(row) )
return NULL;
Panel *panel = m_DataItems[ m_SortedItems[row] ].panel;
return panel;
}
//-----------------------------------------------------------------------------
// Purpose: adds an item to the view
// data->GetName() is used to uniquely identify an item
// data sub items are matched against column header name to be used in the table
//-----------------------------------------------------------------------------
int PanelListPanel::AddItem( Panel *labelPanel, Panel *panel)
{
Assert(panel);
if ( labelPanel )
{
labelPanel->SetParent( m_pPanelEmbedded );
}
panel->SetParent( m_pPanelEmbedded );
int itemID = m_DataItems.AddToTail();
DATAITEM &newitem = m_DataItems[itemID];
newitem.labelPanel = labelPanel;
newitem.panel = panel;
m_SortedItems.AddToTail(itemID);
InvalidateLayout();
return itemID;
}
//-----------------------------------------------------------------------------
// Purpose: iteration accessor
//-----------------------------------------------------------------------------
int PanelListPanel::GetItemCount()
{
return m_DataItems.Count();
}
//-----------------------------------------------------------------------------
// Purpose: returns label panel for this itemID
//-----------------------------------------------------------------------------
Panel *PanelListPanel::GetItemLabel(int itemID)
{
if ( !m_DataItems.IsValidIndex(itemID) )
return NULL;
return m_DataItems[itemID].labelPanel;
}
//-----------------------------------------------------------------------------
// Purpose: returns label panel for this itemID
//-----------------------------------------------------------------------------
Panel *PanelListPanel::GetItemPanel(int itemID)
{
if ( !m_DataItems.IsValidIndex(itemID) )
return NULL;
return m_DataItems[itemID].panel;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void PanelListPanel::RemoveItem(int itemID)
{
if ( !m_DataItems.IsValidIndex(itemID) )
return;
DATAITEM &item = m_DataItems[itemID];
if ( item.panel )
{
item.panel->MarkForDeletion();
}
if ( item.labelPanel )
{
item.labelPanel->MarkForDeletion();
}
m_DataItems.Remove(itemID);
m_SortedItems.FindAndRemove(itemID);
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: clears and deletes all the memory used by the data items
//-----------------------------------------------------------------------------
void PanelListPanel::DeleteAllItems()
{
FOR_EACH_LL( m_DataItems, i )
{
if ( m_DataItems[i].panel )
{
delete m_DataItems[i].panel;
}
}
m_DataItems.RemoveAll();
m_SortedItems.RemoveAll();
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: clears and deletes all the memory used by the data items
//-----------------------------------------------------------------------------
void PanelListPanel::RemoveAll()
{
m_DataItems.RemoveAll();
m_SortedItems.RemoveAll();
// move the scrollbar to the top of the list
m_vbar->SetValue(0);
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void PanelListPanel::OnSizeChanged(int wide, int tall)
{
BaseClass::OnSizeChanged(wide, tall);
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: relayouts out the panel after any internal changes
//-----------------------------------------------------------------------------
void PanelListPanel::PerformLayout()
{
int wide, tall;
GetSize( wide, tall );
int vpixels = ComputeVPixelsNeeded();
m_vbar->SetVisible( true );
m_vbar->SetRange( 0, vpixels );
m_vbar->SetRangeWindow( tall );
m_vbar->SetButtonPressedScrollValue( tall / 4 ); // standard height of labels/buttons etc.
m_vbar->SetPos( wide - m_vbar->GetWide() - 2, 0 );
m_vbar->SetSize( m_vbar->GetWide(), tall - 2 );
int top = m_vbar->GetValue();
m_pPanelEmbedded->SetPos( 1, -top );
m_pPanelEmbedded->SetSize( wide - m_vbar->GetWide() - 2, vpixels );
int sliderPos = m_vbar->GetValue();
// Now lay out the controls on the embedded panel
int y = 0;
int h = 0;
int totalh = 0;
int x_inset = 0;
for ( int i = 0; i < m_SortedItems.Count(); i++, y += h )
{
// add in a little buffer between panels
y += m_iPanelBuffer;
DATAITEM &item = m_DataItems[ m_SortedItems[i] ];
h = item.panel->GetTall();
totalh += h;
if (totalh >= sliderPos)
{
if ( item.labelPanel )
{
item.labelPanel->SetBounds( x_inset, y, m_iFirstColumnWidth, h );
}
int xpos = x_inset + m_iFirstColumnWidth + m_iPanelBuffer;
int itemwide = wide - xpos - m_vbar->GetWide() - 12;
item.panel->SetBounds( xpos, y, itemwide, h );
}
}
}
//-----------------------------------------------------------------------------
// Purpose: scheme settings
//-----------------------------------------------------------------------------
void PanelListPanel::ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
SetBorder(pScheme->GetBorder("ButtonDepressedBorder"));
SetBgColor(GetSchemeColor("ListPanel.BgColor", GetBgColor(), pScheme));
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void PanelListPanel::OnSliderMoved( int position )
{
InvalidateLayout();
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void PanelListPanel::MoveScrollBarToTop()
{
m_vbar->SetValue(0);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void PanelListPanel::SetFirstColumnWidth( int width )
{
m_iFirstColumnWidth = width;
}
//-----------------------------------------------------------------------------
// Purpose: data accessor
//-----------------------------------------------------------------------------
int PanelListPanel::GetFirstColumnWidth()
{
return m_iFirstColumnWidth;
}
//-----------------------------------------------------------------------------
// Purpose: moves the scrollbar with the mousewheel
//-----------------------------------------------------------------------------
void PanelListPanel::OnMouseWheeled(int delta)
{
int val = m_vbar->GetValue();
val -= (delta * DEFAULT_HEIGHT);
m_vbar->SetValue(val);
}
//-----------------------------------------------------------------------------
// Purpose: selection handler
//-----------------------------------------------------------------------------
void PanelListPanel::SetSelectedPanel( Panel *panel )
{
if ( panel != m_hSelectedItem )
{
// notify the panels of the selection change
if ( m_hSelectedItem )
{
PostMessage( m_hSelectedItem, new KeyValues("PanelSelected", "state", 0) );
}
if ( panel )
{
PostMessage( panel, new KeyValues("PanelSelected", "state", 1) );
}
m_hSelectedItem = panel;
}
}
//-----------------------------------------------------------------------------
// Purpose: data accessor
//-----------------------------------------------------------------------------
Panel *PanelListPanel::GetSelectedPanel()
{
return m_hSelectedItem;
}

View File

@ -0,0 +1,300 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <vgui_controls/ProgressBar.h>
#include <vgui_controls/Controls.h>
#include <vgui/ILocalize.h>
#include <vgui/IScheme.h>
#include <vgui/ISurface.h>
#include <KeyValues.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
DECLARE_BUILD_FACTORY( ProgressBar );
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
ProgressBar::ProgressBar(Panel *parent, const char *panelName) : Panel(parent, panelName)
{
_progress = 0.0f;
m_pszDialogVar = NULL;
SetSegmentInfo( 4, 8 );
SetBarInset( 4 );
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
ProgressBar::~ProgressBar()
{
delete [] m_pszDialogVar;
}
//-----------------------------------------------------------------------------
// Purpose: data accessor
//-----------------------------------------------------------------------------
void ProgressBar::SetSegmentInfo( int gap, int width )
{
_segmentGap = gap;
_segmentWide = width;
}
//-----------------------------------------------------------------------------
// Purpose: returns the number of segment blocks drawn
//-----------------------------------------------------------------------------
int ProgressBar::GetDrawnSegmentCount()
{
int wide, tall;
GetSize(wide, tall);
int segmentTotal = wide / (_segmentGap + _segmentWide);
return (int)(segmentTotal * _progress);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ProgressBar::PaintBackground()
{
int wide, tall;
GetSize(wide, tall);
surface()->DrawSetColor(GetBgColor());
surface()->DrawFilledRect(0, 0, wide, tall);
// gaps
int segmentTotal = wide / (_segmentGap + _segmentWide);
int segmentsDrawn = (int)(segmentTotal * _progress);
surface()->DrawSetColor(GetFgColor());
int x = 0, y = m_iBarInset;
for (int i = 0; i < segmentsDrawn; i++)
{
x += _segmentGap;
surface()->DrawFilledRect(x, y, x + _segmentWide, y + tall - (y * 2));
x += _segmentWide;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ProgressBar::SetProgress(float progress)
{
if (progress != _progress)
{
// clamp the progress value within the range
if (progress < 0.0f)
{
progress = 0.0f;
}
else if (progress > 1.0f)
{
progress = 1.0f;
}
_progress = progress;
Repaint();
}
}
//-----------------------------------------------------------------------------
// Purpose: data accessor
//-----------------------------------------------------------------------------
float ProgressBar::GetProgress()
{
return _progress;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ProgressBar::ApplySchemeSettings(IScheme *pScheme)
{
Panel::ApplySchemeSettings(pScheme);
SetFgColor(GetSchemeColor("ProgressBar.FgColor", pScheme));
SetBgColor(GetSchemeColor("ProgressBar.BgColor", pScheme));
SetBorder(pScheme->GetBorder("ButtonDepressedBorder"));
}
//-----------------------------------------------------------------------------
// Purpose: utility function for calculating a time remaining string
//-----------------------------------------------------------------------------
bool ProgressBar::ConstructTimeRemainingString(wchar_t *output, int outputBufferSizeInBytes, float startTime, float currentTime, float currentProgress, float lastProgressUpdateTime, bool addRemainingSuffix)
{
Assert(lastProgressUpdateTime <= currentTime);
output[0] = 0;
// calculate pre-extrapolation values
float timeElapsed = lastProgressUpdateTime - startTime;
float totalTime = timeElapsed / currentProgress;
// calculate seconds
int secondsRemaining = (int)(totalTime - timeElapsed);
if (lastProgressUpdateTime < currentTime)
{
// old update, extrapolate
float progressRate = currentProgress / timeElapsed;
float extrapolatedProgress = progressRate * (currentTime - startTime);
float extrapolatedTotalTime = (currentTime - startTime) / extrapolatedProgress;
secondsRemaining = (int)(extrapolatedTotalTime - timeElapsed);
}
// if there's some time, make sure it's at least one second left
if ( secondsRemaining == 0 && ( ( totalTime - timeElapsed ) > 0 ) )
{
secondsRemaining = 1;
}
// calculate minutes
int minutesRemaining = 0;
while (secondsRemaining >= 60)
{
minutesRemaining++;
secondsRemaining -= 60;
}
char minutesBuf[16];
Q_snprintf(minutesBuf, sizeof( minutesBuf ), "%d", minutesRemaining);
char secondsBuf[16];
Q_snprintf(secondsBuf, sizeof( secondsBuf ), "%d", secondsRemaining);
if (minutesRemaining > 0)
{
wchar_t unicodeMinutes[16];
localize()->ConvertANSIToUnicode(minutesBuf, unicodeMinutes, sizeof( unicodeMinutes ));
wchar_t unicodeSeconds[16];
localize()->ConvertANSIToUnicode(secondsBuf, unicodeSeconds, sizeof( unicodeSeconds ));
const char *unlocalizedString = "#vgui_TimeLeftMinutesSeconds";
if (minutesRemaining == 1 && secondsRemaining == 1)
{
unlocalizedString = "#vgui_TimeLeftMinuteSecond";
}
else if (minutesRemaining == 1)
{
unlocalizedString = "#vgui_TimeLeftMinuteSeconds";
}
else if (secondsRemaining == 1)
{
unlocalizedString = "#vgui_TimeLeftMinutesSecond";
}
char unlocString[64];
Q_strncpy(unlocString, unlocalizedString,sizeof( unlocString ));
if (addRemainingSuffix)
{
Q_strncat(unlocString, "Remaining", sizeof(unlocString ), COPY_ALL_CHARACTERS);
}
localize()->ConstructString(output, outputBufferSizeInBytes, localize()->Find(unlocString), 2, unicodeMinutes, unicodeSeconds);
}
else if (secondsRemaining > 0)
{
wchar_t unicodeSeconds[16];
localize()->ConvertANSIToUnicode(secondsBuf, unicodeSeconds, sizeof( unicodeSeconds ));
const char *unlocalizedString = "#vgui_TimeLeftSeconds";
if (secondsRemaining == 1)
{
unlocalizedString = "#vgui_TimeLeftSecond";
}
char unlocString[64];
Q_strncpy(unlocString, unlocalizedString,sizeof(unlocString));
if (addRemainingSuffix)
{
Q_strncat(unlocString, "Remaining",sizeof(unlocString), COPY_ALL_CHARACTERS);
}
localize()->ConstructString(output, outputBufferSizeInBytes, localize()->Find(unlocString), 1, unicodeSeconds);
}
else
{
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose: data accessor
//-----------------------------------------------------------------------------
void ProgressBar::SetBarInset( int pixels )
{
m_iBarInset = pixels;
}
//-----------------------------------------------------------------------------
// Purpose: data accessor
//-----------------------------------------------------------------------------
int ProgressBar::GetBarInset( void )
{
return m_iBarInset;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ProgressBar::ApplySettings(KeyValues *inResourceData)
{
_progress = inResourceData->GetFloat("progress", 0.0f);
const char *dialogVar = inResourceData->GetString("variable", "");
if (dialogVar && *dialogVar)
{
m_pszDialogVar = new char[strlen(dialogVar) + 1];
strcpy(m_pszDialogVar, dialogVar);
}
BaseClass::ApplySettings(inResourceData);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ProgressBar::GetSettings(KeyValues *outResourceData)
{
BaseClass::GetSettings(outResourceData);
outResourceData->SetFloat("progress", _progress );
if (m_pszDialogVar)
{
outResourceData->SetString("variable", m_pszDialogVar);
}
}
//-----------------------------------------------------------------------------
// Purpose: Returns a string description of the panel fields for use in the UI
//-----------------------------------------------------------------------------
const char *ProgressBar::GetDescription( void )
{
static char buf[1024];
_snprintf(buf, sizeof(buf), "%s, string progress, string variable", BaseClass::GetDescription());
return buf;
}
//-----------------------------------------------------------------------------
// Purpose: updates progress bar bases on values
//-----------------------------------------------------------------------------
void ProgressBar::OnDialogVariablesChanged(KeyValues *dialogVariables)
{
if (m_pszDialogVar)
{
int val = dialogVariables->GetInt(m_pszDialogVar, -1);
if (val >= 0.0f)
{
SetProgress(val / 100.0f);
}
}
}

View File

@ -0,0 +1,360 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <vgui/IInput.h>
#include <vgui/ILocalize.h>
#include <vgui/ISurface.h>
#include <vgui/ISystem.h>
#include <vgui/IVGui.h>
#include <KeyValues.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/Controls.h>
#include <vgui_controls/Label.h>
#include <vgui_controls/ProgressBar.h>
#include <vgui_controls/ProgressBox.h>
#include <stdio.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
ProgressBox::ProgressBox(const char *title, const char *text, const char *pszUnknownTimeString, Panel *parent) : Frame(parent, NULL, parent ? false : true)
{
// save off the non-localized title, since we may need to dynamically localize it (on progress updates)
const wchar_t *ws = localize()->Find(title);
if (ws)
{
wcsncpy(m_wszTitleString, ws, sizeof(m_wszTitleString) / sizeof(wchar_t));
}
else
{
localize()->ConvertANSIToUnicode(title, m_wszTitleString, sizeof(m_wszTitleString));
}
m_pMessageLabel = new Label(this, NULL, pszUnknownTimeString);
ws = localize()->Find(text);
if (ws)
{
wcsncpy(m_wcsInfoString, ws, sizeof(m_wcsInfoString) / sizeof(wchar_t));
}
else
{
m_wcsInfoString[0] = 0;
}
ws = localize()->Find(pszUnknownTimeString);
if (ws)
{
wcsncpy(m_wszUnknownTimeString, ws, sizeof(m_wszUnknownTimeString) / sizeof(wchar_t));
}
else
{
m_wszUnknownTimeString[0] = 0;
}
Init();
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
ProgressBox::ProgressBox(const wchar_t *wszTitle, const wchar_t *wszText, const wchar_t *wszUnknownTimeString, Panel *parent) : Frame(parent, NULL, parent ? false : true)
{
wcsncpy(m_wszTitleString, wszTitle, sizeof(m_wszTitleString) / sizeof(wchar_t));
m_pMessageLabel = new Label(this, NULL, wszUnknownTimeString);
wcsncpy(m_wcsInfoString, wszText, sizeof(m_wcsInfoString) / sizeof(wchar_t));
wcsncpy(m_wszUnknownTimeString, wszUnknownTimeString, sizeof(m_wszUnknownTimeString) / sizeof(wchar_t));
Init();
}
//-----------------------------------------------------------------------------
// Purpose: Constructor Helper
//-----------------------------------------------------------------------------
void ProgressBox::Init()
{
m_pProgressBar = new ProgressBar(this, NULL);
m_pProgressBar->SetVisible(false);
m_pCancelButton = new Button(this, NULL, "#VGui_Cancel");
m_pCancelButton->SetSize(72, 24);
m_pCancelButton->SetCommand("Cancel");
SetMenuButtonResponsive(false);
SetMinimizeButtonVisible(false);
SetCancelButtonVisible(false);
SetSizeable(false);
SetSize(384, 128);
m_flCurrentProgress = 0.0f;
m_flFirstProgressUpdate = -0.1f;
m_flLastProgressUpdate = 0.0f;
// mark ourselves as needed ticked once a second, to force us to repaint
ivgui()->AddTickSignal(GetVPanel(), 1000);
UpdateTitle();
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
ProgressBox::~ProgressBox()
{
}
//-----------------------------------------------------------------------------
// Purpose: resize the message label
//-----------------------------------------------------------------------------
void ProgressBox::ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
int wide, tall;
m_pMessageLabel->GetContentSize(wide, tall);
SetSize(384, tall + 92);
m_pMessageLabel->SetSize(344, tall);
}
//-----------------------------------------------------------------------------
// Purpose: Put the message box into a modal state
// Does not suspend execution - use addActionSignal to get return value
//-----------------------------------------------------------------------------
void ProgressBox::DoModal(Frame *pFrameOver)
{
ShowWindow(pFrameOver);
input()->SetAppModalSurface(GetVPanel());
}
//-----------------------------------------------------------------------------
// Purpose: Activates the window
//-----------------------------------------------------------------------------
void ProgressBox::ShowWindow(Frame *pFrameOver)
{
// move to the middle of the screen
// get the screen size
int wide, tall;
// get our dialog size
GetSize(wide, tall);
if (pFrameOver)
{
int frameX, frameY;
int frameWide, frameTall;
pFrameOver->GetPos(frameX, frameY);
pFrameOver->GetSize(frameWide, frameTall);
SetPos((frameWide - wide) / 2 + frameX, (frameTall - tall) / 2 + frameY);
}
else
{
int swide, stall;
surface()->GetScreenSize(swide, stall);
// put the dialog in the middle of the screen
SetPos((swide - wide) / 2, (stall - tall) / 2);
}
BaseClass::Activate();
}
//-----------------------------------------------------------------------------
// Purpose: Put the text and OK buttons in correct place
//-----------------------------------------------------------------------------
void ProgressBox::PerformLayout()
{
int x, y, wide, tall;
GetClientArea(x, y, wide, tall);
wide += x;
tall += y;
int leftEdge = x + 16;
m_pMessageLabel->SetPos(leftEdge, y + 12);
m_pProgressBar->SetPos(leftEdge, y + 14 + m_pMessageLabel->GetTall() + 2);
m_pProgressBar->SetSize(wide - 44, 24);
if (m_pCancelButton->IsVisible())
{
// make room for cancel
int px, py, pw, pt;
int offs = m_pCancelButton->GetWide();
m_pProgressBar->GetBounds(px, py, pw, pt);
m_pCancelButton->SetPos(px + pw - offs, py);
m_pProgressBar->SetSize(pw - offs - 10, pt);
}
BaseClass::PerformLayout();
}
//-----------------------------------------------------------------------------
// Purpose: updates progress bar, range [0, 1]
//-----------------------------------------------------------------------------
void ProgressBox::SetProgress(float progress)
{
Assert(progress >= 0.0f && progress <= 1.0f);
m_pProgressBar->SetProgress(progress);
m_pProgressBar->SetVisible(true);
// only update progress timings if the progress has actually changed
if (progress != m_flCurrentProgress)
{
// store off timings for calculating time remaining
if (m_flFirstProgressUpdate < 0.0f)
{
m_flFirstProgressUpdate = (float)system()->GetFrameTime();
}
m_flCurrentProgress = progress;
m_flLastProgressUpdate = (float)system()->GetFrameTime();
UpdateTitle();
}
}
//-----------------------------------------------------------------------------
// Purpose: sets the info text
//-----------------------------------------------------------------------------
void ProgressBox::SetText(const char *text)
{
m_pMessageLabel->SetText(text);
}
//-----------------------------------------------------------------------------
// Purpose: Updates the dialog title text
//-----------------------------------------------------------------------------
void ProgressBox::UpdateTitle()
{
// update progress text
wchar_t unicode[256];
wchar_t completion[64];
if ((int)(m_flCurrentProgress * 100.0f) > 0)
{
_snwprintf(completion, sizeof(completion) / sizeof(wchar_t), L"- %d%% complete", (int)(m_flCurrentProgress * 100.0f));
}
else
{
completion[0] = 0;
}
localize()->ConstructString(unicode, sizeof(unicode), m_wszTitleString, 1, completion);
SetTitle(unicode, true);
}
//-----------------------------------------------------------------------------
// Purpose: called every render
//-----------------------------------------------------------------------------
void ProgressBox::OnThink()
{
// calculate the progress made
if (m_flFirstProgressUpdate >= 0.0f && m_wcsInfoString[0])
{
wchar_t timeRemaining[128];
if (ProgressBar::ConstructTimeRemainingString(timeRemaining, sizeof(timeRemaining), m_flFirstProgressUpdate, (float)system()->GetFrameTime(), m_flCurrentProgress, m_flLastProgressUpdate, true))
{
wchar_t unicode[256];
localize()->ConstructString(unicode, sizeof(unicode), m_wcsInfoString, 1, timeRemaining);
m_pMessageLabel->SetText(unicode);
}
else
{
m_pMessageLabel->SetText(m_wszUnknownTimeString);
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Forces us to repaint once per second
//-----------------------------------------------------------------------------
void ProgressBox::OnTick()
{
if (m_flFirstProgressUpdate >= 0.0f)
{
Repaint();
}
BaseClass::OnTick();
}
//-----------------------------------------------------------------------------
// Purpose: Handles ESC closing dialog
//-----------------------------------------------------------------------------
void ProgressBox::OnCommand(const char *command)
{
if (!stricmp(command, "Cancel"))
{
OnCancel();
}
else
{
BaseClass::OnCommand(command);
}
}
//-----------------------------------------------------------------------------
// Purpose: close button pressed
//-----------------------------------------------------------------------------
void ProgressBox::OnCloseFrameButtonPressed()
{
OnCancel();
}
//-----------------------------------------------------------------------------
// Purpose: Deletes self when closed
//-----------------------------------------------------------------------------
void ProgressBox::OnClose()
{
BaseClass::OnClose();
// modal surface is released on deletion
MarkForDeletion();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ProgressBox::OnShutdownRequest()
{
// Shutdown the dialog
PostMessage(this, new KeyValues("Command", "command", "Cancel"));
}
//-----------------------------------------------------------------------------
// Purpose: On update cancelled
//-----------------------------------------------------------------------------
void ProgressBox::OnCancel()
{
// post a message that we've been cancelled
PostActionSignal(new KeyValues("ProgressBoxCancelled"));
// close this dialog
Close();
}
//-----------------------------------------------------------------------------
// Purpose: Toggles visibility of the close box.
//-----------------------------------------------------------------------------
void ProgressBox::SetCancelButtonVisible(bool state)
{
BaseClass::SetCloseButtonVisible(state);
m_pCancelButton->SetVisible(state);
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ProgressBox::SetCancelButtonEnabled(bool state)
{
m_pCancelButton->SetEnabled(state);
BaseClass::SetCloseButtonVisible(state);
InvalidateLayout();
Repaint();
}

View File

@ -0,0 +1,297 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <vgui/KeyCode.h>
#include <KeyValues.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/PropertyDialog.h>
#include <vgui_controls/PropertySheet.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
PropertyDialog::PropertyDialog(Panel *parent, const char *panelName) : Frame(parent, panelName)
{
// create the property sheet
_propertySheet = new PropertySheet(this, "Sheet");
_propertySheet->AddActionSignalTarget(this);
_propertySheet->SetTabPosition(1);
// add the buttons
_okButton = new Button(this, "OKButton", "#PropertyDialog_OK");
_okButton->AddActionSignalTarget(this);
_okButton->SetTabPosition(2);
_okButton->SetCommand("OK");
GetFocusNavGroup().SetDefaultButton(_okButton);
_cancelButton = new Button(this, "CancelButton", "#PropertyDialog_Cancel");
_cancelButton->AddActionSignalTarget(this);
_cancelButton->SetTabPosition(3);
_cancelButton->SetCommand("Cancel");
_applyButton = new Button(this, "ApplyButton", "#PropertyDialog_Apply");
_applyButton->AddActionSignalTarget(this);
_applyButton->SetTabPosition(4);
_applyButton->SetVisible(false); // default to not visible
_applyButton->SetEnabled(false); // default to not enabled
_applyButton->SetCommand("Apply");
SetSizeable(false);
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
PropertyDialog::~PropertyDialog()
{
}
//-----------------------------------------------------------------------------
// Purpose: Returns a pointer to the PropertySheet this dialog encapsulates
// Output : PropertySheet *
//-----------------------------------------------------------------------------
PropertySheet *PropertyDialog::GetPropertySheet()
{
return _propertySheet;
}
//-----------------------------------------------------------------------------
// Purpose: Gets a pointer to the currently active page.
// Output : Panel
//-----------------------------------------------------------------------------
Panel *PropertyDialog::GetActivePage()
{
return _propertySheet->GetActivePage();
}
//-----------------------------------------------------------------------------
// Purpose: Wrapped function
//-----------------------------------------------------------------------------
void PropertyDialog::AddPage(Panel *page, const char *title)
{
_propertySheet->AddPage(page, title);
}
//-----------------------------------------------------------------------------
// Purpose: reloads the data in all the property page
//-----------------------------------------------------------------------------
void PropertyDialog::ResetAllData()
{
_propertySheet->ResetAllData();
}
//-----------------------------------------------------------------------------
// Purpose: Applies any changes
//-----------------------------------------------------------------------------
void PropertyDialog::ApplyChanges()
{
OnCommand("Apply");
}
//-----------------------------------------------------------------------------
// Purpose: Sets up the sheet
//-----------------------------------------------------------------------------
void PropertyDialog::PerformLayout()
{
BaseClass::PerformLayout();
int x, y, wide, tall;
GetClientArea(x, y, wide, tall);
_propertySheet->SetBounds(x, y, wide, tall - 32);
// move the buttons to the bottom-right corner
int xpos = x + wide - 80;
int ypos = tall + y - 28;
if (_applyButton->IsVisible())
{
_applyButton->SetBounds(xpos, ypos, 72, 24);
xpos -= 80;
}
if (_cancelButton->IsVisible())
{
_cancelButton->SetBounds(xpos, ypos, 72, 24);
xpos -= 80;
}
_okButton->SetBounds(xpos, ypos, 72, 24);
_propertySheet->InvalidateLayout(); // tell the propertysheet to redraw!
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: Handles command text from the buttons
//-----------------------------------------------------------------------------
void PropertyDialog::OnCommand(const char *command)
{
if (!stricmp(command, "OK"))
{
if ( OnOK(false) )
{
OnCommand("Close");
}
_applyButton->SetEnabled(false);
}
else if (!stricmp(command, "Cancel"))
{
OnCancel();
Close();
}
else if (!stricmp(command, "Apply"))
{
OnOK(true);
_applyButton->SetEnabled(false);
InvalidateLayout();
}
else
{
BaseClass::OnCommand(command);
}
}
//-----------------------------------------------------------------------------
// Purpose: called when the Cancel button is pressed
//-----------------------------------------------------------------------------
void PropertyDialog::OnCancel()
{
// designed to be overridden
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : code -
//-----------------------------------------------------------------------------
void PropertyDialog::OnKeyCodeTyped(KeyCode code)
{
// this has been removed, since it conflicts with how we use the escape key in the game
// if (code == KEY_ESCAPE)
// {
// OnCommand("Cancel");
// }
// else
{
BaseClass::OnKeyCodeTyped(code);
}
}
//-----------------------------------------------------------------------------
// Purpose: Command handler
//-----------------------------------------------------------------------------
bool PropertyDialog::OnOK(bool applyOnly)
{
// the sheet should have the pages apply changes before we tell the world
_propertySheet->ApplyChanges();
// this should tell anybody who's watching us that we're done
PostActionSignal(new KeyValues("ApplyChanges"));
// default to closing
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Overrides build mode so it edits the sub panel
//-----------------------------------------------------------------------------
void PropertyDialog::ActivateBuildMode()
{
// no subpanel, no build mode
EditablePanel *panel = dynamic_cast<EditablePanel *>(GetActivePage());
if (!panel)
return;
panel->ActivateBuildMode();
}
//-----------------------------------------------------------------------------
// Purpose: sets the text on the OK/Cancel buttons, overriding the default
//-----------------------------------------------------------------------------
void PropertyDialog::SetOKButtonText(const char *text)
{
_okButton->SetText(text);
}
//-----------------------------------------------------------------------------
// Purpose: sets the text on the OK/Cancel buttons, overriding the default
//-----------------------------------------------------------------------------
void PropertyDialog::SetCancelButtonText(const char *text)
{
_cancelButton->SetText(text);
}
//-----------------------------------------------------------------------------
// Purpose: sets the text on the apply buttons, overriding the default
//-----------------------------------------------------------------------------
void PropertyDialog::SetApplyButtonText(const char *text)
{
_applyButton->SetText(text);
}
//-----------------------------------------------------------------------------
// Purpose: changes the visibility of the buttons
//-----------------------------------------------------------------------------
void PropertyDialog::SetOKButtonVisible(bool state)
{
_okButton->SetVisible(state);
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: changes the visibility of the buttons
//-----------------------------------------------------------------------------
void PropertyDialog::SetCancelButtonVisible(bool state)
{
_cancelButton->SetVisible(state);
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: changes the visibility of the buttons
//-----------------------------------------------------------------------------
void PropertyDialog::SetApplyButtonVisible(bool state)
{
_applyButton->SetVisible(state);
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: when a sheet changes, enable the apply button
//-----------------------------------------------------------------------------
void PropertyDialog::OnApplyButtonEnable()
{
if (_applyButton->IsEnabled())
return;
EnableApplyButton(true);
}
//-----------------------------------------------------------------------------
// Purpose: enable/disable the apply button
//-----------------------------------------------------------------------------
void PropertyDialog::EnableApplyButton(bool bEnable)
{
_applyButton->SetEnabled(bEnable);
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void PropertyDialog::RequestFocus(int direction)
{
_propertySheet->RequestFocus(direction);
}

View File

@ -0,0 +1,114 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "vgui/IScheme.h"
#include "vgui/KeyCode.h"
#include "vgui/ISurface.h"
#include "KeyValues.h"
#include "vgui_controls/PropertyPage.h"
#include "vgui_controls/Controls.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
PropertyPage::PropertyPage(Panel *parent, const char *panelName) : EditablePanel(parent, panelName)
{
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
PropertyPage::~PropertyPage()
{
}
//-----------------------------------------------------------------------------
// Purpose: Called when page is loaded. Data should be reloaded from document into controls.
//-----------------------------------------------------------------------------
void PropertyPage::OnResetData()
{
}
//-----------------------------------------------------------------------------
// Purpose: Called when the OK / Apply button is pressed. Changed data should be written into document.
//-----------------------------------------------------------------------------
void PropertyPage::OnApplyChanges()
{
}
//-----------------------------------------------------------------------------
// Purpose: Designed to be overriden
//-----------------------------------------------------------------------------
void PropertyPage::OnPageShow()
{
}
//-----------------------------------------------------------------------------
// Purpose: Designed to be overriden
//-----------------------------------------------------------------------------
void PropertyPage::OnPageHide()
{
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pageTab -
//-----------------------------------------------------------------------------
void PropertyPage::OnPageTabActivated(Panel *pageTab)
{
_pageTab = pageTab;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void PropertyPage::OnKeyCodeTyped(KeyCode code)
{
switch (code)
{
// left and right only get propogated to parents if our tab has focus
case KEY_RIGHT:
{
if (_pageTab != NULL && _pageTab->HasFocus())
BaseClass::OnKeyCodeTyped(code);
break;
}
case KEY_LEFT:
{
if (_pageTab != NULL && _pageTab->HasFocus())
BaseClass::OnKeyCodeTyped(code);
break;
}
default:
BaseClass::OnKeyCodeTyped(code);
break;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void PropertyPage::SetVisible(bool state)
{
if (IsVisible() && !state)
{
// if we're going away and we have a current button, get rid of it
if (GetFocusNavGroup().GetCurrentDefaultButton())
{
GetFocusNavGroup().SetCurrentDefaultButton(NULL);
}
}
BaseClass::SetVisible(state);
}

File diff suppressed because it is too large Load Diff

210
vgui2/controls/QueryBox.cpp Normal file
View File

@ -0,0 +1,210 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
// This class is a message box that has two buttons, ok and cancel instead of
// just the ok button of a message box. We use a message box class for the ok button
// and implement another button here.
//
// $NoKeywords: $
//=============================================================================//
#include <vgui/KeyCode.h>
#include <vgui_controls/QueryBox.h>
#include <vgui_controls/TextImage.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
QueryBox::QueryBox(const char *title, const char *queryText, vgui::Panel *parent) : MessageBox(title, queryText,parent)
{
SetDeleteSelfOnClose(true);
m_pCancelButton = new Button(this, "CancelButton", "#QueryBox_Cancel");
m_pCancelButton->SetCommand("Cancel");
m_pOkButton->SetCommand("OK");
m_pCancelCommand = NULL;
m_pOkCommand = NULL;
m_pOkButton->SetTabPosition(1);
m_pCancelButton->SetTabPosition(2);
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
QueryBox::QueryBox(const wchar_t *wszTitle, const wchar_t *wszQueryText,vgui::Panel *parent) : MessageBox(wszTitle, wszQueryText,parent)
{
SetDeleteSelfOnClose(true);
m_pCancelButton = new Button(this, "CancelButton", "#QueryBox_Cancel");
m_pCancelButton->SetCommand("Cancel");
m_pOkButton->SetCommand("OK");
m_pCancelCommand = NULL;
m_pOkCommand = NULL;
m_pOkButton->SetTabPosition(1);
m_pCancelButton->SetTabPosition(2);
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
QueryBox::~QueryBox()
{
delete m_pCancelButton;
if ( m_pOkCommand )
{
m_pOkCommand->deleteThis();
}
if ( m_pCancelCommand )
{
m_pCancelCommand->deleteThis();
}
}
//-----------------------------------------------------------------------------
// Purpose: Layout the window for drawing
//-----------------------------------------------------------------------------
void QueryBox::PerformLayout()
{
BaseClass::PerformLayout();
int boxWidth, boxTall;
GetSize(boxWidth, boxTall);
int x, y, wide, tall;
GetClientArea(x, y, wide, tall);
wide += x;
tall += y;
int oldWide, oldTall;
m_pCancelButton->GetSize(oldWide, oldTall);
int btnWide, btnTall;
m_pCancelButton->GetContentSize(btnWide, btnTall);
btnWide = max(oldWide, btnWide + 10);
btnTall = max(oldTall, btnTall + 10);
m_pCancelButton->SetSize(btnWide, btnTall);
//nt boxWidth, boxTall;
GetSize(boxWidth, boxTall);
// wide = max(wide, btnWide * 2 + 100);
// SetSize(wide, tall);
m_pOkButton->SetPos((wide/2)-(m_pOkButton->GetWide())-1 + x, tall - m_pOkButton->GetTall() - 15);
m_pCancelButton->SetPos((wide/2) + x+16, tall - m_pCancelButton->GetTall() - 15);
}
//-----------------------------------------------------------------------------
// Purpose: Handles command text from the buttons
// Deletes self when closed
//-----------------------------------------------------------------------------
void QueryBox::OnCommand(const char *command)
{
if (!stricmp(command, "OK"))
{
OnCommand("Close");
if ( m_pOkCommand )
{
PostActionSignal(m_pOkCommand->MakeCopy());
}
}
else if (!stricmp(command, "Cancel"))
{
OnCommand("Close");
if (m_pCancelCommand)
{
PostActionSignal(m_pCancelCommand->MakeCopy());
}
}
BaseClass::OnCommand(command);
}
//-----------------------------------------------------------------------------
// Purpose: Set the keyvalues to send when ok button is hit
//-----------------------------------------------------------------------------
void QueryBox::SetOKCommand(KeyValues *keyValues)
{
if ( m_pOkCommand )
{
m_pOkCommand->deleteThis();
}
m_pOkCommand = keyValues;
}
//-----------------------------------------------------------------------------
// Purpose: Set a value of the ok command
//-----------------------------------------------------------------------------
void QueryBox::SetOKCommandValue(const char *keyName, int value)
{
if ( !m_pOkCommand )
{
m_pOkCommand = new KeyValues("Command");
}
m_pOkCommand->SetInt(keyName, value);
}
//-----------------------------------------------------------------------------
// Purpose: Set the keyvalues to send when the cancel button is hit
//-----------------------------------------------------------------------------
void QueryBox::SetCancelCommand(KeyValues *keyValues)
{
if ( m_pCancelCommand )
{
m_pCancelCommand->deleteThis();
}
m_pCancelCommand = keyValues;
}
//-----------------------------------------------------------------------------
// Purpose: Sets the cancel button text
//-----------------------------------------------------------------------------
void QueryBox::SetCancelButtonText(const char* buttonText)
{
m_pCancelButton->SetText(buttonText);
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: Sets the cancel button text
//-----------------------------------------------------------------------------
void QueryBox::SetCancelButtonText(const wchar_t* wszButtonText)
{
m_pCancelButton->SetText(wszButtonText);
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void QueryBox::OnKeyCodeTyped(KeyCode code)
{
if (code == KEY_ESCAPE)
{
OnCommand("Cancel");
}
else
{
Frame::OnKeyCodeTyped(code);
}
}

View File

@ -0,0 +1,422 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <stdarg.h>
#include <stdio.h>
#include <vgui/IInput.h>
#include <vgui/IPanel.h>
#include <vgui/IScheme.h>
#include <vgui/ISystem.h>
#include <vgui/IVGui.h>
#include <vgui/KeyCode.h>
#include <KeyValues.h>
#include <vgui_controls/FocusNavGroup.h>
#include <vgui_controls/Image.h>
#include <vgui_controls/RadioButton.h>
#include <vgui_controls/TextImage.h>
#include <vgui_controls/Controls.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
enum direction
{
UP = -1,
DOWN = 1,
};
//-----------------------------------------------------------------------------
// Purpose: Check box image
//-----------------------------------------------------------------------------
class RadioImage : public Image
{
public:
RadioImage(RadioButton *radioButton)
{
_radioButton = radioButton;
_font = INVALID_FONT;
SetSize(20, 13);
}
virtual void ApplySchemeSettings(IScheme *pScheme, bool proportional)
{
_bgColor = _radioButton->GetSchemeColor("CheckButton.BgColor", Color(150, 150, 150, 0), pScheme);
_borderColor1 = _radioButton->GetSchemeColor("CheckButton.Border1", Color(20, 20, 20, 0), pScheme);
_borderColor2 = _radioButton->GetSchemeColor("CheckButton.Border2", Color(90, 90, 90, 0), pScheme);
_checkColor = _radioButton->GetSchemeColor("CheckButton.Check", Color(20, 20, 20, 0), pScheme);
_font = pScheme->GetFont("Marlett", proportional);
}
virtual void Paint()
{
DrawSetTextFont(_font);
// draw background
if (_radioButton->IsEnabled())
{
DrawSetTextColor(_bgColor);
}
else
{
DrawSetTextColor(_radioButton->GetBgColor());
}
DrawPrintChar(0, 1, 'n');
// draw border circl
DrawSetTextColor(_borderColor1);
DrawPrintChar(0, 1, 'j');
DrawSetTextColor(_borderColor2);
DrawPrintChar(0, 1, 'k');
// draw selected check
if (_radioButton->IsSelected())
{
DrawSetTextColor(_checkColor);
DrawPrintChar(0, 1, 'h');
}
}
private:
RadioButton *_radioButton;
Color _borderColor1;
Color _borderColor2;
Color _checkColor;
Color _bgColor;
HFont _font;
};
DECLARE_BUILD_FACTORY_DEFAULT_TEXT( RadioButton, RadioButton );
//-----------------------------------------------------------------------------
// Purpose: Create a radio button.
//-----------------------------------------------------------------------------
RadioButton::RadioButton(Panel *parent, const char *panelName, const char *text) : ToggleButton(parent, panelName, text)
{
SetContentAlignment(a_west);
// create the image
_radioBoxImage = new RadioImage(this);
_oldTabPosition = 0;
_subTabPosition = 0;
SetTextImageIndex(1);
SetImageAtIndex(0, _radioBoxImage, 0);
SetButtonActivationType(ACTIVATE_ONPRESSED);
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
RadioButton::~RadioButton()
{
delete _radioBoxImage;
}
//-----------------------------------------------------------------------------
// Purpose: Apply resource file scheme.
//-----------------------------------------------------------------------------
void RadioButton::ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
_radioBoxImage->ApplySchemeSettings(pScheme, IsProportional());
SetFgColor(GetSchemeColor("RadioButton.TextColor", pScheme));
_selectedFgColor = GetSchemeColor("RadioButton.SelectedTextColor", GetSchemeColor("ControlText", pScheme), pScheme);
SetContentAlignment(a_west);
// reloading the scheme wipes out lists of images
SetImageAtIndex(0, _radioBoxImage, 0);
// don't draw a background
SetPaintBackgroundEnabled(false);
}
//-----------------------------------------------------------------------------
// Purpose: Get the border style of the button, Radio buttons have no border
//-----------------------------------------------------------------------------
IBorder *RadioButton::GetBorder(bool depressed, bool armed, bool selected, bool keyfocus)
{
return NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Get the tab position of the radio button with the set of radio buttons
// A group of RadioButtons must have the same TabPosition, with [1, n] subtabpositions
//-----------------------------------------------------------------------------
int RadioButton::GetSubTabPosition()
{
return _subTabPosition;
}
//-----------------------------------------------------------------------------
// Purpose: Get the tab position of the radio button with the set of radio buttons
// A group of RadioButtons must have the same TabPosition, with [1, n] subtabpositions
//-----------------------------------------------------------------------------
void RadioButton::SetSubTabPosition(int position)
{
_subTabPosition = position;
}
//-----------------------------------------------------------------------------
// Purpose: Return the RadioButton's real tab position (its Panel one changes)
//-----------------------------------------------------------------------------
int RadioButton::GetRadioTabPosition()
{
return _oldTabPosition;
}
//-----------------------------------------------------------------------------
// Purpose: Set the radio button checked. When a radio button is checked, a
// message is sent to all other radio buttons in the same group so
// they will become unchecked.
//-----------------------------------------------------------------------------
void RadioButton::SetSelected(bool state)
{
if (state == true)
{
if (!IsEnabled())
return;
// restore our tab position
SetTabPosition(_oldTabPosition);
// send a message saying we've signed on
KeyValues *msg = new KeyValues("RadioButtonChecked");
msg->SetPtr("panel", this);
msg->SetInt("tabposition", _oldTabPosition);
// send a message to all other panels on the same level as heirarchy,
// so that other radio buttons know to shut off
VPANEL radioParent = GetVParent();
if (radioParent)
{
for (int i = 0; i < ipanel()->GetChildCount(radioParent); i++)
{
VPANEL child = ipanel()->GetChild(radioParent, i);
if (child != GetVPanel())
{
ivgui()->PostMessage(child, msg->MakeCopy(), GetVPanel());
}
}
}
RequestFocus();
PostActionSignal(msg);
}
else
{
// remove ourselves from the tab order
if (GetTabPosition())
{
_oldTabPosition = GetTabPosition();
}
SetTabPosition(0);
}
InvalidateLayout();
Repaint();
ToggleButton::SetSelected(state);
}
//-----------------------------------------------------------------------------
// Purpose: Set up the text color before doing normal layout
//-----------------------------------------------------------------------------
void RadioButton::PerformLayout()
{
if (IsSelected())
{
SetFgColor(_selectedFgColor);
}
else
{
SetFgColor(GetButtonFgColor());
}
BaseClass::PerformLayout();
}
//-----------------------------------------------------------------------------
// Purpose: Apply resouce settings including button state and text color.
//-----------------------------------------------------------------------------
void RadioButton::ApplySettings(KeyValues *inResourceData)
{
ToggleButton::ApplySettings(inResourceData);
SetTextColorState(CS_NORMAL);
_subTabPosition = inResourceData->GetInt("SubTabPosition");
_oldTabPosition = GetTabPosition();
SetImageAtIndex(0, _radioBoxImage, 0);
}
//-----------------------------------------------------------------------------
// Purpose: Get resouce settings including button state, text color, and subTabPosition
//-----------------------------------------------------------------------------
void RadioButton::GetSettings(KeyValues *outResourceData)
{
ToggleButton::GetSettings(outResourceData);
outResourceData->SetInt("SubTabPosition", _subTabPosition);
outResourceData->SetInt("TabPosition", GetRadioTabPosition());
}
//-----------------------------------------------------------------------------
// Purpose: Describe editing details
//-----------------------------------------------------------------------------
const char *RadioButton::GetDescription( void )
{
static char buf[1024];
Q_snprintf(buf, sizeof(buf), "%s, int SubTabPosition", BaseClass::GetDescription());
return buf;
}
//-----------------------------------------------------------------------------
// Purpose: When a radio button is checked, all other radio buttons
// in the same group become unchecked.
//-----------------------------------------------------------------------------
void RadioButton::OnRadioButtonChecked(int tabPosition)
{
// make sure we're in the same tab group
if (tabPosition != _oldTabPosition)
return;
// wouldn't be sent to us from ourselves, so another radio button has taken over
SetSelected(false);
}
//-----------------------------------------------------------------------------
// Purpose: Draws the selection rectangle
//-----------------------------------------------------------------------------
void RadioButton::Paint()
{
BaseClass::Paint();
/*
if (HasFocus())
{
int tx0, ty0, tx1, ty1;
_textImage->GetPos(tx0, ty0);
_textImage->GetSize(tx1, ty1);
DrawFocusBorder(tx0, ty0, tx0 + tx1, ty0 + ty1);
}
*/
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void RadioButton::DoClick()
{
SetSelected(true);
}
//-----------------------------------------------------------------------------
// Purpose: Handle arrow key movement
//-----------------------------------------------------------------------------
void RadioButton::OnKeyCodeTyped(KeyCode code)
{
switch (code)
{
case KEY_ENTER:
case KEY_SPACE:
{
if (!IsSelected())
{
SetSelected(true);
}
else
{
Panel::OnKeyCodeTyped(code);
}
}
break;
case KEY_DOWN:
case KEY_RIGHT:
{
RadioButton *bestRadio = FindBestRadioButton( DOWN );
if (bestRadio)
{
bestRadio->SetSelected(true);
}
}
break;
case KEY_UP:
case KEY_LEFT:
{
RadioButton *bestRadio = FindBestRadioButton( UP );
if (bestRadio)
{
bestRadio->SetSelected(true);
}
}
break;
default:
BaseClass::OnKeyCodeTyped(code);
break;
}
}
//-----------------------------------------------------------------------------
// Purpose: Find the correct radio button to move to.
// Input : direction - the direction we are moving, up or down.
//-----------------------------------------------------------------------------
RadioButton *RadioButton::FindBestRadioButton(int direction)
{
RadioButton *bestRadio = NULL;
int highestRadio = 0;
Panel *pr = GetParent();
if (pr)
{
// find the radio button to go to next
for (int i = 0; i < pr->GetChildCount(); i++)
{
RadioButton *child = dynamic_cast<RadioButton *>(pr->GetChild(i));
if (child && child->GetRadioTabPosition() == _oldTabPosition)
{
if (child->GetSubTabPosition() == _subTabPosition + direction)
{
bestRadio = child;
break;
}
if ( (child->GetSubTabPosition() == 0) && (direction == DOWN) )
{
bestRadio = child;
continue;
}
else if ( (child->GetSubTabPosition() > highestRadio) && (direction == UP) )
{
bestRadio = child;
highestRadio = bestRadio->GetSubTabPosition();
continue;
}
if (!bestRadio)
{
bestRadio = child;
}
}
}
if (bestRadio)
{
bestRadio->RequestFocus();
}
InvalidateLayout();
Repaint();
}
return bestRadio;
}

2348
vgui2/controls/RichText.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,516 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <assert.h>
#include <vgui/IScheme.h>
#include <vgui/ISystem.h>
#include <vgui/IInput.h>
#include <KeyValues.h>
#include <vgui_controls/ScrollBar.h>
#include <vgui_controls/ScrollBarSlider.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/Controls.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
namespace
{
enum
{ // scroll bar will scroll a little, then continuous scroll like in windows
SCROLL_BAR_DELAY = 400, // default delay for all scroll bars
SCROLL_BAR_SPEED = 50, // this is how fast the bar scrolls when you hold down the arrow button
SCROLLBAR_DEFAULT_WIDTH = 17,
};
//-----------------------------------------------------------------------------
// Purpose: Scroll bar button-the arrow button that moves the slider up and down.
//-----------------------------------------------------------------------------
class ScrollBarButton : public Button
{
public:
ScrollBarButton(Panel *parent, const char *panelName, const char *text) : Button(parent, panelName, text)
{
SetButtonActivationType(ACTIVATE_ONPRESSED);
SetContentAlignment(Label::a_center);
}
void OnMouseFocusTicked()
{
// pass straight up to parent
CallParentFunction(new KeyValues("MouseFocusTicked"));
}
virtual void ApplySchemeSettings(IScheme *pScheme)
{
Button::ApplySchemeSettings(pScheme);
SetFont(pScheme->GetFont("Marlett", IsProportional() ));
SetDefaultBorder(pScheme->GetBorder("ScrollBarButtonBorder"));
SetDepressedBorder(pScheme->GetBorder("ScrollBarButtonDepressedBorder"));
SetDefaultColor(GetSchemeColor("ScrollBarButton.FgColor", pScheme), GetSchemeColor("ScrollBarButton.BgColor", pScheme));
SetArmedColor(GetSchemeColor("ScrollBarButton.ArmedFgColor", pScheme), GetSchemeColor("ScrollBarButton.ArmedBgColor", pScheme));
SetDepressedColor(GetSchemeColor("ScrollBarButton.DepressedFgColor", pScheme), GetSchemeColor("ScrollBarButton.DepressedBgColor", pScheme));
}
// Don't request focus.
// This will keep cursor focus in main window in text entry windows.
virtual void OnMousePressed(MouseCode code)
{
if (!IsEnabled())
return;
if (!IsMouseClickEnabled(code))
return;
if (IsUseCaptureMouseEnabled())
{
{
SetSelected(true);
Repaint();
}
// lock mouse input to going to this button
input()->SetMouseCapture(GetVPanel());
}
}
virtual void OnMouseReleased(MouseCode code)
{
if (!IsEnabled())
return;
if (!IsMouseClickEnabled(code))
return;
if (IsUseCaptureMouseEnabled())
{
{
SetSelected(false);
Repaint();
}
// lock mouse input to going to this button
input()->SetMouseCapture(NULL);
}
}
};
}
vgui::Panel *ScrollBar_Vertical_Factory()
{
return new ScrollBar(NULL, NULL, true );
}
vgui::Panel *ScrollBar_Horizontal_Factory()
{
return new ScrollBar(NULL, NULL, false );
}
DECLARE_BUILD_FACTORY_CUSTOM_ALIAS( ScrollBar, ScrollBar_Vertical, ScrollBar_Vertical_Factory );
DECLARE_BUILD_FACTORY_CUSTOM_ALIAS( ScrollBar, ScrollBar_Horizontal, ScrollBar_Horizontal_Factory );
// Default is a horizontal one
DECLARE_BUILD_FACTORY_CUSTOM( ScrollBar, ScrollBar_Horizontal_Factory );
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
ScrollBar::ScrollBar(Panel *parent, const char *panelName, bool vertical) : Panel(parent, panelName)
{
_slider=null;
_button[0]=null;
_button[1]=null;
_scrollDelay = SCROLL_BAR_DELAY;
_respond = true;
if (vertical)
{
// FIXME: proportional changes needed???
SetSlider(new ScrollBarSlider(NULL, NULL, true));
SetButton(new ScrollBarButton(NULL, NULL, "t"), 0);
SetButton(new ScrollBarButton(NULL, NULL, "u"), 1);
_button[0]->SetTextInset(0, 1);
_button[1]->SetTextInset(0, -1);
SetSize(SCROLLBAR_DEFAULT_WIDTH, 64);
}
else
{
SetSlider(new ScrollBarSlider(NULL, NULL, false));
SetButton(new ScrollBarButton(NULL, NULL, "w"), 0);
SetButton(new ScrollBarButton(NULL, NULL, "4"), 1);
_button[0]->SetTextInset(0, 0);
_button[1]->SetTextInset(0, 0);
SetSize(64, SCROLLBAR_DEFAULT_WIDTH);
}
Panel::SetPaintBorderEnabled(true);
Panel::SetPaintBackgroundEnabled(false);
Panel::SetPaintEnabled(true);
SetButtonPressedScrollValue(20);
SetBlockDragChaining( true );
Validate();
}
//-----------------------------------------------------------------------------
// Purpose: sets up the width of the scrollbar according to the scheme
//-----------------------------------------------------------------------------
void ScrollBar::ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
const char *resourceString = pScheme->GetResourceString("ScrollBar.Wide");
if (resourceString)
{
int value = atoi(resourceString);
if (IsProportional())
{
value = scheme()->GetProportionalScaledValueEx(GetScheme(), value);
}
if (_slider && _slider->IsVertical())
{
// we're vertical, so reset the width
SetSize( value, GetTall() );
}
else
{
// we're horizontal, so the width means the height
SetSize( GetWide(), value );
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Set the slider's Paint border enabled.
//-----------------------------------------------------------------------------
void ScrollBar::SetPaintBorderEnabled(bool state)
{
if ( _slider )
{
_slider->SetPaintBorderEnabled( state );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ScrollBar::SetPaintBackgroundEnabled(bool state)
{
if ( _slider )
{
_slider->SetPaintBackgroundEnabled( state );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ScrollBar::SetPaintEnabled(bool state)
{
if ( _slider )
{
_slider->SetPaintEnabled( state );
}
}
//-----------------------------------------------------------------------------
// Purpose: Layout the scroll bar and buttons on screen
//-----------------------------------------------------------------------------
void ScrollBar::PerformLayout()
{
if (_slider)
{
int wide, tall;
GetPaintSize(wide,tall);
if(_slider->IsVertical())
{
_slider->SetBounds(0, wide, wide, tall-(wide*2)+1);
_button[0]->SetBounds(0,0, wide-1, wide );
_button[1]->SetBounds(0,tall-wide ,wide-1, wide );
}
else
{
_slider->SetBounds(tall, -1, wide-(tall*2)+1, tall + 1 );
_button[0]->SetBounds(0, 0, tall, tall);
_button[1]->SetBounds(wide-tall, 0, tall, tall);
}
// after resizing our child, we should remind it to perform a layout
_slider->InvalidateLayout();
}
// get tooltips to draw
Panel::PerformLayout();
}
//-----------------------------------------------------------------------------
// Purpose: Set the value of the scroll bar slider.
//-----------------------------------------------------------------------------
void ScrollBar::SetValue(int value)
{
_slider->SetValue(value);
}
//-----------------------------------------------------------------------------
// Purpose: Get the value of the scroll bar slider.
//-----------------------------------------------------------------------------
int ScrollBar::GetValue()
{
return _slider->GetValue();
}
//-----------------------------------------------------------------------------
// Purpose: Set the range of the scroll bar slider.
// This the range of numbers the slider can scroll through.
//-----------------------------------------------------------------------------
void ScrollBar::SetRange(int min,int max)
{
_slider->SetRange(min,max);
}
//-----------------------------------------------------------------------------
// Purpose: Gets the range of the scroll bar slider.
// This the range of numbers the slider can scroll through.
//-----------------------------------------------------------------------------
void ScrollBar::GetRange(int &min, int &max)
{
_slider->GetRange(min, max);
}
//-----------------------------------------------------------------------------
// Purpose: Send a message when the slider is moved.
// Input : value -
//-----------------------------------------------------------------------------
void ScrollBar::SendSliderMoveMessage(int value)
{
PostActionSignal(new KeyValues("ScrollBarSliderMoved", "position", value));
}
//-----------------------------------------------------------------------------
// Purpose: Called when the Slider is dragged by the user
// Input : value -
//-----------------------------------------------------------------------------
void ScrollBar::OnSliderMoved(int value)
{
SendSliderMoveMessage(value);
}
//-----------------------------------------------------------------------------
// Purpose: Check if the scrollbar is vertical (true) or horizontal (false)
//-----------------------------------------------------------------------------
bool ScrollBar::IsVertical()
{
return _slider->IsVertical();
}
//-----------------------------------------------------------------------------
// Purpose: Check if the the scrollbar slider has full range.
// Normally if you have a scroll bar and the range goes from a to b and
// the slider is sized to c, the range will go from a to b-c.
// This makes it so the slider goes from a to b fully.
//-----------------------------------------------------------------------------
bool ScrollBar::HasFullRange()
{
return _slider->HasFullRange();
}
//-----------------------------------------------------------------------------
// Purpose: Setup the indexed scroll bar button with the input params.
//-----------------------------------------------------------------------------
//LEAK: new and old slider will leak
void ScrollBar::SetButton(Button *button, int index)
{
if(_button[index]!=null)
{
_button[index]->SetParent((Panel *)NULL);
}
_button[index]=button;
_button[index]->SetParent(this);
_button[index]->AddActionSignalTarget(this);
_button[index]->SetCommand(new KeyValues("ScrollButtonPressed", "index", index));
Validate();
}
//-----------------------------------------------------------------------------
// Purpose: Return the indexed scroll bar button
//-----------------------------------------------------------------------------
Button* ScrollBar::GetButton(int index)
{
return _button[index];
}
//-----------------------------------------------------------------------------
// Purpose: Set up the slider.
//-----------------------------------------------------------------------------
//LEAK: new and old slider will leak
void ScrollBar::SetSlider(ScrollBarSlider *slider)
{
if(_slider!=null)
{
_slider->SetParent((Panel *)NULL);
}
_slider=slider;
_slider->AddActionSignalTarget(this);
_slider->SetParent(this);
Validate();
}
//-----------------------------------------------------------------------------
// Purpose: Return a pointer to the slider.
//-----------------------------------------------------------------------------
ScrollBarSlider *ScrollBar::GetSlider()
{
return _slider;
}
//-----------------------------------------------------------------------------
// Purpose: Scrolls in response to clicking and holding on up or down arrow
// The idea is to have the slider move one step then delay a bit and then
// the bar starts moving at normal speed. This gives a stepping feeling
// to just clicking an arrow once.
//-----------------------------------------------------------------------------
void ScrollBar::OnMouseFocusTicked()
{
int direction = 0;
// top button is down
if ( _button[0]->IsDepressed() )
{
direction = -1;
}
// bottom top button is down
else if (_button[1]->IsDepressed())
{
direction = 1;
}
// a button is down
if ( direction != 0 )
{
RespondToScrollArrow(direction);
if (_scrollDelay < system()->GetTimeMillis())
{
_scrollDelay = system()->GetTimeMillis() + SCROLL_BAR_SPEED;
_respond = true;
}
else
{
_respond = false;
}
}
// a button is not down.
else
{
// if neither button is down keep delay at max
_scrollDelay = system()->GetTimeMillis() + SCROLL_BAR_DELAY;
_respond = true;
}
}
//-----------------------------------------------------------------------------
// Purpose: move scroll bar in response to the first button
// Input: button and direction to move scroll bar when that button is pressed
// direction can only by +/- 1
// Output: whether button is down or not
//-----------------------------------------------------------------------------
void ScrollBar::RespondToScrollArrow(int const direction)
{
if (_respond)
{
int newValue = _slider->GetValue() + (direction * _buttonPressedScrollValue);
_slider->SetValue(newValue);
SendSliderMoveMessage(newValue);
}
}
//-----------------------------------------------------------------------------
// Purpose: Trigger layout changes when the window size is changed.
//-----------------------------------------------------------------------------
void ScrollBar::OnSizeChanged(int wide, int tall)
{
InvalidateLayout();
_slider->InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: Set how far the scroll bar slider moves when a scroll bar button is
// pressed.
//-----------------------------------------------------------------------------
void ScrollBar::SetButtonPressedScrollValue(int value)
{
_buttonPressedScrollValue=value;
}
//-----------------------------------------------------------------------------
// Purpose: Set the range of the rangewindow. This is how many
// lines are displayed at one time
// in the window the scroll bar is attached to.
// This also controls the size of the slider, its size is proportional
// to the number of lines displayed / total number of lines.
//-----------------------------------------------------------------------------
void ScrollBar::SetRangeWindow(int rangeWindow)
{
_slider->SetRangeWindow(rangeWindow);
}
//-----------------------------------------------------------------------------
// Purpose: Get the range of the rangewindow. This is how many
// lines are displayed at one time
// in the window the scroll bar is attached to.
// This also controls the size of the slider, its size is proportional
// to the number of lines displayed / total number of lines.
//-----------------------------------------------------------------------------
int ScrollBar::GetRangeWindow()
{
return _slider->GetRangeWindow();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ScrollBar::Validate()
{
if ( _slider != null )
{
int buttonOffset = 0;
for( int i=0; i<2; i++ )
{
if( _button[i] != null )
{
if( _button[i]->IsVisible() )
{
if( _slider->IsVertical() )
{
buttonOffset += _button[i]->GetTall();
}
else
{
buttonOffset += _button[i]->GetWide();
}
}
}
}
_slider->SetButtonOffset(buttonOffset);
}
}

View File

@ -0,0 +1,549 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#define PROTECTED_THINGS_DISABLE
#include <vgui/IBorder.h>
#include <vgui/IInput.h>
#include <vgui/ISystem.h>
#include <vgui/IScheme.h>
#include <vgui/ISurface.h>
#include <vgui/MouseCode.h>
#include <KeyValues.h>
#include <vgui_controls/ScrollBarSlider.h>
#include <vgui_controls/Controls.h>
#include <math.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// The ScrollBarSlider is the scroll bar nob that moves up and down in through a range.
//-----------------------------------------------------------------------------
ScrollBarSlider::ScrollBarSlider(Panel *parent, const char *panelName, bool vertical) : Panel(parent, panelName)
{
_vertical=vertical;
_dragging=false;
_value=0;
_range[0]=0;
_range[1]=0;
_rangeWindow=0;
_buttonOffset=0;
_ScrollBarSliderBorder=NULL;
RecomputeNobPosFromValue();
SetBlockDragChaining( true );
}
//-----------------------------------------------------------------------------
// Purpose: Set the size of the ScrollBarSlider nob
//-----------------------------------------------------------------------------
void ScrollBarSlider::SetSize(int wide,int tall)
{
BaseClass::SetSize(wide,tall);
RecomputeNobPosFromValue();
}
//-----------------------------------------------------------------------------
// Purpose: Whether the scroll bar is vertical (true) or not (false)
//-----------------------------------------------------------------------------
bool ScrollBarSlider::IsVertical()
{
return _vertical;
}
//-----------------------------------------------------------------------------
// Purpose: Set the ScrollBarSlider value of the nob.
//-----------------------------------------------------------------------------
void ScrollBarSlider::SetValue(int value)
{
int oldValue = _value;
if (value > _range[1] - _rangeWindow)
{
// note our scrolling range must take into acount _rangeWindow
value = _range[1] - _rangeWindow;
}
if (value < _range[0])
{
value = _range[0];
}
_value = value;
RecomputeNobPosFromValue();
if (_value != oldValue)
{
SendScrollBarSliderMovedMessage();
}
}
//-----------------------------------------------------------------------------
// Purpose: Get the ScrollBarSlider value of the nob.
//-----------------------------------------------------------------------------
int ScrollBarSlider::GetValue()
{
return _value;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ScrollBarSlider::PerformLayout()
{
RecomputeNobPosFromValue();
BaseClass::PerformLayout();
}
//-----------------------------------------------------------------------------
// Purpose: Given the value of the ScrollBarSlider, adjust the ends of the nob.
//-----------------------------------------------------------------------------
void ScrollBarSlider::RecomputeNobPosFromValue()
{
int wide, tall;
GetPaintSize(wide, tall);
float fwide = (float)( wide - 1 );
float ftall = (float)( tall - 1 );
float frange = (float)(_range[1] -_range[0]);
float fvalue = (float)(_value - _range[0]);
float frangewindow = (float)(_rangeWindow);
float fper = ( frange != frangewindow ) ? fvalue / ( frange-frangewindow ) : 0;
if ( frangewindow > 0 )
{
if ( frange <= 0.0 )
{
frange = 1.0;
}
float width, length;
if (_vertical)
{
width = fwide;
length = ftall;
}
else
{
width = ftall;
length = fwide;
}
// our size is proportional to frangewindow/frange
// the scroll bar nob's length reflects the amount of stuff on the screen
// vs the total amount of stuff we could scroll through in window
// so if a window showed half its contents and the other half is hidden the
// scroll bar's length is half the window.
// if everything is on the screen no nob is displayed
// frange is how many 'lines' of stuff we can display
// frangewindow is how many 'lines' are in the display window
// proportion of whole window that is on screen
float proportion = frangewindow / frange;
float fnobsize = length * proportion;
if ( fnobsize < width ) fnobsize = (float)width;
float freepixels = length - fnobsize;
float firstpixel = freepixels * fper;
_nobPos[0] = (int)( firstpixel );
_nobPos[1] = (int)( firstpixel + fnobsize );
if ( _nobPos[1] > length )
{
_nobPos[0] = (int)( length - fnobsize );
_nobPos[1] = (int)length;
}
}
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: Get the ScrollBarSlider value using the location of the nob ends.
//-----------------------------------------------------------------------------
void ScrollBarSlider::RecomputeValueFromNobPos()
{
int wide, tall;
GetPaintSize(wide, tall);
float fwide = (float)( wide - 1 );
float ftall = (float)( tall - 1 );
float frange = (float)( _range[1] - _range[0] );
float fvalue = (float)( _value - _range[0] );
float fnob = (float)_nobPos[0];
float frangewindow = (float)(_rangeWindow);
if ( frangewindow > 0 )
{
if ( frange <= 0.0 )
{
frange = 1.0;
}
// set local width and length
float width, length;
if ( _vertical )
{
width = fwide;
length = ftall;
}
else
{
width = ftall;
length = fwide;
}
// calculate the size of the nob
float proportion = frangewindow / frange;
float fnobsize = length * proportion;
if ( fnobsize < width )
{
fnobsize = width;
}
// Our scroll bar actually doesnt scroll through all frange lines in the truerange, we
// actually only scroll through frange-frangewindow number of lines so we must take that
// into account when we calculate the value
// convert to our local size system
fvalue = (frange - frangewindow) * ( fnob / ( length - fnobsize ) );
}
// check to see if we should just snap to the bottom
if (fabs(fvalue + _rangeWindow - _range[1]) < (0.01f * frange))
{
// snap to the end
_value = _range[1] - _rangeWindow;
}
else
{
// Take care of rounding issues.
_value = (int)( fvalue + _range[0] + 0.5);
}
// Clamp final result
_value = ( _value < (_range[1] - _rangeWindow) ) ? _value : (_range[1] - _rangeWindow);
}
//-----------------------------------------------------------------------------
// Purpose: Check if the ScrollBarSlider can move through one or more pixels per
// unit of its range.
//-----------------------------------------------------------------------------
bool ScrollBarSlider::HasFullRange()
{
int wide, tall;
GetPaintSize(wide, tall);
float frangewindow = (float)(_rangeWindow);
float checkAgainst = 0;
if(_vertical)
{
checkAgainst = (float)tall;
}
else
{
checkAgainst = (float)wide;
}
if ( frangewindow > 0 )
{
if( frangewindow <= ( checkAgainst + _buttonOffset ) )
{
return true;
}
}
return false;
}
//-----------------------------------------------------------------------------
// Purpose: Inform other watchers that the ScrollBarSlider was moved
//-----------------------------------------------------------------------------
void ScrollBarSlider::SendScrollBarSliderMovedMessage()
{
// send a changed message
PostActionSignal(new KeyValues("ScrollBarSliderMoved", "position", _value));
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ScrollBarSlider::ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
SetFgColor(GetSchemeColor("ScrollBarSlider.FgColor", pScheme));
SetBgColor(GetSchemeColor("ScrollBarSlider.BgColor", pScheme));
_ScrollBarSliderBorder = pScheme->GetBorder("ButtonBorder");
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ScrollBarSlider::Paint()
{
int wide,tall;
GetPaintSize(wide,tall);
int itemRange = _range[1] - _range[0];
// Don't draw nob, no items in list
if ( itemRange <= 0 )
return;
// Not enough range
if ( itemRange <= _rangeWindow )
return;
Color col = GetFgColor();
surface()->DrawSetColor(col);
if (_vertical)
{
// Nob
surface()->DrawFilledRect(0, _nobPos[0], wide - 1, _nobPos[1]);
// border
if (_ScrollBarSliderBorder)
{
_ScrollBarSliderBorder->Paint(0, _nobPos[0], wide - 1, _nobPos[1]);
}
}
else
{
// horizontal nob
surface()->DrawFilledRect(_nobPos[0], 0, _nobPos[1], tall );
// border
if (_ScrollBarSliderBorder)
{
_ScrollBarSliderBorder->Paint(_nobPos[0] - 1, 1, _nobPos[1], tall );
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ScrollBarSlider::PaintBackground()
{
// BaseClass::PaintBackground();
int wide,tall;
GetPaintSize(wide,tall);
surface()->DrawSetColor(GetBgColor());
surface()->DrawFilledRect(0, 0, wide-1, tall-1);
}
//-----------------------------------------------------------------------------
// Purpose: Set the range of the ScrollBarSlider
//-----------------------------------------------------------------------------
void ScrollBarSlider::SetRange(int min,int max)
{
if(max<min)
{
max=min;
}
if(min>max)
{
min=max;
}
_range[0]=min;
_range[1]=max;
// update the value (forces it within the range)
SetValue( _value );
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: Get the range values of the ScrollBarSlider
//-----------------------------------------------------------------------------
void ScrollBarSlider::GetRange(int& min,int& max)
{
min=_range[0];
max=_range[1];
}
//-----------------------------------------------------------------------------
// Purpose: Respond to cursor movements, we only care about clicking and dragging
//-----------------------------------------------------------------------------
void ScrollBarSlider::OnCursorMoved(int x,int y)
{
if (!_dragging)
{
return;
}
// input()->GetCursorPos(x, y);
// ScreenToLocal(x, y);
int wide, tall;
GetPaintSize(wide, tall);
tall;
if (_vertical)
{
_nobPos[0] = _nobDragStartPos[0] + (y - _dragStartPos[1]);
_nobPos[1] = _nobDragStartPos[1] + (y - _dragStartPos[1]);
if (_nobPos[1] > tall)
{
_nobPos[0] = tall - (_nobPos[1] - _nobPos[0]);
_nobPos[1] = tall;
SetValue( _range[1] - _rangeWindow );
}
}
else
{
_nobPos[0] = _nobDragStartPos[0] + (x - _dragStartPos[0]);
_nobPos[1] = _nobDragStartPos[1] + (x - _dragStartPos[0]);
if (_nobPos[1] > wide)
{
_nobPos[0] = wide - (_nobPos[1] - _nobPos[0]);
_nobPos[1] = wide;
}
}
if (_nobPos[0] < 0)
{
_nobPos[1] = _nobPos[1] - _nobPos[0];
_nobPos[0] = 0;
SetValue(0);
}
InvalidateLayout(); // not invalidatelayout - because it won't draw while we're scrolling the slider
RecomputeValueFromNobPos();
// Repaint();
SendScrollBarSliderMovedMessage();
}
//-----------------------------------------------------------------------------
// Purpose: Respond to mouse clicks on the ScrollBarSlider
//-----------------------------------------------------------------------------
void ScrollBarSlider::OnMousePressed(MouseCode code)
{
int x,y;
input()->GetCursorPos(x,y);
ScreenToLocal(x,y);
if (_vertical)
{
if ((y >= _nobPos[0]) && (y < _nobPos[1]))
{
_dragging = true;
input()->SetMouseCapture(GetVPanel());
_nobDragStartPos[0] = _nobPos[0];
_nobDragStartPos[1] = _nobPos[1];
_dragStartPos[0] = x;
_dragStartPos[1] = y;
}
else if (y < _nobPos[0])
{
// jump the bar up by the range window
int val = GetValue();
val -= _rangeWindow;
SetValue(val);
}
else if (y >= _nobPos[1])
{
// jump the bar down by the range window
int val = GetValue();
val += _rangeWindow;
SetValue(val);
}
}
else
{
if((x >= _nobPos[0]) && (x < _nobPos[1]))
{
_dragging = true;
input()->SetMouseCapture(GetVPanel());
_nobDragStartPos[0] = _nobPos[0];
_nobDragStartPos[1] = _nobPos[1];
_dragStartPos[0] = x;
_dragStartPos[1] = y;
}
else if (x < _nobPos[0])
{
// jump the bar up by the range window
int val = GetValue();
val -= _rangeWindow;
SetValue(val);
}
else if (x >= _nobPos[1])
{
// jump the bar down by the range window
int val = GetValue();
val += _rangeWindow;
SetValue(val);
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Treat double clicks as single clicks
//-----------------------------------------------------------------------------
void ScrollBarSlider::OnMouseDoublePressed(MouseCode code)
{
OnMousePressed(code);
}
//-----------------------------------------------------------------------------
// Purpose: Stop looking for mouse events when mouse is up.
//-----------------------------------------------------------------------------
void ScrollBarSlider::OnMouseReleased(MouseCode code)
{
_dragging = false;
input()->SetMouseCapture(null);
}
//-----------------------------------------------------------------------------
// Purpose: Get the position of the ends of the ScrollBarSlider.
//-----------------------------------------------------------------------------
void ScrollBarSlider::GetNobPos(int& min, int& max)
{
min=_nobPos[0];
max=_nobPos[1];
}
//-----------------------------------------------------------------------------
// Purpose: Set the number of lines visible in the window the ScrollBarSlider is attached to
//-----------------------------------------------------------------------------
void ScrollBarSlider::SetRangeWindow(int rangeWindow)
{
_rangeWindow = rangeWindow;
}
//-----------------------------------------------------------------------------
// Purpose: Get the number of lines visible in the window the ScrollBarSlider is attached to
//-----------------------------------------------------------------------------
int ScrollBarSlider::GetRangeWindow()
{
return _rangeWindow;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ScrollBarSlider::SetButtonOffset(int buttonOffset)
{
_buttonOffset = buttonOffset;
}

File diff suppressed because it is too large Load Diff

770
vgui2/controls/Slider.cpp Normal file
View File

@ -0,0 +1,770 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <stdio.h>
#define PROTECTED_THINGS_DISABLE
#include <vgui/MouseCode.h>
#include <KeyValues.h>
#include <vgui/IBorder.h>
#include <vgui/IInput.h>
#include <vgui/ISystem.h>
#include <vgui/IScheme.h>
#include <vgui/ISurface.h>
#include <vgui/ILocalize.h>
#include <vgui_controls/Slider.h>
#include <vgui_controls/Controls.h>
#include <vgui_controls/TextImage.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
static const float NOB_SIZE = 8.0f;
//-----------------------------------------------------------------------------
// Purpose: Create a slider bar with ticks underneath it
//-----------------------------------------------------------------------------
Slider::Slider(Panel *parent, const char *panelName ) : Panel(parent, panelName)
{
m_bIsDragOnRepositionNob = false;
_dragging = false;
_value = 0;
_range[0] = 0;
_range[1] = 0;
_buttonOffset = 0;
_sliderBorder = NULL;
_insetBorder = NULL;
m_nNumTicks = 10;
_leftCaption = NULL;
_rightCaption = NULL;
SetThumbWidth( 8 );
RecomputeNobPosFromValue();
AddActionSignalTarget(this);
SetBlockDragChaining( true );
}
//-----------------------------------------------------------------------------
// Purpose: Set the size of the slider bar.
// Warning less than 30 pixels tall and everything probably won't fit.
//-----------------------------------------------------------------------------
void Slider::OnSizeChanged(int wide,int tall)
{
BaseClass::OnSizeChanged(wide,tall);
RecomputeNobPosFromValue();
}
//-----------------------------------------------------------------------------
// Purpose: Set the value of the slider to one of the ticks.
//-----------------------------------------------------------------------------
void Slider::SetValue(int value, bool bTriggerChangeMessage)
{
int oldValue=_value;
if(value<_range[0])
{
value=_range[0];
}
if(value>_range[1])
{
value=_range[1];
}
_value = value;
RecomputeNobPosFromValue();
if (_value != oldValue && bTriggerChangeMessage)
{
SendSliderMovedMessage();
}
}
//-----------------------------------------------------------------------------
// Purpose: Return the value of the slider
//-----------------------------------------------------------------------------
int Slider::GetValue()
{
return _value;
}
//-----------------------------------------------------------------------------
// Purpose: Layout the slider before drawing it on screen.
//-----------------------------------------------------------------------------
void Slider::PerformLayout()
{
BaseClass::PerformLayout();
RecomputeNobPosFromValue();
if (_leftCaption)
{
_leftCaption->ResizeImageToContent();
}
if (_rightCaption)
{
_rightCaption->ResizeImageToContent();
}
}
//-----------------------------------------------------------------------------
// Purpose: Move the nob on the slider in response to changing its value.
//-----------------------------------------------------------------------------
void Slider::RecomputeNobPosFromValue()
{
//int wide,tall;
//GetPaintSize(wide,tall);
int x, y, wide, tall;
GetTrackRect( x, y, wide, tall );
float fwide=(float)wide;
float frange=(float)(_range[1] -_range[0]);
float fvalue=(float)(_value -_range[0]);
float fper = (frange != 0.0f) ? fvalue / frange : 0.0f;
float freepixels = fwide - _nobSize;
float leftpixel = (float)x;
float firstpixel = leftpixel + freepixels * fper + 0.5f;
_nobPos[0]=(int)( firstpixel );
_nobPos[1]=(int)( firstpixel + _nobSize );
int rightEdge = x + wide;
if(_nobPos[1]> rightEdge )
{
_nobPos[0]=rightEdge-((int)_nobSize);
_nobPos[1]=rightEdge;
}
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: Sync the slider's value up with the nob's position.
//-----------------------------------------------------------------------------
void Slider::RecomputeValueFromNobPos()
{
// int wide, tall;
// GetPaintSize(wide, tall);
int x, y, wide, tall;
GetTrackRect( x, y, wide, tall );
float fwide = (float)wide;
float frange = (float)( _range[1] - _range[0] );
float fvalue = (float)( _value - _range[0] );
float fnob = (float)( _nobPos[0] - x );
float freepixels = fwide - _nobSize;
// Map into reduced range
fvalue = freepixels != 0.0f ? fnob / freepixels : 0.0f;
// Scale by true range
fvalue *= frange;
// Take care of rounding issues.
SetValue( (int)( fvalue + _range[0] + 0.5) );
}
//-----------------------------------------------------------------------------
// Purpose: Send a message to interested parties when the slider moves
//-----------------------------------------------------------------------------
void Slider::SendSliderMovedMessage()
{
// send a changed message
PostActionSignal(new KeyValues("SliderMoved", "position", _value));
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Slider::ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
SetFgColor(GetSchemeColor("Slider.NobColor", pScheme));
// this line is useful for debugging
//SetBgColor(GetSchemeColor("0 0 0 255"));
m_TickColor = pScheme->GetColor( "Slider.TextColor", GetFgColor() );
m_TrackColor = pScheme->GetColor( "Slider.TrackColor", GetFgColor() );
m_DisabledTextColor1 = pScheme->GetColor( "Slider.DisabledTextColor1", GetFgColor() );
m_DisabledTextColor2 = pScheme->GetColor( "Slider.DisabledTextColor2", GetFgColor() );
_sliderBorder = pScheme->GetBorder("ButtonBorder");
_insetBorder = pScheme->GetBorder("ButtonDepressedBorder");
if ( _leftCaption )
{
_leftCaption->SetFont(pScheme->GetFont("DefaultVerySmall", IsProportional() ));
}
if ( _rightCaption )
{
_rightCaption->SetFont(pScheme->GetFont("DefaultVerySmall", IsProportional() ));
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Slider::GetSettings(KeyValues *outResourceData)
{
BaseClass::GetSettings(outResourceData);
char buf[256];
if (_leftCaption)
{
_leftCaption->GetUnlocalizedText(buf, sizeof(buf));
outResourceData->SetString("leftText", buf);
}
if (_rightCaption)
{
_rightCaption->GetUnlocalizedText(buf, sizeof(buf));
outResourceData->SetString("rightText", buf);
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Slider::ApplySettings(KeyValues *inResourceData)
{
BaseClass::ApplySettings(inResourceData);
const char *left = inResourceData->GetString("leftText", NULL);
const char *right = inResourceData->GetString("rightText", NULL);
int thumbWidth = inResourceData->GetInt("thumbwidth", 0);
if (thumbWidth != 0)
{
SetThumbWidth(thumbWidth);
}
SetTickCaptions(left, right);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const char *Slider::GetDescription()
{
static char buf[1024];
Q_snprintf(buf, sizeof(buf), "%s, string leftText, string rightText", BaseClass::GetDescription());
return buf;
}
//-----------------------------------------------------------------------------
// Purpose: Get the rectangle to draw the slider track in.
//-----------------------------------------------------------------------------
void Slider::GetTrackRect( int& x, int& y, int& w, int& h )
{
int wide, tall;
GetPaintSize( wide, tall );
x = 0;
y = 8;
w = wide - (int)_nobSize;
h = 4;
}
//-----------------------------------------------------------------------------
// Purpose: Draw everything on screen
//-----------------------------------------------------------------------------
void Slider::Paint()
{
DrawTicks();
DrawTickLabels();
// Draw nob last so it draws over ticks.
DrawNob();
}
//-----------------------------------------------------------------------------
// Purpose: Draw the ticks below the slider.
//-----------------------------------------------------------------------------
void Slider::DrawTicks()
{
int x, y;
int wide,tall;
GetTrackRect( x, y, wide, tall );
// Figure out how to draw the ticks
// GetPaintSize( wide, tall );
float fwide = (float)wide;
float freepixels = fwide - _nobSize;
float leftpixel = _nobSize / 2.0f;
float pixelspertick = freepixels / ( m_nNumTicks );
y += (int)_nobSize;
int tickHeight = 5;
if (IsEnabled())
{
surface()->DrawSetColor( m_TickColor ); //vgui::Color( 127, 140, 127, 255 ) );
for ( int i = 0; i <= m_nNumTicks; i++ )
{
int xpos = (int)( leftpixel + i * pixelspertick );
surface()->DrawFilledRect( xpos, y, xpos + 1, y + tickHeight );
}
}
else
{
surface()->DrawSetColor( m_DisabledTextColor1 ); //vgui::Color( 127, 140, 127, 255 ) );
for ( int i = 0; i <= m_nNumTicks; i++ )
{
int xpos = (int)( leftpixel + i * pixelspertick );
surface()->DrawFilledRect( xpos+1, y+1, xpos + 2, y + tickHeight + 1 );
}
surface()->DrawSetColor( m_DisabledTextColor2 ); //vgui::Color( 127, 140, 127, 255 ) );
for ( i = 0; i <= m_nNumTicks; i++ )
{
int xpos = (int)( leftpixel + i * pixelspertick );
surface()->DrawFilledRect( xpos, y, xpos + 1, y + tickHeight );
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Draw Tick labels under the ticks.
//-----------------------------------------------------------------------------
void Slider::DrawTickLabels()
{
int x, y;
int wide,tall;
GetTrackRect( x, y, wide, tall );
// Figure out how to draw the ticks
// GetPaintSize( wide, tall );
y += (int)NOB_SIZE + 4;
// Draw Start and end range values
if (IsEnabled())
surface()->DrawSetTextColor( m_TickColor ); //vgui::Color( 127, 140, 127, 255 ) );
else
surface()->DrawSetTextColor( m_DisabledTextColor1 ); //vgui::Color( 127, 140, 127, 255 ) );
if ( _leftCaption != NULL )
{
_leftCaption->SetPos(0, y);
if (IsEnabled())
{
_leftCaption->SetColor( m_TickColor );
}
else
{
_leftCaption->SetColor( m_DisabledTextColor1 );
}
_leftCaption->Paint();
}
if ( _rightCaption != NULL)
{
int rwide, rtall;
_rightCaption->GetSize(rwide, rtall);
_rightCaption->SetPos((int)(wide - rwide) , y);
if (IsEnabled())
{
_rightCaption->SetColor( m_TickColor );
}
else
{
_rightCaption->SetColor( m_DisabledTextColor1 );
}
_rightCaption->Paint();
}
}
//-----------------------------------------------------------------------------
// Purpose: Draw the nob part of the slider.
//-----------------------------------------------------------------------------
void Slider::DrawNob()
{
// horizontal nob
int x, y;
int wide,tall;
GetTrackRect( x, y, wide, tall );
Color col = GetFgColor();
surface()->DrawSetColor(col);
int nobheight = 16;
surface()->DrawFilledRect(
_nobPos[0],
y + tall / 2 - nobheight / 2,
_nobPos[1],
y + tall / 2 + nobheight / 2);
// border
if (_sliderBorder)
{
_sliderBorder->Paint(
_nobPos[0],
y + tall / 2 - nobheight / 2,
_nobPos[1],
y + tall / 2 + nobheight / 2);
}
}
//-----------------------------------------------------------------------------
// Purpose: Set the text labels of the Start and end ticks.
//-----------------------------------------------------------------------------
void Slider::SetTickCaptions( const char *left, const char *right )
{
if (left)
{
if (_leftCaption)
{
_leftCaption->SetText(left);
}
else
{
_leftCaption = new TextImage(left);
}
}
if (right)
{
if (_rightCaption)
{
_rightCaption->SetText(right);
}
else
{
_rightCaption = new TextImage(right);
}
}
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: Set the text labels of the Start and end ticks.
//-----------------------------------------------------------------------------
void Slider::SetTickCaptions( const wchar_t *left, const wchar_t *right )
{
if (left)
{
if (_leftCaption)
{
_leftCaption->SetText(left);
}
else
{
_leftCaption = new TextImage(left);
}
}
if (right)
{
if (_rightCaption)
{
_rightCaption->SetText(right);
}
else
{
_rightCaption = new TextImage(right);
}
}
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: Draw the slider track
//-----------------------------------------------------------------------------
void Slider::PaintBackground()
{
BaseClass::PaintBackground();
int x, y;
int wide,tall;
GetTrackRect( x, y, wide, tall );
surface()->DrawSetColor( m_TrackColor );
surface()->DrawFilledRect( x, y, x + wide, y + tall );
if (_insetBorder)
{
_insetBorder->Paint( x, y, x + wide, y + tall );
}
}
//-----------------------------------------------------------------------------
// Purpose: Set the range of the slider.
//-----------------------------------------------------------------------------
void Slider::SetRange(int min,int max)
{
if(max<min)
{
max=min;
}
if(min>max)
{
min=max;
}
_range[0]=min;
_range[1]=max;
if(_value<_range[0])
{
SetValue( _range[0] );
}
else if( _value>_range[1])
{
SetValue( _range[0] );
}
}
//-----------------------------------------------------------------------------
// Purpose: Get the max and min values of the slider
//-----------------------------------------------------------------------------
void Slider::GetRange(int& min,int& max)
{
min=_range[0];
max=_range[1];
}
//-----------------------------------------------------------------------------
// Purpose: Respond when the cursor is moved in our window if we are clicking
// and dragging.
//-----------------------------------------------------------------------------
void Slider::OnCursorMoved(int x,int y)
{
if(!_dragging)
{
return;
}
// input()->GetCursorPos(x,y);
input()->GetCursorPosition( x, y );
ScreenToLocal(x,y);
// int wide,tall;
// GetPaintSize(wide,tall);
int _x, _y, wide, tall;
GetTrackRect( _x, _y, wide, tall );
_nobPos[0]=_nobDragStartPos[0]+(x-_dragStartPos[0]);
_nobPos[1]=_nobDragStartPos[1]+(x-_dragStartPos[0]);
int rightEdge = _x +wide;
if(_nobPos[1]>rightEdge)
{
_nobPos[0]=rightEdge-(_nobPos[1]-_nobPos[0]);
_nobPos[1]=rightEdge;
}
if(_nobPos[0]<_x)
{
int offset = _x - _nobPos[0];
_nobPos[1]=_nobPos[1]-offset;
_nobPos[0]=0;
}
RecomputeValueFromNobPos();
Repaint();
SendSliderMovedMessage();
}
//-----------------------------------------------------------------------------
// Purpose: If you click on the slider outside of the nob, the nob jumps
// to the click position, and if this setting is enabled, the nob
// is then draggable from the new position until the mouse is released
// Input : state -
//-----------------------------------------------------------------------------
void Slider::SetDragOnRepositionNob( bool state )
{
m_bIsDragOnRepositionNob = state;
}
bool Slider::IsDragOnRepositionNob() const
{
return m_bIsDragOnRepositionNob;
}
//-----------------------------------------------------------------------------
// Purpose: Respond to mouse presses. Trigger Record staring positon.
//-----------------------------------------------------------------------------
void Slider::OnMousePressed(MouseCode code)
{
int x,y;
if (!IsEnabled())
return;
// input()->GetCursorPos(x,y);
input()->GetCursorPosition( x, y );
ScreenToLocal(x,y);
RequestFocus();
bool startdragging = false;
if ((x >= _nobPos[0]) && (x < _nobPos[1]))
{
startdragging = true;
}
else
{
// we clicked elsewhere on the slider; move the nob to that position
int min, max;
GetRange(min, max);
// int wide = GetWide();
int _x, _y, wide, tall;
GetTrackRect( _x, _y, wide, tall );
if ( wide > 0 )
{
float frange = ( float )( max - min );
float clickFrac = clamp( ( float )( x - _x ) / (float)( wide - 1 ), 0.0f, 1.0f );
float value = (float)min + clickFrac * frange;
SetValue( ( int )( value + 0.5f ) );
startdragging = IsDragOnRepositionNob();
}
}
if ( startdragging )
{
// drag the nob
_dragging = true;
input()->SetMouseCapture(GetVPanel());
_nobDragStartPos[0] = _nobPos[0];
_nobDragStartPos[1] = _nobPos[1];
_dragStartPos[0] = x;
_dragStartPos[1] = y;
}
}
//-----------------------------------------------------------------------------
// Purpose: Just handle double presses like mouse presses
//-----------------------------------------------------------------------------
void Slider::OnMouseDoublePressed(MouseCode code)
{
OnMousePressed(code);
}
//-----------------------------------------------------------------------------
// Purpose: Handle key presses
//-----------------------------------------------------------------------------
void Slider::OnKeyCodeTyped(KeyCode code)
{
switch (code)
{
// for now left and right arrows just open or close submenus if they are there.
case KEY_LEFT:
case KEY_DOWN:
{
int val = GetValue();
SetValue(val-1);
break;
}
case KEY_RIGHT:
case KEY_UP:
{
int val = GetValue();
SetValue(val+1);
break;
}
case KEY_PAGEDOWN:
{
int min, max;
GetRange(min, max);
float range = (float) max-min;
float pertick = range/m_nNumTicks;
int val = GetValue();
SetValue(val - (int) pertick);
break;
}
case KEY_PAGEUP:
{
int min, max;
GetRange(min, max);
float range = (float) max-min;
float pertick = range/m_nNumTicks;
int val = GetValue();
SetValue(val + (int) pertick);
break;
}
case KEY_HOME:
{
int min, max;
GetRange(min, max);
SetValue(min);
break;
}
case KEY_END:
{
int min, max;
GetRange(min, max);
SetValue(max);
break;
}
default:
BaseClass::OnKeyCodeTyped(code);
break;
}
}
//-----------------------------------------------------------------------------
// Purpose: Stop dragging when the mouse is released.
//-----------------------------------------------------------------------------
void Slider::OnMouseReleased(MouseCode code)
{
_dragging=false;
input()->SetMouseCapture(null);
}
//-----------------------------------------------------------------------------
// Purpose: Get the nob's position (the ends of each side of the nob)
//-----------------------------------------------------------------------------
void Slider::GetNobPos(int& min, int& max)
{
min=_nobPos[0];
max=_nobPos[1];
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Slider::SetButtonOffset(int buttonOffset)
{
_buttonOffset=buttonOffset;
}
void Slider::SetThumbWidth( int width )
{
_nobSize = (float)width;
}
//-----------------------------------------------------------------------------
// Purpose: Set the number of ticks that appear under the slider.
//-----------------------------------------------------------------------------
void Slider::SetNumTicks( int ticks )
{
m_nNumTicks = ticks;
}

761
vgui2/controls/Splitter.cpp Normal file
View File

@ -0,0 +1,761 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#include <vgui/IScheme.h>
#include <vgui/Cursor.h>
#include <vgui/iinput.h>
#include <vgui_controls/Splitter.h>
#include "tier1/keyvalues.h"
#include <limits.h>
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
using namespace vgui;
enum
{
SPLITTER_HANDLE_WIDTH = 4
};
//-----------------------------------------------------------------------------
// Splitter handle
//-----------------------------------------------------------------------------
namespace vgui
{
class SplitterHandle : public Panel
{
DECLARE_CLASS_SIMPLE( SplitterHandle, Panel );
public:
SplitterHandle( Splitter *parent, const char *name, SplitterMode_t mode, int nIndex );
~SplitterHandle();
virtual void ApplySchemeSettings( IScheme *pScheme );
virtual void OnMousePressed( MouseCode code );
virtual void OnMouseReleased( MouseCode code );
virtual void OnCursorMoved( int x, int y );
virtual void OnMouseDoublePressed( MouseCode code );
private:
SplitterMode_t m_nMode;
int m_nIndex;
bool m_bDragging;
};
} // end namespace vgui
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
SplitterHandle::SplitterHandle( Splitter *parent, const char *name, SplitterMode_t mode, int nIndex ) : BaseClass( parent, name )
{
int w, h;
parent->GetSize( w, h );
if ( mode == SPLITTER_MODE_HORIZONTAL )
{
SetSize( w, SPLITTER_HANDLE_WIDTH );
SetCursor( dc_sizens );
}
else
{
SetSize( SPLITTER_HANDLE_WIDTH, h );
SetCursor( dc_sizewe );
}
SetVisible( true );
SetPaintBackgroundEnabled( false );
SetPaintEnabled( false );
SetPaintBorderEnabled( true );
m_bDragging = false;
m_nIndex = nIndex;
m_nMode = mode;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
SplitterHandle::~SplitterHandle()
{
}
//-----------------------------------------------------------------------------
// Scheme settings
//-----------------------------------------------------------------------------
void SplitterHandle::ApplySchemeSettings(IScheme *pScheme)
{
// Cache off background color stored in SetSplitterColor
Color c = GetBgColor();
SetBorder(pScheme->GetBorder("ButtonDepressedBorder"));
BaseClass::ApplySchemeSettings(pScheme);
SetBgColor( c );
}
//-----------------------------------------------------------------------------
// Capture mouse when dragging
//-----------------------------------------------------------------------------
void SplitterHandle::OnMousePressed(MouseCode code)
{
if ( !m_bDragging )
{
input()->SetMouseCapture(GetVPanel());
m_bDragging = true;
}
}
//-----------------------------------------------------------------------------
// Release mouse capture when finished dragging
//-----------------------------------------------------------------------------
void SplitterHandle::OnMouseReleased(MouseCode code)
{
if ( m_bDragging )
{
input()->SetMouseCapture(NULL);
m_bDragging = false;
}
}
//-----------------------------------------------------------------------------
// While dragging, update the splitter position
//-----------------------------------------------------------------------------
void SplitterHandle::OnCursorMoved(int x, int y)
{
if (m_bDragging)
{
input()->GetCursorPos( x, y );
Splitter *pSplitter = assert_cast<Splitter*>( GetParent() );
pSplitter->ScreenToLocal( x,y );
pSplitter->SetSplitterPosition( m_nIndex, (m_nMode == SPLITTER_MODE_HORIZONTAL) ? y : x );
}
}
//-----------------------------------------------------------------------------
// Double-click: make both panels on either side of the splitter equal size
//-----------------------------------------------------------------------------
void SplitterHandle::OnMouseDoublePressed( MouseCode code )
{
Splitter *pSplitter = assert_cast<Splitter*>( GetParent() );
pSplitter->EvenlyRespaceSplitters();
}
//-----------------------------------------------------------------------------
// Returns a panel that chains user configs
//-----------------------------------------------------------------------------
namespace vgui
{
class SplitterChildPanel : public EditablePanel
{
DECLARE_CLASS_SIMPLE( SplitterChildPanel, EditablePanel );
public:
SplitterChildPanel( Panel *parent, const char *panelName ) : BaseClass( parent, panelName )
{
SetPaintBackgroundEnabled( false );
SetPaintEnabled( false );
SetPaintBorderEnabled( false );
}
virtual ~SplitterChildPanel() {}
// Children may have user config settings
bool HasUserConfigSettings()
{
return true;
}
};
} // end namespace vgui
//-----------------------------------------------------------------------------
//
// Splitter panel
//
//-----------------------------------------------------------------------------
vgui::Panel *Splitter_V_Factory()
{
return new Splitter( NULL, NULL, SPLITTER_MODE_VERTICAL, 1 );
}
vgui::Panel *Splitter_H_Factory()
{
return new Splitter( NULL, NULL, SPLITTER_MODE_HORIZONTAL, 1 );
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
Splitter::Splitter( Panel *parent, const char *name, SplitterMode_t mode, int nCount ) : BaseClass( parent, name )
{
Assert( nCount >= 1 );
m_Mode = mode;
SetPaintBackgroundEnabled( false );
SetPaintEnabled( false );
SetPaintBorderEnabled( false );
RecreateSplitters( nCount );
EvenlyRespaceSplitters();
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
Splitter::~Splitter()
{
m_Splitters.RemoveAll();
}
void Splitter::RecreateSplitters( int nCount )
{
int i;
int c = m_Splitters.Count();
for ( i = 0; i < c; ++i )
{
delete m_Splitters[ i ].m_pPanel;
delete m_Splitters[ i ].m_pHandle;
}
m_Splitters.RemoveAll();
for ( i = 0; i < (nCount + 1); ++i )
{
char pBuffer[512];
Q_snprintf( pBuffer, sizeof(pBuffer), "child%d", i );
int nIndex = m_Splitters.AddToTail( );
SplitterChildPanel *pEditablePanel = new SplitterChildPanel( this, pBuffer );
m_Splitters[nIndex].m_pPanel = pEditablePanel;
m_Splitters[nIndex].m_bLocked = false;
m_Splitters[nIndex].m_nLockedSize = 0;
}
// We do this in 2 loops so that the first N children are actual child panels
for ( i = 0; i < nCount; ++i )
{
SplitterHandle *pHandle = new SplitterHandle( this, "SplitterHandle", m_Mode, i );
m_Splitters[i].m_pHandle = pHandle;
pHandle->MoveToFront();
}
m_Splitters[nCount].m_pHandle = NULL;
}
//-----------------------------------------------------------------------------
// Sets the splitter color
//-----------------------------------------------------------------------------
void Splitter::SetSplitterColor( Color c )
{
int nCount = m_Splitters.Count() - 1;
if ( c.a() != 0 )
{
for ( int i = 0; i < nCount; ++i )
{
m_Splitters[i].m_pHandle->SetBgColor( c );
m_Splitters[i].m_pHandle->SetPaintBackgroundEnabled( true );
}
}
else
{
for ( int i = 0; i < nCount; ++i )
{
m_Splitters[i].m_pHandle->SetPaintBackgroundEnabled( false );
}
}
}
//-----------------------------------------------------------------------------
// Enables borders on the splitters
//-----------------------------------------------------------------------------
void Splitter::EnableBorders( bool bEnable )
{
int nCount = m_Splitters.Count() - 1;
for ( int i = 0; i < nCount; ++i )
{
m_Splitters[i].m_pHandle->SetPaintBorderEnabled( bEnable );
}
}
//-----------------------------------------------------------------------------
// controls splitters
//-----------------------------------------------------------------------------
int Splitter::GetSplitterCount() const
{
return m_Splitters.Count() - 1;
}
//-----------------------------------------------------------------------------
// controls splitters
//-----------------------------------------------------------------------------
int Splitter::GetSubPanelCount() const
{
return m_Splitters.Count();
}
//-----------------------------------------------------------------------------
// Purpose: Applies resouce settings
//-----------------------------------------------------------------------------
void Splitter::ApplySettings(KeyValues *inResourceData)
{
BaseClass::ApplySettings(inResourceData);
// Look for splitter positions
int nSplitterCount = GetSplitterCount();
for ( int i = 0; i < nSplitterCount; ++i )
{
char pBuffer[512];
Q_snprintf( pBuffer, sizeof(pBuffer), "splitter%d", i );
int nSplitterPos = inResourceData->GetInt( pBuffer , -1 );
if ( nSplitterPos >= 0 )
{
SetSplitterPosition( i, nSplitterPos );
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int Splitter::GetPosRange()
{
int w, h;
GetSize( w, h );
int nPosRange = (m_Mode == SPLITTER_MODE_HORIZONTAL) ? h : w;
return nPosRange;
}
//-----------------------------------------------------------------------------
// Locks the size of a particular child in pixels.
//-----------------------------------------------------------------------------
void Splitter::LockChildSize( int nChildIndex, int nSize )
{
Assert( nChildIndex < m_Splitters.Count() );
SplitterInfo_t &info = m_Splitters[nChildIndex];
nSize += SPLITTER_HANDLE_WIDTH;
if ( !info.m_bLocked || (info.m_nLockedSize != nSize) )
{
float flPrevPos = (nChildIndex > 0) ? m_Splitters[nChildIndex-1].m_flPos : 0.0f;
float flOldSize = info.m_flPos - flPrevPos;
float flDelta = nSize - flOldSize;
int nCount = m_Splitters.Count();
for ( int i = nChildIndex; i < nCount-1; ++i )
{
m_Splitters[i].m_flPos += flDelta;
}
m_Splitters[nCount-1].m_flPos = GetPosRange();
info.m_bLocked = true;
info.m_nLockedSize = nSize;
InvalidateLayout();
}
}
void Splitter::UnlockChildSize( int nChildIndex )
{
Assert( nChildIndex < m_Splitters.Count() );
SplitterInfo_t &info = m_Splitters[nChildIndex];
if ( info.m_bLocked )
{
info.m_bLocked = false;
float flPrevPos = (nChildIndex > 0) ? m_Splitters[nChildIndex-1].m_flPos : 0.0f;
float flBelowSize = GetPosRange() - flPrevPos;
int nLockedSize = ComputeLockedSize( nChildIndex + 1 );
int nUnlockedCount = 1;
int nCount = m_Splitters.Count();
for ( int i = nChildIndex + 1; i < nCount; ++i )
{
if ( !m_Splitters[i].m_bLocked )
{
++nUnlockedCount;
}
}
float flUnlockedSize = ( flBelowSize - nLockedSize ) / nUnlockedCount;
for ( int i = nChildIndex; i < nCount; ++i )
{
if ( !m_Splitters[i].m_bLocked )
{
m_Splitters[i].m_flPos = flPrevPos + flUnlockedSize;
}
else
{
m_Splitters[i].m_flPos = flPrevPos + m_Splitters[i].m_nLockedSize;
}
flPrevPos = m_Splitters[i].m_flPos;
}
InvalidateLayout();
}
}
//-----------------------------------------------------------------------------
// Called when size changes
//-----------------------------------------------------------------------------
void Splitter::OnSizeChanged( int newWide, int newTall )
{
BaseClass::OnSizeChanged( newWide, newTall );
int nLockedSize = 0;
float flUnlockedSize = 0.0f;
int nCount = m_Splitters.Count();
float flLastPos = 0.0f;
int nUnlockedCount = 0;
for ( int i = 0; i < nCount; ++i )
{
SplitterInfo_t &info = m_Splitters[i];
if ( info.m_bLocked )
{
nLockedSize += info.m_nLockedSize;
}
else
{
++nUnlockedCount;
flUnlockedSize += info.m_flPos - flLastPos;
}
flLastPos = info.m_flPos;
}
int nNewTotalSize = (m_Mode == SPLITTER_MODE_HORIZONTAL) ? newTall : newWide;
int nNewUnlockedSize = nNewTotalSize - nLockedSize;
if ( nNewUnlockedSize < nUnlockedCount * SPLITTER_HANDLE_WIDTH )
{
nNewUnlockedSize = nUnlockedCount * SPLITTER_HANDLE_WIDTH;
}
float flRatio = nNewUnlockedSize / flUnlockedSize;
float flLastPrevPos = 0.0f;
flLastPos = 0.0f;
for ( int i = 0; i < nCount - 1; ++i )
{
SplitterInfo_t &info = m_Splitters[i];
if ( info.m_bLocked )
{
flLastPrevPos = info.m_flPos;
info.m_flPos = flLastPos + info.m_nLockedSize;
}
else
{
float flNewSize = info.m_flPos - flLastPrevPos;
flNewSize *= flRatio;
flLastPrevPos = info.m_flPos;
info.m_flPos = flLastPos + flNewSize;
}
flLastPos = info.m_flPos;
}
// Clamp the bottom to 1.0
m_Splitters[nCount-1].m_flPos = nNewTotalSize;
}
//-----------------------------------------------------------------------------
// Splitter position
//-----------------------------------------------------------------------------
int Splitter::GetSplitterPosition( int nIndex )
{
return (int)( m_Splitters[nIndex].m_flPos + 0.5f );
}
void Splitter::SetSplitterPosition( int nIndex, int nPos )
{
int nPosRange = GetPosRange();
if ( nPosRange == 0 )
return;
// If we're locked to a sibling, move the previous sibling first
while ( ( nIndex >= 0 ) && m_Splitters[nIndex].m_bLocked )
{
nPos -= m_Splitters[nIndex].m_nLockedSize;
--nIndex;
}
if ( nIndex < 0 )
return;
// Clamp to the valid positional range
int i;
int nMinPos = 0;
for ( i = 0; i < nIndex; ++i )
{
if ( !m_Splitters[i].m_bLocked )
{
nMinPos += SPLITTER_HANDLE_WIDTH;
}
else
{
nMinPos += m_Splitters[i].m_nLockedSize;
}
}
int nMaxPos = nPosRange - SPLITTER_HANDLE_WIDTH;
int c = GetSplitterCount();
for ( i = nIndex + 1; i < c; ++i )
{
if ( !m_Splitters[i].m_bLocked )
{
nMaxPos -= SPLITTER_HANDLE_WIDTH;
}
else
{
nMaxPos -= m_Splitters[i].m_nLockedSize;
}
}
nPos = clamp( nPos, nMinPos, nMaxPos );
m_Splitters[nIndex].m_flPos = nPos;
int p = nPos;
for ( i = nIndex - 1 ; i >= 0; --i )
{
int nMinPrevPos;
int nMaxPrevPos;
if ( !m_Splitters[i+1].m_bLocked )
{
nMinPrevPos = -INT_MAX;
nMaxPrevPos = nPos - SPLITTER_HANDLE_WIDTH;
}
else
{
nMinPrevPos = nMaxPrevPos = p - m_Splitters[i+1].m_nLockedSize;
}
int nCurPos = GetSplitterPosition( i );
if ( nMaxPrevPos < nCurPos || nMinPrevPos > nCurPos )
{
m_Splitters[ i ].m_flPos = nMaxPrevPos;
p = nMaxPrevPos;
}
else
{
p = m_Splitters[ i ].m_flPos;
}
}
for ( i = nIndex + 1 ; i < c; ++i )
{
int nMinNextPos;
int nMaxNextPos;
if ( !m_Splitters[i].m_bLocked )
{
nMinNextPos = nPos + SPLITTER_HANDLE_WIDTH;
nMaxNextPos = INT_MAX;
}
else
{
nMinNextPos = nMaxNextPos = nPos + m_Splitters[i].m_nLockedSize;
}
int nCurPos = GetSplitterPosition( i );
if ( nMinNextPos > nCurPos || nMaxNextPos < nCurPos )
{
m_Splitters[ i ].m_flPos = nMinNextPos;
nPos = nMinNextPos;
}
else
{
nPos = m_Splitters[ i ].m_flPos;
}
}
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Computes the locked size
//-----------------------------------------------------------------------------
int Splitter::ComputeLockedSize( int nStartingIndex )
{
int nLockedSize = 0;
int nCount = m_Splitters.Count();
for ( int i = nStartingIndex; i < nCount; ++i )
{
if ( m_Splitters[i].m_bLocked )
{
nLockedSize += m_Splitters[i].m_nLockedSize;
}
}
return nLockedSize;
}
//-----------------------------------------------------------------------------
// Evenly respaces all the splitters
//-----------------------------------------------------------------------------
void Splitter::EvenlyRespaceSplitters( )
{
int nSplitterCount = GetSubPanelCount();
if ( nSplitterCount == 0 )
return;
int nLockedSize = ComputeLockedSize( 0 );
float flUnlockedSize = (float)( GetPosRange() - nLockedSize );
float flDPos = flUnlockedSize / (float)nSplitterCount;
if ( flDPos < SPLITTER_HANDLE_WIDTH )
{
flDPos = SPLITTER_HANDLE_WIDTH;
}
float flPos = 0.0f;
for ( int i = 0; i < nSplitterCount; ++i )
{
if ( !m_Splitters[i].m_bLocked )
{
flPos += flDPos;
}
else
{
flPos += m_Splitters[i].m_nLockedSize;
}
m_Splitters[i].m_flPos = flPos;
}
InvalidateLayout();
}
void Splitter::RespaceSplitters( float *flFractions )
{
int nSplitterCount = GetSubPanelCount();
if ( nSplitterCount == 0 )
return;
float flPos = 0.0f;
int nPosRange = GetPosRange();
for ( int i = 0; i < nSplitterCount; ++i )
{
flPos += flFractions[i];
m_Splitters[i].m_flPos = flPos * nPosRange;
}
Assert( flPos == 1.0f );
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: sets user settings
//-----------------------------------------------------------------------------
void Splitter::ApplyUserConfigSettings(KeyValues *userConfig)
{
BaseClass::ApplyUserConfigSettings( userConfig );
// read the splitter sizes
int c = m_Splitters.Count();
float *pFractions = (float*)_alloca( c * sizeof(float) );
float flTotalSize = 0.0f;
for ( int i = 0; i < c; i++ )
{
char name[128];
_snprintf(name, sizeof(name), "%d_splitter_pos", i);
pFractions[i] = userConfig->GetFloat( name, flTotalSize + SPLITTER_HANDLE_WIDTH + 1 );
flTotalSize = pFractions[i];
}
if ( flTotalSize != 0.0f )
{
int nPosRange = GetPosRange();
for ( int i = 0; i < c; ++i )
{
pFractions[i] /= flTotalSize;
m_Splitters[i].m_flPos = pFractions[i] * nPosRange;
}
}
}
//-----------------------------------------------------------------------------
// Purpose: returns user config settings for this control
//-----------------------------------------------------------------------------
void Splitter::GetUserConfigSettings(KeyValues *userConfig)
{
BaseClass::GetUserConfigSettings( userConfig );
// save which columns are hidden
int c = m_Splitters.Count();
for ( int i = 0 ; i < c; i++ )
{
char name[128];
_snprintf(name, sizeof(name), "%d_splitter_pos", i);
userConfig->SetFloat( name, m_Splitters[i].m_flPos );
}
}
//-----------------------------------------------------------------------------
// Called to perform layout
//-----------------------------------------------------------------------------
void Splitter::PerformLayout( )
{
BaseClass::PerformLayout();
int nSplitterCount = GetSubPanelCount();
if ( nSplitterCount == 0 )
return;
int w, h;
GetSize( w, h );
int nLastPos = 0;
for ( int i = 0; i < nSplitterCount; ++i )
{
Panel *pChild = m_Splitters[i].m_pPanel;
SplitterHandle *pHandle = m_Splitters[i].m_pHandle;
int nSplitterPos = (int)( m_Splitters[i].m_flPos + 0.5f );
if ( m_Mode == SPLITTER_MODE_HORIZONTAL )
{
pChild->SetPos( 0, nLastPos );
pChild->SetSize( w, nSplitterPos - nLastPos );
if ( pHandle )
{
pHandle->SetPos( 0, nSplitterPos );
pHandle->SetSize( w, SPLITTER_HANDLE_WIDTH );
}
}
else
{
pChild->SetPos( nLastPos, 0 );
pChild->SetSize( nSplitterPos - nLastPos, h );
if ( pHandle )
{
pHandle->SetPos( nSplitterPos, 0 );
pHandle->SetSize( SPLITTER_HANDLE_WIDTH, h );
}
}
nLastPos = nSplitterPos + SPLITTER_HANDLE_WIDTH;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Splitter::GetSettings( KeyValues *outResourceData )
{
BaseClass::GetSettings( outResourceData );
}

4117
vgui2/controls/TextEntry.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,625 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Implementation of vgui::TextImage control
//
// $NoKeywords: $
//=============================================================================//
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#include <malloc.h>
#include <vgui/IPanel.h>
#include <vgui/ISurface.h>
#include <vgui/IScheme.h>
#include <vgui/IInput.h>
#include <vgui/ILocalize.h>
#include <KeyValues.h>
#include <vgui_controls/TextImage.h>
#include <vgui_controls/Controls.h>
#include "tier0/dbg.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
// enable this define if you want unlocalized strings logged to files unfound.txt and unlocalized.txt
// #define LOG_UNLOCALIZED_STRINGS
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
TextImage::TextImage(const char *text) : Image()
{
_utext = NULL;
_textBufferLen = 0;
_font = INVALID_FONT;
_unlocalizedTextSymbol = INVALID_STRING_INDEX;
_drawWidth = 0;
_textBufferLen = 0;
_textLen = 0;
m_bWrap = false;
m_LineBreaks.RemoveAll();
m_pwszEllipsesPosition = NULL;
SetText(text); // set the text.
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
TextImage::TextImage(const wchar_t *wszText) : Image()
{
_utext = NULL;
_textBufferLen = 0;
_font = INVALID_FONT;
_unlocalizedTextSymbol = INVALID_STRING_INDEX;
_drawWidth = 0;
_textBufferLen = 0;
_textLen = 0;
m_bWrap = false;
m_LineBreaks.RemoveAll();
SetText(wszText); // set the text.
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
TextImage::~TextImage()
{
delete [] _utext;
}
//-----------------------------------------------------------------------------
// Purpose: takes the string and looks it up in the localization file to convert it to unicode
//-----------------------------------------------------------------------------
void TextImage::SetText(const char *text)
{
if (!text)
{
text = "";
}
// check for localization
if (*text == '#')
{
// try lookup in localization tables
_unlocalizedTextSymbol = localize()->FindIndex(text + 1);
if (_unlocalizedTextSymbol != INVALID_STRING_INDEX)
{
wchar_t *unicode = localize()->GetValueByIndex(_unlocalizedTextSymbol);
SetText(unicode);
return;
}
else
{
// could not find string
// debug code for logging unlocalized strings
#if defined(LOG_UNLOCALIZED_STRINGS)
if (*text)
{
// write out error to unfound.txt log file
static bool first = true;
FILE *f;
if (first)
{
first = false;
f = fopen("unfound.txt", "wt");
}
else
{
f = fopen("unfound.txt", "at");
}
if (f)
{
fprintf(f, "\"%s\"\n", text);
fclose(f);
}
}
#endif // LOG_UNLOCALIZED_STRINGS
}
}
else
{
// debug code for logging unlocalized strings
#if defined(LOG_UNLOCALIZED_STRINGS)
if (text[0])
{
// setting a label to be ANSI text, write out error to unlocalized.txt log file
static bool first = true;
FILE *f;
if (first)
{
first = false;
f = fopen("unlocalized.txt", "wt");
}
else
{
f = fopen("unlocalized.txt", "at");
}
if (f)
{
fprintf(f, "\"%s\"\n", text);
fclose(f);
}
}
#endif // LOG_UNLOCALIZED_STRINGS
}
// convert the ansi string to unicode and use that
wchar_t unicode[1024];
localize()->ConvertANSIToUnicode(text, unicode, sizeof(unicode));
SetText(unicode);
}
//-----------------------------------------------------------------------------
// Purpose: Sets the width that the text can be.
//-----------------------------------------------------------------------------
void TextImage::SetDrawWidth(int width)
{
_drawWidth = width;
m_bRecalculateTruncation = true;
}
//-----------------------------------------------------------------------------
// Purpose: Gets the width that the text can be.
//-----------------------------------------------------------------------------
void TextImage::GetDrawWidth(int &width)
{
width = _drawWidth;
}
//-----------------------------------------------------------------------------
// Purpose: sets unicode text directly
//-----------------------------------------------------------------------------
void TextImage::SetText(const wchar_t *unicode)
{
if (!unicode)
{
unicode = L"";
}
// reallocate the buffer if necessary
_textLen = (short)wcslen(unicode);
if (_textLen >= _textBufferLen)
{
delete [] _utext;
_textBufferLen = (short)(_textLen + 1);
_utext = new wchar_t[_textBufferLen];
}
m_LineBreaks.RemoveAll();
// store the text as unicode
wcscpy(_utext, unicode);
m_bRecalculateTruncation = true;
}
//-----------------------------------------------------------------------------
// Purpose: Gets the text in the textImage
//-----------------------------------------------------------------------------
void TextImage::GetText(char *buffer, int bufferSize)
{
localize()->ConvertUnicodeToANSI(_utext, buffer, bufferSize);
}
//-----------------------------------------------------------------------------
// Purpose: Gets the text in the textImage
//-----------------------------------------------------------------------------
void TextImage::GetText(wchar_t *buffer, int bufLenInBytes)
{
wcsncpy(buffer, _utext, bufLenInBytes / sizeof(wchar_t));
}
//-----------------------------------------------------------------------------
// Purpose: data accessor
//-----------------------------------------------------------------------------
void TextImage::GetUnlocalizedText(char *buffer, int bufferSize)
{
if (_unlocalizedTextSymbol != INVALID_STRING_INDEX)
{
const char *text = localize()->GetNameByIndex(_unlocalizedTextSymbol);
buffer[0] = '#';
Q_strncpy(buffer + 1, text, bufferSize - 1);
buffer[bufferSize-1] = 0;
}
else
{
GetText(buffer, bufferSize);
}
}
//-----------------------------------------------------------------------------
// Purpose: unlocalized text symbol
//-----------------------------------------------------------------------------
StringIndex_t TextImage::GetUnlocalizedTextSymbol()
{
return _unlocalizedTextSymbol;
}
//-----------------------------------------------------------------------------
// Purpose: Changes the current font
//-----------------------------------------------------------------------------
void TextImage::SetFont(HFont font)
{
_font = font;
m_bRecalculateTruncation = true;
}
//-----------------------------------------------------------------------------
// Purpose: Gets the font of the text.
//-----------------------------------------------------------------------------
HFont TextImage::GetFont()
{
return _font;
}
//-----------------------------------------------------------------------------
// Purpose: Sets the size of the TextImage. This is directly tied to drawWidth
//-----------------------------------------------------------------------------
void TextImage::SetSize(int wide, int tall)
{
Image::SetSize(wide, tall);
_drawWidth = wide;
m_bRecalculateTruncation = true;
}
//-----------------------------------------------------------------------------
// Purpose: Draw the Image on screen.
//-----------------------------------------------------------------------------
void TextImage::Paint()
{
int wide, tall;
GetSize(wide, tall);
if (!_utext || _font == INVALID_FONT )
return;
if (m_bRecalculateTruncation)
{
RecalculateEllipsesPosition();
}
DrawSetTextColor(GetColor());
HFont font = GetFont();
DrawSetTextFont(font);
int lineHeight = surface()->GetFontTall(font);
int x = 0, y = 0;
int px, py;
GetPos(px, py);
int currentLineBreak = 0;
for (wchar_t *wsz = _utext; *wsz != 0; wsz++)
{
wchar_t ch = wsz[0];
// check for special characters
if (ch == '\r')
{
// ignore, just use \n for newlines
continue;
}
else if (ch == '\n')
{
// newline
x = 0;
y += lineHeight;
continue;
}
else if (ch == '&')
{
// "&&" means draw a single ampersand, single one is a shortcut character
if (wsz[1] == '&')
{
// just move on and draw the second ampersand
wsz++;
}
else
{
// draw the underline, then continue to the next character without moving forward
#ifdef VGUI_DRAW_HOTKEYS_ENABLED
DrawPrintChar(x + px, y + py, '_');
#endif
continue;
}
}
// see if we've hit the truncated portion of the string
if (wsz == m_pwszEllipsesPosition)
{
// string is truncated, draw ellipses
for (int i = 0; i < 3; i++)
{
surface()->DrawSetTextPos(x + px, y + py);
surface()->DrawUnicodeChar('.');
x += surface()->GetCharacterWidth(font, '.');
}
break;
}
if (currentLineBreak != m_LineBreaks.Count())
{
if (wsz == m_LineBreaks[currentLineBreak])
{
x = 0;
y += lineHeight;
currentLineBreak++;
}
}
if (ch != ' ')
{
// render the character
surface()->DrawSetTextPos(x + px, y + py);
surface()->DrawUnicodeChar(ch);
}
x += surface()->GetCharacterWidth(font, ch);
}
}
//-----------------------------------------------------------------------------
// Purpose: Get the size of a text string in pixels
//-----------------------------------------------------------------------------
void TextImage::GetTextSize(int &wide, int &tall)
{
wide = 0;
tall = 0;
int maxWide = 0;
const wchar_t *text = _utext;
HFont font = GetFont();
if ( font == INVALID_FONT )
return;
if ( m_bWrap )
RecalculateNewLinePositions();
tall = surface()->GetFontTall(font);
int textLen = wcslen(text);
for (int i = 0; i < textLen; i++)
{
// handle stupid special characters, these should be removed
if (text[i] == '&' && text[i + 1] != 0)
{
i++;
}
int a, b, c;
surface()->GetCharABCwide(font, text[i], a, b, c);
wide += (a + b + c);
if (text[i] == '\n')
{
tall += surface()->GetFontTall(font);
if(wide>maxWide)
{
maxWide=wide;
}
wide=0; // new line, wide is reset...
}
if ( m_bWrap )
{
for(int j=0; j<m_LineBreaks.Count(); j++)
{
if ( &text[i] == m_LineBreaks[j] )
{
tall += surface()->GetFontTall(font);
if(wide>maxWide)
{
maxWide=wide;
}
wide=0; // new line, wide is reset...
}
}
}
}
if (wide < maxWide)
{
// maxWide only gets set if a newline is in the label
wide = maxWide;
}
}
//-----------------------------------------------------------------------------
// Purpose: Get the size of the text in the image
//-----------------------------------------------------------------------------
void TextImage::GetContentSize(int &wide, int &tall)
{
GetTextSize(wide, tall);
}
//-----------------------------------------------------------------------------
// Purpose: Resize the text image to the content size
//-----------------------------------------------------------------------------
void TextImage::ResizeImageToContent()
{
int wide, tall;
GetContentSize(wide, tall);
SetSize(wide, tall);
}
//-----------------------------------------------------------------------------
// Purpose: Recalculates line breaks
//-----------------------------------------------------------------------------
void TextImage::RecalculateNewLinePositions()
{
HFont font = _font;
int charWidth;
int x = 0;
//int wordStartIndex = 0;
wchar_t *wordStartIndex = _utext;
int wordLength = 0;
bool hasWord = false;
bool justStartedNewLine = true;
bool wordStartedOnNewLine = true;
int startChar = 0;
// clear the line breaks list
m_LineBreaks.RemoveAll();
// handle the case where this char is a new line, in that case
// we have already taken its break index into account above so skip it.
if (_utext[startChar] == '\r' || _utext[startChar] == '\n')
{
startChar++;
}
// loop through all the characters
for (wchar_t *wsz = &_utext[startChar]; *wsz != 0; wsz++)
{
wchar_t ch = wsz[0];
// line break only on whitespace characters
if (!iswspace(ch))
{
if ( !hasWord )
{
// Start a new word
wordStartIndex = wsz;
hasWord = true;
wordStartedOnNewLine = justStartedNewLine;
wordLength = 0;
}
//else append to the current word
}
else
{
// whitespace/punctuation character
// end the word
hasWord = false;
}
// get the width
charWidth = surface()->GetCharacterWidth(font, ch);
if (!iswcntrl(ch))
{
justStartedNewLine = false;
}
// check to see if the word is past the end of the line [wordStartIndex, i)
if ((x + charWidth) > _drawWidth || ch == '\r' || ch == '\n')
{
justStartedNewLine = true;
hasWord = false;
if (ch == '\r' || ch == '\n')
{
// set the break at the current character
//don't do this, paint will manually wrap on newline chars
// m_LineBreaks.AddToTail(i);
}
else if (wordStartedOnNewLine)
{
// word is longer than a line, so set the break at the current cursor
m_LineBreaks.AddToTail(wsz);
}
else
{
// set it at the last word Start
m_LineBreaks.AddToTail(wordStartIndex);
// just back to reparse the next line of text
wsz = wordStartIndex;
}
// reset word length
wordLength = 0;
x = 0;
continue;
}
// add to the size
x += charWidth;
wordLength += charWidth;
}
}
//-----------------------------------------------------------------------------
// Purpose: Calculates where the text should be truncated
//-----------------------------------------------------------------------------
void TextImage::RecalculateEllipsesPosition()
{
m_pwszEllipsesPosition = NULL;
m_bRecalculateTruncation = false;
//don't insert ellipses on wrapped strings
if ( m_bWrap )
return;
// don't truncate strings with newlines
if (wcschr(_utext, '\n') != NULL)
return;
HFont font = GetFont();
int ellipsesWidth = 3 * surface()->GetCharacterWidth(font, '.');
int x = 0;
for (wchar_t *wsz = _utext; *wsz != 0; wsz++)
{
wchar_t ch = wsz[0];
// check for special characters
if (ch == '\r')
{
// ignore, just use \n for newlines
continue;
}
else if (ch == '&')
{
// "&&" means draw a single ampersand, single one is a shortcut character
if (wsz[1] == '&')
{
// just move on and draw the second ampersand
wsz++;
}
else
{
continue;
}
}
// don't truncate the first character
if (wsz == _utext)
continue;
int len = surface()->GetCharacterWidth(font, ch);
if (x + len + ellipsesWidth > _drawWidth)
{
// potential have an ellipses, see if the remaining characters will fit
int remainingLength = len;
for (const wchar_t *rwsz = wsz + 1; *rwsz != 0; rwsz++)
{
remainingLength += surface()->GetCharacterWidth(font, *rwsz);
}
if (x + remainingLength > _drawWidth)
{
// looks like we've got an ellipses situation
m_pwszEllipsesPosition = wsz;
break;
}
}
x += len;
}
}
void TextImage::SetWrap( bool bWrap )
{
m_bWrap = bWrap;
}

View File

@ -0,0 +1,102 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <vgui/KeyCode.h>
#include <vgui_controls/ToggleButton.h>
#include <KeyValues.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
DECLARE_BUILD_FACTORY_DEFAULT_TEXT( ToggleButton, ToggleButton );
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
ToggleButton::ToggleButton(Panel *parent, const char *panelName, const char* text) : Button(parent, panelName, text)
{
SetButtonActivationType(ACTIVATE_ONPRESSED);
}
//-----------------------------------------------------------------------------
// Purpose: Turns double-click into normal click
//-----------------------------------------------------------------------------
void ToggleButton::OnMouseDoublePressed(MouseCode code)
{
OnMousePressed(code);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
Color ToggleButton::GetButtonFgColor()
{
if (IsSelected())
{
// highlight the text when depressed
return _selectedColor;
}
else
{
return BaseClass::GetButtonFgColor();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool ToggleButton::CanBeDefaultButton(void)
{
return false;
}
//-----------------------------------------------------------------------------
// Purpose: Toggles the state of the button
//-----------------------------------------------------------------------------
void ToggleButton::DoClick()
{
if (IsSelected())
{
ForceDepressed(false);
}
else if (!IsSelected())
{
ForceDepressed(true);
}
SetSelected(!IsSelected());
FireActionSignal();
// post a button toggled message
KeyValues *msg = new KeyValues("ButtonToggled");
msg->SetInt("state", (int)IsSelected());
PostActionSignal(msg);
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ToggleButton::ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
_selectedColor = GetSchemeColor("ToggleButton.SelectedTextColor", pScheme);
}
void ToggleButton::OnKeyCodePressed(KeyCode code)
{
if (code != KEY_ENTER)
{
BaseClass::OnKeyCodePressed(code);
}
}

View File

@ -0,0 +1,473 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <vgui/KeyCode.h>
#include <KeyValues.h>
#include "vgui/iinput.h"
#include "vgui/MouseCode.h"
#include "vgui/ISurface.h"
#include <vgui_controls/ToolWindow.h>
#include <vgui_controls/PropertySheet.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
CUtlVector< ToolWindow * > ToolWindow::s_ToolWindows;
//-----------------------------------------------------------------------------
// Purpose:
// Input : -
// Output : int
//-----------------------------------------------------------------------------
int ToolWindow::GetToolWindowCount()
{
return s_ToolWindows.Count();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : index -
// Output : PropertySheet
//-----------------------------------------------------------------------------
ToolWindow *ToolWindow::GetToolWindow( int index )
{
return s_ToolWindows[ index ];
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
ToolWindow::ToolWindow(
Panel *parent,
bool contextlabel,
IToolWindowFactory *factory /*= 0*/,
Panel *page /*= NULL*/,
char const *title /*= NULL */,
bool contextMenu /*=false*/,
bool inGlobalList /*= true*/ ) : BaseClass( parent, "ToolWindow" ),
m_pFactory( factory )
{
if ( inGlobalList )
{
s_ToolWindows.AddToTail( this );
}
// create the property sheet
m_pPropertySheet = new PropertySheet(this, "ToolWindowSheet", true );
m_pPropertySheet->ShowContextButtons( contextlabel );
m_pPropertySheet->AddPage( page, title, 0, contextMenu );
m_pPropertySheet->AddActionSignalTarget(this);
m_pPropertySheet->SetSmallTabs( true );
m_pPropertySheet->SetKBNavigationEnabled( false );
SetSmallCaption( true );
SetMenuButtonResponsive(false);
SetMinimizeButtonVisible(false);
SetCloseButtonVisible(true);
SetMoveable( true );
SetSizeable(true);
SetClipToParent( false );
SetVisible( true );
SetDeleteSelfOnClose( true );
SetTitle( "", false );
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
ToolWindow::~ToolWindow()
{
// These don't actually kill the children of the property sheet
m_pPropertySheet->RemoveAllPages();
s_ToolWindows.FindAndRemove( this );
}
//-----------------------------------------------------------------------------
// Purpose: Pass through to sheet
// Input : -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool ToolWindow::IsDraggableTabContainer() const
{
return m_pPropertySheet->IsDraggableTab();
}
//-----------------------------------------------------------------------------
// Purpose: Returns a pointer to the PropertySheet this dialog encapsulates
// Output : PropertySheet *
//-----------------------------------------------------------------------------
PropertySheet *ToolWindow::GetPropertySheet()
{
return m_pPropertySheet;
}
//-----------------------------------------------------------------------------
// Purpose: Gets a pointer to the currently active page.
// Output : Panel
//-----------------------------------------------------------------------------
Panel *ToolWindow::GetActivePage()
{
return m_pPropertySheet->GetActivePage();
}
//-----------------------------------------------------------------------------
// Purpose: Wrapped function
//-----------------------------------------------------------------------------
void ToolWindow::AddPage(Panel *page, const char *title, bool contextMenu)
{
m_pPropertySheet->AddPage(page, title, 0, contextMenu );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *page -
//-----------------------------------------------------------------------------
void ToolWindow::RemovePage( Panel *page )
{
m_pPropertySheet->RemovePage( page );
if ( m_pPropertySheet->GetNumPages() == 0 )
{
MarkForDeletion();
}
}
//-----------------------------------------------------------------------------
// Purpose: Sets up the sheet
//-----------------------------------------------------------------------------
void ToolWindow::PerformLayout()
{
BaseClass::PerformLayout();
int x, y, wide, tall;
GetClientArea(x, y, wide, tall);
m_pPropertySheet->SetBounds(x, y, wide, tall);
m_pPropertySheet->InvalidateLayout(); // tell the propertysheet to redraw!
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: Overrides build mode so it edits the sub panel
//-----------------------------------------------------------------------------
void ToolWindow::ActivateBuildMode()
{
// no subpanel, no build mode
EditablePanel *panel = dynamic_cast<EditablePanel *>(GetActivePage());
if (!panel)
return;
panel->ActivateBuildMode();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ToolWindow::RequestFocus(int direction)
{
m_pPropertySheet->RequestFocus(direction);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *factory -
//-----------------------------------------------------------------------------
void ToolWindow::SetToolWindowFactory( IToolWindowFactory *factory )
{
m_pFactory = factory;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : -
// Output : IToolWindowFactory
//-----------------------------------------------------------------------------
IToolWindowFactory *ToolWindow::GetToolWindowFactory()
{
return m_pFactory;
}
//-----------------------------------------------------------------------------
// Purpose: To fill the space left by other tool windows
// Input : edge: 0=all, 1=top, 2=right, 3=bottom, 4=left
// Output :
//-----------------------------------------------------------------------------
void ToolWindow::Grow( int edge, int from_x, int from_y )
{
int status_h = 24;
int menubar_h = 27;
int sw, sh;
surface()->GetScreenSize( sw, sh );
int old_x, old_y, old_w, old_h;
GetBounds( old_x, old_y, old_w, old_h );
int new_x, new_y, new_w, new_h;
new_x = old_x;
new_y = old_y;
new_w = old_w;
new_h = old_h;
int c = GetToolWindowCount();
// grow up
if ( ( edge == 0 ) || ( edge == 1 ) )
{
// first shrink the edge back to the grow point
if ( from_y >= 0 )
{
old_h = old_h - ( from_y - old_y );
old_y = from_y;
}
// now grow the edge as far as it can go
new_h = old_h + ( old_y - menubar_h );
new_y = menubar_h;
for ( int i = 0 ; i < c; ++i )
{
ToolWindow *tw = GetToolWindow( i );
Assert( tw );
if ( ( !tw ) || ( tw == this ) )
continue;
// Get panel bounds
int x, y, w, h;
tw->GetBounds( x, y, w, h );
// grow it
if ( ( ( ( old_x > x ) && ( old_x < x + w ) )
|| ( ( old_x + old_w > x ) && ( old_x + old_w < x + w ) )
|| ( ( old_x <= x ) && old_x + old_w >= x + w ))
&& ( ( old_y >= y + h ) && ( new_y < y + h ) ) )
{
new_h = old_h + ( old_y - ( y + h ) );
new_y = y + h;
}
}
old_h = new_h;
old_y = new_y;
}
// grow right
if ( ( edge == 0 ) || ( edge == 2 ) )
{
// first shrink the edge back to the grow point
if ( from_x >= 0 )
{
old_w = from_x - old_x;
}
// now grow the edge as far as it can go
new_w = sw - old_x;
for ( int i = 0 ; i < c; ++i )
{
ToolWindow *tw = GetToolWindow( i );
Assert( tw );
if ( ( !tw ) || ( tw == this ) )
continue;
// Get panel bounds
int x, y, w, h;
tw->GetBounds( x, y, w, h );
// grow it
if ( ( ( ( old_y > y ) && ( old_y < y + h ) )
|| ( ( old_y + old_h > y ) && ( old_y + old_h < y + h ) )
|| ( ( old_y <= y ) && old_y + old_h >= y + h ))
&& ( ( old_x + old_w <= x ) && ( new_w > x - old_x ) ) )
{
new_w = x - old_x;
}
}
old_w = new_w;
}
// grow down
if ( ( edge == 0 ) || ( edge == 3 ) )
{
// first shrink the edge back to the grow point
if ( from_y >= 0 )
{
old_h = from_y - old_y;
}
// now grow the edge as far as it can go
new_h = sh - old_y - status_h;
for ( int i = 0 ; i < c; ++i )
{
ToolWindow *tw = GetToolWindow( i );
Assert( tw );
if ( ( !tw ) || ( tw == this ) )
continue;
// Get panel bounds
int x, y, w, h;
tw->GetBounds( x, y, w, h );
// grow it
if ( ( ( ( old_x > x ) && ( old_x < x + w ) )
|| ( ( old_x + old_w > x ) && ( old_x + old_w < x + w ) )
|| ( ( old_x <= x ) && old_x + old_w >= x + w ))
&& ( ( old_y + old_h <= y ) && ( new_h > y - old_y ) ) )
{
new_h = y - old_y;
}
}
old_h = new_h;
}
// grow left
if ( ( edge == 0 ) || ( edge == 4 ) )
{
// first shrink the edge back to the grow point
if ( from_x >= 0 )
{
old_w = old_w - ( from_x - old_x );
old_x = from_x;
}
// now grow the edge as far as it can go
new_w = old_w + old_x;
new_x = 0;
for ( int i = 0 ; i < c; ++i )
{
ToolWindow *tw = GetToolWindow( i );
Assert( tw );
if ( ( !tw ) || ( tw == this ) )
continue;
// Get panel bounds
int x, y, w, h;
tw->GetBounds( x, y, w, h );
// grow it
if ( ( ( ( old_y > y ) && ( old_y < y + h ) )
|| ( ( old_y + old_h > y ) && ( old_y + old_h < y + h ) )
|| ( ( old_y <= y ) && old_y + old_h >= y + h ))
&& ( ( old_x >= x + w ) && ( new_x < x + w ) ) )
{
new_w = old_w + ( old_x - ( x + w ) );
new_x = x + w;
}
}
old_w = new_w;
old_x = new_x;
}
// Set panel bounds
SetBounds( new_x, new_y, new_w, new_h );
}
//-----------------------------------------------------------------------------
// Purpose: Calls Grow based on where the mouse is.
// over titlebar: grows all edges ( from mouse pos )
// over edge grab area: grows just that edge
// over corner grab area: grows the two adjacent edges
// Input :
// Output :
//-----------------------------------------------------------------------------
void ToolWindow::GrowFromClick()
{
int mx, my;
input()->GetCursorPos( mx, my );
int esz, csz, brsz, ch;
esz = GetDraggerSize();
csz = GetCornerSize();
brsz = GetBottomRightSize();
ch = GetCaptionHeight();
int x, y, w, h;
GetBounds( x, y, w, h );
// upper right
if ( ( mx > x+w-csz-1 ) && ( my < y+csz ) )
{
Grow(1);
Grow(2);
}
// lower right (the big one)
else if ( ( mx > x+w-brsz-1 ) && ( my > y+h-brsz-1 ) )
{
Grow(2);
Grow(3);
}
// lower left
else if ( ( mx < x+csz ) && ( my > y+h-csz-1 ) )
{
Grow(3);
Grow(4);
}
// upper left
else if ( ( mx < x+csz ) && ( my < y+csz ) )
{
Grow(4);
Grow(1);
}
// top edge
else if ( my < y+esz )
{
Grow(1);
}
// right edge
else if ( mx > x+w-esz-1 )
{
Grow(2);
}
// bottom edge
else if ( my > y+h-esz-1 )
{
Grow(3);
}
// left edge
else if ( mx < x+esz )
{
Grow(4);
}
// otherwise (if over the grab bar), grow all edges (from the clicked point)
else if ( my < y + ch )
{
Grow(0, mx, my);
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : -
// Output :
//-----------------------------------------------------------------------------
void ToolWindow::OnMouseDoublePressed( MouseCode code )
{
GrowFromClick();
}
void ToolWindow::OnMousePressed( MouseCode code )
{
switch ( code )
{
case MOUSE_MIDDLE:
GrowFromClick();
break;
default:
BaseClass::OnMousePressed( code );
}
}

306
vgui2/controls/Tooltip.cpp Normal file
View File

@ -0,0 +1,306 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
// This class is a message box that has two buttons, ok and cancel instead of
// just the ok button of a message box. We use a message box class for the ok button
// and implement another button here.
//=============================================================================//
#include <math.h>
#define PROTECTED_THINGS_DISABLE
#include <vgui/IInput.h>
#include <vgui/ISystem.h>
#include <vgui/ISurface.h>
#include <vgui/IScheme.h>
#include <vgui/IVGui.h>
#include <vgui/IPanel.h>
#include <vgui_controls/Tooltip.h>
#include <vgui_controls/TextEntry.h>
#include <vgui_controls/Controls.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
static vgui::DHANDLE< TextEntry > s_TooltipWindow;
static int s_iTooltipWindowCount = 0;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
Tooltip::Tooltip(Panel *parent, const char *text)
{
if (!s_TooltipWindow.Get())
{
s_TooltipWindow = new TextEntry(NULL, "tooltip");
}
s_iTooltipWindowCount++;
// this line prevents the main window from losing focus
// when a tooltip pops up
s_TooltipWindow->MakePopup(false, true);
SetText(text);
s_TooltipWindow->SetText(m_Text.Base());
s_TooltipWindow->SetEditable(false);
s_TooltipWindow->SetMultiline(true);
s_TooltipWindow->SetVisible(false);
_displayOnOneLine = false;
_makeVisible = false;
_tooltipDelay = 500; // default delay for opening tooltips
_delay = 0;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
Tooltip::~Tooltip()
{
if (--s_iTooltipWindowCount < 1)
{
if ( s_TooltipWindow.Get() )
{
s_TooltipWindow->MarkForDeletion();
}
s_TooltipWindow = NULL;
}
}
//-----------------------------------------------------------------------------
// Purpose: Get the tooltip text
//-----------------------------------------------------------------------------
const char *Tooltip::GetText()
{
return m_Text.Base();
}
//-----------------------------------------------------------------------------
// Purpose: Set the tooltip text
//-----------------------------------------------------------------------------
void Tooltip::SetText(const char *text)
{
if (!text)
{
text = "";
}
if (m_Text.Size() > 0)
{
m_Text.RemoveAll();
}
for (unsigned int i = 0; i < strlen(text); i++)
{
m_Text.AddToTail(text[i]);
}
m_Text.AddToTail('\0');
if (s_TooltipWindow.Get())
{
s_TooltipWindow->SetText(m_Text.Base());
}
}
//-----------------------------------------------------------------------------
// Purpose: gets the font from the scheme
//-----------------------------------------------------------------------------
void Tooltip::ApplySchemeSettings(IScheme *pScheme)
{
if ( s_TooltipWindow.Get() )
{
s_TooltipWindow->SetFont(pScheme->GetFont("DefaultSmall", s_TooltipWindow->IsProportional()));
}
}
//-----------------------------------------------------------------------------
// Purpose: Reset the tooltip delay timer
//-----------------------------------------------------------------------------
void Tooltip::ResetDelay()
{
_delay = system()->GetTimeMillis() + _tooltipDelay;
}
//-----------------------------------------------------------------------------
// Purpose: Set the tooltip delay before a tooltip comes up.
//-----------------------------------------------------------------------------
void Tooltip::SetTooltipDelay( int tooltipDelay )
{
_tooltipDelay = tooltipDelay;
}
//-----------------------------------------------------------------------------
// Purpose: Get the tooltip delay before a tooltip comes up.
//-----------------------------------------------------------------------------
int Tooltip::GetTooltipDelay()
{
return _tooltipDelay;
}
//-----------------------------------------------------------------------------
// Purpose: Display the tooltip
//-----------------------------------------------------------------------------
void Tooltip::ShowTooltip(Panel *currentPanel)
{
if ( s_TooltipWindow.Get() )
{
s_TooltipWindow->SetText(m_Text.Base());
s_TooltipWindow->SetParent(currentPanel);
}
_makeVisible = true;
PerformLayout();
}
//-----------------------------------------------------------------------------
// Purpose: Display the tooltip
//-----------------------------------------------------------------------------
void Tooltip::PerformLayout()
{
if (!_makeVisible)
return;
if (_delay > system()->GetTimeMillis())
return;
// we're ready, just make us visible
if ( !s_TooltipWindow.Get() )
{
return;
}
s_TooltipWindow->SetVisible(true);
s_TooltipWindow->MakePopup(false, true);
IScheme *pScheme = scheme()->GetIScheme( s_TooltipWindow->GetScheme() );
s_TooltipWindow->SetBgColor(s_TooltipWindow->GetSchemeColor("Tooltip.BgColor", s_TooltipWindow->GetBgColor(), pScheme));
s_TooltipWindow->SetFgColor(s_TooltipWindow->GetSchemeColor("Tooltip.TextColor", s_TooltipWindow->GetFgColor(), pScheme));
s_TooltipWindow->SetBorder(pScheme->GetBorder("ToolTipBorder"));
// get cursor position
int cursorX, cursorY;
input()->GetCursorPos(cursorX, cursorY);
// relayout the textwindow immediately so that we know it's size
//m_pTextEntry->InvalidateLayout(true);
SizeTextWindow();
int menuWide, menuTall;
s_TooltipWindow->GetSize(menuWide, menuTall);
// work out where the cursor is and therefore the best place to put the menu
int wide, tall;
surface()->GetScreenSize(wide, tall);
if (wide - menuWide > cursorX)
{
cursorY += 20;
// menu hanging right
if (tall - menuTall > cursorY)
{
// menu hanging down
s_TooltipWindow->SetPos(cursorX, cursorY);
}
else
{
// menu hanging up
s_TooltipWindow->SetPos(cursorX, cursorY - menuTall - 20);
}
}
else
{
// menu hanging left
if (tall - menuTall > cursorY)
{
// menu hanging down
s_TooltipWindow->SetPos(cursorX - menuWide, cursorY);
}
else
{
// menu hanging up
s_TooltipWindow->SetPos(cursorX - menuWide, cursorY - menuTall - 20 );
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Size the text window so all the text fits inside it.
//-----------------------------------------------------------------------------
void Tooltip::SizeTextWindow()
{
if ( !s_TooltipWindow.Get() )
return;
if (_displayOnOneLine)
{
// We want the tool tip to be one line
s_TooltipWindow->SetMultiline(false);
s_TooltipWindow->SetToFullWidth();
}
else
{
// We want the tool tip to be one line
s_TooltipWindow->SetMultiline(false);
s_TooltipWindow->SetToFullWidth();
int wide, tall;
s_TooltipWindow->GetSize( wide, tall );
double newWide = sqrt( (2.0/1) * wide * tall );
double newTall = (1/2) * newWide;
s_TooltipWindow->SetMultiline(true);
s_TooltipWindow->SetSize((int)newWide, (int)newTall );
s_TooltipWindow->SetToFullHeight();
s_TooltipWindow->GetSize( wide, tall );
if (( wide < 100 ) && ( s_TooltipWindow->GetNumLines() == 2) )
{
s_TooltipWindow->SetMultiline(false);
s_TooltipWindow->SetToFullWidth();
}
else
{
while ( (float)wide/(float)tall < 2 )
{
s_TooltipWindow->SetSize( wide + 1, tall );
s_TooltipWindow->SetToFullHeight();
s_TooltipWindow->GetSize( wide, tall );
}
}
s_TooltipWindow->GetSize( wide, tall );
// ivgui()->DPrintf("End Ratio: %f\n", (float)wide/(float)tall);
}
}
//-----------------------------------------------------------------------------
// Purpose: Set the tool tip to display on one line only
// Default is multiple lines.
//-----------------------------------------------------------------------------
void Tooltip::SetTooltipFormatToSingleLine()
{
_displayOnOneLine = true;
}
//-----------------------------------------------------------------------------
// Purpose: Set the tool tip to display on multiple lines.
//-----------------------------------------------------------------------------
void Tooltip::SetTooltipFormatToMultiLine()
{
_displayOnOneLine = false;
}
//-----------------------------------------------------------------------------
// Purpose: Display the tooltip
//-----------------------------------------------------------------------------
void Tooltip::HideTooltip()
{
if ( s_TooltipWindow.Get() )
{
s_TooltipWindow->SetVisible(false);
}
_makeVisible = false;
}

2830
vgui2/controls/TreeView.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,315 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include <assert.h>
#define PROTECTED_THINGS_DISABLE
#include <vgui/Cursor.h>
#include <vgui/IScheme.h>
#include <vgui/IInput.h>
#include <vgui/IPanel.h>
#include <vgui/ISurface.h>
#include <vgui/KeyCode.h>
#include <KeyValues.h>
#include <vgui/MouseCode.h>
#include <vgui/IBorder.h>
#include <vgui_controls/TreeViewListControl.h>
#include <vgui_controls/ScrollBar.h>
#include <vgui_controls/TextEntry.h>
#include <vgui_controls/TreeView.h>
#include <vgui_controls/Label.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/TextImage.h>
#include <vgui_controls/ImageList.h>
#include <vgui_controls/ImagePanel.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
DECLARE_BUILD_FACTORY( CTreeViewListControl );
CTreeViewListControl::CTreeViewListControl( vgui::Panel *pParent, const char *pName ) :
BaseClass( pParent, pName )
{
m_pTree = NULL;
m_BorderColor.SetColor( 255, 255, 255, 255 );
m_TitleBarFont = NULL;
m_TitleBarHeight = 20;
SetPostChildPaintEnabled( true );
}
void CTreeViewListControl::SetTreeView( vgui::TreeView *pTree )
{
m_pTree = pTree;
if ( m_pTree )
{
m_pTree->SetParent( this );
m_pTree->SetPaintBackgroundEnabled( false );
}
InvalidateLayout();
}
vgui::TreeView *CTreeViewListControl::GetTree()
{
return m_pTree;
}
int CTreeViewListControl::GetTitleBarHeight()
{
return m_TitleBarHeight;
}
void CTreeViewListControl::SetTitleBarInfo( vgui::HFont hFont, int titleBarHeight )
{
m_TitleBarFont = hFont;
m_TitleBarHeight = titleBarHeight;
InvalidateLayout();
}
void CTreeViewListControl::SetBorderColor( Color clr )
{
m_BorderColor = clr;
}
void CTreeViewListControl::SetNumColumns( int nColumns )
{
m_Columns.Purge();
m_Columns.SetSize( nColumns );
InvalidateLayout();
}
int CTreeViewListControl::GetNumColumns() const
{
return m_Columns.Count();
}
void CTreeViewListControl::SetColumnInfo( int iColumn, const char *pTitle, int width, int ciFlags )
{
if ( iColumn < 0 || iColumn >= m_Columns.Count() )
{
Assert( false );
return;
}
CColumnInfo *pInfo = &m_Columns[iColumn];
pInfo->m_Title = pTitle;
pInfo->m_Width = width;
pInfo->m_ciFlags = ciFlags;
InvalidateLayout();
}
int CTreeViewListControl::GetNumRows()
{
return m_Rows.Count();
}
int CTreeViewListControl::GetTreeItemAtRow( int iRow )
{
if ( iRow < 0 || iRow >= m_Rows.Count() )
return -1;
else
return m_Rows[iRow];
}
void CTreeViewListControl::GetGridElementBounds( int iColumn, int iRow, int &left, int &top, int &right, int &bottom )
{
left = m_Columns[iColumn].m_Left;
right = m_Columns[iColumn].m_Right;
// vgui doesn't seem to be drawing things exactly right. Like it you draw a line at (0,0) to (100,0),
// then a rectangle from (1,1) to (100,100), it'll overwrite the line at the top.
int treeTopBorder = 0;
IBorder *treeBorder = m_pTree->GetBorder();
if ( treeBorder )
{
int l, t, r, b;
treeBorder->GetInset( l, t, r, b );
treeTopBorder = t;
}
if ( iRow == -1 )
{
top = 1;
bottom = m_TitleBarHeight - 2;
}
else if ( m_pTree )
{
int x, y;
m_pTree->GetPos( x, y );
top = treeTopBorder + m_TitleBarHeight + ( iRow * m_pTree->GetRowHeight() );
bottom = top + m_pTree->GetRowHeight();
}
else
{
left = top = right = bottom = 0;
}
}
void CTreeViewListControl::PerformLayout()
{
RecalculateRows();
RecalculateColumns();
// Reposition the tree view.
if ( m_pTree && m_Columns.Count() > 0 )
{
int left, top, right, bottom;
GetGridElementBounds( 0, -1, left, top, right, bottom );
top = m_TitleBarHeight;
m_pTree->SetBounds( left, top, right - left, GetTall() - top );
}
BaseClass::PerformLayout();
}
void CTreeViewListControl::RecalculateRows()
{
m_Rows.Purge();
if ( !m_pTree || m_pTree->GetRootItemIndex() == -1 )
return;
int iRoot = m_pTree->GetRootItemIndex();
RecalculateRows_R( iRoot );
}
void CTreeViewListControl::RecalculateRows_R( int index )
{
m_Rows.AddToTail( index );
if ( !m_pTree->IsItemExpanded( index ) )
return;
int nChildren = m_pTree->GetNumChildren( index );
for ( int i=0; i < nChildren; i++ )
{
int iChild = m_pTree->GetChild( index, i );
RecalculateRows_R( iChild );
}
}
int CTreeViewListControl::GetScrollBarSize()
{
return 0;
}
void CTreeViewListControl::RecalculateColumns()
{
int rightEdge = GetWide()-1 - GetScrollBarSize();
int x = 0;
int c = m_Columns.Count();
for ( int i=0; i < c; i++ )
{
m_Columns[i].m_Left = x + 1;
int cw = m_Columns[i].m_Width;
if ( i == c - 1 )
{
cw = rightEdge - x - 2;
}
m_Columns[i].m_Right = x + cw - 2;
x += cw;
}
}
void CTreeViewListControl::PostChildPaint()
{
BaseClass::PostChildPaint();
// Draw the grid lines.
vgui::surface()->DrawSetColor( m_BorderColor );
if ( m_Columns.Count() <= 0 )
return;
// Draw the horizontal lines.
int endX = 0;
endX = m_Columns[m_Columns.Count()-1].m_Right + 1;
int bottomY = 0;
for ( int i=0; i < m_Rows.Count(); i++ )
{
int left, top, right, bottom;
GetGridElementBounds( 0, i, left, top, right, bottom );
bottomY = bottom;
vgui::surface()->DrawLine( 0, bottomY, endX, bottomY );
}
// Draw the vertical lines.
int curX = 0;
for ( i=0; i < m_Columns.Count(); i++ )
{
vgui::surface()->DrawLine( curX, 0, curX, bottomY );
curX += m_Columns[i].m_Width;
}
vgui::surface()->DrawLine( curX, 0, curX, bottomY );
}
void CTreeViewListControl::Paint()
{
BaseClass::Paint();
// Draw the title bars.
DrawTitleBars();
}
void CTreeViewListControl::DrawTitleBars()
{
int rightEdge = GetWide();
for ( int i=0; i < m_Columns.Count(); i++ )
{
int left, top, right, bottom;
GetGridElementBounds( i, -1, left, top, right, bottom );
if ( left >= rightEdge )
continue;
vgui::surface()->DrawSetColor( 0, 0, 0, 255 );
vgui::surface()->DrawFilledRect( left, top, right, bottom );
vgui::surface()->DrawSetTextColor( 255, 255, 255, 255 );
const char *pTitleString = m_Columns[i].m_Title.String();
wchar_t unicodeString[1024];
vgui::localize()->ConvertANSIToUnicode( pTitleString, unicodeString, sizeof(unicodeString) );
int wide, tall;
surface()->GetTextSize( m_TitleBarFont, unicodeString, wide, tall );
surface()->DrawSetTextFont( m_TitleBarFont );
if ( m_Columns[i].m_ciFlags & CTreeViewListControl::CI_HEADER_LEFTALIGN )
{
int midy = (top+bottom)/2;
surface()->DrawSetTextPos( left, midy );
}
else
{
int textRight = min( right, rightEdge );
int midx = (left+textRight)/2;
int midy = (top+bottom)/2;
surface()->DrawSetTextPos( midx - wide/2, midy - tall/2 );
}
surface()->DrawPrintText( unicodeString, strlen( pTitleString ) );
}
}

158
vgui2/controls/URLLabel.cpp Normal file
View File

@ -0,0 +1,158 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <stdio.h>
#include "vgui/ISurface.h"
#include "vgui/ISystem.h"
#include "vgui/MouseCode.h"
#include "vgui/Cursor.h"
#include "KeyValues.h"
#include "vgui_controls/URLLabel.h"
#include "vgui_controls/TextImage.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
using namespace vgui;
vgui::Panel *URLLabel_Factory()
{
return new URLLabel(NULL, NULL, "URLLabel", NULL);
}
DECLARE_BUILD_FACTORY_CUSTOM( URLLabel, URLLabel_Factory );
//-----------------------------------------------------------------------------
// Purpose: constructor
//-----------------------------------------------------------------------------
URLLabel::URLLabel(Panel *parent, const char *panelName, const char *text, const char *pszURL) : Label(parent, panelName, text)
{
m_pszURL = NULL;
m_bUnderline = false;
m_iURLSize = 0;
if (pszURL && strlen(pszURL) > 0)
{
SetURL(pszURL);
}
}
//-----------------------------------------------------------------------------
// Purpose: unicode constructor
//-----------------------------------------------------------------------------
URLLabel::URLLabel(Panel *parent, const char *panelName, const wchar_t *wszText, const char *pszURL) : Label(parent, panelName, wszText)
{
m_pszURL = NULL;
m_bUnderline = false;
m_iURLSize = 0;
if (pszURL && strlen(pszURL) > 0)
{
SetURL(pszURL);
}
}
//-----------------------------------------------------------------------------
// Purpose: destructor
//-----------------------------------------------------------------------------
URLLabel::~URLLabel()
{
if (m_pszURL)
delete [] m_pszURL;
}
//-----------------------------------------------------------------------------
// Purpose: sets the URL
//-----------------------------------------------------------------------------
void URLLabel::SetURL(const char *pszURL)
{
int iNewURLSize = strlen(pszURL);
if (iNewURLSize > m_iURLSize || !m_pszURL)
{
delete [] m_pszURL;
m_pszURL = new char [iNewURLSize + 1];
}
strcpy(m_pszURL, pszURL);
m_iURLSize = iNewURLSize;
}
//-----------------------------------------------------------------------------
// Purpose: If we were left clicked on, launch the URL
//-----------------------------------------------------------------------------
void URLLabel::OnMousePressed(MouseCode code)
{
if (code == MOUSE_LEFT)
{
if (m_pszURL)
{
system()->ShellExecute("open", m_pszURL);
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Applies resouce settings
//-----------------------------------------------------------------------------
void URLLabel::ApplySettings(KeyValues *inResourceData)
{
BaseClass::ApplySettings(inResourceData);
const char *pszURL = inResourceData->GetString("URLText", NULL);
if (pszURL)
{
if (pszURL[0] == '#')
{
// it's a localized url, look it up
const wchar_t *ws = localize()->Find(pszURL + 1);
if (ws)
{
char localizedUrl[512];
localize()->ConvertUnicodeToANSI(ws, localizedUrl, sizeof(localizedUrl));
SetURL(localizedUrl);
}
}
else
{
SetURL(pszURL);
}
}
}
//-----------------------------------------------------------------------------
// Purpose: saves them to disk
//-----------------------------------------------------------------------------
void URLLabel::GetSettings( KeyValues *outResourceData )
{
BaseClass::GetSettings(outResourceData);
if (m_pszURL)
{
outResourceData->SetString("URLText", m_pszURL);
}
}
//-----------------------------------------------------------------------------
// Purpose: Returns a description of the label string
//-----------------------------------------------------------------------------
const char *URLLabel::GetDescription( void )
{
static char buf[1024];
_snprintf(buf, sizeof(buf), "%s, string URLText", BaseClass::GetDescription());
return buf;
}
//-----------------------------------------------------------------------------
// Purpose: scheme settings
//-----------------------------------------------------------------------------
void URLLabel::ApplySchemeSettings(IScheme *pScheme)
{
// set our font to be underlined by default
// the Label::ApplySchemeSettings() will override it if override set in scheme file
SetFont( pScheme->GetFont( "DefaultUnderline", IsProportional() ) );
BaseClass::ApplySchemeSettings(pScheme);
SetCursor(dc_hand);
}

View File

@ -0,0 +1,720 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <vgui/IVGui.h>
#include <KeyValues.h>
#include <vgui_controls/BuildGroup.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/Controls.h>
#include <vgui_controls/WizardPanel.h>
#include <vgui_controls/WizardSubPanel.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
WizardPanel::WizardPanel(Panel *parent, const char *panelName) : Frame(parent, panelName)
{
_currentSubPanel = NULL;
_currentData = new KeyValues("WizardData");
_showButtons = true;
SetSizeable(false);
CreateButtons();
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
WizardPanel::~WizardPanel()
{
if (_currentData)
{
_currentData->deleteThis();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::PerformLayout()
{
BaseClass::PerformLayout();
// resize the sub panel to fit in the Client area
int x, y, wide, tall;
GetClientArea(x, y, wide, tall);
if (_currentSubPanel && _currentSubPanel->isNonWizardPanel())
{
// just have the subpanel cover the full size
_currentSubPanel->SetBounds(x, y, wide, tall);
_cancelButton->SetVisible(false);
_prevButton->SetVisible(false);
_nextButton->SetVisible(false);
_finishButton->SetVisible(false);
}
else
{
// make room for the buttons at bottom
if (_currentSubPanel)
{
if( _showButtons )
{
_currentSubPanel->SetBounds(x, y, wide, tall - 35);
}
else
{
_currentSubPanel->SetBounds(x, y, wide, tall);
}
}
// align the buttons to the right hand side
GetSize(wide, tall);
int bwide, btall;
_cancelButton->GetSize(bwide, btall);
x = wide - (20 + bwide);
y = tall - (12 + btall);
_cancelButton->SetPos(x, y);
x -= (20 + bwide);
// only display one of the next or finish buttons (and only if both are visible)
if ( _showButtons )
{
if (_finishButton->IsEnabled() )
{
_nextButton->SetVisible(false);
_finishButton->SetVisible(true);
_finishButton->SetPos(x, y);
}
else
{
_nextButton->SetVisible(true);
_finishButton->SetVisible(false);
_nextButton->SetPos(x, y);
}
}
x -= (1 + bwide);
_prevButton->SetPos(x, y);
ResetDefaultButton();
}
}
//-----------------------------------------------------------------------------
// Purpose: if we don't show buttons then let the sub panel occupy the whole screen
//-----------------------------------------------------------------------------
void WizardPanel::GetClientArea(int &x, int &y, int &wide, int &tall)
{
if( _showButtons )
{
BaseClass::GetClientArea( x, y, wide, tall );
}
else
{
x = 0;
y = 0;
GetSize( wide, tall );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::Run(WizardSubPanel *startPanel)
{
// skip over sub panels if they don't want to be displayed
startPanel = FindNextValidSubPanel(startPanel);
// show it
ActivateNextSubPanel(startPanel);
// make sure we're set up and Run the first panel
Activate();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::ActivateBuildMode()
{
// no subpanel, no build mode
if (!_currentSubPanel)
return;
_currentSubPanel->ActivateBuildMode();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::ResetDefaultButton()
{
// work out which is the default button
if (_nextButton->IsEnabled())
{
_nextButton->SetAsDefaultButton(true);
}
else if (_finishButton->IsEnabled())
{
_finishButton->SetAsDefaultButton(true);
}
else if (_prevButton->IsEnabled())
{
_prevButton->SetAsDefaultButton(true);
}
/* Don't ever set the cancel button as the default, as it is too easy for users to quit the wizard without realizing
else if (_cancelButton->IsEnabled())
{
_cancelButton->SetAsDefaultButton(true);
}
*/
// reset them all (this may not be necessary)
_nextButton->InvalidateLayout();
_prevButton->InvalidateLayout();
_cancelButton->InvalidateLayout();
_finishButton->InvalidateLayout();
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::ResetKeyFocus()
{
// set the focus on the default
FocusNavGroup &navGroup = GetFocusNavGroup();
Panel *def = navGroup.GetDefaultPanel();
if (def)
{
if (def->IsEnabled() && def->IsVisible())
{
def->RequestFocus();
}
else
{
def->RequestFocusNext();
}
}
ResetDefaultButton();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::CreateButtons()
{
_prevButton = new Button(this, "PrevButton", "");
_nextButton = new Button(this, "NextButton", "");
_cancelButton = new Button(this, "CancelButton", "");
_finishButton = new Button(this, "FinishButton", "");
_prevButton->SetCommand(new KeyValues("PrevButton"));
_nextButton->SetCommand(new KeyValues("NextButton"));
_cancelButton->SetCommand(new KeyValues("CancelButton"));
_finishButton->SetCommand(new KeyValues("FinishButton"));
SetNextButtonText(NULL);
SetPrevButtonText(NULL);
SetFinishButtonText(NULL);
SetCancelButtonText(NULL);
_prevButton->SetSize(82, 24);
_nextButton->SetSize(82, 24);
_cancelButton->SetSize(82, 24);
_finishButton->SetSize(82, 24);
}
//-----------------------------------------------------------------------------
// Purpose: clears all previous history
//-----------------------------------------------------------------------------
void WizardPanel::ResetHistory()
{
_subPanelStack.RemoveAll();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::ActivateNextSubPanel(WizardSubPanel *subPanel)
{
// get rid of previous panel
WizardSubPanel *prevPanel = _currentSubPanel;
if (prevPanel && prevPanel->ShouldDisplayPanel())
{
// hide
prevPanel->SetVisible(false);
// push onto history stack
_subPanelStack.AddElement(_currentSubPanel);
}
// reenable all buttons, returning them to their default state
_prevButton->SetEnabled(true);
_nextButton->SetEnabled(true);
_cancelButton->SetEnabled(true);
_finishButton->SetEnabled(true);
if ( _showButtons )
{
_prevButton->SetVisible(true);
_cancelButton->SetVisible(true);
}
// set up new subpanel
_currentSubPanel = subPanel;
_currentSubPanel->SetParent(this);
_currentSubPanel->SetVisible(true);
_currentSubPanel->SetWizardPanel(this);
_currentSubPanel->OnDisplayAsNext();
_currentSubPanel->OnDisplay();
_currentSubPanel->InvalidateLayout(false);
SETUP_PANEL( _currentSubPanel );
int wide, tall;
if ( _currentSubPanel->GetDesiredSize(wide, tall) )
{
SetSize(wide, tall);
}
if (!prevPanel)
{
// no previous panel, so disable the back button
_prevButton->SetEnabled(false);
}
_currentSubPanel->RequestFocus();
RecalculateTabOrdering();
InvalidateLayout(false);
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: Pops the last panel off the stack and runs it
//-----------------------------------------------------------------------------
void WizardPanel::ActivatePrevSubPanel()
{
_currentSubPanel->SetVisible(false);
WizardSubPanel *prevPanel = NULL;
if (_subPanelStack.GetCount())
{
// check to see if we need to jump back to a previous sub panel
WizardSubPanel *searchPanel = _currentSubPanel->GetPrevSubPanel();
if (searchPanel && _subPanelStack.HasElement(searchPanel))
{
// keep poping the stack till we find it
while (_subPanelStack.GetCount() && prevPanel != searchPanel)
{
prevPanel = _subPanelStack[_subPanelStack.GetCount() - 1];
_subPanelStack.RemoveElementAt(_subPanelStack.GetCount() - 1);
}
}
else
{
// just get the last one
prevPanel = _subPanelStack[_subPanelStack.GetCount() - 1];
_subPanelStack.RemoveElementAt(_subPanelStack.GetCount() - 1);
}
}
if (!prevPanel)
{
ivgui()->DPrintf2("Error: WizardPanel::ActivatePrevSubPanel(): no previous panel to go back to\n");
return;
}
// hide old panel
_currentSubPanel->SetVisible(false);
// reenable all buttons, returning them to their default state
_prevButton->SetEnabled(true);
_nextButton->SetEnabled(true);
_cancelButton->SetEnabled(true);
_finishButton->SetEnabled(true);
// Activate new panel
_currentSubPanel = prevPanel;
_currentSubPanel->RequestFocus();
_currentSubPanel->SetWizardPanel(this);
_currentSubPanel->OnDisplayAsPrev();
_currentSubPanel->OnDisplay();
_currentSubPanel->InvalidateLayout(false);
SETUP_PANEL( _currentSubPanel );
int wide, tall;
if ( _currentSubPanel->GetDesiredSize(wide, tall) )
{
SetSize(wide, tall);
}
// show the previous panel, but don't Activate it (since it should show just what it was previously)
_currentSubPanel->SetVisible(true);
if (!_subPanelStack.GetCount())
{
// no previous panel, so disable the back button
_prevButton->SetEnabled(false);
}
RecalculateTabOrdering();
InvalidateLayout(false);
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: Sets up the new tab ordering
//-----------------------------------------------------------------------------
void WizardPanel::RecalculateTabOrdering()
{
if (_currentSubPanel)
{
_currentSubPanel->SetTabPosition(1);
}
_prevButton->SetTabPosition(2);
_nextButton->SetTabPosition(3);
_finishButton->SetTabPosition(4);
_cancelButton->SetTabPosition(5);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::SetNextButtonEnabled(bool state)
{
if (_nextButton->IsEnabled() != state)
{
_nextButton->SetEnabled(state);
InvalidateLayout(false);
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::SetPrevButtonEnabled(bool state)
{
if (_prevButton->IsEnabled() != state)
{
_prevButton->SetEnabled(state);
InvalidateLayout(false);
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::SetFinishButtonEnabled(bool state)
{
if (_finishButton->IsEnabled() != state)
{
_finishButton->SetEnabled(state);
InvalidateLayout(false);
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::SetCancelButtonEnabled(bool state)
{
if (_cancelButton->IsEnabled() != state)
{
_cancelButton->SetEnabled(state);
InvalidateLayout(false);
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::SetNextButtonVisible(bool state)
{
_nextButton->SetVisible(state);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::SetPrevButtonVisible(bool state)
{
_prevButton->SetVisible(state);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::SetFinishButtonVisible(bool state)
{
_finishButton->SetVisible(state);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::SetCancelButtonVisible(bool state)
{
_cancelButton->SetVisible(state);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::SetNextButtonText(const char *text)
{
if (text)
{
_nextButton->SetText(text);
}
else
{
_nextButton->SetText("#WizardPanel_Next");
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::SetPrevButtonText(const char *text)
{
if (text)
{
_prevButton->SetText(text);
}
else
{
_prevButton->SetText("#WizardPanel_Back");
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::SetFinishButtonText(const char *text)
{
if (text)
{
_finishButton->SetText(text);
}
else
{
_finishButton->SetText("#WizardPanel_Finish");
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::SetCancelButtonText(const char *text)
{
if (text)
{
_cancelButton->SetText(text);
}
else
{
_cancelButton->SetText("#WizardPanel_Cancel");
}
}
//-----------------------------------------------------------------------------
// Purpose: Finds the next panel that wants to be shown
//-----------------------------------------------------------------------------
WizardSubPanel *WizardPanel::FindNextValidSubPanel(WizardSubPanel *currentPanel)
{
// skip over sub panels if they don't want to be displayed
while (currentPanel)
{
currentPanel->SetWizardPanel(this);
if (currentPanel->ShouldDisplayPanel())
break;
// ok the panel wants to be skipped, so skip ahead
currentPanel = currentPanel->GetNextSubPanel();
}
return currentPanel;
}
//-----------------------------------------------------------------------------
// Purpose: Advances to the next panel
//-----------------------------------------------------------------------------
void WizardPanel::OnNextButton()
{
if (_currentSubPanel)
{
bool shouldAdvance = _currentSubPanel->OnNextButton();
if (shouldAdvance)
{
WizardSubPanel *nextPanel = FindNextValidSubPanel(_currentSubPanel->GetNextSubPanel());
if (nextPanel)
{
KeyValues *kv = new KeyValues("ActivateNextSubPanel");
kv->SetPtr("panel", nextPanel);
ivgui()->PostMessage(GetVPanel(), kv, GetVPanel());
}
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Retreats to the previous panel
//-----------------------------------------------------------------------------
void WizardPanel::OnPrevButton()
{
bool shouldRetreat = true;
if (_currentSubPanel)
{
shouldRetreat = _currentSubPanel->OnPrevButton();
}
if (shouldRetreat)
{
ActivatePrevSubPanel();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::OnFinishButton()
{
if (_currentSubPanel && _currentSubPanel->OnFinishButton())
{
// hide ourselves away
BaseClass::OnClose();
// automatically delete ourselves if marked to do so
if (IsAutoDeleteSet())
{
MarkForDeletion();
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardPanel::OnCancelButton()
{
if (_currentSubPanel && _currentSubPanel->OnCancelButton())
{
// hide ourselves away
BaseClass::OnClose();
if (IsAutoDeleteSet())
{
MarkForDeletion();
}
}
}
//-----------------------------------------------------------------------------
// Purpose: command handler for catching escape key presses
//-----------------------------------------------------------------------------
void WizardPanel::OnCommand(const char *command)
{
if (!stricmp(command, "Cancel"))
{
if (_cancelButton->IsEnabled())
{
_cancelButton->DoClick();
}
}
else
{
BaseClass::OnCommand(command);
}
}
//-----------------------------------------------------------------------------
// Purpose: Maps close button to cancel button
//-----------------------------------------------------------------------------
void WizardPanel::OnClose()
{
if (_cancelButton->IsEnabled())
{
_cancelButton->DoClick();
}
else if (_finishButton->IsEnabled())
{
_finishButton->DoClick();
}
// don't chain back
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
KeyValues *WizardPanel::GetWizardData()
{
return _currentData;
}
//-----------------------------------------------------------------------------
// Purpose: whether to show the next,prev,finish and cancel buttons
//-----------------------------------------------------------------------------
void WizardPanel::ShowButtons(bool state)
{
_showButtons = state; // hide the wizard panel buttons
SetNextButtonVisible( state );
SetPrevButtonVisible( state );
SetFinishButtonVisible( state );
SetCancelButtonVisible( state );
}
//-----------------------------------------------------------------------------
// Purpose: filters close buttons
//-----------------------------------------------------------------------------
void WizardPanel::OnCloseFrameButtonPressed()
{
// only allow close if the cancel button is enabled
if (_cancelButton->IsEnabled())
{
BaseClass::OnCloseFrameButtonPressed();
}
}
//-----------------------------------------------------------------------------
// Purpose: returns a page by name
//-----------------------------------------------------------------------------
WizardSubPanel *WizardPanel::GetSubPanelByName(const char *pageName)
{
return dynamic_cast<WizardSubPanel *>(FindChildByName(pageName));
}

View File

@ -0,0 +1,114 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "vgui_controls/WizardPanel.h"
#include "vgui_controls/WizardSubPanel.h"
#include "vgui_controls/BuildGroup.h"
#include "KeyValues.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
#include <stdio.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
WizardSubPanel::WizardSubPanel(Panel *parent, const char *panelName) : EditablePanel(parent, panelName), _wizardPanel(NULL)
{
SetVisible(false);
m_iDesiredWide = 0;
m_iDesiredTall = 0;
SetBuildGroup(GetBuildGroup());
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
WizardSubPanel::~WizardSubPanel()
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardSubPanel::ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
SetBgColor(GetSchemeColor("WizardSubPanel.BgColor",pScheme));
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardSubPanel::GetSettings( KeyValues *outResourceData )
{
BaseClass::GetSettings(outResourceData);
outResourceData->SetInt("WizardWide", m_iDesiredWide);
outResourceData->SetInt("WizardTall", m_iDesiredTall);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void WizardSubPanel::ApplySettings(KeyValues *inResourceData)
{
// don't adjust visiblity during settings application (since it's our parent who really controls it)
bool bVisible = IsVisible();
BaseClass::ApplySettings(inResourceData);
m_iDesiredWide = inResourceData->GetInt("WizardWide", 0);
m_iDesiredTall = inResourceData->GetInt("WizardTall", 0);
if (GetWizardPanel() && m_iDesiredWide && m_iDesiredTall)
{
GetWizardPanel()->SetSize(m_iDesiredWide, m_iDesiredTall);
}
SetVisible(bVisible);
}
//-----------------------------------------------------------------------------
// Purpose: build mode description
//-----------------------------------------------------------------------------
const char *WizardSubPanel::GetDescription()
{
static char buf[1024];
_snprintf(buf, sizeof(buf), "%s, int WizardWide, int WizardTall", BaseClass::GetDescription());
return buf;
}
//-----------------------------------------------------------------------------
// Purpose: gets the size this subpanel would like the wizard to be
//-----------------------------------------------------------------------------
bool WizardSubPanel::GetDesiredSize(int &wide, int &tall)
{
wide = m_iDesiredWide;
tall = m_iDesiredTall;
return (m_iDesiredWide && m_iDesiredTall);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
KeyValues *WizardSubPanel::GetWizardData()
{
return GetWizardPanel()->GetWizardData();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
WizardSubPanel *WizardSubPanel::GetSiblingSubPanelByName(const char *pageName)
{
return GetWizardPanel()->GetSubPanelByName(pageName);
}

175
vgui2/controls/controls.cpp Normal file
View File

@ -0,0 +1,175 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <FileSystem.h>
#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <vgui/IInput.h>
#include <vgui/ILocalize.h>
#include <vgui/IPanel.h>
#include <vgui/IScheme.h>
#include <vgui/ISurface.h>
#include <vgui/ISystem.h>
#include <vgui/IVGui.h>
#include <vgui_controls/Controls.h>
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
namespace vgui
{
vgui::IInput *g_pInputInterface = NULL;
vgui::IInput *input()
{
return g_pInputInterface;
}
vgui::ISchemeManager *g_pSchemeInterface = NULL;
vgui::ISchemeManager *scheme()
{
return g_pSchemeInterface;
}
vgui::ISurface *g_pSurfaceInterface = NULL;
vgui::ISurface *surface()
{
return g_pSurfaceInterface;
}
vgui::ISystem *g_pSystemInterface = NULL;
vgui::ISystem *system()
{
return g_pSystemInterface;
}
vgui::IVGui *g_pVGuiInterface = NULL;
vgui::IVGui *ivgui()
{
return g_pVGuiInterface;
}
vgui::IPanel *g_pPanelInterface = NULL;
vgui::IPanel *ipanel()
{
return g_pPanelInterface;
}
IFileSystem *g_pFileSystemInterface = NULL;
IFileSystem *filesystem()
{
Assert( g_pFileSystemInterface );
return g_pFileSystemInterface;
}
vgui::ILocalize *g_pLocalizeInterface = NULL;
vgui::ILocalize *localize()
{
return g_pLocalizeInterface;
}
//-----------------------------------------------------------------------------
// Purpose: finds a particular interface in the factory set
//-----------------------------------------------------------------------------
static void *InitializeInterface( char const *interfaceName, CreateInterfaceFn *factoryList, int numFactories )
{
void *retval;
for ( int i = 0; i < numFactories; i++ )
{
CreateInterfaceFn factory = factoryList[ i ];
if ( !factory )
continue;
retval = factory( interfaceName, NULL );
if ( retval )
return retval;
}
// No provider for requested interface!!!
// Assert( !"No provider for requested interface!!!" );
return NULL;
}
static char g_szControlsModuleName[256];
//-----------------------------------------------------------------------------
// Purpose: Initializes the controls
//-----------------------------------------------------------------------------
extern "C" { extern int _heapmin(); }
bool VGui_InitInterfacesList( const char *moduleName, CreateInterfaceFn *factoryList, int numFactories )
{
// If you hit this error, then you need to include memoverride.cpp in the project somewhere or else
// you'll get crashes later when vgui_controls allocates KeyValues and vgui tries to delete them.
#if !defined(NO_MALLOC_OVERRIDE)
#ifndef _XBOX
if ( _heapmin() != 1 )
{
Assert( false );
Error( "Must include memoverride.cpp in your project." );
}
#endif
#endif
// keep a record of this module name
strncpy(g_szControlsModuleName, moduleName, sizeof(g_szControlsModuleName));
g_szControlsModuleName[sizeof(g_szControlsModuleName) - 1] = 0;
// initialize our locale (must be done for every vgui dll/exe)
// "" makes it use the default locale, required to make iswprint() work correctly in different languages
setlocale(LC_CTYPE, "");
setlocale(LC_TIME, "");
setlocale(LC_COLLATE, "");
setlocale(LC_MONETARY, "");
g_pVGuiInterface = (IVGui *)InitializeInterface( VGUI_IVGUI_INTERFACE_VERSION, factoryList, numFactories );
g_pPanelInterface = (IPanel *)InitializeInterface( VGUI_PANEL_INTERFACE_VERSION, factoryList, numFactories );
g_pSurfaceInterface = (ISurface *)InitializeInterface( VGUI_SURFACE_INTERFACE_VERSION, factoryList, numFactories );
g_pSchemeInterface = (ISchemeManager *)InitializeInterface( VGUI_SCHEME_INTERFACE_VERSION, factoryList, numFactories );
g_pSystemInterface = (ISystem *)InitializeInterface( VGUI_SYSTEM_INTERFACE_VERSION, factoryList, numFactories );
g_pInputInterface = (IInput *)InitializeInterface( VGUI_INPUT_INTERFACE_VERSION, factoryList, numFactories );
g_pLocalizeInterface = (ILocalize *)InitializeInterface( VGUI_LOCALIZE_INTERFACE_VERSION, factoryList, numFactories );
g_pFileSystemInterface = (IFileSystem *)InitializeInterface( FILESYSTEM_INTERFACE_VERSION, factoryList, numFactories );
if (!g_pVGuiInterface)
return false;
g_pVGuiInterface->Init( factoryList, numFactories );
if ( g_pSchemeInterface &&
g_pSurfaceInterface &&
g_pSystemInterface &&
g_pInputInterface &&
g_pVGuiInterface &&
g_pFileSystemInterface &&
g_pLocalizeInterface &&
g_pPanelInterface)
return true;
return false;
}
//-----------------------------------------------------------------------------
// Purpose: returns the name of the module this has been compiled into
//-----------------------------------------------------------------------------
const char *GetControlsModuleName()
{
return g_szControlsModuleName;
}
} // namespace vgui

View File

@ -0,0 +1,565 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="vgui_controls"
ProjectGUID="{C3CEFD6F-5CDC-41DE-8D43-D932F508F51B}"
SccProjectName=""
SccAuxPath=""
SccLocalPath=""
SccProvider="">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="4"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
OptimizeForProcessor="3"
AdditionalIncludeDirectories="..\..\public,..\..\public\tier1"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
ExceptionHandling="FALSE"
BasicRuntimeChecks="3"
SmallerTypeCheck="FALSE"
RuntimeLibrary="1"
EnableFunctionLevelLinking="TRUE"
TreatWChar_tAsBuiltInType="FALSE"
ForceConformanceInForLoopScope="FALSE"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/vgui_controls.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
WarningLevel="4"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="..\..\lib-vc7\public\vgui_controls.lib"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"
Description="Making ..\..\lib-vc7\public\vgui_controls.lib writeable"
CommandLine="if exist ..\..\lib-vc7\public\vgui_controls.lib attrib -r ..\..\lib-vc7\public\vgui_controls.lib"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="4"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2"
WholeProgramOptimization="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="TRUE"
ImproveFloatingPointConsistency="FALSE"
FavorSizeOrSpeed="1"
OmitFramePointers="FALSE"
OptimizeForProcessor="3"
AdditionalIncludeDirectories="..\..\public,..\..\public\tier1"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
StringPooling="TRUE"
ExceptionHandling="FALSE"
RuntimeLibrary="0"
BufferSecurityCheck="FALSE"
EnableFunctionLevelLinking="FALSE"
TreatWChar_tAsBuiltInType="FALSE"
ForceConformanceInForLoopScope="FALSE"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/vgui_controls.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
BrowseInformation="1"
WarningLevel="4"
SuppressStartupBanner="TRUE"
DebugInformationFormat="2"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="..\..\lib-vc7\public\vgui_controls.lib"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"
Description="Making ..\..\lib-vc7\public\vgui_controls.lib writable..."
CommandLine="if exist ..\..\lib-vc7\public\vgui_controls.lib attrib -r ..\..\lib-vc7\public\vgui_controls.lib"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath="..\..\public\vgui_controls\AnimatingImagePanel.h">
</File>
<File
RelativePath="..\..\Public\vgui_controls\AnimationController.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\BitmapImagePanel.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\BuildGroup.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\BuildModeDialog.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\Button.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\CheckButton.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\CheckButtonList.h">
</File>
<File
RelativePath="..\..\public\vgui\Color.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\ComboBox.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\Controls.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\DialogManager.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\DirectorySelectDialog.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\Divider.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\EditablePanel.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\ExpandButton.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\FileOpenDialog.h">
</File>
<File
RelativePath="..\..\Public\FileSystem.h">
</File>
<File
RelativePath="..\..\public\filesystem_helpers.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\FocusNavGroup.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\Frame.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\GraphPanel.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\HTML.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\Image.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\ImageList.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\ImagePanel.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\InputDialog.h">
</File>
<File
RelativePath="..\..\public\tier1\interface.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\KeyBindingHelpDialog.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\KeyBindingMap.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\KeyBoardEditorDialog.h">
</File>
<File
RelativePath="..\..\public\tier1\KeyValues.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\Label.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\ListPanel.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\ListViewPanel.h">
</File>
<File
RelativePath="..\..\public\tier0\memdbgoff.h">
</File>
<File
RelativePath="..\..\public\tier0\memdbgon.h">
</File>
<File
RelativePath="..\..\public\tier1\mempool.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\Menu.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\MenuBar.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\MenuButton.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\MenuItem.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\MessageBox.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\Panel.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\PanelAnimationVar.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\PanelListPanel.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\PHandle.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\ProgressBar.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\ProgressBox.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\PropertyDialog.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\PropertyPage.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\PropertySheet.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\QueryBox.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\RadioButton.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\RichText.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\ScrollBar.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\ScrollBarSlider.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\SectionedListPanel.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\Slider.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\Splitter.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\TextEntry.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\TextImage.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\ToggleButton.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\Tooltip.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\ToolWindow.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\TreeView.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\TreeViewListControl.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\URLLabel.h">
</File>
<File
RelativePath="..\..\public\tier1\utlmemory.h">
</File>
<File
RelativePath="..\..\public\tier1\utlrbtree.h">
</File>
<File
RelativePath="..\..\public\tier1\utlvector.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\WizardPanel.h">
</File>
<File
RelativePath="..\..\public\vgui_controls\WizardSubPanel.h">
</File>
</Filter>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath="AnimatingImagePanel.cpp">
</File>
<File
RelativePath="AnimationController.cpp">
</File>
<File
RelativePath="BitmapImagePanel.cpp">
</File>
<File
RelativePath=".\BuildFactoryHelper.cpp">
</File>
<File
RelativePath="BuildGroup.cpp">
</File>
<File
RelativePath="BuildModeDialog.cpp">
</File>
<File
RelativePath="Button.cpp">
</File>
<File
RelativePath="CheckButton.cpp">
</File>
<File
RelativePath="CheckButtonList.cpp">
</File>
<File
RelativePath="ComboBox.cpp">
</File>
<File
RelativePath="controls.cpp">
</File>
<File
RelativePath="DirectorySelectDialog.cpp">
</File>
<File
RelativePath="Divider.cpp">
</File>
<File
RelativePath="EditablePanel.cpp">
</File>
<File
RelativePath=".\ExpandButton.cpp">
</File>
<File
RelativePath="FileOpenDialog.cpp">
</File>
<File
RelativePath="..\..\Public\filesystem_helpers.cpp">
</File>
<File
RelativePath="FocusNavGroup.cpp">
</File>
<File
RelativePath="Frame.cpp">
</File>
<File
RelativePath="GraphPanel.cpp">
</File>
<File
RelativePath="HTML.cpp">
</File>
<File
RelativePath="Image.cpp">
</File>
<File
RelativePath="ImageList.cpp">
</File>
<File
RelativePath="ImagePanel.cpp">
</File>
<File
RelativePath=".\InputDialog.cpp">
</File>
<File
RelativePath=".\KeyBindingHelpDialog.cpp">
</File>
<File
RelativePath=".\KeyBoardEditorDialog.cpp">
</File>
<File
RelativePath="Label.cpp">
</File>
<File
RelativePath="ListPanel.cpp">
</File>
<File
RelativePath="ListViewPanel.cpp">
</File>
<File
RelativePath="Menu.cpp">
</File>
<File
RelativePath="MenuBar.cpp">
</File>
<File
RelativePath="MenuButton.cpp">
</File>
<File
RelativePath="MenuItem.cpp">
</File>
<File
RelativePath="MessageBox.cpp">
</File>
<File
RelativePath="Panel.cpp">
</File>
<File
RelativePath="PanelListPanel.cpp">
</File>
<File
RelativePath="ProgressBar.cpp">
</File>
<File
RelativePath="ProgressBox.cpp">
</File>
<File
RelativePath="PropertyDialog.cpp">
</File>
<File
RelativePath="PropertyPage.cpp">
</File>
<File
RelativePath="PropertySheet.cpp">
</File>
<File
RelativePath="QueryBox.cpp">
</File>
<File
RelativePath="RadioButton.cpp">
</File>
<File
RelativePath="RichText.cpp">
</File>
<File
RelativePath="ScrollBar.cpp">
</File>
<File
RelativePath="ScrollBarSlider.cpp">
</File>
<File
RelativePath="SectionedListPanel.cpp">
</File>
<File
RelativePath="Slider.cpp">
</File>
<File
RelativePath=".\Splitter.cpp">
</File>
<File
RelativePath="TextEntry.cpp">
</File>
<File
RelativePath="TextImage.cpp">
</File>
<File
RelativePath="ToggleButton.cpp">
</File>
<File
RelativePath="Tooltip.cpp">
</File>
<File
RelativePath=".\ToolWindow.cpp">
</File>
<File
RelativePath="TreeView.cpp">
</File>
<File
RelativePath="TreeViewListControl.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
GeneratePreprocessedFile="0"/>
</FileConfiguration>
</File>
<File
RelativePath="URLLabel.cpp">
</File>
<File
RelativePath="WizardPanel.cpp">
</File>
<File
RelativePath="WizardSubPanel.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,744 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="vgui_controls"
ProjectGUID="{C3CEFD6F-5CDC-41DE-8D43-D932F508F51B}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\public,..\..\public\tier1"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
ExceptionHandling="0"
BasicRuntimeChecks="3"
SmallerTypeCheck="false"
RuntimeLibrary="1"
EnableFunctionLevelLinking="true"
TreatWChar_tAsBuiltInType="true"
ForceConformanceInForLoopScope="false"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/vgui_controls.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
WarningLevel="4"
SuppressStartupBanner="true"
DebugInformationFormat="4"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
Description="Making ..\..\lib\public\vgui_controls.lib writeable"
CommandLine="if exist ..\..\lib\public\vgui_controls.lib attrib -r ..\..\lib\public\vgui_controls.lib"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="..\..\lib\public\vgui_controls.lib"
SuppressStartupBanner="true"
IgnoreDefaultLibraryNames=""
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="false"
AdditionalIncludeDirectories="..\..\public,..\..\public\tier1"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
StringPooling="true"
ExceptionHandling="0"
RuntimeLibrary="0"
BufferSecurityCheck="false"
EnableFunctionLevelLinking="false"
TreatWChar_tAsBuiltInType="true"
ForceConformanceInForLoopScope="false"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/vgui_controls.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
BrowseInformation="1"
WarningLevel="4"
SuppressStartupBanner="true"
DebugInformationFormat="1"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
Description="Making ..\..\lib\public\vgui_controls.lib writable..."
CommandLine="if exist ..\..\lib\public\vgui_controls.lib attrib -r ..\..\lib\public\vgui_controls.lib"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="..\..\lib\public\vgui_controls.lib"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
>
<File
RelativePath="..\..\public\vgui_controls\AnimatingImagePanel.h"
>
</File>
<File
RelativePath="..\..\Public\vgui_controls\AnimationController.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\BitmapImagePanel.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\BuildGroup.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\BuildModeDialog.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\Button.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\CheckButton.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\CheckButtonList.h"
>
</File>
<File
RelativePath="..\..\public\vgui\Color.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\ComboBox.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\Controls.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\DialogManager.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\DirectorySelectDialog.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\Divider.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\EditablePanel.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\ExpandButton.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\FileOpenDialog.h"
>
</File>
<File
RelativePath="..\..\Public\FileSystem.h"
>
</File>
<File
RelativePath="..\..\public\filesystem_helpers.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\FocusNavGroup.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\Frame.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\GraphPanel.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\HTML.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\Image.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\ImageList.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\ImagePanel.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\InputDialog.h"
>
</File>
<File
RelativePath="..\..\public\tier1\interface.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\KeyBindingHelpDialog.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\KeyBindingMap.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\KeyBoardEditorDialog.h"
>
</File>
<File
RelativePath="..\..\public\tier1\KeyValues.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\Label.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\ListPanel.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\ListViewPanel.h"
>
</File>
<File
RelativePath="..\..\public\tier0\memdbgoff.h"
>
</File>
<File
RelativePath="..\..\public\tier0\memdbgon.h"
>
</File>
<File
RelativePath="..\..\public\tier1\mempool.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\Menu.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\MenuBar.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\MenuButton.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\MenuItem.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\MessageBox.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\Panel.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\PanelAnimationVar.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\PanelListPanel.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\PHandle.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\ProgressBar.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\ProgressBox.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\PropertyDialog.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\PropertyPage.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\PropertySheet.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\QueryBox.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\RadioButton.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\RichText.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\ScrollBar.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\ScrollBarSlider.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\SectionedListPanel.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\Slider.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\Splitter.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\TextEntry.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\TextImage.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\ToggleButton.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\Tooltip.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\ToolWindow.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\TreeView.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\TreeViewListControl.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\URLLabel.h"
>
</File>
<File
RelativePath="..\..\public\tier1\utlmemory.h"
>
</File>
<File
RelativePath="..\..\public\tier1\utlrbtree.h"
>
</File>
<File
RelativePath="..\..\public\tier1\utlvector.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\WizardPanel.h"
>
</File>
<File
RelativePath="..\..\public\vgui_controls\WizardSubPanel.h"
>
</File>
</Filter>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="AnimatingImagePanel.cpp"
>
</File>
<File
RelativePath="AnimationController.cpp"
>
</File>
<File
RelativePath="BitmapImagePanel.cpp"
>
</File>
<File
RelativePath=".\BuildFactoryHelper.cpp"
>
</File>
<File
RelativePath="BuildGroup.cpp"
>
</File>
<File
RelativePath="BuildModeDialog.cpp"
>
</File>
<File
RelativePath="Button.cpp"
>
</File>
<File
RelativePath="CheckButton.cpp"
>
</File>
<File
RelativePath="CheckButtonList.cpp"
>
</File>
<File
RelativePath="ComboBox.cpp"
>
</File>
<File
RelativePath="controls.cpp"
>
</File>
<File
RelativePath="DirectorySelectDialog.cpp"
>
</File>
<File
RelativePath="Divider.cpp"
>
</File>
<File
RelativePath="EditablePanel.cpp"
>
</File>
<File
RelativePath=".\ExpandButton.cpp"
>
</File>
<File
RelativePath="FileOpenDialog.cpp"
>
</File>
<File
RelativePath="..\..\Public\filesystem_helpers.cpp"
>
</File>
<File
RelativePath="FocusNavGroup.cpp"
>
</File>
<File
RelativePath="Frame.cpp"
>
</File>
<File
RelativePath="GraphPanel.cpp"
>
</File>
<File
RelativePath="HTML.cpp"
>
</File>
<File
RelativePath="Image.cpp"
>
</File>
<File
RelativePath="ImageList.cpp"
>
</File>
<File
RelativePath="ImagePanel.cpp"
>
</File>
<File
RelativePath=".\InputDialog.cpp"
>
</File>
<File
RelativePath=".\KeyBindingHelpDialog.cpp"
>
</File>
<File
RelativePath=".\KeyBoardEditorDialog.cpp"
>
</File>
<File
RelativePath="Label.cpp"
>
</File>
<File
RelativePath="ListPanel.cpp"
>
</File>
<File
RelativePath="ListViewPanel.cpp"
>
</File>
<File
RelativePath="Menu.cpp"
>
</File>
<File
RelativePath="MenuBar.cpp"
>
</File>
<File
RelativePath="MenuButton.cpp"
>
</File>
<File
RelativePath="MenuItem.cpp"
>
</File>
<File
RelativePath="MessageBox.cpp"
>
</File>
<File
RelativePath="Panel.cpp"
>
</File>
<File
RelativePath="PanelListPanel.cpp"
>
</File>
<File
RelativePath="ProgressBar.cpp"
>
</File>
<File
RelativePath="ProgressBox.cpp"
>
</File>
<File
RelativePath="PropertyDialog.cpp"
>
</File>
<File
RelativePath="PropertyPage.cpp"
>
</File>
<File
RelativePath="PropertySheet.cpp"
>
</File>
<File
RelativePath="QueryBox.cpp"
>
</File>
<File
RelativePath="RadioButton.cpp"
>
</File>
<File
RelativePath="RichText.cpp"
>
</File>
<File
RelativePath="ScrollBar.cpp"
>
</File>
<File
RelativePath="ScrollBarSlider.cpp"
>
</File>
<File
RelativePath="SectionedListPanel.cpp"
>
</File>
<File
RelativePath="Slider.cpp"
>
</File>
<File
RelativePath=".\Splitter.cpp"
>
</File>
<File
RelativePath="TextEntry.cpp"
>
</File>
<File
RelativePath="TextImage.cpp"
>
</File>
<File
RelativePath="ToggleButton.cpp"
>
</File>
<File
RelativePath="Tooltip.cpp"
>
</File>
<File
RelativePath=".\ToolWindow.cpp"
>
</File>
<File
RelativePath="TreeView.cpp"
>
</File>
<File
RelativePath="TreeViewListControl.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
GeneratePreprocessedFile="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="URLLabel.cpp"
>
</File>
<File
RelativePath="WizardPanel.cpp"
>
</File>
<File
RelativePath="WizardSubPanel.cpp"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,805 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="vgui_controls"
ProjectGUID="{CA5D3BC1-934A-4702-AE64-4620B7C75F0D}"
SccProjectName=""
SccAuxPath=""
SccLocalPath=""
SccProvider=""
Keyword="XboxProj">
<Platforms>
<Platform
Name="Xbox"/>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Xbox"
OutputDirectory="Debug_XBox"
IntermediateDirectory="Debug_XBox"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
OptimizeForProcessor="2"
AdditionalIncludeDirectories="..\..\public,..\..\public\tier1,..\..\common"
PreprocessorDefinitions="_WIN32;_DEBUG;_MBCS;_LIB;_XBOX;_STATIC_LINKED;_SUBSYSTEM=VguiControls"
StringPooling="TRUE"
MinimalRebuild="TRUE"
ExceptionHandling="FALSE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
EnableEnhancedInstructionSet="1"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"
ForcedIncludeFiles="staticlink/system.h;xbox/xbox_isswappable.h"/>
<Tool
Name="VCCustomBuildTool"
CommandLine="if exist ..\..\lib_xbox\public\vgui_controls_xbox.lib attrib -r ..\..\lib_xbox\public\vgui_controls_xbox.lib
if exist $(TargetPath) copy $(TargetPath) ..\..\lib_xbox\public\vgui_controls_xbox.lib"
Outputs="..\..\lib_xbox\public\vgui_controls_xbox.lib"/>
<Tool
Name="VCLibrarianTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"
CommandLine="if exist ..\..\lib_xbox\public\vgui_controls_xbox.lib del ..\..\lib_xbox\public\vgui_controls_xbox.lib"/>
<Tool
Name="VCPreLinkEventTool"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
OptimizeForProcessor="2"
AdditionalIncludeDirectories="..\..\public,..\..\public\tier1,..\..\common"
PreprocessorDefinitions="_WIN32;_DEBUG;_MBCS;_LIB;_STATIC_LINKED;_SUBSYSTEM=VguiControls"
StringPooling="TRUE"
MinimalRebuild="TRUE"
ExceptionHandling="FALSE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
EnableEnhancedInstructionSet="1"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"
ForcedIncludeFiles="staticlink/system.h"/>
<Tool
Name="VCCustomBuildTool"
CommandLine="if exist ..\..\lib_xbox\public\vgui_controls_xbox.lib attrib -r ..\..\lib_xbox\public\vgui_controls_xbox.lib
if exist $(TargetPath) copy $(TargetPath) ..\..\lib_xbox\public\vgui_controls_xbox.lib"
Outputs="..\..\lib_xbox\public\vgui_controls_xbox.lib"/>
<Tool
Name="VCLibrarianTool"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"
CommandLine="if exist ..\..\lib_xbox\public\vgui_controls_xbox.lib del ..\..\lib_xbox\public\vgui_controls_xbox.lib"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Profile|Xbox"
OutputDirectory="Profile"
IntermediateDirectory="Profile"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="3"
OmitFramePointers="TRUE"
OptimizeForProcessor="2"
PreprocessorDefinitions="NDEBUG;_XBOX;PROFILE"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
EnableEnhancedInstructionSet="1"
UsePrecompiledHeader="3"
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="xapilib.lib d3d8i.lib d3dx8.lib xgraphics.lib dsound.lib dmusici.lib xactengi.lib xsndtrk.lib xvoice.lib xonlines.lib xboxkrnl.lib xbdm.lib xperf.lib"
OutputFile="$(OutDir)/$(ProjectName).exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
OptimizeForWindows98="1"
SetChecksum="TRUE"
TargetMachine="1"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="XboxDeploymentTool"/>
<Tool
Name="XboxImageTool"
StackSize="65536"
IncludeDebugInfo="TRUE"
NoLibWarn="TRUE"/>
</Configuration>
<Configuration
Name="Profile|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="3"
OmitFramePointers="TRUE"
OptimizeForProcessor="2"
PreprocessorDefinitions="NDEBUG;_XBOX;PROFILE"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
EnableEnhancedInstructionSet="1"
UsePrecompiledHeader="3"
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="xapilib.lib d3d8i.lib d3dx8.lib xgraphics.lib dsound.lib dmusici.lib xactengi.lib xsndtrk.lib xvoice.lib xonlines.lib xboxkrnl.lib xbdm.lib xperf.lib"
OutputFile="$(OutDir)/$(ProjectName).exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
OptimizeForWindows98="1"
SetChecksum="TRUE"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Profile_FastCap|Xbox"
OutputDirectory="Profile_FastCap"
IntermediateDirectory="Profile_FastCap"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="3"
OmitFramePointers="TRUE"
OptimizeForProcessor="2"
PreprocessorDefinitions="NDEBUG;_XBOX;PROFILE;FASTCAP"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
EnableEnhancedInstructionSet="1"
UsePrecompiledHeader="3"
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"
FastCAP="TRUE"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="xapilib.lib d3d8i.lib d3dx8.lib xgraphics.lib dsound.lib dmusici.lib xactengi.lib xsndtrk.lib xvoice.lib xonlines.lib xboxkrnl.lib xbdm.lib xperf.lib"
OutputFile="$(OutDir)/$(ProjectName).exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
OptimizeForWindows98="1"
SetChecksum="TRUE"
TargetMachine="1"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="XboxDeploymentTool"/>
<Tool
Name="XboxImageTool"
StackSize="65536"
IncludeDebugInfo="TRUE"
NoLibWarn="TRUE"/>
</Configuration>
<Configuration
Name="Profile_FastCap|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="3"
OmitFramePointers="TRUE"
OptimizeForProcessor="2"
PreprocessorDefinitions="NDEBUG;_XBOX;PROFILE;FASTCAP"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
EnableEnhancedInstructionSet="1"
UsePrecompiledHeader="3"
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"
FastCAP="TRUE"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="xapilib.lib d3d8i.lib d3dx8.lib xgraphics.lib dsound.lib dmusici.lib xactengi.lib xsndtrk.lib xvoice.lib xonlines.lib xboxkrnl.lib xbdm.lib xperf.lib"
OutputFile="$(OutDir)/$(ProjectName).exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
OptimizeForWindows98="1"
SetChecksum="TRUE"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Xbox"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="3"
OmitFramePointers="TRUE"
OptimizeForProcessor="2"
PreprocessorDefinitions="NDEBUG;_XBOX"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
EnableEnhancedInstructionSet="1"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="3"
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="xapilib.lib d3d8.lib d3dx8.lib xgraphics.lib dsound.lib dmusic.lib xacteng.lib xsndtrk.lib xvoice.lib xonlines.lib xboxkrnl.lib"
OutputFile="$(OutDir)/$(ProjectName).exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
OptimizeForWindows98="1"
SetChecksum="TRUE"
TargetMachine="1"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="XboxDeploymentTool"/>
<Tool
Name="XboxImageTool"
StackSize="65536"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="3"
OmitFramePointers="TRUE"
OptimizeForProcessor="2"
PreprocessorDefinitions="NDEBUG;_XBOX"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
EnableEnhancedInstructionSet="1"
UsePrecompiledHeader="3"
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="xapilib.lib d3d8.lib d3dx8.lib xgraphics.lib dsound.lib dmusic.lib xacteng.lib xsndtrk.lib xvoice.lib xonlines.lib xboxkrnl.lib"
OutputFile="$(OutDir)/$(ProjectName).exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
OptimizeForWindows98="1"
SetChecksum="TRUE"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release_LTCG|Xbox"
OutputDirectory="Release_LTCG"
IntermediateDirectory="Release_LTCG"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="TRUE">
<Tool
Name="VCCLCompilerTool"
Optimization="3"
OmitFramePointers="TRUE"
OptimizeForProcessor="2"
PreprocessorDefinitions="NDEBUG;_XBOX;LTCG"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
EnableEnhancedInstructionSet="1"
UsePrecompiledHeader="3"
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="xapilib.lib d3d8ltcg.lib d3dx8.lib xgraphicsltcg.lib dsound.lib dmusicltcg.lib xactengltcg.lib xsndtrk.lib xvoice.lib xonlines.lib xboxkrnl.lib"
OutputFile="$(OutDir)/$(ProjectName).exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
OptimizeForWindows98="1"
SetChecksum="TRUE"
TargetMachine="1"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="XboxDeploymentTool"/>
<Tool
Name="XboxImageTool"
StackSize="65536"/>
</Configuration>
<Configuration
Name="Release_LTCG|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="TRUE">
<Tool
Name="VCCLCompilerTool"
Optimization="3"
OmitFramePointers="TRUE"
OptimizeForProcessor="2"
PreprocessorDefinitions="NDEBUG;_XBOX;LTCG"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
EnableEnhancedInstructionSet="1"
UsePrecompiledHeader="3"
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="xapilib.lib d3d8ltcg.lib d3dx8.lib xgraphicsltcg.lib dsound.lib dmusicltcg.lib xactengltcg.lib xsndtrk.lib xvoice.lib xonlines.lib xboxkrnl.lib"
OutputFile="$(OutDir)/$(ProjectName).exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
OptimizeForWindows98="1"
SetChecksum="TRUE"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release_XBox|Xbox"
OutputDirectory="Release_XBox"
IntermediateDirectory="Release_XBox"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="1"
FavorSizeOrSpeed="2"
OptimizeForProcessor="2"
AdditionalIncludeDirectories="..\..\public,..\..\public\tier1,..\..\common"
PreprocessorDefinitions="NDEBUG;_RELEASE;_WIN32;_MBCS;_LIB;_XBOX;_STATIC_LINKED;_SUBSYSTEM=VguiControls"
StringPooling="TRUE"
MinimalRebuild="FALSE"
ExceptionHandling="FALSE"
BasicRuntimeChecks="0"
RuntimeLibrary="0"
EnableEnhancedInstructionSet="1"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="2"
ForcedIncludeFiles="staticlink/system.h;xbox/xbox_isswappable.h"/>
<Tool
Name="VCCustomBuildTool"
CommandLine="if exist ..\..\lib_xbox\public\vgui_controls_xbox.lib attrib -r ..\..\lib_xbox\public\vgui_controls_xbox.lib
if exist $(TargetPath) copy $(TargetPath) ..\..\lib_xbox\public\vgui_controls_xbox.lib"
Outputs="..\..\lib_xbox\public\vgui_controls_xbox.lib"/>
<Tool
Name="VCLibrarianTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"
CommandLine="if exist ..\..\lib_xbox\public\vgui_controls_xbox.lib del ..\..\lib_xbox\public\vgui_controls_xbox.lib"/>
<Tool
Name="VCPreLinkEventTool"/>
</Configuration>
<Configuration
Name="Release_XBox|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="3"
OptimizeForProcessor="2"
AdditionalIncludeDirectories="..\..\public,..\..\public\tier1,..\..\common"
PreprocessorDefinitions="NDEBUG;_WIN32;_MBCS;_LIB;_STATIC_LINKED;_SUBSYSTEM=VguiControls"
StringPooling="TRUE"
MinimalRebuild="FALSE"
ExceptionHandling="FALSE"
BasicRuntimeChecks="0"
RuntimeLibrary="0"
EnableEnhancedInstructionSet="1"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="2"
ForcedIncludeFiles="staticlink/system.h"/>
<Tool
Name="VCCustomBuildTool"
CommandLine="if exist ..\..\lib_xbox\public\vgui_controls_xbox.lib attrib -r ..\..\lib_xbox\public\vgui_controls_xbox.lib
if exist $(TargetPath) copy $(TargetPath) ..\..\lib_xbox\public\vgui_controls_xbox.lib"
Outputs="..\..\lib_xbox\public\vgui_controls_xbox.lib"/>
<Tool
Name="VCLibrarianTool"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"
CommandLine="if exist ..\..\lib_xbox\public\vgui_controls_xbox.lib del ..\..\lib_xbox\public\vgui_controls_xbox.lib"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Retail_XBox|Xbox"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2"
WholeProgramOptimization="FALSE">
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/D &quot;_RETAIL&quot;"
Optimization="1"
GlobalOptimizations="TRUE"
FavorSizeOrSpeed="2"
OmitFramePointers="TRUE"
OptimizeForProcessor="2"
AdditionalIncludeDirectories="..\..\public,..\..\public\tier1,..\..\common"
PreprocessorDefinitions="NDEBUG;_WIN32;_MBCS;_LIB;_XBOX;_STATIC_LINKED;_SUBSYSTEM=VguiControls"
StringPooling="TRUE"
MinimalRebuild="FALSE"
ExceptionHandling="FALSE"
BasicRuntimeChecks="0"
RuntimeLibrary="0"
EnableEnhancedInstructionSet="1"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="2"
CallingConvention="1"
ForcedIncludeFiles="staticlink/system.h;xbox/xbox_isswappable.h"/>
<Tool
Name="VCCustomBuildTool"
CommandLine="if exist ..\..\lib_xbox\public\vgui_controls_xbox.lib attrib -r ..\..\lib_xbox\public\vgui_controls_xbox.lib
if exist $(TargetPath) copy $(TargetPath) ..\..\lib_xbox\public\vgui_controls_xbox.lib"
Outputs="..\..\lib_xbox\public\vgui_controls_xbox.lib"/>
<Tool
Name="VCLibrarianTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"
CommandLine="if exist ..\..\lib_xbox\public\vgui_controls_xbox.lib del ..\..\lib_xbox\public\vgui_controls_xbox.lib"/>
<Tool
Name="VCPreLinkEventTool"/>
</Configuration>
<Configuration
Name="Retail_XBox|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="3"
OptimizeForProcessor="2"
AdditionalIncludeDirectories="..\..\public,..\..\public\tier1,..\..\common"
PreprocessorDefinitions="NDEBUG;_WIN32;_MBCS;_LIB;_STATIC_LINKED;_SUBSYSTEM=VguiControls"
StringPooling="TRUE"
MinimalRebuild="FALSE"
ExceptionHandling="FALSE"
BasicRuntimeChecks="0"
RuntimeLibrary="0"
EnableEnhancedInstructionSet="1"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
PrecompiledHeaderFile="$(OutDir)/$(ProjectName).pch"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="2"
ForcedIncludeFiles="staticlink/system.h"/>
<Tool
Name="VCCustomBuildTool"
CommandLine="if exist ..\..\lib_xbox\public\vgui_controls_xbox.lib attrib -r ..\..\lib_xbox\public\vgui_controls_xbox.lib
if exist $(TargetPath) copy $(TargetPath) ..\..\lib_xbox\public\vgui_controls_xbox.lib"
Outputs="..\..\lib_xbox\public\vgui_controls_xbox.lib"/>
<Tool
Name="VCLibrarianTool"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"
CommandLine="if exist ..\..\lib_xbox\public\vgui_controls_xbox.lib del ..\..\lib_xbox\public\vgui_controls_xbox.lib"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\AnimationController.cpp">
</File>
<File
RelativePath=".\BuildFactoryHelper.cpp">
</File>
<File
RelativePath=".\BuildGroup.cpp">
</File>
<File
RelativePath=".\Button.cpp">
</File>
<File
RelativePath=".\controls.cpp">
</File>
<File
RelativePath=".\EditablePanel.cpp">
</File>
<File
RelativePath=".\FocusNavGroup.cpp">
</File>
<File
RelativePath=".\Image.cpp">
</File>
<File
RelativePath=".\ImagePanel.cpp">
</File>
<File
RelativePath=".\Label.cpp">
</File>
<File
RelativePath=".\Panel.cpp">
</File>
<File
RelativePath=".\TextImage.cpp">
</File>
<File
RelativePath=".\ToggleButton.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath="..\..\public\characterset.h">
</File>
<File
RelativePath="..\..\public\filesystem_helpers.h">
</File>
<File
RelativePath="..\..\public\KeyValues.h">
</File>
<File
RelativePath="..\..\public\mempool.h">
</File>
<File
RelativePath="..\..\public\utlbuffer.h">
</File>
<File
RelativePath="..\..\public\utlsymbol.h">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>