source: trunk/gtk/icons.c @ 7999

Last change on this file since 7999 was 7999, checked in by charles, 13 years ago

(trunk gtk) maybe compile a little better for Lacrocivous

File size: 6.6 KB
Line 
1/*
2 * icons.[ch] written by Paolo Bacchilega, who writes:
3 * "There is no problem for me, you can license my code under whatever licence you wish :)"
4 */
5
6#include <glib.h>
7#include <gtk/gtk.h>
8#include "icons.h"
9
10#ifdef HAVE_GIO
11
12#include <gio/gio.h>
13
14#define VOID_PIXBUF_KEY "void-pixbuf"
15
16static GHashTable *static_strings = NULL;
17
18static const char *
19get_static_string( const char *s )
20{
21    const char *result;
22
23    if ( s == NULL )
24        return NULL;
25
26    if ( static_strings == NULL )
27        static_strings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
28
29    if ( ! g_hash_table_lookup_extended( static_strings, s, (gpointer) &result, NULL )) {
30        result = g_strdup( s );
31        g_hash_table_insert( static_strings,
32                             (gpointer) result,
33                             GINT_TO_POINTER( 1 ));
34    }
35
36    return result;
37}
38
39
40typedef struct {
41    GtkIconTheme * icon_theme;
42    int            icon_size;
43    GHashTable   * cache;
44} IconCache;
45
46
47static IconCache *icon_cache[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
48
49
50static GdkPixbuf*
51create_void_pixbuf (int width,
52                    int height)
53{
54    GdkPixbuf *p;
55
56    p = gdk_pixbuf_new( GDK_COLORSPACE_RGB,
57                        TRUE,
58                        8,
59                        width,
60                        height);
61    gdk_pixbuf_fill( p, 0xFFFFFF00 );
62
63    return p;
64}
65
66
67static int
68get_size_in_pixels( GtkWidget   * widget,
69                    GtkIconSize   icon_size )
70{
71    int width, height;
72
73    gtk_icon_size_lookup_for_settings( gtk_widget_get_settings( widget ),
74                                       icon_size,
75                                       &width, 
76                                       &height );
77    return MAX( width, height );
78}
79
80
81static IconCache * 
82icon_cache_new (GtkWidget * for_widget,
83                int         icon_size)
84{
85    IconCache * icon_cache;
86       
87    g_return_val_if_fail( for_widget != NULL, NULL );
88       
89    icon_cache = g_new0( IconCache, 1 );
90    icon_cache->icon_theme = gtk_icon_theme_get_for_screen( gtk_widget_get_screen( for_widget )); 
91    icon_cache->icon_size = get_size_in_pixels( for_widget, icon_size );
92    icon_cache->cache = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
93       
94    g_hash_table_insert( icon_cache->cache, (void*)VOID_PIXBUF_KEY, create_void_pixbuf( icon_cache->icon_size, icon_cache->icon_size ));
95       
96    return icon_cache;
97}
98
99static const char *
100_icon_cache_get_icon_key( GIcon * icon )
101{
102    const char * key = NULL;
103       
104    if ( G_IS_THEMED_ICON( icon )) {
105        char ** icon_names;
106        char  * name;
107       
108        g_object_get( icon, "names", &icon_names, NULL );
109        name = g_strjoinv( ",", icon_names );
110               
111        key = get_static_string( name );
112               
113        g_free( name );
114        g_strfreev( icon_names );       
115    }
116    else if ( G_IS_FILE_ICON( icon )) {
117        GFile * file;
118        char  * filename;
119
120        file = g_file_icon_get_file( G_FILE_ICON( icon ));
121        filename = g_file_get_path( file );
122               
123        key = get_static_string( filename );
124               
125        g_free( filename );
126        g_object_unref( file );
127    }
128       
129    return key;
130}
131
132
133static GdkPixbuf *
134get_themed_icon_pixbuf( GThemedIcon  *icon,
135                        int           size,
136                        GtkIconTheme *icon_theme )
137{
138    char        ** icon_names;
139    GtkIconInfo  * icon_info;
140    GdkPixbuf    * pixbuf;
141    GError       * error = NULL;
142
143    g_object_get( icon, "names", &icon_names, NULL );
144
145    icon_info = gtk_icon_theme_choose_icon( icon_theme, (const char **)icon_names, size, 0 );
146    if ( icon_info == NULL )
147        icon_info = gtk_icon_theme_lookup_icon( icon_theme, "text-x-generic", size, GTK_ICON_LOOKUP_USE_BUILTIN );
148
149    pixbuf = gtk_icon_info_load_icon( icon_info, &error );
150    if ( pixbuf == NULL ) {
151        g_warning( "could not load icon pixbuf: %s\n", error->message );
152        g_clear_error( &error );
153    }
154
155    gtk_icon_info_free( icon_info );
156    g_strfreev( icon_names );
157
158    return pixbuf;
159}
160
161
162static GdkPixbuf *
163get_file_icon_pixbuf( GFileIcon *icon,
164                      int        size )
165{
166    GFile     * file;
167    char      * filename;
168    GdkPixbuf * pixbuf;
169       
170    file = g_file_icon_get_file( icon );
171    filename = g_file_get_path( file );
172    pixbuf = gdk_pixbuf_new_from_file_at_size( filename, size, -1, NULL );
173    g_free( filename );
174    g_object_unref( file );
175       
176    return pixbuf;
177}
178
179
180static GdkPixbuf *
181_get_icon_pixbuf( GIcon        *icon,
182                  int           size,
183                  GtkIconTheme *theme )
184{
185    if ( icon == NULL )
186        return NULL;
187    if ( G_IS_THEMED_ICON (icon) )
188        return get_themed_icon_pixbuf( G_THEMED_ICON( icon ), size, theme );
189    if ( G_IS_FILE_ICON (icon) )
190        return get_file_icon_pixbuf( G_FILE_ICON( icon ), size );
191    return NULL;
192}
193
194                 
195static GdkPixbuf *
196icon_cache_get_mime_type_icon( IconCache  * icon_cache,
197                               const char * mime_type )
198{
199    GIcon      * icon;
200    const char * key = NULL;
201    GdkPixbuf  * pixbuf;
202
203    icon = g_content_type_get_icon( mime_type );
204    key = _icon_cache_get_icon_key( icon );
205       
206    if (key == NULL)
207        key = VOID_PIXBUF_KEY;
208
209    pixbuf = g_hash_table_lookup( icon_cache->cache, key );
210    if (pixbuf != NULL) {
211        g_object_ref( pixbuf );
212        return pixbuf;
213    }
214       
215    pixbuf = _get_icon_pixbuf( icon, icon_cache->icon_size, icon_cache->icon_theme );
216    g_hash_table_insert( icon_cache->cache, (gpointer) key, g_object_ref( pixbuf ));
217       
218    return pixbuf;
219}
220
221
222GdkPixbuf * 
223get_mime_type_icon( const char   * mime_type,
224                    GtkIconSize    icon_size,
225                    GtkWidget    * for_widget )
226{
227    int n;
228   
229    switch ( icon_size ) {
230        case GTK_ICON_SIZE_INVALID:       n = 0; break;
231        case GTK_ICON_SIZE_MENU:          n = 1; break;
232        case GTK_ICON_SIZE_SMALL_TOOLBAR: n = 2; break;
233        case GTK_ICON_SIZE_LARGE_TOOLBAR: n = 3; break;
234        case GTK_ICON_SIZE_BUTTON:        n = 4; break;
235        case GTK_ICON_SIZE_DND:           n = 5; break;
236        case GTK_ICON_SIZE_DIALOG:        n = 6; break; 
237    }   
238
239    if( icon_cache[n] == NULL )
240        icon_cache[n] = icon_cache_new( for_widget, icon_size );
241
242    return icon_cache_get_mime_type_icon( icon_cache[n], mime_type );
243}                   
244
245
246const char * 
247get_mime_type_from_filename( const char *file )
248{
249    return get_static_string( g_content_type_guess( file, NULL, 0, NULL ));
250}
251
252#else
253
254GdkPixbuf * 
255get_mime_type_icon( const char   * mime_type,
256                    GtkIconSize    icon_size,
257                    GtkWidget    * for_widget )
258{
259    return NULL;
260}                   
261
262
263const char * 
264get_mime_type_from_filename( const char *file )
265{
266    return "uncertain";
267}
268
269#endif
Note: See TracBrowser for help on using the repository browser.