1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/artstd.cpp
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(__WXUNIVERSAL__)
25 #include "wx/artprov.h"
28 #include "wx/module.h"
31 #include <gtk/gtkversion.h>
32 #if GTK_CHECK_VERSION(2, 9, 0)
34 #undef GTK_DISABLE_DEPRECATED
38 // compatibility with older GTK+ versions:
39 #ifndef GTK_STOCK_FILE
40 #define GTK_STOCK_FILE "gtk-file"
42 #ifndef GTK_STOCK_DIRECTORY
43 #define GTK_STOCK_DIRECTORY "gtk-directory"
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
51 class wxGTK2ArtProvider
: public wxArtProvider
54 virtual wxBitmap
CreateBitmap(const wxArtID
& id
, const wxArtClient
& client
,
58 /*static*/ void wxArtProvider::InitNativeProvider()
60 Push(new wxGTK2ArtProvider
);
63 // ----------------------------------------------------------------------------
64 // CreateBitmap routine
65 // ----------------------------------------------------------------------------
67 static const char *wxArtIDToStock(const wxArtID
& id
)
69 #define ART(wxid, gtkid) \
70 if (id == wxid) return gtkid;
72 ART(wxART_ERROR
, GTK_STOCK_DIALOG_ERROR
)
73 ART(wxART_INFORMATION
, GTK_STOCK_DIALOG_INFO
)
74 ART(wxART_WARNING
, GTK_STOCK_DIALOG_WARNING
)
75 ART(wxART_QUESTION
, GTK_STOCK_DIALOG_QUESTION
)
77 //ART(wxART_HELP_SIDE_PANEL, )
78 ART(wxART_HELP_SETTINGS
, GTK_STOCK_SELECT_FONT
)
79 //ART(wxART_HELP_BOOK, )
80 ART(wxART_HELP_FOLDER
, GTK_STOCK_DIRECTORY
)
81 ART(wxART_HELP_PAGE
, GTK_STOCK_FILE
)
82 ART(wxART_MISSING_IMAGE
, GTK_STOCK_MISSING_IMAGE
)
83 ART(wxART_ADD_BOOKMARK
, GTK_STOCK_ADD
)
84 ART(wxART_DEL_BOOKMARK
, GTK_STOCK_REMOVE
)
85 ART(wxART_GO_BACK
, GTK_STOCK_GO_BACK
)
86 ART(wxART_GO_FORWARD
, GTK_STOCK_GO_FORWARD
)
87 ART(wxART_GO_UP
, GTK_STOCK_GO_UP
)
88 ART(wxART_GO_DOWN
, GTK_STOCK_GO_DOWN
)
89 ART(wxART_GO_TO_PARENT
, GTK_STOCK_GO_UP
)
90 ART(wxART_GO_HOME
, GTK_STOCK_HOME
)
91 ART(wxART_FILE_OPEN
, GTK_STOCK_OPEN
)
92 ART(wxART_PRINT
, GTK_STOCK_PRINT
)
93 ART(wxART_HELP
, GTK_STOCK_HELP
)
94 ART(wxART_TIP
, GTK_STOCK_DIALOG_INFO
)
95 //ART(wxART_REPORT_VIEW, )
96 //ART(wxART_LIST_VIEW, )
97 //ART(wxART_NEW_DIR, )
99 ART(wxART_FOLDER
, GTK_STOCK_DIRECTORY
)
100 ART(wxART_FOLDER_OPEN
, GTK_STOCK_DIRECTORY
)
102 //ART(wxART_GO_DIR_UP, )
103 ART(wxART_EXECUTABLE_FILE
, GTK_STOCK_EXECUTE
)
104 ART(wxART_NORMAL_FILE
, GTK_STOCK_FILE
)
105 ART(wxART_TICK_MARK
, GTK_STOCK_APPLY
)
106 ART(wxART_CROSS_MARK
, GTK_STOCK_CANCEL
)
109 ART(wxART_FLOPPY
, GTK_STOCK_FLOPPY
)
110 ART(wxART_CDROM
, GTK_STOCK_CDROM
)
111 ART(wxART_HARDDISK
, GTK_STOCK_HARDDISK
)
112 ART(wxART_REMOVABLE
, GTK_STOCK_HARDDISK
)
114 ART(wxART_FILE_SAVE
, GTK_STOCK_SAVE
)
115 ART(wxART_FILE_SAVE_AS
, GTK_STOCK_SAVE_AS
)
117 ART(wxART_COPY
, GTK_STOCK_COPY
)
118 ART(wxART_CUT
, GTK_STOCK_CUT
)
119 ART(wxART_PASTE
, GTK_STOCK_PASTE
)
120 ART(wxART_DELETE
, GTK_STOCK_DELETE
)
121 ART(wxART_NEW
, GTK_STOCK_NEW
)
123 ART(wxART_UNDO
, GTK_STOCK_UNDO
)
124 ART(wxART_REDO
, GTK_STOCK_REDO
)
126 ART(wxART_QUIT
, GTK_STOCK_QUIT
)
128 ART(wxART_FIND
, GTK_STOCK_FIND
)
129 ART(wxART_FIND_AND_REPLACE
, GTK_STOCK_FIND_AND_REPLACE
)
137 GtkIconSize
wxArtClientToIconSize(const wxArtClient
& client
)
139 if (client
== wxART_TOOLBAR
)
140 return GTK_ICON_SIZE_LARGE_TOOLBAR
;
141 else if (client
== wxART_MENU
)
142 return GTK_ICON_SIZE_MENU
;
143 else if (client
== wxART_CMN_DIALOG
|| client
== wxART_MESSAGE_BOX
)
144 return GTK_ICON_SIZE_DIALOG
;
145 else if (client
== wxART_BUTTON
)
146 return GTK_ICON_SIZE_BUTTON
;
148 return GTK_ICON_SIZE_INVALID
; // this is arbitrary
151 static GtkIconSize
FindClosestIconSize(const wxSize
& size
)
158 } s_sizes
[NUM_SIZES
];
159 static bool s_sizesInitialized
= false;
161 if (!s_sizesInitialized
)
163 s_sizes
[0].icon
= GTK_ICON_SIZE_MENU
;
164 s_sizes
[1].icon
= GTK_ICON_SIZE_SMALL_TOOLBAR
;
165 s_sizes
[2].icon
= GTK_ICON_SIZE_LARGE_TOOLBAR
;
166 s_sizes
[3].icon
= GTK_ICON_SIZE_BUTTON
;
167 s_sizes
[4].icon
= GTK_ICON_SIZE_DND
;
168 s_sizes
[5].icon
= GTK_ICON_SIZE_DIALOG
;
169 for (size_t i
= 0; i
< NUM_SIZES
; i
++)
171 gtk_icon_size_lookup(s_sizes
[i
].icon
,
172 &s_sizes
[i
].x
, &s_sizes
[i
].y
);
174 s_sizesInitialized
= true;
177 GtkIconSize best
= GTK_ICON_SIZE_DIALOG
; // presumably largest
178 unsigned distance
= INT_MAX
;
179 for (size_t i
= 0; i
< NUM_SIZES
; i
++)
181 // only use larger bitmaps, scaling down looks better than scaling up:
182 if (size
.x
> s_sizes
[i
].x
|| size
.y
> s_sizes
[i
].y
)
185 unsigned dist
= (size
.x
- s_sizes
[i
].x
) * (size
.x
- s_sizes
[i
].x
) +
186 (size
.y
- s_sizes
[i
].y
) * (size
.y
- s_sizes
[i
].y
);
188 return s_sizes
[i
].icon
;
189 else if (dist
< distance
)
192 best
= s_sizes
[i
].icon
;
199 static GtkStyle
*gs_gtkStyle
= NULL
;
201 static GdkPixbuf
*CreateStockIcon(const char *stockid
, GtkIconSize size
)
203 // FIXME: This code is not 100% correct, because stock pixmap are
204 // context-dependent and may be affected by theme engine, the
205 // correct value can only be obtained for given GtkWidget object.
207 // Fool-proof implementation of stock bitmaps would extend wxBitmap
208 // with "stock-id" representation (in addition to pixmap and pixbuf
209 // ones) and would convert it to pixbuf when rendered.
211 if (gs_gtkStyle
== NULL
)
213 GtkWidget
*widget
= gtk_button_new();
214 gs_gtkStyle
= gtk_rc_get_style(widget
);
215 wxASSERT( gs_gtkStyle
!= NULL
);
216 g_object_ref(gs_gtkStyle
);
217 gtk_object_sink((GtkObject
*)widget
);
220 GtkIconSet
*iconset
= gtk_style_lookup_icon_set(gs_gtkStyle
, stockid
);
225 return gtk_icon_set_render_icon(iconset
, gs_gtkStyle
,
226 gtk_widget_get_default_direction(),
227 GTK_STATE_NORMAL
, size
, NULL
, NULL
);
231 static GdkPixbuf
*CreateThemeIcon(const char *iconname
,
232 GtkIconSize iconsize
, const wxSize
& sz
)
235 if (size
== wxDefaultSize
)
237 gtk_icon_size_lookup(iconsize
, &size
.x
, &size
.y
);
240 return gtk_icon_theme_load_icon(
241 gtk_icon_theme_get_default(),
244 (GtkIconLookupFlags
)0, NULL
);
248 wxBitmap
wxGTK2ArtProvider::CreateBitmap(const wxArtID
& id
,
249 const wxArtClient
& client
,
252 wxCharBuffer stockid
= wxArtIDToStock(id
);
253 GtkIconSize stocksize
= (size
== wxDefaultSize
) ?
254 wxArtClientToIconSize(client
) :
255 FindClosestIconSize(size
);
257 // we must have some size, this is arbitrary
258 if (stocksize
== GTK_ICON_SIZE_INVALID
)
259 stocksize
= GTK_ICON_SIZE_BUTTON
;
261 // allow passing GTK+ stock IDs to wxArtProvider:
263 stockid
= id
.ToAscii();
265 GdkPixbuf
*pixbuf
= CreateStockIcon(stockid
, stocksize
);
268 if (!pixbuf
&& !gtk_check_version(2,4,0))
270 pixbuf
= CreateThemeIcon(stockid
, stocksize
, size
);
274 if (pixbuf
&& size
!= wxDefaultSize
&&
275 (size
.x
!= gdk_pixbuf_get_width(pixbuf
) ||
276 size
.y
!= gdk_pixbuf_get_height(pixbuf
)))
278 GdkPixbuf
*p2
= gdk_pixbuf_scale_simple(pixbuf
, size
.x
, size
.y
,
279 GDK_INTERP_BILINEAR
);
282 g_object_unref (pixbuf
);
289 bmp
.SetPixbuf(pixbuf
);
294 // ----------------------------------------------------------------------------
296 // ----------------------------------------------------------------------------
298 class wxArtGtkModule
: public wxModule
301 bool OnInit() { return true; }
306 g_object_unref(gs_gtkStyle
);
311 DECLARE_DYNAMIC_CLASS(wxArtGtkModule
)
314 IMPLEMENT_DYNAMIC_CLASS(wxArtGtkModule
, wxModule
)
316 #endif // !defined(__WXUNIVERSAL__)