Fix sizes of images stored in generic wxImageList
Sizing the images stored in the list should stick to the convention adopted in the native wxImageList implemented in wxMSW. Images stored in the list should have the sizes as it is declared for the list even if provided bitmaps have different sizes. In case of discrepancies their dimensions should be adjusted accordingly (cropped or extended).
This commit is contained in:
@@ -54,7 +54,7 @@ bool wxGenericImageList::Create( int width, int height, bool mask, int WXUNUSED(
|
||||
|
||||
namespace
|
||||
{
|
||||
wxBitmap GetImageListBitmap(const wxBitmap& bitmap, bool useMask)
|
||||
wxBitmap GetImageListBitmap(const wxBitmap& bitmap, bool useMask, const wxSize& imgSize)
|
||||
{
|
||||
wxBitmap bmp(bitmap);
|
||||
if ( useMask )
|
||||
@@ -115,7 +115,30 @@ wxBitmap GetImageListBitmap(const wxBitmap& bitmap, bool useMask)
|
||||
}
|
||||
}
|
||||
|
||||
return bmp;
|
||||
// Ensure image size is the same as the size of the images on the image list.
|
||||
wxBitmap bmpResized;
|
||||
const wxSize sz = bmp.GetSize();
|
||||
if ( sz.x == imgSize.x && sz.y == imgSize.y )
|
||||
{
|
||||
bmpResized = bmp;
|
||||
}
|
||||
else if ( sz.x > imgSize.x && sz.y > imgSize.y )
|
||||
{
|
||||
wxRect r(0, 0, imgSize.x, imgSize.y);
|
||||
bmpResized = bmp.GetSubBitmap(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if wxUSE_IMAGE
|
||||
wxImage img = bmp.ConvertToImage();
|
||||
wxImage imgResized = img.Size(imgSize, wxPoint(0, 0), 0, 0, 0);
|
||||
bmpResized = imgResized;
|
||||
#else
|
||||
bmpResized = bmp;
|
||||
#endif // wxUSE_IMAGE
|
||||
}
|
||||
|
||||
return bmpResized;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -131,29 +154,27 @@ int wxGenericImageList::Add( const wxBitmap &bitmap )
|
||||
// size: adopt the size of our first bitmap as image size.
|
||||
m_size = bitmapSize;
|
||||
}
|
||||
else // We already have a fixed size, check that the bitmap conforms to it.
|
||||
|
||||
// There is a special case: a bitmap may contain more than one image,
|
||||
// in which case we're supposed to chop it in parts, just as Windows
|
||||
// ImageList_Add() does.
|
||||
if ( bitmapSize.x == m_size.x )
|
||||
{
|
||||
// There is a special case: a bitmap may contain more than one image,
|
||||
// in which case we're supposed to chop it in parts, just as Windows
|
||||
// ImageList_Add() does.
|
||||
if ( bitmapSize.x > m_size.x && (bitmapSize.x % m_size.x == 0) )
|
||||
{
|
||||
const int numImages = bitmapSize.x / m_size.x;
|
||||
for (int subIndex = 0; subIndex < numImages; subIndex++)
|
||||
{
|
||||
wxRect rect(m_size.x * subIndex, 0, m_size.x, m_size.y);
|
||||
Add(bitmap.GetSubBitmap(rect));
|
||||
}
|
||||
|
||||
return GetImageCount() - 1;
|
||||
}
|
||||
|
||||
wxASSERT_MSG( bitmapSize == m_size,
|
||||
"All bitmaps in wxImageList must have the same size" );
|
||||
m_images.push_back(GetImageListBitmap(bitmap, m_useMask, m_size));
|
||||
}
|
||||
else if ( bitmapSize.x > m_size.x )
|
||||
{
|
||||
const int numImages = bitmapSize.x / m_size.x;
|
||||
for (int subIndex = 0; subIndex < numImages; subIndex++)
|
||||
{
|
||||
wxRect rect(m_size.x * subIndex, 0, m_size.x, m_size.y);
|
||||
m_images.push_back(GetImageListBitmap(bitmap.GetSubBitmap(rect), m_useMask, m_size));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
wxBitmap bmp = GetImageListBitmap(bitmap, m_useMask);
|
||||
m_images.push_back(bmp);
|
||||
|
||||
return GetImageCount() - 1;
|
||||
}
|
||||
@@ -175,8 +196,8 @@ int wxGenericImageList::Add( const wxBitmap& bitmap, const wxColour& maskColour
|
||||
|
||||
const wxBitmap *wxGenericImageList::DoGetPtr( int index ) const
|
||||
{
|
||||
wxCHECK_MSG( index >= 0 && (size_t)index < m_images.size(),
|
||||
NULL, wxT("wrong index in image list") );
|
||||
if ( index < 0 || (size_t)index >= m_images.size() )
|
||||
return NULL;
|
||||
|
||||
return &m_images[index];
|
||||
}
|
||||
@@ -216,7 +237,7 @@ wxGenericImageList::Replace(int index,
|
||||
if ( mask.IsOk() )
|
||||
bmp.SetMask(new wxMask(mask));
|
||||
|
||||
m_images[index] = GetImageListBitmap(bmp, m_useMask);
|
||||
m_images[index] = GetImageListBitmap(bmp, m_useMask, m_size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -195,6 +195,243 @@ TEST_CASE("ImageList:WithMask", "[imagelist][withmask]")
|
||||
CHECK(bmp2.GetWidth() == 32);
|
||||
CHECK(bmp2.GetHeight() == 32);
|
||||
}
|
||||
|
||||
SECTION("Add images with incompatible sizes")
|
||||
{
|
||||
il.RemoveAll();
|
||||
wxSize sz = il.GetSize();
|
||||
|
||||
wxBitmap bmpSmallerW(sz.GetWidth() / 2, sz.GetHeight(), 24);
|
||||
{
|
||||
wxMemoryDC mdc(bmpSmallerW);
|
||||
mdc.SetBackground(*wxBLUE_BRUSH);
|
||||
mdc.Clear();
|
||||
}
|
||||
REQUIRE(bmpSmallerW.IsOk());
|
||||
|
||||
wxBitmap bmpSmallerH(sz.GetWidth(), sz.GetHeight() / 2, 24);
|
||||
{
|
||||
wxMemoryDC mdc(bmpSmallerH);
|
||||
mdc.SetBackground(*wxBLUE_BRUSH);
|
||||
mdc.Clear();
|
||||
}
|
||||
REQUIRE(bmpSmallerH.IsOk());
|
||||
|
||||
wxBitmap bmpSmallerWH(sz.GetWidth() / 2, sz.GetHeight() / 2, 24);
|
||||
{
|
||||
wxMemoryDC mdc(bmpSmallerWH);
|
||||
mdc.SetBackground(*wxBLUE_BRUSH);
|
||||
mdc.Clear();
|
||||
}
|
||||
REQUIRE(bmpSmallerWH.IsOk());
|
||||
|
||||
wxBitmap bmpBiggerW(sz.GetWidth() * 3 / 2, sz.GetHeight(), 24);
|
||||
{
|
||||
wxMemoryDC mdc(bmpBiggerW);
|
||||
mdc.SetBackground(*wxBLUE_BRUSH);
|
||||
mdc.Clear();
|
||||
}
|
||||
REQUIRE(bmpBiggerW.IsOk());
|
||||
|
||||
wxBitmap bmpBiggerW2x(sz.GetWidth() * 2, sz.GetHeight(), 24);
|
||||
{
|
||||
wxMemoryDC mdc(bmpBiggerW2x);
|
||||
mdc.SetBackground(*wxBLUE_BRUSH);
|
||||
mdc.Clear();
|
||||
}
|
||||
REQUIRE(bmpBiggerW2x.IsOk());
|
||||
|
||||
wxBitmap bmpBiggerH(sz.GetWidth(), sz.GetHeight() * 3 / 2, 24);
|
||||
{
|
||||
wxMemoryDC mdc(bmpBiggerH);
|
||||
mdc.SetBackground(*wxBLUE_BRUSH);
|
||||
mdc.Clear();
|
||||
}
|
||||
REQUIRE(bmpBiggerH.IsOk());
|
||||
|
||||
wxBitmap bmpBiggerH2x(sz.GetWidth(), sz.GetHeight() * 2, 24);
|
||||
{
|
||||
wxMemoryDC mdc(bmpBiggerH2x);
|
||||
mdc.SetBackground(*wxBLUE_BRUSH);
|
||||
mdc.Clear();
|
||||
}
|
||||
REQUIRE(bmpBiggerH2x.IsOk());
|
||||
|
||||
wxBitmap bmpBiggerWH(sz.GetWidth() * 3 / 2, sz.GetHeight() * 3 / 2, 24);
|
||||
{
|
||||
wxMemoryDC mdc(bmpBiggerWH);
|
||||
mdc.SetBackground(*wxBLUE_BRUSH);
|
||||
mdc.Clear();
|
||||
}
|
||||
REQUIRE(bmpBiggerWH.IsOk());
|
||||
|
||||
wxBitmap bmpBiggerWH2x(sz.GetWidth() * 2, sz.GetHeight() * 2, 24);
|
||||
{
|
||||
wxMemoryDC mdc(bmpBiggerWH2x);
|
||||
mdc.SetBackground(*wxBLUE_BRUSH);
|
||||
mdc.Clear();
|
||||
}
|
||||
REQUIRE(bmpBiggerWH2x.IsOk());
|
||||
|
||||
// Adding
|
||||
int cnt = il.GetImageCount();
|
||||
int idx = il.Add(bmpSmallerW);
|
||||
CHECK(idx == -1);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
idx = il.Add(bmpSmallerH);
|
||||
CHECK(idx >= 0);
|
||||
CHECK(il.GetImageCount() == cnt + 1);
|
||||
wxBitmap bmp = il.GetBitmap(idx);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
idx = il.Add(bmpSmallerWH);
|
||||
CHECK(idx == -1);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
idx = il.Add(bmpBiggerW);
|
||||
CHECK(idx >= 0);
|
||||
CHECK(il.GetImageCount() == cnt + 1);
|
||||
bmp = il.GetBitmap(idx);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
idx = il.Add(bmpBiggerW2x);
|
||||
CHECK(idx >= 0);
|
||||
CHECK(il.GetImageCount() == cnt + 2);
|
||||
bmp = il.GetBitmap(idx);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
idx = il.Add(bmpBiggerH);
|
||||
CHECK(idx >= 0);
|
||||
CHECK(il.GetImageCount() == cnt + 1);
|
||||
bmp = il.GetBitmap(idx);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
idx = il.Add(bmpBiggerH2x);
|
||||
CHECK(idx >= 0);
|
||||
CHECK(il.GetImageCount() == cnt + 1);
|
||||
bmp = il.GetBitmap(idx);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
idx = il.Add(bmpBiggerWH);
|
||||
CHECK(idx >= 0);
|
||||
CHECK(il.GetImageCount() == cnt + 1);
|
||||
bmp = il.GetBitmap(idx);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
idx = il.Add(bmpBiggerWH2x);
|
||||
CHECK(idx >= 0);
|
||||
CHECK(il.GetImageCount() == cnt + 2);
|
||||
bmp = il.GetBitmap(idx);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
// Replacing
|
||||
il.RemoveAll();
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
bool ok = il.Replace(0, bmpRGBA);
|
||||
CHECK(ok == false);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
|
||||
// List with 1 image
|
||||
idx = il.Add(bmpRGB);
|
||||
CHECK(idx >= 0);
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
ok = il.Replace(0, bmpRGBA);
|
||||
CHECK(ok == true);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
bmp = il.GetBitmap(0);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
ok = il.Replace(0, bmpSmallerW);
|
||||
CHECK(ok == true);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
bmp = il.GetBitmap(0);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
ok = il.Replace(0, bmpSmallerH);
|
||||
CHECK(ok == true);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
bmp = il.GetBitmap(0);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
ok = il.Replace(0, bmpSmallerWH);
|
||||
CHECK(ok == true);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
bmp = il.GetBitmap(0);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
ok = il.Replace(0, bmpBiggerW);
|
||||
CHECK(ok == true);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
bmp = il.GetBitmap(0);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
ok = il.Replace(0, bmpBiggerW2x);
|
||||
CHECK(ok == true);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
bmp = il.GetBitmap(0);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
ok = il.Replace(0, bmpBiggerH);
|
||||
CHECK(ok == true);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
bmp = il.GetBitmap(0);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
ok = il.Replace(0, bmpBiggerH2x);
|
||||
CHECK(ok == true);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
bmp = il.GetBitmap(0);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
ok = il.Replace(0, bmpBiggerWH);
|
||||
CHECK(ok == true);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
bmp = il.GetBitmap(0);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
ok = il.Replace(0, bmpBiggerWH2x);
|
||||
CHECK(ok == true);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
bmp = il.GetBitmap(0);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ImageList:NoMask", "[imagelist][nomask]")
|
||||
|
Reference in New Issue
Block a user