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
) 
 106     ART(wxART_FILE_SAVE
,                           GTK_STOCK_SAVE
) 
 107     ART(wxART_FILE_SAVE_AS
,                        GTK_STOCK_SAVE_AS
) 
 109     ART(wxART_COPY
,                                GTK_STOCK_COPY
) 
 110     ART(wxART_CUT
,                                 GTK_STOCK_CUT
) 
 111     ART(wxART_PASTE
,                               GTK_STOCK_PASTE
) 
 112     ART(wxART_DELETE
,                              GTK_STOCK_DELETE
) 
 114     ART(wxART_UNDO
,                                GTK_STOCK_UNDO
) 
 115     ART(wxART_REDO
,                                GTK_STOCK_REDO
) 
 117     ART(wxART_QUIT
,                                GTK_STOCK_QUIT
) 
 119     ART(wxART_FIND
,                                GTK_STOCK_FIND
) 
 120     ART(wxART_FIND_AND_REPLACE
,                    GTK_STOCK_FIND_AND_REPLACE
) 
 128 GtkIconSize 
wxArtClientToIconSize(const wxArtClient
& client
) 
 130     if (client 
== wxART_TOOLBAR
) 
 131         return GTK_ICON_SIZE_LARGE_TOOLBAR
; 
 132     else if (client 
== wxART_MENU
) 
 133         return GTK_ICON_SIZE_MENU
; 
 134     else if (client 
== wxART_CMN_DIALOG 
|| client 
== wxART_MESSAGE_BOX
) 
 135         return GTK_ICON_SIZE_DIALOG
; 
 136     else if (client 
== wxART_BUTTON
) 
 137         return GTK_ICON_SIZE_BUTTON
; 
 139         return GTK_ICON_SIZE_BUTTON
; // this is arbitrary 
 142 static GtkIconSize 
FindClosestIconSize(const wxSize
& size
) 
 149     } s_sizes
[NUM_SIZES
]; 
 150     static bool s_sizesInitialized 
= false; 
 152     if (!s_sizesInitialized
) 
 154         s_sizes
[0].icon 
= GTK_ICON_SIZE_MENU
; 
 155         s_sizes
[1].icon 
= GTK_ICON_SIZE_SMALL_TOOLBAR
; 
 156         s_sizes
[2].icon 
= GTK_ICON_SIZE_LARGE_TOOLBAR
; 
 157         s_sizes
[3].icon 
= GTK_ICON_SIZE_BUTTON
; 
 158         s_sizes
[4].icon 
= GTK_ICON_SIZE_DND
; 
 159         s_sizes
[5].icon 
= GTK_ICON_SIZE_DIALOG
; 
 160         for (size_t i 
= 0; i 
< NUM_SIZES
; i
++) 
 162             gtk_icon_size_lookup(s_sizes
[i
].icon
, 
 163                                  &s_sizes
[i
].x
, &s_sizes
[i
].y
); 
 165         s_sizesInitialized 
= true; 
 168     GtkIconSize best 
= GTK_ICON_SIZE_DIALOG
; // presumably largest 
 169     unsigned distance 
= INT_MAX
; 
 170     for (size_t i 
= 0; i 
< NUM_SIZES
; i
++) 
 172         // only use larger bitmaps, scaling down looks better than scaling up: 
 173         if (size
.x 
> s_sizes
[i
].x 
|| size
.y 
> s_sizes
[i
].y
) 
 176         unsigned dist 
= (size
.x 
- s_sizes
[i
].x
) * (size
.x 
- s_sizes
[i
].x
) +  
 177                         (size
.y 
- s_sizes
[i
].y
) * (size
.y 
- s_sizes
[i
].y
); 
 179             return s_sizes
[i
].icon
; 
 180         else if (dist 
< distance
) 
 183             best 
= s_sizes
[i
].icon
; 
 190 static GtkStyle 
*gs_gtkStyle 
= NULL
; 
 192 static GdkPixbuf 
