int clip_GTK_ICONTHEMEGETICONSIZES(ClipMachine * cm) { C_object *cicon = _fetch_co_arg(cm); gchar *icon_name = _clip_parc(cm, 2); ClipVar *cv = RETPTR(cm); gint *a ; CHECKCOBJ(cicon, GTK_IS_ICON_THEME(cicon->object)); CHECKARG(2, CHARACTER_t); LOCALE_TO_UTF(icon_name); a = gtk_icon_theme_get_icon_sizes(GTK_ICON_THEME(cicon->object), icon_name); FREE_TEXT(icon_name); _clip_array(cm, cv, 0, 0); while (a) { ClipVar *item; item = NEW(ClipVar); item->t.type = NUMERIC_t; item->t.flags = 0; item->n.d = a[0]; _clip_aadd(cm, cv, item); _clip_delete(cm, item); a++; } free(a); return 0; err: return 1; }
/* If we can't find a matching icon size, use the one provided as parameter * This is to avoid having two pixbufs in memory when not needed. */ GdkPixbuf *get_icon_with_fallback(const char *icon_name, int icon_size, GdkPixbuf *fallback) { gint *icon_sizes; gint i; gboolean found; GtkIconTheme *icon_theme; GdkPixbuf *pixbuf = NULL; GError *error = NULL; if (icon_name) { icon_theme = gtk_icon_theme_get_default(); icon_sizes = gtk_icon_theme_get_icon_sizes(icon_theme, icon_name); i = 0; found = FALSE; while (icon_sizes[i] != 0) { /* If found or has scalable icon (-1), use it * Well, in theory at least. Maemo-Gtk+ doesn't return -1 at all * it seems (scalable is a synonyme for "64" really) */ if (icon_sizes[i] == icon_size || icon_sizes[i] == -1) { found = TRUE; break; } i++; } g_free (icon_sizes); if (!found) { g_object_ref(fallback); return fallback; } pixbuf = gtk_icon_theme_load_icon(icon_theme, icon_name, icon_size, GTK_ICON_LOOKUP_NO_SVG, &error); if (error) { g_warning("Error loading icon '%s': %s\n", icon_name, error->message); g_error_free(error); error = NULL; } } else { g_warning("Error loading icon: no icon name\n"); } return pixbuf; } /* static GdkPixbuf *get_icon_with_fallback() */
static VALUE it_get_icon_sizes(VALUE self, VALUE icon_name) { VALUE ary = rb_ary_new(); gint* sizes = gtk_icon_theme_get_icon_sizes(_SELF(self), RVAL2CSTR(icon_name)); gint* tmp_sizes = sizes; while (*tmp_sizes) { rb_ary_push(ary, INT2NUM(*tmp_sizes)); tmp_sizes++; } g_free(sizes); return ary; }
static void select_icon (GtkTreeSelection * sel, IconBrowserData * data) { GtkTreeModel *model; GtkTreeIter iter; GtkIconInfo *info; gint *sz, i; gchar *icon, *file; GString *sizes; if (!gtk_tree_selection_get_selected (sel, &model, &iter)) return; gtk_tree_model_get (model, &iter, 1, &icon, -1); gtk_image_set_from_icon_name (GTK_IMAGE (data->image), icon, GTK_ICON_SIZE_DIALOG); sz = gtk_icon_theme_get_icon_sizes (data->theme, icon); info = gtk_icon_theme_lookup_icon (data->theme, icon, sz[0], 0); if (info) file = (gchar *) gtk_icon_info_get_filename (info); else file = NULL; /* create sizes string */ i = 0; sizes = g_string_new (""); while (sz[i]) { if (sz[i] == -1) g_string_append (sizes, _("scalable ")); else g_string_append_printf (sizes, "%dx%d ", sz[i], sz[i]); i++; } /* free memory */ g_free (sz); gtk_label_set_text (GTK_LABEL (data->lname), icon); gtk_label_set_text (GTK_LABEL (data->lsize), sizes->str); gtk_label_set_text (GTK_LABEL (data->lfile), file ? file : _("built-in")); g_string_free (sizes, TRUE); if (info) gtk_icon_info_free (info); }
static gint get_icon_size (GKeyFile *key_file) { gchar *icon; gint icon_size = 0; icon = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ICON, NULL); if (!icon) return 0; if (g_path_is_absolute (icon)) { GdkPixbuf *pixbuf; gint width, height; GError *error = NULL; pixbuf = gdk_pixbuf_new_from_file (icon, &error); width = gdk_pixbuf_get_width (pixbuf); height = gdk_pixbuf_get_height (pixbuf); g_object_unref (pixbuf); icon_size = MIN (width, height); } else { gint *sizes, i; GtkIconTheme *icon_theme = gtk_icon_theme_get_default (); sizes = gtk_icon_theme_get_icon_sizes (icon_theme, icon); if (sizes != NULL) { for (i = 0; sizes != NULL && sizes[i] != 0; i++) { g_debug ("size %d found for icon %s", sizes[i], icon); if (sizes[i] == -1) { /* Scalable */ icon_size = 256; break; } icon_size = MAX (icon_size, sizes[i]); } g_free (sizes); } } g_free (icon); return icon_size; }
static void exo_cell_renderer_icon_render (GtkCellRenderer *renderer, GdkWindow *window, GtkWidget *widget, GdkRectangle *background_area, GdkRectangle *cell_area, GdkRectangle *expose_area, GtkCellRendererState flags) { const ExoCellRendererIconPrivate *priv = EXO_CELL_RENDERER_ICON_GET_PRIVATE (renderer); GtkIconSource *icon_source; GtkIconTheme *icon_theme; GdkRectangle icon_area; GdkRectangle draw_area; GtkStateType state; const gchar *filename; GtkIconInfo *icon_info = NULL; GdkPixbuf *icon = NULL; GdkPixbuf *temp; GError *err = NULL; gchar *display_name = NULL; gint *icon_sizes; gint icon_size; gint n; /* verify that we have an icon */ if (G_UNLIKELY (priv->icon == NULL && priv->gicon == NULL)) return; /* icon may be either an image file or a named icon */ if (priv->icon != NULL && g_path_is_absolute (priv->icon)) { /* load the icon via the thumbnail database */ icon = _exo_thumbnail_get_for_file (priv->icon, (priv->size > 128) ? EXO_THUMBNAIL_SIZE_LARGE : EXO_THUMBNAIL_SIZE_NORMAL, &err); } else if (priv->icon != NULL || priv->gicon != NULL) { /* determine the best icon size (GtkIconTheme is somewhat messy scaling up small icons) */ icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget)); if (priv->icon != NULL) { icon_sizes = gtk_icon_theme_get_icon_sizes (icon_theme, priv->icon); for (icon_size = -1, n = 0; icon_sizes[n] != 0; ++n) { /* we can use any size if scalable, because we load the file directly */ if (icon_sizes[n] == -1) icon_size = priv->size; else if (icon_sizes[n] > icon_size && icon_sizes[n] <= priv->size) icon_size = icon_sizes[n]; } g_free (icon_sizes); /* if we don't know any icon sizes at all, the icon is probably not present */ if (G_UNLIKELY (icon_size < 0)) icon_size = priv->size; /* lookup the icon in the icon theme */ icon_info = gtk_icon_theme_lookup_icon (icon_theme, priv->icon, icon_size, 0); } else if (priv->gicon != NULL) { icon_info = gtk_icon_theme_lookup_by_gicon (icon_theme, priv->gicon, priv->size, GTK_ICON_LOOKUP_USE_BUILTIN); } if (G_UNLIKELY (icon_info == NULL)) return; /* check if we have an SVG icon here */ filename = gtk_icon_info_get_filename (icon_info); if (filename != NULL && g_str_has_suffix (filename, ".svg")) { /* loading SVG icons is terribly slow, so we try to use thumbnail instead, and we use the * real available cell area directly here, because loading thumbnails involves scaling anyway * and this way we need to the thumbnail pixbuf scale only once. */ icon = _exo_thumbnail_get_for_file (filename, (priv->size > 128) ? EXO_THUMBNAIL_SIZE_LARGE : EXO_THUMBNAIL_SIZE_NORMAL, &err); } else { /* regularly load the icon from the theme */ icon = gtk_icon_info_load_icon (icon_info, &err); } gtk_icon_info_free (icon_info); } /* check if we failed */ if (G_UNLIKELY (icon == NULL)) { /* better let the user know whats going on, might be surprising otherwise */ if (G_LIKELY (priv->icon != NULL)) { display_name = g_filename_display_name (priv->icon); } else if (G_UNLIKELY (priv->gicon != NULL && g_object_class_find_property (G_OBJECT_GET_CLASS (priv->gicon), "name"))) { g_object_get (priv->gicon, "name", &display_name, NULL); } if (display_name != NULL) { g_warning ("Failed to load \"%s\": %s", display_name, err->message); g_free (display_name); } g_error_free (err); return; } /* determine the real icon size */ icon_area.width = gdk_pixbuf_get_width (icon); icon_area.height = gdk_pixbuf_get_height (icon); /* scale down the icon on-demand */ if (G_UNLIKELY (icon_area.width > cell_area->width || icon_area.height > cell_area->height)) { /* scale down to fit */ temp = exo_gdk_pixbuf_scale_down (icon, TRUE, cell_area->width, cell_area->height); g_object_unref (G_OBJECT (icon)); icon = temp; /* determine the icon dimensions again */ icon_area.width = gdk_pixbuf_get_width (icon); icon_area.height = gdk_pixbuf_get_height (icon); } icon_area.x = cell_area->x + (cell_area->width - icon_area.width) / 2; icon_area.y = cell_area->y + (cell_area->height - icon_area.height) / 2; /* check whether the icon is affected by the expose event */ if (gdk_rectangle_intersect (expose_area, &icon_area, &draw_area)) { /* colorize the icon if we should follow the selection state */ if ((flags & (GTK_CELL_RENDERER_SELECTED | GTK_CELL_RENDERER_PRELIT)) != 0 && priv->follow_state) { if ((flags & GTK_CELL_RENDERER_SELECTED) != 0) { state = GTK_WIDGET_HAS_FOCUS (widget) ? GTK_STATE_SELECTED : GTK_STATE_ACTIVE; temp = exo_gdk_pixbuf_colorize (icon, &widget->style->base[state]); g_object_unref (G_OBJECT (icon)); icon = temp; } if ((flags & GTK_CELL_RENDERER_PRELIT) != 0) { temp = exo_gdk_pixbuf_spotlight (icon); g_object_unref (G_OBJECT (icon)); icon = temp; } } /* check if we should render an insensitive icon */ if (G_UNLIKELY (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE || !renderer->sensitive)) { /* allocate an icon source */ icon_source = gtk_icon_source_new (); gtk_icon_source_set_pixbuf (icon_source, icon); gtk_icon_source_set_size_wildcarded (icon_source, FALSE); gtk_icon_source_set_size (icon_source, GTK_ICON_SIZE_SMALL_TOOLBAR); /* render the insensitive icon */ temp = gtk_style_render_icon (widget->style, icon_source, gtk_widget_get_direction (widget), GTK_STATE_INSENSITIVE, -1, widget, "gtkcellrendererpixbuf"); g_object_unref (G_OBJECT (icon)); icon = temp; /* release the icon source */ gtk_icon_source_free (icon_source); } /* render the invalid parts of the icon */ gdk_draw_pixbuf (window, widget->style->black_gc, icon, draw_area.x - icon_area.x, draw_area.y - icon_area.y, draw_area.x, draw_area.y, draw_area.width, draw_area.height, GDK_RGB_DITHER_NORMAL, 0, 0); } /* release the file's icon */ g_object_unref (G_OBJECT (icon)); }