[gnome-control-center/wip/um-avatar-picker: 2/2] user-accounts: Add a new um-avatar-picker to replace um-photo-dialog
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center/wip/um-avatar-picker: 2/2] user-accounts: Add a new um-avatar-picker to replace um-photo-dialog
- Date: Mon, 21 Oct 2013 22:04:24 +0000 (UTC)
commit ff59c1bdbd6c4683f3d806cfd1c0c9ac29b99907
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Mon Oct 21 14:23:44 2013 -0400
user-accounts: Add a new um-avatar-picker to replace um-photo-dialog
This is a new implementation using GtkStackSwitcher and composite
template widgets and friends that implements the new avatar picker
designs by Allan.
Based-heavily-on-a-patch-by: Bogdan Ciobanu <bgdn ciobanu gmail com>
panels/user-accounts/Makefile.am | 45 +++-
.../data/avatar-picker-camera-page.ui | 35 +++
panels/user-accounts/data/avatar-picker.ui | 97 +++++++
panels/user-accounts/test-um-avatar-picker.c | 53 ++++
.../user-accounts/um-avatar-picker-camera-page.c | 122 +++++++++
.../user-accounts/um-avatar-picker-camera-page.h | 55 ++++
panels/user-accounts/um-avatar-picker.c | 265 ++++++++++++++++++++
panels/user-accounts/um-avatar-picker.h | 55 ++++
.../user-accounts-camera.gresource.xml | 6 +
panels/user-accounts/user-accounts.gresource.xml | 1 +
10 files changed, 731 insertions(+), 3 deletions(-)
---
diff --git a/panels/user-accounts/Makefile.am b/panels/user-accounts/Makefile.am
index 4bb02ee..6752039 100644
--- a/panels/user-accounts/Makefile.am
+++ b/panels/user-accounts/Makefile.am
@@ -25,6 +25,27 @@ BUILT_SOURCES = \
um-resources.c \
um-resources.h
+if BUILD_CHEESE
+BUILT_SOURCES += \
+ um-camera-resources.c \
+ um-camera-resources.h \
+ $(NULL)
+endif
+
+avatar_picker_sources = \
+ um-avatar-picker.c \
+ um-avatar-picker.h \
+ online-avatars.c \
+ online-avatars.h \
+ $(NULL)
+
+if BUILD_CHEESE
+avatar_picker_sources += \
+ um-avatar-picker-camera-page.c \
+ um-avatar-picker-camera-page.h \
+ $(NULL)
+endif
+
libuser_accounts_la_SOURCES = \
um-account-type.h \
um-account-type.c \
@@ -55,8 +76,7 @@ libuser_accounts_la_SOURCES = \
um-realm-manager.h \
um-history-dialog.h \
um-history-dialog.c \
- online-avatars.c \
- online-avatars.h \
+ $(avatar_picker_sources) \
$(BUILT_SOURCES)
libuser_accounts_la_LIBADD = \
@@ -84,7 +104,13 @@ um-resources.c: user-accounts.gresource.xml $(resource_files)
um-resources.h: user-accounts.gresource.xml $(resource_files)
$(AM_V_GEN) glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-header --c-name um $<
-noinst_PROGRAMS = frob-account-dialog test-online-avatars
+camera_resource_files = $(shell glib-compile-resources --sourcedir=$(srcdir) --generate-dependencies
$(srcdir)/user-accounts-camera.gresource.xml)
+um-camera-resources.c: user-accounts-camera.gresource.xml $(resource_files)
+ $(AM_V_GEN) glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-source --c-name
um_camera $<
+um-camera-resources.h: user-accounts-camera.gresource.xml $(resource_files)
+ $(AM_V_GEN) glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-header --c-name
um_camera $<
+
+noinst_PROGRAMS = frob-account-dialog test-online-avatars test-um-avatar-picker
frob_account_dialog_SOURCES = \
frob-account-dialog.c \
@@ -115,6 +141,17 @@ test_online_avatars_LDADD = \
test_online_avatars_CFLAGS = \
$(AM_CPPFLAGS)
+test_um_avatar_picker_SOURCES = \
+ test-um-avatar-picker.c \
+ $(avatar_picker_sources) \
+ $(BUILT_SOURCES)
+
+test_um_avatar_picker_LDADD = \
+ $(libuser_accounts_la_LIBADD)
+
+test_um_avatar_picker_CFLAGS = \
+ $(AM_CPPFLAGS)
+
polkitdir = $(datadir)/polkit-1/actions
polkit_in_files = org.gnome.controlcenter.user-accounts.policy.in
@@ -125,6 +162,8 @@ EXTRA_DIST = \
$(polkit_in_files) \
$(resource_files) \
user-accounts.gresource.xml \
+ $(camera_resource_files) \
+ user-accounts-camera.gresource.xml \
$(NULL)
CLEANFILES = \
diff --git a/panels/user-accounts/data/avatar-picker-camera-page.ui
b/panels/user-accounts/data/avatar-picker-camera-page.ui
new file mode 100644
index 0000000..88ee048
--- /dev/null
+++ b/panels/user-accounts/data/avatar-picker-camera-page.ui
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.10 -->
+ <template class="UmAvatarPickerCameraPage" parent="GtkBox">
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkBox" id="camera_placeholder">
+ <property name="visible">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkToolbar" id="camera_toolbar">
+ <property name="visible">True</property>
+ <property name="icon-size">menu</property>
+ <child>
+ <object class="GtkToolButton" id="camera_photo_button">
+ <property name="visible">True</property>
+ <property name="width-request">80</property>
+ <property name="margin-top">4</property>
+ <property name="margin-bottom">4</property>
+ <property name="halign">center</property>
+ <property name="icon-name">camera-photo-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ </packing>
+ </child>
+ <style>
+ <class name="inline-toolbar" />
+ </style>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/panels/user-accounts/data/avatar-picker.ui b/panels/user-accounts/data/avatar-picker.ui
new file mode 100644
index 0000000..f72a202
--- /dev/null
+++ b/panels/user-accounts/data/avatar-picker.ui
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.10 -->
+ <template class="UmAvatarPicker" parent="GtkDialog">
+ <property name="title" translatable="yes">Account Picture</property>
+ <property name="default-width">600</property>
+ <property name="default-height">500</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="content_box">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">10</property>
+ <child>
+ <object class="GtkStackSwitcher" id="tabs">
+ <property name="visible">True</property>
+ <property name="stack">stack</property>
+ <property name="halign">center</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkStack" id="stack">
+ <property name="visible">True</property>
+ <property name="vexpand">True</property>
+ <property name="transition-type">crossfade</property>
+ <child>
+ <object class="GtkScrolledWindow" id="avatars_page">
+ <property name="visible">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow-type">etched-in</property>
+ <child>
+ <object class="GtkBox" id="avatars_box">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">10</property>
+ <child>
+ <object class="GtkFlowBox" id="avatars_online">
+ <property name="visible">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSeparator" id="avatars_separator">
+ <property name="visible">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkFlowBox" id="avatars_stock">
+ <property name="visible">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="name">avatars</property>
+ <property name="title" translatable="yes">Avatars</property>
+ </packing>
+ </child>
+
+ <!--
+ <child>
+ <object class="GtkBox" id="pictures_page">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="name">pictures</property>
+ <property name="title" translatable="yes">Pictures</property>
+ </packing>
+ </child>
+ -->
+ </object>
+ </child>
+ <child internal-child="action_area">
+ <object class="GtkBox" id="button_box">
+ <property name="visible">True</property>
+ <property name="halign">end</property>
+ <child>
+ <object class="GtkButton" id="cancel_button">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Cancel</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="select_button">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Select</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="3">select_button</action-widget>
+ <action-widget response="-5">cancel_button</action-widget>
+ </action-widgets>
+ </template>
+</interface>
diff --git a/panels/user-accounts/test-um-avatar-picker.c b/panels/user-accounts/test-um-avatar-picker.c
new file mode 100644
index 0000000..369f19b
--- /dev/null
+++ b/panels/user-accounts/test-um-avatar-picker.c
@@ -0,0 +1,53 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * Copyright 2013 Red Hat, Inc,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Written by:
+ * Jasper St. Pierre <jstpierre mecheye net>
+ */
+
+#include "config.h"
+
+#include "um-avatar-picker.h"
+
+#ifdef HAVE_CHEESE
+#include <cheese-gtk.h>
+#include <clutter-gtk/clutter-gtk.h>
+#endif /* HAVE_CHEESE */
+
+#include <gtk/gtk.h>
+
+int
+main (int argc, char *argv[])
+{
+#ifdef HAVE_CHEESE
+ cheese_gtk_init (&argc, &argv);
+ if (gtk_clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
+ g_error ("could not init clutter-gtk");
+#endif /* HAVE_CHEESE */
+
+ gtk_init (&argc, &argv);
+
+ {
+ UmAvatarPicker *picker = g_object_new (UM_TYPE_AVATAR_PICKER, NULL);
+ gtk_dialog_run (GTK_DIALOG (picker));
+ }
+
+ gtk_main ();
+
+ return 0;
+}
diff --git a/panels/user-accounts/um-avatar-picker-camera-page.c
b/panels/user-accounts/um-avatar-picker-camera-page.c
new file mode 100644
index 0000000..e915515
--- /dev/null
+++ b/panels/user-accounts/um-avatar-picker-camera-page.c
@@ -0,0 +1,122 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * Copyright 2013 Red Hat, Inc,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Written by:
+ * Jasper St. Pierre <jstpierre mecheye net>
+ * Bogdan Ciobanu <bgdn ciobanu gmail com>
+ */
+
+#include "config.h"
+
+#include <cheese-widget.h>
+#include <cheese-camera.h>
+#include <cheese-camera-device.h>
+#include <cheese-camera-device-monitor.h>
+
+#include "um-avatar-picker-camera-page.h"
+
+struct _UmAvatarPickerCameraPagePrivate
+{
+ GtkWidget *camera_photo_button;
+ GtkWidget *camera_placeholder;
+ GtkWidget *camera;
+
+ CheeseCameraDeviceMonitor *monitor;
+ guint num_cameras;
+};
+
+typedef struct _UmAvatarPickerCameraPagePrivate UmAvatarPickerCameraPagePrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (UmAvatarPickerCameraPage, um_avatar_picker_camera_page, GTK_TYPE_BOX);
+
+static void
+update_visibility (UmAvatarPickerCameraPage *page)
+{
+ UmAvatarPickerCameraPagePrivate *priv = um_avatar_picker_camera_page_get_instance_private (page);
+ gtk_widget_set_visible (GTK_WIDGET (page), priv->num_cameras > 0);
+}
+
+static void
+camera_photo_taken (CheeseCamera *camera,
+ GdkPixbuf *pixbuf,
+ gpointer user_data)
+{
+}
+
+static void
+device_added (CheeseCameraDeviceMonitor *monitor,
+ CheeseCameraDevice *device,
+ UmAvatarPickerCameraPage *page)
+{
+ UmAvatarPickerCameraPagePrivate *priv = um_avatar_picker_camera_page_get_instance_private (page);
+ priv->num_cameras++;
+ update_visibility (page);
+}
+
+static void
+device_removed (CheeseCameraDeviceMonitor *monitor,
+ const char *id,
+ UmAvatarPickerCameraPage *page)
+{
+ UmAvatarPickerCameraPagePrivate *priv = um_avatar_picker_camera_page_get_instance_private (page);
+ priv->num_cameras--;
+ update_visibility (page);
+}
+
+static void
+um_avatar_picker_camera_page_dispose (GObject *object)
+{
+ UmAvatarPickerCameraPage *page = UM_AVATAR_PICKER_CAMERA_PAGE (object);
+ UmAvatarPickerCameraPagePrivate *priv = um_avatar_picker_camera_page_get_instance_private (page);
+
+ g_clear_object (&priv->monitor);
+}
+
+static void
+um_avatar_picker_camera_page_class_init (UmAvatarPickerCameraPageClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = um_avatar_picker_camera_page_dispose;
+
+ gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass),
"/org/gnome/control-center/user-accounts/avatar-picker-camera-page.ui");
+
+ gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), UmAvatarPickerCameraPage,
camera_placeholder);
+ gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), UmAvatarPickerCameraPage,
camera_photo_button);
+}
+
+static void
+um_avatar_picker_camera_page_init (UmAvatarPickerCameraPage *page)
+{
+ UmAvatarPickerCameraPagePrivate *priv = um_avatar_picker_camera_page_get_instance_private (page);
+
+ gtk_widget_init_template (GTK_WIDGET (page));
+
+ priv->camera = cheese_widget_new ();
+ g_signal_connect (cheese_widget_get_camera (CHEESE_CAMERA (priv->camera)), "photo-taken",
+ G_CALLBACK (camera_photo_taken), page);
+ gtk_widget_show (priv->camera);
+ gtk_container_add (GTK_CONTAINER (priv->camera_placeholder), priv->camera);
+
+ priv->monitor = cheese_camera_device_monitor_new ();
+ g_signal_connect (G_OBJECT (priv->monitor), "added",
+ G_CALLBACK (device_added), page);
+ g_signal_connect (G_OBJECT (priv->monitor), "removed",
+ G_CALLBACK (device_removed), page);
+ cheese_camera_device_monitor_coldplug (priv->monitor);
+}
diff --git a/panels/user-accounts/um-avatar-picker-camera-page.h
b/panels/user-accounts/um-avatar-picker-camera-page.h
new file mode 100644
index 0000000..f70d40a
--- /dev/null
+++ b/panels/user-accounts/um-avatar-picker-camera-page.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * Copyright 2013 Red Hat, Inc,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Written by:
+ * Jasper St. Pierre <jstpierre mecheye net>
+ * Bogdan Ciobanu <bgdn ciobanu gmail com>
+ */
+
+#ifndef __UM_AVATAR_PICKER_CAMERA_PAGE_H__
+#define __UM_AVATAR_PICKER_CAMERA_PAGE_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define UM_TYPE_AVATAR_PICKER_CAMERA_PAGE (um_avatar_picker_camera_page_get_type ())
+#define UM_AVATAR_PICKER_CAMERA_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
UM_TYPE_AVATAR_PICKER_CAMERA_PAGE, UmAvatarPickerCameraPage))
+#define UM_AVATAR_PICKER_CAMERA_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
UM_TYPE_AVATAR_PICKER_CAMERA_PAGE, UmAvatarPickerCameraPageClass))
+#define UM_IS_AVATAR_PICKER_CAMERA_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
UM_TYPE_AVATAR_PICKER_CAMERA_PAGE))
+#define UM_IS_AVATAR_PICKER_CAMERA_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
UM_TYPE_AVATAR_PICKER_CAMERA_PAGE))
+#define UM_AVATAR_PICKER_CAMERA_PAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
UM_TYPE_AVATAR_PICKER_CAMERA_PAGE, UmAvatarPickerCameraPageClass))
+
+typedef struct _UmAvatarPickerCameraPage UmAvatarPickerCameraPage;
+typedef struct _UmAvatarPickerCameraPageClass UmAvatarPickerCameraPageClass;
+
+struct _UmAvatarPickerCameraPage
+{
+ GtkBox parent;
+};
+
+struct _UmAvatarPickerCameraPageClass
+{
+ GtkBoxClass parent_class;
+};
+
+GType um_avatar_picker_camera_page_get_type (void);
+
+G_END_DECLS
+
+#endif /* __UM_AVATAR_PICKER_CAMERA_PAGE_H__ */
diff --git a/panels/user-accounts/um-avatar-picker.c b/panels/user-accounts/um-avatar-picker.c
new file mode 100644
index 0000000..d2ec48a
--- /dev/null
+++ b/panels/user-accounts/um-avatar-picker.c
@@ -0,0 +1,265 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * Copyright 2013 Red Hat, Inc,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Written by:
+ * Jasper St. Pierre <jstpierre mecheye net>
+ * Bogdan Ciobanu <bgdn ciobanu gmail com>
+ */
+
+#define IMAGE_SIZE 96
+
+#include "config.h"
+#include "um-avatar-picker.h"
+
+#include <glib/gi18n.h>
+#include "online-avatars.h"
+
+#ifdef HAVE_CHEESE
+#include "um-avatar-picker-camera-page.h"
+#endif /* HAVE_CHEESE */
+
+struct _UmAvatarPickerPrivate
+{
+ GtkWidget *stack;
+ GtkWidget *avatars_online;
+ GtkWidget *avatars_stock;
+
+ GtkWidget *camera_placeholder;
+
+ GtkWidget *selected_avatar;
+ gboolean clearing_selection;
+};
+typedef struct _UmAvatarPickerPrivate UmAvatarPickerPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (UmAvatarPicker, um_avatar_picker, GTK_TYPE_DIALOG);
+
+static void
+image_set_from_bytes (GtkImage *image,
+ GBytes *bytes)
+{
+ GdkPixbufLoader *loader;
+ GdkPixbuf *pixbuf = NULL;
+ GdkPixbuf *scaled_pixbuf = NULL;
+ GError *error = NULL;
+
+ if (!bytes) {
+ GtkWidget *flow_box_child = gtk_widget_get_parent (GTK_WIDGET (image));
+ gtk_widget_destroy (flow_box_child);
+ return;
+ }
+
+ loader = gdk_pixbuf_loader_new ();
+ if (!gdk_pixbuf_loader_write_bytes (loader, bytes, &error)) {
+ g_warning ("Could not load image: %s\n", error->message);
+ goto out;
+ }
+
+ if (!gdk_pixbuf_loader_close (loader, NULL)) {
+ g_warning ("Could not load image: %s\n", error->message);
+ goto out;
+ }
+
+ pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+ if (!pixbuf) {
+ g_warning ("Could not load image\n");
+ goto out;
+ }
+
+ scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_SIZE, IMAGE_SIZE,
+ GDK_INTERP_BILINEAR);
+ gtk_image_set_from_pixbuf (image, scaled_pixbuf);
+ gtk_widget_show (GTK_WIDGET (image));
+
+ out:
+ g_clear_error (&error);
+ g_object_unref (loader);
+ if (scaled_pixbuf)
+ g_object_unref (scaled_pixbuf);
+}
+
+static void
+got_avatar_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GtkImage *image = GTK_IMAGE (user_data);
+ GBytes *bytes;
+ bytes = get_avatar_from_online_account_finish (GOA_ACCOUNT (source_object), result, NULL);
+ image_set_from_bytes (image, bytes);
+}
+
+static void
+got_gravatar_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GtkImage *image = GTK_IMAGE (user_data);
+ GBytes *bytes;
+ bytes = get_gravatar_from_email_finish (result, NULL);
+ image_set_from_bytes (image, bytes);
+}
+
+static void
+fill_online_icons (UmAvatarPicker *picker)
+{
+ UmAvatarPickerPrivate *priv = um_avatar_picker_get_instance_private (picker);
+ GHashTable *used_emails;
+ GoaClient *client;
+ GList *accounts, *l;
+
+ client = goa_client_new_sync (NULL, NULL);
+ if (!client)
+ return;
+
+ used_emails = g_hash_table_new (g_str_hash, g_str_equal);
+ accounts = goa_client_get_accounts (client);
+
+ for (l = accounts; l; l = l->next) {
+ GoaObject *object = GOA_OBJECT (l->data);
+ GoaAccount *account = goa_object_peek_account (object);
+ GoaMail *mail = goa_object_peek_mail (object);
+ GtkWidget *image;
+
+ image = gtk_image_new ();
+ gtk_widget_set_size_request (image, IMAGE_SIZE, IMAGE_SIZE);
+ get_avatar_from_online_account (account, NULL, got_avatar_cb, image);
+ gtk_container_add (GTK_CONTAINER (priv->avatars_online), image);
+
+ if (mail) {
+ const char *email = goa_mail_get_email_address (mail);
+ if (!g_hash_table_contains (used_emails, email)) {
+ image = gtk_image_new ();
+ gtk_widget_set_size_request (image, IMAGE_SIZE, IMAGE_SIZE);
+ get_gravatar_from_email (email, NULL, got_gravatar_cb, image);
+ gtk_container_add (GTK_CONTAINER (priv->avatars_online), image);
+
+ g_hash_table_add (used_emails, (gpointer) email);
+ }
+ }
+ }
+
+ g_list_free_full (accounts, (GDestroyNotify) g_object_unref);
+ g_hash_table_destroy (used_emails);
+}
+
+static void
+fill_stock_icons_from_dir (UmAvatarPicker *picker,
+ char *path,
+ GDir *dir)
+{
+ UmAvatarPickerPrivate *priv = um_avatar_picker_get_instance_private (picker);
+ const char *face;
+ GtkWidget *image;
+
+ while ((face = g_dir_read_name (dir)) != NULL) {
+ char *filename = g_build_filename (path, face, NULL);
+
+ image = gtk_image_new_from_file (filename);
+ gtk_widget_set_size_request (image, IMAGE_SIZE, IMAGE_SIZE);
+ gtk_widget_show (image);
+
+ gtk_container_add (GTK_CONTAINER (priv->avatars_stock), image);
+
+ g_free (filename);
+ }
+}
+
+static void
+fill_stock_icons (UmAvatarPicker *picker)
+{
+ const char * const * dirs = g_get_system_data_dirs ();
+ int i;
+
+ for (i = 0; dirs[i] != NULL; i++) {
+ char *path = g_build_filename (dirs[i], "pixmaps", "faces", NULL);
+ GDir *dir = g_dir_open (path, 0, NULL);
+
+ if (!dir)
+ goto next;
+
+ fill_stock_icons_from_dir (picker, path, dir);
+
+ next:
+ g_free (path);
+ if (dir)
+ g_dir_close (dir);
+ }
+}
+
+static void
+selection_changed (GtkFlowBox *box,
+ gpointer user_data)
+{
+ UmAvatarPicker *picker = user_data;
+ UmAvatarPickerPrivate *priv = um_avatar_picker_get_instance_private (picker);
+ GtkFlowBox *boxen[3] = { (GtkFlowBox *) priv->avatars_stock, (GtkFlowBox *) priv->avatars_online, NULL };
+ GtkFlowBox **widget;
+ GList *l;
+
+ if (priv->clearing_selection)
+ return;
+
+ /* The flow box is in single selection mode, so I know this
+ * list will always contain either one item or NULL. */
+ l = gtk_flow_box_get_selected_children (box);
+ priv->selected_avatar = l->data ? GTK_WIDGET (l->data) : NULL;
+ g_list_free (l);
+
+ priv->clearing_selection = TRUE;
+ for (widget = boxen; *widget != NULL; widget++) {
+ if (*widget == box)
+ continue;
+
+ gtk_flow_box_unselect_all (GTK_FLOW_BOX (*widget));
+ }
+ priv->clearing_selection = FALSE;
+}
+
+static void
+um_avatar_picker_class_init (UmAvatarPickerClass *klass)
+{
+ gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass),
"/org/gnome/control-center/user-accounts/avatar-picker.ui");
+
+ gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), UmAvatarPicker, stack);
+ gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), UmAvatarPicker, avatars_online);
+ gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), UmAvatarPicker, avatars_stock);
+}
+
+static void
+um_avatar_picker_init (UmAvatarPicker *picker)
+{
+ UmAvatarPickerPrivate *priv = um_avatar_picker_get_instance_private (picker);
+
+ gtk_widget_init_template (GTK_WIDGET (picker));
+
+ fill_stock_icons (picker);
+ fill_online_icons (picker);
+
+ g_signal_connect (priv->avatars_online, "selected-children-changed",
+ G_CALLBACK (selection_changed), picker);
+ g_signal_connect (priv->avatars_stock, "selected-children-changed",
+ G_CALLBACK (selection_changed), picker);
+
+#ifdef HAVE_CHEESE
+ gtk_container_add_with_properties (GTK_CONTAINER (priv->stack),
+ g_object_new (UM_TYPE_AVATAR_PICKER_CAMERA_PAGE, NULL),
+ "name", "camera",
+ "title", _("Camera"),
+ NULL);
+#endif /* HAVE_CHEESE */
+}
diff --git a/panels/user-accounts/um-avatar-picker.h b/panels/user-accounts/um-avatar-picker.h
new file mode 100644
index 0000000..3a19b54
--- /dev/null
+++ b/panels/user-accounts/um-avatar-picker.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * Copyright 2013 Red Hat, Inc,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Written by:
+ * Jasper St. Pierre <jstpierre mecheye net>
+ * Bogdan Ciobanu <bgdn ciobanu gmail com>
+ */
+
+#ifndef __UM_AVATAR_PICKER_H__
+#define __UM_AVATAR_PICKER_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define UM_TYPE_AVATAR_PICKER (um_avatar_picker_get_type ())
+#define UM_AVATAR_PICKER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
UM_TYPE_AVATAR_PICKER, UmAvatarPicker))
+#define UM_AVATAR_PICKER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
UM_TYPE_AVATAR_PICKER, UmAvatarPickerClass))
+#define UM_IS_AVATAR_PICKER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UM_TYPE_AVATAR_PICKER))
+#define UM_IS_AVATAR_PICKER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UM_TYPE_AVATAR_PICKER))
+#define UM_AVATAR_PICKER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
UM_TYPE_AVATAR_PICKER, UmAvatarPickerClass))
+
+typedef struct _UmAvatarPicker UmAvatarPicker;
+typedef struct _UmAvatarPickerClass UmAvatarPickerClass;
+
+struct _UmAvatarPicker
+{
+ GtkDialog parent;
+};
+
+struct _UmAvatarPickerClass
+{
+ GtkDialogClass parent_class;
+};
+
+GType um_avatar_picker_get_type (void);
+
+G_END_DECLS
+
+#endif /* __UM_AVATAR_PICKER_H__ */
diff --git a/panels/user-accounts/user-accounts-camera.gresource.xml
b/panels/user-accounts/user-accounts-camera.gresource.xml
new file mode 100644
index 0000000..cb0ed12
--- /dev/null
+++ b/panels/user-accounts/user-accounts-camera.gresource.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/org/gnome/control-center/user-accounts">
+ <file alias="avatar-picker-camera-page.ui"
preprocess="xml-stripblanks">data/avatar-picker-camera-page.ui</file>
+ </gresource>
+</gresources>
diff --git a/panels/user-accounts/user-accounts.gresource.xml
b/panels/user-accounts/user-accounts.gresource.xml
index c8fc11e..5db8c1c 100644
--- a/panels/user-accounts/user-accounts.gresource.xml
+++ b/panels/user-accounts/user-accounts.gresource.xml
@@ -6,6 +6,7 @@
<file alias="password-dialog.ui" preprocess="xml-stripblanks">data/password-dialog.ui</file>
<file alias="history-dialog.ui" preprocess="xml-stripblanks">data/history-dialog.ui</file>
<file alias="user-accounts-dialog.ui" preprocess="xml-stripblanks">data/user-accounts-dialog.ui</file>
+ <file alias="avatar-picker.ui" preprocess="xml-stripblanks">data/avatar-picker.ui</file>
<file alias="left-index-finger.png">data/icons/left-index-finger.png</file>
<file alias="left-middle-finger.png">data/icons/left-middle-finger.png</file>
<file alias="left-little-finger.png">data/icons/left-little-finger.png</file>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]