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" 
  26 #include "wx/module.h" 
  30 // compatibility with older GTK+ versions: 
  31 #ifndef GTK_STOCK_FILE 
  32     #define GTK_STOCK_FILE "gtk-file" 
  34 #ifndef GTK_STOCK_DIRECTORY 
  35     #define GTK_STOCK_DIRECTORY "gtk-directory" 
  39 // ---------------------------------------------------------------------------- 
  41 // ---------------------------------------------------------------------------- 
  43 class wxGTK2ArtProvider 
: public wxArtProvider
 
  46     virtual wxBitmap 
CreateBitmap(const wxArtID
& id
, const wxArtClient
& client
, 
  50 /*static*/ void wxArtProvider::InitNativeProvider() 
  52     wxArtProvider::PushProvider(new wxGTK2ArtProvider
); 
  55 // ---------------------------------------------------------------------------- 
  56 // CreateBitmap routine 
  57 // ---------------------------------------------------------------------------- 
  59 static const char *wxArtIDToStock(const wxArtID
& id
) 
  61     #define ART(wxid, gtkid) \ 
  62            if (id == wxid) return gtkid; 
  64     ART(wxART_ERROR
,                               GTK_STOCK_DIALOG_ERROR
) 
  65     ART(wxART_INFORMATION
,                         GTK_STOCK_DIALOG_INFO
) 
  66     ART(wxART_WARNING
,                             GTK_STOCK_DIALOG_WARNING
) 
  67     ART(wxART_QUESTION
,                            GTK_STOCK_DIALOG_QUESTION
) 
  69     //ART(wxART_HELP_SIDE_PANEL,                     ) 
  70     ART(wxART_HELP_SETTINGS
,                       GTK_STOCK_SELECT_FONT
) 
  71     //ART(wxART_HELP_BOOK,                           ) 
  72     ART(wxART_HELP_FOLDER
,                         GTK_STOCK_DIRECTORY
) 
  73     ART(wxART_HELP_PAGE
,                           GTK_STOCK_FILE
) 
  74     ART(wxART_MISSING_IMAGE
,                       GTK_STOCK_MISSING_IMAGE
) 
  75     ART(wxART_ADD_BOOKMARK
,                        GTK_STOCK_ADD
) 
  76     ART(wxART_DEL_BOOKMARK
,                        GTK_STOCK_REMOVE
) 
  77     ART(wxART_GO_BACK
,                             GTK_STOCK_GO_BACK
) 
  78     ART(wxART_GO_FORWARD
,                          GTK_STOCK_GO_FORWARD
) 
  79     ART(wxART_GO_UP
,                               GTK_STOCK_GO_UP
) 
  80     ART(wxART_GO_DOWN
,                             GTK_STOCK_GO_DOWN
) 
  81     ART(wxART_GO_TO_PARENT
,                        GTK_STOCK_GO_UP
) 
  82     ART(wxART_GO_HOME
,                             GTK_STOCK_HOME
) 
  83     ART(wxART_FILE_OPEN
,                           GTK_STOCK_OPEN
) 
  84     ART(wxART_PRINT
,                               GTK_STOCK_PRINT
) 
  85     ART(wxART_HELP
,                                GTK_STOCK_HELP
) 
  86     ART(wxART_TIP
,                                 GTK_STOCK_DIALOG_INFO
) 
  87     //ART(wxART_REPORT_VIEW,                         ) 
  88     //ART(wxART_LIST_VIEW,                           ) 
  89     //ART(wxART_NEW_DIR,                             ) 
  91     ART(wxART_FOLDER
,                              GTK_STOCK_DIRECTORY
) 
  92     ART(wxART_FOLDER_OPEN
,                         GTK_STOCK_DIRECTORY
) 
  94     //ART(wxART_GO_DIR_UP,                           ) 
  95     ART(wxART_EXECUTABLE_FILE
,                     GTK_STOCK_EXECUTE
) 
  96     ART(wxART_NORMAL_FILE
,                         GTK_STOCK_FILE
) 
  97     ART(wxART_TICK_MARK
,                           GTK_STOCK_APPLY
) 
  98     ART(wxART_CROSS_MARK
,                          GTK_STOCK_CANCEL
) 
 101     ART(wxART_FLOPPY
,                              GTK_STOCK_FLOPPY
) 
 102     ART(wxART_CDROM
,                               GTK_STOCK_CDROM
) 
 103     ART(wxART_HARDDISK
,                            GTK_STOCK_HARDDISK
) 
 104     ART(wxART_REMOVABLE
,                           GTK_STOCK_HARDDISK
) 
 112 static GtkIconSize 
wxArtClientToIconSize(const wxArtClient
& client
) 
 114     if (client 
== wxART_TOOLBAR
) 
 115         return GTK_ICON_SIZE_LARGE_TOOLBAR
; 
 116     else if (client 
== wxART_MENU
) 
 117         return GTK_ICON_SIZE_MENU
; 
 118     else if (client 
== wxART_CMN_DIALOG 
|| client 
== wxART_MESSAGE_BOX
) 
 119         return GTK_ICON_SIZE_DIALOG
; 
 120     else if (client 
== wxART_BUTTON
) 
 121         return GTK_ICON_SIZE_BUTTON
; 
 123         return GTK_ICON_SIZE_BUTTON
; // this is arbitrary 
 126 static GtkIconSize 
FindClosestIconSize(const wxSize
& size
) 
 133     } s_sizes
[NUM_SIZES
]; 
 134     static bool s_sizesInitialized 
= false; 
 136     if (!s_sizesInitialized
) 
 138         s_sizes
[0].icon 
= GTK_ICON_SIZE_MENU
; 
 139         s_sizes
