diff --git a/include/wx/generic/private/drawbitmap.h b/include/wx/generic/private/drawbitmap.h new file mode 100644 index 0000000000..af6d64e596 --- /dev/null +++ b/include/wx/generic/private/drawbitmap.h @@ -0,0 +1,41 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/generic/private/drawbitmap.h +// Purpose: Small helper for drawing images. +// Author: Vadim Zeitlin +// Created: 2022-10-25 +// Copyright: (c) 2022 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_GENERIC_PRIVATE_DRAWBITMAP_H_ +#define _WX_GENERIC_PRIVATE_DRAWBITMAP_H_ + +#include "wx/dc.h" +#include "wx/window.h" +#include "wx/withimages.h" + +// Just a trivial wrapper for wxDC::DrawBitmap() using wxWithImages: this is +// used in several places in the generic wxListCtrl and wxTreeCtrl code. +inline void +wxDrawImageBitmap(wxWindow* window, + const wxWithImages& images, + int image, + wxDC& dc, + int x, + int y) +{ + dc.DrawBitmap(images.GetImageBitmapFor(window, image), + x, y, + true /* use mask */); +} + +// Overload for the controls deriving from both wxWindow and wxWithImages, as +// both wxListCtrl and wxTreeCtrl do. +template +inline void +wxDrawImageBitmap(T* window, int image, wxDC& dc, int x, int y) +{ + wxDrawImageBitmap(window, *window, image, dc, x, y); +} + +#endif // _WX_GENERIC_PRIVATE_DRAWBITMAP_H_ diff --git a/include/wx/generic/private/listctrl.h b/include/wx/generic/private/listctrl.h index 5135ce9db7..d10561372b 100644 --- a/include/wx/generic/private/listctrl.h +++ b/include/wx/generic/private/listctrl.h @@ -640,7 +640,7 @@ public: void DrawImage( int index, wxDC *dc, int x, int y ); void GetImageSize( int index, int &width, int &height ) const; - void SetImageList( wxImageList *imageList, int which ); + void SetImages( wxWithImages *images, const int which ); void SetItemSpacing( int spacing, bool isSmall = false ); int GetItemSpacing( bool isSmall = false ); @@ -694,8 +694,9 @@ public: SetItem( info ); } - wxImageList* GetSmallImageList() const - { return m_small_image_list; } + wxWithImages* GetSmallImages() const + { return m_small_images; } + // set the scrollbars and update the positions of the items void RecalculatePositions(); @@ -811,8 +812,9 @@ protected: bool m_dirty; wxColour *m_highlightColour; - wxImageList *m_small_image_list; - wxImageList *m_normal_image_list; + wxWithImages *m_small_images; + wxWithImages *m_normal_images; + int m_small_spacing; int m_normal_spacing; bool m_hasFocus; diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index 3da7620e68..2bbe14cf10 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -35,6 +35,8 @@ #include "wx/imaglist.h" #include "wx/renderer.h" + +#include "wx/generic/private/drawbitmap.h" #include "wx/generic/private/listctrl.h" #include "wx/generic/private/widthcalc.h" @@ -1134,19 +1136,19 @@ 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 *smallImages; if ( image != -1 ) { - imageList = m_owner->GetSmallImageList(); - if ( imageList ) + smallImages = m_owner->GetSmallImages(); + if ( smallImages ) { - imageList->GetSize(image, ix, iy); + smallImages->GetImageLogicalSize(this, image, ix, iy); wLabel += ix + HEADER_IMAGE_MARGIN_IN_REPORT_MODE; } } else { - imageList = nullptr; + smallImages = nullptr; } // ignore alignment if there is not enough space anyhow @@ -1175,16 +1177,15 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) wxDCClipper clipper(dc, x, HEADER_OFFSET_Y, cw, h); // if we have an image, draw it on the right of the label - if ( imageList ) + if ( smallImages ) { - imageList->Draw - ( - image, - dc, - xAligned + wLabel - ix - HEADER_IMAGE_MARGIN_IN_REPORT_MODE, - HEADER_OFFSET_Y + (h - iy)/2, - wxIMAGELIST_DRAW_TRANSPARENT - ); + wxDrawImageBitmap + ( + this, *smallImages, image, + dc, + xAligned + wLabel - ix - HEADER_IMAGE_MARGIN_IN_REPORT_MODE, + HEADER_OFFSET_Y + (h - iy)/2 + ); } dc.DrawText( item.GetText(), @@ -1592,8 +1593,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 +1752,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 +3303,25 @@ 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 ); + wxDrawImageBitmap(this, *m_normal_images, index, *dc, x, y); } - else if ( HasFlag(wxLC_SMALL_ICON) && (m_small_image_list)) + else if ( HasFlag(wxLC_SMALL_ICON | wxLC_LIST | wxLC_REPORT) && m_small_images ) { - m_small_image_list->Draw( index, *dc, x, y, wxIMAGELIST_DRAW_TRANSPARENT ); - } - else if ( HasFlag(wxLC_LIST) && (m_small_image_list)) - { - m_small_image_list->Draw( index, *dc, x, y, wxIMAGELIST_DRAW_TRANSPARENT ); - } - else if ( InReportView() && (m_small_image_list)) - { - m_small_image_list->Draw( index, *dc, x, y, wxIMAGELIST_DRAW_TRANSPARENT ); + wxDrawImageBitmap(this, *m_small_images, index, *dc, 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 | wxLC_LIST | wxLC_REPORT) && m_small_images ) { - m_small_image_list->GetSize( index, width, height ); - } - else if ( HasFlag(wxLC_LIST) && m_small_image_list ) - { - m_small_image_list->GetSize( index, width, height ); - } - else if ( InReportView() && m_small_image_list ) - { - m_small_image_list->GetSize( index, width, height ); + m_small_images->GetImageLogicalSize(this, index, width, height); } else { @@ -3345,28 +3330,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 +3389,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 +4015,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 +4612,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 +5442,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) ) diff --git a/src/generic/treectlg.cpp b/src/generic/treectlg.cpp index 0c4d1c9477..98f444c25a 100644 --- a/src/generic/treectlg.cpp +++ b/src/generic/treectlg.cpp @@ -38,6 +38,8 @@ #include "wx/renderer.h" +#include "wx/generic/private/drawbitmap.h" + #ifdef __WXMAC__ #include "wx/osx/private.h" #endif @@ -2648,24 +2650,23 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc) if ( state != wxTREE_ITEMSTATE_NONE ) { wxDCClipper clip(dc, item->GetX(), item->GetY(), state_w, total_h); - dc.DrawBitmap( m_imagesState.GetImageBitmapFor(this, state), - item->GetX(), - item->GetY() + - (total_h > state_h ? (total_h-state_h)/2 - : 0), - true /* use mask */ ); + + wxDrawImageBitmap(this, m_imagesState, state, + dc, + item->GetX(), + item->GetY() + + total_h > state_h ? (total_h-state_h)/2 : 0); } if ( image != NO_IMAGE ) { wxDCClipper clip(dc, item->GetX() + state_w, item->GetY(), image_w, total_h); - dc.DrawBitmap( GetImageBitmapFor(this, image), - item->GetX() + state_w, - item->GetY() + - (total_h > image_h ? (total_h-image_h)/2 - : 0), - true /* use mask */ ); + wxDrawImageBitmap(this, image, + dc, + item->GetX() + state_w, + item->GetY() + + total_h > image_h ? (total_h-image_h)/2 : 0); } dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT); @@ -2832,16 +2833,13 @@ wxGenericTreeCtrl::PaintLevel(wxGenericTreeItem *item, if ( item->IsSelected() ) image += wxTreeItemIcon_Selected - wxTreeItemIcon_Normal; - const wxBitmap& bmp = m_imagesButtons.GetImageBitmapFor(this, image); - - // we need logical coordinates for wxDC. - int image_h = FromPhys(bmp.GetHeight()), - image_w = FromPhys(bmp.GetWidth()); + int image_w, image_h; + m_imagesButtons.GetImageLogicalSize(this, image, image_w, image_h); int xx = x - image_w/2; int yy = y_mid - image_h/2; wxDCClipper clip(dc, xx, yy, image_w, image_h); - dc.DrawBitmap( bmp, xx, yy, true /* use mask */ ); + wxDrawImageBitmap(this, m_imagesButtons, image, dc, xx, yy); } else // no custom buttons {