- 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:
spx 2010-12-04 15:07:28 +00:00
parent 19294c4339
commit 96c81ac516
13 changed files with 395 additions and 200 deletions

View File

@ -672,6 +672,12 @@ const std::wstring& CConfigParser::ReadString(LPCTSTR section, LPCTSTR key, LPCT
return result;
}
bool CConfigParser::IsValueDefined(LPCTSTR section, LPCTSTR key)
{
ReadString(section, key, L"", false);
return !m_LastDefaultUsed;
}
void CConfigParser::AddMeasure(CMeasure* 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());
}
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
**
@ -929,6 +949,76 @@ Color CConfigParser::ParseColor(LPCTSTR string)
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.

View File

@ -52,10 +52,13 @@ public:
void ResetMonitorVariables(CMeterWindow* meterWindow = NULL);
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 ReadFormula(LPCTSTR section, LPCTSTR key, double defValue);
int ReadInt(LPCTSTR section, LPCTSTR key, int 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);
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 double ParseDouble(const std::wstring& string, double defValue, bool rejectExp = false);
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 UpdateWorkareaVariables() { SetMultiMonitorVariables(false); }

View File

@ -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_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_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);
if (updateDivider != m_UpdateDivider)
{
@ -575,6 +578,8 @@ void CMeter::SetAllMeasures(const std::vector<CMeasure*>& measures)
*/
void CMeter::ReplaceMeasures(const std::vector<std::wstring>& stringValues, std::wstring& str)
{
if (str.find(L'%') != std::wstring::npos)
{
WCHAR buffer[64];
// Create the actual text (i.e. replace %1, %2, .. with the measure texts)
@ -595,6 +600,7 @@ void CMeter::ReplaceMeasures(const std::vector<std::wstring>& stringValues, std:
}
} while(pos != std::wstring::npos);
}
}
}
/*

View File

@ -210,11 +210,14 @@ void CMeterHistogram::ReadConfig(const WCHAR* section)
m_SecondaryColor = parser.ReadColor(section, L"SecondaryColor", Color::Red);
m_BothColor = parser.ReadColor(section, L"BothColor", Color::Yellow);
if (!m_Initialized && !m_MeasureName.empty())
{
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"");
if (!m_PrimaryImageName.empty())

View File

@ -38,6 +38,7 @@ CMeterImage::CMeterImage(CMeterWindow* meterWindow) : CMeter(meterWindow)
m_WidthDefined = false;
m_HeightDefined = false;
m_PreserveAspectRatio = false;
m_Tile = false;
}
/*
@ -85,14 +86,14 @@ void CMeterImage::LoadImage(bool bLoadAlways)
{
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
{
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
{
@ -144,12 +145,13 @@ void CMeterImage::ReadConfig(const WCHAR* section)
}
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;
}
if (-1 != (int)parser.ReadFormula(section, L"H", -1))
if (parser.IsValueDefined(section, L"H"))
{
m_HeightDefined = true;
}
@ -215,17 +217,32 @@ bool CMeterImage::Draw(Graphics& graphics)
// Copy the image over the doublebuffer
Bitmap* drawBitmap = m_Image.GetImage();
int x = GetX();
int y = GetY();
int imageW = drawBitmap->GetWidth();
int imageH = drawBitmap->GetHeight();
int drawW, drawH;
if (m_PreserveAspectRatio)
{
if (imageW == 0 || imageH == 0 || m_W == 0 || m_H == 0) return true;
int x = GetX();
int y = GetY();
int drawW = m_W;
int drawH = m_H;
ImageAttributes imgAttr;
bool useImgAttr = false;
if (m_Tile)
{
imageW = m_W;
imageH = m_H;
imgAttr.SetWrapMode(WrapModeTile);
useImgAttr = true;
}
else if (m_PreserveAspectRatio)
{
if (m_WidthDefined && m_HeightDefined)
{
REAL imageRatio = imageW / (REAL)imageH;
REAL meterRatio = m_W / (REAL)m_H;
@ -244,14 +261,10 @@ bool CMeterImage::Draw(Graphics& graphics)
x += (m_W - drawW) / 2;
y += (m_H - drawH) / 2;
}
else
{
drawW = m_W;
drawH = m_H;
}
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;

View File

@ -46,6 +46,7 @@ protected:
bool m_WidthDefined;
bool m_HeightDefined;
bool m_PreserveAspectRatio; // If true, aspect ratio of the image is preserved when the image is scaled
bool m_Tile;
};
#endif

View File

@ -109,7 +109,6 @@ void CMeterLine::ReadConfig(const WCHAR* section)
m_Colors.clear();
m_ScaleValues.clear();
m_MeasureNames.clear();
for (int i = 0; i < lineCount; ++i)
{
@ -135,12 +134,15 @@ void CMeterLine::ReadConfig(const WCHAR* section)
m_ScaleValues.push_back(parser.ReadFloat(section, tmpName, 1.0));
if (!m_Initialized && !m_MeasureName.empty())
{
if (i != 0)
{
swprintf(tmpName, L"MeasureName%i", i + 1);
m_MeasureNames.push_back(parser.ReadString(section, tmpName, L""));
}
}
}
m_Flip = 0!=parser.ReadInt(section, L"Flip", 0);
m_Autoscale = 0!=parser.ReadInt(section, L"AutoScale", 0);

View File

@ -244,8 +244,6 @@ void CMeterString::Initialize()
*/
void CMeterString::ReadConfig(const WCHAR* section)
{
WCHAR tmpName[64];
// Store the current font values so we know if the font needs to be updated
std::wstring oldFontFace = m_FontFace;
int oldFontSize = m_FontSize;
@ -256,11 +254,10 @@ void CMeterString::ReadConfig(const WCHAR* section)
CConfigParser& parser = m_MeterWindow->GetParser();
m_MeasureNames.clear();
// Check for extra measures
if (!m_MeasureName.empty())
if (!m_Initialized && !m_MeasureName.empty())
{
WCHAR tmpName[64];
int i = 2;
bool loop = true;
do
@ -415,7 +412,7 @@ void CMeterString::ReadConfig(const WCHAR* section)
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;
}

View File

@ -30,6 +30,7 @@
#include "MeasureNet.h"
#include "MeasurePlugin.h"
#include "MeterButton.h"
#include "TintedImage.h"
using namespace Gdiplus;
@ -1735,21 +1736,13 @@ bool CMeterWindow::ReadSkin()
m_BackgroundName = m_Parser.ReadString(L"Rainmeter", L"Background", L"");
m_BackgroundName = MakePathAbsolute(m_BackgroundName);
std::wstring margins = m_Parser.ReadString(L"Rainmeter", L"BackgroundMargins", L"0, 0, 0, 0");
int left = 0, top = 0, right = 0, bottom = 0;
swscanf(margins.c_str(), L"%i, %i, %i, %i", &left, &top, &right, &bottom);
m_BackgroundMargins.X = left;
m_BackgroundMargins.Width = right - left;
m_BackgroundMargins.Y = top;
m_BackgroundMargins.Height = bottom - top;
m_BackgroundMargins = m_Parser.ReadRect(L"Rainmeter", L"BackgroundMargins", Rect(0,0,0,0));
m_BackgroundMargins.Width -= m_BackgroundMargins.X;
m_BackgroundMargins.Height -= m_BackgroundMargins.Y;
margins = m_Parser.ReadString(L"Rainmeter", L"DragMargins", L"0, 0, 0, 0");
left = 0, top = 0, right = 0, bottom = 0;
swscanf(margins.c_str(), L"%i, %i, %i, %i", &left, &top, &right, &bottom);
m_DragMargins.X = left;
m_DragMargins.Width = right - left;
m_DragMargins.Y = top;
m_DragMargins.Height = bottom - top;
m_DragMargins = m_Parser.ReadRect(L"Rainmeter", L"DragMargins", Rect(0,0,0,0));
m_DragMargins.Width -= m_DragMargins.X;
m_DragMargins.Height -= m_DragMargins.Y;
m_BackgroundMode = (BGMODE)m_Parser.ReadInt(L"Rainmeter", L"BackgroundMode", BGMODE_IMAGE);
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);
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;
}
@ -2106,17 +2099,16 @@ bool CMeterWindow::ResizeWindow(bool reset)
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
m_Background = new Bitmap(m_BackgroundName.c_str());
Status status = m_Background->GetLastStatus();
if(Ok != status)
CTintedImage tintedBackground;
tintedBackground.SetConfigAttributes(L"Background", NULL);
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.cy = 0;
@ -2125,81 +2117,99 @@ bool CMeterWindow::ResizeWindow(bool reset)
}
else
{
// Calculate the window dimensions
m_BackgroundSize.cx = m_Background->GetWidth();
m_BackgroundSize.cy = m_Background->GetHeight();
Bitmap* tempBackground = tintedBackground.GetImage();
// Calculate the window dimensions
m_BackgroundSize.cx = tempBackground->GetWidth();
m_BackgroundSize.cy = tempBackground->GetHeight();
if (m_BackgroundMode == BGMODE_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
Bitmap* background = new Bitmap(w, h, PixelFormat32bppARGB);
Graphics graphics(background);
if (m_BackgroundMode == BGMODE_SCALED_IMAGE)
{
// Scale the background to fill the whole window
Bitmap* scaledBackground = new Bitmap(w, h, PixelFormat32bppARGB);
RECT m = {m_BackgroundMargins.GetLeft(), m_BackgroundMargins.GetTop(), m_BackgroundMargins.GetRight(), m_BackgroundMargins.GetBottom()};
Graphics graphics(scaledBackground);
if (m_BackgroundMargins.GetTop() > 0)
if (m.top > 0)
{
if (m_BackgroundMargins.GetLeft() > 0)
if (m.left > 0)
{
// Top-Left
Rect r(0, 0, m_BackgroundMargins.GetLeft(), m_BackgroundMargins.GetTop());
graphics.DrawImage(m_Background, r, 0, 0, m_BackgroundMargins.GetLeft(), m_BackgroundMargins.GetTop(), UnitPixel);
Rect r(0, 0, m.left, m.top);
graphics.DrawImage(tempBackground, r, 0, 0, m.left, m.top, UnitPixel);
}
// Top
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);
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_BackgroundMargins.GetRight() > 0)
if (m.right > 0)
{
// Top-Right
Rect r(w - m_BackgroundMargins.GetRight(), 0, m_BackgroundMargins.GetRight(), m_BackgroundMargins.GetTop());
graphics.DrawImage(m_Background, r, m_Background->GetWidth() - m_BackgroundMargins.GetRight(), 0, m_BackgroundMargins.GetRight(), m_BackgroundMargins.GetTop(), UnitPixel);
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);
}
}
if (m_BackgroundMargins.GetLeft() > 0)
if (m.left > 0)
{
// Left
Rect r(0, m_BackgroundMargins.GetTop(), m_BackgroundMargins.GetLeft(), h - m_BackgroundMargins.GetTop() - m_BackgroundMargins.GetBottom());
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, m.top, m.left, h - m.top - m.bottom);
graphics.DrawImage(tempBackground, r, 0, m.top, m.left, m_BackgroundSize.cy - m.top - m.bottom, UnitPixel);
}
// Center
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);
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_BackgroundMargins.GetRight() > 0)
if (m.right > 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);
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_BackgroundMargins.GetBottom() > 0)
if (m.bottom > 0)
{
if (m_BackgroundMargins.GetLeft() > 0)
if (m.left > 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);
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_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);
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_BackgroundMargins.GetRight() > 0)
if (m.right > 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);
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
{
ImageAttributes imgAttr;
imgAttr.SetWrapMode(WrapModeTile);
Rect r(0, 0, w, h);
graphics.DrawImage(tempBackground, r, 0, 0, w, h, UnitPixel, &imgAttr);
}
delete m_Background;
m_Background = scaledBackground;
m_Background = background;
}
// Get the size form the background bitmap
@ -2238,6 +2248,8 @@ bool CMeterWindow::ResizeWindow(bool reset)
}
}
else
{
if (m_WindowW != 0 && m_WindowH != 0)
{
// Create a solid color bitmap for the background
m_Background = new Bitmap(m_WindowW, m_WindowH, PixelFormat32bppARGB);
@ -2245,8 +2257,7 @@ bool CMeterWindow::ResizeWindow(bool reset)
if (m_SolidColor.GetValue() == m_SolidColor2.GetValue())
{
SolidBrush solid(m_SolidColor);
graphics.FillRectangle(&solid, 0, 0, m_WindowW, m_WindowH);
graphics.Clear(m_SolidColor);
}
else
{
@ -2270,6 +2281,7 @@ bool CMeterWindow::ResizeWindow(bool reset)
}
}
}
}
return true;
}

