[appearance] Make slideshows visually distinct

The patch fixes the tooltips to not lie about the backgrounds, and adds a
stacked frame decoration around slide shows.

This patch adds two little buttons below the slide show that let you step
through the frames of the slide show, to see whats in it.

Fixes http://bugzilla.gnome.org/show_bug.cgi?id=591375
This commit is contained in:
Matthias Clasen 2009-08-25 12:55:39 -04:00 committed by William Jon McCann
parent d0f766937f
commit 3a88e51353
5 changed files with 255 additions and 23 deletions

View file

@ -131,9 +131,7 @@ static void on_item_changed (GnomeBG *bg, AppearanceData *data) {
pixbuf = gnome_wp_item_get_thumbnail (item, data->thumb_factory); pixbuf = gnome_wp_item_get_thumbnail (item, data->thumb_factory);
if (pixbuf) { if (pixbuf) {
gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter, gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter, 0, pixbuf, -1);
0, pixbuf,
-1);
g_object_unref (pixbuf); g_object_unref (pixbuf);
} }
@ -316,10 +314,7 @@ wp_scale_type_changed (GtkComboBox *combobox,
item->options = gtk_combo_box_get_active (GTK_COMBO_BOX (data->wp_style_menu)); item->options = gtk_combo_box_get_active (GTK_COMBO_BOX (data->wp_style_menu));
pixbuf = gnome_wp_item_get_thumbnail (item, data->thumb_factory); pixbuf = gnome_wp_item_get_thumbnail (item, data->thumb_factory);
gtk_list_store_set (GTK_LIST_STORE (data->wp_model), gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter, 0, pixbuf, -1);
&iter,
0, pixbuf,
-1);
if (pixbuf != NULL) if (pixbuf != NULL)
g_object_unref (pixbuf); g_object_unref (pixbuf);
@ -344,9 +339,7 @@ wp_shade_type_changed (GtkWidget *combobox,
item->shade_type = gtk_combo_box_get_active (GTK_COMBO_BOX (data->wp_color_menu)); item->shade_type = gtk_combo_box_get_active (GTK_COMBO_BOX (data->wp_color_menu));
pixbuf = gnome_wp_item_get_thumbnail (item, data->thumb_factory); pixbuf = gnome_wp_item_get_thumbnail (item, data->thumb_factory);
gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter, gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter, 0, pixbuf, -1);
0, pixbuf,
-1);
if (pixbuf != NULL) if (pixbuf != NULL)
g_object_unref (pixbuf); g_object_unref (pixbuf);
@ -991,6 +984,162 @@ wp_select_after_realize (GtkWidget *widget,
select_item (data, item, TRUE); select_item (data, item, TRUE);
} }
static GdkPixbuf *buttons[3];
static void
create_button_images (AppearanceData *data)
{
GtkWidget *widget = (GtkWidget*)data->wp_view;
GtkIconSet *icon_set;
GdkPixbuf *pixbuf, *pb, *pb2;
gint i, w, h;
icon_set = gtk_style_lookup_icon_set (widget->style, "gtk-media-play");
pb = gtk_icon_set_render_icon (icon_set,
widget->style,
GTK_TEXT_DIR_RTL,
GTK_STATE_NORMAL,
GTK_ICON_SIZE_MENU,
widget,
NULL);
pb2 = gtk_icon_set_render_icon (icon_set,
widget->style,
GTK_TEXT_DIR_LTR,
GTK_STATE_NORMAL,
GTK_ICON_SIZE_MENU,
widget,
NULL);
w = gdk_pixbuf_get_width (pb);
h = gdk_pixbuf_get_height (pb);
for (i = 0; i < 3; i++) {
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 2 * w, h);
gdk_pixbuf_fill (pixbuf, 0);
if (i > 0)
gdk_pixbuf_composite (pb, pixbuf, 0, 0, w, h, 0, 0, 1, 1, GDK_INTERP_NEAREST, 255);
if (i < 2)
gdk_pixbuf_composite (pb2, pixbuf, w, 0, w, h, w, 0, 1, 1, GDK_INTERP_NEAREST, 255);
buttons[i] = pixbuf;
}
g_object_unref (pb);
g_object_unref (pb2);
}
static gboolean
next_frame (AppearanceData *data,
GtkCellRenderer *cr,
gint direction)
{
GnomeWPItem *item;
GtkTreeIter iter;
GdkPixbuf *pixbuf, *pb;
gint frame;
pixbuf = NULL;
frame = data->frame + direction;
item = get_selected_item (data, &iter);
if (frame >= 0)
pixbuf = gnome_wp_item_get_frame_thumbnail (item, data->thumb_factory, frame);
if (pixbuf) {
gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter, 0, pixbuf, -1);
g_object_unref (pixbuf);
data->frame = frame;
}
pb = buttons[1];
if (direction < 0) {
if (frame == 0)
pb = buttons[0];
}
else {
pixbuf = gnome_wp_item_get_frame_thumbnail (item, data->thumb_factory, frame + 1);
if (pixbuf)
g_object_unref (pixbuf);
else
pb = buttons[2];
}
g_object_set (cr, "pixbuf", pb, NULL);
}
static gboolean
wp_button_press_cb (GtkWidget *widget,
GdkEventButton *event,
AppearanceData *data)
{
GtkCellRenderer *cell;
GdkEventButton *button_event = (GdkEventButton *) event;
if (event->type != GDK_BUTTON_PRESS)
return FALSE;
if (gtk_icon_view_get_item_at_pos (GTK_ICON_VIEW (widget),
button_event->x, button_event->y,
NULL, &cell)) {
if (g_object_get_data (G_OBJECT (cell), "buttons")) {
gint w, h;
GtkCellRenderer *cell2 = NULL;
gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
if (gtk_icon_view_get_item_at_pos (GTK_ICON_VIEW (widget),
button_event->x + w, button_event->y,
NULL, &cell2) && cell == cell2)
next_frame (data, cell, -1);
else
next_frame (data, cell, 1);
return TRUE;
}
}
return FALSE;
}
static void
wp_selected_changed_cb (GtkIconView *view,
AppearanceData *data)
{
GtkCellRenderer *cr;
GList *cells, *l;
data->frame = -1;
cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (data->wp_view));
for (l = cells; l; l = l->next) {
cr = l->data;
if (g_object_get_data (cr, "buttons"))
g_object_set (cr, "pixbuf", buttons[0], NULL);
}
g_list_free (cells);
}
static void
buttons_cell_data_func (GtkCellLayout *layout,
GtkCellRenderer *cell,
GtkTreeModel *model,
GtkTreeIter *iter,
gpointer user_data)
{
AppearanceData *data = user_data;
GtkTreePath *path;
GnomeWPItem *item;
gboolean visible;
path = gtk_tree_model_get_path (model, iter);
if (gtk_icon_view_path_is_selected (GTK_ICON_VIEW (layout), path)) {
item = get_selected_item (data, NULL);
visible = gnome_bg_changes_with_time (item->bg);
}
else
visible = FALSE;
g_object_set (G_OBJECT (cell), "visible", visible, NULL);
gtk_tree_path_free (path);
}
void void
desktop_init (AppearanceData *data, desktop_init (AppearanceData *data,
const gchar **uris) const gchar **uris)
@ -1067,6 +1216,24 @@ desktop_init (AppearanceData *data,
"pixbuf", 0, "pixbuf", 0,
NULL); NULL);
cr = gtk_cell_renderer_pixbuf_new ();
create_button_images (data);
g_object_set (cr,
"mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE,
"pixbuf", buttons[0],
NULL);
g_object_set_data (G_OBJECT (cr), "buttons", GINT_TO_POINTER (TRUE));
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (data->wp_view), cr, FALSE);
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (data->wp_view), cr,
buttons_cell_data_func, data, NULL);
g_signal_connect (data->wp_view, "selection-changed",
(GCallback) wp_selected_changed_cb, data);
g_signal_connect (data->wp_view, "button-press-event",
G_CALLBACK (wp_button_press_cb), data);
data->frame = -1;
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (data->wp_model), 2, gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (data->wp_model), 2,
(GtkTreeIterCompareFunc) wp_list_sort, (GtkTreeIterCompareFunc) wp_list_sort,
data, NULL); data, NULL);

