diff --git a/include/wx/generic/treectlg.h b/include/wx/generic/treectlg.h index e431299f88..bd6ae56b40 100644 --- a/include/wx/generic/treectlg.h +++ b/include/wx/generic/treectlg.h @@ -71,6 +71,7 @@ public: virtual unsigned int GetIndent() const override { return m_indent; } virtual void SetIndent(unsigned int indent) override; + virtual void SetStateImages(const wxVector& images) override; virtual void SetImageList(wxImageList *imageList) override; virtual void SetStateImageList(wxImageList *imageList) override; diff --git a/include/wx/msw/treectrl.h b/include/wx/msw/treectrl.h index cdc4aebd32..98b8c8bc29 100644 --- a/include/wx/msw/treectrl.h +++ b/include/wx/msw/treectrl.h @@ -72,6 +72,8 @@ public: virtual unsigned int GetIndent() const override; virtual void SetIndent(unsigned int indent) override; + virtual void SetStateImages(const wxVector& images) override; + virtual void SetImageList(wxImageList *imageList) override; virtual void SetStateImageList(wxImageList *imageList) override; diff --git a/include/wx/qt/treectrl.h b/include/wx/qt/treectrl.h index 77c49072a8..3f252c4928 100644 --- a/include/wx/qt/treectrl.h +++ b/include/wx/qt/treectrl.h @@ -35,6 +35,8 @@ public: virtual unsigned int GetIndent() const override; virtual void SetIndent(unsigned int indent) override; + virtual void SetStateImages(const wxVector& images) override; + virtual void SetImageList(wxImageList *imageList) override; virtual void SetStateImageList(wxImageList *imageList) override; diff --git a/include/wx/treectrl.h b/include/wx/treectrl.h index e004abc3ed..d72655227e 100644 --- a/include/wx/treectrl.h +++ b/include/wx/treectrl.h @@ -56,10 +56,17 @@ public: unsigned int GetSpacing() const { return m_spacing; } void SetSpacing(unsigned int spacing) { m_spacing = spacing; } - // In addition to {Set,Get,Assign}ImageList() methods inherited from - // wxWithImages, this control has similar functions for the state image - // list that can be used to show a state icon corresponding to an - // app-defined item state (for example, checked/unchecked). + // In addition to SetImages() inherited from wxWithImages, this class + // also provides SetStateImages() function which can be used to set the + // images showing an icon corresponding to an app-defined item state + // (for example, checked/unchecked). + virtual void SetStateImages(const wxVector& images) = 0; + + // These functions parallel {Set,Get,Assign}ImageList() methods + // inherited from wxWithImages, but correspond to SetStateImages(). + // As with the other functions using wxImageList, they still work but + // don't allow to define high resolution icons for high DPI screens, so + // SetStateImages() above should be preferred. wxImageList *GetStateImageList() const { return m_imagesState.GetImageList(); diff --git a/interface/wx/treectrl.h b/interface/wx/treectrl.h index 382e81d5a2..5fafa5efd8 100644 --- a/interface/wx/treectrl.h +++ b/interface/wx/treectrl.h @@ -30,9 +30,11 @@ In addition to normal images, handled with the methods mentioned above, wxTreeCtrl also provides optional state images that may be used to indicate some additional state of the item, e.g. checked or unchecked status. These - images can be set using SetStateImageList() and AssignStateImageList() - functions that behave in the same way as the corresponding methods of - wxWithImages. + images can be set using SetStateImages() (preferred, as they allow to + specify high resolution versions of the state images too) or legacy + SetStateImageList() and AssignStateImageList() functions that behave in the + same way as the corresponding methods of wxWithImages. Note that state + images are currently not supported in the native wxQt version. Finally, in the generic version of this control (wxGenericTreeCtrl), also provides SetButtonsImageList() and AssignButtonsImageList(), which can be @@ -281,6 +283,8 @@ public: automatically deleted by wxTreeCtrl as appropriate (i.e. it takes ownership of the list). + @note Prefer using SetStateImages() in the new code. + @see SetStateImageList(). */ void AssignStateImageList(wxImageList* imageList); @@ -976,10 +980,24 @@ public: by @ref wxTreeCtrl "wxTreeCtrl"'s destructor, you must delete it yourself. - @see AssignStateImageList(). + @note Prefer using SetStateImages() in the new code. + + @see AssignStateImageList() */ virtual void SetStateImageList(wxImageList* imageList); + /** + Sets the images to use for the application-defined item states. + + This function takes a vector of wxBitmapBundle objects which can + specify multiple versions of the same icon for different display + resolutions for each state. If the vector is empty, no state images are + shown. + + @since 3.3.0 + */ + virtual void SetStateImages(const wxVector& images); + /** Sets the mode flags associated with the display of the tree control. The new mode takes effect immediately. diff --git a/samples/treectrl/treetest.cpp b/samples/treectrl/treetest.cpp index 13e447e64f..a23b542517 100644 --- a/samples/treectrl/treetest.cpp +++ b/samples/treectrl/treetest.cpp @@ -704,12 +704,12 @@ void MyFrame::OnToggleStates(wxCommandEvent& WXUNUSED(event)) { if ( wxGetApp().ShowStates() ) { - m_treeCtrl->SetStateImageList(nullptr); + m_treeCtrl->SetStateImages({}); wxGetApp().SetShowStates(false); } else { - m_treeCtrl->CreateStateImageList(); + m_treeCtrl->CreateStateImages(); wxGetApp().SetShowStates(true); } } @@ -732,7 +732,7 @@ void MyFrame::OnToggleAlternateStates(wxCommandEvent& WXUNUSED(event)) bool alternateStates = m_treeCtrl->AlternateStates(); m_treeCtrl->SetAlternateStates(!alternateStates); - m_treeCtrl->CreateStateImageList(); + m_treeCtrl->CreateStateImages(); // normal states < alternate states // so we must reset broken states @@ -950,7 +950,7 @@ MyTreeCtrl::MyTreeCtrl(wxWindow *parent, const wxWindowID id, m_reverseSort = false; CreateImages(16); - CreateStateImageList(); + CreateStateImages(); // Add some items to the tree AddTestItemsToTree(NUM_CHILDREN_PER_LEVEL, NUM_LEVELS); @@ -1039,46 +1039,33 @@ void MyTreeCtrl::CreateImages(int size) SetImages(images); } -void MyTreeCtrl::CreateStateImageList() +void MyTreeCtrl::CreateStateImages() { - wxImageList *states; - wxBusyCursor wait; + std::vector icons; if (m_alternateStates) { - wxIcon icons[5]; - icons[0] = wxIcon(state1_xpm); // yellow - icons[1] = wxIcon(state2_xpm); // green - icons[2] = wxIcon(state3_xpm); // red - icons[3] = wxIcon(state4_xpm); // blue - icons[4] = wxIcon(state5_xpm); // black - - int width = icons[0].GetWidth(), - height = icons[0].GetHeight(); - - // Make a state image list containing small icons - states = new wxImageList(width, height, true); - - for ( size_t i = 0; i < WXSIZEOF(icons); i++ ) - states->Add(icons[i]); + icons.push_back(wxIcon(state1_xpm)); // yellow + icons.push_back(wxIcon(state2_xpm)); // green + icons.push_back(wxIcon(state3_xpm)); // red + icons.push_back(wxIcon(state4_xpm)); // blue + icons.push_back(wxIcon(state5_xpm)); // black } else { - wxIcon icons[2]; - icons[0] = wxIcon(unchecked_xpm); - icons[1] = wxIcon(checked_xpm); - - int width = icons[0].GetWidth(), - height = icons[0].GetHeight(); - - // Make an state image list containing small icons - states = new wxImageList(width, height, true); - - for ( size_t i = 0; i < WXSIZEOF(icons); i++ ) - states->Add(icons[i]); + icons.push_back(wxIcon(unchecked_xpm)); + icons.push_back(wxIcon(checked_xpm)); } - AssignStateImageList(states); + std::vector images; + + const wxSize iconSize(icons[0].GetWidth(), icons[0].GetHeight()); + for ( const wxIcon& icon : icons ) + { + images.push_back(wxBitmapBundle::FromImpl(new FixedSizeImpl(iconSize, icon))); + } + + SetStateImages(images); } void MyTreeCtrl::CreateButtonsImageList(int size) diff --git a/samples/treectrl/treetest.h b/samples/treectrl/treetest.h index de6b9bf0d0..01bcb292f7 100644 --- a/samples/treectrl/treetest.h +++ b/samples/treectrl/treetest.h @@ -113,7 +113,7 @@ public: void CreateImages(int size); void CreateButtonsImageList(int size = 11); - void CreateStateImageList(); + void CreateStateImages(); void AddTestItemsToTree(size_t numChildren, size_t depth); diff --git a/src/generic/treectlg.cpp b/src/generic/treectlg.cpp index 49d0987335..2271b0d8f0 100644 --- a/src/generic/treectlg.cpp +++ b/src/generic/treectlg.cpp @@ -2481,6 +2481,16 @@ void wxGenericTreeCtrl::SetImageList(wxImageList *imageList) UpdateAfterImageListChange(); } +void wxGenericTreeCtrl::SetStateImages(const wxVector& images) +{ + m_imagesState.SetImages(images); + + // As above, only call it for the side effect of updating the image list. + m_imagesState.GetUpdatedImageListFor(this); + + UpdateAfterImageListChange(); +} + void wxGenericTreeCtrl::SetStateImageList(wxImageList *imageList) { m_imagesState.SetImageList(imageList); diff --git a/src/msw/treectrl.cpp b/src/msw/treectrl.cpp index cfd4466023..b0b725982d 100644 --- a/src/msw/treectrl.cpp +++ b/src/msw/treectrl.cpp @@ -946,6 +946,12 @@ void wxTreeCtrl::SetImageList(wxImageList *imageList) SetAnyImageList(imageList, TVSIL_NORMAL); } +void wxTreeCtrl::SetStateImages(const wxVector& images) +{ + m_imagesState.SetImages(images); + SetAnyImageList(m_imagesState.GetUpdatedImageListFor(this), TVSIL_STATE); +} + void wxTreeCtrl::SetStateImageList(wxImageList *imageList) { m_imagesState.SetImageList(imageList); diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 5b6fe397d0..1faedcbc6f 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -629,6 +629,12 @@ void wxTreeCtrl::OnImagesChanged() } } +void wxTreeCtrl::SetStateImages(const wxVector& images) +{ + m_imagesState.SetImages(images); + m_qtTreeWidget->update(); +} + void wxTreeCtrl::SetStateImageList(wxImageList *imageList) { m_imagesState.SetImageList(imageList);