Adds new [Meter:] and [Measure:] functionality

This commit is contained in:
Brian 2012-08-01 13:52:50 -04:00 committed by jsmorley
parent 746bd059fd
commit 06f625c91c
3 changed files with 246 additions and 36 deletions

View File

@ -23,6 +23,7 @@
#include "Rainmeter.h" #include "Rainmeter.h"
#include "System.h" #include "System.h"
#include "Measure.h" #include "Measure.h"
#include "Meter.h"
#include "resource.h" #include "resource.h"
extern CRainmeter* Rainmeter; extern CRainmeter* Rainmeter;
@ -80,6 +81,8 @@ void CConfigParser::Initialize(const std::wstring& filename, CMeterWindow* meter
m_FoundSections.clear(); m_FoundSections.clear();
m_ListVariables.clear(); m_ListVariables.clear();
m_SectionInsertPos = m_Sections.end(); m_SectionInsertPos = m_Sections.end();
m_MeterWindow = meterWindow;
} }
void CConfigParser::SetBuiltInVariables(const std::wstring& filename, const std::wstring* resourcePath, CMeterWindow* meterWindow) void CConfigParser::SetBuiltInVariables(const std::wstring& filename, const std::wstring* resourcePath, CMeterWindow* meterWindow)
@ -188,6 +191,188 @@ bool CConfigParser::GetVariable(const std::wstring& strVariable, std::wstring& s
return false; return false;
} }
/*
** Meter/Measure psuedo-variables. [MeasureName:] returns numeric value of measure.
** ie. [MeterName:X], [MeasureName:], [MeasureName:%, 2], [MeasureName:3]
*/
bool CConfigParser::GetSectionVariables(const std::wstring& strVariable, std::wstring& strValue)
{
WCHAR buffer[MAX_LINE_LENGTH];
std::vector<std::wstring> strToken = Tokenize(strVariable, L":");
if (strToken.size() == 1 && !m_Measures.empty())
{
// [MeasureName:] returns number value
CMeasure* measure = m_MeterWindow->GetMeasure(strToken[0]);
if (measure)
{
_snwprintf_s(buffer, _TRUNCATE, L"%lli", (LONGLONG)measure->GetValue());
strValue = buffer;
return true;
}
}
else if (strToken.size() == 2)
{
std::wstring args = strToken[1];
// strip off leading and trailing spaces
size_t startPos = args.find_first_not_of(L" \t");
size_t endPos = args.find_last_not_of(L" \t");
if (std::wstring::npos != startPos || std::wstring::npos != endPos)
args = args.substr(startPos, endPos - startPos + 1);
// Check meters first
// Format: [MeterName:X]
CMeter* meter = m_MeterWindow->GetMeter(strToken[0]);
if (meter)
{
WCHAR buffer[MAX_LINE_LENGTH];
if (_wcsicmp(args.c_str(), L"X") == 0)
{
_itow_s(meter->GetX(), buffer, 10);
}
else if (_wcsicmp(args.c_str(), L"Y") == 0)
{
_itow_s(meter->GetY(), buffer, 10);
}
else if (_wcsicmp(args.c_str(), L"W") == 0)
{
_itow_s(meter->GetW(), buffer, 10);
}
else if (_wcsicmp(args.c_str(), L"H") == 0)
{
_itow_s(meter->GetH(), buffer, 10);
}
else
{
return false;
}
strValue = buffer;
return true;
}
// Check measures
// Format: [MeasureName:/1000,2] [MeasureName:%,2] [MeasureName:10]
CMeasure* measure = m_MeterWindow->GetMeasure(strToken[0]);
if (measure)
{
double scale = 1.0;
int numOfDecimals = -1;
bool foundDecimal = false;
bool percentual = false;
WCHAR format[32];
std::vector<std::wstring> measureOptions = Tokenize(args, L",");
if (_wcsicmp(measureOptions[0].c_str(), L"%") == 0) // Percentual
{
percentual = true;
}
else if (_wcsicmp(measureOptions[0].substr(0,1).c_str(), L"/") == 0) // Scale
{
std::wstring tempScale = measureOptions[0].substr(1, measureOptions[0].length() - 1);
// strip off leading and trailing spaces
size_t startPos = tempScale.find_first_not_of(L" \t");
size_t endPos = tempScale.find_last_not_of(L" \t");
if ((std::wstring::npos != startPos) || (std::wstring::npos != endPos))
{
tempScale = tempScale.substr(startPos, endPos - startPos + 1);
}
scale = _wtoi(tempScale.c_str());
// _wtoi returns 0 if there is an error.
if (scale == 0 && tempScale != L"0")
scale = 1.0;
}
else // NumOfDecimals
{
std::wstring tempStr = measureOptions[0];
// strip off leading and trailing spaces
size_t startPos = tempStr.find_first_not_of(L" \t");
size_t endPos = tempStr.find_last_not_of(L" \t");
if ((std::wstring::npos != startPos) || (std::wstring::npos != endPos))
{
tempStr = tempStr.substr(startPos, endPos - startPos + 1);
}
numOfDecimals = _wtoi(tempStr.c_str());
// _wtoi returns 0 if there is an error.
if ((numOfDecimals == 0 && tempStr != L"0") || numOfDecimals < -1)
numOfDecimals = -1;
foundDecimal = true;
}
// NumOfDecimals (for Percentual and Scale)
if (measureOptions.size() == 2 && !foundDecimal)
{
std::wstring tempStr = measureOptions[1];
// strip off leading and trailing spaces
size_t startPos = tempStr.find_first_not_of(L" \t");
size_t endPos = tempStr.find_last_not_of(L" \t");
if ((std::wstring::npos != startPos) || (std::wstring::npos != endPos))
{
tempStr = tempStr.substr(startPos, endPos - startPos + 1);
}
numOfDecimals = _wtoi(tempStr.c_str());
// _wtoi returns 0 if there is an error.
if ((numOfDecimals == 0 && tempStr != L"0") || numOfDecimals < -1)
numOfDecimals = -1;
}
if (percentual)
{
double val = 100.0 * measure->GetRelativeValue();
if (numOfDecimals <= 0)
{
_itow_s((int)val, buffer, 10);
}
else
{
_snwprintf_s(format, _TRUNCATE, L"%%.%if", numOfDecimals);
_snwprintf_s(buffer, _TRUNCATE, format, val);
}
}
else
{
double val = measure->GetValue() / scale;
if (numOfDecimals == 0)
{
val += (val >= 0) ? 0.5 : -0.5;
_snwprintf_s(buffer, _TRUNCATE, L"%lli", (LONGLONG)val);
}
else if (numOfDecimals < 0)
{
int len = _snwprintf_s(buffer, _TRUNCATE, L"%.15f", val);
measure->RemoveTrailingZero(buffer, len);
}
else
{
_snwprintf_s(format, _TRUNCATE, L"%%.%if", numOfDecimals);
_snwprintf_s(buffer, _TRUNCATE, format, val);
}
}
strValue = buffer;
return true;
}
}
return false;
}
void CConfigParser::ResetMonitorVariables(CMeterWindow* meterWindow) void CConfigParser::ResetMonitorVariables(CMeterWindow* meterWindow)
{ {
// Set the SCREENAREA/WORKAREA variables // Set the SCREENAREA/WORKAREA variables
@ -498,40 +683,47 @@ bool CConfigParser::ReplaceMeasures(std::wstring& result)
{ {
bool replaced = false; bool replaced = false;
// Check for measures ([Measure]) size_t start = 0, end, next;
if (!m_Measures.empty()) bool loop = true;
{
size_t start = 0, end, next;
bool loop = true;
do do
{
start = result.find(L'[', start);
if (start != std::wstring::npos)
{ {
start = result.find(L'[', start); size_t si = start + 1;
if (start != std::wstring::npos) end = result.find(L']', si);
if (end != std::wstring::npos)
{ {
size_t si = start + 1; next = result.find(L'[', si);
end = result.find(L']', si); if (next == std::wstring::npos || end < next)
if (end != std::wstring::npos)
{ {
next = result.find(L'[', si); size_t ei = end - 1;
if (next == std::wstring::npos || end < next) if (si != ei && result[si] == L'*' && result[ei] == L'*')
{ {
size_t ei = end - 1; result.erase(ei, 1);
if (si != ei && result[si] == L'*' && result[ei] == L'*') result.erase(si, 1);
start = ei;
}
else
{
std::wstring var = result.substr(si, end - si);
CMeasure* measure = GetMeasure(var);
if (measure)
{ {
result.erase(ei, 1); const std::wstring& value = measure->GetStringValue(AUTOSCALE_OFF, 1, -1, false);
result.erase(si, 1);
start = ei; // Measure found, replace it with the value
result.replace(start, end - start + 1, value);
start += value.length();
replaced = true;
} }
else else
{ {
std::wstring var = result.substr(si, end - si); std::wstring value;
if (GetSectionVariables(var, value))
CMeasure* measure = GetMeasure(var);
if (measure)
{ {
const std::wstring& value = measure->GetStringValue(AUTOSCALE_OFF, 1, -1, false);
// Measure found, replace it with the value // Measure found, replace it with the value
result.replace(start, end - start + 1, value); result.replace(start, end - start + 1, value);
start += value.length(); start += value.length();
@ -543,14 +735,10 @@ bool CConfigParser::ReplaceMeasures(std::wstring& result)
} }
} }
} }
else
{
start = next;
}
} }
else else
{ {
loop = false; start = next;
} }
} }
else else
@ -558,8 +746,12 @@ bool CConfigParser::ReplaceMeasures(std::wstring& result)
loop = false; loop = false;
} }
} }
while (loop); else
{
loop = false;
}
} }
while (loop);
return replaced; return replaced;
} }