View file

@ -50,6 +50,7 @@ typedef struct
GtkFileChooser *wp_filesel; GtkFileChooser *wp_filesel;
GtkWidget *wp_image; GtkWidget *wp_image;
GSList *wp_uris; GSList *wp_uris;
gint frame;
/* font */ /* font */
GtkWidget *font_details; GtkWidget *font_details;

View file

@ -140,9 +140,9 @@ GnomeWPItem * gnome_wp_item_new (const gchar * filename,
item->name = g_filename_to_utf8 (item->fileinfo->name, -1, NULL, item->name = g_filename_to_utf8 (item->fileinfo->name, -1, NULL,
NULL, NULL); NULL, NULL);
gnome_wp_item_ensure_gnome_bg (item);
gnome_wp_item_update (item); gnome_wp_item_update (item);
gnome_wp_item_update_description (item); gnome_wp_item_update_description (item);
gnome_wp_item_ensure_gnome_bg (item);
g_hash_table_insert (wallpapers, item->filename, item); g_hash_table_insert (wallpapers, item->filename, item);
} else { } else {
@ -177,24 +177,71 @@ void gnome_wp_item_free (GnomeWPItem * item) {
g_free (item); g_free (item);
} }
static GdkPixbuf *
add_slideshow_frame (GdkPixbuf *pixbuf)
{
GdkPixbuf *sheet, *sheet2;
GdkPixbuf *tmp;
gint w, h;
w = gdk_pixbuf_get_width (pixbuf);
h = gdk_pixbuf_get_height (pixbuf);
sheet = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, w, h);
gdk_pixbuf_fill (sheet, 0x00000000);
sheet2 = gdk_pixbuf_new_subpixbuf (sheet, 1, 1, w - 2, h - 2);
gdk_pixbuf_fill (sheet2, 0xffffffff);
g_object_unref (sheet2);
tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, w + 6, h + 6);
gdk_pixbuf_fill (tmp, 0x00000000);
gdk_pixbuf_composite (sheet, tmp, 6, 6, w, h, 6.0, 6.0, 1.0, 1.0, GDK_INTERP_NEAREST, 255);
gdk_pixbuf_composite (sheet, tmp, 3, 3, w, h, 3.0, 3.0, 1.0, 1.0, GDK_INTERP_NEAREST, 255);
gdk_pixbuf_composite (pixbuf, tmp, 0, 0, w, h, 0.0, 0.0, 1.0, 1.0, GDK_INTERP_NEAREST, 255);
g_object_unref (sheet);
return tmp;
}
#define LIST_IMAGE_WIDTH 108 #define LIST_IMAGE_WIDTH 108
GdkPixbuf * gnome_wp_item_get_thumbnail (GnomeWPItem * item, GdkPixbuf * gnome_wp_item_get_frame_thumbnail (GnomeWPItem * item,
GnomeDesktopThumbnailFactory * thumbs) { GnomeDesktopThumbnailFactory * thumbs,
GdkPixbuf *pixbuf; gint frame) {
GdkPixbuf *pixbuf = NULL;
double aspect = double aspect =
(double)gdk_screen_get_height (gdk_screen_get_default()) / (double)gdk_screen_get_height (gdk_screen_get_default()) /
gdk_screen_get_width (gdk_screen_get_default()); gdk_screen_get_width (gdk_screen_get_default());
set_bg_properties (item); set_bg_properties (item);
if (frame != -1)
pixbuf = gnome_bg_create_frame_thumbnail (item->bg, thumbs, gdk_screen_get_default (), LIST_IMAGE_WIDTH, LIST_IMAGE_WIDTH * aspect, frame);
else
pixbuf = gnome_bg_create_thumbnail (item->bg, thumbs, gdk_screen_get_default(), LIST_IMAGE_WIDTH, LIST_IMAGE_WIDTH * aspect); pixbuf = gnome_bg_create_thumbnail (item->bg, thumbs, gdk_screen_get_default(), LIST_IMAGE_WIDTH, LIST_IMAGE_WIDTH * aspect);
if (pixbuf && gnome_bg_changes_with_time (item->bg))
{
GdkPixbuf *tmp;
tmp = add_slideshow_frame (pixbuf);
g_object_unref (pixbuf);
pixbuf = tmp;
}
gnome_bg_get_image_size (item->bg, thumbs, &item->width, &item->height); gnome_bg_get_image_size (item->bg, thumbs, &item->width, &item->height);
return pixbuf; return pixbuf;
} }
GdkPixbuf * gnome_wp_item_get_thumbnail (GnomeWPItem * item,
GnomeDesktopThumbnailFactory * thumbs) {
return gnome_wp_item_get_frame_thumbnail (item, thumbs, -1);
}
void gnome_wp_item_update_description (GnomeWPItem * item) { void gnome_wp_item_update_description (GnomeWPItem * item) {
g_free (item->description); g_free (item->description);
@ -202,27 +249,41 @@ void gnome_wp_item_update_description (GnomeWPItem * item) {
item->description = g_strdup (item->name); item->description = g_strdup (item->name);
} else { } else {
const gchar *description; const gchar *description;
gchar *size;
gchar *dirname = g_path_get_dirname (item->filename); gchar *dirname = g_path_get_dirname (item->filename);
if (strcmp (item->fileinfo->mime_type, "application/xml") == 0) if (strcmp (item->fileinfo->mime_type, "application/xml") == 0)
{
if (gnome_bg_changes_with_time (item->bg))
description = _("Slide Show"); description = _("Slide Show");
else
description = _("Image");
}
else else
description = g_content_type_get_description (item->fileinfo->mime_type); description = g_content_type_get_description (item->fileinfo->mime_type);
/* translators: <b>wallpaper name</b> if (gnome_bg_changes_with_size (item->bg))
* mime type, x pixel(s) by y pixel(s) size = g_strdup (_("multiple sizes"));
* Folder: /path/to/file else
*/ /* translators: x pixel(s) by y pixel(s) */
item->description = g_markup_printf_escaped (_("<b>%s</b>\n" size = g_strdup_printf ("%d %s by %d %s",
"%s, %d %s by %d %s\n"
"Folder: %s"),
item->name,
description,
item->width, item->width,
ngettext ("pixel", "pixels", item->width), ngettext ("pixel", "pixels", item->width),
item->height, item->height,
ngettext ("pixel", "pixels", item->height), ngettext ("pixel", "pixels", item->height));
/* translators: <b>wallpaper name</b>
* mime type, size
* Folder: /path/to/file
*/
item->description = g_markup_printf_escaped (_("<b>%s</b>\n"
"%s, %s\n"
"Folder: %s"),
item->name,
description,
size,
dirname); dirname);
g_free (size);
g_free (dirname); g_free (dirname);
} }
} }

