X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7bebedd82651a0fc6cf002497956c467375362f7..aaf37267a8d038f61f06c4a12d16bf3df38fc3be:/src/gtk/artgtk.cpp diff --git a/src/gtk/artgtk.cpp b/src/gtk/artgtk.cpp index e7aaa2935d..7bc18ba46c 100644 --- a/src/gtk/artgtk.cpp +++ b/src/gtk/artgtk.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: artstd.cpp +// Name: src/gtk/artstd.cpp // Purpose: stock wxArtProvider instance with native GTK+ stock icons // Author: Vaclav Slavik // Modified by: @@ -20,11 +20,8 @@ #pragma hdrstop #endif -#if defined(__WXGTK20__) && !defined(__WXUNIVERSAL__) - #include "wx/artprov.h" - -#include +#include "wx/gtk/private.h" // compatibility with older GTK+ versions: #ifndef GTK_STOCK_FILE @@ -48,23 +45,26 @@ protected: /*static*/ void wxArtProvider::InitNativeProvider() { - wxArtProvider::PushProvider(new wxGTK2ArtProvider); + Push(new wxGTK2ArtProvider); } // ---------------------------------------------------------------------------- // CreateBitmap routine // ---------------------------------------------------------------------------- -static const char *wxArtIDToStock(const wxArtID& id) +namespace +{ + +const char *wxArtIDToStock(const wxArtID& id) { #define ART(wxid, gtkid) \ if (id == wxid) return gtkid; - + ART(wxART_ERROR, GTK_STOCK_DIALOG_ERROR) ART(wxART_INFORMATION, GTK_STOCK_DIALOG_INFO) ART(wxART_WARNING, GTK_STOCK_DIALOG_WARNING) ART(wxART_QUESTION, GTK_STOCK_DIALOG_QUESTION) - + //ART(wxART_HELP_SIDE_PANEL, ) ART(wxART_HELP_SETTINGS, GTK_STOCK_SELECT_FONT) //ART(wxART_HELP_BOOK, ) @@ -87,18 +87,41 @@ static const char *wxArtIDToStock(const wxArtID& id) //ART(wxART_LIST_VIEW, ) //ART(wxART_NEW_DIR, ) ART(wxART_FOLDER, GTK_STOCK_DIRECTORY) + ART(wxART_FOLDER_OPEN, GTK_STOCK_DIRECTORY) //ART(wxART_GO_DIR_UP, ) ART(wxART_EXECUTABLE_FILE, GTK_STOCK_EXECUTE) ART(wxART_NORMAL_FILE, GTK_STOCK_FILE) ART(wxART_TICK_MARK, GTK_STOCK_APPLY) ART(wxART_CROSS_MARK, GTK_STOCK_CANCEL) - + + ART(wxART_FLOPPY, GTK_STOCK_FLOPPY) + ART(wxART_CDROM, GTK_STOCK_CDROM) + ART(wxART_HARDDISK, GTK_STOCK_HARDDISK) + ART(wxART_REMOVABLE, GTK_STOCK_HARDDISK) + + ART(wxART_FILE_SAVE, GTK_STOCK_SAVE) + ART(wxART_FILE_SAVE_AS, GTK_STOCK_SAVE_AS) + + ART(wxART_COPY, GTK_STOCK_COPY) + ART(wxART_CUT, GTK_STOCK_CUT) + ART(wxART_PASTE, GTK_STOCK_PASTE) + ART(wxART_DELETE, GTK_STOCK_DELETE) + ART(wxART_NEW, GTK_STOCK_NEW) + + ART(wxART_UNDO, GTK_STOCK_UNDO) + ART(wxART_REDO, GTK_STOCK_REDO) + + ART(wxART_QUIT, GTK_STOCK_QUIT) + + ART(wxART_FIND, GTK_STOCK_FIND) + ART(wxART_FIND_AND_REPLACE, GTK_STOCK_FIND_AND_REPLACE) + return NULL; - + #undef ART } -static GtkIconSize wxArtClientToIconSize(const wxArtClient& client) +GtkIconSize ArtClientToIconSize(const wxArtClient& client) { if (client == wxART_TOOLBAR) return GTK_ICON_SIZE_LARGE_TOOLBAR; @@ -109,10 +132,10 @@ static GtkIconSize wxArtClientToIconSize(const wxArtClient& client) else if (client == wxART_BUTTON) return GTK_ICON_SIZE_BUTTON; else - return GTK_ICON_SIZE_BUTTON; // this is arbitrary + return GTK_ICON_SIZE_INVALID; // this is arbitrary } -static GtkIconSize FindClosestIconSize(const wxSize& size) +GtkIconSize FindClosestIconSize(const wxSize& size) { #define NUM_SIZES 6 static struct @@ -145,8 +168,8 @@ static GtkIconSize FindClosestIconSize(const wxSize& size) // only use larger bitmaps, scaling down looks better than scaling up: if (size.x > s_sizes[i].x || size.y > s_sizes[i].y) continue; - - unsigned dist = (size.x - s_sizes[i].x) * (size.x - s_sizes[i].x) + + + unsigned dist = (size.x - s_sizes[i].x) * (size.x - s_sizes[i].x) + (size.y - s_sizes[i].y) * (size.y - s_sizes[i].y); if (dist == 0) return s_sizes[i].icon; @@ -154,42 +177,70 @@ static GtkIconSize FindClosestIconSize(const wxSize& size) { distance = dist; best = s_sizes[i].icon; - } + } } return best; } +GdkPixbuf *CreateStockIcon(const char *stockid, GtkIconSize size) +{ + // FIXME: This code is not 100% correct, because stock pixmap are + // context-dependent and may be affected by theme engine, the + // correct value can only be obtained for given GtkWidget object. + // + // Fool-proof implementation of stock bitmaps would extend wxBitmap + // with "stock-id" representation (in addition to pixmap and pixbuf + // ones) and would convert it to pixbuf when rendered. + + GtkStyle* style = wxGTKPrivate::GetButtonWidget()->style; + GtkIconSet* iconset = gtk_style_lookup_icon_set(style, stockid); + + if (!iconset) + return NULL; + + return gtk_icon_set_render_icon(iconset, style, + gtk_widget_get_default_direction(), + GTK_STATE_NORMAL, size, NULL, NULL); +} + +GdkPixbuf *CreateThemeIcon(const char *iconname, + GtkIconSize iconsize, const wxSize& sz) +{ + wxSize size(sz); + if (size == wxDefaultSize) + { + gtk_icon_size_lookup(iconsize, &size.x, &size.y); + } + + return gtk_icon_theme_load_icon( + gtk_icon_theme_get_default(), + iconname, + size.x, + (GtkIconLookupFlags)0, NULL); +} + +} // anonymous namespace + wxBitmap wxGTK2ArtProvider::CreateBitmap(const wxArtID& id, const wxArtClient& client, const wxSize& size) { wxCharBuffer stockid = wxArtIDToStock(id); GtkIconSize stocksize = (size == wxDefaultSize) ? - wxArtClientToIconSize(client) : + ArtClientToIconSize(client) : FindClosestIconSize(size); + // we must have some size, this is arbitrary + if (stocksize == GTK_ICON_SIZE_INVALID) + stocksize = GTK_ICON_SIZE_BUTTON; + // allow passing GTK+ stock IDs to wxArtProvider: if (!stockid) stockid = id.ToAscii(); - // FIXME: This code is not 100% correct, because stock pixmap are - // context-dependent and may be affected by theme engine, the - // correct value can only be obtained for given GtkWidget object. - // - // Fool-proof implementation of stock bitmaps would extend wxBitmap - // with "stock-id" representation (in addition to pixmap and pixbuf - // ones) and would convert it to pixbuf when rendered. - - GtkStyle *style = gtk_widget_get_default_style(); - GtkIconSet *iconset = gtk_style_lookup_icon_set(style, stockid); - - if (!iconset) - return wxNullBitmap; - - GdkPixbuf *pixbuf = - gtk_icon_set_render_icon(iconset, style, - gtk_widget_get_default_direction(), - GTK_STATE_NORMAL, stocksize, NULL, NULL); + GdkPixbuf *pixbuf = CreateStockIcon(stockid, stocksize); + if (!pixbuf) + pixbuf = CreateThemeIcon(stockid, stocksize, size); if (pixbuf && size != wxDefaultSize && (size.x != gdk_pixbuf_get_width(pixbuf) || @@ -199,20 +250,31 @@ wxBitmap wxGTK2ArtProvider::CreateBitmap(const wxArtID& id, GDK_INTERP_BILINEAR); if (p2) { - gdk_pixbuf_unref(pixbuf); + g_object_unref (pixbuf); pixbuf = p2; } } - - if (!pixbuf) - return wxNullBitmap; wxBitmap bmp; - bmp.SetWidth(gdk_pixbuf_get_width(pixbuf)); - bmp.SetHeight(gdk_pixbuf_get_height(pixbuf)); - bmp.SetPixbuf(pixbuf); + if (pixbuf != NULL) + bmp.SetPixbuf(pixbuf); return bmp; } -#endif // defined(__WXGTK20__) && !defined(__WXUNIVERSAL__) +// ---------------------------------------------------------------------------- +// wxArtProvider::GetNativeSizeHint() +// ---------------------------------------------------------------------------- + +/*static*/ +wxSize wxArtProvider::GetNativeSizeHint(const wxArtClient& client) +{ + // Gtk has specific sizes for each client, see artgtk.cpp + GtkIconSize gtk_size = ArtClientToIconSize(client); + // no size hints for this client + if (gtk_size == GTK_ICON_SIZE_INVALID) + return wxDefaultSize; + gint width, height; + gtk_icon_size_lookup( gtk_size, &width, &height); + return wxSize(width, height); +}