*CreateStockIcon(const char *stockid
, GtkIconSize size
) 
 194     // FIXME: This code is not 100% correct, because stock pixmap are 
 195     //        context-dependent and may be affected by theme engine, the 
 196     //        correct value can only be obtained for given GtkWidget object. 
 198     //        Fool-proof implementation of stock bitmaps would extend wxBitmap 
 199     //        with "stock-id" representation (in addition to pixmap and pixbuf 
 200     //        ones) and would convert it to pixbuf when rendered. 
 202     if (gs_gtkStyle 
== NULL
) 
 204         GtkWidget 
*widget 
= gtk_button_new(); 
 205         gs_gtkStyle 
= gtk_rc_get_style(widget
); 
 206         wxASSERT( gs_gtkStyle 
!= NULL 
); 
 207         g_object_ref(G_OBJECT(gs_gtkStyle
)); 
 208         gtk_widget_destroy(widget
); 
 211     GtkIconSet 
*iconset 
= gtk_style_lookup_icon_set(gs_gtkStyle
, stockid
); 
 216     return gtk_icon_set_render_icon(iconset
, gs_gtkStyle
, 
 217                                     gtk_widget_get_default_direction(), 
 218                                     GTK_STATE_NORMAL
, size
, NULL
, NULL
); 
 222 static GdkPixbuf 
*CreateThemeIcon(const char *iconname
, 
 223                                   GtkIconSize iconsize
, const wxSize
& sz
) 
 226     if (size 
== wxDefaultSize
) 
 228         gtk_icon_size_lookup(iconsize
, &size
.x
, &size
.y
); 
 231     return gtk_icon_theme_load_icon( 
 232                     gtk_icon_theme_get_default(), 
 235                     (GtkIconLookupFlags
)0, NULL
); 
 239 wxBitmap 
wxGTK2ArtProvider::CreateBitmap(const wxArtID
& id
, 
 240                                          const wxArtClient
& client
, 
 243     wxCharBuffer stockid 
= wxArtIDToStock(id
); 
 244     GtkIconSize stocksize 
= (size 
== wxDefaultSize
) ? 
 245                                 wxArtClientToIconSize(client
) :  
 246                                 FindClosestIconSize(size
); 
 248     // allow passing GTK+ stock IDs to wxArtProvider: 
 250         stockid 
= id
.ToAscii(); 
 252     GdkPixbuf 
*pixbuf 
= CreateStockIcon(stockid
, stocksize
); 
 255     if (!gtk_check_version(2,4,0)) 
 258             pixbuf 
= CreateThemeIcon(stockid
, stocksize
, size
); 
 262     if (pixbuf 
&& size 
!= wxDefaultSize 
&& 
 263         (size
.x 
!= gdk_pixbuf_get_width(pixbuf
) || 
 264          size
.y 
!= gdk_pixbuf_get_height(pixbuf
))) 
 266         GdkPixbuf 
*p2 
= gdk_pixbuf_scale_simple(pixbuf
, size
.x
, size
.y
, 
 267                                                 GDK_INTERP_BILINEAR
); 
 270             gdk_pixbuf_unref(pixbuf
); 
 279     bmp
.SetWidth(gdk_pixbuf_get_width(pixbuf
)); 
 280     bmp
.SetHeight(gdk_pixbuf_get_height(pixbuf
)); 
 281     bmp
.SetPixbuf(pixbuf
); 
 286 // ---------------------------------------------------------------------------- 
 288 // ---------------------------------------------------------------------------- 
 290 class wxArtGtkModule
: public wxModule
 
 293     bool OnInit() { return true; } 
 298             g_object_unref(G_OBJECT(gs_gtkStyle
)); 
 303     DECLARE_DYNAMIC_CLASS(wxArtGtkModule
) 
 306 IMPLEMENT_DYNAMIC_CLASS(wxArtGtkModule
, wxModule
) 
 308 #endif // defined(__WXGTK20__) && !defined(__WXUNIVERSAL__)