Update wxTreeCtrl and its sample to work with wxBitmapBundle
Override OnImagesChanged() to call UpdateImageListIfNecessary() even in wxGenericTreeCtrl for now, although in the future it would really make sense to stop using wxImageList in its implementation and just use wxBitmapBundle directly instead. wxMSW is the only one which really needs an image list, as it's required by the native control. Also update the sample, even though it doesn't look very nice because its icons are only available in a single size, so we have to always scale them.
This commit is contained in:
@@ -287,6 +287,9 @@ protected:
|
|||||||
// overridden wxWindow methods
|
// overridden wxWindow methods
|
||||||
virtual void DoThaw() wxOVERRIDE;
|
virtual void DoThaw() wxOVERRIDE;
|
||||||
|
|
||||||
|
virtual void OnImagesChanged() wxOVERRIDE;
|
||||||
|
void UpdateAfterImageListChange();
|
||||||
|
|
||||||
// misc helpers
|
// misc helpers
|
||||||
void SendDeleteEvent(wxGenericTreeItem *itemBeingDeleted);
|
void SendDeleteEvent(wxGenericTreeItem *itemBeingDeleted);
|
||||||
|
|
||||||
|
|||||||
@@ -212,6 +212,8 @@ protected:
|
|||||||
|
|
||||||
virtual bool MSWShouldSetDefaultFont() const wxOVERRIDE { return false; }
|
virtual bool MSWShouldSetDefaultFont() const wxOVERRIDE { return false; }
|
||||||
|
|
||||||
|
virtual void OnImagesChanged() wxOVERRIDE;
|
||||||
|
|
||||||
// SetImageList helper
|
// SetImageList helper
|
||||||
void SetAnyImageList(wxImageList *imageList, int which);
|
void SetAnyImageList(wxImageList *imageList, int which);
|
||||||
|
|
||||||
|
|||||||
@@ -135,10 +135,14 @@ protected:
|
|||||||
|
|
||||||
virtual wxTreeItemId DoTreeHitTest(const wxPoint& point, int& flags) const wxOVERRIDE;
|
virtual wxTreeItemId DoTreeHitTest(const wxPoint& point, int& flags) const wxOVERRIDE;
|
||||||
|
|
||||||
|
virtual void OnImagesChanged() wxOVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SendDeleteEvent(const wxTreeItemId &item);
|
void SendDeleteEvent(const wxTreeItemId &item);
|
||||||
wxTreeItemId GetNext(const wxTreeItemId &item) const;
|
wxTreeItemId GetNext(const wxTreeItemId &item) const;
|
||||||
|
|
||||||
|
void DoUpdateIconsSize(wxImageList *imageList);
|
||||||
|
|
||||||
wxQTreeWidget *m_qtTreeWidget;
|
wxQTreeWidget *m_qtTreeWidget;
|
||||||
wxDECLARE_DYNAMIC_CLASS(wxTreeCtrl);
|
wxDECLARE_DYNAMIC_CLASS(wxTreeCtrl);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -688,7 +688,7 @@ void MyFrame::OnSetImageSize(wxCommandEvent& WXUNUSED(event))
|
|||||||
if ( size == -1 )
|
if ( size == -1 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_treeCtrl->CreateImageList(size);
|
m_treeCtrl->CreateImages(size);
|
||||||
wxGetApp().SetShowImages(true);
|
wxGetApp().SetShowImages(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -696,12 +696,12 @@ void MyFrame::OnToggleImages(wxCommandEvent& WXUNUSED(event))
|
|||||||
{
|
{
|
||||||
if ( wxGetApp().ShowImages() )
|
if ( wxGetApp().ShowImages() )
|
||||||
{
|
{
|
||||||
m_treeCtrl->CreateImageList(-1);
|
m_treeCtrl->CreateImages(-1);
|
||||||
wxGetApp().SetShowImages(false);
|
wxGetApp().SetShowImages(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_treeCtrl->CreateImageList(0);
|
m_treeCtrl->CreateImages(0);
|
||||||
wxGetApp().SetShowImages(true);
|
wxGetApp().SetShowImages(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -730,7 +730,7 @@ void MyFrame::OnToggleAlternateImages(wxCommandEvent& WXUNUSED(event))
|
|||||||
bool alternateImages = m_treeCtrl->AlternateImages();
|
bool alternateImages = m_treeCtrl->AlternateImages();
|
||||||
|
|
||||||
m_treeCtrl->SetAlternateImages(!alternateImages);
|
m_treeCtrl->SetAlternateImages(!alternateImages);
|
||||||
m_treeCtrl->CreateImageList(0);
|
m_treeCtrl->CreateImages(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyFrame::OnToggleAlternateStates(wxCommandEvent& WXUNUSED(event))
|
void MyFrame::OnToggleAlternateStates(wxCommandEvent& WXUNUSED(event))
|
||||||
@@ -955,14 +955,14 @@ MyTreeCtrl::MyTreeCtrl(wxWindow *parent, const wxWindowID id,
|
|||||||
{
|
{
|
||||||
m_reverseSort = false;
|
m_reverseSort = false;
|
||||||
|
|
||||||
CreateImageList();
|
CreateImages(16);
|
||||||
CreateStateImageList();
|
CreateStateImageList();
|
||||||
|
|
||||||
// Add some items to the tree
|
// Add some items to the tree
|
||||||
AddTestItemsToTree(NUM_CHILDREN_PER_LEVEL, NUM_LEVELS);
|
AddTestItemsToTree(NUM_CHILDREN_PER_LEVEL, NUM_LEVELS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyTreeCtrl::CreateImageList(int size)
|
void MyTreeCtrl::CreateImages(int size)
|
||||||
{
|
{
|
||||||
if ( size == -1 )
|
if ( size == -1 )
|
||||||
{
|
{
|
||||||
@@ -974,8 +974,7 @@ void MyTreeCtrl::CreateImageList(int size)
|
|||||||
else
|
else
|
||||||
m_imageSize = size;
|
m_imageSize = size;
|
||||||
|
|
||||||
// Make an image list containing small icons
|
const wxSize iconSize(size, size);
|
||||||
wxImageList *images = new wxImageList(size, size, true);
|
|
||||||
|
|
||||||
// should correspond to TreeCtrlIcon_xxx enum
|
// should correspond to TreeCtrlIcon_xxx enum
|
||||||
wxIcon icons[5];
|
wxIcon icons[5];
|
||||||
@@ -990,8 +989,6 @@ void MyTreeCtrl::CreateImageList(int size)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxSize iconSize(size, size);
|
|
||||||
|
|
||||||
icons[TreeCtrlIcon_File] =
|
icons[TreeCtrlIcon_File] =
|
||||||
icons[TreeCtrlIcon_FileSelected] = wxArtProvider::GetIcon(wxART_NORMAL_FILE, wxART_LIST, iconSize);
|
icons[TreeCtrlIcon_FileSelected] = wxArtProvider::GetIcon(wxART_NORMAL_FILE, wxART_LIST, iconSize);
|
||||||
icons[TreeCtrlIcon_Folder] =
|
icons[TreeCtrlIcon_Folder] =
|
||||||
@@ -999,20 +996,50 @@ void MyTreeCtrl::CreateImageList(int size)
|
|||||||
icons[TreeCtrlIcon_FolderOpened] = wxArtProvider::GetIcon(wxART_FOLDER, wxART_LIST, iconSize);
|
icons[TreeCtrlIcon_FolderOpened] = wxArtProvider::GetIcon(wxART_FOLDER, wxART_LIST, iconSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( size_t i = 0; i < WXSIZEOF(icons); i++ )
|
// 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<wxBitmapBundle> images;
|
||||||
|
|
||||||
|
class FixedSizeImpl : public wxBitmapBundleImpl
|
||||||
{
|
{
|
||||||
int sizeOrig = icons[0].GetWidth();
|
public:
|
||||||
if ( size == sizeOrig )
|
FixedSizeImpl(const wxSize& sizeDef, const wxIcon& icon)
|
||||||
|
: m_sizeDef(sizeDef),
|
||||||
|
m_icon(icon)
|
||||||
{
|
{
|
||||||
images->Add(icons[i]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
images->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AssignImageList(images);
|
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++ )
|
||||||
|
{
|
||||||
|
images.push_back(wxBitmapBundle::FromImpl(new FixedSizeImpl(iconSize, icons[i])));
|
||||||
|
}
|
||||||
|
|
||||||
|
SetImages(images);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyTreeCtrl::CreateStateImageList(bool del)
|
void MyTreeCtrl::CreateStateImageList(bool del)
|
||||||
|
|||||||
@@ -107,7 +107,12 @@ public:
|
|||||||
void GetItemsRecursively(const wxTreeItemId& idParent,
|
void GetItemsRecursively(const wxTreeItemId& idParent,
|
||||||
wxTreeItemIdValue cookie = 0);
|
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 CreateButtonsImageList(int size = 11);
|
||||||
void CreateStateImageList(bool del = false);
|
void CreateStateImageList(bool del = false);
|
||||||
|
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ wxTreeCtrlBase::wxTreeCtrlBase()
|
|||||||
m_quickBestSize = true;
|
m_quickBestSize = true;
|
||||||
|
|
||||||
Bind(wxEVT_CHAR_HOOK, &wxTreeCtrlBase::OnCharHook, this);
|
Bind(wxEVT_CHAR_HOOK, &wxTreeCtrlBase::OnCharHook, this);
|
||||||
|
Bind(wxEVT_DPI_CHANGED, &wxTreeCtrlBase::WXHandleDPIChanged, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxTreeCtrlBase::~wxTreeCtrlBase()
|
wxTreeCtrlBase::~wxTreeCtrlBase()
|
||||||
|
|||||||
@@ -2424,9 +2424,18 @@ void wxGenericTreeCtrl::CalculateLineHeight()
|
|||||||
m_lineHeight += m_lineHeight/10; // otherwise 10% extra spacing
|
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;
|
m_dirty = true;
|
||||||
|
|
||||||
if (m_anchor)
|
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,
|
// 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.
|
// since we may be in the process of deleting the tree control.
|
||||||
if (imageList)
|
if (GetImageList())
|
||||||
CalculateLineHeight();
|
CalculateLineHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxGenericTreeCtrl::SetImageList(wxImageList *imageList)
|
||||||
|
{
|
||||||
|
wxWithImages::SetImageList(imageList);
|
||||||
|
UpdateAfterImageListChange();
|
||||||
|
}
|
||||||
|
|
||||||
void wxGenericTreeCtrl::SetStateImageList(wxImageList *imageList)
|
void wxGenericTreeCtrl::SetStateImageList(wxImageList *imageList)
|
||||||
{
|
{
|
||||||
m_imagesState.SetImageList(imageList);
|
m_imagesState.SetImageList(imageList);
|
||||||
m_dirty = true;
|
UpdateAfterImageListChange();
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxGenericTreeCtrl::SetButtonsImageList(wxImageList *imageList)
|
void wxGenericTreeCtrl::SetButtonsImageList(wxImageList *imageList)
|
||||||
{
|
{
|
||||||
m_imagesButtons.SetImageList(imageList);
|
m_imagesButtons.SetImageList(imageList);
|
||||||
m_dirty = true;
|
UpdateAfterImageListChange();
|
||||||
|
|
||||||
if (m_anchor)
|
|
||||||
m_anchor->RecursiveResetSize();
|
|
||||||
|
|
||||||
CalculateLineHeight();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxGenericTreeCtrl::AssignButtonsImageList(wxImageList *imageList)
|
void wxGenericTreeCtrl::AssignButtonsImageList(wxImageList *imageList)
|
||||||
|
|||||||
@@ -931,6 +931,24 @@ void wxTreeCtrl::SetStateImageList(wxImageList *imageList)
|
|||||||
SetAnyImageList(imageList, TVSIL_STATE);
|
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,
|
size_t wxTreeCtrl::GetChildrenCount(const wxTreeItemId& item,
|
||||||
bool recursively) const
|
bool recursively) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -613,12 +613,27 @@ void wxTreeCtrl::SetImageList(wxImageList *imageList)
|
|||||||
{
|
{
|
||||||
wxWithImages::SetImageList(imageList);
|
wxWithImages::SetImageList(imageList);
|
||||||
|
|
||||||
|
DoUpdateIconsSize(imageList);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxTreeCtrl::DoUpdateIconsSize(wxImageList *imageList)
|
||||||
|
{
|
||||||
int width, height;
|
int width, height;
|
||||||
imageList->GetSize(0, width, height);
|
imageList->GetSize(0, width, height);
|
||||||
m_qtTreeWidget->ResizeIcons(QSize(width, height));
|
m_qtTreeWidget->ResizeIcons(QSize(width, height));
|
||||||
m_qtTreeWidget->update();
|
m_qtTreeWidget->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxTreeCtrl::OnImagesChanged()
|
||||||
|
{
|
||||||
|
if ( HasImages() )
|
||||||
|
{
|
||||||
|
UpdateImageListIfNecessary(this);
|
||||||
|
|
||||||
|
DoUpdateIconsSize(GetImageList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void wxTreeCtrl::SetStateImageList(wxImageList *imageList)
|
void wxTreeCtrl::SetStateImageList(wxImageList *imageList)
|
||||||
{
|
{
|
||||||
m_imagesState.SetImageList(imageList);
|
m_imagesState.SetImageList(imageList);
|
||||||
|
|||||||
Reference in New Issue
Block a user