[gnome-control-center/wip/feborges/avatar-chooser: 89/90] user-accounts: Introduce the new Avatar Chooser popover



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]