[gnome-control-center/wip/feborges/avatar-chooser: 89/90] user-accounts: Introduce the new Avatar Chooser popover
- From: Felipe Borges <felipeborges src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center/wip/feborges/avatar-chooser: 89/90] user-accounts: Introduce the new Avatar Chooser popover
- Date: Wed, 31 Jan 2018 14:58:21 +0000 (UTC)
commit 142f9eaba6dcf024500c9008ea30af73aae35b90
Author: Felipe Borges <felipeborges gnome org>
Date: Wed Jan 10 13:40:36 2018 +0100
user-accounts: Introduce the new Avatar Chooser popover
panels/user-accounts/data/avatar-chooser.ui | 39 ++++
panels/user-accounts/um-photo-dialog.c | 317 ++++----------------------
2 files changed, 88 insertions(+), 268 deletions(-)
---
diff --git a/panels/user-accounts/data/avatar-chooser.ui b/panels/user-accounts/data/avatar-chooser.ui
index c906d0b..6bd210c 100644
--- a/panels/user-accounts/data/avatar-chooser.ui
+++ b/panels/user-accounts/data/avatar-chooser.ui
@@ -2,5 +2,44 @@
<interface>
<!-- interface-requires gtk+ 3.8 -->
<template class="UmPhotoDialog" 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>
+ <child>
+ <object class="GtkFlowBox" id="flowbox">
+ <property name="visible">True</property>
+ <property name="border-width">20</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="halign">GTK_ALIGN_CENTER</property>
+ <property name="border-width">10</property>
+ <property name="spacing">10</property>
+ <child>
+ <object class="GtkButton" id="take_picture_button">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Take a Picture…</property>
+ <signal name="clicked" handler="webcam_icon_selected" swapped="yes"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Select a File…</property>
+ <signal name="clicked" handler="um_photo_dialog_select_file" swapped="yes"/>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="pack-type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </object>
+ </child>
</template>
</interface>
diff --git a/panels/user-accounts/um-photo-dialog.c b/panels/user-accounts/um-photo-dialog.c
index 3afebcd..f02f971 100644
--- a/panels/user-accounts/um-photo-dialog.c
+++ b/panels/user-accounts/um-photo-dialog.c
@@ -43,17 +43,20 @@
#define AVATAR_PIXEL_SIZE 72
struct _UmPhotoDialog {
- GtkWidget *photo_popup;
+ GtkPopover parent;
+
GtkWidget *popup_button;
GtkWidget *crop_area;
+ GtkWidget *flowbox;
+ GtkWidget *take_picture_button;
#ifdef HAVE_CHEESE
CheeseCameraDeviceMonitor *monitor;
- GtkWidget *take_photo_menuitem;
guint num_cameras;
#endif /* HAVE_CHEESE */
GnomeDesktopThumbnailFactory *thumb_factory;
+ GListStore *faces;
ActUser *user;
};
@@ -255,20 +258,6 @@ um_photo_dialog_select_file (UmPhotoDialog *um)
gtk_window_present (GTK_WINDOW (chooser));
}
-static void
-none_icon_selected (GtkMenuItem *menuitem,
- UmPhotoDialog *um)
-{
- act_user_set_icon_file (um->user, "");
-}
-
-static void
-file_icon_selected (GtkMenuItem *menuitem,
- UmPhotoDialog *um)
-{
- um_photo_dialog_select_file (um);
-}
-
#ifdef HAVE_CHEESE
static gboolean
destroy_chooser (GtkWidget *chooser)
@@ -299,8 +288,7 @@ webcam_response_cb (GtkDialog *dialog,
}
static void
-webcam_icon_selected (GtkMenuItem *menuitem,
- UmPhotoDialog *um)
+webcam_icon_selected (UmPhotoDialog *um)
{
GtkWidget *window;
@@ -317,9 +305,9 @@ static void
update_photo_menu_status (UmPhotoDialog *um)
{
if (um->num_cameras == 0)
- gtk_widget_set_sensitive (um->take_photo_menuitem, FALSE);
+ gtk_widget_set_visible (um->take_picture_button, FALSE);
else
- gtk_widget_set_sensitive (um->take_photo_menuitem, TRUE);
+ gtk_widget_set_sensitive (um->take_picture_button, TRUE);
}
static void
@@ -343,59 +331,58 @@ device_removed (CheeseCameraDeviceMonitor *monitor,
#endif /* HAVE_CHEESE */
static void
-stock_icon_selected (GtkMenuItem *menuitem,
- UmPhotoDialog *um)
+face_widget_activated (GtkFlowBox *flowbox,
+ GtkFlowBoxChild *child,
+ UmPhotoDialog *um)
{
- const char *filename;
+ const gchar *filename;
+ GtkWidget *image;
+
+ image = gtk_bin_get_child (GTK_BIN (child));
+ filename = g_object_get_data (G_OBJECT (image), "filename");
- filename = g_object_get_data (G_OBJECT (menuitem), "filename");
act_user_set_icon_file (um->user, filename);
}
static GtkWidget *
-menu_item_for_filename (UmPhotoDialog *um,
- const char *filename)
+create_face_widget (gpointer item,
+ gpointer user_data)
{
- GtkWidget *image, *menuitem;
- GFile *file;
+ GtkWidget *image;
GIcon *icon;
- file = g_file_new_for_path (filename);
- icon = g_file_icon_new (file);
- g_object_unref (file);
+ icon = g_file_icon_new (G_FILE (item));
image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_DIALOG);
gtk_image_set_pixel_size (GTK_IMAGE (image), AVATAR_PIXEL_SIZE);
g_object_unref (icon);
- menuitem = gtk_menu_item_new ();
- gtk_container_add (GTK_CONTAINER (menuitem), image);
- gtk_widget_show_all (menuitem);
+ gtk_widget_show (image);
- g_object_set_data_full (G_OBJECT (menuitem), "filename",
- g_strdup (filename), (GDestroyNotify) g_free);
- g_signal_connect (G_OBJECT (menuitem), "activate",
- G_CALLBACK (stock_icon_selected), um);
+ g_object_set_data (G_OBJECT (image),
+ "filename", g_file_get_path (G_FILE (item)));
- return menuitem;
+ return image;
}
static void
setup_photo_popup (UmPhotoDialog *um)
{
- GtkWidget *menu, *menuitem, *image;
- guint x, y;
+ GFile *face_file;
const gchar * const * dirs;
guint i;
GDir *dir;
const char *face;
- gboolean none_item_shown;
gboolean added_faces;
- menu = gtk_menu_new ();
+ um->faces = g_list_store_new (G_TYPE_FILE);
+ gtk_flow_box_bind_model (GTK_FLOW_BOX (um->flowbox),
+ G_LIST_MODEL (um->faces),
+ create_face_widget,
+ um,
+ NULL);
- x = 0;
- y = 0;
- none_item_shown = added_faces = FALSE;
+ g_signal_connect (um->flowbox, "child-activated",
+ G_CALLBACK (face_widget_activated), um);
dirs = g_get_system_data_dirs ();
for (i = 0; dirs[i] != NULL; i++) {
@@ -414,20 +401,10 @@ setup_photo_popup (UmPhotoDialog *um)
added_faces = TRUE;
filename = g_build_filename (path, face, NULL);
- menuitem = menu_item_for_filename (um, filename);
+ face_file = g_file_new_for_path (filename);
g_free (filename);
- if (menuitem == NULL)
- continue;
-
- gtk_menu_attach (GTK_MENU (menu), GTK_WIDGET (menuitem),
- x, x + 1, y, y + 1);
- gtk_widget_show (menuitem);
-
- x++;
- if (x >= ROW_SPAN - 1) {
- y++;
- x = 0;
- }
+
+ g_list_store_append (um->faces, face_file);
}
g_dir_close (dir);
g_free (path);
@@ -436,48 +413,8 @@ setup_photo_popup (UmPhotoDialog *um)
break;
}
- if (!added_faces)
- goto skip_faces;
-
- image = gtk_image_new_from_icon_name ("avatar-default", GTK_ICON_SIZE_DIALOG);
- menuitem = gtk_menu_item_new ();
- gtk_container_add (GTK_CONTAINER (menuitem), image);
- gtk_widget_show_all (menuitem);
- gtk_menu_attach (GTK_MENU (menu), GTK_WIDGET (menuitem),
- x, x + 1, y, y + 1);
- g_signal_connect (G_OBJECT (menuitem), "activate",
- G_CALLBACK (none_icon_selected), um);
- gtk_widget_show (menuitem);
- none_item_shown = TRUE;
- y++;
-
-skip_faces:
- if (!none_item_shown) {
- menuitem = gtk_menu_item_new_with_label (_("Disable image"));
- gtk_menu_attach (GTK_MENU (menu), GTK_WIDGET (menuitem),
- 0, ROW_SPAN - 1, y, y + 1);
- g_signal_connect (G_OBJECT (menuitem), "activate",
- G_CALLBACK (none_icon_selected), um);
- gtk_widget_show (menuitem);
- y++;
- }
-
- /* Separator */
- menuitem = gtk_separator_menu_item_new ();
- gtk_menu_attach (GTK_MENU (menu), GTK_WIDGET (menuitem),
- 0, ROW_SPAN - 1, y, y + 1);
- gtk_widget_show (menuitem);
-
- y++;
-
#ifdef HAVE_CHEESE
- um->take_photo_menuitem = gtk_menu_item_new_with_label (_("Take a photo…"));
- gtk_menu_attach (GTK_MENU (menu), GTK_WIDGET (um->take_photo_menuitem),
- 0, ROW_SPAN - 1, y, y + 1);
- g_signal_connect (G_OBJECT (um->take_photo_menuitem), "activate",
- G_CALLBACK (webcam_icon_selected), um);
- gtk_widget_set_sensitive (um->take_photo_menuitem, FALSE);
- gtk_widget_show (um->take_photo_menuitem);
+ gtk_widget_set_visible (um->take_picture_button, TRUE);
um->monitor = cheese_camera_device_monitor_new ();
g_signal_connect (G_OBJECT (um->monitor), "added",
@@ -485,39 +422,13 @@ skip_faces:
g_signal_connect (G_OBJECT (um->monitor), "removed",
G_CALLBACK (device_removed), um);
cheese_camera_device_monitor_coldplug (um->monitor);
-
- y++;
#endif /* HAVE_CHEESE */
-
- menuitem = gtk_menu_item_new_with_label (_("Browse for more pictures…"));
- gtk_menu_attach (GTK_MENU (menu), GTK_WIDGET (menuitem),
- 0, ROW_SPAN - 1, y, y + 1);
- g_signal_connect (G_OBJECT (menuitem), "activate",
- G_CALLBACK (file_icon_selected), um);
- gtk_widget_show (menuitem);
-
- um->photo_popup = menu;
}
static void
popup_icon_menu (GtkToggleButton *button, UmPhotoDialog *um)
{
- GtkWindow *window;
-
- window = GTK_WINDOW (gtk_widget_get_toplevel (um->photo_popup));
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) && !gtk_widget_get_visible
(um->photo_popup)) {
- gtk_menu_popup_at_widget (GTK_MENU (um->photo_popup),
- GTK_WIDGET (button),
- GDK_GRAVITY_NORTH_WEST,
- GDK_GRAVITY_SOUTH_WEST,
- NULL);
-
- gtk_window_set_transient_for (window, GTK_WINDOW (gtk_widget_get_toplevel
(um->popup_button)));
- } else {
- gtk_menu_popdown (GTK_MENU (um->photo_popup));
-
- gtk_window_set_transient_for (window, NULL);
- }
+ gtk_popover_popup (GTK_POPOVER (um));
}
static gboolean
@@ -526,11 +437,11 @@ on_popup_button_button_pressed (GtkToggleButton *button,
UmPhotoDialog *um)
{
if (event->button == 1) {
- if (!gtk_widget_get_visible (um->photo_popup)) {
+ if (!gtk_widget_get_visible (GTK_WIDGET (um))) {
popup_icon_menu (button, um);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
} else {
- gtk_menu_popdown (GTK_MENU (um->photo_popup));
+ gtk_popover_popdown (GTK_POPOVER (um));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
}
@@ -540,55 +451,25 @@ on_popup_button_button_pressed (GtkToggleButton *button,
return FALSE;
}
-static void
-on_photo_popup_unmap (GtkWidget *popup_menu,
- UmPhotoDialog *um)
-{
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (um->popup_button), FALSE);
-}
-
-static void
-popup_button_draw (GtkWidget *widget,
- cairo_t *cr,
- UmPhotoDialog *um)
-{
- if (!(gtk_widget_get_state_flags (gtk_bin_get_child (GTK_BIN (widget))) & GTK_STATE_FLAG_PRELIGHT) &&
- !gtk_widget_is_focus (widget)) {
- return;
- }
-}
-
-static void
-popup_button_focus_changed (GObject *button,
- GParamSpec *pspec,
- UmPhotoDialog *um)
-{
- gtk_widget_queue_draw (gtk_bin_get_child (GTK_BIN (button)));
-}
-
UmPhotoDialog *
um_photo_dialog_new (GtkWidget *button)
{
UmPhotoDialog *um;
- um = g_object_new (UM_TYPE_PHOTO_DIALOG, NULL);
+ um = g_object_new (UM_TYPE_PHOTO_DIALOG,
+ "relative-to", button,
+ NULL);
um->thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
/* Set up the popup */
um->popup_button = button;
+
setup_photo_popup (um);
g_signal_connect (button, "toggled",
G_CALLBACK (popup_icon_menu), um);
g_signal_connect (button, "button-press-event",
G_CALLBACK (on_popup_button_button_pressed), um);
- g_signal_connect (button, "notify::is-focus",
- G_CALLBACK (popup_button_focus_changed), um);
- g_signal_connect_after (button, "draw",
- G_CALLBACK (popup_button_draw), um);
-
- g_signal_connect (um->photo_popup, "unmap",
- G_CALLBACK (on_photo_popup_unmap), um);
return um;
}
@@ -621,75 +502,19 @@ um_photo_dialog_class_init (UmPhotoDialogClass *klass)
gtk_widget_class_set_template_from_resource (wclass,
"/org/gnome/control-center/user-accounts/avatar-chooser.ui");
- oclass->dispose = um_photo_dialog_dispose;
-}
-
-static void
-clear_tip (GtkMenuItem *item,
- gpointer user_data)
-{
- GList *children;
- GtkWidget *image;
- GIcon *icon, *icon2;
- const char *filename;
-
- /* Not a stock icon? */
- filename = g_object_get_data (G_OBJECT (item), "filename");
- if (filename == NULL)
- return;
-
- children = gtk_container_get_children (GTK_CONTAINER (item));
- image = children->data;
- g_assert (image != NULL);
- g_list_free (children);
-
- gtk_image_get_gicon (GTK_IMAGE (image), &icon, NULL);
-
- if (G_IS_EMBLEMED_ICON (icon))
- icon2 = g_emblemed_icon_get_icon (G_EMBLEMED_ICON (icon));
- else
- return;
-
- gtk_image_set_from_gicon (GTK_IMAGE (image), icon2, GTK_ICON_SIZE_DIALOG);
- g_object_unref (icon);
-}
-
-static void
-set_tip (GtkWidget *item,
- const char *tip,
- GEmblem *emblem)
-{
- GList *children;
- GtkWidget *image;
- GIcon *icon, *icon2;
-
- children = gtk_container_get_children (GTK_CONTAINER (item));
- image = children->data;
- g_assert (image != NULL);
- g_list_free (children);
-
- gtk_image_get_gicon (GTK_IMAGE (image), &icon, NULL);
- if (G_IS_EMBLEMED_ICON (icon)) {
- return;
- }
+ gtk_widget_class_bind_template_child (wclass, UmPhotoDialog, flowbox);
+ gtk_widget_class_bind_template_child (wclass, UmPhotoDialog, take_picture_button);
- icon2 = g_emblemed_icon_new (icon, emblem);
- gtk_image_set_from_gicon (GTK_IMAGE (image), icon2, GTK_ICON_SIZE_DIALOG);
+ gtk_widget_class_bind_template_callback (wclass, um_photo_dialog_select_file);
+ gtk_widget_class_bind_template_callback (wclass, webcam_icon_selected);
- gtk_widget_set_tooltip_text (GTK_WIDGET (item), tip);
+ oclass->dispose = um_photo_dialog_dispose;
}
void
um_photo_dialog_set_user (UmPhotoDialog *um,
ActUser *user)
{
- ActUserManager *manager;
- GSList *list, *l;
- ActUser *u;
- GIcon *icon;
- GEmblem *emblem;
- GList *children, *c;
-
g_return_if_fail (um != NULL);
if (um->user) {
@@ -697,49 +522,5 @@ um_photo_dialog_set_user (UmPhotoDialog *um,
um->user = NULL;
}
um->user = user;
-
- if (um->user) {
- g_object_ref (um->user);
-
- children = gtk_container_get_children (GTK_CONTAINER (um->photo_popup));
- g_list_foreach (children, (GFunc) clear_tip, NULL);
-
- manager = act_user_manager_get_default ();
- list = act_user_manager_list_users (manager);
-
- icon = g_themed_icon_new ("avatar-default");
- emblem = g_emblem_new (icon);
- g_object_unref (icon);
-
- for (l = list; l; l = l->next) {
- const char *filename;
-
- u = l->data;
- if (u == user)
- continue;
- filename = act_user_get_icon_file (u);
- if (filename == NULL)
- continue;
- for (c = children; c; c = c->next) {
- const char *f;
-
- f = g_object_get_data (G_OBJECT (c->data), "filename");
- if (f == NULL)
- continue;
- if (strcmp (f, filename) == 0) {
- char *tip;
-
- tip = g_strdup_printf (_("Used by %s"),
- act_user_get_real_name (u));
- set_tip (GTK_WIDGET (c->data), tip, emblem);
- g_free (tip);
- break;
- }
- }
- }
- g_slist_free (list);
-
- g_object_unref (emblem);
- }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]