View File

@ -33,6 +33,7 @@
class CRainmeter; class CRainmeter;
class CMeterWindow; class CMeterWindow;
class CMeasure; class CMeasure;
class CMeter;
class CConfigParser class CConfigParser
{ {
@ -109,6 +110,8 @@ private:
void SetAutoSelectedMonitorVariables(CMeterWindow* meterWindow); void SetAutoSelectedMonitorVariables(CMeterWindow* meterWindow);
bool GetSectionVariables(const std::wstring& strVariable, std::wstring& strValue);
static void SetVariable(std::unordered_map<std::wstring, std::wstring>& variables, const std::wstring& strVariable, const std::wstring& strValue); static void SetVariable(std::unordered_map<std::wstring, std::wstring>& variables, const std::wstring& strVariable, const std::wstring& strValue);
static void SetVariable(std::unordered_map<std::wstring, std::wstring>& variables, const WCHAR* strVariable, const WCHAR* strValue); static void SetVariable(std::unordered_map<std::wstring, std::wstring>& variables, const WCHAR* strVariable, const WCHAR* strValue);
@ -140,6 +143,8 @@ private:
std::unordered_map<std::wstring, std::wstring> m_BuiltInVariables; std::unordered_map<std::wstring, std::wstring> m_BuiltInVariables;
std::unordered_map<std::wstring, std::wstring> m_Variables; std::unordered_map<std::wstring, std::wstring> m_Variables;
CMeterWindow* m_MeterWindow;
static std::unordered_map<std::wstring, std::wstring> c_MonitorVariables; static std::unordered_map<std::wstring, std::wstring> c_MonitorVariables;
}; };

