[accounts-dialog] Use a popup menu to select the user's icon
- From: Bastien Nocera <hadess src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [accounts-dialog] Use a popup menu to select the user's icon
- Date: Fri, 15 Jan 2010 15:26:39 +0000 (UTC)
commit 98005457c8ec879dceaeae5858063e636f8507cf
Author: Bastien Nocera <hadess hadess net>
Date: Fri Jan 15 11:32:28 2010 +0000
Use a popup menu to select the user's icon
In a popup menu, present the user with the various options to
select their user icon:
- Reset icon
- Set to the cropped version of a picture
- Capture via webcam using Cheese
- Select from the list of stock icons
data/user-accounts-dialog.ui | 2 +-
src/main.c | 31 +-
src/um-crop-area.c | 3 +
src/um-photo-dialog.c | 670 ++++++++++++++++++++++--------------------
src/um-photo-dialog.h | 5 +-
5 files changed, 380 insertions(+), 331 deletions(-)
---
diff --git a/data/user-accounts-dialog.ui b/data/user-accounts-dialog.ui
index 63e424b..f8b622b 100644
--- a/data/user-accounts-dialog.ui
+++ b/data/user-accounts-dialog.ui
@@ -570,7 +570,7 @@
</packing>
</child>
<child>
- <object class="GtkButton" id="user-icon-button">
+ <object class="GtkToggleButton" id="user-icon-button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
diff --git a/src/main.c b/src/main.c
index 7cd177b..79983c1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -19,6 +19,8 @@
* Written by: Matthias Clasen <mclasen redhat com>
*/
+#include "config.h"
+
#include <stdlib.h>
#include <string.h>
#include <locale.h>
@@ -32,6 +34,10 @@
#include <unique/unique.h>
#include <polkit/polkit.h>
+#ifdef HAVE_CHEESE
+#include <gst/gst.h>
+#endif /* HAVE_CHEESE */
+
#include "um-user.h"
#include "um-user-manager.h"
@@ -366,6 +372,8 @@ show_user (UmUser *user, UserAccountDialog *d)
gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
g_object_unref (pixbuf);
+ um_photo_dialog_set_user (d->photo_dialog, user);
+
label = get_widget (d, "full-name-value-label");
gtk_label_set_text (GTK_LABEL (label), um_user_get_real_name (user));
gtk_widget_set_tooltip_text (label, um_user_get_user_name (user));
@@ -676,20 +684,6 @@ selected_user_changed (GtkTreeSelection *selection, UserAccountDialog *d)
}
static void
-change_icon (GtkButton *button, UserAccountDialog *d)
-{
- UmUser *user;
-
- user = get_selected_user (d);
-
- um_photo_dialog_set_user (d->photo_dialog, user);
- um_photo_dialog_show (d->photo_dialog,
- GTK_WINDOW (get_widget (d, "user-account-window")));
-
- g_object_unref (user);
-}
-
-static void
change_name (GtkButton *button, UserAccountDialog *d)
{
UmUser *user;
@@ -1004,6 +998,7 @@ main (int argc, char *argv[])
GError *error;
const gchar *filename;
GtkWidget *dialog;
+ GtkWidget *button;
GOptionContext *context;
static gboolean do_debug;
static gboolean do_version;
@@ -1017,12 +1012,17 @@ main (int argc, char *argv[])
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
g_thread_init (NULL);
+ gdk_threads_init ();
context = g_option_context_new ("");
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
g_option_context_set_summary (context, _("Lets you edit user account information."));
g_option_context_add_main_entries (context, entries, NULL);
g_option_context_add_group (context, gtk_get_option_group (TRUE));
+#ifdef HAVE_CHEESE
+ g_option_context_add_group (context, gst_init_get_option_group ());
+#endif /* HAVE_CHEESE */
+
error = NULL;
if (!g_option_context_parse (context, &argc, &argv, &error)) {
g_warning ("%s", error->message);
@@ -1076,8 +1076,9 @@ main (int argc, char *argv[])
d->email_dialog = um_email_dialog_new ();
d->language_dialog = um_language_dialog_new ();
d->password_dialog = um_password_dialog_new ();
- d->photo_dialog = um_photo_dialog_new ();
d->location_dialog = um_location_dialog_new ();
+ button = get_widget (d, "user-icon-button");
+ d->photo_dialog = um_photo_dialog_new (button, d->main_window);
d->main_window = get_widget (d, "user-account-window");
gtk_widget_show (d->main_window);
diff --git a/src/um-crop-area.c b/src/um-crop-area.c
index 47053c0..3b19615 100644
--- a/src/um-crop-area.c
+++ b/src/um-crop-area.c
@@ -415,6 +415,9 @@ um_crop_area_motion_notify_event (GtkWidget *widget,
gint width, height, d;
UmCropArea *area = UM_CROP_AREA (widget);
+ if (area->priv->browse_pixbuf == NULL)
+ return FALSE;
+
width = gdk_pixbuf_get_width (area->priv->browse_pixbuf);
height = gdk_pixbuf_get_height (area->priv->browse_pixbuf);
diff --git a/src/um-photo-dialog.c b/src/um-photo-dialog.c
index 906a588..31edf1c 100644
--- a/src/um-photo-dialog.c
+++ b/src/um-photo-dialog.c
@@ -19,6 +19,8 @@
* Written by: Matthias Clasen <mclasen redhat com>
*/
+#include "config.h"
+
#include <stdlib.h>
#include <glib.h>
@@ -27,88 +29,85 @@
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include <libgnomeui/gnome-desktop-thumbnail.h>
+#ifdef HAVE_CHEESE
+#include <cheese-avatar-chooser.h>
+#endif /* HAVE_CHEESE */
+
#include "um-photo-dialog.h"
#include "um-user-manager.h"
#include "um-crop-area.h"
+#define ROW_SPAN 6
+
struct _UmPhotoDialog {
- GtkWidget *dialog;
- GtkWidget *user_icon;
- GtkWidget *user_name;
- GtkWidget *gallery_radio;
- GtkWidget *browse_radio;
- GtkWidget *photo_radio;
- GtkWidget *notebook;
- GtkWidget *gallery;
- GtkWidget *browse_drawing_area;
- GtkWidget *browse_scale;
- GtkWidget *ok_button;
- GtkListStore *gallery_store;
+ GtkWidget *parent_window;
+ GtkWidget *photo_popup;
+ GtkWidget *popup_button;
+ GtkWidget *crop_area;
GnomeDesktopThumbnailFactory *thumb_factory;
- GdkPixbuf *browse_pixbuf;
UmUser *user;
};
static void
-cancel_photo_dialog (GtkButton *button,
- UmPhotoDialog *um)
+crop_dialog_response (GtkWidget *dialog,
+ gint response_id,
+ UmPhotoDialog *um)
{
- gtk_widget_hide (um->dialog);
- um_photo_dialog_set_user (um, NULL);
-}
-
-static void
-accept_photo_dialog (GtkButton *button,
- UmPhotoDialog *um)
-{
- GtkTreeModel *model;
- GList *selected;
- GtkTreeIter iter;
- gchar *file;
GdkPixbuf *pb, *pb2;
- switch (gtk_notebook_get_current_page (GTK_NOTEBOOK (um->notebook))) {
- case 0:
- model = GTK_TREE_MODEL (um->gallery_store);
- selected = gtk_icon_view_get_selected_items (GTK_ICON_VIEW (um->gallery));
- if (selected == NULL)
- goto out;
-
- gtk_tree_model_get_iter (model, &iter, (GtkTreePath *)selected->data);
- g_list_foreach (selected, (GFunc)gtk_tree_path_free, NULL);
- g_list_free (selected);
-
- gtk_tree_model_get (model, &iter, 1, &file, -1);
-
- um_user_set_icon_file (um->user, file);
-
- g_free (file);
- break;
-
- case 1:
- pb = um_crop_area_get_picture (UM_CROP_AREA (um->browse_drawing_area));
- pb2 = gdk_pixbuf_scale_simple (pb, 96, 96, GDK_INTERP_BILINEAR);
+ if (response_id != GTK_RESPONSE_ACCEPT) {
+ um->crop_area = NULL;
+ gtk_widget_destroy (dialog);
+ return;
+ }
- um_user_set_icon_data (um->user, pb2);
+ pb = um_crop_area_get_picture (UM_CROP_AREA (um->crop_area));
+ pb2 = gdk_pixbuf_scale_simple (pb, 96, 96, GDK_INTERP_BILINEAR);
- g_object_unref (pb2);
- g_object_unref (pb);
+ um_user_set_icon_data (um->user, pb2);
- }
+ g_object_unref (pb2);
+ g_object_unref (pb);
-out:
- gtk_widget_hide (um->dialog);
- um_photo_dialog_set_user (um, NULL);
+ um->crop_area = NULL;
+ gtk_widget_destroy (dialog);
}
static void
-show_gallery (GtkButton *button,
- UmPhotoDialog *um)
+um_photo_dialog_crop (UmPhotoDialog *um,
+ GdkPixbuf *pixbuf)
{
- gtk_notebook_set_current_page (GTK_NOTEBOOK (um->notebook), 0);
- gtk_widget_set_sensitive (um->ok_button, TRUE);
+ GtkWidget *dialog;
+ GtkWidget *frame;
+
+ dialog = gtk_dialog_new_with_buttons ("",
+ GTK_WINDOW (um->parent_window),
+ GTK_DIALOG_NO_SEPARATOR,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_REJECT,
+ "Select",
+ GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ g_signal_connect (G_OBJECT (dialog), "response",
+ G_CALLBACK (crop_dialog_response), um);
+
+ /* Content */
+ um->crop_area = um_crop_area_new ();
+ um_crop_area_set_picture (UM_CROP_AREA (um->crop_area), pixbuf);
+ frame = gtk_frame_new (NULL);
+ gtk_container_add (GTK_CONTAINER (frame), um->crop_area);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
+
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
+ frame,
+ TRUE, TRUE, 8);
+
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 300);
+
+ gtk_widget_show_all (dialog);
}
static void
@@ -120,35 +119,30 @@ file_chooser_response (GtkDialog *chooser,
GError *error;
GdkPixbuf *pixbuf;
- if (response == GTK_RESPONSE_ACCEPT) {
- filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
-
- error = NULL;
- pixbuf = gdk_pixbuf_new_from_file (filename, &error);
- if (pixbuf == NULL) {
- g_warning ("Failed to load %s: %s", filename, error->message);
- g_error_free (error);
- }
- if (um->browse_pixbuf)
- g_object_unref (um->browse_pixbuf);
- um->browse_pixbuf = pixbuf;
-
- um_crop_area_set_picture (UM_CROP_AREA (um->browse_drawing_area), pixbuf);
+ if (response != GTK_RESPONSE_ACCEPT) {
+ gtk_widget_destroy (GTK_WIDGET (chooser));
+ return;
+ }
- g_free (filename);
+ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
- gtk_widget_set_sensitive (um->ok_button, TRUE);
- }
- else {
- gtk_widget_set_sensitive (um->ok_button, FALSE);
+ error = NULL;
+ pixbuf = gdk_pixbuf_new_from_file (filename, &error);
+ if (pixbuf == NULL) {
+ g_warning ("Failed to load %s: %s", filename, error->message);
+ g_error_free (error);
}
+ g_free (filename);
gtk_widget_destroy (GTK_WIDGET (chooser));
+
+ um_photo_dialog_crop (um, pixbuf);
+ g_object_unref (pixbuf);
}
static void
-update_preview (GtkFileChooser *chooser,
- UmPhotoDialog *um)
+update_preview (GtkFileChooser *chooser,
+ GnomeDesktopThumbnailFactory *thumb_factory)
{
gchar *uri;
@@ -176,7 +170,7 @@ update_preview (GtkFileChooser *chooser,
}
if (mime_type) {
- pixbuf = gnome_desktop_thumbnail_factory_generate_thumbnail (um->thumb_factory,
+ pixbuf = gnome_desktop_thumbnail_factory_generate_thumbnail (thumb_factory,
uri,
mime_type);
}
@@ -198,27 +192,20 @@ update_preview (GtkFileChooser *chooser,
}
static void
-show_files (GtkButton *button,
- UmPhotoDialog *um)
+um_photo_dialog_select_file (UmPhotoDialog *um)
{
GtkWidget *chooser;
const gchar *folder;
GtkWidget *preview;
- if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
- return;
-
- gtk_notebook_set_current_page (GTK_NOTEBOOK (um->notebook), 1);
-
chooser = gtk_file_chooser_dialog_new (_("Browse for more pictures"),
- GTK_WINDOW (um->dialog),
+ GTK_WINDOW (um->parent_window),
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL);
- gtk_window_set_modal (GTK_WINDOW (chooser),
- gtk_window_get_modal (GTK_WINDOW (um->dialog)));
+ gtk_window_set_modal (GTK_WINDOW (chooser), TRUE);
preview = gtk_image_new ();
gtk_widget_set_size_request (preview, 128, -1);
@@ -226,7 +213,7 @@ show_files (GtkButton *button,
gtk_file_chooser_set_use_preview_label (GTK_FILE_CHOOSER (chooser), FALSE);
gtk_widget_show (preview);
g_signal_connect (chooser, "update-preview",
- G_CALLBACK (update_preview), um);
+ G_CALLBACK (update_preview), um->thumb_factory);
folder = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES);
if (folder)
@@ -237,200 +224,266 @@ show_files (GtkButton *button,
G_CALLBACK (file_chooser_response), um);
gtk_window_present (GTK_WINDOW (chooser));
- gtk_widget_set_sensitive (um->ok_button, FALSE);
}
static void
-show_photo (GtkButton *button,
- UmPhotoDialog *um)
+none_icon_selected (GtkMenuItem *menuitem,
+ UmPhotoDialog *um)
{
- gtk_notebook_set_current_page (GTK_NOTEBOOK (um->notebook), 2);
- gtk_widget_set_sensitive (um->ok_button, FALSE);
+ um_user_set_icon_file (um->user, NULL);
}
static void
-load_faces (UmPhotoDialog *um)
+file_icon_selected (GtkMenuItem *menuitem,
+ UmPhotoDialog *um)
{
- GDir *dir;
- const gchar *face;
- gchar *filename;
+ um_photo_dialog_select_file (um);
+}
+
+#ifdef HAVE_CHEESE
+static gboolean
+destroy_chooser (GtkWidget *chooser)
+{
+ gtk_widget_destroy (chooser);
+ return FALSE;
+}
+
+static void
+webcam_response_cb (GtkDialog *dialog,
+ int response,
+ UmPhotoDialog *um)
+{
+ if (response == GTK_RESPONSE_ACCEPT) {
+ GdkPixbuf *pb, *pb2;
+
+ g_object_get (G_OBJECT (dialog), "pixbuf", &pb, NULL);
+ pb2 = gdk_pixbuf_scale_simple (pb, 96, 96, GDK_INTERP_BILINEAR);
+
+ um_user_set_icon_data (um->user, pb2);
+
+ g_object_unref (pb2);
+ g_object_unref (pb);
+ }
+ if (response != GTK_RESPONSE_DELETE_EVENT &&
+ response != GTK_RESPONSE_NONE)
+ g_idle_add ((GSourceFunc) destroy_chooser, dialog);
+}
+
+static void
+webcam_icon_selected (GtkMenuItem *menuitem,
+ UmPhotoDialog *um)
+{
+ GtkWidget *window;
+
+ window = cheese_avatar_chooser_new ();
+ gtk_window_set_transient_for (GTK_WINDOW (window),
+ GTK_WINDOW (um->parent_window));
+ g_signal_connect (G_OBJECT (window), "response",
+ G_CALLBACK (webcam_response_cb), um);
+ gtk_widget_show (window);
+}
+#endif /* HAVE_CHEESE */
+
+static void
+stock_icon_selected (GtkMenuItem *menuitem,
+ UmPhotoDialog *um)
+{
+ const char *filename;
+
+ filename = g_object_get_data (G_OBJECT (menuitem), "filename");
+ um_user_set_icon_file (um->user, filename);
+}
+
+static GtkWidget *
+menu_item_for_filename (UmPhotoDialog *um,
+ const char *filename)
+{
+ GtkWidget *image, *menuitem;
GFile *file;
GIcon *icon;
- GtkListStore *store;
- GtkTreeIter iter;
- /* TODO load incrementally, add recent images, add user faces */
- store = gtk_list_store_new (4, G_TYPE_ICON, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_STRING);
+ file = g_file_new_for_path (filename);
+ icon = g_file_icon_new (file);
+ g_object_unref (file);
+ image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_DIALOG);
+ g_object_unref (icon);
+
+ menuitem = gtk_menu_item_new ();
+ gtk_container_add (GTK_CONTAINER (menuitem), image);
+ gtk_widget_show_all (menuitem);
+
+ 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);
+
+ return menuitem;
+}
+
+static void
+setup_photo_popup (UmPhotoDialog *um)
+{
+ GtkWidget *menu, *menuitem;
+ guint x, y;
+ GDir *dir;
+ const char *face;
+
+ menu = gtk_menu_new ();
+
+ menuitem = gtk_menu_item_new_with_label (_("None"));
+ gtk_menu_attach (GTK_MENU (menu), GTK_WIDGET (menuitem),
+ 0, ROW_SPAN - 1, 0, 1);
+ g_signal_connect (G_OBJECT (menuitem), "activate",
+ G_CALLBACK (none_icon_selected), um);
+ gtk_widget_show (menuitem);
+
+ menuitem = gtk_menu_item_new_with_label (_("Browse for more pictures..."));
+ gtk_menu_attach (GTK_MENU (menu), GTK_WIDGET (menuitem),
+ 0, ROW_SPAN - 1, 1, 2);
+ g_signal_connect (G_OBJECT (menuitem), "activate",
+ G_CALLBACK (file_icon_selected), um);
+ gtk_widget_show (menuitem);
+
+#ifdef HAVE_CHEESE
+ menuitem = gtk_menu_item_new_with_label (_("Take a photograph..."));
+ gtk_menu_attach (GTK_MENU (menu), GTK_WIDGET (menuitem),
+ 0, ROW_SPAN - 1, 2, 3);
+ g_signal_connect (G_OBJECT (menuitem), "activate",
+ G_CALLBACK (webcam_icon_selected), um);
+ gtk_widget_show (menuitem);
+#endif /* HAVE_CHEESE */
+
+ /* Separator */
+ menuitem = gtk_separator_menu_item_new ();
+#ifdef HAVE_CHEESE
+ gtk_menu_attach (GTK_MENU (menu), GTK_WIDGET (menuitem),
+ 0, ROW_SPAN - 1, 3, 4);
+#else
+ gtk_menu_attach (GTK_MENU (menu), GTK_WIDGET (menuitem),
+ 0, ROW_SPAN - 1, 2, 3);
+#endif /* HAVE_CHEESE */
+ gtk_widget_show (menuitem);
+
+ x = 0;
+#ifdef HAVE_CHEESE
+ y = 5;
+#else
+ y = 4;
+#endif /* HAVE_CHEESE */
dir = g_dir_open (DATADIR "/pixmaps/faces", 0, NULL);
while ((face = g_dir_read_name (dir)) != NULL) {
+ char *filename;
+
filename = g_build_filename (DATADIR "/pixmaps/faces", face, NULL);
- file = g_file_new_for_path (filename);
- icon = g_file_icon_new (file);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, icon, 1, filename, 2, TRUE, 3, NULL, -1);
- g_object_unref (icon);
- g_object_unref (file);
+ menuitem = menu_item_for_filename (um, 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_dir_close (dir);
- gtk_icon_view_set_model (GTK_ICON_VIEW (um->gallery), GTK_TREE_MODEL (store));
- um->gallery_store = store;
+ um->photo_popup = menu;
}
static void
-gallery_selection_changed (GtkIconView *gallery,
- UmPhotoDialog *um)
+popup_icon_menu_position (GtkMenu *menu,
+ gint *x,
+ gint *y,
+ gboolean *push_in,
+ UmPhotoDialog *um)
{
- GList *list;
- GtkTreeModel *model;
- GtkTreePath *path;
- GtkTreeIter iter;
- gboolean can_select;
-
- model = GTK_TREE_MODEL (um->gallery_store);
- list = gtk_icon_view_get_selected_items (gallery);
- if (list == NULL) {
- can_select = FALSE;
- goto out;
- }
+ GtkRequisition menu_req;
+ GtkTextDirection direction;
+ GtkAllocation allocation;
- path = list->data;
+ gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_model_get (model, &iter, 2, &can_select, -1);
+ direction = gtk_widget_get_direction (um->popup_button);
- g_list_foreach (list, (GFunc)gtk_tree_path_free, NULL);
- g_list_free (list);
+ gdk_window_get_origin (gtk_widget_get_window (um->popup_button), x, y);
+ gtk_widget_get_allocation (um->popup_button, &allocation);
+ *x += allocation.x;
+ *y += allocation.y + allocation.height;
-out:
- gtk_widget_set_sensitive (um->ok_button, can_select);
+ if (direction == GTK_TEXT_DIR_LTR)
+ *x += MAX (allocation.width - menu_req.width, 0);
+ else if (menu_req.width > allocation.width)
+ *x -= menu_req.width - allocation.width;
+
+ *push_in = TRUE;
}
static void
-gallery_item_activated (GtkIconView *gallery,
- GtkTreePath *path,
- UmPhotoDialog *um)
+popup_icon_menu (GtkToggleButton *button, UmPhotoDialog *um)
{
- GtkTreeModel *model;
- GtkTreeIter iter;
- gboolean can_select;
- gchar *file;
-
- model = GTK_TREE_MODEL (um->gallery_store);
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_model_get (model, &iter, 2, &can_select, -1);
-
- if (!can_select)
- return;
-
- gtk_tree_model_get (model, &iter, 1, &file, -1);
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) && !GTK_WIDGET_VISIBLE (um->photo_popup)) {
+ gtk_menu_popup (GTK_MENU (um->photo_popup),
+ NULL, NULL,
+ (GtkMenuPositionFunc) popup_icon_menu_position, um,
+ 0, gtk_get_current_event_time ());
+ } else {
+ gtk_menu_popdown (GTK_MENU (um->photo_popup));
+ }
+}
- um_user_set_icon_file (um->user, file);
+static gboolean
+on_popup_button_button_pressed (GtkToggleButton *button,
+ GdkEventButton *event,
+ UmPhotoDialog *um)
+{
+ if (event->button == 1) {
+ if (!GTK_WIDGET_VISIBLE (um->photo_popup)) {
+ 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_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
+ }
- g_free (file);
+ return TRUE;
+ }
- gtk_widget_hide (um->dialog);
- um_photo_dialog_set_user (um, NULL);
+ return FALSE;
}
static void
-scale_changed (GtkRange *range,
- UmPhotoDialog *um)
+on_photo_popup_unmap (GtkWidget *popup_menu,
+ UmPhotoDialog *um)
{
- gtk_widget_queue_draw (um->browse_drawing_area);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (um->popup_button), FALSE);
}
UmPhotoDialog *
-um_photo_dialog_new (void)
+um_photo_dialog_new (GtkWidget *button, GtkWidget *parent)
{
- GtkBuilder *builder;
- GtkWidget *widget;
UmPhotoDialog *um;
- const gchar *filename;
- GError *error = NULL;
- GtkCellRenderer *cell;
-
- builder = gtk_builder_new ();
-
- filename = DATADIR "/" PACKAGE_NAME "/photo-dialog.ui";
- if (!g_file_test (filename, G_FILE_TEST_EXISTS))
- filename = "../data/photo-dialog.ui";
- if (!gtk_builder_add_from_file (builder, filename, &error)) {
- g_error ("%s", error->message);
- g_error_free (error);
- exit (1);
- }
um = g_new0 (UmPhotoDialog, 1);
- widget = (GtkWidget *) gtk_builder_get_object (builder, "dialog");
- g_signal_connect (widget, "delete-event",
- G_CALLBACK (gtk_widget_hide_on_delete), NULL);
- um->dialog = widget;
-
- um->notebook = (GtkWidget *) gtk_builder_get_object (builder, "notebook");
- um->user_icon = (GtkWidget *) gtk_builder_get_object (builder, "user-icon");
- um->user_name = (GtkWidget *) gtk_builder_get_object (builder, "user-name");
-
- widget = (GtkWidget *) gtk_builder_get_object (builder, "cancel-button");
- g_signal_connect (widget, "clicked",
- G_CALLBACK (cancel_photo_dialog), um);
-
- widget = (GtkWidget *) gtk_builder_get_object (builder, "ok-button");
- g_signal_connect (widget, "clicked",
- G_CALLBACK (accept_photo_dialog), um);
- um->ok_button = widget;
- gtk_widget_grab_default (widget);
-
- widget = (GtkWidget *) gtk_builder_get_object (builder, "gallery-radiobutton");
- g_signal_connect (widget, "clicked",
- G_CALLBACK (show_gallery), um);
- um->gallery_radio = widget;
-
- widget = (GtkWidget *) gtk_builder_get_object (builder, "browse-radiobutton");
- g_signal_connect (widget, "clicked",
- G_CALLBACK (show_files), um);
- um->browse_radio = widget;
-
- widget = (GtkWidget *) gtk_builder_get_object (builder, "photo-radiobutton");
- g_signal_connect (widget, "clicked",
- G_CALLBACK (show_photo), um);
- um->photo_radio = widget;
-
- widget = (GtkWidget *) gtk_builder_get_object (builder, "gallery");
- g_signal_connect (widget, "selection-changed",
- G_CALLBACK (gallery_selection_changed), um);
- g_signal_connect (widget, "item-activated",
- G_CALLBACK (gallery_item_activated), um);
- gtk_icon_view_set_item_padding (GTK_ICON_VIEW (widget), 4);
- gtk_icon_view_set_row_spacing (GTK_ICON_VIEW (widget), 0);
- gtk_icon_view_set_column_spacing (GTK_ICON_VIEW (widget), 0);
- gtk_widget_set_size_request (widget, 248, -1);
- cell = gtk_cell_renderer_pixbuf_new ();
- g_object_set (cell, "stock-size", GTK_ICON_SIZE_DIALOG, NULL);
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), cell, FALSE);
- gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (widget), cell, "gicon", 0);
- gtk_icon_view_set_tooltip_column (GTK_ICON_VIEW (widget), 3);
-
- um->gallery = widget;
-
um->thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
- /* FIXME replace drawing area with UmCropArea */
- widget = (GtkWidget *) gtk_builder_get_object (builder, "browse-drawing-area");
- gtk_widget_destroy (widget);
- um->browse_drawing_area = um_crop_area_new ();
- widget = (GtkWidget *) gtk_builder_get_object (builder, "vbox1234");
- gtk_box_pack_start (GTK_BOX (widget), um->browse_drawing_area, TRUE, TRUE, 0);
- gtk_widget_show (um->browse_drawing_area);
+ /* 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 (G_OBJECT (um->popup_button), "button-press-event",
+ G_CALLBACK (on_popup_button_button_pressed), um);
+ g_signal_connect (um->photo_popup, "unmap",
+ G_CALLBACK (on_photo_popup_unmap), um);
- widget = (GtkWidget *) gtk_builder_get_object (builder, "browse-scale");
- g_signal_connect (widget, "value-changed",
- G_CALLBACK (scale_changed), um);
- um->browse_scale = widget;
-
- load_faces (um);
+ /* Parent window */
+ um->parent_window = parent;
return um;
}
@@ -438,7 +491,10 @@ um_photo_dialog_new (void)
void
um_photo_dialog_free (UmPhotoDialog *um)
{
- gtk_widget_destroy (um->dialog);
+ gtk_widget_destroy (um->photo_popup);
+
+ if (um->thumb_factory)
+ g_object_unref (um->thumb_factory);
if (um->user)
g_object_unref (um->user);
@@ -446,47 +502,68 @@ um_photo_dialog_free (UmPhotoDialog *um)
g_free (um);
}
-static gboolean
-clear_tip (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data)
+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;
- gtk_tree_model_get (model, iter, 0, &icon, -1);
+ 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
- icon2 = icon;
+ return;
- gtk_list_store_set ((GtkListStore *)model, iter,
- 0, icon2,
- 2, TRUE,
- 3, NULL,
- -1);
+ gtk_image_set_from_gicon (GTK_IMAGE (image), icon2, GTK_ICON_SIZE_DIALOG);
g_object_unref (icon);
+}
- return FALSE;
+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);
+ g_object_ref (emblem);
+ icon2 = g_emblemed_icon_new (icon, emblem);
+ gtk_image_set_from_gicon (GTK_IMAGE (image), icon2, GTK_ICON_SIZE_DIALOG);
+
+ gtk_widget_set_tooltip_text (GTK_WIDGET (item), tip);
}
void
um_photo_dialog_set_user (UmPhotoDialog *um,
UmUser *user)
{
- GdkPixbuf *pixbuf;
- const gchar *name;
- GtkTreeModel *model;
- GtkTreeIter iter;
- GtkTreePath *path;
UmUserManager *manager;
GSList *list, *l;
UmUser *u;
- const gchar *filename;
- gchar *tip, *f;
- GIcon *icon, *icon2;
+ GIcon *icon;
GEmblem *emblem;
+ GList *children, *c;
g_return_if_fail (um != NULL);
@@ -495,18 +572,12 @@ um_photo_dialog_set_user (UmPhotoDialog *um,
um->user = NULL;
}
um->user = user;
+
if (um->user) {
g_object_ref (user);
- pixbuf = um_user_render_icon (user, FALSE, 48);
- gtk_image_set_from_pixbuf (GTK_IMAGE (um->user_icon), pixbuf);
- g_object_unref (pixbuf);
-
- name = um_user_get_real_name (user);
- gtk_label_set_label (GTK_LABEL (um->user_name), name);
-
- model = GTK_TREE_MODEL (um->gallery_store);
- gtk_tree_model_foreach (model, clear_tip, NULL);
+ children = gtk_container_get_children (GTK_CONTAINER (um->photo_popup));
+ g_list_foreach (children, (GFunc) clear_tip, NULL);
manager = um_user_manager_ref_default ();
list = um_user_manager_list_users (manager);
@@ -517,59 +588,34 @@ um_photo_dialog_set_user (UmPhotoDialog *um,
g_object_unref (icon);
for (l = list; l; l = l->next) {
+ const char *filename;
+
u = l->data;
+ if (u == user)
+ continue;
filename = um_user_get_icon_file (u);
if (filename == NULL)
continue;
- gtk_tree_model_get_iter_first (model, &iter);
- do {
- gtk_tree_model_get (model, &iter, 1, &f, -1);
- if (g_strcmp0 (f, filename) == 0) {
- if (u == user) {
- path = gtk_tree_model_get_path (model, &iter);
- gtk_icon_view_select_path (GTK_ICON_VIEW (um->gallery), path);
- gtk_tree_path_free (path);
- }
- else {
- tip = g_strdup_printf (_("Used by %s"),
- um_user_get_real_name (u));
- gtk_tree_model_get (model, &iter, 0, &icon, -1);
- icon2 = g_emblemed_icon_new (icon, emblem);
- gtk_list_store_set ((GtkListStore*)model, &iter,
- 0, icon2,
- 2, FALSE,
- 3, tip,
- -1);
- g_object_unref (icon);
- g_object_unref (icon2);
- g_free (tip);
- }
-
- g_free (f);
+ 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"),
+ um_user_get_real_name (u));
+ set_tip (GTK_WIDGET (c->data), tip, emblem);
+ g_free (tip);
break;
}
- g_free (f);
- } while (gtk_tree_model_iter_next (model, &iter));
+ }
}
g_slist_free (list);
g_object_unref (emblem);
-
- gallery_selection_changed (GTK_ICON_VIEW (um->gallery), um);
-
- gtk_notebook_set_current_page (GTK_NOTEBOOK (um->notebook), 0);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (um->gallery_radio), TRUE);
- if (um->browse_pixbuf) {
- g_object_unref (um->browse_pixbuf);
- um->browse_pixbuf = NULL;
- }
}
}
-void
-um_photo_dialog_show (UmPhotoDialog *um,
- GtkWindow *parent)
-{
- gtk_window_set_transient_for (GTK_WINDOW (um->dialog), parent);
- gtk_window_present (GTK_WINDOW (um->dialog));
-}
diff --git a/src/um-photo-dialog.h b/src/um-photo-dialog.h
index 32a975c..f5a9b5f 100644
--- a/src/um-photo-dialog.h
+++ b/src/um-photo-dialog.h
@@ -29,12 +29,11 @@ G_BEGIN_DECLS
typedef struct _UmPhotoDialog UmPhotoDialog;
-UmPhotoDialog *um_photo_dialog_new (void);
+UmPhotoDialog *um_photo_dialog_new (GtkWidget *button,
+ GtkWidget *parent);
void um_photo_dialog_free (UmPhotoDialog *dialog);
void um_photo_dialog_set_user (UmPhotoDialog *dialog,
UmUser *user);
-void um_photo_dialog_show (UmPhotoDialog *dialog,
- GtkWindow *parent);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]