MattKings Changes:

1) New feature of Meter=String
StringCase= [NONE | LOWER | UPPER | PROPER]
2) Changes to SetVariable to allow mathematical formulas and functions to be used in setting a variable.
This commit is contained in:
jsmorley 2010-03-18 19:48:14 +00:00
parent 65bfaa31f0
commit 3166c5d5f2
5 changed files with 165 additions and 20 deletions

View File

@ -604,6 +604,27 @@ double CConfigParser::ReadFormula(LPCTSTR section, LPCTSTR key, double defValue)
return ParseDouble(result, defValue);
}
// Returns an int if the formula was read successfully, -1 for failure.
// Pass a pointer to a double.
int CConfigParser::ReadFormula(std::wstring& result, double* resultValue)
{
// Formulas must be surrounded by parenthesis
if (!result.empty() && result[0] == L'(' && result[result.size() - 1] == L')')
{
char* errMsg = MathParser_Parse(m_Parser, ConvertToAscii(result.substr(1, result.size() - 2).c_str()).c_str(), resultValue);
if (errMsg != NULL)
{
DebugLog(ConvertToWide(errMsg).c_str());
return -1;
}
return 1;
}
return -1;
}
Color CConfigParser::ReadColor(LPCTSTR section, LPCTSTR key, Color defValue)
{
TCHAR buffer[256];

View File

@ -54,6 +54,10 @@ public:
std::wstring& GetFilename() { return m_Filename; }
const std::vector<std::wstring>& GetSections();
// Returns an int if the formula was read successfully, -1 for failure.
int ReadFormula(std::wstring& result, double* number);
static std::vector<std::wstring> Tokenize(const std::wstring& str, const std::wstring delimiters);
static void ClearMultiMonitorVariables() { c_MonitorVariables.clear(); }

View File

@ -27,6 +27,10 @@ using namespace Gdiplus;
std::map<std::wstring, Gdiplus::FontFamily*> CMeterString::c_FontFamilies;
std::map<std::wstring, Gdiplus::Font*> CMeterString::c_Fonts;
std::wstring StringToUpper(std::wstring str);
std::wstring StringToLower(std::wstring str);
std::wstring StringToProper(std::wstring str);
/*
** CMeterString
**
@ -51,6 +55,7 @@ CMeterString::CMeterString(CMeterWindow* meterWindow) : CMeter(meterWindow)
m_NumOfDecimals = -1;
m_DimensionsDefined = false;
m_Angle = 0.0;
m_textCase = TEXTCASE_NONE;
}
/*
@ -299,6 +304,28 @@ void CMeterString::ReadConfig(const WCHAR* section)
throw CError(std::wstring(L"No such StringAlign: ") + align, __LINE__, __FILE__);
}
std::wstring stringCase;
stringCase = parser.ReadString(section, L"StringCase", L"NONE");
if(_wcsicmp(stringCase.c_str(), L"NONE") == 0)
{
m_textCase = TEXTCASE_NONE;
}
else if(_wcsicmp(stringCase.c_str(), L"UPPER") == 0)
{
m_textCase = TEXTCASE_UPPER;
}
else if(_wcsicmp(stringCase.c_str(), L"LOWER") == 0)
{
m_textCase = TEXTCASE_LOWER;
}
else if(_wcsicmp(stringCase.c_str(), L"PROPER") == 0)
{
m_textCase = TEXTCASE_PROPER;
}
std::wstring style;
style = parser.ReadString(section, L"StringStyle", L"NORMAL");
@ -417,6 +444,20 @@ bool CMeterString::Update()
}
m_String += m_Postfix;
switch(m_textCase)
{
case TEXTCASE_UPPER:
m_String = StringToUpper(m_String);
break;
case TEXTCASE_LOWER:
m_String = StringToLower(m_String);
break;
case TEXTCASE_PROPER:
m_String = StringToProper(m_String);
break;
}
if (!m_DimensionsDefined)
{
// Calculate the text size
@ -623,4 +664,57 @@ std::wstring CMeterString::FontPropertiesToString(FontFamily* fontFamily, REAL s
return stream.str();
}
/*
** FontPropertiesToString
**
** Static helper to convert font properties to a string so it can be used as a key for the cache map.
**
*/
std::wstring StringToUpper(std::wstring str)
{
//change each element of the string to upper case
for(unsigned int i = 0; i < str.length(); i++)
{
str[i] = toupper( str[i] );
}
return str; //return the converted string
}
std::wstring StringToLower(std::wstring str)
{
//change each element of the string to lower case
for(unsigned int i = 0; i < str.length(); i++)
{
str[i] = tolower(str[i]);
}
return str;//return the converted string
}
std::wstring StringToProper(std::wstring str)
{
//change each element of the string to lower case
for(unsigned int i = 0; i < str.length(); i++)
{
if(i == 0)
{
str[i] = toupper( str[i] );
}
else
{
if(str[i-1] == ' ')
{
str[i] = toupper(str[i]);
}
else
{
str[i] = tolower(str[i]);
}
}
}
return str;//return the converted string
}
// EOF

View File

@ -58,26 +58,35 @@ private:
EFFECT_BORDER
};
enum TEXTCASE
{
TEXTCASE_NONE,
TEXTCASE_UPPER,
TEXTCASE_LOWER,
TEXTCASE_PROPER,
};
bool DrawString(Gdiplus::Graphics& graphics, Gdiplus::RectF* rect);
Gdiplus::Color m_Color; // The color of the text
Gdiplus::Color m_Color; // The color of the text
Gdiplus::Color m_EffectColor; // The color of the text effect
std::wstring m_Postfix; // The postfix of the text
std::wstring m_Prefix; // The prefix of the text
std::wstring m_Text; // The text
std::wstring m_FontFace; // name of the font face
bool m_AutoScale; // true, if the value should be autoscaled
METER_ALIGNMENT m_Align; // Alignment of the text
TEXTSTYLE m_Style; // Style of the text
TEXTEFFECT m_Effect; // Text effect
int m_FontSize; // Size of the fonts
double m_Scale; // Scaling if autoscale is not used
bool m_NoDecimals; // Number of decimals to use
bool m_Percentual; // True, if the value should be given as %
bool m_ClipString; // True, the text is clipped in borders (adds ellipsis to the end of the string)
Gdiplus::Font* m_Font; // The font
Gdiplus::FontFamily* m_FontFamily; // The font family
int m_NumOfDecimals; // Number of decimals to be displayed
std::wstring m_Postfix; // The postfix of the text
std::wstring m_Prefix; // The prefix of the text
std::wstring m_Text; // The text
std::wstring m_FontFace; // name of the font face
bool m_AutoScale; // true, if the value should be autoscaled
METER_ALIGNMENT m_Align; // Alignment of the text
TEXTSTYLE m_Style; // Style of the text
TEXTEFFECT m_Effect; // Text effect
TEXTCASE m_textCase; // Case of the text
int m_FontSize; // Size of the fonts
double m_Scale; // Scaling if autoscale is not used
bool m_NoDecimals; // Number of decimals to use
bool m_Percentual; // True, if the value should be given as %
bool m_ClipString; // True, the text is clipped in borders (adds ellipsis to the end of the string)
Gdiplus::Font* m_Font; // The font
Gdiplus::FontFamily* m_FontFamily; // The font family
int m_NumOfDecimals; // Number of decimals to be displayed
bool m_DimensionsDefined;
Gdiplus::REAL m_Angle;

View File

@ -732,7 +732,23 @@ void CMeterWindow::RunBang(BANGCOMMAND bang, const WCHAR* arg)
{
std::wstring strVariable(arg, pos - arg);
std::wstring strValue(pos + 1);
m_Parser.SetVariable(strVariable, strValue);
double value;
int result = m_Parser.ReadFormula(strValue, &value);
// Formula read fine
if(result != -1)
{
TCHAR buffer[256];
swprintf(buffer, L"%f", value);
const std::wstring& resultString = buffer;
m_Parser.SetVariable(strVariable, resultString);
}
else
{
m_Parser.SetVariable(strVariable, strValue);
}
}
else
{
@ -2437,7 +2453,6 @@ void CMeterWindow::Redraw()
}
}
/*
** Update
**
@ -2454,6 +2469,7 @@ void CMeterWindow::Update(bool nodraw)
// Update all measures
std::list<CMeasure*>::iterator i = m_Measures.begin();
for( ; i != m_Measures.end(); i++)
{
try
@ -2490,6 +2506,7 @@ void CMeterWindow::Update(bool nodraw)
// Statistics
CMeasureNet::UpdateStats();
OutputDebugString(L"Butts");
Rainmeter->WriteStats(false);
if (!nodraw)