Support high DPI bitmaps in wxGenericListCtrl

Use wxWithImages::GetImageBitmapFor() instead of wxImageList in this
control code to ensure that we use the provided high DPI bitmaps, if we
have them, instead of always scaling up the fixed-size image list
images.

Closes #22907.
This commit is contained in:
Gerhard Stein 2022-10-22 21:35:58 +02:00 committed by Vadim Zeitlin
parent ed6c25beed
commit 502e189f47
2 changed files with 53 additions and 48 deletions

View file

@ -1134,13 +1134,13 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
// and the width of the icon, if any
int ix = 0, iy = 0; // init them just to suppress the compiler warnings
const int image = item.m_image;
wxImageList *imageList;
wxWithImages *imageList;
if ( image != -1 )
{
imageList = m_owner->GetSmallImageList();
imageList = m_owner->GetSmallImages();
if ( imageList )
{
imageList->GetSize(image, ix, iy);
imageList->GetImageLogicalSize(this, image, ix, iy);
wLabel += ix + HEADER_IMAGE_MARGIN_IN_REPORT_MODE;
}
}
@ -1177,14 +1177,12 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
// if we have an image, draw it on the right of the label
if ( imageList )
{
imageList->Draw
(
image,
dc,
xAligned + wLabel - ix - HEADER_IMAGE_MARGIN_IN_REPORT_MODE,
HEADER_OFFSET_Y + (h - iy)/2,
wxIMAGELIST_DRAW_TRANSPARENT
);
wxBitmap bmp = imageList->GetImageBitmapFor(this, image);
dc.DrawBitmap(
bmp,
xAligned + wLabel - ix - HEADER_IMAGE_MARGIN_IN_REPORT_MODE,
HEADER_OFFSET_Y + (h - iy)/2
);
}
dc.DrawText( item.GetText(),
@ -1592,8 +1590,8 @@ void wxListMainWindow::Init()
m_headerWidth =
m_lineHeight = 0;
m_small_image_list = nullptr;
m_normal_image_list = nullptr;
m_small_images = nullptr;
m_normal_images = nullptr;
m_small_spacing = 30;
m_normal_spacing = 40;
@ -1751,10 +1749,10 @@ wxCoord wxListMainWindow::GetLineHeight() const
wxCoord y;
dc.GetTextExtent(wxT("H"), nullptr, &y);
if ( m_small_image_list && m_small_image_list->GetImageCount() )
if ( m_small_images && m_small_images->GetImageCount() )
{
int iw = 0, ih = 0;
m_small_image_list->GetSize(0, iw, ih);
m_small_images->GetImageLogicalSize(this, 0, iw, ih);
y = wxMax(y, ih);
}
@ -3302,41 +3300,45 @@ void wxListMainWindow::OnKillFocus( wxFocusEvent &WXUNUSED(event) )
void wxListMainWindow::DrawImage( int index, wxDC *dc, int x, int y )
{
if ( HasFlag(wxLC_ICON) && (m_normal_image_list))
if ( HasFlag(wxLC_ICON) && (m_normal_images))
{
m_normal_image_list->Draw( index, *dc, x, y, wxIMAGELIST_DRAW_TRANSPARENT );
const auto bmp = m_normal_images->GetImageBitmapFor(this, index);
dc->DrawBitmap(bmp, x, y);
}
else if ( HasFlag(wxLC_SMALL_ICON) && (m_small_image_list))
else if ( HasFlag(wxLC_SMALL_ICON) && (m_small_images))
{
m_small_image_list->Draw( index, *dc, x, y, wxIMAGELIST_DRAW_TRANSPARENT );
const auto bmp = m_small_images->GetImageBitmapFor(this, index);
dc->DrawBitmap(bmp, x, y);
}
else if ( HasFlag(wxLC_LIST) && (m_small_image_list))
else if ( HasFlag(wxLC_LIST) && (m_small_images))
{
m_small_image_list->Draw( index, *dc, x, y, wxIMAGELIST_DRAW_TRANSPARENT );
const auto bmp = m_small_images->GetImageBitmapFor(this, index);
dc->DrawBitmap(bmp, x, y);
}
else if ( InReportView() && (m_small_image_list))
else if ( InReportView() && (m_small_images))
{
m_small_image_list->Draw( index, *dc, x, y, wxIMAGELIST_DRAW_TRANSPARENT );
const auto bmp = m_small_images->GetImageBitmapFor(this, index);
dc->DrawBitmap(bmp, x, y);
}
}
void wxListMainWindow::GetImageSize( int index, int &width, int &height ) const
{
if ( HasFlag(wxLC_ICON) && m_normal_image_list )
if ( HasFlag(wxLC_ICON) && m_normal_images )
{
m_normal_image_list->GetSize( index, width, height );
m_normal_images->GetImageLogicalSize(this, index, width, height);
}
else if ( HasFlag(wxLC_SMALL_ICON) && m_small_image_list )
else if ( HasFlag(wxLC_SMALL_ICON) && m_small_images )
{
m_small_image_list->GetSize( index, width, height );
m_small_images->GetImageLogicalSize(this, index, width, height);
}
else if ( HasFlag(wxLC_LIST) && m_small_image_list )
else if ( HasFlag(wxLC_LIST) && m_small_images )
{
m_small_image_list->GetSize( index, width, height );
m_small_images->GetImageLogicalSize(this, index, width, height);
}
else if ( InReportView() && m_small_image_list )
else if ( InReportView() && m_small_images )
{
m_small_image_list->GetSize( index, width, height );
m_small_images->GetImageLogicalSize(this, index, width, height);
}
else
{
@ -3345,28 +3347,29 @@ void wxListMainWindow::GetImageSize( int index, int &width, int &height ) const
}
}
void wxListMainWindow::SetImageList( wxImageList *imageList, int which )
void wxListMainWindow::SetImages( wxWithImages *images, const int which )
{
m_dirty = true;
// calc the spacing from the icon size
int width = 0;
if ((imageList) && (imageList->GetImageCount()) )
if ((images) && (images->HasImages()) )
{
int height;
imageList->GetSize(0, width, height);
images->GetImageLogicalSize(this, 0, width, height);
}
if (which == wxIMAGE_LIST_NORMAL)
{
m_normal_image_list = imageList;
m_normal_images = images;
m_normal_spacing = width + 8;
}
if (which == wxIMAGE_LIST_SMALL)
{
m_small_image_list = imageList;
m_small_images = images;
m_small_spacing = width + 14;
m_lineHeight = 0; // ensure that the line height will be recalc'd
}
@ -3403,10 +3406,10 @@ wxListMainWindow::ComputeMinHeaderWidth(const wxListHeaderData* column) const
const int image = column->GetImage();
if ( image != -1 )
{
if ( m_small_image_list )
if ( m_small_images )
{
int ix = 0, iy = 0;
m_small_image_list->GetSize(image, ix, iy);
m_small_images->GetImageLogicalSize(this, image, ix, iy);
width += ix + HEADER_IMAGE_MARGIN_IN_REPORT_MODE;
}
}
@ -4029,9 +4032,9 @@ void wxListMainWindow::RecalculatePositions()
const size_t count = GetItemCount();
int iconSpacing;
if ( HasFlag(wxLC_ICON) && m_normal_image_list )
if ( HasFlag(wxLC_ICON) && m_normal_images )
iconSpacing = m_normal_spacing;
else if ( HasFlag(wxLC_SMALL_ICON) && m_small_image_list )
else if ( HasFlag(wxLC_SMALL_ICON) && m_small_images )
iconSpacing = m_small_spacing;
else
iconSpacing = 0;
@ -4626,10 +4629,10 @@ void wxListMainWindow::InsertItem( wxListItem &item )
{
// Reset the buffered height if it's not big enough for the new image.
int image = item.GetImage();
if ( m_small_image_list && image != -1 && InReportView() )
if ( m_small_images && image != -1 && InReportView() )
{
int imageWidth, imageHeight;
m_small_image_list->GetSize(image, imageWidth, imageHeight);
m_small_images->GetImageLogicalSize(this, image, imageWidth, imageHeight);
if ( imageHeight > m_lineHeight )
m_lineHeight = 0;
@ -5456,7 +5459,7 @@ long wxGenericListCtrl::GetNextItem( long item, int geom, int state ) const
void wxGenericListCtrl::DoUpdateImages(int which )
{
m_mainWin->SetImageList( GetUpdatedImageList(which), which );
m_mainWin->SetImages( GetImages(which), which );
}
bool wxGenericListCtrl::Arrange( int WXUNUSED(flag) )