View File

@ -77,7 +77,8 @@ enum BGMODE
BGMODE_IMAGE = 0,
BGMODE_COPY,
BGMODE_SOLID,
BGMODE_SCALED_IMAGE
BGMODE_SCALED_IMAGE,
BGMODE_TILED_IMAGE
};
enum HIDEMODE

View File

@ -2843,9 +2843,7 @@ void CRainmeter::ReadGeneralSettings(const std::wstring& iniFile)
std::wstring area = parser.ReadString(L"Rainmeter", L"DesktopWorkArea", L"");
if (!area.empty())
{
RECT r;
swscanf(area.c_str(), L"%i,%i,%i,%i", &r.left, &r.top, &r.right, &r.bottom);
m_DesktopWorkAreas[0] = r;
m_DesktopWorkAreas[0] = parser.ParseRECT(area.c_str());
m_DesktopWorkAreaChanged = true;
}
@ -2856,9 +2854,7 @@ void CRainmeter::ReadGeneralSettings(const std::wstring& iniFile)
area = parser.ReadString(L"Rainmeter", buffer, L"");
if (!area.empty())
{
RECT r;
swscanf(area.c_str(), L"%i,%i,%i,%i", &r.left, &r.top, &r.right, &r.bottom);
m_DesktopWorkAreas[i] = r;
m_DesktopWorkAreas[i] = parser.ParseRECT(area.c_str());
m_DesktopWorkAreaChanged = true;
}
}

