From 527343602e91d60c65fb7589a6ddcf4683930c78 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 7 Apr 2007 19:59:51 +0000 Subject: [PATCH] 1. changed wxIconBundle to use m_refData and COW to make copying icon bundles fast (which was needed for 2) 2. make it possible to return wxIconBundles from wxArtProvider 3. implement Mac-specific wxArtProvider doing (2) (modified patch 1581960) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45309 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- Makefile.in | 16 +++ build/bakefiles/files.bkl | 1 + build/msw/makefile.vc | 4 +- docs/changes.txt | 1 + docs/latex/wx/artprov.tex | 65 ++++++++-- docs/latex/wx/iconbndl.tex | 28 ++++- include/wx/artprov.h | 21 +++- include/wx/gdicmn.h | 4 +- include/wx/iconbndl.h | 61 ++++++--- include/wx/mac/carbon/icon.h | 3 + include/wx/toplevel.h | 2 +- samples/treectrl/treetest.cpp | 64 ++++++++-- samples/treectrl/treetest.h | 8 +- src/common/artprov.cpp | 82 ++++++++++-- src/common/artstd.cpp | 2 +- src/common/gdicmn.cpp | 2 + src/common/iconbndl.cpp | 231 ++++++++++++++++++++++++---------- src/gtk/toplevel.cpp | 18 +-- src/mac/carbon/artmac.cpp | 108 ++++++++++++++++ src/mac/carbon/icon.cpp | 24 ++++ src/unix/utilsx11.cpp | 30 ++--- 21 files changed, 622 insertions(+), 153 deletions(-) create mode 100644 src/mac/carbon/artmac.cpp diff --git a/Makefile.in b/Makefile.in index 32565adb82..0906a7f627 100644 --- a/Makefile.in +++ b/Makefile.in @@ -4391,6 +4391,7 @@ COND_TOOLKIT_MAC___GUI_SRC_OBJECTS = \ monodll_accel.o \ monodll_aga.o \ monodll_app.o \ + monodll_artmac.o \ monodll_bitmap.o \ monodll_bmpbuttn.o \ monodll_brush.o \ @@ -6193,6 +6194,7 @@ COND_TOOLKIT_MAC___GUI_SRC_OBJECTS_1 = \ monolib_accel.o \ monolib_aga.o \ monolib_app.o \ + monolib_artmac.o \ monolib_bitmap.o \ monolib_bmpbuttn.o \ monolib_brush.o \ @@ -8224,6 +8226,7 @@ COND_TOOLKIT_MAC___GUI_SRC_OBJECTS_2 = \ coredll_accel.o \ coredll_aga.o \ coredll_app.o \ + coredll_artmac.o \ coredll_bitmap.o \ coredll_bmpbuttn.o \ coredll_brush.o \ @@ -9693,6 +9696,7 @@ COND_TOOLKIT_MAC___GUI_SRC_OBJECTS_3 = \ corelib_accel.o \ corelib_aga.o \ corelib_app.o \ + corelib_artmac.o \ corelib_bitmap.o \ corelib_bmpbuttn.o \ corelib_brush.o \ @@ -13558,6 +13562,9 @@ monodll_textctrlce.o: $(srcdir)/src/msw/wince/textctrlce.cpp $(MONODLL_ODEP) monodll_aga.o: $(srcdir)/src/mac/carbon/aga.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/mac/carbon/aga.cpp +monodll_artmac.o: $(srcdir)/src/mac/carbon/artmac.cpp $(MONODLL_ODEP) + $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/mac/carbon/artmac.cpp + monodll_dccg.o: $(srcdir)/src/mac/carbon/dccg.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/mac/carbon/dccg.cpp @@ -17731,6 +17738,9 @@ monolib_textctrlce.o: $(srcdir)/src/msw/wince/textctrlce.cpp $(MONOLIB_ODEP) monolib_aga.o: $(srcdir)/src/mac/carbon/aga.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/mac/carbon/aga.cpp +monolib_artmac.o: $(srcdir)/src/mac/carbon/artmac.cpp $(MONOLIB_ODEP) + $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/mac/carbon/artmac.cpp + monolib_dccg.o: $(srcdir)/src/mac/carbon/dccg.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/mac/carbon/dccg.cpp @@ -22915,6 +22925,9 @@ coredll_textctrlce.o: $(srcdir)/src/msw/wince/textctrlce.cpp $(COREDLL_ODEP) coredll_aga.o: $(srcdir)/src/mac/carbon/aga.cpp $(COREDLL_ODEP) $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/mac/carbon/aga.cpp +coredll_artmac.o: $(srcdir)/src/mac/carbon/artmac.cpp $(COREDLL_ODEP) + $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/mac/carbon/artmac.cpp + coredll_dccg.o: $(srcdir)/src/mac/carbon/dccg.cpp $(COREDLL_ODEP) $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/mac/carbon/dccg.cpp @@ -25891,6 +25904,9 @@ corelib_textctrlce.o: $(srcdir)/src/msw/wince/textctrlce.cpp $(CORELIB_ODEP) corelib_aga.o: $(srcdir)/src/mac/carbon/aga.cpp $(CORELIB_ODEP) $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/mac/carbon/aga.cpp +corelib_artmac.o: $(srcdir)/src/mac/carbon/artmac.cpp $(CORELIB_ODEP) + $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/mac/carbon/artmac.cpp + corelib_dccg.o: $(srcdir)/src/mac/carbon/dccg.cpp $(CORELIB_ODEP) $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/mac/carbon/dccg.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index f7aa9e9646..3d2921ab1f 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -2100,6 +2100,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/mac/carbon/accel.cpp src/mac/carbon/aga.cpp src/mac/carbon/app.cpp + src/mac/carbon/artmac.cpp src/mac/carbon/bitmap.cpp src/mac/carbon/bmpbuttn.cpp src/mac/carbon/brush.cpp diff --git a/build/msw/makefile.vc b/build/msw/makefile.vc index 133a5a2c71..147b32cd55 100644 --- a/build/msw/makefile.vc +++ b/build/msw/makefile.vc @@ -4486,7 +4486,7 @@ clean: -if exist $(LIBDIRNAME)\wx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl.lib del $(LIBDIRNAME)\wx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl.lib cd ..\..\samples $(MAKE) -f makefile.vc $(MAKEARGS) clean - cd $(MAKEDIR) + cd "$(MAKEDIR)" setup_h: $(SETUPHDIR)\wx ..\..\include\wx\$(__SETUP_H_SUBDIR_FILENAMES)\setup.h $(SETUPHDIR)\wx\setup.h $(SETUPHDIR)\wx\msw\rcdefs.h @@ -4833,7 +4833,7 @@ $(LIBDIRNAME)\wx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)$(WXUNICODEFLAG)$(WXD sub_samples: cd ..\..\samples $(MAKE) -f makefile.vc $(MAKEARGS) all - cd $(MAKEDIR) + cd "$(MAKEDIR)" $(LIBDIRNAME): if not exist $(LIBDIRNAME) mkdir $(LIBDIRNAME) diff --git a/docs/changes.txt b/docs/changes.txt index d9141a11c5..b9068df632 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -115,6 +115,7 @@ wxGTK: wxMac: +- Better IconRef support (Alan Shouls) - Fix duplicate (empty) help menu in non-English programs (Andreas Jacobs) - Allow accelerators to be used with buttons too (Ryan Wilcox) - Support resource forks in wxCopyFile() (Hank Schultz) diff --git a/docs/latex/wx/artprov.tex b/docs/latex/wx/artprov.tex index 179111d9e6..264f579b7e 100644 --- a/docs/latex/wx/artprov.tex +++ b/docs/latex/wx/artprov.tex @@ -10,9 +10,10 @@ When wxWidgets needs to display an icon or a bitmap (e.g. in the standard file dialog), it does not use a hard-coded resource but asks wxArtProvider for it instead. This way users can plug in their own wxArtProvider class and easily replace standard art with their own version. All -that is needed is to derive a class from wxArtProvider, override its -\helpref{CreateBitmap}{wxartprovidercreatebitmap} method and register the -provider with +that is needed is to derive a class from wxArtProvider, override either its +\helpref{CreateBitmap}{wxartprovidercreatebitmap} and/or its +\helpref{CreateIconBundle}{wxartprovidercreateiconbundle} methods +and register the provider with \helpref{wxArtProvider::Push}{wxartproviderpush}: \begin{verbatim} @@ -22,12 +23,20 @@ provider with wxBitmap CreateBitmap(const wxArtID& id, const wxArtClient& client, const wxSize size) + + // optionally override this one as well + wxIconBundle CreateIconBundle(const wxArtID& id, + const wxArtClient& client) { ... } }; ... wxArtProvider::Push(new MyProvider); \end{verbatim} +If you need bitmap images (of the same artwork) that should be displayed at different sizes +you should probably consider overriding \helpref{CreateIconBundle()}{wxartprovidercreateiconbundle} +and supplying icon bundles that contain different bitmap sizes. + There's another way of taking advantage of this class: you can use it in your code and use platform native icons as provided by \helpref{wxArtProvider::GetBitmap}{wxartprovidergetbitmap} or \helpref{wxArtProvider::GetIcon}{wxartprovidergeticon} (NB: this is not yet really @@ -37,7 +46,7 @@ small). \membersection{Identifying art resources}\label{artprovideridentifying} -Every bitmap is known to wxArtProvider under an unique ID that is used by when +Every bitmap and icon bundle are known to wxArtProvider under an unique ID that is used when requesting a resource from it. The ID is represented by wxArtID type and can have one of these predefined values (you can see bitmaps represented by these constants in the \helpref{artprov}{sampleartprovider} sample): @@ -159,10 +168,10 @@ by \helpref{GetBitmap}{wxartprovidergetbitmap}. \func{wxBitmap}{CreateBitmap}{\param{const wxArtID\& }{id}, \param{const wxArtClient\& }{client}, \param{const wxSize\& }{size}} -Derived art provider classes must override this method to create requested -art resource. Note that returned bitmaps are cached by wxArtProvider and it is therefore -not necessary to optimize CreateBitmap for speed (e.g. you may create wxBitmap objects -from XPMs here). +Derived art provider classes must override this method or the CreateIconBundle() method +to create requested art resource. Note that returned bitmaps are cached by wxArtProvider +and it is therefore not necessary to optimize CreateBitmap() for speed (e.g. you may create +wxBitmap objects from XPMs here). \wxheading{Parameters} @@ -178,10 +187,33 @@ dimensions, it will be automatically rescaled to meet client's request.} This is {\bf not} part of wxArtProvider's public API, use \helpref{wxArtProvider::GetBitmap}{wxartprovidergetbitmap} or +\helpref{wxArtProvider::GetIconBundle}{wxartprovidergeticonbundle} or \helpref{wxArtProvider::GetIcon}{wxartprovidergeticon} to query wxArtProvider for a resource. +\func{wxIconBundle}{CreateIconBundle}{\param{const wxArtID\& }{id}, \param{const wxArtClient\& }{client}} + +Derived art provider classes must override this method or the CreateIconBundle method +to create requested art resource. Note that returned icon bundles are cached by wxArtProvider +and it is therefore not necessary to optimize CreateIconBundle for speed (e.g. you may create icon bundles +from artwork resources here). + +\wxheading{Parameters} + +\docparam{id}{wxArtID unique identifier of the icon bundle.} + +\docparam{client}{wxArtClient identifier of the client (i.e. who is asking for the icon bundle). +This only servers as a hint.} + +\wxheading{Note} + +This is {\bf not} part of wxArtProvider's public API, use +\helpref{wxArtProvider::GetBitmap}{wxartprovidergetbitmap} or +\helpref{wxArtProvider::GetIconBundle}{wxartprovidergeticonbundle} or +\helpref{wxArtProvider::GetIcon}{wxartprovidergeticon} +to query wxArtProvider for a resource. + \membersection{wxArtProvider::Delete}\label{wxartproviderdelete} \func{static bool}{Delete}{\param{wxArtProvider* }{provider}} @@ -208,6 +240,23 @@ Query registered providers for bitmap with given ID. The bitmap if one of registered providers recognizes the ID or wxNullBitmap otherwise. +\membersection{wxArtProvider::GetIconBundle}\label{wxartprovidergeticonbundle} + +\func{static wxIconBundle}{GetIconBundle}{\param{const wxArtID\& }{id}, \param{const wxArtClient\& }{client = wxART\_OTHER}} + +Query registered providers for icon bundle with given ID. + +\wxheading{Parameters} + +\docparam{id}{wxArtID unique identifier of the icon bundle.} + +\docparam{client}{wxArtClient identifier of the client (i.e. who is asking for the icon bundle).} + +\wxheading{Return value} + +The icon bundle if one of registered providers recognizes the ID or wxNullIconBundle otherwise. + + \membersection{wxArtProvider::GetIcon}\label{wxartprovidergeticon} \func{static wxIcon}{GetIcon}{\param{const wxArtID\& }{id}, \param{const wxArtClient\& }{client = wxART\_OTHER}, \param{const wxSize\& }{size = wxDefaultSize}} diff --git a/docs/latex/wx/iconbndl.tex b/docs/latex/wx/iconbndl.tex index d1a68478c3..e76082bb04 100644 --- a/docs/latex/wx/iconbndl.tex +++ b/docs/latex/wx/iconbndl.tex @@ -6,7 +6,12 @@ see also \helpref{wxDialog::SetIcons}{wxdialogseticons} and \wxheading{Derived from} -No base class +\helpref{wxGDIObject}{wxgdiobject}\\ +\helpref{wxObject}{wxobject} + +\wxheading{Predefined objects} + +{\bf wxNullIconBundle} \latexignore{\rtfignore{\wxheading{Members}}} @@ -50,7 +55,7 @@ replaced by the new one. \membersection{wxIconBundle::GetIcon}\label{wxiconbundlegeticon} -\constfunc{const wxIcon\&}{GetIcon}{\param{const wxSize\& }{size}} +\constfunc{wxIcon}{GetIcon}{\param{const wxSize\& }{size}} Returns the icon with the given size; if no such icon exists, returns the icon with size wxSYS\_ICON\_X/wxSYS\_ICON\_Y; @@ -58,13 +63,24 @@ if no such icon exists, returns the first icon in the bundle. If size = wxSize( -1, -1 ), returns the icon with size wxSYS\_ICON\_X/wxSYS\_ICON\_Y. -\constfunc{const wxIcon\&}{GetIcon}{\param{wxCoord }{size = -1}} +\constfunc{wxIcon}{GetIcon}{\param{wxCoord }{size = -1}} Same as GetIcon( wxSize( size, size ) ). -\membersection{wxIconBundle::operator=}\label{wxiconbundleoperatorassign} +\membersection{wxIconBundle::operator $=$}\label{wxiconbundleoperatorassign} + +\func{wxIconBundle\&}{operator $=$}{\param{const wxIconBundle\& }{ic}} + +Assignment operator, using \helpref{reference counting}{trefcount}. + +\membersection{wxIconBundle::operator $==$}\label{wxiconbundleoperatorequals} + +\func{bool}{operator $==$}{\param{const wxIconBundle\& }{ic}} + +Equality operator. This returns \true if two icon bundles are equal. -\func{const wxIconBundle\&}{operator=}{\param{const wxIconBundle\& }{ic}} +\membersection{wxIconBundle::operator $!=$}\label{wxiconbundleoperatornotequals} -Assignment operator. +\func{bool}{operator $!=$}{\param{const wxIconBundle\& }{ic}} +Inequality operator. This returns \true if two icon bundles are not equal. diff --git a/include/wx/artprov.h b/include/wx/artprov.h index 184a21791f..e98bd41182 100644 --- a/include/wx/artprov.h +++ b/include/wx/artprov.h @@ -15,6 +15,7 @@ #include "wx/string.h" #include "wx/bitmap.h" #include "wx/icon.h" +#include "wx/iconbndl.h" class WXDLLEXPORT wxArtProvidersList; class WXDLLEXPORT wxArtProviderCache; @@ -44,6 +45,7 @@ typedef wxString wxArtID; #define wxART_HELP_BROWSER wxART_MAKE_CLIENT_ID(wxART_HELP_BROWSER) #define wxART_MESSAGE_BOX wxART_MAKE_CLIENT_ID(wxART_MESSAGE_BOX) #define wxART_BUTTON wxART_MAKE_CLIENT_ID(wxART_BUTTON) +#define wxART_LIST wxART_MAKE_CLIENT_ID(wxART_LIST) #define wxART_OTHER wxART_MAKE_CLIENT_ID(wxART_OTHER) @@ -146,6 +148,11 @@ public: const wxArtClient& client = wxART_OTHER, const wxSize& size = wxDefaultSize); + // Query the providers for iconbundle with given ID and return it. Return + // wxNullIconBundle if no provider provides it. + static wxIconBundle GetIconBundle(const wxArtID& id, + const wxArtClient& client = wxART_OTHER); + // Get the size hint of an icon from a specific wxArtClient, queries // the topmost provider if platform_dependent = false static wxSize GetSizeHint(const wxArtClient& client, bool platform_dependent = false); @@ -177,12 +184,18 @@ protected: return GetSizeHint(client, true); } - // Derived classes must override this method to create requested - // art resource. This method is called only once per instance's - // lifetime for each requested wxArtID. + // Derived classes must override CreateBitmap or CreateIconBundle + // (or both) to create requested art resource. This method is called + // only once per instance's lifetime for each requested wxArtID. virtual wxBitmap CreateBitmap(const wxArtID& WXUNUSED(id), const wxArtClient& WXUNUSED(client), - const wxSize& WXUNUSED(size)) = 0; + const wxSize& WXUNUSED(size)) { return wxNullBitmap; } + + virtual wxIconBundle CreateIconBundle(const wxArtID& WXUNUSED(id), + const wxArtClient& WXUNUSED(client)) + { + return wxNullIconBundle; + } private: static void CommonAddingProvider(); diff --git a/include/wx/gdicmn.h b/include/wx/gdicmn.h index 18dce6cbfb..acd374d4c3 100644 --- a/include/wx/gdicmn.h +++ b/include/wx/gdicmn.h @@ -37,6 +37,7 @@ class WXDLLIMPEXP_CORE wxPalette; class WXDLLIMPEXP_CORE wxPen; class WXDLLIMPEXP_CORE wxRegion; class WXDLLIMPEXP_BASE wxString; +class WXDLLIMPEXP_CORE wxIconBundle; // --------------------------------------------------------------------------- // constants @@ -712,9 +713,10 @@ extern WXDLLEXPORT_DATA(wxIcon) wxNullIcon; extern WXDLLEXPORT_DATA(wxCursor) wxNullCursor; extern WXDLLEXPORT_DATA(wxPen) wxNullPen; extern WXDLLEXPORT_DATA(wxBrush) wxNullBrush; -extern WXDLLEXPORT_DATA(wxPalette) wxNullPalette; +extern WXDLLEXPORT_DATA(wxPalette) wxNullPalette; extern WXDLLEXPORT_DATA(wxFont) wxNullFont; extern WXDLLEXPORT_DATA(wxColour) wxNullColour; +extern WXDLLEXPORT_DATA(wxIconBundle) wxNullIconBundle; extern WXDLLEXPORT_DATA(wxColourDatabase*) wxTheColourDatabase; diff --git a/include/wx/iconbndl.h b/include/wx/iconbndl.h index 3749467240..8a76d39eb5 100644 --- a/include/wx/iconbndl.h +++ b/include/wx/iconbndl.h @@ -13,57 +13,80 @@ #define _WX_ICONBNDL_H_ #include "wx/dynarray.h" +#include "wx/gdiobj.h" // for wxSize #include "wx/gdicmn.h" +#include "wx/icon.h" class WXDLLIMPEXP_CORE wxIcon; class WXDLLIMPEXP_BASE wxString; -WX_DECLARE_EXPORTED_OBJARRAY( wxIcon, wxIconArray ); +class WXDLLEXPORT wxIconBundle; + +WX_DECLARE_EXPORTED_OBJARRAY(wxIcon, wxIconArray); // this class can't load bitmaps of type wxBITMAP_TYPE_ICO_RESOURCE, // if you need them, you have to load them manually and call // wxIconCollection::AddIcon -class WXDLLEXPORT wxIconBundle +class WXDLLEXPORT wxIconBundle : public wxGDIObject { public: // default constructor - wxIconBundle() : m_icons() {} + wxIconBundle(); + // initializes the bundle with the icon(s) found in the file - wxIconBundle( const wxString& file, long type ) : m_icons() - { AddIcon( file, type ); } + wxIconBundle(const wxString& file, long type); + // initializes the bundle with a single icon - wxIconBundle( const wxIcon& icon ) : m_icons() - { AddIcon( icon ); } + wxIconBundle(const wxIcon& icon); + + // initializes the bundle from another icon bundle + wxIconBundle(const wxIconBundle& icon); - const wxIconBundle& operator =( const wxIconBundle& ic ); - wxIconBundle( const wxIconBundle& ic ) : m_icons() - { *this = ic; } + wxIconBundle& operator=(const wxIconBundle& ic) + { if ( this != &ic) Ref(ic); return *this; } + + virtual bool IsOk() const; - ~wxIconBundle() { DeleteIcons(); } // adds all the icons contained in the file to the collection, // if the collection already contains icons with the same // width and height, they are replaced - void AddIcon( const wxString& file, long type ); + void AddIcon(const wxString& file, long type); + // adds the icon to the collection, if the collection already // contains an icon with the same width and height, it is // replaced - void AddIcon( const wxIcon& icon ); + void AddIcon(const wxIcon& icon); // returns the icon with the given size; if no such icon exists, // returns the icon with size wxSYS_ICON_[XY]; if no such icon exists, // returns the first icon in the bundle - const wxIcon& GetIcon( const wxSize& size ) const; + wxIcon GetIcon(const wxSize& size) const; + // equivalent to GetIcon( wxSize( size, size ) ) - const wxIcon& GetIcon( wxCoord size = wxDefaultCoord ) const + wxIcon GetIcon(wxCoord size = wxDefaultCoord) const { return GetIcon( wxSize( size, size ) ); } + + + // enumerate all icons in the bundle: don't use these functions if ti can + // be avoided, using GetIcon() directly is better + + // return the number of available icons + size_t GetIconCount() const; + + // return the icon at index (must be < GetIconCount()) + wxIcon GetIconByIndex(size_t n) const; + +protected: + virtual wxObjectRefData *CreateRefData() const; + virtual wxObjectRefData *CloneRefData(const wxObjectRefData *data) const; + private: // delete all icons void DeleteIcons(); -public: - wxIconArray m_icons; + + DECLARE_DYNAMIC_CLASS(wxIconBundle) }; -#endif - // _WX_ICONBNDL_H_ +#endif // _WX_ICONBNDL_H_ diff --git a/include/wx/mac/carbon/icon.h b/include/wx/mac/carbon/icon.h index 2e9e0d0af9..5e786bca58 100644 --- a/include/wx/mac/carbon/icon.h +++ b/include/wx/mac/carbon/icon.h @@ -29,6 +29,9 @@ public: { LoadFile(loc.GetFileName(), wxBITMAP_TYPE_ICON); } + + wxIcon(WXHICON icon, const wxSize& size); + virtual ~wxIcon(); bool LoadFile(const wxString& name, wxBitmapType flags /* = wxBITMAP_TYPE_ICON_RESOURCE */ , diff --git a/include/wx/toplevel.h b/include/wx/toplevel.h index a4530bd2b8..3814678337 100644 --- a/include/wx/toplevel.h +++ b/include/wx/toplevel.h @@ -145,7 +145,7 @@ public: virtual bool IsIconized() const = 0; // get the frame icon - const wxIcon& GetIcon() const { return m_icons.GetIcon( -1 ); } + wxIcon GetIcon() const { return m_icons.GetIcon( -1 ); } // get the frame icons const wxIconBundle& GetIcons() const { return m_icons; } diff --git a/samples/treectrl/treetest.cpp b/samples/treectrl/treetest.cpp index 1eab7f8e13..73a7bb62f9 100644 --- a/samples/treectrl/treetest.cpp +++ b/samples/treectrl/treetest.cpp @@ -24,6 +24,7 @@ #include "wx/colordlg.h" #include "wx/numdlg.h" +#include "wx/artprov.h" #include "wx/image.h" #include "wx/imaglist.h" #include "wx/treectrl.h" @@ -96,6 +97,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) MENU_LINK(DeleteAll) MENU_LINK(Recreate) MENU_LINK(ToggleImages) + MENU_LINK(ToggleAlternateImages) MENU_LINK(ToggleButtons) MENU_LINK(SetImageSize) MENU_LINK(CollapseAndReset) @@ -209,6 +211,7 @@ MyFrame::MyFrame(const wxString& title, int x, int y, int w, int h) style_menu->AppendCheckItem(TreeTest_ToggleSel, wxT("Toggle &selection mode")); #endif // NO_MULTIPLE_SELECTION style_menu->AppendCheckItem(TreeTest_ToggleImages, wxT("Toggle show ima&ges")); + style_menu->AppendCheckItem(TreeTest_ToggleAlternateImages, wxT("Toggle alternate images")); style_menu->Append(TreeTest_SetImageSize, wxT("Set image si&ze...")); style_menu->AppendSeparator(); style_menu->Append(TreeTest_SetFgColour, wxT("Set &foreground colour...")); @@ -276,6 +279,7 @@ MyFrame::MyFrame(const wxString& title, int x, int y, int w, int h) CreateTreeWithDefStyle(); menu_bar->Check(TreeTest_ToggleImages, true); + menu_bar->Check(TreeTest_ToggleAlternateImages, false); #if wxUSE_STATUSBAR // create a status bar @@ -601,6 +605,14 @@ void MyFrame::OnToggleImages(wxCommandEvent& WXUNUSED(event)) } } +void MyFrame::OnToggleAlternateImages(wxCommandEvent& WXUNUSED(event)) +{ + bool alternateImages = m_treeCtrl->AlternateImages(); + + m_treeCtrl->SetAlternateImages(!alternateImages); + m_treeCtrl->CreateImageList(0); +} + void MyFrame::OnToggleButtons(wxCommandEvent& WXUNUSED(event)) { #if USE_GENERIC_TREECTRL || !defined(__WXMSW__) @@ -706,7 +718,8 @@ IMPLEMENT_DYNAMIC_CLASS(MyTreeCtrl, wxTreeCtrl) MyTreeCtrl::MyTreeCtrl(wxWindow *parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style) - : wxTreeCtrl(parent, id, pos, size, style) + : wxTreeCtrl(parent, id, pos, size, style), + m_alternateImages(false) { m_reverseSort = false; @@ -734,15 +747,29 @@ void MyTreeCtrl::CreateImageList(int size) // should correspond to TreeCtrlIcon_xxx enum wxBusyCursor wait; wxIcon icons[5]; - icons[0] = wxIcon(icon1_xpm); - icons[1] = wxIcon(icon2_xpm); - icons[2] = wxIcon(icon3_xpm); - icons[3] = wxIcon(icon4_xpm); - icons[4] = wxIcon(icon5_xpm); - int sizeOrig = icons[0].GetWidth(); + if (m_alternateImages) + { + icons[TreeCtrlIcon_File] = wxIcon(icon1_xpm); + icons[TreeCtrlIcon_FileSelected] = wxIcon(icon2_xpm); + icons[TreeCtrlIcon_Folder] = wxIcon(icon3_xpm); + icons[TreeCtrlIcon_FolderSelected] = wxIcon(icon4_xpm); + icons[TreeCtrlIcon_FolderOpened] = wxIcon(icon5_xpm); + } + else + { + wxSize iconSize(size, size); + + icons[TreeCtrlIcon_File] = + icons[TreeCtrlIcon_FileSelected] = wxArtProvider::GetIcon(wxART_NORMAL_FILE, wxART_LIST, iconSize); + icons[TreeCtrlIcon_Folder] = + icons[TreeCtrlIcon_FolderSelected] = + icons[TreeCtrlIcon_FolderOpened] = wxArtProvider::GetIcon(wxART_FOLDER, wxART_LIST, iconSize); + } + for ( size_t i = 0; i < WXSIZEOF(icons); i++ ) { + int sizeOrig = icons[0].GetWidth(); if ( size == sizeOrig ) { images->Add(icons[i]); @@ -771,12 +798,25 @@ void MyTreeCtrl::CreateButtonsImageList(int size) // should correspond to TreeCtrlIcon_xxx enum wxBusyCursor wait; wxIcon icons[4]; - icons[0] = wxIcon(icon3_xpm); // closed - icons[1] = wxIcon(icon3_xpm); // closed, selected - icons[2] = wxIcon(icon5_xpm); // open - icons[3] = wxIcon(icon5_xpm); // open, selected - for ( size_t i = 0; i < WXSIZEOF(icons); i++ ) + if (m_alternateImages) + { + icons[0] = wxIcon(icon3_xpm); // closed + icons[1] = wxIcon(icon3_xpm); // closed, selected + icons[2] = wxIcon(icon5_xpm); // open + icons[3] = wxIcon(icon5_xpm); // open, selected + } + else + { + wxSize iconSize(size, size); + + icons[0] = // closed + icons[1] = wxArtProvider::GetIcon(wxART_FOLDER, wxART_LIST, iconSize); // closed, selected + icons[2] = // open + icons[3] = wxArtProvider::GetIcon(wxART_FOLDER_OPEN, wxART_LIST, iconSize);// open, selected + } + + for ( size_t i = 0; i < WXSIZEOF(icons); i++ ) { int sizeOrig = icons[i].GetWidth(); if ( size == sizeOrig ) diff --git a/samples/treectrl/treetest.h b/samples/treectrl/treetest.h index f9a2f3bcaa..14e26e6a13 100644 --- a/samples/treectrl/treetest.h +++ b/samples/treectrl/treetest.h @@ -61,7 +61,7 @@ public: TreeCtrlIcon_FolderOpened }; - MyTreeCtrl() { } + MyTreeCtrl() { m_alternateImages = false; } MyTreeCtrl(wxWindow *parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style); @@ -111,6 +111,9 @@ public: void SetLastItem(wxTreeItemId id) { m_lastItem = id; } + void SetAlternateImages(bool show) { m_alternateImages = show; } + bool AlternateImages() const { return m_alternateImages; } + protected: virtual int OnCompareItems(const wxTreeItemId& i1, const wxTreeItemId& i2); @@ -133,6 +136,7 @@ private: bool m_reverseSort; // flag for OnCompareItems wxTreeItemId m_lastItem, // for OnEnsureVisible() m_draggedItem; // item being dragged right now + bool m_alternateImages; // NB: due to an ugly wxMSW hack you _must_ use DECLARE_DYNAMIC_CLASS() // if you want your overloaded OnCompareItems() to be called. @@ -193,6 +197,7 @@ public: void OnRecreate(wxCommandEvent& event); void OnToggleButtons(wxCommandEvent& event); void OnToggleImages(wxCommandEvent& event); + void OnToggleAlternateImages(wxCommandEvent& event); void OnSetImageSize(wxCommandEvent& event); void OnCollapseAndReset(wxCommandEvent& event); @@ -274,6 +279,7 @@ enum TreeTest_DeleteAll, TreeTest_Recreate, TreeTest_ToggleImages, + TreeTest_ToggleAlternateImages, TreeTest_ToggleButtons, TreeTest_SetImageSize, TreeTest_ToggleSel, diff --git a/src/common/artprov.cpp b/src/common/artprov.cpp index dd5cdb4bd5..bd79bb96e3 100644 --- a/src/common/artprov.cpp +++ b/src/common/artprov.cpp @@ -43,6 +43,7 @@ WX_DEFINE_LIST(wxArtProvidersList) // ---------------------------------------------------------------------------- WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxBitmap, wxArtProviderBitmapsHash); +WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxIconBundle, wxArtProviderIconBundlesHash); class WXDLLEXPORT wxArtProviderCache { @@ -51,14 +52,22 @@ public: void PutBitmap(const wxString& full_id, const wxBitmap& bmp) { m_bitmapsHash[full_id] = bmp; } + bool GetIconBundle(const wxString& full_id, wxIconBundle* bmp); + void PutIconBundle(const wxString& full_id, const wxIconBundle& iconbundle) + { m_iconBundlesHash[full_id] = iconbundle; } + void Clear(); static wxString ConstructHashID(const wxArtID& id, const wxArtClient& client, const wxSize& size); + static wxString ConstructHashID(const wxArtID& id, + const wxArtClient& client); + private: - wxArtProviderBitmapsHash m_bitmapsHash; + wxArtProviderBitmapsHash m_bitmapsHash; // cache of wxBitmaps + wxArtProviderIconBundlesHash m_iconBundlesHash; // cache of wxIconBundles }; bool wxArtProviderCache::GetBitmap(const wxString& full_id, wxBitmap* bmp) @@ -75,21 +84,43 @@ bool wxArtProviderCache::GetBitmap(const wxString& full_id, wxBitmap* bmp) } } +bool wxArtProviderCache::GetIconBundle(const wxString& full_id, wxIconBundle* bmp) +{ + wxArtProviderIconBundlesHash::iterator entry = m_iconBundlesHash.find(full_id); + if ( entry == m_iconBundlesHash.end() ) + { + return false; + } + else + { + *bmp = entry->second; + return true; + } +} + void wxArtProviderCache::Clear() { m_bitmapsHash.clear(); + m_iconBundlesHash.clear(); } -/*static*/ wxString wxArtProviderCache::ConstructHashID( - const wxArtID& id, const wxArtClient& client, - const wxSize& size) +/* static */ wxString +wxArtProviderCache::ConstructHashID(const wxArtID& id, + const wxArtClient& client) { - wxString str; - str.Printf(wxT("%s-%s-%i-%i"), id.c_str(), client.c_str(), size.x, size.y); - return str; + return id + _T('-') + client; } +/* static */ wxString +wxArtProviderCache::ConstructHashID(const wxArtID& id, + const wxArtClient& client, + const wxSize& size) +{ + return ConstructHashID(id, client) + _T('-') + + wxString::Format(_T("%d-%d"), size.x, size.y); +} + // ============================================================================ // wxArtProvider class // ============================================================================ @@ -216,20 +247,53 @@ wxArtProvider::~wxArtProvider() #endif break; } + // We could try the IconBundles here and convert what we find + // to a bitmap. } - sm_cache->PutBitmap(hashId, bmp); - } + } return bmp; } +/*static*/ wxIconBundle wxArtProvider::GetIconBundle(const wxArtID& id, const wxArtClient& client) +{ + // safety-check against writing client,id,size instead of id,client,size: + wxASSERT_MSG( client.Last() == _T('C'), _T("invalid 'client' parameter") ); + + wxCHECK_MSG( sm_providers, wxNullIconBundle, _T("no wxArtProvider exists") ); + + wxString hashId = wxArtProviderCache::ConstructHashID(id, client); + + wxIconBundle iconbundle; + if ( !sm_cache->GetIconBundle(hashId, &iconbundle) ) + { + for (wxArtProvidersList::compatibility_iterator node = sm_providers->GetFirst(); + node; node = node->GetNext()) + { + iconbundle = node->GetData()->CreateIconBundle(id, client); + if ( iconbundle.IsOk() ) + break; + } + + sm_cache->PutIconBundle(hashId, iconbundle); + } + + return iconbundle; +} + /*static*/ wxIcon wxArtProvider::GetIcon(const wxArtID& id, const wxArtClient& client, const wxSize& size) { wxCHECK_MSG( sm_providers, wxNullIcon, _T("no wxArtProvider exists") ); + // First look for an appropriate icon bundle - this will give us the best icon + wxIconBundle iconBundle = GetIconBundle(id, client); + if ( iconBundle.IsOk() ) + return iconBundle.GetIcon(size); + + // If there is no icon bundle then look for a bitmap wxBitmap bmp = GetBitmap(id, client, size); if ( !bmp.Ok() ) return wxNullIcon; diff --git a/src/common/artstd.cpp b/src/common/artstd.cpp index c3e4fe994b..c5a9679e38 100644 --- a/src/common/artstd.cpp +++ b/src/common/artstd.cpp @@ -77,7 +77,7 @@ protected: wxArtProvider::Push(new wxDefaultArtProvider); } -#if !defined(__WXGTK20__) || defined(__WXUNIVERSAL__) +#if !(defined(__WXGTK20__) || defined(__WXMAC__)) || defined(__WXUNIVERSAL__) /*static*/ void wxArtProvider::InitNativeProvider() { } diff --git a/src/common/gdicmn.cpp b/src/common/gdicmn.cpp index a4b09c9493..0214f8cad3 100644 --- a/src/common/gdicmn.cpp +++ b/src/common/gdicmn.cpp @@ -25,6 +25,7 @@ #include "wx/brush.h" #include "wx/palette.h" #include "wx/icon.h" + #include "wx/iconbndl.h" #include "wx/cursor.h" #include "wx/settings.h" #include "wx/bitmap.h" @@ -52,6 +53,7 @@ WXDLLIMPEXP_DATA_CORE(wxPen) wxNullPen; #if wxUSE_PALETTE WXDLLIMPEXP_DATA_CORE(wxPalette) wxNullPalette; #endif +WXDLLIMPEXP_DATA_CORE(wxIconBundle) wxNullIconBundle; const wxSize wxDefaultSize(wxDefaultCoord, wxDefaultCoord); const wxPoint wxDefaultPosition(wxDefaultCoord, wxDefaultCoord); diff --git a/src/common/iconbndl.cpp b/src/common/iconbndl.cpp index e15376f5bb..19ede4871a 100644 --- a/src/common/iconbndl.cpp +++ b/src/common/iconbndl.cpp @@ -1,13 +1,21 @@ ///////////////////////////////////////////////////////////////////////////// // Name: src/common/iconbndl.cpp // Purpose: wxIconBundle -// Author: Mattia Barbon +// Author: Mattia Barbon, Vadim Zeitlin // Created: 23.03.2002 // RCS-ID: $Id$ // Copyright: (c) Mattia barbon // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -30,113 +38,200 @@ WX_DEFINE_OBJARRAY(wxIconArray) -const wxIconBundle& wxIconBundle::operator =( const wxIconBundle& ic ) +IMPLEMENT_DYNAMIC_CLASS(wxIconBundle, wxGDIObject) + +#define M_ICONBUNDLEDATA ((wxIconBundleRefData *)m_refData) + +// ---------------------------------------------------------------------------- +// wxIconBundleRefData +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxIconBundleRefData : public wxGDIRefData +{ +public: + // default and copy ctors and assignment operators are ok + +protected: + wxIconArray m_icons; + + friend class WXDLLEXPORT wxIconBundle; +}; + +// ============================================================================ +// wxIconBundle implementation +// ============================================================================ + +wxIconBundle::wxIconBundle() + : wxGDIObject() +{ + m_refData = new wxIconBundleRefData; +} + +wxIconBundle::wxIconBundle(const wxString& file, long type) + : wxGDIObject() { - if( this == &ic ) return *this; + m_refData = new wxIconBundleRefData; + AddIcon(file, type); +} - size_t i, max = ic.m_icons.GetCount(); +wxIconBundle::wxIconBundle(const wxIconBundle& icon) + : wxGDIObject() +{ + Ref(icon); +} - DeleteIcons(); - for( i = 0; i < max; ++i ) - m_icons.Add( ic.m_icons[i] ); +wxIconBundle::wxIconBundle(const wxIcon& icon) + : wxGDIObject() +{ + m_refData = new wxIconBundleRefData; + AddIcon(icon); +} - return *this; +wxObjectRefData *wxIconBundle::CreateRefData() const +{ + return new wxIconBundleRefData; +} + +wxObjectRefData *wxIconBundle::CloneRefData(const wxObjectRefData *data) const +{ + return new wxIconBundleRefData(*wx_static_cast(const wxIconBundleRefData *, data)); } void wxIconBundle::DeleteIcons() { - m_icons.Empty(); + wxIconBundleRefData* ref = new wxIconBundleRefData(); + UnRef(); + m_refData = ref; } -#if wxUSE_IMAGE -void wxIconBundle::AddIcon( const wxString& file, long type ) -#else -void wxIconBundle::AddIcon( const wxString& WXUNUSED(file), long WXUNUSED(type) ) -#endif +bool wxIconBundle::IsOk() const +{ + return M_ICONBUNDLEDATA && !M_ICONBUNDLEDATA->m_icons.IsEmpty(); +} + +void wxIconBundle::AddIcon(const wxString& file, long type) { +#ifdef __WXMAC__ + // Deal with standard icons + if ( type == wxBITMAP_TYPE_ICON_RESOURCE ) + { + wxIcon tmp(file, type); + if (tmp.Ok()) + { + AddIcon(tmp); + return; + } + } +#endif // __WXMAC__ + #if wxUSE_IMAGE && (!defined(__WXMSW__) || wxUSE_WXDIB) - size_t count = wxImage::GetImageCount( file, type ); - size_t i; wxImage image; - for( i = 0; i < count; ++i ) + const size_t count = wxImage::GetImageCount( file, type ); + for ( size_t i = 0; i < count; ++i ) { - if( !image.LoadFile( file, type, i ) ) + if ( !image.LoadFile( file, type, i ) ) { wxLogError( _("Failed to load image %d from file '%s'."), i, file.c_str() ); continue; } - wxIcon* tmp = new wxIcon(); - tmp->CopyFromBitmap( wxBitmap( image ) ); - AddIcon( *tmp ); - delete tmp; + wxIcon tmp; + tmp.CopyFromBitmap(wxBitmap(image)); + AddIcon(tmp); } -#endif +#else // !wxUSE_IMAGE + wxUnusedVar(file); + wxUnusedVar(type); +#endif // wxUSE_IMAGE/!wxUSE_IMAGE } -const wxIcon& wxIconBundle::GetIcon( const wxSize& size ) const +wxIcon wxIconBundle::GetIcon(const wxSize& size) const { - // temp. variable needed to fix Borland C++ 5.5.1 problem - // with passing a return value through two functions - wxIcon *tmp; - - size_t max = m_icons.GetCount(); - - // if we have one or no icon, we can return now without doing more work: - if ( max <= 1 ) - { - if ( max == 1 ) // fix for broken BCC - tmp = &m_icons[0]; - else // max == 0 - tmp = &wxNullIcon; - return *tmp; - } + wxCHECK_MSG( IsOk(), wxNullIcon, _T("invalid icon bundle") ); - // there are more icons, find the best match: - wxCoord sysX = wxSystemSettings::GetMetric( wxSYS_ICON_X ), - sysY = wxSystemSettings::GetMetric( wxSYS_ICON_Y ); + const wxIconArray& iconArray = M_ICONBUNDLEDATA->m_icons; - wxIcon *sysIcon = 0; + const size_t count = iconArray.size(); - for( size_t i = 0; i < max; i++ ) + // optimize for the common case of icon bundles containing one icon only + wxIcon iconBest; + switch ( count ) { - if( !m_icons[i].Ok() ) - continue; - wxCoord sx = m_icons[i].GetWidth(), sy = m_icons[i].GetHeight(); - // requested size - if( sx == size.x && sy == size.y ) - { - tmp = &m_icons[i]; // fix for broken BCC - return *tmp; - } - // keep track if there is a system-size icon - if( sx == sysX && sy == sysY ) - sysIcon = &m_icons[i]; + case 0: + // nothing to do, iconBest is already invalid + break; + + case 1: + iconBest = iconArray[0]; + break; + + default: + // there is more than one icon, find the best match: + wxCoord sysX = wxSystemSettings::GetMetric( wxSYS_ICON_X ), + sysY = wxSystemSettings::GetMetric( wxSYS_ICON_Y ); + + for ( size_t i = 0; i < count; i++ ) + { + const wxIcon& icon = iconArray[i]; + wxCoord sx = icon.GetWidth(), + sy = icon.GetHeight(); + + // if we got an icon of exactly the requested size, we're done + if ( sx == size.x && sy == size.y ) + { + iconBest = icon; + break; + } + + // the best icon is by default (arbitrarily) the first one but + // if we find a system-sized icon, take it instead + if ( sx == sysX && sy == sysY || !iconBest.IsOk() ) + iconBest = icon; + } } - // return the system-sized icon if we've got one - if( sysIcon ) return *sysIcon; - // we certainly have at least one icon thanks to the <=1 check above - tmp = &m_icons[0]; - return *tmp; +#ifdef __WXMAC__ + return wxIcon(iconBest.GetHICON(), size); +#else + return iconBest; +#endif } -void wxIconBundle::AddIcon( const wxIcon& icon ) +void wxIconBundle::AddIcon(const wxIcon& icon) { - size_t i, max = m_icons.GetCount(); + wxCHECK_RET( icon.IsOk(), _T("invalid icon") ); - for( i = 0; i < max; ++i ) + AllocExclusive(); + + wxIconArray& iconArray = M_ICONBUNDLEDATA->m_icons; + + // replace existing icon with the same size if we already have it + const size_t count = iconArray.size(); + for ( size_t i = 0; i < count; ++i ) { - wxIcon& tmp = m_icons[i]; - if( tmp.Ok() && tmp.GetWidth() == icon.GetWidth() && - tmp.GetHeight() == icon.GetHeight() ) + wxIcon& tmp = iconArray[i]; + if ( tmp.Ok() && + tmp.GetWidth() == icon.GetWidth() && + tmp.GetHeight() == icon.GetHeight() ) { tmp = icon; return; } } - m_icons.Add( icon ); + // if we don't, add an icon with new size + iconArray.Add(icon); } + +size_t wxIconBundle::GetIconCount() const +{ + return M_ICONBUNDLEDATA->m_icons.size(); +} + +wxIcon wxIconBundle::GetIconByIndex(size_t n) const +{ + return M_ICONBUNDLEDATA->m_icons[n]; +} + diff --git a/src/gtk/toplevel.cpp b/src/gtk/toplevel.cpp index f47a53f8b8..b97cae2363 100644 --- a/src/gtk/toplevel.cpp +++ b/src/gtk/toplevel.cpp @@ -1175,7 +1175,13 @@ void wxTopLevelWindowGTK::SetTitle( const wxString &title ) void wxTopLevelWindowGTK::SetIcon( const wxIcon &icon ) { - SetIcons( wxIconBundle( icon ) ); + // passing wxNullIcon to SetIcon() is possible (it means that we shouldn't + // have any icon), but adding an invalid icon to wxIconBundle is not + wxIconBundle icons; + if ( icon.Ok() ) + icons.AddIcon(icon); + + SetIcons(icons); } void wxTopLevelWindowGTK::SetIcons( const wxIconBundle &icons ) @@ -1185,15 +1191,13 @@ void wxTopLevelWindowGTK::SetIcons( const wxIconBundle &icons ) wxTopLevelWindowBase::SetIcons( icons ); GList *list = NULL; - size_t max = icons.m_icons.GetCount(); - for (size_t i = 0; i < max; i++) + const size_t numIcons = icons.GetIconCount(); + for ( size_t i = 0; i < numIcons; i++ ) { - if (icons.m_icons[i].Ok()) - { - list = g_list_prepend(list, icons.m_icons[i].GetPixbuf()); - } + list = g_list_prepend(list, icons.GetIconByIndex(i).GetPixbuf()); } + gtk_window_set_icon_list(GTK_WINDOW(m_widget), list); g_list_free(list); } diff --git a/src/mac/carbon/artmac.cpp b/src/mac/carbon/artmac.cpp new file mode 100644 index 0000000000..466ba9be56 --- /dev/null +++ b/src/mac/carbon/artmac.cpp @@ -0,0 +1,108 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: src/mac/carbon/artmac.cpp +// Purpose: wxArtProvider instance with native Mac stock icons +// Author: Alan Shouls +// Created: 2006-10-30 +// RCS-ID: $Id$ +// Copyright: (c) wxWindows team +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +// --------------------------------------------------------------------------- +// headers +// --------------------------------------------------------------------------- + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#if defined(__BORLANDC__) + #pragma hdrstop +#endif + +#ifndef WX_PRECOMP + #include "wx/image.h" +#endif + +#include "wx/artprov.h" +#include "wx/image.h" + +// ---------------------------------------------------------------------------- +// wxMacArtProvider +// ---------------------------------------------------------------------------- + +class wxMacArtProvider : public wxArtProvider +{ +protected: + virtual wxBitmap CreateBitmap(const wxArtID& id, const wxArtClient& client, + const wxSize& size); + virtual wxIconBundle CreateIconBundle(const wxArtID& id, + const wxArtClient& client); +}; + +/* static */ void wxArtProvider::InitNativeProvider() +{ + wxArtProvider::Push(new wxMacArtProvider); +} + +// ---------------------------------------------------------------------------- +// helper macros +// ---------------------------------------------------------------------------- + +#define CREATE_STD_ICON(iconId, xpmRc) \ + { \ + wxIconBundle icon(_T(iconId), wxBITMAP_TYPE_ICON_RESOURCE); \ + return icon; \ + } + +// Macro used in CreateBitmap to get wxICON_FOO icons: +#define ART_MSGBOX(artId, iconId, xpmRc) \ + if ( id == artId ) \ + { \ + CREATE_STD_ICON(#iconId, xpmRc) \ + } + +static wxIconBundle wxMacArtProvider_CreateIconBundle(const wxArtID& id) +{ + ART_MSGBOX(wxART_ERROR, wxICON_ERROR, error) + ART_MSGBOX(wxART_INFORMATION, wxICON_INFORMATION, info) + ART_MSGBOX(wxART_WARNING, wxICON_WARNING, warning) + ART_MSGBOX(wxART_QUESTION, wxICON_QUESTION, question) + + ART_MSGBOX(wxART_FOLDER, wxICON_FOLDER, folder) + ART_MSGBOX(wxART_FOLDER_OPEN, wxICON_FOLDER_OPEN, folder_open) + ART_MSGBOX(wxART_NORMAL_FILE, wxICON_NORMAL_FILE, deffile) + + return wxNullIconBundle; +} + +// ---------------------------------------------------------------------------- +// CreateIconBundle +// ---------------------------------------------------------------------------- + +wxIconBundle wxMacArtProvider::CreateIconBundle(const wxArtID& id, const wxArtClient& client) +{ + // On the Mac folders in lists are always drawn closed, so if an open + // folder icon is asked for we will ask for a closed one in its place + if ( client == wxART_LIST && id == wxART_FOLDER_OPEN ) + return wxMacArtProvider_CreateIconBundle(wxART_FOLDER); + + return wxMacArtProvider_CreateIconBundle(id); +} + +// ---------------------------------------------------------------------------- +// CreateBitmap +// ---------------------------------------------------------------------------- + +wxBitmap wxMacArtProvider::CreateBitmap(const wxArtID& id, + const wxArtClient& client, + const wxSize& reqSize) +{ + wxIconBundle ic(CreateIconBundle(id, client)); + if (ic.IsOk()) + { + wxIcon theIcon(ic.GetIcon(reqSize)); + return wxBitmap(theIcon); + } + + return wxNullBitmap; +} diff --git a/src/mac/carbon/icon.cpp b/src/mac/carbon/icon.cpp index 7084b59cfc..68e908bf25 100644 --- a/src/mac/carbon/icon.cpp +++ b/src/mac/carbon/icon.cpp @@ -53,6 +53,18 @@ wxIcon::wxIcon( LoadFile( icon_file, (wxBitmapType) flags, desiredWidth, desiredHeight ); } +wxIcon::wxIcon(WXHICON icon, const wxSize& size) + : wxGDIObject() +{ + // as the icon owns that ref, we have to acquire it as well + if (icon) + AcquireIconRef( (IconRef) icon ) ; + + m_refData = new wxIconRefData( icon ) ; + M_ICONDATA->SetWidth( size.x ) ; + M_ICONDATA->SetHeight( size.y ) ; +} + wxIcon::~wxIcon() { } @@ -126,6 +138,18 @@ bool wxIcon::LoadFile( { theId = kAlertStopIcon ; } + else if ( filename == wxT("wxICON_FOLDER") ) + { + theId = kGenericFolderIcon ; + } + else if ( filename == wxT("wxICON_FOLDER_OPEN") ) + { + theId = kOpenFolderIcon ; + } + else if ( filename == wxT("wxICON_NORMAL_FILE") ) + { + theId = kGenericDocumentIcon ; + } else { #if 0 diff --git a/src/unix/utilsx11.cpp b/src/unix/utilsx11.cpp index f6627e6e69..67e641c3cb 100644 --- a/src/unix/utilsx11.cpp +++ b/src/unix/utilsx11.cpp @@ -106,31 +106,32 @@ private: // Setting icons for window manager: // ---------------------------------------------------------------------------- -void wxSetIconsX11( WXDisplay* display, WXWindow window, - const wxIconBundle& ib ) +void +wxSetIconsX11(WXDisplay* display, WXWindow window, const wxIconBundle& ib) { #if !wxUSE_NANOX size_t size = 0; - size_t i, max = ib.m_icons.GetCount(); - for( i = 0; i < max; ++i ) - if( ib.m_icons[i].Ok() ) - size += 2 + ib.m_icons[i].GetWidth() * ib.m_icons[i].GetHeight(); + const size_t numIcons = ib.GetIconCount(); + for ( size_t i = 0; i < numIcons; ++i ) + { + const wxIcon icon = ib.GetIconByIndex(i); + + size += 2 + icon.GetWidth() * icon.GetHeight(); + } wxMAKE_ATOM(_NET_WM_ICON, (Display*)display); - if( size > 0 ) + if ( size > 0 ) { -// The code below is correct for 64-bit machines also. -// wxUint32* data = new wxUint32[size]; -// wxUint32* ptr = data; unsigned long* data = new unsigned long[size]; unsigned long* ptr = data; - for( i = 0; i < max; ++i ) + for ( size_t i = 0; i < numIcons; ++i ) { - const wxImage image = ib.m_icons[i].ConvertToImage(); - int width = image.GetWidth(), height = image.GetHeight(); + const wxImage image = ib.GetIconByIndex(i).ConvertToImage(); + int width = image.GetWidth(), + height = image.GetHeight(); unsigned char* imageData = image.GetData(); unsigned char* imageDataEnd = imageData + ( width * height * 3 ); bool hasMask = image.HasMask(); @@ -153,7 +154,8 @@ void wxSetIconsX11( WXDisplay* display, WXWindow window, *ptr++ = width; *ptr++ = height; - while( imageData < imageDataEnd ) { + while ( imageData < imageDataEnd ) + { r = imageData[0]; g = imageData[1]; b = imageData[2]; -- 2.47.2