You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1532 lines
45 KiB
1532 lines
45 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
|
|
#include <stdio.h> |
|
#include <math.h> |
|
|
|
#include <vgui/VGUI.h> |
|
#include <vgui/IScheme.h> |
|
#include <KeyValues.h> |
|
#include <vgui/ISurface.h> |
|
#include <vgui/IPanel.h> |
|
#include <vgui/ISystem.h> |
|
#include <vstdlib/IKeyValuesSystem.h> |
|
#include <vgui/IVGui.h> |
|
|
|
#include "tier1/utlvector.h" |
|
#include "tier1/utlrbtree.h" |
|
#include "tier1/utldict.h" |
|
#include "VGUI_Border.h" |
|
#include "ScalableImageBorder.h" |
|
#include "ImageBorder.h" |
|
#include "vgui_internal.h" |
|
#include "bitmap.h" |
|
#include "filesystem.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include <tier0/memdbgon.h> |
|
|
|
using namespace vgui; |
|
#define FONT_ALIAS_NAME_LENGTH 64 |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Implementation of global scheme interface |
|
//----------------------------------------------------------------------------- |
|
class CScheme : public IScheme |
|
{ |
|
public: |
|
CScheme(); |
|
|
|
// gets a string from the default settings section |
|
virtual const char *GetResourceString(const char *stringName); |
|
|
|
// returns a pointer to an existing border |
|
virtual IBorder *GetBorder(const char *borderName); |
|
|
|
// returns a pointer to an existing font |
|
virtual HFont GetFont(const char *fontName, bool proportional); |
|
|
|
// m_pkvColors |
|
virtual Color GetColor( const char *colorName, Color defaultColor); |
|
|
|
|
|
void Shutdown( bool full ); |
|
void LoadFromFile( VPANEL sizingPanel, const char *filename, const char *tag, KeyValues *inKeys ); |
|
|
|
// Gets at the scheme's name |
|
const char *GetName() { return tag; } |
|
const char *GetFileName() { return fileName; } |
|
|
|
char const *GetFontName( const HFont& font ); |
|
|
|
void ReloadFontGlyphs(); |
|
|
|
VPANEL GetSizingPanel() { return m_SizingPanel; } |
|
|
|
void SpewFonts(); |
|
|
|
bool GetFontRange( const char *fontname, int &nMin, int &nMax ); |
|
void SetFontRange( const char *fontname, int nMin, int nMax ); |
|
|
|
// Get the number of borders |
|
virtual int GetBorderCount() const; |
|
|
|
// Get the border at the given index |
|
virtual IBorder *GetBorderAtIndex( int iIndex ); |
|
|
|
// Get the number of fonts |
|
virtual int GetFontCount() const; |
|
|
|
// Get the font at the given index |
|
virtual HFont GetFontAtIndex( int iIndex ); |
|
|
|
// Get color data |
|
virtual const KeyValues *GetColorData() const; |
|
|
|
private: |
|
const char *LookupSchemeSetting(const char *pchSetting); |
|
const char *GetMungedFontName( const char *fontName, const char *scheme, bool proportional); |
|
void LoadFonts(); |
|
void LoadBorders(); |
|
HFont FindFontInAliasList( const char *fontName ); |
|
int GetMinimumFontHeightForCurrentLanguage(); |
|
|
|
char fileName[256]; |
|
char tag[64]; |
|
|
|
KeyValues *m_pData; |
|
KeyValues *m_pkvBaseSettings; |
|
KeyValues *m_pkvColors; |
|
int m_nColorCount; |
|
|
|
struct SchemeBorder_t |
|
{ |
|
IBorder *border; |
|
int borderSymbol; |
|
bool bSharedBorder; |
|
}; |
|
CUtlVector<SchemeBorder_t> m_BorderList; |
|
IBorder *m_pBaseBorder; // default border to use if others not found |
|
KeyValues *m_pkvBorders; |
|
#pragma pack(1) |
|
struct fontalias_t |
|
{ |
|
CUtlSymbol _trueFontName; |
|
unsigned short _font : 15; |
|
unsigned short m_bProportional : 1; |
|
}; |
|
#pragma pack() |
|
friend struct fontalias_t; |
|
|
|
CUtlDict< fontalias_t, int > m_FontAliases; |
|
VPANEL m_SizingPanel; |
|
int m_nScreenWide; |
|
int m_nScreenTall; |
|
|
|
struct fontrange_t |
|
{ |
|
int _min; |
|
int _max; |
|
}; |
|
CUtlDict< fontrange_t, int > m_FontRanges; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Implementation of global scheme interface |
|
//----------------------------------------------------------------------------- |
|
class CSchemeManager : public ISchemeManager |
|
{ |
|
public: |
|
CSchemeManager(); |
|
~CSchemeManager(); |
|
|
|
// loads a scheme from a file |
|
// first scheme loaded becomes the default scheme, and all subsequent loaded scheme are derivitives of that |
|
// tag is friendly string representing the name of the loaded scheme |
|
virtual HScheme LoadSchemeFromFile(const char *fileName, const char *tag); |
|
// first scheme loaded becomes the default scheme, and all subsequent loaded scheme are derivitives of that |
|
virtual HScheme LoadSchemeFromFileEx( VPANEL sizingPanel, const char *fileName, const char *tag); |
|
|
|
// reloads the schemes from the file |
|
virtual void ReloadSchemes(); |
|
virtual void ReloadFonts(); |
|
|
|
// returns a handle to the default (first loaded) scheme |
|
virtual HScheme GetDefaultScheme(); |
|
|
|
// returns a handle to the scheme identified by "tag" |
|
virtual HScheme GetScheme(const char *tag); |
|
|
|
// returns a pointer to an image |
|
virtual IImage *GetImage(const char *imageName, bool hardwareFiltered); |
|
virtual HTexture GetImageID(const char *imageName, bool hardwareFiltered); |
|
|
|
virtual IScheme *GetIScheme( HScheme scheme ); |
|
|
|
virtual void Shutdown( bool full ); |
|
|
|
// gets the proportional coordinates for doing screen-size independant panel layouts |
|
// use these for font, image and panel size scaling (they all use the pixel height of the display for scaling) |
|
virtual int GetProportionalScaledValue(int normalizedValue); |
|
virtual int GetProportionalNormalizedValue(int scaledValue); |
|
|
|
// gets the proportional coordinates for doing screen-size independant panel layouts |
|
// use these for font, image and panel size scaling (they all use the pixel height of the display for scaling) |
|
virtual int GetProportionalScaledValueEx( HScheme scheme, int normalizedValue ); |
|
virtual int GetProportionalNormalizedValueEx( HScheme scheme, int scaledValue ); |
|
|
|
virtual bool DeleteImage( const char *pImageName ); |
|
|
|
// gets the proportional coordinates for doing screen-size independant panel layouts |
|
// use these for font, image and panel size scaling (they all use the pixel height of the display for scaling) |
|
int GetProportionalScaledValueEx( CScheme *pScheme, int normalizedValue ); |
|
int GetProportionalNormalizedValueEx( CScheme *pScheme, int scaledValue ); |
|
|
|
void SpewFonts(); |
|
|
|
private: |
|
|
|
int GetProportionalScaledValue_( int rootWide, int rootTall, int normalizedValue ); |
|
int GetProportionalNormalizedValue_( int rootWide, int rootTall, int scaledValue ); |
|
|
|
// Search for already-loaded schemes |
|
HScheme FindLoadedScheme(const char *fileName); |
|
|
|
CUtlVector<CScheme *> m_Schemes; |
|
|
|
static const char *s_pszSearchString; |
|
struct CachedBitmapHandle_t |
|
{ |
|
Bitmap *pBitmap; |
|
}; |
|
static bool BitmapHandleSearchFunc(const CachedBitmapHandle_t &, const CachedBitmapHandle_t &); |
|
CUtlRBTree<CachedBitmapHandle_t, int> m_Bitmaps; |
|
}; |
|
|
|
const char *CSchemeManager::s_pszSearchString = NULL; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: search function for stored bitmaps |
|
//----------------------------------------------------------------------------- |
|
bool CSchemeManager::BitmapHandleSearchFunc(const CachedBitmapHandle_t &lhs, const CachedBitmapHandle_t &rhs) |
|
{ |
|
// a NULL bitmap indicates to use the search string instead |
|
if (lhs.pBitmap && rhs.pBitmap) |
|
{ |
|
return stricmp(lhs.pBitmap->GetName(), rhs.pBitmap->GetName()) > 0; |
|
} |
|
else if (lhs.pBitmap) |
|
{ |
|
return stricmp(lhs.pBitmap->GetName(), s_pszSearchString) > 0; |
|
} |
|
return stricmp(s_pszSearchString, rhs.pBitmap->GetName()) > 0; |
|
} |
|
|
|
|
|
|
|
CSchemeManager g_Scheme; |
|
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CSchemeManager, ISchemeManager, VGUI_SCHEME_INTERFACE_VERSION, g_Scheme); |
|
|
|
|
|
namespace vgui |
|
{ |
|
vgui::ISchemeManager *g_pScheme = &g_Scheme; |
|
} // namespace vgui |
|
|
|
CON_COMMAND( vgui_spew_fonts, "" ) |
|
{ |
|
g_Scheme.SpewFonts(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Constructor |
|
//----------------------------------------------------------------------------- |
|
CSchemeManager::CSchemeManager() |
|
{ |
|
// 0th element is null, since that would be an invalid handle |
|
CScheme *nullScheme = new CScheme(); |
|
m_Schemes.AddToTail(nullScheme); |
|
m_Bitmaps.SetLessFunc(&BitmapHandleSearchFunc); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Destructor |
|
//----------------------------------------------------------------------------- |
|
CSchemeManager::~CSchemeManager() |
|
{ |
|
int i; |
|
for ( i = 0; i < m_Schemes.Count(); i++ ) |
|
{ |
|
delete m_Schemes[i]; |
|
} |
|
m_Schemes.RemoveAll(); |
|
|
|
for ( i = 0; i < m_Bitmaps.MaxElement(); i++ ) |
|
{ |
|
if (m_Bitmaps.IsValidIndex(i)) |
|
{ |
|
delete m_Bitmaps[i].pBitmap; |
|
} |
|
} |
|
m_Bitmaps.RemoveAll(); |
|
|
|
Shutdown( false ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Reload the fonts in all schemes |
|
//----------------------------------------------------------------------------- |
|
void CSchemeManager::ReloadFonts() |
|
{ |
|
for (int i = 1; i < m_Schemes.Count(); i++) |
|
{ |
|
m_Schemes[i]->ReloadFontGlyphs(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Converts the handle into an interface |
|
//----------------------------------------------------------------------------- |
|
IScheme *CSchemeManager::GetIScheme( HScheme scheme ) |
|
{ |
|
if ( scheme >= (unsigned long)m_Schemes.Count() ) |
|
{ |
|
AssertOnce( !"Invalid scheme requested." ); |
|
return NULL; |
|
} |
|
else |
|
{ |
|
return m_Schemes[scheme]; |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CSchemeManager::Shutdown( bool full ) |
|
{ |
|
// Full shutdown kills the null scheme |
|
for( int i = full ? 0 : 1; i < m_Schemes.Count(); i++ ) |
|
{ |
|
m_Schemes[i]->Shutdown( full ); |
|
} |
|
|
|
if ( full ) |
|
{ |
|
m_Schemes.RemoveAll(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: loads a scheme from disk |
|
//----------------------------------------------------------------------------- |
|
HScheme CSchemeManager::FindLoadedScheme(const char *fileName) |
|
{ |
|
// Find the scheme in the list of already loaded schemes |
|
for (int i = 1; i < m_Schemes.Count(); i++) |
|
{ |
|
char const *schemeFileName = m_Schemes[i]->GetFileName(); |
|
if (!stricmp(schemeFileName, fileName)) |
|
return i; |
|
} |
|
|
|
return 0; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Constructor |
|
//----------------------------------------------------------------------------- |
|
CScheme::CScheme() |
|
{ |
|
fileName[ 0 ] = 0; |
|
tag[ 0 ] = 0; |
|
|
|
m_pData = NULL; |
|
m_pkvBaseSettings = NULL; |
|
m_pkvColors = NULL; |
|
m_nColorCount = 0; |
|
|
|
m_pBaseBorder = NULL; // default border to use if others not found |
|
m_pkvBorders = NULL; |
|
m_SizingPanel = 0; |
|
m_nScreenWide = -1; |
|
m_nScreenTall = -1; |
|
} |
|
|
|
// first scheme loaded becomes the default scheme, and all subsequent loaded scheme are derivitives of that |
|
HScheme CSchemeManager::LoadSchemeFromFileEx( VPANEL sizingPanel, const char *fileName, const char *tag) |
|
{ |
|
// Look to see if we've already got this scheme... |
|
HScheme hScheme = FindLoadedScheme(fileName); |
|
if (hScheme != 0) |
|
{ |
|
CScheme *pScheme = static_cast< CScheme * >( GetIScheme( hScheme ) ); |
|
if ( IsPC() && pScheme ) |
|
{ |
|
pScheme->ReloadFontGlyphs(); |
|
} |
|
return hScheme; |
|
} |
|
|
|
KeyValues *data; |
|
data = new KeyValues("Scheme"); |
|
|
|
data->UsesEscapeSequences( true ); // VGUI uses this |
|
|
|
// Look first in game directory |
|
bool result = data->LoadFromFile( g_pFullFileSystem, fileName, "GAME" ); |
|
if ( !result ) |
|
{ |
|
// look in any directory |
|
result = data->LoadFromFile( g_pFullFileSystem, fileName, NULL ); |
|
} |
|
|
|
if (!result) |
|
{ |
|
data->deleteThis(); |
|
return 0; |
|
} |
|
|
|
if ( IsX360() ) |
|
{ |
|
data->ProcessResolutionKeys( g_pSurface->GetResolutionKey() ); |
|
} |
|
if ( IsPC() ) |
|
{ |
|
ConVarRef cl_hud_minmode( "cl_hud_minmode", true ); |
|
if ( cl_hud_minmode.IsValid() && cl_hud_minmode.GetBool() ) |
|
{ |
|
data->ProcessResolutionKeys( "_minmode" ); |
|
} |
|
} |
|
if( g_pIVgui->GetVRMode() ) |
|
{ |
|
data->ProcessResolutionKeys( "_vrmode" ); |
|
} |
|
|
|
CScheme *newScheme = new CScheme(); |
|
newScheme->LoadFromFile( sizingPanel, fileName, tag, data ); |
|
|
|
return m_Schemes.AddToTail(newScheme); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: loads a scheme from disk |
|
//----------------------------------------------------------------------------- |
|
HScheme CSchemeManager::LoadSchemeFromFile(const char *fileName, const char *tag) |
|
{ |
|
return LoadSchemeFromFileEx( 0, fileName, tag ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Table of scheme file entries, translation from old goldsrc schemes to new src schemes |
|
//----------------------------------------------------------------------------- |
|
struct SchemeEntryTranslation_t |
|
{ |
|
const char *pchNewEntry; |
|
const char *pchOldEntry; |
|
const char *pchDefaultValue; |
|
}; |
|
SchemeEntryTranslation_t g_SchemeTranslation[] = |
|
{ |
|
{ "Border.Bright", "BorderBright", "200 200 200 196" }, // the lit side of a control |
|
{ "Border.Dark" "BorderDark", "40 40 40 196" }, // the dark/unlit side of a control |
|
{ "Border.Selection" "BorderSelection", "0 0 0 196" }, // the additional border color for displaying the default/selected button |
|
|
|
{ "Button.TextColor", "ControlFG", "White" }, |
|
{ "Button.BgColor", "ControlBG", "Blank" }, |
|
{ "Button.ArmedTextColor", "ControlFG" }, |
|
{ "Button.ArmedBgColor", "ControlBG" }, |
|
{ "Button.DepressedTextColor", "ControlFG" }, |
|
{ "Button.DepressedBgColor", "ControlBG" }, |
|
{ "Button.FocusBorderColor", "0 0 0 255" }, |
|
|
|
{ "CheckButton.TextColor", "BaseText" }, |
|
{ "CheckButton.SelectedTextColor", "BrightControlText" }, |
|
{ "CheckButton.BgColor", "CheckBgColor" }, |
|
{ "CheckButton.Border1", "CheckButtonBorder1" }, |
|
{ "CheckButton.Border2", "CheckButtonBorder2" }, |
|
{ "CheckButton.Check", "CheckButtonCheck" }, |
|
|
|
{ "ComboBoxButton.ArrowColor", "LabelDimText" }, |
|
{ "ComboBoxButton.ArmedArrowColor", "MenuButton/ArmedArrowColor" }, |
|
{ "ComboBoxButton.BgColor", "MenuButton/ButtonBgColor" }, |
|
{ "ComboBoxButton.DisabledBgColor", "ControlBG" }, |
|
|
|
{ "Frame.TitleTextInsetX", NULL, "32" }, |
|
{ "Frame.ClientInsetX", NULL, "8" }, |
|
{ "Frame.ClientInsetY", NULL, "6" }, |
|
{ "Frame.BgColor", "BgColor" }, |
|
{ "Frame.OutOfFocusBgColor", "BgColor" }, |
|
{ "Frame.FocusTransitionEffectTime",NULL, "0" }, |
|
{ "Frame.TransitionEffectTime", NULL, "0" }, |
|
{ "Frame.AutoSnapRange", NULL, "8" }, |
|
{ "FrameGrip.Color1", "BorderBright" }, |
|
{ "FrameGrip.Color2", "BorderSelection" }, |
|
{ "FrameTitleButton.FgColor", "TitleButtonFgColor" }, |
|
{ "FrameTitleButton.BgColor", "TitleButtonBgColor" }, |
|
{ "FrameTitleButton.DisabledFgColor", "TitleButtonDisabledFgColor" }, |
|
{ "FrameTitleButton.DisabledBgColor", "TitleButtonDisabledBgColor" }, |
|
{ "FrameSystemButton.FgColor", "TitleBarBgColor" }, |
|
{ "FrameSystemButton.BgColor", "TitleBarBgColor" }, |
|
{ "FrameSystemButton.Icon", "TitleBarIcon" }, |
|
{ "FrameSystemButton.DisabledIcon", "TitleBarDisabledIcon" }, |
|
{ "FrameTitleBar.Font", NULL, "Default" }, |
|
{ "FrameTitleBar.TextColor", "TitleBarFgColor" }, |
|
{ "FrameTitleBar.BgColor", "TitleBarBgColor" }, |
|
{ "FrameTitleBar.DisabledTextColor","TitleBarDisabledFgColor" }, |
|
{ "FrameTitleBar.DisabledBgColor", "TitleBarDisabledBgColor" }, |
|
|
|
{ "GraphPanel.FgColor", "BrightControlText" }, |
|
{ "GraphPanel.BgColor", "WindowBgColor" }, |
|
|
|
{ "Label.TextDullColor", "LabelDimText" }, |
|
{ "Label.TextColor", "BaseText" }, |
|
{ "Label.TextBrightColor", "BrightControlText" }, |
|
{ "Label.SelectedTextColor", "BrightControlText" }, |
|
{ "Label.BgColor", "LabelBgColor" }, |
|
{ "Label.DisabledFgColor1", "DisabledFgColor1" }, |
|
{ "Label.DisabledFgColor2", "DisabledFgColor2" }, |
|
|
|
{ "ListPanel.TextColor", "WindowFgColor" }, |
|
{ "ListPanel.TextBgColor", "Menu/ArmedBgColor" }, |
|
{ "ListPanel.BgColor", "ListBgColor" }, |
|
{ "ListPanel.SelectedTextColor", "ListSelectionFgColor" }, |
|
{ "ListPanel.SelectedBgColor", "Menu/ArmedBgColor" }, |
|
{ "ListPanel.SelectedOutOfFocusBgColor","SelectionBG2" }, |
|
{ "ListPanel.EmptyListInfoTextColor", "LabelDimText" }, |
|
{ "ListPanel.DisabledTextColor", "LabelDimText" }, |
|
{ "ListPanel.DisabledSelectedTextColor","ListBgColor" }, |
|
|
|
{ "Menu.TextColor", "Menu/FgColor" }, |
|
{ "Menu.BgColor", "Menu/BgColor" }, |
|
{ "Menu.ArmedTextColor", "Menu/ArmedFgColor" }, |
|
{ "Menu.ArmedBgColor", "Menu/ArmedBgColor" }, |
|
{ "Menu.TextInset", NULL, "6" }, |
|
|
|
{ "Panel.FgColor", "FgColor" }, |
|
{ "Panel.BgColor", "BgColor" }, |
|
|
|
{ "ProgressBar.FgColor", "BrightControlText" }, |
|
{ "ProgressBar.BgColor", "WindowBgColor" }, |
|
|
|
{ "PropertySheet.TextColor", "FgColorDim" }, |
|
{ "PropertySheet.SelectedTextColor", "BrightControlText" }, |
|
{ "PropertySheet.TransitionEffectTime", NULL, "0" }, |
|
|
|
{ "RadioButton.TextColor", "FgColor" }, |
|
{ "RadioButton.SelectedTextColor", "BrightControlText" }, |
|
|
|
{ "RichText.TextColor", "WindowFgColor" }, |
|
{ "RichText.BgColor", "WindowBgColor" }, |
|
{ "RichText.SelectedTextColor", "SelectionFgColor" }, |
|
{ "RichText.SelectedBgColor", "SelectionBgColor" }, |
|
|
|
{ "ScrollBar.Wide", NULL, "19" }, |
|
|
|
{ "ScrollBarButton.FgColor", "DimBaseText" }, |
|
{ "ScrollBarButton.BgColor", "ControlBG" }, |
|
{ "ScrollBarButton.ArmedFgColor", "BaseText" }, |
|
{ "ScrollBarButton.ArmedBgColor", "ControlBG" }, |
|
{ "ScrollBarButton.DepressedFgColor", "BaseText" }, |
|
{ "ScrollBarButton.DepressedBgColor", "ControlBG" }, |
|
|
|
{ "ScrollBarSlider.FgColor", "ScrollBarSlider/ScrollBarSliderFgColor" }, |
|
{ "ScrollBarSlider.BgColor", "ScrollBarSlider/ScrollBarSliderBgColor" }, |
|
|
|
{ "SectionedListPanel.HeaderTextColor", "SectionTextColor" }, |
|
{ "SectionedListPanel.HeaderBgColor", "BuddyListBgColor" }, |
|
{ "SectionedListPanel.DividerColor", "SectionDividerColor" }, |
|
{ "SectionedListPanel.TextColor", "BuddyButton/FgColor1" }, |
|
{ "SectionedListPanel.BrightTextColor", "BuddyButton/ArmedFgColor1" }, |
|
{ "SectionedListPanel.BgColor", "BuddyListBgColor" }, |
|
{ "SectionedListPanel.SelectedTextColor", "BuddyButton/ArmedFgColor1" }, |
|
{ "SectionedListPanel.SelectedBgColor", "BuddyButton/ArmedBgColor" }, |
|
{ "SectionedListPanel.OutOfFocusSelectedTextColor", "BuddyButton/ArmedFgColor2" }, |
|
{ "SectionedListPanel.OutOfFocusSelectedBgColor", "SelectionBG2" }, |
|
|
|
{ "Slider.NobColor", "SliderTickColor" }, |
|
{ "Slider.TextColor", "Slider/SliderFgColor" }, |
|
{ "Slider.TrackColor", "SliderTrackColor"}, |
|
{ "Slider.DisabledTextColor1", "DisabledFgColor1" }, |
|
{ "Slider.DisabledTextColor2", "DisabledFgColor2" }, |
|
|
|
{ "TextEntry.TextColor", "WindowFgColor" }, |
|
{ "TextEntry.BgColor", "WindowBgColor" }, |
|
{ "TextEntry.CursorColor", "TextCursorColor" }, |
|
{ "TextEntry.DisabledTextColor","WindowDisabledFgColor" }, |
|
{ "TextEntry.DisabledBgColor", "ControlBG" }, |
|
{ "TextEntry.SelectedTextColor","SelectionFgColor" }, |
|
{ "TextEntry.SelectedBgColor", "SelectionBgColor" }, |
|
{ "TextEntry.OutOfFocusSelectedBgColor", "SelectionBG2" }, |
|
{ "TextEntry.FocusEdgeColor", "BorderSelection" }, |
|
|
|
{ "ToggleButton.SelectedTextColor", "BrightControlText" }, |
|
|
|
{ "Tooltip.TextColor", "BorderSelection" }, |
|
{ "Tooltip.BgColor", "SelectionBG" }, |
|
|
|
{ "TreeView.BgColor", "ListBgColor" }, |
|
|
|
{ "WizardSubPanel.BgColor", "SubPanelBgColor" }, |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: loads a scheme from from disk into memory |
|
//----------------------------------------------------------------------------- |
|
void CScheme::LoadFromFile( VPANEL sizingPanel, const char *inFilename, const char *inTag, KeyValues *inKeys ) |
|
{ |
|
COM_TimestampedLog( "CScheme::LoadFromFile( %s )", inFilename ); |
|
|
|
Q_strncpy(fileName, inFilename, sizeof(fileName) ); |
|
|
|
m_SizingPanel = sizingPanel; |
|
|
|
m_pData = inKeys; |
|
m_pkvBaseSettings = m_pData->FindKey("BaseSettings", true); |
|
m_pkvColors = m_pData->FindKey("Colors", true); |
|
|
|
// override the scheme name with the tag name |
|
KeyValues *name = m_pData->FindKey("Name", true); |
|
name->SetString("Name", inTag); |
|
|
|
if ( inTag ) |
|
{ |
|
Q_strncpy( tag, inTag, sizeof( tag ) ); |
|
} |
|
else |
|
{ |
|
Assert( "You need to name the scheme!" ); |
|
Q_strncpy( tag, "default", sizeof( tag ) ); |
|
} |
|
|
|
// translate format from goldsrc scheme to new scheme |
|
for (int i = 0; i < ARRAYSIZE(g_SchemeTranslation); i++) |
|
{ |
|
if (!m_pkvBaseSettings->FindKey(g_SchemeTranslation[i].pchNewEntry, false)) |
|
{ |
|
const char *pchColor; |
|
|
|
if (g_SchemeTranslation[i].pchOldEntry) |
|
{ |
|
pchColor = LookupSchemeSetting(g_SchemeTranslation[i].pchOldEntry); |
|
} |
|
else |
|
{ |
|
pchColor = g_SchemeTranslation[i].pchDefaultValue; |
|
} |
|
|
|
Assert( pchColor ); |
|
|
|
m_pkvBaseSettings->SetString(g_SchemeTranslation[i].pchNewEntry, pchColor); |
|
} |
|
} |
|
|
|
// need to copy tag before loading fonts |
|
LoadFonts(); |
|
LoadBorders(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
bool CScheme::GetFontRange( const char *fontname, int &nMin, int &nMax ) |
|
{ |
|
int i = m_FontRanges.Find( fontname ); |
|
if ( i != m_FontRanges.InvalidIndex() ) |
|
{ |
|
nMin = m_FontRanges[i]._min; |
|
nMax = m_FontRanges[i]._max; |
|
return true; |
|
} |
|
|
|
return false; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CScheme::SetFontRange( const char *fontname, int nMin, int nMax ) |
|
{ |
|
int i = m_FontRanges.Find( fontname ); |
|
if ( i != m_FontRanges.InvalidIndex() ) |
|
{ |
|
m_FontRanges[i]._min = nMin; |
|
m_FontRanges[i]._max = nMax; |
|
return; |
|
} |
|
|
|
// not already in our list |
|
int iNew = m_FontRanges.Insert( fontname ); |
|
|
|
m_FontRanges[iNew]._min = nMin; |
|
m_FontRanges[iNew]._max = nMax; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: adds all the font specifications to the surface |
|
//----------------------------------------------------------------------------- |
|
void CScheme::LoadFonts() |
|
{ |
|
bool bValid = false; |
|
char language[64]; |
|
memset( language, 0, sizeof( language ) ); |
|
|
|
// get our language |
|
if ( IsPC() ) |
|
{ |
|
bValid = vgui::g_pSystem->GetRegistryString( "HKEY_CURRENT_USER\\Software\\Valve\\Source\\Language", language, sizeof( language ) - 1 ); |
|
} |
|
else |
|
{ |
|
Q_strncpy( language, XBX_GetLanguageString(), sizeof( language ) ); |
|
bValid = true; |
|
} |
|
|
|
if ( !bValid ) |
|
{ |
|
Q_strncpy( language, "english", sizeof( language ) ); |
|
} |
|
|
|
// add our custom fonts |
|
for (KeyValues *kv = m_pData->FindKey("CustomFontFiles", true)->GetFirstSubKey(); kv != NULL; kv = kv->GetNextKey()) |
|
{ |
|
const char *fontFile = kv->GetString(); |
|
if (fontFile && *fontFile) |
|
{ |
|
g_pSurface->AddCustomFontFile( NULL, fontFile ); |
|
} |
|
else |
|
{ |
|
// we have a block to read |
|
int nRangeMin = 0, nRangeMax = 0; |
|
const char *pszName = NULL; |
|
bool bUseRange = false; |
|
|
|
for ( KeyValues *pData = kv->GetFirstSubKey(); pData != NULL; pData = pData->GetNextKey() ) |
|
{ |
|
const char *pszKey = pData->GetName(); |
|
if ( !Q_stricmp( pszKey, "font" ) ) |
|
{ |
|
fontFile = pData->GetString(); |
|
} |
|
else if ( !Q_stricmp( pszKey, "name" ) ) |
|
{ |
|
pszName = pData->GetString(); |
|
} |
|
else |
|
{ |
|
// we must have a language |
|
if ( Q_stricmp( language, pszKey ) == 0 ) // matches the language we're running? |
|
{ |
|
// get the range |
|
KeyValues *pRange = pData->FindKey( "range" ); |
|
if ( pRange ) |
|
{ |
|
bUseRange = true; |
|
sscanf( pRange->GetString(), "%x %x", &nRangeMin, &nRangeMax ); |
|
|
|
if ( nRangeMin > nRangeMax ) |
|
{ |
|
int nTemp = nRangeMin; |
|
nRangeMin = nRangeMax; |
|
nRangeMax = nTemp; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
if ( fontFile && *fontFile ) |
|
{ |
|
g_pSurface->AddCustomFontFile( pszName, fontFile ); |
|
|
|
if ( bUseRange ) |
|
{ |
|
SetFontRange( pszName, nRangeMin, nRangeMax ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
// add bitmap fonts |
|
for (KeyValues *kv = m_pData->FindKey("BitmapFontFiles", true)->GetFirstSubKey(); kv != NULL; kv = kv->GetNextKey()) |
|
{ |
|
const char *fontFile = kv->GetString(); |
|
if (fontFile && *fontFile) |
|
{ |
|
bool bSuccess = g_pSurface->AddBitmapFontFile( fontFile ); |
|
if ( bSuccess ) |
|
{ |
|
// refer to the font by a user specified symbol |
|
g_pSurface->SetBitmapFontName( kv->GetName(), fontFile ); |
|
} |
|
} |
|
} |
|
|
|
// create the fonts |
|
for (KeyValues *kv = m_pData->FindKey("Fonts", true)->GetFirstSubKey(); kv != NULL; kv = kv->GetNextKey()) |
|
{ |
|
for ( int i = 0; i < 2; i++ ) |
|
{ |
|
// create the base font |
|
bool proportionalFont = static_cast<bool>( i ); |
|
const char *fontName = GetMungedFontName( kv->GetName(), tag, proportionalFont ); // first time it adds a normal font, and then a proportional one |
|
HFont font = g_pSurface->CreateFont(); |
|
|
|
int j = m_FontAliases.Insert( fontName ); |
|
m_FontAliases[j]._trueFontName = kv->GetName(); |
|
m_FontAliases[j]._font = font; |
|
m_FontAliases[j].m_bProportional = proportionalFont; |
|
} |
|
} |
|
|
|
// load in the font glyphs |
|
ReloadFontGlyphs(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Reloads all scheme fonts |
|
//----------------------------------------------------------------------------- |
|
void CScheme::ReloadFontGlyphs() |
|
{ |
|
COM_TimestampedLog( "ReloadFontGlyphs(): Start" ); |
|
|
|
// get our current resolution |
|
if ( m_SizingPanel != 0 ) |
|
{ |
|
g_pIPanel->GetSize( m_SizingPanel, m_nScreenWide, m_nScreenTall ); |
|
} |
|
else |
|
{ |
|
g_pSurface->GetScreenSize( m_nScreenWide, m_nScreenTall ); |
|
} |
|
|
|
// check our language; some have minimum sizes |
|
int minimumFontHeight = GetMinimumFontHeightForCurrentLanguage(); |
|
|
|
// add the data to all the fonts |
|
KeyValues *fonts = m_pData->FindKey("Fonts", true); |
|
FOR_EACH_DICT_FAST( m_FontAliases, i ) |
|
{ |
|
KeyValues *kv = fonts->FindKey( m_FontAliases[i]._trueFontName.String(), true ); |
|
|
|
// walk through creating adding the first matching glyph set to the font |
|
for (KeyValues *fontdata = kv->GetFirstSubKey(); fontdata != NULL; fontdata = fontdata->GetNextKey()) |
|
{ |
|
// skip over fonts not meant for this resolution |
|
int fontYResMin = 0, fontYResMax = 0; |
|
sscanf(fontdata->GetString("yres", ""), "%d %d", &fontYResMin, &fontYResMax); |
|
if (fontYResMin) |
|
{ |
|
if (!fontYResMax) |
|
{ |
|
fontYResMax = fontYResMin; |
|
} |
|
// check the range |
|
if (m_nScreenTall < fontYResMin || m_nScreenTall > fontYResMax) |
|
continue; |
|
} |
|
|
|
int flags = 0; |
|
if (fontdata->GetInt( "italic" )) |
|
{ |
|
flags |= ISurface::FONTFLAG_ITALIC; |
|
} |
|
if (fontdata->GetInt( "underline" )) |
|
{ |
|
flags |= ISurface::FONTFLAG_UNDERLINE; |
|
} |
|
if (fontdata->GetInt( "strikeout" )) |
|
{ |
|
flags |= ISurface::FONTFLAG_STRIKEOUT; |
|
} |
|
if (fontdata->GetInt( "symbol" )) |
|
{ |
|
flags |= ISurface::FONTFLAG_SYMBOL; |
|
} |
|
if (fontdata->GetInt( "antialias" ) && g_pSurface->SupportsFeature(ISurface::ANTIALIASED_FONTS)) |
|
{ |
|
flags |= ISurface::FONTFLAG_ANTIALIAS; |
|
} |
|
if (fontdata->GetInt( "dropshadow" ) && g_pSurface->SupportsFeature(ISurface::DROPSHADOW_FONTS)) |
|
{ |
|
flags |= ISurface::FONTFLAG_DROPSHADOW; |
|
} |
|
if (fontdata->GetInt( "outline" ) && g_pSurface->SupportsFeature(ISurface::OUTLINE_FONTS)) |
|
{ |
|
flags |= ISurface::FONTFLAG_OUTLINE; |
|
} |
|
if (fontdata->GetInt( "custom" )) |
|
{ |
|
flags |= ISurface::FONTFLAG_CUSTOM; |
|
} |
|
if (fontdata->GetInt( "bitmap" )) |
|
{ |
|
flags |= ISurface::FONTFLAG_BITMAP; |
|
} |
|
if (fontdata->GetInt( "rotary" )) |
|
{ |
|
flags |= ISurface::FONTFLAG_ROTARY; |
|
} |
|
if (fontdata->GetInt( "additive" )) |
|
{ |
|
flags |= ISurface::FONTFLAG_ADDITIVE; |
|
} |
|
|
|
int tall = fontdata->GetInt( "tall" ); |
|
int blur = fontdata->GetInt( "blur" ); |
|
int scanlines = fontdata->GetInt( "scanlines" ); |
|
float scalex = fontdata->GetFloat( "scalex", 1.0f ); |
|
float scaley = fontdata->GetFloat( "scaley", 1.0f ); |
|
|
|
// only grow this font if it doesn't have a resolution filter specified |
|
if ( ( !fontYResMin && !fontYResMax ) && m_FontAliases[i].m_bProportional ) |
|
{ |
|
tall = g_Scheme.GetProportionalScaledValueEx( this, tall ); |
|
blur = g_Scheme.GetProportionalScaledValueEx( this, blur ); |
|
scanlines = g_Scheme.GetProportionalScaledValueEx( this, scanlines ); |
|
scalex = g_Scheme.GetProportionalScaledValueEx( this, scalex * 10000.0f ) * 0.0001f; |
|
scaley = g_Scheme.GetProportionalScaledValueEx( this, scaley * 10000.0f ) * 0.0001f; |
|
} |
|
|
|
// clip the font size so that fonts can't be too big |
|
if ( tall > 127 ) |
|
{ |
|
tall = 127; |
|
} |
|
|
|
// check our minimum font height |
|
if ( tall < minimumFontHeight ) |
|
{ |
|
tall = minimumFontHeight; |
|
} |
|
|
|
if ( flags & ISurface::FONTFLAG_BITMAP ) |
|
{ |
|
// add the new set |
|
g_pSurface->SetBitmapFontGlyphSet( |
|
m_FontAliases[i]._font, |
|
g_pSurface->GetBitmapFontName( fontdata->GetString( "name" ) ), |
|
scalex, |
|
scaley, |
|
flags); |
|
} |
|
else |
|
{ |
|
int nRangeMin, nRangeMax; |
|
|
|
if ( GetFontRange( fontdata->GetString( "name" ), nRangeMin, nRangeMax ) ) |
|
{ |
|
// add the new set |
|
g_pSurface->SetFontGlyphSet( |
|
m_FontAliases[i]._font, |
|
fontdata->GetString( "name" ), |
|
tall, |
|
fontdata->GetInt( "weight" ), |
|
blur, |
|
scanlines, |
|
flags, |
|
nRangeMin, |
|
nRangeMax); |
|
} |
|
else |
|
{ |
|
// add the new set |
|
g_pSurface->SetFontGlyphSet( |
|
m_FontAliases[i]._font, |
|
fontdata->GetString( "name" ), |
|
tall, |
|
fontdata->GetInt( "weight" ), |
|
blur, |
|
scanlines, |
|
flags); |
|
} |
|
} |
|
|
|
// don't add any more |
|
break; |
|
} |
|
} |
|
|
|
COM_TimestampedLog( "ReloadFontGlyphs(): End" ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: create the Border objects from the scheme data |
|
//----------------------------------------------------------------------------- |
|
void CScheme::LoadBorders() |
|
{ |
|
m_pkvBorders = m_pData->FindKey("Borders", true); |
|
{for ( KeyValues *kv = m_pkvBorders->GetFirstSubKey(); kv != NULL; kv = kv->GetNextKey()) |
|
{ |
|
if (kv->GetDataType() == KeyValues::TYPE_STRING) |
|
{ |
|
// it's referencing another border, ignore for now |
|
} |
|
else |
|
{ |
|
int i = m_BorderList.AddToTail(); |
|
|
|
IBorder *border = NULL; |
|
const char *pszBorderType = kv->GetString( "bordertype", NULL ); |
|
if ( pszBorderType && pszBorderType[0] ) |
|
{ |
|
if ( !stricmp(pszBorderType,"image") ) |
|
{ |
|
border = new ImageBorder(); |
|
} |
|
else if ( !stricmp(pszBorderType,"scalable_image") ) |
|
{ |
|
border = new ScalableImageBorder(); |
|
} |
|
else |
|
{ |
|
Assert(0); |
|
// Fall back to the base border type. See below. |
|
pszBorderType = NULL; |
|
} |
|
} |
|
|
|
if ( !pszBorderType || !pszBorderType[0] ) |
|
{ |
|
border = new Border(); |
|
} |
|
|
|
border->SetName(kv->GetName()); |
|
border->ApplySchemeSettings(this, kv); |
|
|
|
m_BorderList[i].border = border; |
|
m_BorderList[i].bSharedBorder = false; |
|
m_BorderList[i].borderSymbol = kv->GetNameSymbol(); |
|
} |
|
}} |
|
|
|
// iterate again to get the border references |
|
for ( KeyValues *kv = m_pkvBorders->GetFirstSubKey(); kv != NULL; kv = kv->GetNextKey()) |
|
{ |
|
if (kv->GetDataType() == KeyValues::TYPE_STRING) |
|
{ |
|
// it's referencing another border, find it |
|
Border *border = (Border *)GetBorder(kv->GetString()); |
|
// const char *str = kv->GetName(); |
|
Assert(border); |
|
|
|
// add an entry that just references the existing border |
|
int i = m_BorderList.AddToTail(); |
|
m_BorderList[i].border = border; |
|
m_BorderList[i].bSharedBorder = true; |
|
m_BorderList[i].borderSymbol = kv->GetNameSymbol(); |
|
} |
|
} |
|
|
|
m_pBaseBorder = GetBorder("BaseBorder"); |
|
} |
|
|
|
void CScheme::SpewFonts( void ) |
|
{ |
|
Msg( "Scheme: %s (%s)\n", GetName(), GetFileName() ); |
|
FOR_EACH_DICT_FAST( m_FontAliases, i ) |
|
{ |
|
const fontalias_t& FontAlias = m_FontAliases[ i ]; |
|
uint32 Font = FontAlias._font; |
|
const char *szFontName = g_pSurface->GetFontName( Font ); |
|
const char *szFontFamilyName = g_pSurface->GetFontFamilyName( Font ); |
|
const char *szTrueFontName = FontAlias._trueFontName.String(); |
|
const char *szFontAlias = m_FontAliases.GetElementName( i ); |
|
|
|
Msg( " %2d: HFont:0x%8.8x, %s, %s, font:%s, tall:%d(%d). %s\n", |
|
i, |
|
Font, |
|
szTrueFontName ? szTrueFontName : "??", |
|
szFontAlias ? szFontAlias : "??", |
|
szFontName ? szFontName : "??", |
|
g_pSurface->GetFontTall( Font ), |
|
g_pSurface->GetFontTallRequested( Font ), |
|
szFontFamilyName ? szFontFamilyName : "" ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: reloads the scheme from the file |
|
//----------------------------------------------------------------------------- |
|
void CSchemeManager::ReloadSchemes() |
|
{ |
|
int count = m_Schemes.Count(); |
|
Shutdown( false ); |
|
|
|
// reload the scheme |
|
for (int i = 1; i < count; i++) |
|
{ |
|
LoadSchemeFromFile(m_Schemes[i]->GetFileName(), m_Schemes[i]->GetName()); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: kills all the schemes |
|
//----------------------------------------------------------------------------- |
|
void CScheme::Shutdown( bool full ) |
|
{ |
|
for (int i = 0; i < m_BorderList.Count(); i++) |
|
{ |
|
// delete if it's not shared |
|
if (!m_BorderList[i].bSharedBorder) |
|
{ |
|
IBorder *border = m_BorderList[i].border; |
|
delete border; |
|
} |
|
} |
|
|
|
m_pBaseBorder = NULL; |
|
m_BorderList.RemoveAll(); |
|
m_pkvBorders = NULL; |
|
|
|
if (full && m_pData) |
|
{ |
|
m_pData->deleteThis(); |
|
m_pData = NULL; |
|
delete this; |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: returns a handle to the default (first loaded) scheme |
|
//----------------------------------------------------------------------------- |
|
HScheme CSchemeManager::GetDefaultScheme() |
|
{ |
|
return 1; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: returns a handle to the scheme identified by "tag" |
|
//----------------------------------------------------------------------------- |
|
HScheme CSchemeManager::GetScheme(const char *tag) |
|
{ |
|
for (int i=1;i<m_Schemes.Count();i++) |
|
{ |
|
if ( !stricmp(tag,m_Schemes[i]->GetName()) ) |
|
{ |
|
return i; |
|
} |
|
} |
|
return 1; // default scheme |
|
} |
|
|
|
int CSchemeManager::GetProportionalScaledValue_( int rootWide, int rootTall, int normalizedValue ) |
|
{ |
|
int proH, proW; |
|
g_pSurface->GetProportionalBase( proW, proH ); |
|
double scale = (double)rootTall / (double)proH; |
|
|
|
return (int)( normalizedValue * scale ); |
|
} |
|
|
|
int CSchemeManager::GetProportionalNormalizedValue_( int rootWide, int rootTall, int scaledValue ) |
|
{ |
|
int proH, proW; |
|
g_pSurface->GetProportionalBase( proW, proH ); |
|
float scale = (float)rootTall / (float)proH; |
|
|
|
return (int)( scaledValue / scale ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: converts a value into proportional mode |
|
//----------------------------------------------------------------------------- |
|
int CSchemeManager::GetProportionalScaledValue(int normalizedValue) |
|
{ |
|
int wide, tall; |
|
g_pSurface->GetScreenSize( wide, tall ); |
|
return GetProportionalScaledValue_( wide, tall, normalizedValue ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: converts a value out of proportional mode |
|
//----------------------------------------------------------------------------- |
|
int CSchemeManager::GetProportionalNormalizedValue(int scaledValue) |
|
{ |
|
int wide, tall; |
|
g_pSurface->GetScreenSize( wide, tall ); |
|
return GetProportionalNormalizedValue_( wide, tall, scaledValue ); |
|
} |
|
|
|
// gets the proportional coordinates for doing screen-size independant panel layouts |
|
// use these for font, image and panel size scaling (they all use the pixel height of the display for scaling) |
|
int CSchemeManager::GetProportionalScaledValueEx( CScheme *pScheme, int normalizedValue ) |
|
{ |
|
VPANEL sizing = pScheme->GetSizingPanel(); |
|
if ( !sizing ) |
|
{ |
|
return GetProportionalScaledValue( normalizedValue ); |
|
} |
|
|
|
int w, h; |
|
g_pIPanel->GetSize( sizing, w, h ); |
|
return GetProportionalScaledValue_( w, h, normalizedValue ); |
|
} |
|
|
|
int CSchemeManager::GetProportionalNormalizedValueEx( CScheme *pScheme, int scaledValue ) |
|
{ |
|
VPANEL sizing = pScheme->GetSizingPanel(); |
|
if ( !sizing ) |
|
{ |
|
return GetProportionalNormalizedValue( scaledValue ); |
|
} |
|
|
|
int w, h; |
|
g_pIPanel->GetSize( sizing, w, h ); |
|
return GetProportionalNormalizedValue_( w, h, scaledValue ); |
|
} |
|
|
|
int CSchemeManager::GetProportionalScaledValueEx( HScheme scheme, int normalizedValue ) |
|
{ |
|
IScheme *pscheme = GetIScheme( scheme ); |
|
if ( !pscheme ) |
|
{ |
|
Assert( 0 ); |
|
return GetProportionalScaledValue( normalizedValue ); |
|
} |
|
|
|
CScheme *p = static_cast< CScheme * >( pscheme ); |
|
return GetProportionalScaledValueEx( p, normalizedValue ); |
|
} |
|
|
|
int CSchemeManager::GetProportionalNormalizedValueEx( HScheme scheme, int scaledValue ) |
|
{ |
|
IScheme *pscheme = GetIScheme( scheme ); |
|
if ( !pscheme ) |
|
{ |
|
Assert( 0 ); |
|
return GetProportionalNormalizedValue( scaledValue ); |
|
} |
|
|
|
CScheme *p = static_cast< CScheme * >( pscheme ); |
|
return GetProportionalNormalizedValueEx( p, scaledValue ); |
|
} |
|
|
|
void CSchemeManager::SpewFonts( void ) |
|
{ |
|
for ( int i = 1; i < m_Schemes.Count(); i++ ) |
|
{ |
|
m_Schemes[i]->SpewFonts(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
const char *CScheme::GetResourceString(const char *stringName) |
|
{ |
|
return m_pkvBaseSettings->GetString(stringName); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: returns a pointer to an image |
|
//----------------------------------------------------------------------------- |
|
IImage *CSchemeManager::GetImage(const char *imageName, bool hardwareFiltered) |
|
{ |
|
if ( !imageName || strlen(imageName) <= 0 ) // frame icons and the like are in the scheme file and may not be defined, so if this is null then fail silently |
|
{ |
|
return NULL; |
|
} |
|
|
|
// set up to search for the bitmap |
|
CachedBitmapHandle_t searchBitmap; |
|
searchBitmap.pBitmap = NULL; |
|
|
|
// Prepend 'vgui/'. Resource files try to load images assuming they live in the vgui directory. |
|
// Used to do this in Bitmap::Bitmap, moved so that the s_pszSearchString is searching for the |
|
// filename with 'vgui/' already added. |
|
char szFileName[MAX_PATH]; |
|
|
|
//if ( Q_IsAbsolutePath(imageName) ) |
|
//{ |
|
// Q_strncpy( szFileName, imageName, sizeof(szFileName) ); |
|
//} |
|
//else |
|
{ |
|
if ( Q_stristr( imageName, ".pic" ) ) |
|
{ |
|
Q_snprintf( szFileName, sizeof(szFileName), "%s", imageName ); |
|
} |
|
else |
|
{ |
|
Q_snprintf( szFileName, sizeof(szFileName), "vgui/%s", imageName ); |
|
} |
|
} |
|
|
|
s_pszSearchString = szFileName; |
|
int i = m_Bitmaps.Find( searchBitmap ); |
|
if (m_Bitmaps.IsValidIndex( i ) ) |
|
{ |
|
return m_Bitmaps[i].pBitmap; |
|
} |
|
|
|
// couldn't find the image, try and load it |
|
CachedBitmapHandle_t hBitmap = { new Bitmap( szFileName, hardwareFiltered ) }; |
|
m_Bitmaps.Insert( hBitmap ); |
|
return hBitmap.pBitmap; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
HTexture CSchemeManager::GetImageID(const char *imageName, bool hardwareFiltered) |
|
{ |
|
IImage *img = GetImage(imageName, hardwareFiltered); |
|
return ((Bitmap *)img)->GetID(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Delete a managed image |
|
//----------------------------------------------------------------------------- |
|
bool CSchemeManager::DeleteImage( const char *pImageName ) |
|
{ |
|
if ( !pImageName ) |
|
{ |
|
// nothing to do |
|
return false; |
|
} |
|
|
|
// set up to search for the bitmap |
|
CachedBitmapHandle_t searchBitmap; |
|
searchBitmap.pBitmap = NULL; |
|
|
|
// Prepend 'vgui/'. Resource files try to load images assuming they live in the vgui directory. |
|
// Used to do this in Bitmap::Bitmap, moved so that the s_pszSearchString is searching for the |
|
// filename with 'vgui/' already added. |
|
char szFileName[256]; |
|
if ( Q_stristr( pImageName, ".pic" ) ) |
|
{ |
|
Q_snprintf( szFileName, sizeof(szFileName), "%s", pImageName ); |
|
} |
|
else |
|
{ |
|
Q_snprintf( szFileName, sizeof(szFileName), "vgui/%s", pImageName ); |
|
} |
|
s_pszSearchString = szFileName; |
|
|
|
int i = m_Bitmaps.Find( searchBitmap ); |
|
if ( !m_Bitmaps.IsValidIndex( i ) ) |
|
{ |
|
// not found |
|
return false; |
|
} |
|
|
|
// no way to know if eviction occured, assume it does |
|
m_Bitmaps[i].pBitmap->Evict(); |
|
delete m_Bitmaps[i].pBitmap; |
|
m_Bitmaps.RemoveAt( i ); |
|
|
|
return true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: returns a pointer to an existing border |
|
//----------------------------------------------------------------------------- |
|
IBorder *CScheme::GetBorder(const char *borderName) |
|
{ |
|
int symbol = KeyValuesSystem()->GetSymbolForString(borderName); |
|
for (int i = 0; i < m_BorderList.Count(); i++) |
|
{ |
|
if (m_BorderList[i].borderSymbol == symbol) |
|
{ |
|
return m_BorderList[i].border; |
|
} |
|
} |
|
|
|
return m_pBaseBorder; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Get the number of borders |
|
//----------------------------------------------------------------------------- |
|
int CScheme::GetBorderCount() const |
|
{ |
|
return m_BorderList.Count(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Get the border at the given index |
|
//----------------------------------------------------------------------------- |
|
IBorder *CScheme::GetBorderAtIndex( int iIndex ) |
|
{ |
|
if ( !m_BorderList.IsValidIndex( iIndex ) ) |
|
return NULL; |
|
|
|
return m_BorderList[ iIndex ].border; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Finds a font in the alias list |
|
//----------------------------------------------------------------------------- |
|
HFont CScheme::FindFontInAliasList( const char *fontName ) |
|
{ |
|
int i = m_FontAliases.Find( fontName ); |
|
if ( i != m_FontAliases.InvalidIndex() ) |
|
{ |
|
return m_FontAliases[i]._font; |
|
} |
|
|
|
// No dice |
|
return 0; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : font - |
|
// Output : char const |
|
//----------------------------------------------------------------------------- |
|
char const *CScheme::GetFontName( const HFont& font ) |
|
{ |
|
for (int i = m_FontAliases.Count(); --i >= 0; ) |
|
{ |
|
HFont fnt = (HFont)m_FontAliases[i]._font; |
|
if ( fnt == font ) |
|
return m_FontAliases[i]._trueFontName.String(); |
|
} |
|
|
|
return "<Unknown font>"; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: returns a pointer to an existing font, proportional=false means use default |
|
//----------------------------------------------------------------------------- |
|
HFont CScheme::GetFont( const char *fontName, bool proportional ) |
|
{ |
|
// First look in the list of aliases... |
|
return FindFontInAliasList( GetMungedFontName( fontName, tag, proportional ) ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose:Get the number of fonts |
|
//----------------------------------------------------------------------------- |
|
int CScheme::GetFontCount() const |
|
{ |
|
return m_FontAliases.Count(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Get the font at the given index |
|
//----------------------------------------------------------------------------- |
|
HFont CScheme::GetFontAtIndex( int iIndex ) |
|
{ |
|
if ( !m_FontAliases.IsValidIndex( iIndex ) ) |
|
return INVALID_FONT; |
|
|
|
return m_FontAliases[ iIndex ]._font; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: returns a char string of the munged name this font is stored as in the font manager |
|
//----------------------------------------------------------------------------- |
|
const char *CScheme::GetMungedFontName( const char *fontName, const char *scheme, bool proportional ) |
|
{ |
|
static char mungeBuffer[ 64 ]; |
|
if ( scheme ) |
|
{ |
|
Q_snprintf( mungeBuffer, sizeof( mungeBuffer ), "%s%s-%s", fontName, scheme, proportional ? "p" : "no" ); |
|
} |
|
else |
|
{ |
|
Q_snprintf( mungeBuffer, sizeof( mungeBuffer ), "%s-%s", fontName, proportional ? "p" : "no" ); // we don't want the "(null)" snprintf appends |
|
} |
|
return mungeBuffer; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Gets a color from the scheme file |
|
//----------------------------------------------------------------------------- |
|
Color CScheme::GetColor(const char *colorName, Color defaultColor) |
|
{ |
|
const char *pchT = LookupSchemeSetting(colorName); |
|
if (!pchT) |
|
return defaultColor; |
|
|
|
int r = 0, g = 0, b = 0, a = 0; |
|
if (sscanf(pchT, "%d %d %d %d", &r, &g, &b, &a) >= 3) |
|
return Color(r, g, b, a); |
|
|
|
return defaultColor; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Get the color at the given index |
|
//----------------------------------------------------------------------------- |
|
const KeyValues *CScheme::GetColorData() const |
|
{ |
|
return m_pkvColors; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: recursively looks up a setting |
|
//----------------------------------------------------------------------------- |
|
const char *CScheme::LookupSchemeSetting(const char *pchSetting) |
|
{ |
|
// try parse out the color |
|
int r, g, b, a = 0; |
|
int res = sscanf(pchSetting, "%d %d %d %d", &r, &g, &b, &a); |
|
if (res >= 3) |
|
{ |
|
return pchSetting; |
|
} |
|
|
|
// check the color area first |
|
const char *colStr = m_pkvColors->GetString(pchSetting, NULL); |
|
if (colStr) |
|
return colStr; |
|
|
|
// check base settings |
|
colStr = m_pkvBaseSettings->GetString(pchSetting, NULL); |
|
if (colStr) |
|
{ |
|
return LookupSchemeSetting(colStr); |
|
} |
|
|
|
return pchSetting; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: gets the minimum font height for the current language |
|
//----------------------------------------------------------------------------- |
|
int CScheme::GetMinimumFontHeightForCurrentLanguage() |
|
{ |
|
char language[64]; |
|
bool bValid; |
|
if ( IsPC() ) |
|
{ |
|
bValid = vgui::g_pSystem->GetRegistryString( "HKEY_CURRENT_USER\\Software\\Valve\\Source\\Language", language, sizeof(language)-1 ); |
|
} |
|
else |
|
{ |
|
Q_strncpy( language, XBX_GetLanguageString(), sizeof( language ) ); |
|
bValid = true; |
|
} |
|
|
|
if ( bValid ) |
|
{ |
|
if (!stricmp(language, "korean") |
|
|| !stricmp(language, "tchinese") |
|
|| !stricmp(language, "schinese") |
|
|| !stricmp(language, "japanese")) |
|
{ |
|
// the bitmap-based fonts for these languages simply don't work with a pt. size of less than 9 (13 pixels) |
|
return 13; |
|
} |
|
|
|
if ( !stricmp(language, "thai" ) ) |
|
{ |
|
// thai has problems below 18 pts |
|
return 18; |
|
} |
|
} |
|
|
|
// no special minimum height required |
|
return 0; |
|
}
|
|
|