1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: stock wxArtProvider instance with native GTK+ stock icons
4 // Author: Vaclav Slavik
8 // Copyright: (c) Vaclav Slavik, 2004
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ---------------------------------------------------------------------------
14 // ---------------------------------------------------------------------------
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
19 #if defined(__BORLANDC__)
23 #if defined(__WXGTK20__) && !defined(__WXUNIVERSAL__)
25 #include "wx/artprov.h"
29 // compatibility with older GTK+ versions:
30 #ifndef GTK_STOCK_FILE
31 #define GTK_STOCK_FILE "gtk-file"
33 #ifndef GTK_STOCK_DIRECTORY
34 #define GTK_STOCK_DIRECTORY "gtk-directory"
38 // ----------------------------------------------------------------------------
40 // ----------------------------------------------------------------------------
42 class wxGTK2ArtProvider
: public wxArtProvider
45 virtual wxBitmap
CreateBitmap(const wxArtID
& id
, const wxArtClient
& client
,
49 /*static*/ void wxArtProvider::InitNativeProvider()
51 wxArtProvider::PushProvider(new wxGTK2ArtProvider
);
54 // ----------------------------------------------------------------------------
55 // CreateBitmap routine
56 // ----------------------------------------------------------------------------
58 static const char *wxArtIDToStock(const wxArtID
& id
)
60 #define ART(wxid, gtkid) \
61 if (id == wxid) return gtkid;
63 ART(wxART_ERROR
, GTK_STOCK_DIALOG_ERROR
)
64 ART(wxART_INFORMATION
, GTK_STOCK_DIALOG_INFO
)
65 ART(wxART_WARNING
, GTK_STOCK_DIALOG_WARNING
)
66 ART(wxART_QUESTION
, GTK_STOCK_DIALOG_QUESTION
)
68 //ART(wxART_HELP_SIDE_PANEL, )
69 ART(wxART_HELP_SETTINGS
, GTK_STOCK_SELECT_FONT
)
70 //ART(wxART_HELP_BOOK, )
71 ART(wxART_HELP_FOLDER
, GTK_STOCK_DIRECTORY
)
72 ART(wxART_HELP_PAGE
, GTK_STOCK_FILE
)
73 ART(wxART_MISSING_IMAGE
, GTK_STOCK_MISSING_IMAGE
)
74 ART(wxART_ADD_BOOKMARK
, GTK_STOCK_ADD
)
75 ART(wxART_DEL_BOOKMARK
, GTK_STOCK_REMOVE
)
76 ART(wxART_GO_BACK
, GTK_STOCK_GO_BACK
)
77 ART(wxART_GO_FORWARD
, GTK_STOCK_GO_FORWARD
)
78 ART(wxART_GO_UP
, GTK_STOCK_GO_UP
)
79 ART(wxART_GO_DOWN
, GTK_STOCK_GO_DOWN
)
80 ART(wxART_GO_TO_PARENT
, GTK_STOCK_GO_UP
)
81 ART(wxART_GO_HOME
, GTK_STOCK_HOME
)
82 ART(wxART_FILE_OPEN
, GTK_STOCK_OPEN
)
83 ART(wxART_PRINT
, GTK_STOCK_PRINT
)
84 ART(wxART_HELP
, GTK_STOCK_HELP
)
85 ART(wxART_TIP
, GTK_STOCK_DIALOG_INFO
)
86 //ART(wxART_REPORT_VIEW, )
87 //ART(wxART_LIST_VIEW, )
88 //ART(wxART_NEW_DIR, )
89 ART(wxART_FOLDER
, GTK_STOCK_DIRECTORY
)
90 //ART(wxART_GO_DIR_UP, )
91 ART(wxART_EXECUTABLE_FILE
, GTK_STOCK_EXECUTE
)
92 ART(wxART_NORMAL_FILE
, GTK_STOCK_FILE
)
93 ART(wxART_TICK_MARK
, GTK_STOCK_APPLY
)
94 ART(wxART_CROSS_MARK
, GTK_STOCK_CANCEL
)
101 static GtkIconSize
wxArtClientToIconSize(const wxArtClient
& client
)
103 if (client
== wxART_TOOLBAR
)
104 return GTK_ICON_SIZE_LARGE_TOOLBAR
;
105 else if (client
== wxART_MENU
)
106 return GTK_ICON_SIZE_MENU
;
107 else if (client
== wxART_CMN_DIALOG
|| client
== wxART_MESSAGE_BOX
)
108 return GTK_ICON_SIZE_DIALOG
;
109 else if (client
== wxART_BUTTON
)
110 return GTK_ICON_SIZE_BUTTON
;
112 return GTK_ICON_SIZE_BUTTON
; // this is arbitrary
115 static GtkIconSize
FindClosestIconSize(const wxSize
& size
)
122 } s_sizes
[NUM_SIZES
];
123 static bool s_sizesInitialized
= false;
125 if (!s_sizesInitialized
)
127 s_sizes
[0].icon
= GTK_ICON_SIZE_MENU
;
128 s_sizes
[1].icon
= GTK_ICON_SIZE_SMALL_TOOLBAR
;
129 s_sizes
[2].icon
= GTK_ICON_SIZE_LARGE_TOOLBAR
;
130 s_sizes
[3].icon
= GTK_ICON_SIZE_BUTTON
;
131 s_sizes
[4].icon
= GTK_ICON_SIZE_DND
;
132 s_sizes
[5].icon
= GTK_ICON_SIZE_DIALOG
;
133 for (size_t i
= 0; i
< NUM_SIZES
; i
++)
135 gtk_icon_size_lookup(s_sizes
[i
].icon
,
136 &s_sizes
[i
].x
, &s_sizes
[i
].y
);
138 s_sizesInitialized
= true;
141 GtkIconSize best
= GTK_ICON_SIZE_DIALOG
; // presumably largest
142 unsigned distance
= INT_MAX
;
143 for (size_t i
= 0; i
< NUM_SIZES
; i
++)
145 // only use larger bitmaps, scaling down looks better than scaling up:
146 if (size
.x
> s_sizes
[i
].x
|| size
.y
> s_sizes
[i
].y
)
149 unsigned dist
= (size
.x
- s_sizes
[i
].x
) * (size
.x
- s_sizes
[i
].x
) +
150 (size
.y
- s_sizes
[i
].y
) * (size
.y
- s_sizes
[i
].y
);
152 return s_sizes
[i
].icon
;
153 else if (dist
< distance
)
156 best
= s_sizes
[i
].icon
;
162 static GdkPixbuf
*CreateStockIcon(const char *stockid
, GtkIconSize size
)
164 // FIXME: This code is not 100% correct, because stock pixmap are
165 // context-dependent and may be affected by theme engine, the
166 // correct value can only be obtained for given GtkWidget object.
168 // Fool-proof implementation of stock bitmaps would extend wxBitmap
169 // with "stock-id" representation (in addition to pixmap and pixbuf
170 // ones) and would convert it to pixbuf when rendered.
172 GtkStyle
*style
= gtk_widget_get_default_style();
173 GtkIconSet
*iconset
= gtk_style_lookup_icon_set(style
, stockid
);
178 return gtk_icon_set_render_icon(iconset
, style
,
179 gtk_widget_get_default_direction(),
180 GTK_STATE_NORMAL
, size
, NULL
, NULL
);
183 #if GTK_CHECK_VERSION(2,4,0)
184 static GdkPixbuf
*CreateThemeIcon(const char *iconname
,
185 GtkIconSize iconsize
, const wxSize
& sz
)
188 if (size
== wxDefaultSize
)
190 gtk_icon_size_lookup(iconsize
, &size
.x
, &size
.y
);
193 return gtk_icon_theme_load_icon(
194 gtk_icon_theme_get_default(),
197 (GtkIconLookupFlags
)0, NULL
);
199 #endif // GTK+ >= 2.4.0
201 wxBitmap
wxGTK2ArtProvider::CreateBitmap(const wxArtID
& id
,
202 const wxArtClient
& client
,
205 wxCharBuffer stockid
= wxArtIDToStock(id
);
206 GtkIconSize stocksize
= (size
== wxDefaultSize
) ?
207 wxArtClientToIconSize(client
) :
208 FindClosestIconSize(size
);
210 // allow passing GTK+ stock IDs to wxArtProvider:
212 stockid
= id
.ToAscii();
214 GdkPixbuf
*pixbuf
= CreateStockIcon(stockid
, stocksize
);
216 #if GTK_CHECK_VERSION(2,4,0)
218 pixbuf
= CreateThemeIcon(stockid
, stocksize
, size
);
221 if (pixbuf
&& size
!= wxDefaultSize
&&
222 (size
.x
!= gdk_pixbuf_get_width(pixbuf
) ||
223 size
.y
!= gdk_pixbuf_get_height(pixbuf
)))
225 GdkPixbuf
*p2
= gdk_pixbuf_scale_simple(pixbuf
, size
.x
, size
.y
,
226 GDK_INTERP_BILINEAR
);
229 gdk_pixbuf_unref(pixbuf
);
238 bmp
.SetWidth(gdk_pixbuf_get_width(pixbuf
));
239 bmp
.SetHeight(gdk_pixbuf_get_height(pixbuf
));
240 bmp
.SetPixbuf(pixbuf
);
245 #endif // defined(__WXGTK20__) && !defined(__WXUNIVERSAL__)