View file

@ -72,6 +72,9 @@ GnomeWPItem * gnome_wp_item_new (const gchar *filename,
void gnome_wp_item_free (GnomeWPItem *item); void gnome_wp_item_free (GnomeWPItem *item);
GdkPixbuf * gnome_wp_item_get_thumbnail (GnomeWPItem *item, GdkPixbuf * gnome_wp_item_get_thumbnail (GnomeWPItem *item,
GnomeDesktopThumbnailFactory *thumbs); GnomeDesktopThumbnailFactory *thumbs);
GdkPixbuf * gnome_wp_item_get_frame_thumbnail (GnomeWPItem *item,
GnomeDesktopThumbnailFactory *thumbs,
gint frame);
void gnome_wp_item_update (GnomeWPItem *item); void gnome_wp_item_update (GnomeWPItem *item);
void gnome_wp_item_update_description (GnomeWPItem *item); void gnome_wp_item_update_description (GnomeWPItem *item);
void gnome_wp_item_ensure_gnome_bg (GnomeWPItem *item); void gnome_wp_item_ensure_gnome_bg (GnomeWPItem *item);

View file

@ -237,9 +237,9 @@ static void gnome_wp_xml_load_xml (AppearanceData *data,
wp->name = g_strdup (wp->fileinfo->name); wp->name = g_strdup (wp->fileinfo->name);
} }
gnome_wp_item_ensure_gnome_bg (wp);
gnome_wp_item_update_description (wp); gnome_wp_item_update_description (wp);
g_hash_table_insert (data->wp_hash, wp->filename, wp); g_hash_table_insert (data->wp_hash, wp->filename, wp);
gnome_wp_item_ensure_gnome_bg (wp);
} else { } else {
gnome_wp_item_free (wp); gnome_wp_item_free (wp);
wp = NULL; wp = NULL;