1 /* -*- Mode: C; indent-tabs-mode: f; c-basic-offset: 4; tab-width: 4 -*- */
2 /* nemo-icon-info.c
3 * Copyright (C) 2007 Red Hat, Inc., Alexander Larsson <alexl@redhat.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin Street - Suite 500,
18 * Boston, MA 02110-1335, USA.
19 */
20
21 #include <config.h>
22 #include <string.h>
23 #include "nemo-icon-info.h"
24 #include "nemo-icon-names.h"
25 #include "nemo-default-file-icon.h"
26 #include <gtk/gtk.h>
27 #include <gio/gio.h>
28
29 static void schedule_reap_cache (void);
30
31 static void
pixbuf_toggle_notify(gpointer info,GObject * object,gboolean is_last_ref)32 pixbuf_toggle_notify (gpointer info,
33 GObject *object,
34 gboolean is_last_ref)
35 {
36 NemoIconInfo *icon = info;
37
38 if (is_last_ref) {
39 icon->sole_owner = TRUE;
40 g_object_remove_toggle_ref (object,
41 pixbuf_toggle_notify,
42 info);
43 icon->last_use_time = g_get_monotonic_time ();
44 schedule_reap_cache ();
45 }
46 }
47
48 static void
nemo_icon_info_free(NemoIconInfo * icon)49 nemo_icon_info_free (NemoIconInfo *icon)
50 {
51 g_return_if_fail (icon != NULL);
52
53 if (!icon->sole_owner && icon->pixbuf) {
54 g_object_remove_toggle_ref (G_OBJECT (icon->pixbuf),
55 pixbuf_toggle_notify,
56 icon);
57 }
58
59 if (icon->pixbuf) {
60 g_object_unref (icon->pixbuf);
61 }
62
63 g_free (icon->icon_name);
64
65 g_slice_free (NemoIconInfo, icon);
66 }
67
68 NemoIconInfo *
nemo_icon_info_ref(NemoIconInfo * icon)69 nemo_icon_info_ref (NemoIconInfo *icon)
70 {
71 g_return_val_if_fail (icon != NULL, NULL);
72
73 icon->ref_count++;
74
75 return icon;
76 }
77
78 void
nemo_icon_info_unref(NemoIconInfo * icon)79 nemo_icon_info_unref (NemoIconInfo *icon)
80 {
81 g_return_if_fail (icon != NULL);
82 g_return_if_fail (icon->ref_count > 0);
83
84 icon->ref_count--;
85
86 if (icon->ref_count == 0) {
87 nemo_icon_info_free (icon);
88 }
89 }
90
91 void
nemo_icon_info_clear(NemoIconInfo ** info)92 nemo_icon_info_clear (NemoIconInfo **info)
93 {
94 gpointer _info;
95
96 _info = *info;
97
98 if (_info) {
99 *info = NULL;
100 nemo_icon_info_unref (_info);
101 }
102 }
103
104 static NemoIconInfo *
nemo_icon_info_create(void)105 nemo_icon_info_create (void)
106 {
107 NemoIconInfo *icon;
108
109 icon = g_slice_new0 (NemoIconInfo);
110
111 icon->last_use_time = g_get_monotonic_time ();
112 icon->sole_owner = TRUE;
113 icon->ref_count = 1;
114
115 return icon;
116 }
117
118 gboolean
nemo_icon_info_is_fallback(NemoIconInfo * icon)119 nemo_icon_info_is_fallback (NemoIconInfo *icon)
120 {
121 return icon->pixbuf == NULL;
122 }
123
124 NemoIconInfo *
nemo_icon_info_new_for_pixbuf(GdkPixbuf * pixbuf,gint scale)125 nemo_icon_info_new_for_pixbuf (GdkPixbuf *pixbuf,
126 gint scale)
127 {
128 NemoIconInfo *icon;
129
130 icon = nemo_icon_info_create ();
131
132 if (pixbuf) {
133 icon->pixbuf = g_object_ref (pixbuf);
134 }
135
136 icon->orig_scale = scale;
137
138 return icon;
139 }
140
141 static NemoIconInfo *
nemo_icon_info_new_for_icon_info(GtkIconInfo * icon_info,gint scale)142 nemo_icon_info_new_for_icon_info (GtkIconInfo *icon_info,
143 gint scale)
144 {
145 NemoIconInfo *icon;
146 const char *filename;
147 char *basename, *p;
148
149 icon = nemo_icon_info_create ();
150
151 icon->pixbuf = gtk_icon_info_load_icon (icon_info, NULL);
152
153 filename = gtk_icon_info_get_filename (icon_info);
154 if (filename != NULL) {
155 basename = g_path_get_basename (filename);
156 p = strrchr (basename, '.');
157 if (p) {
158 *p = 0;
159 }
160 icon->icon_name = basename;
161 }
162
163 icon->orig_scale = scale;
164
165 return icon;
166 }
167
168
169 typedef struct {
170 GIcon *icon;
171 int size;
172 } IconKey;
173
174 static GHashTable *loadable_icon_cache = NULL;
175 static GHashTable *themed_icon_cache = NULL;
176 static guint reap_cache_timeout = 0;
177
178 #define MICROSEC_PER_SEC ((guint64)1000000L)
179
180 static guint time_now;
181
182 static gboolean
reap_old_icon(gpointer key,gpointer value,gpointer user_info)183 reap_old_icon (gpointer key,
184 gpointer value,
185 gpointer user_info)
186 {
187 NemoIconInfo *icon = value;
188 gboolean *reapable_icons_left = user_info;
189
190 if (icon->sole_owner) {
191 if (time_now - icon->last_use_time > (gint64)(30 * MICROSEC_PER_SEC)) {
192 /* This went unused 30 secs ago. reap */
193 return TRUE;
194 } else {
195 /* We can reap this soon */
196 *reapable_icons_left = TRUE;
197 }
198 }
199
200 return FALSE;
201 }
202
203 static gboolean
reap_cache(gpointer data)204 reap_cache (gpointer data)
205 {
206 gboolean reapable_icons_left;
207
208 reapable_icons_left = TRUE;
209
210 time_now = g_get_monotonic_time ();
211
212 if (loadable_icon_cache) {
213 g_hash_table_foreach_remove (loadable_icon_cache,
214 reap_old_icon,
215 &reapable_icons_left);
216 }
217
218 if (themed_icon_cache) {
219 g_hash_table_foreach_remove (themed_icon_cache,
220 reap_old_icon,
221 &reapable_icons_left);
222 }
223
224 if (reapable_icons_left) {
225 return TRUE;
226 } else {
227 reap_cache_timeout = 0;
228 return FALSE;
229 }
230 }
231
232 static void
schedule_reap_cache(void)233 schedule_reap_cache (void)
234 {
235 if (reap_cache_timeout == 0) {
236 reap_cache_timeout = g_timeout_add_seconds_full (0, 5,
237 reap_cache,
238 NULL, NULL);
239 }
240 }
241
242 void
nemo_icon_info_clear_caches(void)243 nemo_icon_info_clear_caches (void)
244 {
245 if (loadable_icon_cache) {
246 g_hash_table_remove_all (loadable_icon_cache);
247 }
248
249 if (themed_icon_cache) {
250 g_hash_table_remove_all (themed_icon_cache);
251 }
252 }
253
254 static guint
icon_key_hash(IconKey * key)255 icon_key_hash (IconKey *key)
256 {
257 return g_icon_hash (key->icon) ^ key->size;
258 }
259
260 static gboolean
icon_key_equal(const IconKey * a,const IconKey * b)261 icon_key_equal (const IconKey *a,
262 const IconKey *b)
263 {
264 return a->size == b->size &&
265 g_icon_equal (a->icon, b->icon);
266 }
267
268 static IconKey *
icon_key_new(GIcon * icon,int size)269 icon_key_new (GIcon *icon, int size)
270 {
271 IconKey *key;
272
273 key = g_slice_new (IconKey);
274 key->icon = g_object_ref (icon);
275 key->size = size;
276
277 return key;
278 }
279
280 static void
icon_key_free(IconKey * key)281 icon_key_free (IconKey *key)
282 {
283 g_object_unref (key->icon);
284 g_slice_free (IconKey, key);
285 }
286
287 NemoIconInfo *
nemo_icon_info_lookup(GIcon * icon,int size,int scale)288 nemo_icon_info_lookup (GIcon *icon,
289 int size,
290 int scale)
291 {
292 GtkIconTheme *icon_theme;
293 GtkIconInfo *gtkicon_info;
294
295 NemoIconInfo *icon_info;
296
297 icon_theme = gtk_icon_theme_get_default ();
298
299 if (G_IS_LOADABLE_ICON (icon)) {
300 GdkPixbuf *pixbuf;
301
302 IconKey lookup_key;
303 IconKey *key;
304 GInputStream *stream;
305
306 if (loadable_icon_cache == NULL) {
307 loadable_icon_cache = g_hash_table_new_full ((GHashFunc) icon_key_hash,
308 (GEqualFunc) icon_key_equal,
309 (GDestroyNotify) icon_key_free,
310 (GDestroyNotify) nemo_icon_info_free);
311 }
312
313 lookup_key.icon = icon;
314 lookup_key.size = size;
315
316 icon_info = g_hash_table_lookup (loadable_icon_cache, &lookup_key);
317 if (icon_info) {
318 return nemo_icon_info_ref (icon_info);
319 }
320
321 pixbuf = NULL;
322 stream = g_loadable_icon_load (G_LOADABLE_ICON (icon),
323 size * scale,
324 NULL, NULL, NULL);
325
326 if (stream) {
327 pixbuf = gdk_pixbuf_new_from_stream_at_scale (stream,
328 size * scale, size * scale,
329 TRUE,
330 NULL, NULL);
331 g_input_stream_close (stream, NULL, NULL);
332 g_object_unref (stream);
333 }
334
335 if (!pixbuf) {
336 gtkicon_info = gtk_icon_theme_lookup_icon_for_scale (icon_theme,
337 "text-x-generic",
338 size,
339 scale,
340 GTK_ICON_LOOKUP_FORCE_SIZE);
341
342 pixbuf = gtk_icon_info_load_icon (gtkicon_info, NULL);
343 }
344
345 icon_info = nemo_icon_info_new_for_pixbuf (pixbuf, scale);
346
347 key = icon_key_new (icon, size);
348 g_hash_table_insert (loadable_icon_cache, key, icon_info);
349
350 g_clear_object (&pixbuf);
351
352 return nemo_icon_info_ref (icon_info);
353 } else {
354 IconKey lookup_key;
355 IconKey *key;
356
357 if (themed_icon_cache == NULL) {
358 themed_icon_cache = g_hash_table_new_full ((GHashFunc) icon_key_hash,
359 (GEqualFunc) icon_key_equal,
360 (GDestroyNotify) icon_key_free,
361 (GDestroyNotify) nemo_icon_info_free);
362 }
363
364 lookup_key.icon = icon;
365 lookup_key.size = size;
366
367 icon_info = g_hash_table_lookup (themed_icon_cache, &lookup_key);
368 if (icon_info) {
369 return nemo_icon_info_ref (icon_info);
370 }
371
372 gtkicon_info = NULL;
373
374 gtkicon_info = gtk_icon_theme_lookup_by_gicon_for_scale (icon_theme,
375 icon,
376 size,
377 scale,
378 GTK_ICON_LOOKUP_FORCE_SIZE);
379
380 if (!gtkicon_info) {
381 gtkicon_info = gtk_icon_theme_lookup_icon_for_scale (icon_theme,
382 "text-x-generic",
383 size,
384 scale,
385 GTK_ICON_LOOKUP_FORCE_SIZE);
386 }
387
388 icon_info = nemo_icon_info_new_for_icon_info (gtkicon_info, scale);
389 g_object_unref (gtkicon_info);
390
391 key = icon_key_new (icon, size);
392 g_hash_table_insert (themed_icon_cache, key, icon_info);
393
394 return nemo_icon_info_ref (icon_info);
395 }
396 }
397
398 NemoIconInfo *
nemo_icon_info_lookup_from_name(const char * name,int size,int scale)399 nemo_icon_info_lookup_from_name (const char *name,
400 int size,
401 int scale)
402 {
403 GIcon *icon;
404 NemoIconInfo *info;
405
406 icon = g_themed_icon_new (name);
407 info = nemo_icon_info_lookup (icon, size, scale);
408 g_object_unref (icon);
409 return info;
410 }
411
412 NemoIconInfo *
nemo_icon_info_lookup_from_path(const char * path,int size,int scale)413 nemo_icon_info_lookup_from_path (const char *path,
414 int size,
415 int scale)
416 {
417 GFile *icon_file;
418 GIcon *icon;
419 NemoIconInfo *info;
420
421 icon_file = g_file_new_for_path (path);
422 icon = g_file_icon_new (icon_file);
423 info = nemo_icon_info_lookup (icon, size, scale);
424 g_object_unref (icon);
425 g_object_unref (icon_file);
426 return info;
427 }
428
429 GdkPixbuf *
nemo_icon_info_get_pixbuf_nodefault(NemoIconInfo * icon)430 nemo_icon_info_get_pixbuf_nodefault (NemoIconInfo *icon)
431 {
432 GdkPixbuf *res;
433
434 if (icon->pixbuf == NULL) {
435 res = NULL;
436 } else {
437 res = g_object_ref (icon->pixbuf);
438
439 if (icon->sole_owner) {
440 icon->sole_owner = FALSE;
441 g_object_add_toggle_ref (G_OBJECT (res),
442 pixbuf_toggle_notify,
443 icon);
444 }
445 }
446
447 return res;
448 }
449
450
451 GdkPixbuf *
nemo_icon_info_get_pixbuf(NemoIconInfo * icon)452 nemo_icon_info_get_pixbuf (NemoIconInfo *icon)
453 {
454 GdkPixbuf *res;
455
456 res = nemo_icon_info_get_pixbuf_nodefault (icon);
457 if (res == NULL) {
458 res = gdk_pixbuf_new_from_data (nemo_default_file_icon,
459 GDK_COLORSPACE_RGB,
460 TRUE,
461 8,
462 nemo_default_file_icon_width,
463 nemo_default_file_icon_height,
464 nemo_default_file_icon_width * 4, /* stride */
465 NULL, /* don't destroy info */
466 NULL);
467 }
468
469 return res;
470 }
471
472 GdkPixbuf *
nemo_icon_info_get_pixbuf_nodefault_at_size(NemoIconInfo * icon,gsize forced_size)473 nemo_icon_info_get_pixbuf_nodefault_at_size (NemoIconInfo *icon,
474 gsize forced_size)
475 {
476 GdkPixbuf *pixbuf, *scaled_pixbuf;
477 guint w, h, s;
478 double scale;
479
480 pixbuf = nemo_icon_info_get_pixbuf_nodefault (icon);
481
482 if (pixbuf == NULL)
483 return NULL;
484
485 w = gdk_pixbuf_get_width (pixbuf) / icon->orig_scale;
486 h = gdk_pixbuf_get_height (pixbuf) / icon->orig_scale;
487 s = MAX (w, h);
488 if (s == forced_size) {
489 return pixbuf;
490 }
491
492 scale = (double)forced_size / s;
493 scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf,
494 MAX (w * scale, 1), MAX (h * scale, 1),
495 GDK_INTERP_BILINEAR);
496 g_object_unref (pixbuf);
497 return scaled_pixbuf;
498 }
499
500
501 GdkPixbuf *
nemo_icon_info_get_pixbuf_at_size(NemoIconInfo * icon,gsize forced_size)502 nemo_icon_info_get_pixbuf_at_size (NemoIconInfo *icon,
503 gsize forced_size)
504 {
505 GdkPixbuf *pixbuf, *scaled_pixbuf;
506 guint w, h, s;
507 double scale;
508
509 pixbuf = nemo_icon_info_get_pixbuf (icon);
510
511 w = gdk_pixbuf_get_width (pixbuf) / icon->orig_scale;
512 h = gdk_pixbuf_get_height (pixbuf) / icon->orig_scale;
513 s = MAX (w, h);
514 if (s == forced_size) {
515 return pixbuf;
516 }
517
518 scale = (double)forced_size / s;
519 scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf,
520 MAX (w * scale, 1), MAX (h * scale, 1),
521 GDK_INTERP_BILINEAR);
522 g_object_unref (pixbuf);
523 return scaled_pixbuf;
524 }
525
526 GdkPixbuf *
nemo_icon_info_get_desktop_pixbuf_at_size(NemoIconInfo * icon,gsize max_height,gsize max_width)527 nemo_icon_info_get_desktop_pixbuf_at_size (NemoIconInfo *icon,
528 gsize max_height,
529 gsize max_width)
530 {
531 GdkPixbuf *pixbuf, *scaled_pixbuf;
532 guint w, h;
533 double scale;
534
535 pixbuf = nemo_icon_info_get_pixbuf (icon);
536
537 w = gdk_pixbuf_get_width (pixbuf) / icon->orig_scale;
538 h = gdk_pixbuf_get_height (pixbuf) / icon->orig_scale;
539
540 if (w == max_width || h == max_height) {
541 return pixbuf;
542 }
543
544 scale = (gdouble) max_height / h;
545
546 if (w * scale > max_width) {
547 scale = (gdouble) max_width / w;
548 }
549
550 scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf,
551 MAX (w * scale, 1), MAX (h * scale, 1),
552 GDK_INTERP_BILINEAR);
553 g_object_unref (pixbuf);
554 return scaled_pixbuf;
555 }
556
557 const char *
nemo_icon_info_get_used_name(NemoIconInfo * icon)558 nemo_icon_info_get_used_name (NemoIconInfo *icon)
559 {
560 return icon->icon_name;
561 }
562
563 /* Return nominal icon size for given zoom level.
564 * @zoom_level: zoom level for which to find matching icon size.
565 *
566 * Return value: icon size between NEMO_ICON_SIZE_SMALLEST and
567 * NEMO_ICON_SIZE_LARGEST, inclusive.
568 */
569 guint
nemo_get_icon_size_for_zoom_level(NemoZoomLevel zoom_level)570 nemo_get_icon_size_for_zoom_level (NemoZoomLevel zoom_level)
571 {
572 switch (zoom_level) {
573 case NEMO_ZOOM_LEVEL_SMALLEST:
574 return NEMO_ICON_SIZE_SMALLEST;
575 case NEMO_ZOOM_LEVEL_SMALLER:
576 return NEMO_ICON_SIZE_SMALLER;
577 case NEMO_ZOOM_LEVEL_SMALL:
578 return NEMO_ICON_SIZE_SMALL;
579 case NEMO_ZOOM_LEVEL_STANDARD:
580 return NEMO_ICON_SIZE_STANDARD;
581 case NEMO_ZOOM_LEVEL_LARGE:
582 return NEMO_ICON_SIZE_LARGE;
583 case NEMO_ZOOM_LEVEL_LARGER:
584 return NEMO_ICON_SIZE_LARGER;
585 case NEMO_ZOOM_LEVEL_LARGEST:
586 return NEMO_ICON_SIZE_LARGEST;
587 case NEMO_ZOOM_LEVEL_NULL:
588 default:
589 g_return_val_if_reached (NEMO_ICON_SIZE_STANDARD);
590 }
591 }
592
593 guint
nemo_get_icon_text_width_for_zoom_level(NemoZoomLevel zoom_level)594 nemo_get_icon_text_width_for_zoom_level (NemoZoomLevel zoom_level)
595 {
596 switch (zoom_level) {
597 case NEMO_ZOOM_LEVEL_SMALLEST:
598 return NEMO_ICON_TEXT_WIDTH_SMALLEST;
599 case NEMO_ZOOM_LEVEL_SMALLER:
600 return NEMO_ICON_TEXT_WIDTH_SMALLER;
601 case NEMO_ZOOM_LEVEL_SMALL:
602 return NEMO_ICON_TEXT_WIDTH_SMALL;
603 case NEMO_ZOOM_LEVEL_STANDARD:
604 return NEMO_ICON_TEXT_WIDTH_STANDARD;
605 case NEMO_ZOOM_LEVEL_LARGE:
606 return NEMO_ICON_TEXT_WIDTH_LARGE;
607 case NEMO_ZOOM_LEVEL_LARGER:
608 return NEMO_ICON_TEXT_WIDTH_LARGER;
609 case NEMO_ZOOM_LEVEL_LARGEST:
610 return NEMO_ICON_TEXT_WIDTH_LARGEST;
611 case NEMO_ZOOM_LEVEL_NULL:
612 default:
613 g_return_val_if_reached (NEMO_ICON_TEXT_WIDTH_STANDARD);
614 }
615 }
616
617
618
619 guint
nemo_get_desktop_icon_size_for_zoom_level(NemoZoomLevel zoom_level)620 nemo_get_desktop_icon_size_for_zoom_level (NemoZoomLevel zoom_level)
621 {
622 switch (zoom_level) {
623 case NEMO_ZOOM_LEVEL_SMALLER:
624 return NEMO_DESKTOP_ICON_SIZE_SMALLER;
625 case NEMO_ZOOM_LEVEL_SMALL:
626 return NEMO_DESKTOP_ICON_SIZE_SMALL;
627 case NEMO_ZOOM_LEVEL_STANDARD:
628 return NEMO_DESKTOP_ICON_SIZE_STANDARD;
629 case NEMO_ZOOM_LEVEL_LARGE:
630 return NEMO_DESKTOP_ICON_SIZE_LARGE;
631 case NEMO_ZOOM_LEVEL_LARGER:
632 return NEMO_DESKTOP_ICON_SIZE_LARGER;
633 case NEMO_ZOOM_LEVEL_SMALLEST:
634 case NEMO_ZOOM_LEVEL_LARGEST:
635 case NEMO_ZOOM_LEVEL_NULL:
636 default:
637 g_return_val_if_reached (NEMO_ICON_SIZE_STANDARD);
638 }
639 }
640
641 guint
nemo_get_desktop_text_width_for_zoom_level(NemoZoomLevel zoom_level)642 nemo_get_desktop_text_width_for_zoom_level (NemoZoomLevel zoom_level)
643 {
644 switch (zoom_level) {
645 case NEMO_ZOOM_LEVEL_SMALLER:
646 return NEMO_DESKTOP_TEXT_WIDTH_SMALLER;
647 case NEMO_ZOOM_LEVEL_SMALL:
648 return NEMO_DESKTOP_TEXT_WIDTH_SMALL;
649 case NEMO_ZOOM_LEVEL_STANDARD:
650 return NEMO_DESKTOP_TEXT_WIDTH_STANDARD;
651 case NEMO_ZOOM_LEVEL_LARGE:
652 return NEMO_DESKTOP_TEXT_WIDTH_LARGE;
653 case NEMO_ZOOM_LEVEL_LARGER:
654 return NEMO_DESKTOP_TEXT_WIDTH_LARGER;
655 case NEMO_ZOOM_LEVEL_NULL:
656 default:
657 g_return_val_if_reached (NEMO_DESKTOP_TEXT_WIDTH_STANDARD);
658 }
659 }
660
661 guint
nemo_get_list_icon_size_for_zoom_level(NemoZoomLevel zoom_level)662 nemo_get_list_icon_size_for_zoom_level (NemoZoomLevel zoom_level)
663 {
664 switch (zoom_level) {
665 case NEMO_ZOOM_LEVEL_SMALLEST:
666 return NEMO_LIST_ICON_SIZE_SMALLEST;
667 case NEMO_ZOOM_LEVEL_SMALLER:
668 return NEMO_LIST_ICON_SIZE_SMALLEST;
669 case NEMO_ZOOM_LEVEL_SMALL:
670 return NEMO_LIST_ICON_SIZE_SMALLER;
671 case NEMO_ZOOM_LEVEL_STANDARD:
672 return NEMO_LIST_ICON_SIZE_SMALL;
673 case NEMO_ZOOM_LEVEL_LARGE:
674 return NEMO_LIST_ICON_SIZE_STANDARD;
675 case NEMO_ZOOM_LEVEL_LARGER:
676 return NEMO_LIST_ICON_SIZE_LARGE;
677 case NEMO_ZOOM_LEVEL_LARGEST:
678 return NEMO_LIST_ICON_SIZE_LARGER;
679 case NEMO_ZOOM_LEVEL_NULL:
680 default:
681 g_return_val_if_reached (NEMO_ICON_SIZE_STANDARD);
682 }
683 }
684
685 gint
nemo_get_icon_size_for_stock_size(GtkIconSize size)686 nemo_get_icon_size_for_stock_size (GtkIconSize size)
687 {
688 gint w, h;
689
690 if (gtk_icon_size_lookup (size, &w, &h)) {
691 return MAX (w, h);
692 }
693 return NEMO_ICON_SIZE_STANDARD;
694 }
695
696
697 guint
nemo_icon_get_emblem_size_for_icon_size(guint size)698 nemo_icon_get_emblem_size_for_icon_size (guint size)
699 {
700 if (size >= 96)
701 return 48;
702 if (size >= 64)
703 return 32;
704 if (size >= 48)
705 return 24;
706 if (size >= 24)
707 return 16;
708 if (size >= 16)
709 return 12;
710
711 return 0; /* no emblems for smaller sizes */
712 }
713
714 GIcon *
nemo_user_special_directory_get_gicon(GUserDirectory directory)715 nemo_user_special_directory_get_gicon (GUserDirectory directory)
716 {
717
718 #define ICON_CASE(x) \
719 case G_USER_DIRECTORY_ ## x:\
720 return g_themed_icon_new (NEMO_ICON_FOLDER_ ## x);
721
722 switch (directory) {
723
724 ICON_CASE (DESKTOP);
725 ICON_CASE (DOCUMENTS);
726 ICON_CASE (DOWNLOAD);
727 ICON_CASE (MUSIC);
728 ICON_CASE (PICTURES);
729 ICON_CASE (PUBLIC_SHARE);
730 ICON_CASE (TEMPLATES);
731 ICON_CASE (VIDEOS);
732
733 case G_USER_N_DIRECTORIES:
734 default:
735 return g_themed_icon_new ("folder");
736 }
737
738 #undef ICON_CASE
739 }
740