user-accounts: Present the default avatar in the avatar popover

Currently, it is not possible to unset a custom avatar, respective it
is not possible to set the default one. Let's present the default
avatar in the avatar popover as suggested in the mockup:
https://wiki.gnome.org/Design/OS/AvatarChooser

Fixes: GNOME/gnome-control-center#62
This commit is contained in:
Ondrej Holy 2019-05-03 09:00:56 +02:00 committed by Felipe Borges
parent 65a8c15467
commit f5f67823db
5 changed files with 65 additions and 16 deletions

View file

@ -50,6 +50,7 @@ struct _CcAvatarChooser {
GtkWidget *popup_button;
GtkWidget *crop_area;
GtkWidget *user_flowbox;
GtkWidget *flowbox;
GtkWidget *take_picture_button;
@ -574,6 +575,7 @@ cc_avatar_chooser_class_init (CcAvatarChooserClass *klass)
gtk_widget_class_set_template_from_resource (wclass, "/org/gnome/control-center/user-accounts/cc-avatar-chooser.ui");
gtk_widget_class_bind_template_child (wclass, CcAvatarChooser, user_flowbox);
gtk_widget_class_bind_template_child (wclass, CcAvatarChooser, flowbox);
gtk_widget_class_bind_template_child (wclass, CcAvatarChooser, take_picture_button);
@ -585,16 +587,39 @@ cc_avatar_chooser_class_init (CcAvatarChooserClass *klass)
oclass->dispose = cc_avatar_chooser_dispose;
}
static void
user_flowbox_activated (GtkFlowBox *flowbox,
GtkFlowBoxChild *child,
CcAvatarChooser *self)
{
set_default_avatar (self->user);
gtk_popover_popdown (GTK_POPOVER (self));
}
void
cc_avatar_chooser_set_user (CcAvatarChooser *self,
ActUser *user)
{
g_autoptr(GdkPixbuf) source_pixbuf = NULL;
g_autoptr(GdkPixbuf) pixbuf = NULL;
GtkWidget *image;
g_return_if_fail (self != NULL);
if (self->user) {
gtk_container_foreach (GTK_CONTAINER (self->user_flowbox), (GtkCallback) gtk_widget_destroy, NULL);
g_object_unref (self->user);
self->user = NULL;
}
self->user = g_object_ref (user);
source_pixbuf = generate_default_avatar (user, AVATAR_CHOOSER_PIXEL_SIZE);
pixbuf = round_image (source_pixbuf);
image = gtk_image_new_from_pixbuf (pixbuf);
gtk_image_set_pixel_size (GTK_IMAGE (image), AVATAR_CHOOSER_PIXEL_SIZE);
gtk_widget_show (image);
gtk_container_add (GTK_CONTAINER (self->user_flowbox), image);
g_signal_connect (self->user_flowbox, "child-activated", G_CALLBACK (user_flowbox_activated), self);
}

View file

@ -2,17 +2,29 @@
<interface>
<!-- interface-requires gtk+ 3.8 -->
<template class="CcAvatarChooser" parent="GtkPopover">
<property name="height-request">360</property>
<property name="width-request">480</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">GTK_ORIENTATION_VERTICAL</property>
<property name="border-width">10</property>
<child>
<object class="GtkFlowBox" id="user_flowbox">
<property name="visible">True</property>
<property name="border-width">10</property>
<property name="selection-mode">none</property>
<property name="homogeneous">True</property>
<property name="max-children-per-line">5</property>
<property name="column-spacing">10</property>
</object>
</child>
<child>
<object class="GtkFlowBox" id="flowbox">
<property name="visible">True</property>
<property name="border-width">20</property>
<property name="border-width">10</property>
<property name="selection-mode">none</property>
<property name="homogeneous">True</property>
<property name="max-children-per-line">5</property>
<property name="column-spacing">10</property>
</object>
</child>
<child>

View file

@ -367,7 +367,7 @@ add_user (CcUserPanel *self)
user = cc_add_user_dialog_get_user (dialog);
if (user != NULL) {
generate_user_avatar (user);
set_default_avatar (user);
reload_users (self, user);
}

View file

@ -559,11 +559,11 @@ get_color_for_name (const gchar *name)
}
static cairo_surface_t *
generate_user_picture (const gchar *name)
generate_user_picture (const gchar *name, gint size)
{
PangoFontDescription *font_desc;
g_autofree gchar *initials = extract_initials_from_name (name);
g_autofree gchar *font = g_strdup_printf ("Sans %d", (int)ceil (IMAGE_SIZE / 2.5));
g_autofree gchar *font = g_strdup_printf ("Sans %d", (int)ceil (size / 2.5));
PangoLayout *layout;
GdkRGBA color = get_color_for_name (name);
cairo_surface_t *surface;
@ -571,10 +571,10 @@ generate_user_picture (const gchar *name)
cairo_t *cr;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
IMAGE_SIZE,
IMAGE_SIZE);
size,
size);
cr = cairo_create (surface);
cairo_rectangle (cr, 0, 0, IMAGE_SIZE, IMAGE_SIZE);
cairo_rectangle (cr, 0, 0, size, size);
cairo_set_source_rgb (cr, color.red/255.0, color.green/255.0, color.blue/255.0);
cairo_fill (cr);
@ -587,7 +587,7 @@ generate_user_picture (const gchar *name)
pango_font_description_free (font_desc);
pango_layout_get_size (layout, &width, &height);
cairo_translate (cr, IMAGE_SIZE/2, IMAGE_SIZE/2);
cairo_translate (cr, size/2, size/2);
cairo_move_to (cr, - ((double)width / PANGO_SCALE)/2, - ((double)height/PANGO_SCALE)/2);
pango_cairo_show_layout (cr, layout);
cairo_destroy (cr);
@ -635,16 +635,26 @@ set_user_icon_data (ActUser *user,
g_free (path);
}
void
generate_user_avatar (ActUser *user)
GdkPixbuf *
generate_default_avatar (ActUser *user, gint size)
{
g_autoptr(GdkPixbuf) pixbuf = NULL;
GdkPixbuf *pixbuf = NULL;
cairo_surface_t *surface;
surface = generate_user_picture (act_user_get_real_name (user));
surface = generate_user_picture (act_user_get_real_name (user), size);
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, IMAGE_SIZE, IMAGE_SIZE);
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, size, size);
cairo_surface_destroy (surface);
return pixbuf;
}
void
set_default_avatar (ActUser *user)
{
g_autoptr(GdkPixbuf) pixbuf = NULL;
pixbuf = generate_default_avatar (user, IMAGE_SIZE);
set_user_icon_data (user, pixbuf);
}

View file

@ -44,7 +44,9 @@ gboolean is_valid_name (const gchar *name);
gboolean is_valid_username (const gchar *name,
gchar **tip);
GdkPixbuf *round_image (GdkPixbuf *pixbuf);
void generate_user_avatar (ActUser *user);
GdkPixbuf *generate_default_avatar (ActUser *user,
gint size);
void set_default_avatar (ActUser *user);
void set_user_icon_data (ActUser *user,
GdkPixbuf *pixbuf);