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" 
  26 #include "wx/gtk/private.h" 
  28 // compatibility with older GTK+ versions: 
  29 #ifndef GTK_STOCK_FILE 
  30     #define GTK_STOCK_FILE "gtk-file" 
  32 #ifndef GTK_STOCK_DIRECTORY 
  33     #define GTK_STOCK_DIRECTORY "gtk-directory" 
  37 // ---------------------------------------------------------------------------- 
  39 // ---------------------------------------------------------------------------- 
  41 class wxGTK2ArtProvider 
: public wxArtProvider
 
  44     virtual wxBitmap 
CreateBitmap(const wxArtID
& id
, const wxArtClient
& client
, 
  48 /*static*/ void wxArtProvider::InitNativeProvider() 
  50     Push(new wxGTK2ArtProvider
); 
  53 // ---------------------------------------------------------------------------- 
  54 // CreateBitmap routine 
  55 // ---------------------------------------------------------------------------- 
  57 static const char *wxArtIDToStock(const wxArtID
& id
) 
  59     #define ART(wxid, gtkid) \ 
  60            if (id == wxid) return gtkid; 
  62     ART(wxART_ERROR
,                               GTK_STOCK_DIALOG_ERROR
) 
  63     ART(wxART_INFORMATION
,                         GTK_STOCK_DIALOG_INFO
) 
  64     ART(wxART_WARNING
,                             GTK_STOCK_DIALOG_WARNING
) 
  65     ART(wxART_QUESTION
,                            GTK_STOCK_DIALOG_QUESTION
) 
  67     //ART(wxART_HELP_SIDE_PANEL,                     ) 
  68     ART(wxART_HELP_SETTINGS
,                       GTK_STOCK_SELECT_FONT
) 
  69     //ART(wxART_HELP_BOOK,                           ) 
  70     ART(wxART_HELP_FOLDER
,                         GTK_STOCK_DIRECTORY
) 
  71     ART(wxART_HELP_PAGE
,                           GTK_STOCK_FILE
) 
  72     ART(wxART_MISSING_IMAGE
,                       GTK_STOCK_MISSING_IMAGE
) 
  73     ART(wxART_ADD_BOOKMARK
,                        GTK_STOCK_ADD
) 
  74     ART(wxART_DEL_BOOKMARK
,                        GTK_STOCK_REMOVE
) 
  75     ART(wxART_GO_BACK
,                             GTK_STOCK_GO_BACK
) 
  76     ART(wxART_GO_FORWARD
,                          GTK_STOCK_GO_FORWARD
) 
  77     ART(wxART_GO_UP
,                               GTK_STOCK_GO_UP
) 
  78     ART(wxART_GO_DOWN
,                             GTK_STOCK_GO_DOWN
) 
  79     ART(wxART_GO_TO_PARENT
,                        GTK_STOCK_GO_UP
) 
  80     ART(wxART_GO_HOME
,                             GTK_STOCK_HOME
) 
  81     ART(wxART_FILE_OPEN
,                           GTK_STOCK_OPEN
) 
  82     ART(wxART_PRINT
,                               GTK_STOCK_PRINT
) 
  83     ART(wxART_HELP
,                                GTK_STOCK_HELP
) 
  84     ART(wxART_TIP
,                                 GTK_STOCK_DIALOG_INFO
) 
  85     //ART(wxART_REPORT_VIEW,                         ) 
  86     //ART(wxART_LIST_VIEW,                           ) 
  87     //ART(wxART_NEW_DIR,                             ) 
  88     ART(wxART_FOLDER
,                              GTK_STOCK_DIRECTORY
) 
  89     ART(wxART_FOLDER_OPEN
,                         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
) 
  96     ART(wxART_FLOPPY
,                              GTK_STOCK_FLOPPY
) 
  97     ART(wxART_CDROM
,                               GTK_STOCK_CDROM
) 
  98     ART(wxART_HARDDISK
,                            GTK_STOCK_HARDDISK
) 
  99     ART(wxART_REMOVABLE
,                           GTK_STOCK_HARDDISK
) 
 101     ART(wxART_FILE_SAVE
,                           GTK_STOCK_SAVE
) 
 102     ART(wxART_FILE_SAVE_AS
,                        GTK_STOCK_SAVE_AS
) 
 104     ART(wxART_COPY
,                                GTK_STOCK_COPY
) 
 105     ART(wxART_CUT
,                                 GTK_STOCK_CUT
) 
 106     ART(wxART_PASTE
,                               GTK_STOCK_PASTE
) 
 107     ART(wxART_DELETE
,                              GTK_STOCK_DELETE
) 
 108     ART(wxART_NEW
,                                 GTK_STOCK_NEW
) 
 110     ART(wxART_UNDO
,                                GTK_STOCK_UNDO
) 
 111     ART(wxART_REDO
,                                GTK_STOCK_REDO
) 
 113     ART(wxART_QUIT
,                                GTK_STOCK_QUIT
) 
 115     ART(wxART_FIND
,                                GTK_STOCK_FIND
) 
 116     ART(wxART_FIND_AND_REPLACE
,                    GTK_STOCK_FIND_AND_REPLACE
) 
 123 GtkIconSize 
wxArtClientToIconSize(const wxArtClient
& client
) 
 125     if (client 
== wxART_TOOLBAR
) 
 126         return GTK_ICON_SIZE_LARGE_TOOLBAR
; 
 127     else if (client 
== wxART_MENU
) 
 128         return GTK_ICON_SIZE_MENU
; 
 129     else if (client 
== wxART_CMN_DIALOG 
|| client 
== wxART_MESSAGE_BOX
) 
 130         return GTK_ICON_SIZE_DIALOG
; 
 131     else if (client 
== wxART_BUTTON
) 
 132         return GTK_ICON_SIZE_BUTTON
; 
 134         return GTK_ICON_SIZE_INVALID
; // this is arbitrary 
 137 static GtkIconSize 
FindClosestIconSize(const wxSize
& size
) 
 144     } s_sizes
