diff --git a/include/wx/generic/treectlg.h b/include/wx/generic/treectlg.h index 67a2a39fd1..dda068bf4f 100644 --- a/include/wx/generic/treectlg.h +++ b/include/wx/generic/treectlg.h @@ -287,6 +287,9 @@ protected: // overridden wxWindow methods virtual void DoThaw() wxOVERRIDE; + virtual void OnImagesChanged() wxOVERRIDE; + void UpdateAfterImageListChange(); + // misc helpers void SendDeleteEvent(wxGenericTreeItem *itemBeingDeleted); diff --git a/include/wx/msw/treectrl.h b/include/wx/msw/treectrl.h index 0e62b89197..08d42f7062 100644 --- a/include/wx/msw/treectrl.h +++ b/include/wx/msw/treectrl.h @@ -212,6 +212,8 @@ protected: virtual bool MSWShouldSetDefaultFont() const wxOVERRIDE { return false; } + virtual void OnImagesChanged() wxOVERRIDE; + // SetImageList helper void SetAnyImageList(wxImageList *imageList, int which); diff --git a/include/wx/qt/treectrl.h b/include/wx/qt/treectrl.h index 473f2c1f09..9744243bf8 100644 --- a/include/wx/qt/treectrl.h +++ b/include/wx/qt/treectrl.h @@ -135,10 +135,14 @@ protected: virtual wxTreeItemId DoTreeHitTest(const wxPoint& point, int& flags) const wxOVERRIDE; + virtual void OnImagesChanged() wxOVERRIDE; + private: void SendDeleteEvent(const wxTreeItemId &item); wxTreeItemId GetNext(const wxTreeItemId &item) const; + void DoUpdateIconsSize(wxImageList *imageList); + wxQTreeWidget *m_qtTreeWidget; wxDECLARE_DYNAMIC_CLASS(wxTreeCtrl); }; diff --git a/samples/treectrl/treetest.cpp b/samples/treectrl/treetest.cpp index 83a0b89e5e..db0d5c94cf 100644 --- a/samples/treectrl/treetest.cpp +++ b/samples/treectrl/treetest.cpp @@ -688,7 +688,7 @@ void MyFrame::OnSetImageSize(wxCommandEvent& WXUNUSED(event)) if ( size == -1 ) return; - m_treeCtrl->CreateImageList(size); + m_treeCtrl->CreateImages(size); wxGetApp().SetShowImages(true); } @@ -696,12 +696,12 @@ void MyFrame::OnToggleImages(wxCommandEvent& WXUNUSED(event)) { if ( wxGetApp().ShowImages() ) { - m_treeCtrl->CreateImageList(-1); + m_treeCtrl->CreateImages(-1); wxGetApp().SetShowImages(false); } else { - m_treeCtrl->CreateImageList(0); + m_treeCtrl->CreateImages(0); wxGetApp().SetShowImages(true); } } @@ -730,7 +730,7 @@ void MyFrame::OnToggleAlternateImages(wxCommandEvent& WXUNUSED(event)) bool alternateImages = m_treeCtrl->AlternateImages(); m_treeCtrl->SetAlternateImages(!alternateImages); - m_treeCtrl->CreateImageList(0); + m_treeCtrl->CreateImages(0); } void MyFrame::OnToggleAlternateStates(wxCommandEvent& WXUNUSED(event)) @@ -955,14 +955,14 @@ MyTreeCtrl::MyTreeCtrl(wxWindow *parent, const wxWindowID id, { m_reverseSort = false; - CreateImageList(); + CreateImages(16); CreateStateImageList(); // Add some items to the tree AddTestItemsToTree(NUM_CHILDREN_PER_LEVEL, NUM_LEVELS); } -void MyTreeCtrl::CreateImageList(int size) +void MyTreeCtrl::CreateImages(int size) { if ( size == -1 ) { @@ -974,8 +974,7 @@ void MyTreeCtrl::CreateImageList(int size) else m_imageSize = size; - // Make an image list containing small icons - wxImageList *images = new wxImageList(size, size, true); + const wxSize iconSize(size, size); // should correspond to TreeCtrlIcon_xxx enum wxIcon icons[5]; @@ -990,8 +989,6 @@ void MyTreeCtrl::CreateImageList(int size) } else { - wxSize iconSize(size, size); - icons[TreeCtrlIcon_File] = icons[TreeCtrlIcon_FileSelected] = wxArtProvider::GetIcon(wxART_NORMAL_FILE, wxART_LIST, iconSize); icons[TreeCtrlIcon_Folder] = @@ -999,20 +996,50 @@ void MyTreeCtrl::CreateImageList(int size) icons[TreeCtrlIcon_FolderOpened] = wxArtProvider::GetIcon(wxART_FOLDER, wxART_LIST, iconSize); } + // Make a vector of bundles corresponding to the icons. We use a custom + // bundle implementation here as we always scale the icons, even at 100% + // DPI, to ensure they are of the desired size. + wxVector images; + + class FixedSizeImpl : public wxBitmapBundleImpl + { + public: + FixedSizeImpl(const wxSize& sizeDef, const wxIcon& icon) + : m_sizeDef(sizeDef), + m_icon(icon) + { + } + + wxSize GetDefaultSize() const wxOVERRIDE + { + return m_sizeDef; + } + + wxSize GetPreferredSizeAtScale(double scale) const wxOVERRIDE + { + return m_sizeDef*scale; + } + + wxBitmap GetBitmap(const wxSize& size) wxOVERRIDE + { + wxBitmap bmp(m_icon); + if ( size != bmp.GetSize() ) + wxBitmap::Rescale(bmp, size); + + return bmp; + } + + private: + const wxSize m_sizeDef; + const wxIcon m_icon; + }; + for ( size_t i = 0; i < WXSIZEOF(icons); i++ ) { - int sizeOrig = icons[0].GetWidth(); - if ( size == sizeOrig ) - { - images->Add(icons[i]); - } - else - { - images->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size))); - } + images.push_back(wxBitmapBundle::FromImpl(new FixedSizeImpl(iconSize, icons[i]))); } - AssignImageList(images); + SetImages(images); } void MyTreeCtrl::CreateStateImageList(bool del) diff --git a/samples/treectrl/treetest.h b/samples/treectrl/treetest.h index 865a39d1fa..68ae3d4d54 100644 --- a/samples/treectrl/treetest.h +++ b/samples/treectrl/treetest.h @@ -107,7 +107,12 @@ public: void GetItemsRecursively(const wxTreeItemId& idParent, wxTreeItemIdValue cookie = 0); - void CreateImageList(int size = 16); + // This function behaves differently depending on the value of size: + // - If it's -1, it turns off the use of images entirely. + // - If it's 0, it reuses the last used size. + // - If it's strictly positive, it creates icons in this size. + void CreateImages(int size); + void CreateButtonsImageList(int size = 11); void CreateStateImageList(bool del = false); diff --git a/src/common/treebase.cpp b/src/common/treebase.cpp index 0145469e60..988e288c5b 100644 --- a/src/common/treebase.cpp +++ b/src/common/treebase.cpp @@ -172,6 +172,7 @@ wxTreeCtrlBase::wxTreeCtrlBase() m_quickBestSize = true; Bind(wxEVT_CHAR_HOOK, &wxTreeCtrlBase::OnCharHook, this); + Bind(wxEVT_DPI_CHANGED, &wxTreeCtrlBase::WXHandleDPIChanged, this); } wxTreeCtrlBase::~wxTreeCtrlBase() diff --git a/src/generic/treectlg.cpp b/src/generic/treectlg.cpp index 01f14f24ef..f988234a1c 100644 --- a/src/generic/treectlg.cpp +++ b/src/generic/treectlg.cpp @@ -2424,9 +2424,18 @@ void wxGenericTreeCtrl::CalculateLineHeight() m_lineHeight += m_lineHeight/10; // otherwise 10% extra spacing } -void wxGenericTreeCtrl::SetImageList(wxImageList *imageList) +void wxGenericTreeCtrl::OnImagesChanged() +{ + if ( HasImages() ) + { + UpdateImageListIfNecessary(this); + + UpdateAfterImageListChange(); + } +} + +void wxGenericTreeCtrl::UpdateAfterImageListChange() { - wxWithImages::SetImageList(imageList); m_dirty = true; if (m_anchor) @@ -2434,33 +2443,26 @@ void wxGenericTreeCtrl::SetImageList(wxImageList *imageList) // Don't do any drawing if we're setting the list to NULL, // since we may be in the process of deleting the tree control. - if (imageList) + if (GetImageList()) CalculateLineHeight(); } +void wxGenericTreeCtrl::SetImageList(wxImageList *imageList) +{ + wxWithImages::SetImageList(imageList); + UpdateAfterImageListChange(); +} + void wxGenericTreeCtrl::SetStateImageList(wxImageList *imageList) { m_imagesState.SetImageList(imageList); - m_dirty = true; - - if (m_anchor) - m_anchor->RecursiveResetSize(); - - // Don't do any drawing if we're setting the list to NULL, - // since we may be in the process of deleting the tree control. - if (imageList) - CalculateLineHeight(); + UpdateAfterImageListChange(); } void wxGenericTreeCtrl::SetButtonsImageList(wxImageList *imageList) { m_imagesButtons.SetImageList(imageList); - m_dirty = true; - - if (m_anchor) - m_anchor->RecursiveResetSize(); - - CalculateLineHeight(); + UpdateAfterImageListChange(); } void wxGenericTreeCtrl::AssignButtonsImageList(wxImageList *imageList) diff --git a/src/msw/treectrl.cpp b/src/msw/treectrl.cpp index 4524cc2bcc..8b63438d0d 100644 --- a/src/msw/treectrl.cpp +++ b/src/msw/treectrl.cpp @@ -931,6 +931,24 @@ void wxTreeCtrl::SetStateImageList(wxImageList *imageList) SetAnyImageList(imageList, TVSIL_STATE); } +void wxTreeCtrl::OnImagesChanged() +{ + wxImageList* imageList; + + if ( HasImages() ) + { + UpdateImageListIfNecessary(this); + + imageList = GetImageList(); + } + else + { + imageList = NULL; + } + + SetAnyImageList(imageList, TVSIL_NORMAL); +} + size_t wxTreeCtrl::GetChildrenCount(const wxTreeItemId& item, bool recursively) const { diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index e1d5845a88..441c667fdb 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -613,12 +613,27 @@ void wxTreeCtrl::SetImageList(wxImageList *imageList) { wxWithImages::SetImageList(imageList); + DoUpdateIconsSize(imageList); +} + +void wxTreeCtrl::DoUpdateIconsSize(wxImageList *imageList) +{ int width, height; imageList->GetSize(0, width, height); m_qtTreeWidget->ResizeIcons(QSize(width, height)); m_qtTreeWidget->update(); } +void wxTreeCtrl::OnImagesChanged() +{ + if ( HasImages() ) + { + UpdateImageListIfNecessary(this); + + DoUpdateIconsSize(GetImageList()); + } +} + void wxTreeCtrl::SetStateImageList(wxImageList *imageList) { m_imagesState.SetImageList(imageList);