From 7890e1cc4b169aab33f1d4adcd0416b122490557 Mon Sep 17 00:00:00 2001 From: Stephen Watson Date: Sun, 1 Jun 2008 19:58:45 +0100 Subject: [PATCH] Change the way emblems are drawn on icons. The emblem images are no longer MaskedPixmaps but are fetched from stock when needed. This allows the theming mechanism to work on them. There may be an overhead due to repeated calls to gtk_style_lookup_icon_set and gtk_icon_set_render_icon. --- ROX-Filer/src/cell_icon.c | 6 ++-- ROX-Filer/src/display.c | 76 ++++++++++++++++++++++++++++------------- ROX-Filer/src/display.h | 9 +++-- ROX-Filer/src/panel.c | 25 ++++---------- ROX-Filer/src/pinboard.c | 42 ++++++++++++++++++++--- ROX-Filer/src/pixmaps.c | 17 +++------ ROX-Filer/src/pixmaps.h | 6 ++-- ROX-Filer/src/view_collection.c | 6 ++-- 8 files changed, 117 insertions(+), 70 deletions(-) diff --git a/ROX-Filer/src/cell_icon.c b/ROX-Filer/src/cell_icon.c index aceb5fba..e9b35faf 100644 --- a/ROX-Filer/src/cell_icon.c +++ b/ROX-Filer/src/cell_icon.c @@ -330,19 +330,19 @@ static void cell_icon_render(GtkCellRenderer *cell, GdkRectangle area = *cell_area; area.width = MIN(area.width, SMALL_WIDTH); area.x = cell_area->x + cell_area->width - area.width; - draw_small_icon(window, &area, item, + draw_small_icon(window, widget->style, &area, item, view_item->image, selected, color); break; } case LARGE_ICONS: - draw_large_icon(window, cell_area, item, + draw_large_icon(window, widget->style, cell_area, item, view_item->image, selected, color); break; case HUGE_ICONS: if (!di_image(item)->huge_pixbuf) pixmap_make_huge(di_image(item)); - draw_huge_icon(window, cell_area, item, + draw_huge_icon(window, widget->style, cell_area, item, view_item->image, selected, color); break; default: diff --git a/ROX-Filer/src/display.c b/ROX-Filer/src/display.c index b80c0769..8cacc398 100644 --- a/ROX-Filer/src/display.c +++ b/ROX-Filer/src/display.c @@ -110,10 +110,32 @@ void display_init() option_add_notify(options_changed); } -static void draw_emblem_on_icon(GdkWindow *window, MaskedPixmap *image, +void draw_emblem_on_icon(GdkWindow *window, GtkStyle *style, + const char *stock_id, int *x, int y) { - gdk_pixbuf_render_to_drawable_alpha(image->pixbuf, + GtkIconSet *icon_set; + GdkPixbuf *pixbuf; + + icon_set = gtk_style_lookup_icon_set(style, + stock_id); + if (icon_set) + { + pixbuf = gtk_icon_set_render_icon(icon_set, + style, + GTK_TEXT_DIR_LTR, + GTK_STATE_NORMAL, + mount_icon_size, + NULL, + NULL); + } + else + { + pixbuf=im_unknown->pixbuf; + g_object_ref(pixbuf); + } + + gdk_pixbuf_render_to_drawable_alpha(pixbuf, window, 0, 0, /* src */ *x, y, /* dest */ @@ -121,13 +143,14 @@ static void draw_emblem_on_icon(GdkWindow *window, MaskedPixmap *image, GDK_PIXBUF_ALPHA_FULL, 128, /* (unused) */ GDK_RGB_DITHER_NORMAL, 0, 0); - *x+=image->width+1; + *x+=gdk_pixbuf_get_width(pixbuf)+1; + g_object_unref(pixbuf); } /* Draw this icon (including any symlink or mount symbol) inside the * given rectangle. */ -void draw_huge_icon(GdkWindow *window, GdkRectangle *area, +void draw_huge_icon(GdkWindow *window, GtkStyle *style, GdkRectangle *area, DirItem *item, MaskedPixmap *image, gboolean selected, GdkColor *color) { @@ -162,18 +185,20 @@ void draw_huge_icon(GdkWindow *window, GdkRectangle *area, if (item->flags & ITEM_FLAG_MOUNT_POINT) { - MaskedPixmap *mp = item->flags & ITEM_FLAG_MOUNTED - ? im_mounted - : im_unmounted; - draw_emblem_on_icon(window, mp, &image_x, area->y + 2); + const char *mp = item->flags & ITEM_FLAG_MOUNTED + ? ROX_STOCK_MOUNTED + : ROX_STOCK_MOUNT; + draw_emblem_on_icon(window, style, mp, &image_x, area->y + 2); } if (item->flags & ITEM_FLAG_SYMLINK) { - draw_emblem_on_icon(window, im_symlink, &image_x, area->y + 2); + draw_emblem_on_icon(window, style, ROX_STOCK_SYMLINK, + &image_x, area->y + 2); } if ((item->flags & ITEM_FLAG_HAS_XATTR) && o_xattr_show.int_value) { - draw_emblem_on_icon(window, im_xattr, &image_x, area->y + 2); + draw_emblem_on_icon(window, style, ROX_STOCK_XATTR, + &image_x, area->y + 2); } } @@ -181,6 +206,7 @@ void draw_huge_icon(GdkWindow *window, GdkRectangle *area, * given rectangle. */ void draw_large_icon(GdkWindow *window, + GtkStyle *style, GdkRectangle *area, DirItem *item, MaskedPixmap *image, @@ -219,22 +245,24 @@ void draw_large_icon(GdkWindow *window, if (item->flags & ITEM_FLAG_MOUNT_POINT) { - MaskedPixmap *mp = item->flags & ITEM_FLAG_MOUNTED - ? im_mounted - : im_unmounted; - draw_emblem_on_icon(window, mp, &image_x, area->y + 2); + const char *mp = item->flags & ITEM_FLAG_MOUNTED + ? ROX_STOCK_MOUNTED + : ROX_STOCK_MOUNT; + draw_emblem_on_icon(window, style, mp, &image_x, area->y + 2); } if (item->flags & ITEM_FLAG_SYMLINK) { - draw_emblem_on_icon(window, im_symlink, &image_x, area->y + 2); + draw_emblem_on_icon(window, style, ROX_STOCK_SYMLINK, + &image_x, area->y + 2); } if ((item->flags & ITEM_FLAG_HAS_XATTR) && o_xattr_show.int_value) { - draw_emblem_on_icon(window, im_xattr, &image_x, area->y + 2); + draw_emblem_on_icon(window, style, ROX_STOCK_XATTR, + &image_x, area->y + 2); } } -void draw_small_icon(GdkWindow *window, GdkRectangle *area, +void draw_small_icon(GdkWindow *window, GtkStyle *style, GdkRectangle *area, DirItem *item, MaskedPixmap *image, gboolean selected, GdkColor *color) { @@ -270,18 +298,20 @@ void draw_small_icon(GdkWindow *window, GdkRectangle *area, if (item->flags & ITEM_FLAG_MOUNT_POINT) { - MaskedPixmap *mp = item->flags & ITEM_FLAG_MOUNTED - ? im_mounted - : im_unmounted; - draw_emblem_on_icon(window, mp, &image_x, area->y + 2); + const char *mp = item->flags & ITEM_FLAG_MOUNTED + ? ROX_STOCK_MOUNTED + : ROX_STOCK_MOUNT; + draw_emblem_on_icon(window, style, mp, &image_x, area->y + 2); } if (item->flags & ITEM_FLAG_SYMLINK) { - draw_emblem_on_icon(window, im_symlink, &image_x, area->y + 8); + draw_emblem_on_icon(window, style, ROX_STOCK_SYMLINK, + &image_x, area->y + 8); } if ((item->flags & ITEM_FLAG_HAS_XATTR) && o_xattr_show.int_value) { - draw_emblem_on_icon(window, im_xattr, &image_x, area->y + 8); + draw_emblem_on_icon(window, style, ROX_STOCK_XATTR, + &image_x, area->y + 8); } } diff --git a/ROX-Filer/src/display.h b/ROX-Filer/src/display.h index b6700dc1..cd4fb45e 100644 --- a/ROX-Filer/src/display.h +++ b/ROX-Filer/src/display.h @@ -57,6 +57,7 @@ void display_set_sort_type(FilerWindow *filer_window, SortType sort_type, void display_set_autoselect(FilerWindow *filer_window, const gchar *leaf); void draw_large_icon(GdkWindow *window, + GtkStyle *style, GdkRectangle *area, DirItem *item, MaskedPixmap *image, @@ -71,12 +72,16 @@ void display_update_view(FilerWindow *filer_window, ViewData *view, gboolean update_name_layout); void display_update_views(FilerWindow *filer_window); -void draw_small_icon(GdkWindow *window, GdkRectangle *area, +void draw_small_icon(GdkWindow *window, GtkStyle *style, GdkRectangle *area, DirItem *item, MaskedPixmap *image, gboolean selected, GdkColor *color); -void draw_huge_icon(GdkWindow *window, GdkRectangle *area, DirItem *item, +void draw_huge_icon(GdkWindow *window, GtkStyle *style, GdkRectangle *area, + DirItem *item, MaskedPixmap *image, gboolean selected, GdkColor *color); void display_set_actual_size(FilerWindow *filer_window, gboolean force_resize); +void draw_emblem_on_icon(GdkWindow *window, GtkStyle *style, + const char *stock_id, + int *x, int y); #endif /* _DISPLAY_H */ diff --git a/ROX-Filer/src/panel.c b/ROX-Filer/src/panel.c index 6766f8cc..0db6ecda 100644 --- a/ROX-Filer/src/panel.c +++ b/ROX-Filer/src/panel.c @@ -1079,27 +1079,16 @@ static gint draw_icon(GtkWidget *widget, GdkRectangle *badarea, PanelIcon *pi) if (icon->item->flags & ITEM_FLAG_SYMLINK) { - gdk_pixbuf_render_to_drawable_alpha(im_symlink->pixbuf, - widget->window, - 0, 0, /* src */ - image_x, image_y + 2, /* dest */ - -1, -1, - GDK_PIXBUF_ALPHA_FULL, 128, /* (unused) */ - GDK_RGB_DITHER_NORMAL, 0, 0); + draw_emblem_on_icon(widget->window, widget->style, + ROX_STOCK_SYMLINK, &image_x, image_y+2); } if (icon->item->flags & ITEM_FLAG_MOUNT_POINT) { - MaskedPixmap *mp = icon->item->flags & ITEM_FLAG_MOUNTED - ? im_mounted - : im_unmounted; - - gdk_pixbuf_render_to_drawable_alpha(mp->pixbuf, - widget->window, - 0, 0, /* src */ - image_x, image_y + 2, /* dest */ - -1, -1, - GDK_PIXBUF_ALPHA_FULL, 128, /* (unused) */ - GDK_RGB_DITHER_NORMAL, 0, 0); + draw_emblem_on_icon(widget->window, widget->style, + icon->item->flags & ITEM_FLAG_MOUNTED + ? ROX_STOCK_MOUNTED + : ROX_STOCK_MOUNT, + &image_x, image_y+2); } return FALSE; } diff --git a/ROX-Filer/src/pinboard.c b/ROX-Filer/src/pinboard.c index c1bced91..de66086e 100644 --- a/ROX-Filer/src/pinboard.c +++ b/ROX-Filer/src/pinboard.c @@ -1038,6 +1038,33 @@ static void set_size_and_style(PinIcon *pi) gtk_widget_set_size_request(pi->widget, iwidth, iheight); } +static GdkPixbuf *get_stock_icon(GtkWidget *widget, + const char *stock_id) +{ + GtkIconSet *icon_set; + GdkPixbuf *pixbuf; + + icon_set = gtk_style_lookup_icon_set(widget->style, + stock_id); + if (icon_set) + { + pixbuf = gtk_icon_set_render_icon(icon_set, + widget->style, + GTK_TEXT_DIR_LTR, + GTK_STATE_NORMAL, + mount_icon_size, + NULL, + NULL); + } + else + { + pixbuf=im_unknown->pixbuf; + g_object_ref(pixbuf); + } + + return pixbuf; +} + static gint draw_icon(GtkWidget *widget, GdkEventExpose *event, PinIcon *pi) { static GtkWidgetClass *parent_class = NULL; @@ -1075,19 +1102,24 @@ static gint draw_icon(GtkWidget *widget, GdkEventExpose *event, PinIcon *pi) if (item->flags & ITEM_FLAG_SYMLINK) { - render_pixbuf(im_symlink->pixbuf, pi->widget->window, + GdkPixbuf *emblem = get_stock_icon(pi->widget, + ROX_STOCK_SYMLINK); + render_pixbuf(emblem, pi->widget->window, pi->widget->style->black_gc, x, y, -1, -1); + g_object_unref(emblem); } else if (item->flags & ITEM_FLAG_MOUNT_POINT) { - MaskedPixmap *mp = item->flags & ITEM_FLAG_MOUNTED - ? im_mounted - : im_unmounted; + GdkPixbuf *emblem = get_stock_icon(pi->widget, + item->flags & ITEM_FLAG_MOUNTED + ? ROX_STOCK_MOUNTED + : ROX_STOCK_MOUNT); - render_pixbuf(mp->pixbuf, pi->widget->window, + render_pixbuf(emblem, pi->widget->window, pi->widget->style->black_gc, x, y, -1, -1); + g_object_unref(emblem); } gdk_gc_set_clip_region(pi->widget->style->black_gc, NULL); diff --git a/ROX-Filer/src/pixmaps.c b/ROX-Filer/src/pixmaps.c index 43f86e38..d2665912 100644 --- a/ROX-Filer/src/pixmaps.c +++ b/ROX-Filer/src/pixmaps.c @@ -78,15 +78,13 @@ static const char * bad_xpm[] = { MaskedPixmap *im_error; MaskedPixmap *im_unknown; -MaskedPixmap *im_symlink; -MaskedPixmap *im_unmounted; -MaskedPixmap *im_mounted; MaskedPixmap *im_appdir; -MaskedPixmap *im_xattr; MaskedPixmap *im_dirs; +GtkIconSize mount_icon_size = -1; + typedef struct _ChildThumbnail ChildThumbnail; /* There is one of these for each active child process */ @@ -106,8 +104,6 @@ static const char *stocks[] = { ROX_STOCK_XATTR, }; -static GtkIconSize mount_icon_size = -1; - /* Static prototypes */ static void load_default_pixmaps(void); @@ -200,7 +196,9 @@ static MaskedPixmap *mp_from_stock(const char *stock_id, int size) GdkPixbuf *pixbuf; MaskedPixmap *retval; - icon_set = gtk_icon_factory_lookup_default(stock_id); + /*icon_set = gtk_icon_factory_lookup_default(stock_id);*/ + icon_set = gtk_style_lookup_icon_set(gtk_widget_get_default_style(), + stock_id); if (!icon_set) return get_bad_image(); @@ -931,11 +929,6 @@ static void load_default_pixmaps(void) im_unknown = mp_from_stock(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG); - im_symlink = mp_from_stock(ROX_STOCK_SYMLINK, mount_icon_size); - im_unmounted = mp_from_stock(ROX_STOCK_MOUNT, mount_icon_size); - im_mounted = mp_from_stock(ROX_STOCK_MOUNTED, mount_icon_size); - im_xattr = mp_from_stock(ROX_STOCK_XATTR, mount_icon_size); - im_dirs = load_pixmap("dirs"); im_appdir = load_pixmap("application"); diff --git a/ROX-Filer/src/pixmaps.h b/ROX-Filer/src/pixmaps.h index f3e95556..5c21803e 100644 --- a/ROX-Filer/src/pixmaps.h +++ b/ROX-Filer/src/pixmaps.h @@ -13,16 +13,14 @@ extern GFSCache *desktop_icon_cache; extern MaskedPixmap *im_error; extern MaskedPixmap *im_unknown; -extern MaskedPixmap *im_symlink; -extern MaskedPixmap *im_unmounted; -extern MaskedPixmap *im_mounted; extern MaskedPixmap *im_exec_file; extern MaskedPixmap *im_appdir; -extern MaskedPixmap *im_xattr; extern MaskedPixmap *im_dirs; +extern GtkIconSize mount_icon_size; + /* If making the huge size larger, be sure to update SMALL_IMAGE_THRESHOLD! */ #define HUGE_WIDTH 96 #define HUGE_HEIGHT 96 diff --git a/ROX-Filer/src/view_collection.c b/ROX-Filer/src/view_collection.c index 2d4cf17a..7385b867 100644 --- a/ROX-Filer/src/view_collection.c +++ b/ROX-Filer/src/view_collection.c @@ -350,18 +350,18 @@ static void draw_item(GtkWidget *widget, if (template.icon.width <= SMALL_WIDTH && template.icon.height <= SMALL_HEIGHT) { - draw_small_icon(widget->window, &template.icon, + draw_small_icon(widget->window, widget->style, &template.icon, item, view->image, selected, color); } else if (template.icon.width <= ICON_WIDTH && template.icon.height <= ICON_HEIGHT) { - draw_large_icon(widget->window, &template.icon, + draw_large_icon(widget->window, widget->style, &template.icon, item, view->image, selected, color); } else { - draw_huge_icon(widget->window, &template.icon, + draw_huge_icon(widget->window, widget->style, &template.icon, item, view->image, selected, color); } -- 2.11.4.GIT