[1].icon 
= GTK_ICON_SIZE_SMALL_TOOLBAR
; 
 140         s_sizes
[2].icon 
= GTK_ICON_SIZE_LARGE_TOOLBAR
; 
 141         s_sizes
[3].icon 
= GTK_ICON_SIZE_BUTTON
; 
 142         s_sizes
[4].icon 
= GTK_ICON_SIZE_DND
; 
 143         s_sizes
[5].icon 
= GTK_ICON_SIZE_DIALOG
; 
 144         for (size_t i 
= 0; i 
< NUM_SIZES
; i
++) 
 146             gtk_icon_size_lookup(s_sizes
[i
].icon
, 
 147                                  &s_sizes
[i
].x
, &s_sizes
[i
].y
); 
 149         s_sizesInitialized 
= true; 
 152     GtkIconSize best 
= GTK_ICON_SIZE_DIALOG
; // presumably largest 
 153     unsigned distance 
= INT_MAX
; 
 154     for (size_t i 
= 0; i 
< NUM_SIZES
; i
++) 
 156         // only use larger bitmaps, scaling down looks better than scaling up: 
 157         if (size
.x 
> s_sizes
[i
].x 
|| size
.y 
> s_sizes
[i
].y
) 
 160         unsigned dist 
= (size
.x 
- s_sizes
[i
].x
) * (size
.x 
- s_sizes
[i
].x
) +  
 161                         (size
.y 
- s_sizes
[i
].y
) * (size
.y 
- s_sizes
[i
].y
); 
 163             return s_sizes
[i
].icon
; 
 164         else if (dist 
< distance
) 
 167             best 
= s_sizes
[i
].icon
; 
 174 static GtkStyle 
*gs_gtkStyle 
= NULL
; 
 176 static GdkPixbuf 
*CreateStockIcon(const char *stockid
, GtkIconSize size
) 
 178     // FIXME: This code is not 100% correct, because stock pixmap are 
 179     //        context-dependent and may be affected by theme engine, the 
 180     //        correct value can only be obtained for given GtkWidget object. 
 182     //        Fool-proof implementation of stock bitmaps would extend wxBitmap 
 183     //        with "stock-id" representation (in addition to pixmap and pixbuf 
 184     //        ones) and would convert it to pixbuf when rendered. 
 186     if (gs_gtkStyle 
== NULL
) 
 188         GtkWidget 
*widget 
= gtk_button_new(); 
 189         gs_gtkStyle 
= gtk_rc_get_style(widget
); 
 190         wxASSERT( gs_gtkStyle 
!= NULL 
); 
 191         g_object_ref(G_OBJECT(gs_gtkStyle
)); 
 192         gtk_widget_destroy(widget
); 
 195     GtkIconSet 
*iconset 
= gtk_style_lookup_icon_set(gs_gtkStyle
, stockid
); 
 200     return gtk_icon_set_render_icon(iconset
, gs_gtkStyle
, 
 201                                     gtk_widget_get_default_direction(), 
 202                                     GTK_STATE_NORMAL
, size
, NULL
, NULL
); 
 206 static GdkPixbuf 
*CreateThemeIcon(const char *iconname
, 
 207                                   GtkIconSize iconsize
, const wxSize
& sz
) 
 210     if (size 
== wxDefaultSize
) 
 212         gtk_icon_size_lookup(iconsize
, &size
.x
, &size
.y
); 
 215     return gtk_icon_theme_load_icon( 
 216                     gtk_icon_theme_get_default(), 
 219                     (GtkIconLookupFlags
)0, NULL
); 
 223 wxBitmap 
wxGTK2ArtProvider::CreateBitmap(const wxArtID
& id
, 
 224                                          const wxArtClient
& client
, 
 227     wxCharBuffer stockid 
= wxArtIDToStock(id
); 
 228     GtkIconSize stocksize 
= (size 
== wxDefaultSize
) ? 
 229                                 wxArtClientToIconSize(client
) :  
 230                                 FindClosestIconSize(size
); 
 232     // allow passing GTK+ stock IDs to wxArtProvider: 
 234         stockid 
= id
.ToAscii(); 
 236     GdkPixbuf 
*pixbuf 
= CreateStockIcon(stockid
, stocksize
); 
 239     if (!gtk_check_version(2,4,0)) 
 242             pixbuf 
= CreateThemeIcon(stockid
, stocksize
, size
); 
 246     if (pixbuf 
&& size 
!= wxDefaultSize 
&& 
 247         (size
.x 
!= gdk_pixbuf_get_width(pixbuf
) || 
 248          size
.y 
!= gdk_pixbuf_get_height(pixbuf
))) 
 250         GdkPixbuf 
*p2 
= gdk_pixbuf_scale_simple(pixbuf
, size
.x
, size
.y
, 
 251                                                 GDK_INTERP_BILINEAR
); 
 254             gdk_pixbuf_unref(pixbuf
); 
 263     bmp
.SetWidth(gdk_pixbuf_get_width(pixbuf
)); 
 264     bmp
.SetHeight(gdk_pixbuf_get_height(pixbuf
)); 
 265     bmp
.SetPixbuf(pixbuf
); 
 270 // ---------------------------------------------------------------------------- 
 272 // ---------------------------------------------------------------------------- 
 274 class wxArtGtkModule
: public wxModule
 
 277     bool OnInit() { return true; } 
 282             g_object_unref(G_OBJECT(gs_gtkStyle
)); 
 287     DECLARE_DYNAMIC_CLASS(wxArtGtkModule
) 
 290 IMPLEMENT_DYNAMIC_CLASS(wxArtGtkModule
, wxModule
) 
 292 #endif // defined(__WXGTK20__) && !defined(__WXUNIVERSAL__)