diff options
-rw-r--r-- | src/idousermenuitem.c | 160 |
1 files changed, 55 insertions, 105 deletions
diff --git a/src/idousermenuitem.c b/src/idousermenuitem.c index c92a890..387c851 100644 --- a/src/idousermenuitem.c +++ b/src/idousermenuitem.c @@ -62,100 +62,6 @@ static gboolean ido_user_menu_item_primitive_draw_cb_gtk_3 (GtkWidget * image, gpointer gself); /*** -**** Avatar -***/ - -static GdkPixbuf * -load_gicon (GtkWidget * self, GIcon * icon, GError ** error) -{ - GtkSettings * settings; - gint width; - gint height; - GdkScreen * screen; - GtkIconTheme * icon_theme; - GtkIconInfo * info; - GtkStyleContext * style_context; - GdkPixbuf * pixbuf; - - settings = gtk_widget_get_settings (self); - if (settings == NULL) /* not attached to a toplevel yet */ - settings = gtk_settings_get_default (); - - if (!gtk_icon_size_lookup_for_settings (settings, - GTK_ICON_SIZE_MENU, - &width, - &height)) - { - /* arbitrary default size in case _size_lookup fails */ - width = 12; - height = 12; - } - - if ((screen = gtk_widget_get_screen (self))) - icon_theme = gtk_icon_theme_get_for_screen (screen); - else - icon_theme = gtk_icon_theme_get_default (); - - - info = gtk_icon_theme_lookup_by_gicon (icon_theme, - icon, - MIN (width, height), - GTK_ICON_LOOKUP_USE_BUILTIN | - GTK_ICON_LOOKUP_GENERIC_FALLBACK | - GTK_ICON_LOOKUP_FORCE_SIZE); - - style_context = gtk_widget_get_style_context (self); - - pixbuf = gtk_icon_info_load_symbolic_for_context (info, - style_context, - NULL, - error); - - g_clear_object (&info); - return pixbuf; -} - -static void -update_avatar (IdoUserMenuItem * self) -{ - IdoUserMenuItemPrivate * p = self->priv; - GdkPixbuf * pixbuf; - GtkImage * image; - - if (p->icon == NULL) - { - pixbuf = NULL; - } - else - { - GError * error = NULL; - - pixbuf = load_gicon (GTK_WIDGET(self), p->icon, &error); - - if (error != NULL) - { - g_warning ("Can't load user avatar icon: %s", error->message); - g_error_free (error); - } - } - - image = GTK_IMAGE (p->user_image); - - if (pixbuf != NULL) - { - gtk_image_set_from_pixbuf (image, pixbuf); - g_object_unref (G_OBJECT (pixbuf)); - } - else - { - GIcon * icon; - icon = g_themed_icon_new_with_default_fallbacks (FALLBACK_ICON_NAME); - gtk_image_set_from_gicon (image, icon, GTK_ICON_SIZE_MENU); - g_object_unref (icon); - } -} - -/*** **** GObject virtual functions ***/ @@ -301,6 +207,9 @@ ido_user_menu_item_init (IdoUserMenuItem *self) // Create the UI elements. priv->user_image = gtk_image_new (); + gtk_image_set_from_icon_name (GTK_IMAGE (priv->user_image), + FALLBACK_ICON_NAME, + GTK_ICON_SIZE_MENU); priv->user_name = gtk_label_new (NULL); @@ -337,11 +246,6 @@ ido_user_menu_item_init (IdoUserMenuItem *self) g_signal_connect_after (GTK_WIDGET(self), "draw", G_CALLBACK(ido_user_menu_item_primitive_draw_cb_gtk_3), GTK_WIDGET(self)); - - /* load_gicon()'s behavior depends on the current screen/toplevel/etc, - so reload the avatar whenever the widget is realized */ - g_signal_connect_swapped (self, "realize", - G_CALLBACK(update_avatar), self); } @@ -387,6 +291,41 @@ ido_user_menu_item_primitive_draw_cb_gtk_3 (GtkWidget * widget, } /*** +**** Avatar +***/ +static gboolean +ido_user_menu_item_set_icon_from_file_icon (IdoUserMenuItem *self, + GFileIcon *icon) +{ + GFile *file; + gchar *path; + gint width; + gint height; + GdkPixbuf *pixbuf; + + file = g_file_icon_get_file (G_FILE_ICON (icon)); + path = g_file_get_path (file); + g_object_unref (file); + + /* width and height will always be set by this function */ + gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (GTK_WIDGET (self)), + GTK_ICON_SIZE_MENU, + &width, &height); + + pixbuf = gdk_pixbuf_new_from_file_at_scale (path, width, height, TRUE, NULL); + g_free (path); + + if (pixbuf) + { + gtk_image_set_from_pixbuf (GTK_IMAGE (self->priv->user_image), pixbuf); + g_object_unref (pixbuf); + return TRUE; + } + + return FALSE; +} + +/*** **** PUBLIC API ***/ @@ -395,14 +334,25 @@ ido_user_menu_item_set_icon (IdoUserMenuItem * self, GIcon * icon) { IdoUserMenuItemPrivate * p = self->priv; - if (p->icon != icon) - { - g_clear_object (&p->icon); + if (p->icon == icon) + return; + + g_clear_object (&p->icon); - if (icon != NULL) - p->icon = g_object_ref (icon); + if (icon) + p->icon = g_object_ref (icon); - update_avatar (self); + /* Avatars are always loaded from disk. Show the fallback when no icon + * is set, the icon is not a file icon, or the file could not be + * found. + */ + if (icon == NULL || + !G_IS_FILE_ICON (icon) || + !ido_user_menu_item_set_icon_from_file_icon (self, G_FILE_ICON (icon))) + { + gtk_image_set_from_icon_name (GTK_IMAGE (p->user_image), + FALLBACK_ICON_NAME, + GTK_ICON_SIZE_MENU); } } |