View File

@ -48,10 +48,12 @@ const Gdiplus::ColorMatrix CTintedImage::c_IdentifyMatrix = {
** The constructor.
**
** If disableTransform is true, following configs are ignored:
** - ImageCrop
** - ImageRotate
**
*/
CTintedImage::CTintedImage(bool disableTransform) : m_DisableTransform(disableTransform),
m_Crop(-1, -1, -1, -1),
m_ColorMatrix(c_IdentifyMatrix)
{
SetConfigAttributes(L"Image", L"");
@ -161,7 +163,14 @@ void CTintedImage::LoadImage(const std::wstring& imageName, bool bLoadAlways)
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_GreyScale || !CompareColorMatrix(m_ColorMatrix, c_IdentifyMatrix))
@ -212,12 +221,27 @@ void CTintedImage::LoadImage(const std::wstring& imageName, bool bLoadAlways)
if (m_Bitmap)
{
// 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)
{
if (m_BitmapTint)
{
delete m_BitmapTint;
m_BitmapTint = NULL;
}
if (m_Bitmap->GetWidth() > 0 && m_Bitmap->GetHeight() > 0)
{
ApplyCrop();
if (!m_BitmapTint || (m_BitmapTint->GetWidth() > 0 && m_BitmapTint->GetHeight() > 0))
{
ApplyTint();
m_NeedsTinting = false;
ApplyTransform();
}
}
m_NeedsCrop = false;
m_NeedsTinting = 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
**
@ -236,25 +285,32 @@ void CTintedImage::LoadImage(const std::wstring& imageName, bool bLoadAlways)
*/
void CTintedImage::ApplyTint()
{
if (m_GreyScale || !CompareColorMatrix(m_ColorMatrix, c_IdentifyMatrix))
{
Bitmap* original = GetImage();
ImageAttributes ImgAttr;
ImgAttr.SetColorMatrix(&m_ColorMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap);
delete m_BitmapTint;
Rect r(0, 0, original->GetWidth(), original->GetHeight());
Rect r(0, 0, m_Bitmap->GetWidth(), m_Bitmap->GetHeight());
m_BitmapTint = new Bitmap(r.Width, r.Height, PixelFormat32bppARGB);
Bitmap* tint = new Bitmap(r.Width, r.Height, PixelFormat32bppARGB);
Graphics graphics(m_BitmapTint);
Graphics graphics(tint);
if (m_GreyScale)
{
Bitmap* gray = TurnGreyscale(m_Bitmap);
Bitmap* gray = TurnGreyscale(original);
graphics.DrawImage(gray, r, 0, 0, r.Width, r.Height, UnitPixel, &ImgAttr);
delete gray;
}
else
{
graphics.DrawImage(m_Bitmap, r, 0, 0, r.Width, r.Height, UnitPixel, &ImgAttr);
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)
{
Bitmap* original = (m_BitmapTint) ? m_BitmapTint : m_Bitmap;
Bitmap* original = GetImage();
REAL originalW = (REAL)original->GetWidth();
REAL originalH = (REAL)original->GetHeight();
@ -331,7 +387,7 @@ void CTintedImage::ApplyTransform()
}
else if (m_Flip != RotateNoneFlipNone)
{
Bitmap* original = (m_BitmapTint) ? m_BitmapTint : m_Bitmap;
Bitmap* original = GetImage();
Rect r(0, 0, original->GetWidth(), original->GetHeight());
Bitmap* transform = new Bitmap(r.Width, r.Height, PixelFormat32bppARGB);
@ -364,6 +420,7 @@ void CTintedImage::SetConfigAttributes(const WCHAR* name, const WCHAR* prefix)
if (prefix)
{
(m_ConfigImageCrop = prefix) += L"ImageCrop";
(m_ConfigGreyscale = prefix) += L"Greyscale";
(m_ConfigImageTint = prefix) += L"ImageTint";
(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)
{
// Store the current values so we know if the image needs to be tinted or transformed
Rect oldCrop = m_Crop;
bool oldGreyScale = m_GreyScale;
ColorMatrix oldColorMatrix = m_ColorMatrix;
RotateFlipType oldFlip = m_Flip;
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);
Color tint = parser.ReadColor(section, m_ConfigImageTint.c_str(), Color::White);

View File

@ -33,8 +33,8 @@ public:
bool IsLoaded() { return (m_Bitmap != NULL); }
bool IsTinted() { return (m_BitmapTint != NULL); }
bool IsConfigsChanged() { return m_NeedsTinting || m_NeedsTransform; }
void ClearConfigFlags() { m_NeedsTinting = m_NeedsTransform = false; }
bool IsConfigsChanged() { return m_NeedsCrop || m_NeedsTinting || m_NeedsTransform; }
void ClearConfigFlags() { m_NeedsCrop = m_NeedsTinting = m_NeedsTransform = false; }
Gdiplus::Bitmap* GetOriginalImage() { return m_Bitmap; }
Gdiplus::Bitmap* GetTintedImage() { return m_BitmapTint; }
@ -44,6 +44,7 @@ public:
void LoadImage(const std::wstring& imageName, bool bLoadAlways);
protected:
void ApplyCrop();
void ApplyTint();
void ApplyTransform();
@ -57,6 +58,7 @@ protected:
FILETIME m_Modified;
std::wstring m_ConfigName;
std::wstring m_ConfigImageCrop;
std::wstring m_ConfigGreyscale;
std::wstring m_ConfigImageTint;
std::wstring m_ConfigImageAlpha;
@ -70,9 +72,11 @@ protected:
const bool m_DisableTransform;
bool m_NeedsCrop;
bool m_NeedsTinting;
bool m_NeedsTransform;
Gdiplus::Rect m_Crop;
bool m_GreyScale;
Gdiplus::ColorMatrix m_ColorMatrix;
Gdiplus::RotateFlipType m_Flip;