[NUM_SIZES
]; 
 145     static bool s_sizesInitialized 
= false; 
 147     if (!s_sizesInitialized
) 
 149         s_sizes
[0].icon 
= GTK_ICON_SIZE_MENU
; 
 150         s_sizes
[1].icon 
= GTK_ICON_SIZE_SMALL_TOOLBAR
; 
 151         s_sizes
[2].icon 
= GTK_ICON_SIZE_LARGE_TOOLBAR
; 
 152         s_sizes
[3].icon 
= GTK_ICON_SIZE_BUTTON
; 
 153         s_sizes
[4].icon 
= GTK_ICON_SIZE_DND
; 
 154         s_sizes
[5].icon 
= GTK_ICON_SIZE_DIALOG
; 
 155         for (size_t i 
= 0; i 
< NUM_SIZES
; i
++) 
 157             gtk_icon_size_lookup(s_sizes
[i
].icon
, 
 158                                  &s_sizes
[i
].x
, &s_sizes
[i
].y
); 
 160         s_sizesInitialized 
= true; 
 163     GtkIconSize best 
= GTK_ICON_SIZE_DIALOG
; // presumably largest 
 164     unsigned distance 
= INT_MAX
; 
 165     for (size_t i 
= 0; i 
< NUM_SIZES
; i
++) 
 167         // only use larger bitmaps, scaling down looks better than scaling up: 
 168         if (size
.x 
> s_sizes
[i
].x 
|| size
.y 
> s_sizes
[i
].y
) 
 171         unsigned dist 
= (size
.x 
- s_sizes
[i
].x
) * (size
.x 
- s_sizes
[i
].x
) + 
 172                         (size
.y 
- s_sizes
[i
].y
) * (size
.y 
- s_sizes
[i
].y
); 
 174             return s_sizes
[i
].icon
; 
 175         else if (dist 
< distance
) 
 178             best 
= s_sizes
[i
].icon
; 
 184 static GdkPixbuf 
*CreateStockIcon(const char *stockid
, GtkIconSize size
) 
 186     // FIXME: This code is not 100% correct, because stock pixmap are 
 187     //        context-dependent and may be affected by theme engine, the 
 188     //        correct value can only be obtained for given GtkWidget object. 
 190     //        Fool-proof implementation of stock bitmaps would extend wxBitmap 
 191     //        with "stock-id" representation (in addition to pixmap and pixbuf 
 192     //        ones) and would convert it to pixbuf when rendered. 
 194     GtkStyle
* style 
= wxGTKPrivate::GetButtonWidget()->style
; 
 195     GtkIconSet
* iconset 
= gtk_style_lookup_icon_set(style
, stockid
); 
 200     return gtk_icon_set_render_icon(iconset
, style
, 
 201                                     gtk_widget_get_default_direction(), 
 202                                     GTK_STATE_NORMAL
, size
, NULL
, NULL
); 
 205 static GdkPixbuf 
*CreateThemeIcon(const char *iconname
, 
 206                                   GtkIconSize iconsize
, const wxSize
& sz
) 
 209     if (size 
== wxDefaultSize
) 
 211         gtk_icon_size_lookup(iconsize
, &size
.x
, &size
.y
); 
 214     return gtk_icon_theme_load_icon( 
 215                     gtk_icon_theme_get_default(), 
 218                     (GtkIconLookupFlags
)0, NULL
); 
 221 wxBitmap 
wxGTK2ArtProvider::CreateBitmap(const wxArtID
& id
, 
 222                                          const wxArtClient
& client
, 
 225     wxCharBuffer stockid 
= wxArtIDToStock(id
); 
 226     GtkIconSize stocksize 
= (size 
== wxDefaultSize
) ? 
 227                                 wxArtClientToIconSize(client
) : 
 228                                 FindClosestIconSize(size
); 
 230     // we must have some size, this is arbitrary 
 231     if (stocksize 
== GTK_ICON_SIZE_INVALID
) 
 232         stocksize 
= GTK_ICON_SIZE_BUTTON
; 
 234     // allow passing GTK+ stock IDs to wxArtProvider: 
 236         stockid 
= id
.ToAscii(); 
 238     GdkPixbuf 
*pixbuf 
= CreateStockIcon(stockid
, stocksize
); 
 240         pixbuf 
= CreateThemeIcon(stockid
, stocksize
, size
); 
 242     if (pixbuf 
&& size 
!= wxDefaultSize 
&& 
 243         (size
.x 
!= gdk_pixbuf_get_width(pixbuf
) || 
 244          size
.y 
!= gdk_pixbuf_get_height(pixbuf
))) 
 246         GdkPixbuf 
*p2 
= gdk_pixbuf_scale_simple(pixbuf
, size
.x
, size
.y
, 
 247                                                 GDK_INTERP_BILINEAR
); 
 250             g_object_unref (pixbuf
); 
 257         bmp
.SetPixbuf(pixbuf
); 
 262 #endif // !defined(__WXUNIVERSAL__)