mirror of
				https://github.com/chibicitiberiu/rainmeter-studio.git
				synced 2024-02-24 04:33:31 +00:00 
			
		
		
		
	- Added BackgroundMode=4 for tiling background image.
- Added tinting functions for Background. - Added "ImageCrop" option to Meter=IMAGE/BAR/HISTOGRAM/ROTATOR and Background. - Added "Tile" option to Meter=IMAGE. - Some code cleanups.
This commit is contained in:
		| @@ -672,6 +672,12 @@ const std::wstring& CConfigParser::ReadString(LPCTSTR section, LPCTSTR key, LPCT | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | bool CConfigParser::IsValueDefined(LPCTSTR section, LPCTSTR key) | ||||||
|  | { | ||||||
|  | 	ReadString(section, key, L"", false); | ||||||
|  | 	return !m_LastDefaultUsed; | ||||||
|  | } | ||||||
|  |  | ||||||
| void CConfigParser::AddMeasure(CMeasure* pMeasure) | void CConfigParser::AddMeasure(CMeasure* pMeasure) | ||||||
| { | { | ||||||
| 	if (pMeasure) | 	if (pMeasure) | ||||||
| @@ -775,6 +781,20 @@ Color CConfigParser::ReadColor(LPCTSTR section, LPCTSTR key, const Color& defVal | |||||||
| 	return (m_LastDefaultUsed) ? defValue : ParseColor(result.c_str()); | 	return (m_LastDefaultUsed) ? defValue : ParseColor(result.c_str()); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | Rect CConfigParser::ReadRect(LPCTSTR section, LPCTSTR key, const Rect& defValue) | ||||||
|  | { | ||||||
|  | 	const std::wstring& result = ReadString(section, key, L""); | ||||||
|  |  | ||||||
|  | 	return (m_LastDefaultUsed) ? defValue : ParseRect(result.c_str()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | RECT CConfigParser::ReadRECT(LPCTSTR section, LPCTSTR key, const RECT& defValue) | ||||||
|  | { | ||||||
|  | 	const std::wstring& result = ReadString(section, key, L""); | ||||||
|  |  | ||||||
|  | 	return (m_LastDefaultUsed) ? defValue : ParseRECT(result.c_str()); | ||||||
|  | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
| ** Tokenize | ** Tokenize | ||||||
| ** | ** | ||||||
| @@ -929,6 +949,76 @@ Color CConfigParser::ParseColor(LPCTSTR string) | |||||||
| 	return Color(A, R, G, B); | 	return Color(A, R, G, B); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | ** Parse4 | ||||||
|  | ** | ||||||
|  | ** This is a helper template that parses four comma separated values from the given string. | ||||||
|  | ** | ||||||
|  | */ | ||||||
|  | template <typename T> | ||||||
|  | bool Parse4(LPCTSTR string, T& v1, T& v2, T& v3, T& v4) | ||||||
|  | { | ||||||
|  | 	if (wcschr(string, L',') != NULL) | ||||||
|  | 	{ | ||||||
|  | 		WCHAR* parseSz = _wcsdup(string); | ||||||
|  | 		WCHAR* token; | ||||||
|  |  | ||||||
|  | 		token = wcstok(parseSz, L","); | ||||||
|  | 		if (token != NULL) | ||||||
|  | 		{ | ||||||
|  | 			v1 = _wtoi(token); | ||||||
|  | 		} | ||||||
|  | 		token = wcstok( NULL, L","); | ||||||
|  | 		if (token != NULL) | ||||||
|  | 		{ | ||||||
|  | 			v2 = _wtoi(token); | ||||||
|  | 		} | ||||||
|  | 		token = wcstok( NULL, L","); | ||||||
|  | 		if (token != NULL) | ||||||
|  | 		{ | ||||||
|  | 			v3 = _wtoi(token); | ||||||
|  | 		} | ||||||
|  | 		token = wcstok( NULL, L","); | ||||||
|  | 		if (token != NULL) | ||||||
|  | 		{ | ||||||
|  | 			v4 = _wtoi(token); | ||||||
|  | 		} | ||||||
|  | 		free(parseSz); | ||||||
|  |  | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | ** ParseRect | ||||||
|  | ** | ||||||
|  | ** This is a helper method that parses the Gdiplus::Rect values from the given string. | ||||||
|  | ** The rect can be supplied as four comma separated values (X/Y/Width/Height). | ||||||
|  | ** | ||||||
|  | */ | ||||||
|  | Rect CConfigParser::ParseRect(LPCTSTR string) | ||||||
|  | { | ||||||
|  | 	Rect r; | ||||||
|  | 	Parse4(string, r.X, r.Y, r.Width, r.Height); | ||||||
|  | 	return r; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | ** ParseRECT | ||||||
|  | ** | ||||||
|  | ** This is a helper method that parses the RECT values from the given string. | ||||||
|  | ** The rect can be supplied as four comma separated values (left/top/right/bottom). | ||||||
|  | ** | ||||||
|  | */ | ||||||
|  | RECT CConfigParser::ParseRECT(LPCTSTR string) | ||||||
|  | { | ||||||
|  | 	RECT r = {0}; | ||||||
|  | 	Parse4(string, r.left, r.top, r.right, r.bottom); | ||||||
|  | 	return r; | ||||||
|  | } | ||||||
|  |  | ||||||
| //============================================================================== | //============================================================================== | ||||||
| /** | /** | ||||||
| ** Reads the given ini file and fills the m_Values and m_Keys maps. | ** Reads the given ini file and fills the m_Values and m_Keys maps. | ||||||
|   | |||||||
| @@ -52,10 +52,13 @@ public: | |||||||
| 	void ResetMonitorVariables(CMeterWindow* meterWindow = NULL); | 	void ResetMonitorVariables(CMeterWindow* meterWindow = NULL); | ||||||
|  |  | ||||||
| 	const std::wstring& ReadString(LPCTSTR section, LPCTSTR key, LPCTSTR defValue, bool bReplaceMeasures = true); | 	const std::wstring& ReadString(LPCTSTR section, LPCTSTR key, LPCTSTR defValue, bool bReplaceMeasures = true); | ||||||
|  | 	bool IsValueDefined(LPCTSTR section, LPCTSTR key); | ||||||
| 	double ReadFloat(LPCTSTR section, LPCTSTR key, double defValue); | 	double ReadFloat(LPCTSTR section, LPCTSTR key, double defValue); | ||||||
| 	double ReadFormula(LPCTSTR section, LPCTSTR key, double defValue); | 	double ReadFormula(LPCTSTR section, LPCTSTR key, double defValue); | ||||||
| 	int ReadInt(LPCTSTR section, LPCTSTR key, int defValue); | 	int ReadInt(LPCTSTR section, LPCTSTR key, int defValue); | ||||||
| 	Gdiplus::Color ReadColor(LPCTSTR section, LPCTSTR key, const Gdiplus::Color& defValue); | 	Gdiplus::Color ReadColor(LPCTSTR section, LPCTSTR key, const Gdiplus::Color& defValue); | ||||||
|  | 	Gdiplus::Rect ReadRect(LPCTSTR section, LPCTSTR key, const Gdiplus::Rect& defValue); | ||||||
|  | 	RECT ReadRECT(LPCTSTR section, LPCTSTR key, const RECT& defValue); | ||||||
| 	std::vector<Gdiplus::REAL> ReadFloats(LPCTSTR section, LPCTSTR key); | 	std::vector<Gdiplus::REAL> ReadFloats(LPCTSTR section, LPCTSTR key); | ||||||
|  |  | ||||||
| 	const std::wstring& GetFilename() { return m_Filename; } | 	const std::wstring& GetFilename() { return m_Filename; } | ||||||
| @@ -67,6 +70,8 @@ public: | |||||||
| 	static std::vector<std::wstring> Tokenize(const std::wstring& str, const std::wstring& delimiters); | 	static std::vector<std::wstring> Tokenize(const std::wstring& str, const std::wstring& delimiters); | ||||||
| 	static double ParseDouble(const std::wstring& string, double defValue, bool rejectExp = false); | 	static double ParseDouble(const std::wstring& string, double defValue, bool rejectExp = false); | ||||||
| 	static Gdiplus::Color ParseColor(LPCTSTR string); | 	static Gdiplus::Color ParseColor(LPCTSTR string); | ||||||
|  | 	static Gdiplus::Rect ParseRect(LPCTSTR string); | ||||||
|  | 	static RECT ParseRECT(LPCTSTR string); | ||||||
|  |  | ||||||
| 	static void ClearMultiMonitorVariables() { c_MonitorVariables.clear(); } | 	static void ClearMultiMonitorVariables() { c_MonitorVariables.clear(); } | ||||||
| 	static void UpdateWorkareaVariables() { SetMultiMonitorVariables(false); } | 	static void UpdateWorkareaVariables() { SetMultiMonitorVariables(false); } | ||||||
|   | |||||||
| @@ -375,6 +375,11 @@ void CMeter::ReadConfig(const WCHAR* section) | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if (!m_Initialized) | ||||||
|  | 	{ | ||||||
|  | 		m_MeasureName = parser.ReadString(section, L"MeasureName", L""); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	m_SolidBevel = (BEVELTYPE)parser.ReadInt(section, L"BevelType", BEVELTYPE_NONE); | 	m_SolidBevel = (BEVELTYPE)parser.ReadInt(section, L"BevelType", BEVELTYPE_NONE); | ||||||
|  |  | ||||||
| 	m_SolidColor = parser.ReadColor(section, L"SolidColor", Color(0, 0, 0, 0)); | 	m_SolidColor = parser.ReadColor(section, L"SolidColor", Color(0, 0, 0, 0)); | ||||||
| @@ -407,8 +412,6 @@ void CMeter::ReadConfig(const WCHAR* section) | |||||||
| 	m_ToolTipType = 0!=parser.ReadInt(section, L"ToolTipType", 0); | 	m_ToolTipType = 0!=parser.ReadInt(section, L"ToolTipType", 0); | ||||||
| 	m_ToolTipHidden = 0!=parser.ReadInt(section, L"ToolTipHidden", m_ToolTipHidden); | 	m_ToolTipHidden = 0!=parser.ReadInt(section, L"ToolTipHidden", m_ToolTipHidden); | ||||||
|  |  | ||||||
| 	m_MeasureName = parser.ReadString(section, L"MeasureName", L""); |  | ||||||
|  |  | ||||||
| 	UINT updateDivider = parser.ReadInt(section, L"UpdateDivider", 1); | 	UINT updateDivider = parser.ReadInt(section, L"UpdateDivider", 1); | ||||||
| 	if (updateDivider != m_UpdateDivider) | 	if (updateDivider != m_UpdateDivider) | ||||||
| 	{ | 	{ | ||||||
| @@ -575,25 +578,28 @@ void CMeter::SetAllMeasures(const std::vector<CMeasure*>& measures) | |||||||
| */ | */ | ||||||
| void CMeter::ReplaceMeasures(const std::vector<std::wstring>& stringValues, std::wstring& str) | void CMeter::ReplaceMeasures(const std::vector<std::wstring>& stringValues, std::wstring& str) | ||||||
| { | { | ||||||
| 	WCHAR buffer[64]; | 	if (str.find(L'%') != std::wstring::npos) | ||||||
|  |  | ||||||
| 	// Create the actual text (i.e. replace %1, %2, .. with the measure texts) |  | ||||||
| 	for (size_t i = stringValues.size(); i > 0; --i) |  | ||||||
| 	{ | 	{ | ||||||
| 		wsprintf(buffer, L"%%%i", i); | 		WCHAR buffer[64]; | ||||||
|  |  | ||||||
| 		size_t start = 0; | 		// Create the actual text (i.e. replace %1, %2, .. with the measure texts) | ||||||
| 		size_t pos = std::wstring::npos; | 		for (size_t i = stringValues.size(); i > 0; --i) | ||||||
|  |  | ||||||
| 		do  |  | ||||||
| 		{ | 		{ | ||||||
| 			pos = str.find(buffer, start); | 			wsprintf(buffer, L"%%%i", i); | ||||||
| 			if (pos != std::wstring::npos) |  | ||||||
|  | 			size_t start = 0; | ||||||
|  | 			size_t pos = std::wstring::npos; | ||||||
|  |  | ||||||
|  | 			do  | ||||||
| 			{ | 			{ | ||||||
| 				str.replace(str.begin() + pos, str.begin() + pos + wcslen(buffer), stringValues[i - 1]); | 				pos = str.find(buffer, start); | ||||||
| 				start = pos + stringValues[i - 1].length(); | 				if (pos != std::wstring::npos) | ||||||
| 			} | 				{ | ||||||
| 		} while(pos != std::wstring::npos); | 					str.replace(str.begin() + pos, str.begin() + pos + wcslen(buffer), stringValues[i - 1]); | ||||||
|  | 					start = pos + stringValues[i - 1].length(); | ||||||
|  | 				} | ||||||
|  | 			} while(pos != std::wstring::npos); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -210,10 +210,13 @@ void CMeterHistogram::ReadConfig(const WCHAR* section) | |||||||
| 	m_SecondaryColor = parser.ReadColor(section, L"SecondaryColor", Color::Red); | 	m_SecondaryColor = parser.ReadColor(section, L"SecondaryColor", Color::Red); | ||||||
| 	m_BothColor = parser.ReadColor(section, L"BothColor", Color::Yellow); | 	m_BothColor = parser.ReadColor(section, L"BothColor", Color::Yellow); | ||||||
|  |  | ||||||
| 	m_SecondaryMeasureName = parser.ReadString(section, L"MeasureName2", L""); | 	if (!m_Initialized && !m_MeasureName.empty()) | ||||||
| 	if (m_SecondaryMeasureName.empty()) |  | ||||||
| 	{ | 	{ | ||||||
| 		m_SecondaryMeasureName = parser.ReadString(section, L"SecondaryMeasureName", L""); | 		m_SecondaryMeasureName = parser.ReadString(section, L"MeasureName2", L""); | ||||||
|  | 		if (m_SecondaryMeasureName.empty()) | ||||||
|  | 		{ | ||||||
|  | 			m_SecondaryMeasureName = parser.ReadString(section, L"SecondaryMeasureName", L""); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	m_PrimaryImageName = parser.ReadString(section, L"PrimaryImage", L""); | 	m_PrimaryImageName = parser.ReadString(section, L"PrimaryImage", L""); | ||||||
|   | |||||||
| @@ -38,6 +38,7 @@ CMeterImage::CMeterImage(CMeterWindow* meterWindow) : CMeter(meterWindow) | |||||||
| 	m_WidthDefined = false; | 	m_WidthDefined = false; | ||||||
| 	m_HeightDefined = false; | 	m_HeightDefined = false; | ||||||
| 	m_PreserveAspectRatio = false; | 	m_PreserveAspectRatio = false; | ||||||
|  | 	m_Tile = false; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @@ -85,14 +86,14 @@ void CMeterImage::LoadImage(bool bLoadAlways) | |||||||
| 		{ | 		{ | ||||||
| 			if (!m_HeightDefined) | 			if (!m_HeightDefined) | ||||||
| 			{ | 			{ | ||||||
| 				m_H = (imageW == 0) ? 0 : (int)(m_W * imageH / (double)imageW); | 				m_H = (imageW == 0) ? 0 : (m_Tile) ? imageH : (int)(m_W * imageH / (double)imageW); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			if (m_HeightDefined) | 			if (m_HeightDefined) | ||||||
| 			{ | 			{ | ||||||
| 				m_W = (imageH == 0) ? 0 : (int)(m_H * imageW / (double)imageH); | 				m_W = (imageH == 0) ? 0 : (m_Tile) ? imageW : (int)(m_H * imageW / (double)imageH); | ||||||
| 			} | 			} | ||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
| @@ -144,12 +145,13 @@ void CMeterImage::ReadConfig(const WCHAR* section) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	m_PreserveAspectRatio = 0!=parser.ReadInt(section, L"PreserveAspectRatio", 0); | 	m_PreserveAspectRatio = 0!=parser.ReadInt(section, L"PreserveAspectRatio", 0); | ||||||
|  | 	m_Tile = 0!=parser.ReadInt(section, L"Tile", 0); | ||||||
|  |  | ||||||
| 	if (-1 != (int)parser.ReadFormula(section, L"W", -1)) | 	if (parser.IsValueDefined(section, L"W")) | ||||||
| 	{ | 	{ | ||||||
| 		m_WidthDefined = true; | 		m_WidthDefined = true; | ||||||
| 	} | 	} | ||||||
| 	if (-1 != (int)parser.ReadFormula(section, L"H", -1)) | 	if (parser.IsValueDefined(section, L"H")) | ||||||
| 	{ | 	{ | ||||||
| 		m_HeightDefined = true; | 		m_HeightDefined = true; | ||||||
| 	} | 	} | ||||||
| @@ -215,43 +217,54 @@ bool CMeterImage::Draw(Graphics& graphics) | |||||||
| 		// Copy the image over the doublebuffer | 		// Copy the image over the doublebuffer | ||||||
| 		Bitmap* drawBitmap = m_Image.GetImage(); | 		Bitmap* drawBitmap = m_Image.GetImage(); | ||||||
|  |  | ||||||
| 		int x = GetX(); |  | ||||||
| 		int y = GetY(); |  | ||||||
| 		int imageW = drawBitmap->GetWidth(); | 		int imageW = drawBitmap->GetWidth(); | ||||||
| 		int imageH = drawBitmap->GetHeight(); | 		int imageH = drawBitmap->GetHeight(); | ||||||
|  |  | ||||||
| 		int drawW, drawH; | 		if (imageW == 0 || imageH == 0 || m_W == 0 || m_H == 0) return true; | ||||||
|  |  | ||||||
| 		if (m_PreserveAspectRatio) | 		int x = GetX(); | ||||||
|  | 		int y = GetY(); | ||||||
|  |  | ||||||
|  | 		int drawW = m_W; | ||||||
|  | 		int drawH = m_H; | ||||||
|  |  | ||||||
|  | 		ImageAttributes imgAttr; | ||||||
|  | 		bool useImgAttr = false; | ||||||
|  |  | ||||||
|  | 		if (m_Tile) | ||||||
| 		{ | 		{ | ||||||
| 			if (imageW == 0 || imageH == 0 || m_W == 0 || m_H == 0) return true; | 			imageW = m_W; | ||||||
|  | 			imageH = m_H; | ||||||
|  |  | ||||||
| 			REAL imageRatio = imageW / (REAL)imageH; | 			imgAttr.SetWrapMode(WrapModeTile); | ||||||
| 			REAL meterRatio = m_W / (REAL)m_H; | 			useImgAttr = true; | ||||||
|  |  | ||||||
| 			if (imageRatio >= meterRatio) |  | ||||||
| 			{ |  | ||||||
| 				drawW = m_W; |  | ||||||
| 				drawH = m_W * imageH / imageW; |  | ||||||
| 			} |  | ||||||
| 			else |  | ||||||
| 			{ |  | ||||||
| 				drawW = m_H * imageW / imageH; |  | ||||||
| 				drawH = m_H; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			// Centering |  | ||||||
| 			x += (m_W - drawW) / 2; |  | ||||||
| 			y += (m_H - drawH) / 2; |  | ||||||
| 		} | 		} | ||||||
| 		else | 		else if (m_PreserveAspectRatio) | ||||||
| 		{ | 		{ | ||||||
| 			drawW = m_W; | 			if (m_WidthDefined && m_HeightDefined) | ||||||
| 			drawH = m_H; | 			{ | ||||||
|  | 				REAL imageRatio = imageW / (REAL)imageH; | ||||||
|  | 				REAL meterRatio = m_W / (REAL)m_H; | ||||||
|  |  | ||||||
|  | 				if (imageRatio >= meterRatio) | ||||||
|  | 				{ | ||||||
|  | 					drawW = m_W; | ||||||
|  | 					drawH = m_W * imageH / imageW; | ||||||
|  | 				} | ||||||
|  | 				else | ||||||
|  | 				{ | ||||||
|  | 					drawW = m_H * imageW / imageH; | ||||||
|  | 					drawH = m_H; | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				// Centering | ||||||
|  | 				x += (m_W - drawW) / 2; | ||||||
|  | 				y += (m_H - drawH) / 2; | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		Rect r(x, y, drawW, drawH); | 		Rect r(x, y, drawW, drawH); | ||||||
| 		graphics.DrawImage(drawBitmap, r, 0, 0, imageW, imageH, UnitPixel); | 		graphics.DrawImage(drawBitmap, r, 0, 0, imageW, imageH, UnitPixel, (useImgAttr) ? &imgAttr : NULL); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return true; | 	return true; | ||||||
|   | |||||||
| @@ -46,6 +46,7 @@ protected: | |||||||
| 	bool m_WidthDefined; | 	bool m_WidthDefined; | ||||||
| 	bool m_HeightDefined; | 	bool m_HeightDefined; | ||||||
| 	bool m_PreserveAspectRatio;			// If true, aspect ratio of the image is preserved when the image is scaled | 	bool m_PreserveAspectRatio;			// If true, aspect ratio of the image is preserved when the image is scaled | ||||||
|  | 	bool m_Tile; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -109,7 +109,6 @@ void CMeterLine::ReadConfig(const WCHAR* section) | |||||||
|  |  | ||||||
| 	m_Colors.clear(); | 	m_Colors.clear(); | ||||||
| 	m_ScaleValues.clear(); | 	m_ScaleValues.clear(); | ||||||
| 	m_MeasureNames.clear(); |  | ||||||
|  |  | ||||||
| 	for (int i = 0; i < lineCount; ++i) | 	for (int i = 0; i < lineCount; ++i) | ||||||
| 	{ | 	{ | ||||||
| @@ -135,10 +134,13 @@ void CMeterLine::ReadConfig(const WCHAR* section) | |||||||
|  |  | ||||||
| 		m_ScaleValues.push_back(parser.ReadFloat(section, tmpName, 1.0)); | 		m_ScaleValues.push_back(parser.ReadFloat(section, tmpName, 1.0)); | ||||||
|  |  | ||||||
| 		if (i != 0) | 		if (!m_Initialized && !m_MeasureName.empty()) | ||||||
| 		{ | 		{ | ||||||
| 			swprintf(tmpName, L"MeasureName%i", i + 1); | 			if (i != 0) | ||||||
| 			m_MeasureNames.push_back(parser.ReadString(section, tmpName, L"")); | 			{ | ||||||
|  | 				swprintf(tmpName, L"MeasureName%i", i + 1); | ||||||
|  | 				m_MeasureNames.push_back(parser.ReadString(section, tmpName, L"")); | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -244,8 +244,6 @@ void CMeterString::Initialize() | |||||||
| */ | */ | ||||||
| void CMeterString::ReadConfig(const WCHAR* section) | void CMeterString::ReadConfig(const WCHAR* section) | ||||||
| { | { | ||||||
| 	WCHAR tmpName[64]; |  | ||||||
|  |  | ||||||
| 	// Store the current font values so we know if the font needs to be updated | 	// Store the current font values so we know if the font needs to be updated | ||||||
| 	std::wstring oldFontFace = m_FontFace; | 	std::wstring oldFontFace = m_FontFace; | ||||||
| 	int oldFontSize = m_FontSize; | 	int oldFontSize = m_FontSize; | ||||||
| @@ -256,11 +254,10 @@ void CMeterString::ReadConfig(const WCHAR* section) | |||||||
|  |  | ||||||
| 	CConfigParser& parser = m_MeterWindow->GetParser(); | 	CConfigParser& parser = m_MeterWindow->GetParser(); | ||||||
|  |  | ||||||
| 	m_MeasureNames.clear(); |  | ||||||
|  |  | ||||||
| 	// Check for extra measures | 	// Check for extra measures | ||||||
| 	if (!m_MeasureName.empty()) | 	if (!m_Initialized && !m_MeasureName.empty()) | ||||||
| 	{ | 	{ | ||||||
|  | 		WCHAR tmpName[64]; | ||||||
| 		int i = 2; | 		int i = 2; | ||||||
| 		bool loop = true; | 		bool loop = true; | ||||||
| 		do  | 		do  | ||||||
| @@ -415,7 +412,7 @@ void CMeterString::ReadConfig(const WCHAR* section) | |||||||
| 		throw CError(error, __LINE__, __FILE__); | 		throw CError(error, __LINE__, __FILE__); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (-1 != (int)parser.ReadFormula(section, L"W", -1) && -1 != (int)parser.ReadFormula(section, L"H", -1)) | 	if (parser.IsValueDefined(section, L"W") && parser.IsValueDefined(section, L"H")) | ||||||
| 	{ | 	{ | ||||||
| 		m_DimensionsDefined = true; | 		m_DimensionsDefined = true; | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -30,6 +30,7 @@ | |||||||
| #include "MeasureNet.h" | #include "MeasureNet.h" | ||||||
| #include "MeasurePlugin.h" | #include "MeasurePlugin.h" | ||||||
| #include "MeterButton.h" | #include "MeterButton.h" | ||||||
|  | #include "TintedImage.h" | ||||||
|  |  | ||||||
| using namespace Gdiplus; | using namespace Gdiplus; | ||||||
|  |  | ||||||
| @@ -1735,21 +1736,13 @@ bool CMeterWindow::ReadSkin() | |||||||
| 	m_BackgroundName = m_Parser.ReadString(L"Rainmeter", L"Background", L""); | 	m_BackgroundName = m_Parser.ReadString(L"Rainmeter", L"Background", L""); | ||||||
| 	m_BackgroundName = MakePathAbsolute(m_BackgroundName); | 	m_BackgroundName = MakePathAbsolute(m_BackgroundName); | ||||||
|  |  | ||||||
| 	std::wstring margins = m_Parser.ReadString(L"Rainmeter", L"BackgroundMargins", L"0, 0, 0, 0"); | 	m_BackgroundMargins = m_Parser.ReadRect(L"Rainmeter", L"BackgroundMargins", Rect(0,0,0,0)); | ||||||
| 	int left = 0, top = 0, right = 0, bottom = 0; | 	m_BackgroundMargins.Width -= m_BackgroundMargins.X; | ||||||
| 	swscanf(margins.c_str(), L"%i, %i, %i, %i", &left, &top, &right, &bottom); | 	m_BackgroundMargins.Height -= m_BackgroundMargins.Y; | ||||||
| 	m_BackgroundMargins.X = left; |  | ||||||
| 	m_BackgroundMargins.Width = right - left; |  | ||||||
| 	m_BackgroundMargins.Y = top; |  | ||||||
| 	m_BackgroundMargins.Height = bottom - top; |  | ||||||
|  |  | ||||||
| 	margins = m_Parser.ReadString(L"Rainmeter", L"DragMargins", L"0, 0, 0, 0"); | 	m_DragMargins = m_Parser.ReadRect(L"Rainmeter", L"DragMargins", Rect(0,0,0,0)); | ||||||
| 	left = 0, top = 0, right = 0, bottom = 0; | 	m_DragMargins.Width -= m_DragMargins.X; | ||||||
| 	swscanf(margins.c_str(), L"%i, %i, %i, %i", &left, &top, &right, &bottom); | 	m_DragMargins.Height -= m_DragMargins.Y; | ||||||
| 	m_DragMargins.X = left; |  | ||||||
| 	m_DragMargins.Width = right - left; |  | ||||||
| 	m_DragMargins.Y = top; |  | ||||||
| 	m_DragMargins.Height = bottom - top; |  | ||||||
|  |  | ||||||
| 	m_BackgroundMode = (BGMODE)m_Parser.ReadInt(L"Rainmeter", L"BackgroundMode", BGMODE_IMAGE); | 	m_BackgroundMode = (BGMODE)m_Parser.ReadInt(L"Rainmeter", L"BackgroundMode", BGMODE_IMAGE); | ||||||
| 	m_SolidBevel = (BEVELTYPE)m_Parser.ReadInt(L"Rainmeter", L"BevelType", BEVELTYPE_NONE); | 	m_SolidBevel = (BEVELTYPE)m_Parser.ReadInt(L"Rainmeter", L"BevelType", BEVELTYPE_NONE); | ||||||
| @@ -1760,7 +1753,7 @@ bool CMeterWindow::ReadSkin() | |||||||
|  |  | ||||||
| 	m_DynamicWindowSize = 0!=m_Parser.ReadInt(L"Rainmeter", L"DynamicWindowSize", 0); | 	m_DynamicWindowSize = 0!=m_Parser.ReadInt(L"Rainmeter", L"DynamicWindowSize", 0); | ||||||
|  |  | ||||||
| 	if ((m_BackgroundMode == BGMODE_IMAGE || m_BackgroundMode == BGMODE_SCALED_IMAGE) && m_BackgroundName.empty()) | 	if ((m_BackgroundMode == BGMODE_IMAGE || m_BackgroundMode == BGMODE_SCALED_IMAGE || m_BackgroundMode == BGMODE_TILED_IMAGE) && m_BackgroundName.empty()) | ||||||
| 	{ | 	{ | ||||||
| 		m_BackgroundMode = BGMODE_COPY; | 		m_BackgroundMode = BGMODE_COPY; | ||||||
| 	} | 	} | ||||||
| @@ -2106,17 +2099,16 @@ bool CMeterWindow::ResizeWindow(bool reset) | |||||||
| 		m_Background = NULL; | 		m_Background = NULL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ((m_BackgroundMode == BGMODE_IMAGE || m_BackgroundMode == BGMODE_SCALED_IMAGE) && !m_BackgroundName.empty()) | 	if ((m_BackgroundMode == BGMODE_IMAGE || m_BackgroundMode == BGMODE_SCALED_IMAGE || m_BackgroundMode == BGMODE_TILED_IMAGE) && !m_BackgroundName.empty()) | ||||||
| 	{ | 	{ | ||||||
| 		// Load the background | 		// Load the background | ||||||
| 		m_Background = new Bitmap(m_BackgroundName.c_str()); | 		CTintedImage tintedBackground; | ||||||
| 		Status status = m_Background->GetLastStatus(); | 		tintedBackground.SetConfigAttributes(L"Background", NULL); | ||||||
| 		if(Ok != status) | 		tintedBackground.ReadConfig(m_Parser, L"Rainmeter"); | ||||||
|  | 		tintedBackground.LoadImage(m_BackgroundName, true); | ||||||
|  |  | ||||||
|  | 		if (!tintedBackground.IsLoaded()) | ||||||
| 		{ | 		{ | ||||||
| 			std::wstring err = L"Unable to load background: " + m_BackgroundName; |  | ||||||
| 			MessageBox(m_Window, err.c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONEXCLAMATION); |  | ||||||
| 			delete m_Background; |  | ||||||
| 			m_Background = NULL; |  | ||||||
| 			m_BackgroundSize.cx = 0; | 			m_BackgroundSize.cx = 0; | ||||||
| 			m_BackgroundSize.cy = 0; | 			m_BackgroundSize.cy = 0; | ||||||
|  |  | ||||||
| @@ -2125,81 +2117,99 @@ bool CMeterWindow::ResizeWindow(bool reset) | |||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
|  | 			Bitmap* tempBackground = tintedBackground.GetImage(); | ||||||
|  |  | ||||||
| 			// Calculate the window dimensions | 			// Calculate the window dimensions | ||||||
| 			m_BackgroundSize.cx = m_Background->GetWidth(); | 			m_BackgroundSize.cx = tempBackground->GetWidth(); | ||||||
| 			m_BackgroundSize.cy = m_Background->GetHeight(); | 			m_BackgroundSize.cy = tempBackground->GetHeight(); | ||||||
|  |  | ||||||
| 			w = max(w, m_BackgroundSize.cx); | 			if (m_BackgroundMode == BGMODE_IMAGE) | ||||||
| 			h = max(h, m_BackgroundSize.cy); |  | ||||||
|  |  | ||||||
| 			if (m_BackgroundMode == BGMODE_SCALED_IMAGE) |  | ||||||
| 			{ | 			{ | ||||||
|  | 				m_Background = tempBackground->Clone(0, 0, m_BackgroundSize.cx, m_BackgroundSize.cy, PixelFormat32bppARGB); | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				w = max(w, m_BackgroundSize.cx); | ||||||
|  | 				h = max(h, m_BackgroundSize.cy); | ||||||
|  |  | ||||||
| 				// Scale the background to fill the whole window | 				// Scale the background to fill the whole window | ||||||
| 				Bitmap* scaledBackground = new Bitmap(w, h, PixelFormat32bppARGB); | 				Bitmap* background = new Bitmap(w, h, PixelFormat32bppARGB); | ||||||
|  |  | ||||||
| 				Graphics graphics(scaledBackground); | 				Graphics graphics(background); | ||||||
|  |  | ||||||
| 				if (m_BackgroundMargins.GetTop() > 0)  | 				if (m_BackgroundMode == BGMODE_SCALED_IMAGE) | ||||||
| 				{ | 				{ | ||||||
| 					if (m_BackgroundMargins.GetLeft() > 0)  | 					RECT m = {m_BackgroundMargins.GetLeft(), m_BackgroundMargins.GetTop(), m_BackgroundMargins.GetRight(), m_BackgroundMargins.GetBottom()}; | ||||||
|  |  | ||||||
|  | 					if (m.top > 0)  | ||||||
| 					{ | 					{ | ||||||
| 						// Top-Left | 						if (m.left > 0)  | ||||||
| 						Rect r(0, 0, m_BackgroundMargins.GetLeft(), m_BackgroundMargins.GetTop()); | 						{ | ||||||
| 						graphics.DrawImage(m_Background, r, 0, 0, m_BackgroundMargins.GetLeft(), m_BackgroundMargins.GetTop(), UnitPixel); | 							// Top-Left | ||||||
|  | 							Rect r(0, 0, m.left, m.top); | ||||||
|  | 							graphics.DrawImage(tempBackground, r, 0, 0, m.left, m.top, UnitPixel); | ||||||
|  | 						} | ||||||
|  |  | ||||||
|  | 						// Top | ||||||
|  | 						Rect r(m.left, 0, w - m.left - m.right, m.top); | ||||||
|  | 						graphics.DrawImage(tempBackground, r, m.left, 0, m_BackgroundSize.cx - m.left - m.right, m.top, UnitPixel); | ||||||
|  |  | ||||||
|  | 						if (m.right > 0)  | ||||||
|  | 						{ | ||||||
|  | 							// Top-Right | ||||||
|  | 							Rect r(w - m.right, 0, m.right, m.top); | ||||||
|  | 							graphics.DrawImage(tempBackground, r, m_BackgroundSize.cx - m.right, 0, m.right, m.top, UnitPixel); | ||||||
|  | 						} | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					// Top | 					if (m.left > 0)  | ||||||
| 					Rect r(m_BackgroundMargins.GetLeft(), 0, w - m_BackgroundMargins.GetLeft() - m_BackgroundMargins.GetRight(), m_BackgroundMargins.GetTop()); |  | ||||||
| 					graphics.DrawImage(m_Background, r, m_BackgroundMargins.GetLeft(), 0, m_Background->GetWidth() - m_BackgroundMargins.GetLeft() - m_BackgroundMargins.GetRight(), m_BackgroundMargins.GetTop(), UnitPixel); |  | ||||||
|  |  | ||||||
| 					if (m_BackgroundMargins.GetRight() > 0)  |  | ||||||
| 					{ | 					{ | ||||||
| 						// Top-Right | 						// Left | ||||||
| 						Rect r(w - m_BackgroundMargins.GetRight(), 0, m_BackgroundMargins.GetRight(), m_BackgroundMargins.GetTop()); | 						Rect r(0, m.top, m.left, h - m.top - m.bottom); | ||||||
| 						graphics.DrawImage(m_Background, r, m_Background->GetWidth() - m_BackgroundMargins.GetRight(), 0, m_BackgroundMargins.GetRight(), m_BackgroundMargins.GetTop(), UnitPixel); | 						graphics.DrawImage(tempBackground, r, 0, m.top, m.left, m_BackgroundSize.cy - m.top - m.bottom, UnitPixel); | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					// Center | ||||||
|  | 					Rect r(m.left, m.top, w - m.left - m.right, h - m.top - m.bottom); | ||||||
|  | 					graphics.DrawImage(tempBackground, r, m.left, m.top, m_BackgroundSize.cx - m.left - m.right, m_BackgroundSize.cy - m.top - m.bottom, UnitPixel); | ||||||
|  |  | ||||||
|  | 					if (m.right > 0)  | ||||||
|  | 					{ | ||||||
|  | 						// Right | ||||||
|  | 						Rect r(w - m.right, m.top, m.right, h - m.top - m.bottom); | ||||||
|  | 						graphics.DrawImage(tempBackground, r, m_BackgroundSize.cx - m.right, m.top, m.right, m_BackgroundSize.cy - m.top - m.bottom, UnitPixel); | ||||||
|  | 					} | ||||||
|  | 					 | ||||||
|  | 					if (m.bottom > 0)  | ||||||
|  | 					{ | ||||||
|  | 						if (m.left > 0)  | ||||||
|  | 						{ | ||||||
|  | 							// Bottom-Left | ||||||
|  | 							Rect r(0, h - m.bottom, m.left, m.bottom); | ||||||
|  | 							graphics.DrawImage(tempBackground, r, 0, m_BackgroundSize.cy - m.bottom, m.left, m.bottom, UnitPixel); | ||||||
|  | 						} | ||||||
|  | 						// Bottom | ||||||
|  | 						Rect r(m.left, h - m.bottom, w - m.left - m.right, m.bottom); | ||||||
|  | 						graphics.DrawImage(tempBackground, r, m.left, m_BackgroundSize.cy - m.bottom, m_BackgroundSize.cx - m.left - m.right, m.bottom, UnitPixel); | ||||||
|  |  | ||||||
|  | 						if (m.right > 0)  | ||||||
|  | 						{ | ||||||
|  | 							// Bottom-Right | ||||||
|  | 							Rect r(w - m.right, h - m.bottom, m.right, m.bottom); | ||||||
|  | 							graphics.DrawImage(tempBackground, r, m_BackgroundSize.cx - m.right, m_BackgroundSize.cy - m.bottom, m.right, m.bottom, UnitPixel); | ||||||
|  | 						} | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  | 				else | ||||||
| 				if (m_BackgroundMargins.GetLeft() > 0)  |  | ||||||
| 				{ | 				{ | ||||||
| 					// Left | 					ImageAttributes imgAttr; | ||||||
| 					Rect r(0, m_BackgroundMargins.GetTop(), m_BackgroundMargins.GetLeft(), h - m_BackgroundMargins.GetTop() - m_BackgroundMargins.GetBottom()); | 					imgAttr.SetWrapMode(WrapModeTile); | ||||||
| 					graphics.DrawImage(m_Background, r, 0, m_BackgroundMargins.GetTop(), m_BackgroundMargins.GetLeft(), m_Background->GetHeight() - m_BackgroundMargins.GetTop() - m_BackgroundMargins.GetBottom(), UnitPixel); |  | ||||||
|  | 					Rect r(0, 0, w, h); | ||||||
|  | 					graphics.DrawImage(tempBackground, r, 0, 0, w, h, UnitPixel, &imgAttr); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				// Center | 				m_Background = background; | ||||||
| 				Rect r(m_BackgroundMargins.GetLeft(), m_BackgroundMargins.GetTop(), w - m_BackgroundMargins.GetLeft() - m_BackgroundMargins.GetRight(), h - m_BackgroundMargins.GetTop() - m_BackgroundMargins.GetBottom()); |  | ||||||
| 				graphics.DrawImage(m_Background, r, m_BackgroundMargins.GetLeft(), m_BackgroundMargins.GetTop(), m_Background->GetWidth() - m_BackgroundMargins.GetLeft() - m_BackgroundMargins.GetRight(), m_Background->GetHeight() - m_BackgroundMargins.GetTop() - m_BackgroundMargins.GetBottom(), UnitPixel); |  | ||||||
|  |  | ||||||
| 				if (m_BackgroundMargins.GetRight() > 0)  |  | ||||||
| 				{ |  | ||||||
| 					// Right |  | ||||||
| 					Rect r(w - m_BackgroundMargins.GetRight(), m_BackgroundMargins.GetTop(), m_BackgroundMargins.GetRight(), h - m_BackgroundMargins.GetTop() - m_BackgroundMargins.GetBottom()); |  | ||||||
| 					graphics.DrawImage(m_Background, r, m_Background->GetWidth() - m_BackgroundMargins.GetRight(), m_BackgroundMargins.GetTop(), m_BackgroundMargins.GetRight(), m_Background->GetHeight() - m_BackgroundMargins.GetTop() - m_BackgroundMargins.GetBottom(), UnitPixel); |  | ||||||
| 				} |  | ||||||
| 				 |  | ||||||
| 				if (m_BackgroundMargins.GetBottom() > 0)  |  | ||||||
| 				{ |  | ||||||
| 					if (m_BackgroundMargins.GetLeft() > 0)  |  | ||||||
| 					{ |  | ||||||
| 						// Bottom-Left |  | ||||||
| 						Rect r(0, h - m_BackgroundMargins.GetBottom(), m_BackgroundMargins.GetLeft(), m_BackgroundMargins.GetBottom()); |  | ||||||
| 						graphics.DrawImage(m_Background, r, 0, m_Background->GetHeight() - m_BackgroundMargins.GetBottom(), m_BackgroundMargins.GetLeft(), m_BackgroundMargins.GetBottom(), UnitPixel); |  | ||||||
| 					} |  | ||||||
| 					// Bottom |  | ||||||
| 					Rect r(m_BackgroundMargins.GetLeft(), h - m_BackgroundMargins.GetBottom(), w - m_BackgroundMargins.GetLeft() - m_BackgroundMargins.GetRight(), m_BackgroundMargins.GetBottom()); |  | ||||||
| 					graphics.DrawImage(m_Background, r, m_BackgroundMargins.GetLeft(), m_Background->GetHeight() - m_BackgroundMargins.GetBottom(), m_Background->GetWidth() - m_BackgroundMargins.GetLeft() - m_BackgroundMargins.GetRight(), m_BackgroundMargins.GetBottom(), UnitPixel); |  | ||||||
|  |  | ||||||
| 					if (m_BackgroundMargins.GetRight() > 0)  |  | ||||||
| 					{ |  | ||||||
| 						// Bottom-Right |  | ||||||
| 						Rect r(w - m_BackgroundMargins.GetRight(), h - m_BackgroundMargins.GetBottom(), m_BackgroundMargins.GetRight(), m_BackgroundMargins.GetBottom()); |  | ||||||
| 						graphics.DrawImage(m_Background, r, m_Background->GetWidth() - m_BackgroundMargins.GetRight(), m_Background->GetHeight() - m_BackgroundMargins.GetBottom(), m_BackgroundMargins.GetRight(), m_BackgroundMargins.GetBottom(), UnitPixel); |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				delete m_Background; |  | ||||||
| 				m_Background = scaledBackground; |  | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			// Get the size form the background bitmap | 			// Get the size form the background bitmap | ||||||
| @@ -2239,34 +2249,36 @@ bool CMeterWindow::ResizeWindow(bool reset) | |||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			// Create a solid color bitmap for the background | 			if (m_WindowW != 0 && m_WindowH != 0) | ||||||
| 			m_Background = new Bitmap(m_WindowW, m_WindowH, PixelFormat32bppARGB); |  | ||||||
| 			Graphics graphics(m_Background); |  | ||||||
|  |  | ||||||
| 			if (m_SolidColor.GetValue() == m_SolidColor2.GetValue()) |  | ||||||
| 			{ | 			{ | ||||||
| 				SolidBrush solid(m_SolidColor); | 				// Create a solid color bitmap for the background | ||||||
| 				graphics.FillRectangle(&solid, 0, 0, m_WindowW, m_WindowH); | 				m_Background = new Bitmap(m_WindowW, m_WindowH, PixelFormat32bppARGB); | ||||||
| 			} | 				Graphics graphics(m_Background); | ||||||
| 			else |  | ||||||
| 			{ |  | ||||||
| 				Rect r(0, 0, m_WindowW, m_WindowH); |  | ||||||
| 				LinearGradientBrush gradient(r, m_SolidColor, m_SolidColor2, m_SolidAngle, TRUE); |  | ||||||
| 				graphics.FillRectangle(&gradient, r); |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if (m_SolidBevel != BEVELTYPE_NONE) | 				if (m_SolidColor.GetValue() == m_SolidColor2.GetValue()) | ||||||
| 			{ |  | ||||||
| 				Pen light(Color(255, 255, 255, 255)); |  | ||||||
| 				Pen dark(Color(255, 0, 0, 0)); |  | ||||||
|  |  | ||||||
| 				if (m_SolidBevel == BEVELTYPE_DOWN) |  | ||||||
| 				{ | 				{ | ||||||
| 					light.SetColor(Color(255, 0, 0, 0)); | 					graphics.Clear(m_SolidColor); | ||||||
| 					dark.SetColor(Color(255, 255, 255, 255)); | 				} | ||||||
|  | 				else | ||||||
|  | 				{ | ||||||
|  | 					Rect r(0, 0, m_WindowW, m_WindowH); | ||||||
|  | 					LinearGradientBrush gradient(r, m_SolidColor, m_SolidColor2, m_SolidAngle, TRUE); | ||||||
|  | 					graphics.FillRectangle(&gradient, r); | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				if (m_SolidBevel != BEVELTYPE_NONE) | ||||||
|  | 				{ | ||||||
|  | 					Pen light(Color(255, 255, 255, 255)); | ||||||
|  | 					Pen dark(Color(255, 0, 0, 0)); | ||||||
|  |  | ||||||
|  | 					if (m_SolidBevel == BEVELTYPE_DOWN) | ||||||
|  | 					{ | ||||||
|  | 						light.SetColor(Color(255, 0, 0, 0)); | ||||||
|  | 						dark.SetColor(Color(255, 255, 255, 255)); | ||||||
|  | 					} | ||||||
|  | 					Rect rect(0, 0, m_WindowW, m_WindowH);	 | ||||||
|  | 					CMeter::DrawBevel(graphics, rect, light, dark); | ||||||
| 				} | 				} | ||||||
| 				Rect rect(0, 0, m_WindowW, m_WindowH);	 |  | ||||||
| 				CMeter::DrawBevel(graphics, rect, light, dark); |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -77,7 +77,8 @@ enum BGMODE | |||||||
| 	BGMODE_IMAGE = 0, | 	BGMODE_IMAGE = 0, | ||||||
| 	BGMODE_COPY, | 	BGMODE_COPY, | ||||||
| 	BGMODE_SOLID, | 	BGMODE_SOLID, | ||||||
| 	BGMODE_SCALED_IMAGE | 	BGMODE_SCALED_IMAGE, | ||||||
|  | 	BGMODE_TILED_IMAGE | ||||||
| }; | }; | ||||||
|  |  | ||||||
| enum HIDEMODE | enum HIDEMODE | ||||||
|   | |||||||
| @@ -2843,9 +2843,7 @@ void CRainmeter::ReadGeneralSettings(const std::wstring& iniFile) | |||||||
| 	std::wstring area = parser.ReadString(L"Rainmeter", L"DesktopWorkArea", L""); | 	std::wstring area = parser.ReadString(L"Rainmeter", L"DesktopWorkArea", L""); | ||||||
| 	if (!area.empty()) | 	if (!area.empty()) | ||||||
| 	{ | 	{ | ||||||
| 		RECT r; | 		m_DesktopWorkAreas[0] = parser.ParseRECT(area.c_str()); | ||||||
| 		swscanf(area.c_str(), L"%i,%i,%i,%i", &r.left, &r.top, &r.right, &r.bottom); |  | ||||||
| 		m_DesktopWorkAreas[0] = r; |  | ||||||
| 		m_DesktopWorkAreaChanged = true; | 		m_DesktopWorkAreaChanged = true; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -2856,9 +2854,7 @@ void CRainmeter::ReadGeneralSettings(const std::wstring& iniFile) | |||||||
| 		area = parser.ReadString(L"Rainmeter", buffer, L""); | 		area = parser.ReadString(L"Rainmeter", buffer, L""); | ||||||
| 		if (!area.empty()) | 		if (!area.empty()) | ||||||
| 		{ | 		{ | ||||||
| 			RECT r; | 			m_DesktopWorkAreas[i] = parser.ParseRECT(area.c_str()); | ||||||
| 			swscanf(area.c_str(), L"%i,%i,%i,%i", &r.left, &r.top, &r.right, &r.bottom); |  | ||||||
| 			m_DesktopWorkAreas[i] = r; |  | ||||||
| 			m_DesktopWorkAreaChanged = true; | 			m_DesktopWorkAreaChanged = true; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -48,10 +48,12 @@ const Gdiplus::ColorMatrix CTintedImage::c_IdentifyMatrix = { | |||||||
| ** The constructor. | ** The constructor. | ||||||
| ** | ** | ||||||
| ** If disableTransform is true, following configs are ignored: | ** If disableTransform is true, following configs are ignored: | ||||||
|  | **  - ImageCrop | ||||||
| **  - ImageRotate | **  - ImageRotate | ||||||
| ** | ** | ||||||
| */ | */ | ||||||
| CTintedImage::CTintedImage(bool disableTransform) : m_DisableTransform(disableTransform), | CTintedImage::CTintedImage(bool disableTransform) : m_DisableTransform(disableTransform), | ||||||
|  | 	m_Crop(-1, -1, -1, -1), | ||||||
| 	m_ColorMatrix(c_IdentifyMatrix) | 	m_ColorMatrix(c_IdentifyMatrix) | ||||||
| { | { | ||||||
| 	SetConfigAttributes(L"Image", L""); | 	SetConfigAttributes(L"Image", L""); | ||||||
| @@ -161,7 +163,14 @@ void CTintedImage::LoadImage(const std::wstring& imageName, bool bLoadAlways) | |||||||
|  |  | ||||||
| 								if (m_Bitmap && Ok == m_Bitmap->GetLastStatus()) | 								if (m_Bitmap && Ok == m_Bitmap->GetLastStatus()) | ||||||
| 								{ | 								{ | ||||||
| 									// Check whether the new image needs tinting (or flipping, rotating) | 									// Check whether the new image needs tinting (or cropping, flipping, rotating) | ||||||
|  | 									if (!m_NeedsCrop) | ||||||
|  | 									{ | ||||||
|  | 										if (m_Crop.X != -1 || m_Crop.Y != -1 || m_Crop.Width != -1 || m_Crop.Height != -1) | ||||||
|  | 										{ | ||||||
|  | 											m_NeedsCrop = true; | ||||||
|  | 										} | ||||||
|  | 									} | ||||||
| 									if (!m_NeedsTinting) | 									if (!m_NeedsTinting) | ||||||
| 									{ | 									{ | ||||||
| 										if (m_GreyScale || !CompareColorMatrix(m_ColorMatrix, c_IdentifyMatrix)) | 										if (m_GreyScale || !CompareColorMatrix(m_ColorMatrix, c_IdentifyMatrix)) | ||||||
| @@ -212,12 +221,27 @@ void CTintedImage::LoadImage(const std::wstring& imageName, bool bLoadAlways) | |||||||
| 		if (m_Bitmap) | 		if (m_Bitmap) | ||||||
| 		{ | 		{ | ||||||
| 			// We need a copy of the image if has tinting (or flipping, rotating) | 			// We need a copy of the image if has tinting (or flipping, rotating) | ||||||
| 			if (m_NeedsTinting || m_NeedsTransform) | 			if (m_NeedsCrop || m_NeedsTinting || m_NeedsTransform) | ||||||
| 			{ | 			{ | ||||||
| 				ApplyTint(); | 				if (m_BitmapTint) | ||||||
| 				m_NeedsTinting = false; | 				{ | ||||||
|  | 					delete m_BitmapTint; | ||||||
|  | 					m_BitmapTint = NULL; | ||||||
|  | 				} | ||||||
|  |  | ||||||
| 				ApplyTransform(); | 				if (m_Bitmap->GetWidth() > 0 && m_Bitmap->GetHeight() > 0) | ||||||
|  | 				{ | ||||||
|  | 					ApplyCrop(); | ||||||
|  |  | ||||||
|  | 					if (!m_BitmapTint || (m_BitmapTint->GetWidth() > 0 && m_BitmapTint->GetHeight() > 0)) | ||||||
|  | 					{ | ||||||
|  | 						ApplyTint(); | ||||||
|  | 						ApplyTransform(); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				m_NeedsCrop = false; | ||||||
|  | 				m_NeedsTinting = false; | ||||||
| 				m_NeedsTransform = false; | 				m_NeedsTransform = false; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @@ -228,6 +252,31 @@ void CTintedImage::LoadImage(const std::wstring& imageName, bool bLoadAlways) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | ** ApplyCrop | ||||||
|  | ** | ||||||
|  | ** This will apply the cropping. | ||||||
|  | ** | ||||||
|  | */ | ||||||
|  | void CTintedImage::ApplyCrop() | ||||||
|  | { | ||||||
|  | 	if (m_Crop.Width >= 0 && m_Crop.Height >= 0) | ||||||
|  | 	{ | ||||||
|  | 		if (m_Crop.Width == 0 || m_Crop.Height == 0) | ||||||
|  | 		{ | ||||||
|  | 			m_BitmapTint = new Bitmap(0, 0, PixelFormat32bppARGB);  // create dummy bitmap | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			Rect r(0, 0, m_Crop.Width, m_Crop.Height); | ||||||
|  | 			m_BitmapTint = new Bitmap(r.Width, r.Height, PixelFormat32bppARGB); | ||||||
|  |  | ||||||
|  | 			Graphics graphics(m_BitmapTint); | ||||||
|  | 			graphics.DrawImage(m_Bitmap, r, m_Crop.X, m_Crop.Y, r.Width, r.Height, UnitPixel); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
| ** ApplyTint | ** ApplyTint | ||||||
| ** | ** | ||||||
| @@ -236,25 +285,32 @@ void CTintedImage::LoadImage(const std::wstring& imageName, bool bLoadAlways) | |||||||
| */ | */ | ||||||
| void CTintedImage::ApplyTint() | void CTintedImage::ApplyTint() | ||||||
| { | { | ||||||
| 	ImageAttributes ImgAttr; | 	if (m_GreyScale || !CompareColorMatrix(m_ColorMatrix, c_IdentifyMatrix)) | ||||||
| 	ImgAttr.SetColorMatrix(&m_ColorMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap); |  | ||||||
|  |  | ||||||
| 	delete m_BitmapTint; |  | ||||||
|  |  | ||||||
| 	Rect r(0, 0, m_Bitmap->GetWidth(), m_Bitmap->GetHeight()); |  | ||||||
| 	m_BitmapTint = new Bitmap(r.Width, r.Height, PixelFormat32bppARGB); |  | ||||||
|  |  | ||||||
| 	Graphics graphics(m_BitmapTint); |  | ||||||
|  |  | ||||||
| 	if (m_GreyScale) |  | ||||||
| 	{ | 	{ | ||||||
| 		Bitmap* gray = TurnGreyscale(m_Bitmap); | 		Bitmap* original = GetImage(); | ||||||
| 		graphics.DrawImage(gray, r, 0, 0, r.Width, r.Height, UnitPixel, &ImgAttr); |  | ||||||
| 		delete gray; | 		ImageAttributes ImgAttr; | ||||||
| 	} | 		ImgAttr.SetColorMatrix(&m_ColorMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap); | ||||||
| 	else |  | ||||||
| 	{ | 		Rect r(0, 0, original->GetWidth(), original->GetHeight()); | ||||||
| 		graphics.DrawImage(m_Bitmap, r, 0, 0, r.Width, r.Height, UnitPixel, &ImgAttr); |  | ||||||
|  | 		Bitmap* tint = new Bitmap(r.Width, r.Height, PixelFormat32bppARGB); | ||||||
|  |  | ||||||
|  | 		Graphics graphics(tint); | ||||||
|  |  | ||||||
|  | 		if (m_GreyScale) | ||||||
|  | 		{ | ||||||
|  | 			Bitmap* gray = TurnGreyscale(original); | ||||||
|  | 			graphics.DrawImage(gray, r, 0, 0, r.Width, r.Height, UnitPixel, &ImgAttr); | ||||||
|  | 			delete gray; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			graphics.DrawImage(original, r, 0, 0, r.Width, r.Height, UnitPixel, &ImgAttr); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		delete m_BitmapTint; | ||||||
|  | 		m_BitmapTint = tint; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -290,7 +346,7 @@ void CTintedImage::ApplyTransform() | |||||||
| { | { | ||||||
| 	if (m_Rotate != 0.0f) | 	if (m_Rotate != 0.0f) | ||||||
| 	{ | 	{ | ||||||
| 		Bitmap* original = (m_BitmapTint) ? m_BitmapTint : m_Bitmap; | 		Bitmap* original = GetImage(); | ||||||
|  |  | ||||||
| 		REAL originalW = (REAL)original->GetWidth(); | 		REAL originalW = (REAL)original->GetWidth(); | ||||||
| 		REAL originalH = (REAL)original->GetHeight(); | 		REAL originalH = (REAL)original->GetHeight(); | ||||||
| @@ -331,7 +387,7 @@ void CTintedImage::ApplyTransform() | |||||||
| 	} | 	} | ||||||
| 	else if (m_Flip != RotateNoneFlipNone) | 	else if (m_Flip != RotateNoneFlipNone) | ||||||
| 	{ | 	{ | ||||||
| 		Bitmap* original = (m_BitmapTint) ? m_BitmapTint : m_Bitmap; | 		Bitmap* original = GetImage(); | ||||||
|  |  | ||||||
| 		Rect r(0, 0, original->GetWidth(), original->GetHeight()); | 		Rect r(0, 0, original->GetWidth(), original->GetHeight()); | ||||||
| 		Bitmap* transform = new Bitmap(r.Width, r.Height, PixelFormat32bppARGB); | 		Bitmap* transform = new Bitmap(r.Width, r.Height, PixelFormat32bppARGB); | ||||||
| @@ -364,6 +420,7 @@ void CTintedImage::SetConfigAttributes(const WCHAR* name, const WCHAR* prefix) | |||||||
|  |  | ||||||
| 	if (prefix) | 	if (prefix) | ||||||
| 	{ | 	{ | ||||||
|  | 		(m_ConfigImageCrop    = prefix) += L"ImageCrop"; | ||||||
| 		(m_ConfigGreyscale    = prefix) += L"Greyscale"; | 		(m_ConfigGreyscale    = prefix) += L"Greyscale"; | ||||||
| 		(m_ConfigImageTint    = prefix) += L"ImageTint"; | 		(m_ConfigImageTint    = prefix) += L"ImageTint"; | ||||||
| 		(m_ConfigImageAlpha   = prefix) += L"ImageAlpha"; | 		(m_ConfigImageAlpha   = prefix) += L"ImageAlpha"; | ||||||
| @@ -386,11 +443,19 @@ void CTintedImage::SetConfigAttributes(const WCHAR* name, const WCHAR* prefix) | |||||||
| void CTintedImage::ReadConfig(CConfigParser& parser, const WCHAR* section) | void CTintedImage::ReadConfig(CConfigParser& parser, const WCHAR* section) | ||||||
| { | { | ||||||
| 	// Store the current values so we know if the image needs to be tinted or transformed | 	// Store the current values so we know if the image needs to be tinted or transformed | ||||||
|  | 	Rect oldCrop = m_Crop; | ||||||
| 	bool oldGreyScale = m_GreyScale; | 	bool oldGreyScale = m_GreyScale; | ||||||
| 	ColorMatrix oldColorMatrix = m_ColorMatrix; | 	ColorMatrix oldColorMatrix = m_ColorMatrix; | ||||||
| 	RotateFlipType oldFlip = m_Flip; | 	RotateFlipType oldFlip = m_Flip; | ||||||
| 	REAL oldRotate = m_Rotate; | 	REAL oldRotate = m_Rotate; | ||||||
|  |  | ||||||
|  | 	if (!m_DisableTransform) | ||||||
|  | 	{ | ||||||
|  | 		m_Crop = parser.ReadRect(section, m_ConfigImageCrop.c_str(), Rect(-1,-1,-1,-1)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	m_NeedsCrop = (oldCrop.X != m_Crop.X || oldCrop.Y != m_Crop.Y || oldCrop.Width != m_Crop.Width || oldCrop.Height != m_Crop.Height); | ||||||
|  |  | ||||||
| 	m_GreyScale = 0!=parser.ReadInt(section, m_ConfigGreyscale.c_str(), 0); | 	m_GreyScale = 0!=parser.ReadInt(section, m_ConfigGreyscale.c_str(), 0); | ||||||
|  |  | ||||||
| 	Color tint = parser.ReadColor(section, m_ConfigImageTint.c_str(), Color::White); | 	Color tint = parser.ReadColor(section, m_ConfigImageTint.c_str(), Color::White); | ||||||
|   | |||||||
| @@ -33,8 +33,8 @@ public: | |||||||
|  |  | ||||||
| 	bool IsLoaded() { return (m_Bitmap != NULL); } | 	bool IsLoaded() { return (m_Bitmap != NULL); } | ||||||
| 	bool IsTinted() { return (m_BitmapTint != NULL); } | 	bool IsTinted() { return (m_BitmapTint != NULL); } | ||||||
| 	bool IsConfigsChanged() { return m_NeedsTinting || m_NeedsTransform; } | 	bool IsConfigsChanged() { return m_NeedsCrop || m_NeedsTinting || m_NeedsTransform; } | ||||||
| 	void ClearConfigFlags() { m_NeedsTinting = m_NeedsTransform = false; } | 	void ClearConfigFlags() { m_NeedsCrop = m_NeedsTinting = m_NeedsTransform = false; } | ||||||
|  |  | ||||||
| 	Gdiplus::Bitmap* GetOriginalImage() { return m_Bitmap; } | 	Gdiplus::Bitmap* GetOriginalImage() { return m_Bitmap; } | ||||||
| 	Gdiplus::Bitmap* GetTintedImage() { return m_BitmapTint; } | 	Gdiplus::Bitmap* GetTintedImage() { return m_BitmapTint; } | ||||||
| @@ -44,6 +44,7 @@ public: | |||||||
| 	void LoadImage(const std::wstring& imageName, bool bLoadAlways); | 	void LoadImage(const std::wstring& imageName, bool bLoadAlways); | ||||||
|  |  | ||||||
| protected: | protected: | ||||||
|  | 	void ApplyCrop(); | ||||||
| 	void ApplyTint(); | 	void ApplyTint(); | ||||||
| 	void ApplyTransform(); | 	void ApplyTransform(); | ||||||
|  |  | ||||||
| @@ -57,6 +58,7 @@ protected: | |||||||
| 	FILETIME m_Modified; | 	FILETIME m_Modified; | ||||||
|  |  | ||||||
| 	std::wstring m_ConfigName; | 	std::wstring m_ConfigName; | ||||||
|  | 	std::wstring m_ConfigImageCrop; | ||||||
| 	std::wstring m_ConfigGreyscale; | 	std::wstring m_ConfigGreyscale; | ||||||
| 	std::wstring m_ConfigImageTint; | 	std::wstring m_ConfigImageTint; | ||||||
| 	std::wstring m_ConfigImageAlpha; | 	std::wstring m_ConfigImageAlpha; | ||||||
| @@ -70,9 +72,11 @@ protected: | |||||||
|  |  | ||||||
| 	const bool m_DisableTransform; | 	const bool m_DisableTransform; | ||||||
|  |  | ||||||
|  | 	bool m_NeedsCrop; | ||||||
| 	bool m_NeedsTinting; | 	bool m_NeedsTinting; | ||||||
| 	bool m_NeedsTransform; | 	bool m_NeedsTransform; | ||||||
|  |  | ||||||
|  | 	Gdiplus::Rect m_Crop; | ||||||
| 	bool m_GreyScale; | 	bool m_GreyScale; | ||||||
| 	Gdiplus::ColorMatrix m_ColorMatrix; | 	Gdiplus::ColorMatrix m_ColorMatrix; | ||||||
| 	Gdiplus::RotateFlipType m_Flip; | 	Gdiplus::RotateFlipType m_Flip; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 spx
					spx