View File

@ -42,8 +42,8 @@ extern CRainmeter* Rainmeter;
CMeter::CMeter(CMeterWindow* meterWindow, const WCHAR* name) : m_MeterWindow(meterWindow), m_Name(name), CMeter::CMeter(CMeterWindow* meterWindow, const WCHAR* name) : m_MeterWindow(meterWindow), m_Name(name),
m_X(), m_X(),
m_Y(), m_Y(),
m_W(), m_W(0),
m_H(), m_H(0),
m_Hidden(false), m_Hidden(false),
m_WDefined(false), m_WDefined(false),
m_HDefined(false), m_HDefined(false),
@ -291,11 +291,24 @@ void CMeter::ReadOptions(CConfigParser& parser, const WCHAR* section)
m_RelativeY = POSITION_ABSOLUTE; m_RelativeY = POSITION_ABSOLUTE;
} }
m_W = parser.ReadInt(section, L"W", 1); bool oldWDefined = m_WDefined;
m_WDefined = parser.GetLastValueDefined(); bool oldHDefined = m_HDefined;
m_H = parser.ReadInt(section, L"H", 1); m_W = parser.ReadInt(section, L"W", m_W);
m_WDefined = parser.GetLastValueDefined();
if (!m_WDefined && oldWDefined)
{
m_W = 0;
parser.SetValue(section, L"W", L"0");
}
m_H = parser.ReadInt(section, L"H", m_H);
m_HDefined = parser.GetLastValueDefined(); m_HDefined = parser.GetLastValueDefined();
if (!m_HDefined && oldHDefined)
{
m_H = 0;
parser.SetValue(section, L"H", L"0");
}
bool oldHidden = m_Hidden; bool oldHidden = m_Hidden;
m_Hidden = 0!=parser.ReadInt(section, L"Hidden", 0); m_Hidden = 0!=parser.ReadInt(section, L"Hidden", 0);