diff --git a/docs/changes.txt b/docs/changes.txt index 624767ba25..e20e6429ac 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -77,6 +77,11 @@ Changes in behaviour not resulting in compilation errors called any longer by default, you need to explicitly enable 3.0 compatibility or change your code to override the newer overload, taking a wxWindow pointer. +- wxImageList size is now expressed in physical pixels, i.e. its size must be + the same as the size of bitmaps added to it, in pixels. This is inconvenient + but should be viewed as a hint not to use wxImageList (but wxBitmapBundle) + in the applications supporting high DPI. + Changes in behaviour which may result in build errors ----------------------------------------------------- diff --git a/include/wx/bmpbndl.h b/include/wx/bmpbndl.h index b8e140d0d0..7b60fd9d18 100644 --- a/include/wx/bmpbndl.h +++ b/include/wx/bmpbndl.h @@ -162,12 +162,12 @@ public: wxNODISCARD static wxSize GetConsensusSizeFor(double scale, const wxVector& bundles); wxNODISCARD static wxSize - GetConsensusSizeFor(wxWindow* win, const wxVector& bundles); + GetConsensusSizeFor(const wxWindow* win, const wxVector& bundles); // Create wxImageList and fill it with the images from the given bundles in // the sizes appropriate for the DPI scaling used for the specified window. wxNODISCARD static wxImageList* - CreateImageList(wxWindow* win, const wxVector& bundles); + CreateImageList(const wxWindow* win, const wxVector& bundles); private: typedef wxObjectDataPtr wxBitmapBundleImplPtr; diff --git a/include/wx/generic/imaglist.h b/include/wx/generic/imaglist.h index 2560418e41..a72bac36d7 100644 --- a/include/wx/generic/imaglist.h +++ b/include/wx/generic/imaglist.h @@ -10,42 +10,38 @@ #ifndef _WX_IMAGLISTG_H_ #define _WX_IMAGLISTG_H_ -#include "wx/bitmap.h" #include "wx/gdicmn.h" #include "wx/vector.h" -class WXDLLIMPEXP_FWD_CORE wxDC; -class WXDLLIMPEXP_FWD_CORE wxIcon; -class WXDLLIMPEXP_FWD_CORE wxColour; - - -class WXDLLIMPEXP_CORE wxGenericImageList: public wxObject +class WXDLLIMPEXP_CORE wxGenericImageList : public wxImageListBase { public: wxGenericImageList(); wxGenericImageList( int width, int height, bool mask = true, int initialCount = 1 ); virtual ~wxGenericImageList(); bool Create( int width, int height, bool mask = true, int initialCount = 1 ); - void Destroy(); + virtual void Destroy() override; - virtual int GetImageCount() const; - virtual bool GetSize( int index, int &width, int &height ) const; - virtual wxSize GetSize() const { return m_size; } + virtual int GetImageCount() const override; + virtual bool GetSize( int index, int &width, int &height ) const override; - int Add( const wxBitmap& bitmap ); - int Add( const wxBitmap& bitmap, const wxBitmap& mask ); - int Add( const wxBitmap& bitmap, const wxColour& maskColour ); - wxBitmap GetBitmap(int index) const; - wxIcon GetIcon(int index) const; - bool Replace( int index, + using wxImageListBase::GetSize; + + virtual int Add( const wxBitmap& bitmap ) override; + virtual int Add( const wxBitmap& bitmap, const wxBitmap& mask ) override; + virtual int Add( const wxBitmap& bitmap, const wxColour& maskColour ) override; + + virtual wxBitmap GetBitmap(int index) const override; + virtual wxIcon GetIcon(int index) const override; + virtual bool Replace( int index, const wxBitmap& bitmap, - const wxBitmap& mask = wxNullBitmap ); - bool Remove( int index ); - bool RemoveAll(); + const wxBitmap& mask = wxNullBitmap ) override; + virtual bool Remove( int index ) override; + virtual bool RemoveAll() override; virtual bool Draw(int index, wxDC& dc, int x, int y, int flags = wxIMAGELIST_DRAW_NORMAL, - bool solidBackground = false); + bool solidBackground = false) override; #if WXWIN_COMPATIBILITY_3_0 wxDEPRECATED_MSG("Don't use this overload: it's not portable and does nothing") @@ -61,10 +57,6 @@ private: wxBitmap GetImageListBitmap(const wxBitmap& bitmap) const; wxVector m_images; - bool m_useMask; - - // Size of a single bitmap in the list. - wxSize m_size; wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxGenericImageList); }; @@ -81,12 +73,7 @@ class WXDLLIMPEXP_CORE wxImageList: public wxGenericImageList wxDECLARE_DYNAMIC_CLASS(wxImageList); public: - wxImageList() {} - - wxImageList( int width, int height, bool mask = true, int initialCount = 1 ) - : wxGenericImageList(width, height, mask, initialCount) - { - } + using wxGenericImageList::wxGenericImageList; }; #endif // !wxHAS_NATIVE_IMAGELIST 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/imaglist.h b/include/wx/imaglist.h index 76954f68b6..e57df6cac0 100644 --- a/include/wx/imaglist.h +++ b/include/wx/imaglist.h @@ -12,6 +12,13 @@ #include "wx/defs.h" +#include "wx/bitmap.h" + +class WXDLLIMPEXP_FWD_CORE wxDC; +class WXDLLIMPEXP_FWD_CORE wxIcon; +class WXDLLIMPEXP_FWD_CORE wxColour; + + /* * wxImageList is used for wxListCtrl, wxTreeCtrl. These controls refer to * images for their items by an index into an image list. @@ -40,6 +47,51 @@ enum #define wxIMAGELIST_DRAW_SELECTED 0x0004 #define wxIMAGELIST_DRAW_FOCUSED 0x0008 +// Define the interface of platform-specific wxImageList class. +class wxImageListBase : public wxObject +{ +public: + /* + This class should provide default ctor as well as the following ctor: + + wxImageList(int width, int height, bool mask = true, int initialCount = 1) + + and Create() member function taking the same parameters and returning + bool. + */ + + virtual void Destroy() = 0; + + // Returns the size the image list was created with. + wxSize GetSize() const { return m_size; } + + virtual int GetImageCount() const = 0; + virtual bool GetSize(int index, int &width, int &height) const = 0; + + virtual int Add(const wxBitmap& bitmap) = 0; + virtual int Add(const wxBitmap& bitmap, const wxBitmap& mask) = 0; + virtual int Add(const wxBitmap& bitmap, const wxColour& maskColour) = 0; + + virtual bool Replace(int index, + const wxBitmap& bitmap, + const wxBitmap& mask = wxNullBitmap) = 0; + virtual bool Remove(int index) = 0; + virtual bool RemoveAll() = 0; + + virtual bool Draw(int index, wxDC& dc, int x, int y, + int flags = wxIMAGELIST_DRAW_NORMAL, + bool solidBackground = false) = 0; + + virtual wxBitmap GetBitmap(int index) const = 0; + virtual wxIcon GetIcon(int index) const = 0; + +protected: + // Size of a single bitmap in the list in physical pixels. + wxSize m_size; + + bool m_useMask = false; +}; + #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__) #include "wx/msw/imaglist.h" #define wxHAS_NATIVE_IMAGELIST diff --git a/include/wx/msw/imaglist.h b/include/wx/msw/imaglist.h index 8ebd8a61ce..17d6060646 100644 --- a/include/wx/msw/imaglist.h +++ b/include/wx/msw/imaglist.h @@ -10,20 +10,14 @@ #ifndef _WX_IMAGLIST_H_ #define _WX_IMAGLIST_H_ -#include "wx/bitmap.h" - -// Eventually we'll make this a reference-counted wxGDIObject. For -// now, the app must take care of ownership issues. That is, the -// image lists must be explicitly deleted after the control(s) that uses them -// is (are) deleted, or when the app exits. -class WXDLLIMPEXP_CORE wxImageList : public wxObject +class WXDLLIMPEXP_CORE wxImageList : public wxImageListBase { public: /* * Public interface */ - wxImageList() { Init(); } + wxImageList() = default; // Creates an image list. // Specify the width and height of the images in the list, @@ -31,7 +25,6 @@ public: // from icons), and the initial size of the list. wxImageList(int width, int height, bool mask = true, int initialCount = 1) { - Init(); Create(width, height, mask, initialCount); } virtual ~wxImageList(); @@ -41,13 +34,12 @@ public: //////////////////////////////////////////////////////////////////////////// // Returns the number of images in the image list. - int GetImageCount() const; + virtual int GetImageCount() const override; // Returns the size (same for all images) of the images in the list - bool GetSize(int index, int &width, int &height) const; + virtual bool GetSize(int index, int &width, int &height) const override; - // Returns the overall size - wxSize GetSize() const { return m_size; } + using wxImageListBase::GetSize; // Operations //////////////////////////////////////////////////////////////////////////// @@ -59,17 +51,21 @@ public: bool Create(int width, int height, bool mask = true, int initialNumber = 1); // Destroys the image list, Create() may then be called again later. - void Destroy(); + virtual void Destroy() override; // Adds a bitmap, and optionally a mask bitmap. // Note that wxImageList creates *new* bitmaps, so you may delete // 'bitmap' and 'mask' after calling Add. - int Add(const wxBitmap& bitmap, const wxBitmap& mask = wxNullBitmap); + virtual int Add(const wxBitmap& bitmap, const wxBitmap& mask) override; + virtual int Add(const wxBitmap& bitmap) override + { + return Add(bitmap, wxNullBitmap); + } // Adds a bitmap, using the specified colour to create the mask bitmap // Note that wxImageList creates *new* bitmaps, so you may delete // 'bitmap' after calling Add. - int Add(const wxBitmap& bitmap, const wxColour& maskColour); + virtual int Add(const wxBitmap& bitmap, const wxColour& maskColour) override; // Adds a bitmap and mask from an icon. int Add(const wxIcon& icon); @@ -77,31 +73,31 @@ public: // Replaces a bitmap, optionally passing a mask bitmap. // Note that wxImageList creates new bitmaps, so you may delete // 'bitmap' and 'mask' after calling Replace. - bool Replace(int index, const wxBitmap& bitmap, const wxBitmap& mask = wxNullBitmap); + virtual bool Replace(int index, const wxBitmap& bitmap, const wxBitmap& mask = wxNullBitmap) override; // Replaces a bitmap and mask from an icon. // You can delete 'icon' after calling Replace. bool Replace(int index, const wxIcon& icon); // Removes the image at the given index. - bool Remove(int index); + virtual bool Remove(int index) override; // Remove all images - bool RemoveAll(); + virtual bool RemoveAll() override; // Draws the given image on a dc at the specified position. // If 'solidBackground' is true, Draw sets the image list background // colour to the background colour of the wxDC, to speed up // drawing by eliminating masked drawing where possible. - bool Draw(int index, wxDC& dc, int x, int y, + virtual bool Draw(int index, wxDC& dc, int x, int y, int flags = wxIMAGELIST_DRAW_NORMAL, - bool solidBackground = false); + bool solidBackground = false) override; // Get a bitmap - wxBitmap GetBitmap(int index) const; + virtual wxBitmap GetBitmap(int index) const override; // Get an icon - wxIcon GetIcon(int index) const; + virtual wxIcon GetIcon(int index) const override; // TODO: miscellaneous functionality /* @@ -195,8 +191,7 @@ public: WXHIMAGELIST GetHIMAGELIST() const { return m_hImageList; } protected: - WXHIMAGELIST m_hImageList; - wxSize m_size; + WXHIMAGELIST m_hImageList = nullptr; private: // Private helper used by GetImageListBitmaps(). @@ -207,14 +202,6 @@ private: void GetImageListBitmaps(wxMSWBitmaps& bitmaps, const wxBitmap& bitmap, const wxBitmap& mask); - bool m_useMask; - - void Init() - { - m_hImageList = nullptr; - m_useMask = false; - } - wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxImageList); }; 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..a0579011d9 100644 --- a/include/wx/treectrl.h +++ b/include/wx/treectrl.h @@ -56,10 +56,22 @@ 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; + + // Simple accessors similar to the inherited from wxWithImages + // HasImages() and GetImageCount() for normal images. + bool HasStateImages() const { return m_imagesState.HasImages(); } + int GetStateImageCount() const { return m_imagesState.GetImageCount(); } + + // 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/include/wx/withimages.h b/include/wx/withimages.h index 12fe439586..bec093d6d0 100644 --- a/include/wx/withimages.h +++ b/include/wx/withimages.h @@ -76,6 +76,15 @@ public: { m_images = images; + // Setting the images overrides any image list set before, especially + // because we may have set it ourselves if GetUpdatedImageListFor() was + // called and we don't want to remain with the outdated image list now + // (if the new images are not empty, this would happen only slightly + // later when the image list is updated again, but if they are empty, + // it's not going to happen at all). + FreeIfNeeded(); + m_imageList = nullptr; + OnImagesChanged(); } @@ -129,6 +138,33 @@ public: return m_imageList; } + // Return physical bitmap size that should be used for all images. + // + // Returns (0, 0) if we don't have any images. + wxSize GetImageSize(const wxWindow* window) const + { + wxSize size; + + // Prefer to use the image list here if we have it because we must have + // already decided for the best size to use when creating it. + // + // Otherwise we need to compute the best size here ourselves. + if ( m_imageList ) + size = m_imageList->GetSize(); + else if ( !m_images.empty() ) + size = wxBitmapBundle::GetConsensusSizeFor(window, m_images); + + return size; + } + + // Return logical bitmap size that should be used for all images. + // + // Returns (0, 0) if we don't have any images. + wxSize GetImageLogicalSize(const wxWindow* window) const + { + return window->FromPhys(GetImageSize(window)); + } + // Return logical size of the image to use or (0, 0) if there are none. wxSize GetImageLogicalSize(const wxWindow* window, int iconIndex) const { @@ -143,7 +179,7 @@ public: else if ( m_imageList ) { // All images in the image list are of the same size. - size = m_imageList->GetSize(); + size = window->FromPhys(m_imageList->GetSize()); } } @@ -171,7 +207,23 @@ public: { if ( !m_images.empty() ) { - bitmap = m_images.at(iconIndex).GetBitmapFor(window); + // Note that it's not enough to just use GetBitmapFor() here to + // choose the bitmap of the size most appropriate for the window + // DPI as we need it to be of the same size as the other images + // used in the same control, so we have to use fixed size here. + const wxSize size = GetImageSize(window); + + bitmap = m_images.at(iconIndex).GetBitmap(size); + + // We also may need to adjust the scale factor to ensure that + // this bitmap takes the same space as all the others, as + // GetBitmap() may set it wrong in this case. + const wxSize logicalSize = window->FromPhys(size); + + if ( bitmap.GetLogicalSize() != logicalSize ) + { + bitmap.SetScaleFactor(size.y / logicalSize.y); + } } else if ( m_imageList ) { diff --git a/interface/wx/imaglist.h b/interface/wx/imaglist.h index 720690813b..885d5b6778 100644 --- a/interface/wx/imaglist.h +++ b/interface/wx/imaglist.h @@ -59,7 +59,8 @@ public: Constructor specifying the image size, whether image masks should be created, and the initial size of the list. - Note that the size is specified in logical pixels. + Note that the size is specified in physical pixels and must correspond + to the size of bitmaps, in pixels, that will be added to this list. @param width Width of the images in the list. @@ -83,10 +84,10 @@ public: /** Adds a new image or images using a bitmap and optional mask bitmap. - The logical size of the bitmap should be the same as the size specified - when constructing wxImageList. If the logical width of the bitmap is - greater than the image list width, bitmap is split into smaller images - of the required width. + The physical size of the bitmap should be the same as the size specified + when constructing wxImageList. If the width of the bitmap is greater + than the image list width, bitmap is split into smaller images of the + required width, allowing to add multiple images from a single bitmap. @param bitmap Bitmap representing the opaque areas of the image. @@ -101,10 +102,10 @@ public: /** Adds a new image or images using a bitmap and mask colour. - The logical size of the bitmap should be the same as the size specified - when constructing wxImageList. If the logical width of the bitmap is - greater than the image list width, bitmap is split into smaller images - of the required width. + The physical size of the bitmap should be the same as the size specified + when constructing wxImageList. If the width of the bitmap is greater + than the image list width, bitmap is split into smaller images of the + required width, allowing to add multiple images from a single bitmap. @param bitmap Bitmap representing the opaque areas of the image. @@ -118,7 +119,7 @@ public: /** Adds a new image using an icon. - The logical size of the icon should be the same as the size specified + The physical size of the icon should be the same as the size specified when constructing wxImageList. @param icon @@ -201,9 +202,9 @@ public: @param index currently unused, should be 0 @param width - receives the width of the images in the list + receives the width of the images in the list in pixels @param height - receives the height of the images in the list + receives the height of the images in the list in pixels @return @true if the function succeeded, @false if it failed (for example, if the image list was not yet initialized). diff --git a/interface/wx/treectrl.h b/interface/wx/treectrl.h index 382e81d5a2..30fa4fb572 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); @@ -695,12 +699,38 @@ public: */ virtual size_t GetSelections(wxArrayTreeItemIds& selection) const; + /** + Returns the number of state images used by the control. + + Returns the number of images passed to the last call to + SetStateImages() or 0 if it had been never called. + + @see HasImages() + + @since 3.3.0 + */ + int GetStateImageCount() const; + /** Returns the state image list (from which application-defined state images are taken). + + @see HasStateImages(), GetStateImageCount() */ wxImageList* GetStateImageList() const; + /** + Returns true if the control uses any state images. + + This is equivalent to comparing GetStateImageCount() return value with + 0 but more clear. + + @see SetStateImages(), GetStateImageCount() + + @since 3.3.0 + */ + bool HasStateImages() const; + /** Calculates which (if any) item is under the given @a point, returning the tree item id at this point plus extra information @a flags. @a flags @@ -976,10 +1006,26 @@ 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. + + @see HasStateImages(), GetStateImageCount() + + @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/state0_2x_png.h b/samples/treectrl/state0_2x_png.h new file mode 100644 index 0000000000..1afe5e52f0 --- /dev/null +++ b/samples/treectrl/state0_2x_png.h @@ -0,0 +1,68 @@ +/* state0_2x.png - 525 bytes */ +static const unsigned char state0_2x_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, + 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, + 0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a, + 0xf4, 0x00, 0x00, 0x01, 0xd4, 0x49, 0x44, 0x41, + 0x54, 0x58, 0xc3, 0x63, 0x60, 0x80, 0x02, 0xe9, + 0x86, 0xa3, 0x06, 0x52, 0x0d, 0x87, 0x97, 0x4b, + 0x35, 0x1e, 0x79, 0x01, 0xc4, 0xff, 0x69, 0x84, + 0x9f, 0x4b, 0x35, 0x1e, 0x5d, 0x26, 0xd3, 0x70, + 0x48, 0x8f, 0x01, 0x19, 0x48, 0x36, 0x1e, 0x89, + 0x06, 0x4a, 0xfe, 0xa2, 0xa1, 0xc5, 0xe8, 0xf8, + 0xa7, 0x54, 0xd3, 0x91, 0x28, 0x84, 0xcf, 0xe9, + 0x6b, 0x39, 0xdc, 0x11, 0xe0, 0x90, 0x80, 0x06, + 0xfb, 0xff, 0x01, 0xc1, 0x0d, 0x47, 0x96, 0x32, + 0x00, 0x19, 0x2f, 0x07, 0xcc, 0x01, 0xc0, 0x34, + 0x01, 0x72, 0xc0, 0xbf, 0x01, 0x74, 0xc0, 0x3f, + 0x06, 0x4a, 0x0d, 0x51, 0x6d, 0x3f, 0xfe, 0x3f, + 0x7a, 0xe9, 0xd5, 0xff, 0x9e, 0xb3, 0x2f, 0x90, + 0xa5, 0x9f, 0x22, 0x07, 0x18, 0xf6, 0x9d, 0xfa, + 0xff, 0xe4, 0xc3, 0x8f, 0xff, 0x30, 0xb0, 0xe8, + 0xcc, 0x73, 0xfa, 0x3a, 0xa0, 0x6b, 0xff, 0xc3, + 0xff, 0xe8, 0xc0, 0xa0, 0xf7, 0x14, 0xfd, 0x1c, + 0x50, 0xbc, 0xe9, 0x36, 0x8a, 0xe5, 0x5f, 0x7e, + 0xfe, 0xf9, 0xaf, 0xdc, 0x76, 0x8c, 0x7e, 0x0e, + 0x90, 0x6d, 0x3a, 0xfa, 0x7f, 0xde, 0xa9, 0x67, + 0xff, 0xdf, 0x7c, 0xfd, 0xf5, 0xff, 0xee, 0x9b, + 0x6f, 0xff, 0x63, 0x97, 0x5d, 0xa5, 0x6f, 0x14, + 0x50, 0x03, 0x53, 0x9c, 0x08, 0xb5, 0xbb, 0x4e, + 0xd0, 0xd7, 0x01, 0x21, 0x0b, 0x2f, 0xff, 0x5f, + 0x7d, 0xf1, 0xe5, 0xff, 0x97, 0x9f, 0x7f, 0x82, + 0xe3, 0xfd, 0x1f, 0x10, 0x6f, 0xb9, 0xfa, 0xe6, + 0xbf, 0x42, 0xcb, 0x31, 0xda, 0x3b, 0x00, 0x94, + 0xc2, 0x4f, 0x3f, 0xfa, 0xf4, 0x7f, 0xe3, 0x95, + 0xd7, 0xff, 0x3f, 0xfd, 0xf8, 0x83, 0x92, 0x00, + 0xcb, 0x36, 0xdf, 0xa1, 0x6f, 0x14, 0x74, 0xa3, + 0x65, 0xc1, 0x59, 0x27, 0x9e, 0xd2, 0xd7, 0x01, + 0x53, 0x8f, 0x3e, 0x41, 0x71, 0x40, 0xdb, 0x9e, + 0x07, 0xf4, 0x75, 0xc0, 0xa1, 0xbb, 0xef, 0x51, + 0x1c, 0x10, 0xb4, 0xe0, 0x12, 0xfd, 0x1c, 0xa0, + 0xd4, 0x7a, 0xec, 0xff, 0xf7, 0xdf, 0x7f, 0xe1, + 0x96, 0x7f, 0x06, 0x16, 0x40, 0x72, 0xcd, 0x47, + 0xe9, 0xe7, 0x80, 0xa8, 0x25, 0x57, 0x50, 0x7c, + 0xbf, 0xeb, 0xe6, 0x5b, 0xfa, 0x96, 0x03, 0x33, + 0x8e, 0xa1, 0xc6, 0x7f, 0xcd, 0xf6, 0xbb, 0xf4, + 0x75, 0xc0, 0xb5, 0x17, 0x5f, 0x50, 0x1c, 0xe0, + 0x38, 0xed, 0x1c, 0xfd, 0x1c, 0x00, 0x2a, 0x70, + 0xfe, 0xa1, 0xd5, 0x80, 0xea, 0x1d, 0xc7, 0xe9, + 0xe7, 0x00, 0x69, 0x20, 0x7e, 0xf6, 0xf1, 0x27, + 0x8a, 0x03, 0x56, 0x5d, 0x78, 0xf9, 0xbf, 0x7c, + 0xcb, 0x9d, 0xff, 0x65, 0x5b, 0xee, 0xd0, 0x27, + 0x0a, 0xe2, 0x96, 0x5f, 0xfb, 0xff, 0x03, 0x29, + 0x17, 0x80, 0x42, 0xe4, 0xf2, 0xf3, 0x2f, 0xff, + 0xf3, 0xd6, 0xdf, 0xa2, 0x5f, 0x39, 0x60, 0x04, + 0xac, 0x88, 0x52, 0x57, 0x5d, 0xff, 0x1f, 0xb1, + 0xf8, 0xca, 0x7f, 0xdd, 0xee, 0x93, 0x14, 0x45, + 0xc1, 0x80, 0x37, 0x4a, 0x5f, 0x0c, 0x70, 0xb3, + 0xfc, 0xe8, 0xb2, 0x01, 0x74, 0xc0, 0x12, 0x06, + 0x50, 0xf7, 0x08, 0xdc, 0x57, 0xa3, 0xbf, 0xe5, + 0x3f, 0xc4, 0x1b, 0x8e, 0xea, 0x80, 0xfb, 0x87, + 0xa0, 0x8e, 0x22, 0x9d, 0x1d, 0xf1, 0x43, 0xaa, + 0xf1, 0x70, 0x24, 0x4a, 0x0f, 0x19, 0x1c, 0x12, + 0xc0, 0xbe, 0x1a, 0x50, 0xf2, 0x19, 0x0d, 0x2d, + 0x06, 0x99, 0xbd, 0x04, 0xee, 0x73, 0x20, 0x00, + 0x00, 0x10, 0x36, 0xc0, 0x2e, 0xe6, 0x2a, 0xe9, + 0x42, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, + 0x44, 0xae, 0x42, 0x60, 0x82}; diff --git a/samples/treectrl/state0_png.h b/samples/treectrl/state0_png.h new file mode 100644 index 0000000000..58ae744b90 --- /dev/null +++ b/samples/treectrl/state0_png.h @@ -0,0 +1,38 @@ +/* state0.png - 287 bytes */ +static const unsigned char state0_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, + 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, + 0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, + 0x61, 0x00, 0x00, 0x00, 0xe6, 0x49, 0x44, 0x41, + 0x54, 0x38, 0xcb, 0x63, 0x90, 0x68, 0x3b, 0x24, + 0x2a, 0xdd, 0x78, 0x64, 0x8d, 0x54, 0xe3, 0x91, + 0x2f, 0x40, 0xfc, 0x9f, 0x48, 0xfc, 0x45, 0xb2, + 0xe9, 0xf0, 0x6a, 0xa9, 0x86, 0xfd, 0x22, 0x0c, + 0x50, 0xcd, 0xff, 0xc9, 0xc3, 0x47, 0x57, 0x31, + 0x90, 0x68, 0x33, 0x3a, 0xfe, 0xcc, 0x80, 0x4f, + 0x81, 0x42, 0xcb, 0xb1, 0xff, 0xb3, 0x8e, 0x3f, + 0xfd, 0xdf, 0xb0, 0xf3, 0x1e, 0x4e, 0x35, 0x78, + 0x0d, 0xf0, 0x9d, 0x7b, 0xf1, 0x3f, 0x08, 0xfc, + 0xf9, 0xf7, 0xef, 0xbf, 0x62, 0xeb, 0x31, 0xd2, + 0x0d, 0x00, 0x86, 0xcf, 0xff, 0xfc, 0x0d, 0xb7, + 0xfe, 0xc7, 0x2c, 0xbd, 0x4a, 0xba, 0x0b, 0x40, + 0xb6, 0x77, 0xef, 0x7f, 0xf8, 0xbf, 0x6c, 0xcb, + 0x1d, 0xbc, 0xe1, 0x80, 0xd5, 0x00, 0xd9, 0xa6, + 0xa3, 0xff, 0x73, 0xd7, 0xdd, 0xfc, 0xff, 0xf0, + 0xfd, 0x77, 0xb0, 0x17, 0x3c, 0x67, 0x5f, 0x20, + 0x2f, 0x0c, 0xae, 0xbd, 0xf8, 0x02, 0x36, 0xc0, + 0x71, 0xda, 0x39, 0xd2, 0x0d, 0xd0, 0xee, 0x3a, + 0xf1, 0xff, 0xef, 0xbf, 0xff, 0xff, 0x5f, 0x7f, + 0xf9, 0x05, 0x0e, 0x0b, 0x92, 0x0d, 0xc8, 0x58, + 0x73, 0x03, 0x6c, 0xfb, 0xfa, 0xcb, 0xaf, 0x48, + 0x0f, 0x03, 0x10, 0x06, 0xc5, 0x3d, 0x08, 0xec, + 0xba, 0xf9, 0xf6, 0xbf, 0xfb, 0x2c, 0x32, 0xc2, + 0x40, 0xb3, 0xf3, 0xc4, 0xff, 0xb9, 0x27, 0x9f, + 0xfd, 0x9f, 0x03, 0xc4, 0x91, 0x4b, 0xae, 0xe0, + 0x35, 0x80, 0xb2, 0xa4, 0x0c, 0xce, 0x55, 0xe4, + 0x1a, 0xd0, 0x70, 0x64, 0x25, 0x03, 0x28, 0x4b, + 0x42, 0x0d, 0xf9, 0x4c, 0x8a, 0xcd, 0x20, 0xcd, + 0x20, 0xbd, 0x00, 0x4e, 0x99, 0x73, 0x54, 0x25, + 0xd3, 0x47, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; diff --git a/samples/treectrl/state1_2x_png.h b/samples/treectrl/state1_2x_png.h new file mode 100644 index 0000000000..f9a2b57539 --- /dev/null +++ b/samples/treectrl/state1_2x_png.h @@ -0,0 +1,98 @@ +/* state1_2x.png - 765 bytes */ +static const unsigned char state1_2x_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, + 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, + 0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a, + 0xf4, 0x00, 0x00, 0x02, 0xc4, 0x49, 0x44, 0x41, + 0x54, 0x58, 0xc3, 0x63, 0x60, 0x20, 0x12, 0xec, + 0xd4, 0x73, 0xe3, 0xde, 0xaf, 0xe6, 0x10, 0xbe, + 0x4f, 0xcd, 0x71, 0x12, 0x90, 0x3e, 0xb5, 0x5f, + 0xcd, 0xf1, 0x31, 0x10, 0x7f, 0x03, 0xe2, 0x5f, + 0x40, 0xfc, 0x0a, 0x24, 0x06, 0x94, 0x9b, 0x05, + 0xa4, 0x23, 0x8e, 0xa8, 0x5b, 0xf3, 0x32, 0x50, + 0x0b, 0xec, 0x51, 0x73, 0x51, 0x82, 0x18, 0xec, + 0xf8, 0x09, 0x88, 0xff, 0x13, 0x83, 0x0f, 0xa8, + 0x3b, 0x7e, 0x05, 0xd2, 0x73, 0x0e, 0x6a, 0xda, + 0xa9, 0x92, 0x6d, 0xf1, 0x7e, 0x05, 0x07, 0x0e, + 0xa0, 0x6f, 0xda, 0x81, 0x06, 0xfd, 0x20, 0xd6, + 0x62, 0x2c, 0xf8, 0xd7, 0x3e, 0x75, 0xc7, 0x2e, + 0x90, 0x59, 0x24, 0x59, 0x7e, 0x50, 0xd9, 0x4e, + 0xf6, 0x80, 0x9a, 0xe3, 0x49, 0x0a, 0x2c, 0x46, + 0xc7, 0xc7, 0x0f, 0x69, 0xda, 0x4a, 0x12, 0x65, + 0xf9, 0x3e, 0x15, 0x47, 0x6d, 0xa0, 0x86, 0xd7, + 0x54, 0xb4, 0x1c, 0x86, 0x1f, 0xef, 0x51, 0x77, + 0xd6, 0xc3, 0x1f, 0xec, 0xca, 0x0e, 0x2a, 0x40, + 0x85, 0xcf, 0x08, 0x19, 0x76, 0xbb, 0x65, 0xca, + 0xff, 0x57, 0xdb, 0x0f, 0xa0, 0x60, 0x90, 0x18, + 0x31, 0x8e, 0xd8, 0xaf, 0xed, 0x20, 0x81, 0xd5, + 0xf2, 0x33, 0xc6, 0xc6, 0xac, 0xd0, 0xd4, 0x4d, + 0xd0, 0xa0, 0x67, 0xab, 0xb7, 0xfe, 0x47, 0x07, + 0xcf, 0x56, 0x6d, 0x21, 0x36, 0x24, 0xce, 0x1c, + 0x93, 0xb1, 0xe4, 0xc4, 0xf4, 0xbd, 0x9a, 0x53, + 0x07, 0xb1, 0xc1, 0xf9, 0x78, 0xc1, 0x1a, 0x0c, + 0x07, 0x3c, 0x9e, 0xbf, 0x9a, 0xe8, 0xe8, 0x00, + 0xa6, 0xaf, 0x46, 0x8c, 0x44, 0x47, 0x4a, 0x6a, + 0x7f, 0x30, 0x75, 0x11, 0x86, 0x03, 0xee, 0x4f, + 0x59, 0x48, 0x4a, 0x7a, 0xf8, 0x82, 0x92, 0x28, + 0xf7, 0xab, 0x3a, 0x4c, 0x27, 0x25, 0x41, 0xdd, + 0xed, 0x9a, 0x89, 0xe1, 0x80, 0x3b, 0x5d, 0x33, + 0x48, 0x4a, 0x94, 0xfb, 0x54, 0x1d, 0xa7, 0x81, + 0x2d, 0x07, 0xc5, 0x07, 0x50, 0xe0, 0x33, 0x29, + 0x9a, 0x6f, 0xd6, 0xf7, 0x63, 0x38, 0xe0, 0x66, + 0x5d, 0x1f, 0xa9, 0xb9, 0xe2, 0x0b, 0xb8, 0xc4, + 0x3c, 0xa0, 0xe6, 0x14, 0x48, 0x6a, 0x96, 0xba, + 0x56, 0xd2, 0x86, 0xe1, 0x80, 0x6b, 0xc5, 0xad, + 0x64, 0x64, 0x4d, 0x87, 0x70, 0x92, 0x83, 0x1f, + 0x84, 0x2f, 0x67, 0xd6, 0x60, 0x38, 0xe0, 0x72, + 0x46, 0x35, 0xc9, 0x0e, 0x00, 0x26, 0xc6, 0x99, + 0xc0, 0xd4, 0xef, 0x78, 0x98, 0x54, 0x8d, 0x17, + 0xe2, 0x8a, 0x30, 0x1c, 0x70, 0x3e, 0xb6, 0x90, + 0xac, 0x12, 0x12, 0x18, 0x05, 0x8e, 0x2f, 0x49, + 0xd5, 0x78, 0x36, 0x24, 0x13, 0xc3, 0x01, 0x67, + 0x82, 0x33, 0xc8, 0x09, 0x81, 0x97, 0xa0, 0x10, + 0xf8, 0x42, 0xaa, 0xc6, 0x93, 0x9e, 0x09, 0x18, + 0x0e, 0x38, 0xe9, 0x11, 0x4f, 0x4e, 0x08, 0xfc, + 0x60, 0x20, 0xa7, 0xb6, 0x3b, 0x66, 0x17, 0x86, + 0xe1, 0x80, 0x63, 0xb6, 0xa1, 0xa4, 0x87, 0x00, + 0xb0, 0xda, 0x06, 0x45, 0xc1, 0x53, 0x52, 0x35, + 0x1e, 0x36, 0xf6, 0xc1, 0x70, 0xc0, 0x61, 0x23, + 0x6f, 0x72, 0x1c, 0xf0, 0x10, 0xe4, 0x80, 0xa3, + 0x24, 0x6b, 0xd4, 0x74, 0xc6, 0xa8, 0x8c, 0x40, + 0x62, 0x64, 0x25, 0x42, 0x72, 0xb2, 0x21, 0xd5, + 0xb0, 0xaa, 0xd3, 0x04, 0xb2, 0x0a, 0x22, 0xaa, + 0x61, 0x75, 0x87, 0x10, 0x86, 0x6d, 0x2a, 0x9e, + 0x7c, 0xa4, 0x16, 0xc5, 0x20, 0x7c, 0xbd, 0xb2, + 0xf3, 0xff, 0xcb, 0xad, 0xfb, 0xfe, 0x3f, 0x5b, + 0xb9, 0xe5, 0xff, 0x29, 0x9f, 0x64, 0x72, 0x1c, + 0xf0, 0x7e, 0xb3, 0x94, 0x2f, 0x17, 0xb4, 0x2a, + 0x76, 0x98, 0x4c, 0x52, 0x51, 0x5c, 0xdc, 0x82, + 0x92, 0x00, 0x7f, 0xbd, 0xfb, 0xf0, 0xff, 0x90, + 0x81, 0x17, 0xa9, 0x65, 0xc0, 0x54, 0x78, 0x6d, + 0xb8, 0x57, 0xc5, 0x49, 0x99, 0x94, 0xec, 0xf8, + 0x64, 0xf1, 0x7a, 0xcc, 0x82, 0x28, 0x30, 0x8d, + 0x14, 0x07, 0x7c, 0xdb, 0xad, 0xe4, 0x22, 0x87, + 0xd2, 0x26, 0x00, 0x35, 0x12, 0xc8, 0xad, 0x8e, + 0xff, 0xfd, 0xf9, 0xfb, 0xff, 0xa8, 0x55, 0x10, + 0x09, 0x71, 0xef, 0xd4, 0x82, 0xd1, 0x22, 0x02, + 0xa6, 0x05, 0x76, 0xa0, 0x23, 0x2e, 0x12, 0x63, + 0xc0, 0x21, 0x7d, 0xcf, 0xff, 0xaf, 0x76, 0x1c, + 0xf8, 0xff, 0xe7, 0xdb, 0x8f, 0xff, 0x3f, 0x5e, + 0xbe, 0xf9, 0x7f, 0xb3, 0xb6, 0x97, 0x94, 0x1a, + 0xf0, 0x14, 0xc8, 0x2e, 0x7c, 0xcd, 0xf1, 0xa7, + 0x34, 0x4c, 0xf9, 0x2f, 0x30, 0x82, 0x1e, 0xa3, + 0x27, 0x04, 0x6c, 0x3a, 0xd3, 0xc8, 0x11, 0x4f, + 0x80, 0xbe, 0xd7, 0x20, 0xba, 0x63, 0x02, 0xd4, + 0x70, 0x81, 0x8a, 0x96, 0x9f, 0x06, 0x75, 0xf1, + 0x48, 0xea, 0x1d, 0x81, 0xe2, 0x09, 0xd8, 0x52, + 0x6e, 0xa0, 0xb0, 0x6b, 0xf6, 0x1d, 0x94, 0xe0, + 0x40, 0x4d, 0x7e, 0x4a, 0x3b, 0xa7, 0x93, 0x48, + 0xe9, 0x9c, 0x82, 0x0a, 0x36, 0x50, 0x3e, 0xdf, + 0xaf, 0xe2, 0x20, 0x43, 0xb5, 0x5e, 0x32, 0xb0, + 0x47, 0xc3, 0x03, 0xec, 0x68, 0xfa, 0x83, 0x0d, + 0x56, 0x73, 0x3c, 0x02, 0x89, 0x53, 0x70, 0x5b, + 0xe2, 0x1d, 0x28, 0x71, 0x01, 0xc5, 0x0f, 0x82, + 0xe4, 0x40, 0x6a, 0xb0, 0x76, 0x3c, 0x70, 0x00, + 0x00, 0x5d, 0x96, 0x8a, 0x03, 0xb0, 0xf9, 0xb5, + 0xa3, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, + 0x44, 0xae, 0x42, 0x60, 0x82}; diff --git a/samples/treectrl/state1_png.h b/samples/treectrl/state1_png.h new file mode 100644 index 0000000000..5d1514a96e --- /dev/null +++ b/samples/treectrl/state1_png.h @@ -0,0 +1,54 @@ +/* state1.png - 415 bytes */ +static const unsigned char state1_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, + 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, + 0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, + 0x61, 0x00, 0x00, 0x01, 0x66, 0x49, 0x44, 0x41, + 0x54, 0x38, 0xcb, 0x63, 0x60, 0x40, 0x03, 0xfb, + 0xd4, 0x1c, 0xf5, 0x0f, 0xa8, 0x39, 0x4e, 0xdd, + 0xaf, 0xe6, 0x78, 0x1d, 0x88, 0xbf, 0x01, 0xf1, + 0x17, 0x20, 0xbe, 0xb2, 0x5f, 0xd5, 0x69, 0xc2, + 0x7e, 0x4d, 0x07, 0x1d, 0x06, 0x5c, 0xe0, 0x98, + 0x8c, 0x25, 0xe7, 0x7e, 0x55, 0x87, 0xe9, 0x40, + 0x03, 0xfe, 0x02, 0x35, 0xfc, 0xc7, 0x81, 0xff, + 0x00, 0xf1, 0x94, 0x55, 0xda, 0xa1, 0x6c, 0x98, + 0x9a, 0xd5, 0x1d, 0x0f, 0x20, 0x2b, 0x3e, 0x66, + 0x17, 0xf6, 0xff, 0x4a, 0x5e, 0x03, 0x18, 0x83, + 0xd8, 0xc8, 0x72, 0x40, 0x17, 0xee, 0x45, 0x31, + 0x04, 0xa8, 0x79, 0x06, 0xba, 0x6d, 0x97, 0xd2, + 0x2a, 0xff, 0xc3, 0xc0, 0xa5, 0xd4, 0x0a, 0x2c, + 0xae, 0x71, 0x98, 0x0c, 0xd6, 0xbc, 0x47, 0xdd, + 0x59, 0x0f, 0x28, 0xf0, 0x0f, 0x5d, 0xc1, 0xf9, + 0xe8, 0x7c, 0xb8, 0x01, 0xe7, 0xa2, 0xf2, 0xb0, + 0x7a, 0x67, 0x9f, 0x8a, 0xa3, 0x36, 0x03, 0x34, + 0xc0, 0x30, 0x14, 0x9c, 0x0e, 0x48, 0x83, 0x1b, + 0x70, 0xda, 0x3f, 0x15, 0x6b, 0x98, 0x00, 0xc3, + 0xab, 0x8f, 0x01, 0xc8, 0xb8, 0x81, 0x4d, 0xf2, + 0x84, 0x6b, 0x0c, 0xdc, 0x80, 0x13, 0x2e, 0xd1, + 0xd8, 0x03, 0x55, 0xd5, 0xf1, 0x32, 0xc8, 0x80, + 0x1f, 0xd8, 0x24, 0x8f, 0x5a, 0x05, 0xc1, 0x0d, + 0x38, 0x6a, 0x19, 0x88, 0x2b, 0x56, 0x3e, 0xe1, + 0x34, 0xe0, 0x90, 0xbe, 0x27, 0xdc, 0x80, 0x43, + 0xfa, 0x1e, 0x58, 0x0d, 0x38, 0xa0, 0xee, 0xf8, + 0x95, 0x01, 0x9a, 0x60, 0x30, 0x15, 0xa8, 0x3b, + 0xc1, 0xa3, 0x11, 0xc4, 0xc6, 0x6a, 0x80, 0x9a, + 0xe3, 0x55, 0x9c, 0x81, 0x08, 0xc2, 0x17, 0xe2, + 0x8a, 0xfe, 0x9f, 0x09, 0x4c, 0xc3, 0xe5, 0x7c, + 0x50, 0x20, 0x4e, 0x02, 0x47, 0x23, 0xb6, 0xd4, + 0x77, 0x2e, 0x32, 0x0f, 0xec, 0xfc, 0x7f, 0xbf, + 0x7f, 0xff, 0x3f, 0x6c, 0xe2, 0x8b, 0x4d, 0xf3, + 0x5f, 0x78, 0xd2, 0xde, 0xa7, 0xea, 0x38, 0x0d, + 0x5d, 0xc1, 0x71, 0xa7, 0xa8, 0xff, 0x3f, 0x5f, + 0xbf, 0xfd, 0xff, 0xf9, 0xc6, 0xdd, 0xff, 0x07, + 0xb5, 0x5d, 0xb1, 0xb9, 0x60, 0x0a, 0x3c, 0x25, + 0x6e, 0x53, 0xf1, 0x64, 0x07, 0xa6, 0xac, 0x7d, + 0x78, 0xf2, 0x00, 0x3a, 0xde, 0x03, 0xd2, 0x83, + 0x92, 0x1f, 0x40, 0x02, 0x20, 0x97, 0xe0, 0xcb, + 0x4c, 0x50, 0xb9, 0x29, 0xfb, 0x15, 0x1c, 0x38, + 0x70, 0xe6, 0xca, 0x83, 0x1a, 0x76, 0xba, 0xa0, + 0x74, 0x0e, 0x0a, 0x61, 0xa0, 0xe2, 0xef, 0x40, + 0xfc, 0x19, 0x94, 0x9d, 0x41, 0x01, 0x86, 0x2d, + 0x3b, 0x03, 0x00, 0x58, 0x21, 0xed, 0xb5, 0xd7, + 0x41, 0xa9, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82}; diff --git a/samples/treectrl/state2_2x_png.h b/samples/treectrl/state2_2x_png.h new file mode 100644 index 0000000000..7093d894d0 --- /dev/null +++ b/samples/treectrl/state2_2x_png.h @@ -0,0 +1,96 @@ +/* state2_2x.png - 744 bytes */ +static const unsigned char state2_2x_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, + 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, + 0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a, + 0xf4, 0x00, 0x00, 0x02, 0xaf, 0x49, 0x44, 0x41, + 0x54, 0x58, 0xc3, 0xd5, 0x97, 0x4b, 0x68, 0xd4, + 0x50, 0x14, 0x86, 0x0f, 0x5a, 0x45, 0xf0, 0x55, + 0x17, 0xba, 0x50, 0xd1, 0xa2, 0x1b, 0x77, 0x82, + 0x52, 0xdc, 0x88, 0x16, 0x5c, 0x89, 0x82, 0x6e, + 0x8a, 0xa8, 0x68, 0xb7, 0x55, 0x11, 0x5c, 0xaa, + 0x0b, 0x11, 0xa4, 0xa2, 0x28, 0xe6, 0xe1, 0x30, + 0x38, 0xa3, 0xa5, 0x2a, 0x3e, 0x40, 0x69, 0x71, + 0x54, 0xa4, 0x16, 0xb5, 0x15, 0x7c, 0x80, 0x50, + 0x0a, 0x62, 0xb1, 0x4a, 0xb5, 0x62, 0x5d, 0xd8, + 0xd6, 0xbe, 0x26, 0x33, 0xc9, 0xcc, 0xe4, 0x71, + 0x3c, 0xc9, 0x98, 0x99, 0xc9, 0x98, 0x74, 0x6e, + 0xe6, 0x85, 0x5e, 0xf8, 0x21, 0x90, 0x7b, 0xef, + 0x77, 0xee, 0x39, 0x27, 0x7f, 0x12, 0x80, 0xff, + 0x75, 0x48, 0x1c, 0x34, 0x44, 0x45, 0x08, 0x47, + 0x05, 0x08, 0x91, 0x36, 0x57, 0x15, 0x4e, 0xc0, + 0x26, 0x92, 0x41, 0xc2, 0x3f, 0xd2, 0x25, 0x1e, + 0xf6, 0x54, 0x05, 0x3e, 0x15, 0x84, 0x25, 0x04, + 0x1c, 0xcf, 0x81, 0xdb, 0x1a, 0x9b, 0x08, 0xc1, + 0xe2, 0xca, 0xa7, 0x9e, 0x07, 0xce, 0x05, 0x9e, + 0x16, 0x0f, 0xe7, 0x2a, 0x7b, 0x7a, 0x0e, 0xd6, + 0x10, 0x28, 0xe1, 0x19, 0x80, 0x00, 0xca, 0x64, + 0x00, 0x56, 0x57, 0xb2, 0xf6, 0xf7, 0x67, 0x80, + 0x5b, 0x92, 0x04, 0xb8, 0x55, 0x11, 0xf8, 0x34, + 0x0f, 0x9b, 0xf2, 0x1a, 0xcf, 0x4b, 0x06, 0xcd, + 0xad, 0x2f, 0xff, 0xe9, 0x79, 0x78, 0xc5, 0x00, + 0xb7, 0xf5, 0xb2, 0xdc, 0x8d, 0xd7, 0x98, 0x49, + 0x71, 0xeb, 0x4a, 0x54, 0x5e, 0x34, 0x63, 0xaa, + 0xbf, 0x15, 0xd5, 0x6f, 0x9d, 0xa8, 0x0d, 0x77, + 0xa3, 0xfa, 0x25, 0x82, 0x89, 0x37, 0x27, 0xad, + 0x7b, 0x39, 0x41, 0xec, 0x2a, 0x0b, 0x1c, 0x43, + 0x30, 0x87, 0x36, 0xfb, 0x1c, 0xbb, 0xbe, 0x16, + 0xd5, 0xaf, 0x8f, 0x10, 0x0d, 0x1d, 0xbd, 0x86, + 0xa1, 0xc6, 0x51, 0xe9, 0xdc, 0x67, 0x07, 0x30, + 0x60, 0xae, 0x2d, 0xbd, 0xf6, 0x22, 0x1c, 0xb3, + 0x4e, 0x1e, 0x5e, 0x66, 0x01, 0x0a, 0x0e, 0x43, + 0xc3, 0xf8, 0xdd, 0x0d, 0xe9, 0x6c, 0xf1, 0x70, + 0xb8, 0x24, 0xf8, 0x24, 0x07, 0xb5, 0xb4, 0xd1, + 0x2f, 0x3b, 0xad, 0xc9, 0xde, 0x8b, 0x26, 0x01, + 0xb5, 0xef, 0xcf, 0xa8, 0x0c, 0x87, 0x30, 0xde, + 0xde, 0x80, 0xf1, 0x8e, 0x6d, 0x98, 0x7a, 0x1f, + 0x74, 0xc4, 0x90, 0xfa, 0x70, 0xd5, 0xce, 0xc2, + 0x68, 0x49, 0xe6, 0x44, 0x1b, 0x5c, 0x70, 0x3c, + 0x62, 0xe1, 0xa5, 0x18, 0xbb, 0xb9, 0xce, 0xb5, + 0xf1, 0xf4, 0xd1, 0xbe, 0x4c, 0x00, 0xda, 0x8f, + 0x9e, 0xec, 0x3d, 0x11, 0x5a, 0x8a, 0x3d, 0x7d, + 0x9d, 0x69, 0x2c, 0x4c, 0x5d, 0x2f, 0xce, 0x42, + 0x7d, 0x7a, 0x28, 0x13, 0x80, 0x3a, 0xd8, 0xe1, + 0x30, 0xa7, 0x09, 0x01, 0x56, 0x15, 0xd3, 0xf9, + 0x77, 0x58, 0xe1, 0xc9, 0x3e, 0xce, 0x51, 0x02, + 0xa5, 0xab, 0x29, 0x6f, 0x0e, 0xdc, 0xf0, 0x6b, + 0x3a, 0xf5, 0x2c, 0xa6, 0x23, 0x05, 0xe7, 0xd3, + 0x69, 0xdb, 0x1d, 0x70, 0x75, 0xe8, 0x31, 0x01, + 0x67, 0xe7, 0xcf, 0xd5, 0xa7, 0x04, 0xd8, 0xe8, + 0xc7, 0x74, 0x9e, 0x17, 0x84, 0x5f, 0xa9, 0x45, + 0x6d, 0xa4, 0xf7, 0xef, 0xe6, 0x0b, 0xcc, 0xf5, + 0xc8, 0x14, 0x74, 0xb3, 0xc1, 0x39, 0xd8, 0xcd, + 0x92, 0xfa, 0xd4, 0xc0, 0xed, 0x2c, 0x59, 0x4f, + 0x61, 0xa2, 0xe7, 0x68, 0xe1, 0x72, 0xf1, 0xb0, + 0x73, 0x66, 0xd3, 0x39, 0x0d, 0x35, 0x34, 0xb1, + 0xbf, 0xe0, 0x46, 0x81, 0x79, 0x04, 0x55, 0xb3, + 0x35, 0xa7, 0x47, 0x92, 0xd1, 0xa2, 0x3f, 0x9a, + 0x0c, 0xef, 0xc6, 0x13, 0xe0, 0x08, 0xcb, 0x46, + 0xb1, 0xb6, 0x3a, 0x47, 0xea, 0xa5, 0x6b, 0xcb, + 0x59, 0x03, 0x30, 0xdf, 0x96, 0xcd, 0xae, 0xf0, + 0xb1, 0xf3, 0xb0, 0x90, 0x26, 0xfc, 0x64, 0xda, + 0x24, 0xb8, 0x00, 0xe5, 0x27, 0x8d, 0x19, 0x79, + 0xd6, 0xdd, 0xbd, 0x0c, 0x23, 0xe3, 0x22, 0x2c, + 0x72, 0x33, 0x9d, 0xb3, 0x3e, 0xde, 0x76, 0x25, + 0x89, 0x9e, 0xb2, 0x33, 0x0e, 0xb8, 0x7c, 0x09, + 0x56, 0x50, 0x6a, 0xe2, 0x7e, 0x36, 0x91, 0x23, + 0x3b, 0x30, 0xf9, 0xae, 0x05, 0x95, 0xa7, 0x07, + 0x30, 0x7a, 0xb9, 0xc6, 0x6f, 0x10, 0xb2, 0xc3, + 0x9c, 0x4c, 0xa3, 0xf0, 0x0b, 0xcf, 0x1d, 0x89, + 0xd7, 0x27, 0xfc, 0x67, 0x82, 0x87, 0x36, 0x0b, + 0x1e, 0x13, 0x61, 0xbd, 0x69, 0x14, 0x7e, 0x16, + 0x27, 0xde, 0x9e, 0x72, 0x9a, 0x8f, 0xd3, 0x7a, + 0x59, 0x95, 0x36, 0x27, 0xba, 0x78, 0xe8, 0x77, + 0xb1, 0xfc, 0x60, 0x7b, 0x5e, 0x06, 0x8e, 0x17, + 0xd7, 0x0f, 0x22, 0x44, 0xcc, 0x00, 0xe4, 0x62, + 0x16, 0x67, 0x7a, 0xa0, 0xeb, 0x60, 0x31, 0x3d, + 0x60, 0x4b, 0x32, 0x03, 0x18, 0xac, 0x56, 0xf7, + 0xbb, 0xe8, 0x93, 0xf9, 0xc5, 0xb3, 0x9f, 0xf1, + 0x6b, 0xb7, 0xdc, 0x32, 0x88, 0xbd, 0x37, 0xed, + 0x80, 0x22, 0x6c, 0xb5, 0x7e, 0x34, 0x45, 0xb8, + 0x57, 0x25, 0x85, 0xe9, 0x75, 0xbf, 0xe5, 0x9f, + 0xf8, 0xcb, 0xfe, 0x0d, 0x94, 0xfe, 0x4f, 0x09, + 0x57, 0x69, 0x8e, 0x2a, 0x00, 0x00, 0x00, 0x00, + 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; diff --git a/samples/treectrl/state2_png.h b/samples/treectrl/state2_png.h new file mode 100644 index 0000000000..dc76a2b92f --- /dev/null +++ b/samples/treectrl/state2_png.h @@ -0,0 +1,55 @@ +/* state2.png - 417 bytes */ +static const unsigned char state2_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, + 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, + 0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, + 0x61, 0x00, 0x00, 0x01, 0x68, 0x49, 0x44, 0x41, + 0x54, 0x38, 0xcb, 0x9d, 0x91, 0xcb, 0x2b, 0x85, + 0x51, 0x14, 0xc5, 0x97, 0x89, 0xd7, 0xc0, 0xc0, + 0x63, 0x24, 0x13, 0x03, 0x0c, 0xc8, 0x63, 0xce, + 0x5f, 0xc0, 0x40, 0x11, 0x8a, 0x3f, 0x42, 0x21, + 0x19, 0xf9, 0x03, 0xa4, 0x6f, 0x9f, 0x18, 0x18, + 0x78, 0x26, 0x4a, 0x94, 0x4c, 0x64, 0x60, 0xe2, + 0x55, 0x86, 0x66, 0x92, 0x92, 0xae, 0x24, 0xba, + 0x2e, 0xfb, 0x1c, 0xd7, 0xed, 0x5e, 0xdf, 0xb7, + 0x0c, 0xbc, 0xaf, 0xcf, 0xbd, 0xd8, 0xb5, 0x26, + 0xe7, 0xec, 0xf5, 0x3b, 0x6b, 0x9f, 0x0d, 0x64, + 0xa8, 0x98, 0x41, 0xa3, 0x33, 0xa8, 0xc7, 0x7f, + 0xca, 0x1a, 0x74, 0xa8, 0x20, 0x50, 0x81, 0xaf, + 0x82, 0xf6, 0x3f, 0x99, 0x39, 0x8b, 0x7c, 0x2b, + 0x38, 0x57, 0x01, 0x5f, 0x15, 0xe1, 0x38, 0x0a, + 0x7e, 0x0d, 0x50, 0x0f, 0x23, 0x9f, 0xcc, 0x6f, + 0x1a, 0xfa, 0x6d, 0xf4, 0x32, 0x15, 0xdc, 0xd9, + 0x99, 0x0a, 0xc6, 0x37, 0x5a, 0x19, 0xdf, 0xec, + 0xa2, 0x9b, 0xab, 0xa4, 0x0a, 0x62, 0x3a, 0x86, + 0xd2, 0xac, 0x80, 0x7b, 0xc1, 0x64, 0x62, 0x77, + 0x80, 0x0c, 0x7c, 0xbe, 0x97, 0x9f, 0xe4, 0xe3, + 0x56, 0x2f, 0xad, 0x07, 0xc9, 0x16, 0xbd, 0x5a, + 0x05, 0x49, 0xb7, 0x50, 0xc3, 0xc4, 0xfe, 0x30, + 0xdd, 0x52, 0x03, 0x1f, 0x56, 0x5b, 0x18, 0x24, + 0x1d, 0xfd, 0x9b, 0x23, 0xaa, 0x20, 0xa9, 0x13, + 0xa8, 0xfa, 0x19, 0x20, 0x58, 0x4f, 0x9f, 0xdd, + 0xcd, 0x57, 0x91, 0x7e, 0x8a, 0x4f, 0x91, 0xed, + 0x97, 0x33, 0x0f, 0x6b, 0xe1, 0xb3, 0x7b, 0x68, + 0xf9, 0x66, 0x5e, 0x6a, 0x64, 0x10, 0xbf, 0x66, + 0xe0, 0x2e, 0xe9, 0x16, 0x6b, 0x3f, 0xee, 0x0c, + 0x9a, 0xbf, 0xae, 0x8d, 0xc8, 0x51, 0x83, 0x83, + 0x74, 0x80, 0x7f, 0x7f, 0x46, 0xff, 0xf6, 0x98, + 0x76, 0xba, 0x3c, 0x7d, 0x23, 0x87, 0x24, 0x72, + 0x3e, 0x3e, 0xce, 0xa0, 0x27, 0xdd, 0x6c, 0x27, + 0x0b, 0x99, 0x3a, 0x59, 0xe1, 0xe3, 0x56, 0x1f, + 0x43, 0x56, 0x4a, 0x2b, 0xe8, 0x7e, 0x79, 0x7d, + 0x14, 0xb9, 0x2a, 0x38, 0x0d, 0x6b, 0x72, 0x8b, + 0x75, 0xb4, 0x53, 0x25, 0xa1, 0x00, 0x15, 0x9c, + 0xd1, 0x20, 0x0f, 0x6a, 0x30, 0x18, 0xd6, 0xf0, + 0xb0, 0xdc, 0x44, 0x92, 0x7c, 0xba, 0x3a, 0xfc, + 0x09, 0x40, 0x15, 0x0c, 0x40, 0x05, 0x17, 0xa1, + 0x11, 0xa7, 0x8a, 0x99, 0x3a, 0x5d, 0x63, 0x62, + 0xa7, 0x3f, 0x13, 0x20, 0x02, 0xf5, 0xb0, 0x97, + 0xa1, 0x21, 0x9b, 0x76, 0x11, 0x35, 0x28, 0x52, + 0x83, 0x36, 0xeb, 0xa1, 0xf3, 0x2f, 0x52, 0x83, + 0xb6, 0xa8, 0x41, 0xd1, 0x33, 0x03, 0x89, 0xb1, + 0xaf, 0xc7, 0x76, 0x9e, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, + 0x82}; diff --git a/samples/treectrl/treetest.cpp b/samples/treectrl/treetest.cpp index 652b596312..85439caf2c 100644 --- a/samples/treectrl/treetest.cpp +++ b/samples/treectrl/treetest.cpp @@ -40,11 +40,15 @@ #include "icon4.xpm" #include "icon5.xpm" -#include "state1.xpm" -#include "state2.xpm" -#include "state3.xpm" -#include "state4.xpm" -#include "state5.xpm" +// Please note that these headers were generated from the original PNG icons +// made by Aleksandr Zyrianov and licensed under CC-BY-SA 4.0 and so are +// covered by this licence and not wxWindows licence itself. +#include "state0_png.h" +#include "state0_2x_png.h" +#include "state1_png.h" +#include "state1_2x_png.h" +#include "state2_png.h" +#include "state2_2x_png.h" #include "unchecked.xpm" #include "checked.xpm" @@ -192,8 +196,12 @@ bool MyApp::OnInit() if ( !wxApp::OnInit() ) return false; + // We use PNG images here, so we could just add PNG image handler but this + // is simpler. + wxInitAllImageHandlers(); + // Create the main frame window - MyFrame *frame = new MyFrame("wxTreeCtrl Test", 50, 50, 450, 600); + MyFrame *frame = new MyFrame(); // Show the frame frame->Show(true); @@ -203,8 +211,9 @@ bool MyApp::OnInit() // My frame constructor -MyFrame::MyFrame(const wxString& title, int x, int y, int w, int h) - : wxFrame(nullptr, wxID_ANY, title, wxPoint(x, y), wxSize(w, h)), +MyFrame::MyFrame() + : wxFrame(nullptr, wxID_ANY, "wxTreeCtrl test", + wxDefaultPosition, FromDIP(wxSize(450, 600), nullptr)), m_treeCtrl(nullptr) #if wxUSE_LOG , m_textCtrl(nullptr) @@ -703,12 +712,12 @@ void MyFrame::OnToggleStates(wxCommandEvent& WXUNUSED(event)) { if ( wxGetApp().ShowStates() ) { - m_treeCtrl->CreateStateImageList(true); + m_treeCtrl->SetStateImages({}); wxGetApp().SetShowStates(false); } else { - m_treeCtrl->CreateStateImageList(false); + m_treeCtrl->CreateStateImages(); wxGetApp().SetShowStates(true); } } @@ -731,7 +740,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 @@ -949,12 +958,48 @@ 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); } +namespace +{ + class FixedSizeImpl : public wxBitmapBundleImpl + { + public: + FixedSizeImpl(const wxSize& sizeDef, const wxIcon& icon) + : m_sizeDef(sizeDef), + m_icon(icon) + { + } + + wxSize GetDefaultSize() const override + { + return m_sizeDef; + } + + wxSize GetPreferredBitmapSizeAtScale(double scale) const override + { + return m_sizeDef*scale; + } + + wxBitmap GetBitmap(const wxSize& size) override + { + wxBitmap bmp(m_icon); + if ( size != bmp.GetSize() ) + wxBitmap::Rescale(bmp, size); + + return bmp; + } + + private: + const wxSize m_sizeDef; + const wxIcon m_icon; + }; +} // anonymous namespace + void MyTreeCtrl::CreateImages(int size) { if ( size == -1 ) @@ -994,39 +1039,6 @@ void MyTreeCtrl::CreateImages(int size) // 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 override - { - return m_sizeDef; - } - - wxSize GetPreferredBitmapSizeAtScale(double scale) const override - { - return m_sizeDef*scale; - } - - wxBitmap GetBitmap(const wxSize& size) override - { - 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]))); @@ -1035,52 +1047,38 @@ void MyTreeCtrl::CreateImages(int size) SetImages(images); } -void MyTreeCtrl::CreateStateImageList(bool del) +void MyTreeCtrl::CreateStateImages() { - if ( del ) - { - SetStateImageList(nullptr); - return; - } - - wxImageList *states; - wxBusyCursor wait; + std::vector images; 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 + // Macro similar to wxBITMAP_BUNDLE_2 but not using resources even + // under the platforms supporting them. + #define myBITMAP_BUNDLE_FROM_DATA_2(name) \ + wxBitmapBundle::FromBitmaps(wxBITMAP_PNG_FROM_DATA(name), \ + wxBITMAP_PNG_FROM_DATA(name##_2x)) - int width = icons[0].GetWidth(), - height = icons[0].GetHeight(); + images.push_back(myBITMAP_BUNDLE_FROM_DATA_2(state0)); + images.push_back(myBITMAP_BUNDLE_FROM_DATA_2(state1)); + images.push_back(myBITMAP_BUNDLE_FROM_DATA_2(state2)); - // 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]); + #undef myBITMAP_BUNDLE_FROM_DATA_2 } else { - wxIcon icons[2]; - icons[0] = wxIcon(unchecked_xpm); - icons[1] = wxIcon(checked_xpm); + std::vector icons; + icons.push_back(wxIcon(unchecked_xpm)); + icons.push_back(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]); + const wxSize iconSize(icons[0].GetWidth(), icons[0].GetHeight()); + for ( const wxIcon& icon : icons ) + { + images.push_back(wxBitmapBundle::FromImpl(new FixedSizeImpl(iconSize, icon))); + } } - AssignStateImageList(states); + SetStateImages(images); } void MyTreeCtrl::CreateButtonsImageList(int size) @@ -1290,7 +1288,7 @@ void MyTreeCtrl::DoToggleState(const wxTreeItemId& item) srand (time(nullptr)); do { - nState = rand() % GetStateImageList()->GetImageCount(); + nState = rand() % GetStateImageCount(); } while (nState == state); SetItemState(item, nState); diff --git a/samples/treectrl/treetest.h b/samples/treectrl/treetest.h index dc7d190b6a..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(bool del = false); + void CreateStateImages(); void AddTestItemsToTree(size_t numChildren, size_t depth); @@ -181,7 +181,7 @@ class MyFrame: public wxFrame { public: // ctor and dtor - MyFrame(const wxString& title, int x, int y, int w, int h); + MyFrame(); virtual ~MyFrame(); // menu callbacks diff --git a/src/common/bmpbase.cpp b/src/common/bmpbase.cpp index aa1608011b..ee9feda5d1 100644 --- a/src/common/bmpbase.cpp +++ b/src/common/bmpbase.cpp @@ -25,6 +25,11 @@ #include "wx/mstream.h" #endif +extern bool wxDumpBitmap(const wxBitmap& bitmap, const char* path) +{ + return bitmap.SaveFile(path, wxBITMAP_TYPE_BMP); +} + // ---------------------------------------------------------------------------- // wxVariant support // ---------------------------------------------------------------------------- diff --git a/src/common/bmpbndl.cpp b/src/common/bmpbndl.cpp index b108a67281..af1e419cc3 100644 --- a/src/common/bmpbndl.cpp +++ b/src/common/bmpbndl.cpp @@ -619,7 +619,7 @@ void RecordSizePref(SizePrefs& prefs, const wxSize& size) /* static */ wxSize -wxBitmapBundle::GetConsensusSizeFor(wxWindow* win, +wxBitmapBundle::GetConsensusSizeFor(const wxWindow* win, const wxVector& bundles) { return GetConsensusSizeFor(win->GetDPIScaleFactor(), bundles); @@ -669,17 +669,13 @@ wxBitmapBundle::GetConsensusSizeFor(double scale, /* static */ wxImageList* -wxBitmapBundle::CreateImageList(wxWindow* win, +wxBitmapBundle::CreateImageList(const wxWindow* win, const wxVector& bundles) { wxCHECK_MSG( win, nullptr, "must have a valid window" ); wxCHECK_MSG( !bundles.empty(), nullptr, "should have some images" ); - wxSize size = GetConsensusSizeFor(win, bundles); - - // wxImageList wants the logical size for the platforms where logical and - // physical pixels are different. - size /= win->GetContentScaleFactor(); + const wxSize size = GetConsensusSizeFor(win, bundles); wxImageList* const iml = new wxImageList(size.x, size.y); diff --git a/src/generic/imaglist.cpp b/src/generic/imaglist.cpp index 7b37e4a457..2a768cd12f 100644 --- a/src/generic/imaglist.cpp +++ b/src/generic/imaglist.cpp @@ -83,7 +83,7 @@ wxBitmap wxGenericImageList::GetImageListBitmap(const wxBitmap& bitmap) const // Ensure image size is the same as the size of the images on the image list. wxBitmap bmpResized; - const wxSize sz = bmp.GetLogicalSize(); + const wxSize sz = bmp.GetSize(); if ( sz.x == m_size.x && sz.y == m_size.y ) { bmpResized = bmp; @@ -125,14 +125,19 @@ int wxGenericImageList::Add( const wxBitmap &bitmap ) // Cannot add image to invalid list wxCHECK_MSG( m_size != wxSize(0, 0), -1, "Invalid image list" ); - // We use the logical size here as image list images size is specified in - // logical pixels, just as window coordinates and sizes are. - const wxSize bitmapSize = bitmap.GetLogicalSize(); + const wxSize bitmapSize = bitmap.GetSize(); // There is a special case: a bitmap may contain more than one image, // in which case we're supposed to chop it in parts, just as Windows // ImageList_Add() does. - if ( bitmapSize.x == m_size.x ) + // + // However we don't apply this special case to bitmaps with a scale factor + // different from 1: their actual physical size could be the same as ours + // for all we know (we don't have a scale factor here and wxImageList API + // prevents it from having one), so leave them alone. This is clearly a + // hack but OTOH nobody uses multi-image bitmaps with a scale factor and it + // avoids problems when using scaled bitmaps in the image list, see #23994. + if ( bitmapSize.x == m_size.x || bitmap.GetScaleFactor() != 1.0 ) { m_images.push_back(GetImageListBitmap(bitmap)); } diff --git a/src/generic/logg.cpp b/src/generic/logg.cpp index db68977aa1..fd526a2444 100644 --- a/src/generic/logg.cpp +++ b/src/generic/logg.cpp @@ -800,8 +800,10 @@ void wxLogDialog::CreateDetailsControls(wxWindow *parent) m_listctrl->InsertColumn(1, wxT("Time")); // prepare the imagelist - static const int ICON_SIZE = 16; - wxImageList *imageList = new wxImageList(ICON_SIZE, ICON_SIZE); + wxSize iconSize(16, 16); + iconSize *= parent->GetDPIScaleFactor(); + + wxImageList *imageList = new wxImageList(iconSize.x, iconSize.y); // order should be the same as in the switch below! static wxString const icons[] = @@ -816,7 +818,7 @@ void wxLogDialog::CreateDetailsControls(wxWindow *parent) for ( size_t icon = 0; icon < WXSIZEOF(icons); icon++ ) { wxBitmap bmp = wxArtProvider::GetBitmap(icons[icon], wxART_MESSAGE_BOX, - wxSize(ICON_SIZE, ICON_SIZE)); + iconSize); // This may very well fail if there are insufficient colours available. // Degrade gracefully. diff --git a/src/generic/treectlg.cpp b/src/generic/treectlg.cpp index e3dcd34ea0..50df9598e2 100644 --- a/src/generic/treectlg.cpp +++ b/src/generic/treectlg.cpp @@ -744,9 +744,7 @@ wxGenericTreeItem *wxGenericTreeItem::HitTest(const wxPoint& point, // assuming every image (normal and selected) has the same size! if ( (GetImage() != NO_IMAGE) && theCtrl->HasImages() ) { - int image_h; - theCtrl->GetImageLogicalSize(theCtrl, GetImage(), - image_w, image_h); + image_w = theCtrl->GetImageLogicalSize(theCtrl).x; } int state_w = -1; @@ -755,7 +753,7 @@ wxGenericTreeItem *wxGenericTreeItem::HitTest(const wxPoint& point, theCtrl->m_imagesState.HasImages() ) { int state_h; - theCtrl->GetStateImageList()->GetSize(GetState(), + theCtrl->m_imagesState.GetImageLogicalSize(theCtrl, GetState(), state_w, state_h); } @@ -879,18 +877,18 @@ wxGenericTreeItem::DoCalculateSize(wxGenericTreeCtrl* control, int text_h = m_heightText + 2; int image_h = 0, image_w = 0; - int image = GetCurrentImage(); - if ( image != NO_IMAGE && control->HasImages() ) + if ( GetCurrentImage() != NO_IMAGE && control->HasImages() ) { - control->GetImageLogicalSize(control, image, image_w, image_h); - image_w += MARGIN_BETWEEN_IMAGE_AND_TEXT; + const wxSize imageSize = control->GetImageLogicalSize(control); + image_h = imageSize.y; + image_w = imageSize.x + MARGIN_BETWEEN_IMAGE_AND_TEXT; } int state_h = 0, state_w = 0; int state = GetState(); if ( state != wxTREE_ITEMSTATE_NONE && control->m_imagesState.HasImages() ) { - control->GetStateImageList()->GetSize(state, state_w, state_h); + control->m_imagesState.GetImageLogicalSize(control, state, state_w, state_h); if ( image_w != 0 ) state_w += MARGIN_BETWEEN_STATE_AND_IMAGE; else @@ -2410,15 +2408,7 @@ void wxGenericTreeCtrl::CalculateLineHeight() if ( HasImages() ) { // Calculate a m_lineHeight value from the normal Image sizes. - // May be toggle off. Then wxGenericTreeCtrl will spread when - // necessary (which might look ugly). - int n = GetImageCount(); - for (int i = 0; i < n ; i++) - { - int width = 0, height = 0; - GetImageLogicalSize(this, i, width, height); - if (height > m_lineHeight) m_lineHeight = height; - } + m_lineHeight = GetImageLogicalSize(this).y; } if ( m_imagesState.HasImages() ) @@ -2457,13 +2447,13 @@ void wxGenericTreeCtrl::CalculateLineHeight() void wxGenericTreeCtrl::OnImagesChanged() { - if ( HasImages() ) - { - // We call it solely for the side effect of updating the image list. - GetUpdatedImageListFor(this); + // We call it solely for the side effect of updating the image list, + // which may be used by the application code using this class, even if + // we don't use it ourselves, but it also has an important side effect + // of ensuring that we can always get the size to use for the images. + GetUpdatedImageListFor(this); - UpdateAfterImageListChange(); - } + UpdateAfterImageListChange(); } void wxGenericTreeCtrl::UpdateAfterImageListChange() @@ -2484,6 +2474,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); @@ -2547,8 +2547,9 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc) { if ( HasImages() ) { - GetImageLogicalSize(this, image, image_w, image_h); - image_w += MARGIN_BETWEEN_IMAGE_AND_TEXT; + const wxSize imageSize = GetImageLogicalSize(this); + image_h = imageSize.y; + image_w = imageSize.x + MARGIN_BETWEEN_IMAGE_AND_TEXT; } else { @@ -2562,7 +2563,7 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc) { if ( m_imagesState.HasImages() ) { - GetStateImageList()->GetSize(state, state_w, state_h); + m_imagesState.GetImageLogicalSize(this, state, state_w, state_h); if ( image_w != 0 ) state_w += MARGIN_BETWEEN_STATE_AND_IMAGE; else @@ -3462,12 +3463,9 @@ bool wxGenericTreeCtrl::GetBoundingRect(const wxTreeItemId& item, if ( textOnly ) { int image_w = 0; - int image = ((wxGenericTreeItem*) item.m_pItem)->GetCurrentImage(); - if ( image != NO_IMAGE && HasImages() ) + if ( i->GetCurrentImage() != NO_IMAGE && HasImages() ) { - int image_h; - GetImageLogicalSize( this, image, image_w, image_h ); - image_w += MARGIN_BETWEEN_IMAGE_AND_TEXT; + image_w = GetImageLogicalSize(this).x + MARGIN_BETWEEN_IMAGE_AND_TEXT; } int state_w = 0; @@ -3475,7 +3473,7 @@ bool wxGenericTreeCtrl::GetBoundingRect(const wxTreeItemId& item, if ( state != wxTREE_ITEMSTATE_NONE && m_imagesState.HasImages() ) { int state_h; - GetStateImageList()->GetSize( state, state_w, state_h ); + m_imagesState.GetImageLogicalSize( this, state, state_w, state_h ); if ( image_w != 0 ) state_w += MARGIN_BETWEEN_STATE_AND_IMAGE; else diff --git a/src/html/helpwnd.cpp b/src/html/helpwnd.cpp index de859d6a11..07bb8bc493 100644 --- a/src/html/helpwnd.cpp +++ b/src/html/helpwnd.cpp @@ -447,16 +447,19 @@ bool wxHtmlHelpWindow::Create(wxWindow* parent, wxWindowID id, #endif ); - wxImageList *ContentsImageList = new wxImageList(16, 16); + wxSize iconSize(16, 16); + iconSize *= GetDPIScaleFactor(); + + wxImageList *ContentsImageList = new wxImageList(iconSize.x, iconSize.y); ContentsImageList->Add(wxArtProvider::GetIcon(wxART_HELP_BOOK, wxART_HELP_BROWSER, - wxSize(16, 16))); + iconSize)); ContentsImageList->Add(wxArtProvider::GetIcon(wxART_HELP_FOLDER, wxART_HELP_BROWSER, - wxSize(16, 16))); + iconSize)); ContentsImageList->Add(wxArtProvider::GetIcon(wxART_HELP_PAGE, wxART_HELP_BROWSER, - wxSize(16, 16))); + iconSize)); m_ContentsBox->AssignImageList(ContentsImageList); 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); diff --git a/tests/graphics/bmpbundle.cpp b/tests/graphics/bmpbundle.cpp index bc890fb9e2..92163013c9 100644 --- a/tests/graphics/bmpbundle.cpp +++ b/tests/graphics/bmpbundle.cpp @@ -16,6 +16,7 @@ #include "wx/artprov.h" #include "wx/dcmemory.h" +#include "wx/imaglist.h" #include "asserthelper.h" @@ -470,6 +471,37 @@ TEST_CASE("BitmapBundle::Scale", "[bmpbundle][scale]") CHECK( b.GetDefaultSize() == wxSize(8, 8) ); } +TEST_CASE("BitmapBundle::ImageList", "[bmpbundle][imagelist]") +{ + wxVector images; + images.push_back(wxBitmapBundle::FromBitmaps(wxBitmap(16, 16), wxBitmap(32, 32))); + images.push_back(wxBitmapBundle::FromBitmap(wxBitmap(24, 24))); + images.push_back(wxBitmapBundle::FromBitmaps(wxBitmap(16, 16), wxBitmap(32, 32))); + + // There are 2 bundles with preferred size of 32x32, so they should win. + const wxSize size = wxBitmapBundle::GetConsensusSizeFor(2.0, images); + CHECK( size == wxSize(32, 32) ); + + wxImageList iml(size.x, size.y); + for ( const auto& bundle : images ) + { + wxBitmap bmp = bundle.GetBitmap(size); + REQUIRE( bmp.IsOk() ); + CHECK( bmp.GetSize() == size ); + REQUIRE( iml.Add(bmp) != -1 ); + } + + CHECK( iml.GetBitmap(0).GetSize() == size ); +#ifdef wxHAS_DPI_INDEPENDENT_PIXELS + CHECK( iml.GetBitmap(0).GetScaleFactor() == 2 ); +#endif + + CHECK( iml.GetBitmap(1).GetSize() == size ); +#ifdef wxHAS_DPI_INDEPENDENT_PIXELS + CHECK( iml.GetBitmap(1).GetScaleFactor() == Approx(1.3333333333) ); +#endif +} + #endif // ports with scaled bitmaps support TEST_CASE("BitmapBundle::GetConsensusSize", "[bmpbundle]")