Commit b6b12659 authored by Andy Hertzfeld's avatar Andy Hertzfeld

added framework for using custom images to reflect highlight state; used


        added framework for using custom images to reflect highlight state;
	used it to make folders reflect drop-highlighting by opening (just
	in eazel theme for now)
parent aa8fdf8b
2000-04-12 John Sullivan <sullivan@eazel.com>
2000-04-12 Andy Hertzfeld <andy@eazel.com>
* data/mime/nautilus.keys:
Prefixed all the MIME type descriptions with [en_US].
Now others are free to localize away.
added a framework for using custom images for icons to reflect their
highlited states. Made folders in the eazel theme open up to reflect
drop highliting.
* icons/eazel/Makefile.am:
added icon for open folder at standard size
* icons/eazel/i-directory-accept.png:
icon of open folder for drop-highlighting
* libnautilus/nautilus-icon-canvas-item.c,h:
added a "modifier" text string attribute with appropriate accessors
when modifier is changed, update the icon
* libnautilus/nautilus-icon-container.c,h:
added modifier parameter to "get_icon_images" signal
added nautilus_icon_container_request_update_by_item to update
the icon corresponding to a given item.
* libnautilus/nautilus-icon-factory.c,h:
added modifier field to NautilusScalableIcon; modified appropriate
lifetime and hashing routines accordingly;
use the modifier to select the proper image in get_icon_file_path
* src/file-manager/fm-icon-view.c:
pass in the modifier from signal to icon_factory_get_icon_for_file.
2000-04-12 John Sullivan <sullivan@eazel.com>
......
......@@ -6,6 +6,7 @@ eazel_DATA = \
i-directory-36.png \
i-directory-72.png \
i-directory-96.png \
i-directory-accept.png \
i-regular.png \
i-regular.xml \
i-regular-36.png \
......
......@@ -54,6 +54,7 @@ struct NautilusIconCanvasItemDetails {
GdkFont *font;
ArtIRect embedded_text_rect;
char *embedded_text_file_URI;
char *modifier;
/* Size of the text at current font. */
int text_width;
......@@ -75,7 +76,8 @@ enum {
ARG_HIGHLIGHTED_FOR_SELECTION,
ARG_HIGHLIGHTED_AS_KEYBOARD_FOCUS,
ARG_HIGHLIGHTED_FOR_DROP,
ARG_TEXT_SOURCE
ARG_TEXT_SOURCE,
ARG_MODIFIER
};
typedef enum {
......@@ -136,6 +138,8 @@ static void nautilus_icon_canvas_item_bounds (GnomeCanvasItem
double *y1,
double *x2,
double *y2);
static void nautilus_icon_canvas_item_set_modifier (NautilusIconCanvasItem *item,
const char* modifier);
/* private */
static void draw_or_measure_label_text (NautilusIconCanvasItem *item,
......@@ -186,6 +190,8 @@ nautilus_icon_canvas_item_initialize_class (NautilusIconCanvasItemClass *class)
GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HIGHLIGHTED_FOR_DROP);
gtk_object_add_arg_type ("NautilusIconCanvasItem::text_source",
GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TEXT_SOURCE);
gtk_object_add_arg_type ("NautilusIconCanvasItem::modifier",
GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_MODIFIER);
object_class->destroy = nautilus_icon_canvas_item_destroy;
object_class->set_arg = nautilus_icon_canvas_item_set_arg;
......@@ -248,7 +254,13 @@ nautilus_icon_canvas_item_destroy (GtkObject *object)
if (details->font != NULL) {
gdk_font_unref (details->font);
}
if (details->embedded_text_file_URI)
g_free(details->embedded_text_file_URI);
if (details->modifier)
g_free(details->modifier);
g_free (details);
NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object));
......@@ -323,6 +335,8 @@ nautilus_icon_canvas_item_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
return;
}
details->is_highlighted_for_drop = GTK_VALUE_BOOL (*arg);
nautilus_icon_canvas_item_set_modifier(NAUTILUS_ICON_CANVAS_ITEM (object),
details->is_highlighted_for_drop ? "accept" : "");
break;
case ARG_TEXT_SOURCE:
......@@ -333,6 +347,14 @@ nautilus_icon_canvas_item_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
g_free (details->embedded_text_file_URI);
details->embedded_text_file_URI = g_strdup (GTK_VALUE_STRING (*arg));
break;
case ARG_MODIFIER:
if (nautilus_strcmp (details->modifier, GTK_VALUE_STRING (*arg)) == 0) {
return;
}
nautilus_icon_canvas_item_set_modifier(NAUTILUS_ICON_CANVAS_ITEM (object), GTK_VALUE_STRING (*arg));
break;
default:
g_warning ("nautilus_icons_view_item_item_set_arg on unknown argument");
......@@ -375,6 +397,10 @@ nautilus_icon_canvas_item_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
case ARG_TEXT_SOURCE:
GTK_VALUE_STRING (*arg) = g_strdup (details->embedded_text_file_URI);
break;
case ARG_MODIFIER:
GTK_VALUE_STRING (*arg) = g_strdup (details->modifier);
break;
default:
arg->type = GTK_TYPE_INVALID;
......@@ -398,6 +424,33 @@ nautilus_icon_canvas_item_get_image (NautilusIconCanvasItem *item,
return details->pixbuf;
}
const char*
nautilus_icon_canvas_item_get_modifier(NautilusIconCanvasItem *item)
{
return item->details->modifier;
}
void
nautilus_icon_canvas_item_set_modifier(NautilusIconCanvasItem *item, const char* modifier)
{
GnomeCanvasItem *canvas_item;
/* if they're the same, there's nothing to do */
if (!modifier && !item->details->modifier)
return;
if (modifier && item->details->modifier && !strcmp(modifier, item->details->modifier))
return;
if (item->details->modifier != NULL)
g_free(item->details->modifier);
item->details->modifier = strdup(modifier);
/* we must update the image, since the modifier has changed */
canvas_item = GNOME_CANVAS_ITEM(item);
nautilus_icon_container_request_update_by_item(NAUTILUS_ICON_CONTAINER(canvas_item->canvas), item);
}
void
nautilus_icon_canvas_item_set_image (NautilusIconCanvasItem *item,
GdkPixbuf *image,
......
......@@ -73,6 +73,7 @@ void nautilus_icon_canvas_item_set_emblems (NautilusIconCanva
void nautilus_icon_canvas_item_set_show_stretch_handles (NautilusIconCanvasItem *item,
gboolean show_stretch_handles);
const char *nautilus_icon_canvas_item_get_modifier (NautilusIconCanvasItem *item);
/* geometry and hit testing */
gboolean nautilus_icon_canvas_item_hit_test_rectangle (NautilusIconCanvasItem *item,
......
......@@ -1815,8 +1815,9 @@ nautilus_icon_container_initialize_class (NautilusIconContainerClass *class)
object_class->type,
GTK_SIGNAL_OFFSET (NautilusIconContainerClass,
get_icon_images),
nautilus_gtk_marshal_POINTER__POINTER_POINTER,
GTK_TYPE_POINTER, 2,
nautilus_gtk_marshal_POINTER__POINTER_POINTER_POINTER,
GTK_TYPE_POINTER, 3,
GTK_TYPE_POINTER,
GTK_TYPE_POINTER,
GTK_TYPE_POINTER);
signals[GET_ICON_TEXT]
......@@ -2231,6 +2232,7 @@ update_icon (NautilusIconContainer *container, NautilusIcon *icon)
signals[GET_ICON_IMAGES],
icon->data,
&emblem_icons,
nautilus_icon_canvas_item_get_modifier(icon->item),
&scalable_icon);
g_assert (scalable_icon != NULL);
......@@ -2401,6 +2403,32 @@ nautilus_icon_container_request_update (NautilusIconContainer *container,
}
}
/**
* nautilus_icon_container_request_update_by_item:
* @container: A NautilusIconContainer.
* @item: Icon canvas item.
*
* Update the icon with this data.
**/
void
nautilus_icon_container_request_update_by_item (NautilusIconContainer *container,
NautilusIconCanvasItem *item)
{
NautilusIcon *icon;
GList *p;
g_return_if_fail (NAUTILUS_IS_ICON_CONTAINER (container));
g_return_if_fail (item != NULL);
for (p = container->details->icons; p != NULL; p = p->next) {
icon = p->data;
if (icon->item == item) {
update_icon (container, icon);
return;
}
}
}
/* zooming */
int
......
......@@ -27,6 +27,7 @@
#include <libgnomeui/gnome-canvas.h>
#include "nautilus-icon-factory.h"
#include "nautilus-icon-canvas-item.h"
typedef struct NautilusIconContainer NautilusIconContainer;
typedef struct NautilusIconContainerClass NautilusIconContainerClass;
......@@ -112,6 +113,8 @@ gboolean nautilus_icon_container_remove (NautilusIconContaine
NautilusIconData *data);
void nautilus_icon_container_request_update (NautilusIconContainer *view,
NautilusIconData *data);
void nautilus_icon_container_request_update_by_item (NautilusIconContainer *view,
NautilusIconCanvasItem *item);
void nautilus_icon_container_request_update_all (NautilusIconContainer *container);
/* operations on all icons */
......
......@@ -158,6 +158,7 @@ struct NautilusScalableIcon {
char *uri;
char *name;
char *modifier;
};
/* The key to a hash table that holds the scaled icons as pixbufs.
......@@ -190,7 +191,8 @@ static char * nautilus_icon_factory_get_thumbnail_uri (NautilusFi
static NautilusIconFactory * nautilus_icon_factory_new (const char *theme_name);
static void nautilus_icon_factory_set_theme (const char *theme_name);
static NautilusScalableIcon *nautilus_scalable_icon_get (const char *uri,
const char *name);
const char *name,
const char *modifier);
static guint nautilus_scalable_icon_hash (gconstpointer p);
static gboolean nautilus_scalable_icon_equal (gconstpointer a,
gconstpointer b);
......@@ -467,11 +469,11 @@ nautilus_icon_factory_get_icon_name_for_regular_file (NautilusFile *file)
/* Get the icon name for a file. */
static const char *
nautilus_icon_factory_get_icon_name_for_file (NautilusFile *file)
{
{
/* Get an icon name based on the file's type. */
switch (nautilus_file_get_file_type (file)) {
case GNOME_VFS_FILE_TYPE_DIRECTORY:
return ICON_NAME_DIRECTORY;
return ICON_NAME_DIRECTORY;
case GNOME_VFS_FILE_TYPE_FIFO:
return ICON_NAME_FIFO;
case GNOME_VFS_FILE_TYPE_SOCKET:
......@@ -586,7 +588,7 @@ get_themed_icon_file_path (const char *theme_name,
/* Choose the file name to load, taking into account theme vs. non-theme icons. */
static char *
get_icon_file_path (const char *name, guint size_in_pixels, ArtIRect *text_rect)
get_icon_file_path (const char *name, const char* modifier, guint size_in_pixels, ArtIRect *text_rect)
{
gboolean use_theme_icon;
const char *theme_name;
......@@ -611,6 +613,19 @@ get_icon_file_path (const char *name, guint size_in_pixels, ArtIRect *text_rect)
}
/* Now we know whether or not to use the theme. */
/* if there's a modifier, try using that first */
if (modifier && strlen(modifier)) {
gchar* modified_name = g_strdup_printf("%s-%s", name, modifier);
path = get_themed_icon_file_path (use_theme_icon ? theme_name : NULL,
modified_name,
size_in_pixels,
text_rect);
g_free(modified_name);
if (path)
return path;
}
return get_themed_icon_file_path (use_theme_icon ? theme_name : NULL,
name,
size_in_pixels,
......@@ -634,7 +649,8 @@ icon_theme_changed_callback (NautilusPreferences *preferences,
/* Get or create a scalable icon. */
static NautilusScalableIcon *
nautilus_scalable_icon_get (const char *uri,
const char *name)
const char *name,
const char *modifier)
{
GHashTable *hash_table;
NautilusScalableIcon icon_key, *icon;
......@@ -645,12 +661,14 @@ nautilus_scalable_icon_get (const char *uri,
/* Check to see if it's already in the table. */
icon_key.uri = (char *) uri;
icon_key.name = (char *) name;
icon_key.modifier = (char *) modifier;
icon = g_hash_table_lookup (hash_table, &icon_key);
if (icon == NULL) {
/* Not in the table, so create it and put it in. */
icon = g_new0 (NautilusScalableIcon, 1);
icon->uri = g_strdup (uri);
icon->name = g_strdup (name);
icon->modifier = g_strdup (modifier);
g_hash_table_insert (hash_table, icon, icon);
}
......@@ -684,6 +702,8 @@ nautilus_scalable_icon_unref (NautilusScalableIcon *icon)
g_free (icon->uri);
g_free (icon->name);
if (icon->modifier)
g_free(icon->modifier);
g_free (icon);
}
......@@ -705,6 +725,11 @@ nautilus_scalable_icon_hash (gconstpointer p)
hash ^= g_str_hash (icon->name);
}
hash <<= 4;
if (icon->modifier != NULL) {
hash ^= g_str_hash (icon->modifier);
}
return hash;
}
......@@ -718,11 +743,12 @@ nautilus_scalable_icon_equal (gconstpointer a,
icon_b = b;
return nautilus_strcmp (icon_a->uri, icon_b->uri) == 0
&& nautilus_strcmp (icon_a->name, icon_b->name) == 0;
&& nautilus_strcmp (icon_a->name, icon_b->name) == 0
&& nautilus_strcmp (icon_a->modifier, icon_b->modifier) == 0;
}
NautilusScalableIcon *
nautilus_icon_factory_get_icon_for_file (NautilusFile *file)
nautilus_icon_factory_get_icon_for_file (NautilusFile *file, const char* modifier)
{
char *uri, *file_uri;
const char *name;
......@@ -754,7 +780,7 @@ nautilus_icon_factory_get_icon_for_file (NautilusFile *file)
name = nautilus_icon_factory_get_icon_name_for_file (file);
/* Create the icon or find it in the cache if it's already there. */
scalable_icon = nautilus_scalable_icon_get (uri, name);
scalable_icon = nautilus_scalable_icon_get (uri, name, modifier);
g_free (uri);
return scalable_icon;
......@@ -766,7 +792,7 @@ add_emblem (GList **icons, const char *name)
char *name_with_prefix;
name_with_prefix = g_strconcat (EMBLEM_NAME_PREFIX, name, NULL);
*icons = g_list_prepend (*icons, nautilus_scalable_icon_get (NULL, name_with_prefix));
*icons = g_list_prepend (*icons, nautilus_scalable_icon_get (NULL, name_with_prefix, NULL));
g_free (name_with_prefix);
}
......@@ -901,6 +927,7 @@ nautilus_icon_factory_get_thumbnail_uri (NautilusFile *file)
/* return the uri to the "loading image" icon */
return get_icon_file_path (ICON_NAME_THUMBNAIL_LOADING,
NULL,
NAUTILUS_ICON_SIZE_STANDARD,
NULL);
}
......@@ -1013,6 +1040,7 @@ load_specific_image (NautilusScalableIcon *scalable_icon,
GdkPixbuf *image;
path = get_icon_file_path (scalable_icon->name,
scalable_icon->modifier,
size_in_pixels,
text_rect);
if (path == NULL) {
......@@ -1358,7 +1386,7 @@ nautilus_icon_factory_get_pixbuf_for_file (NautilusFile *file,
g_return_val_if_fail (file != NULL, NULL);
icon = nautilus_icon_factory_get_icon_for_file (file);
icon = nautilus_icon_factory_get_icon_for_file (file, NULL);
pixbuf = nautilus_icon_factory_get_pixbuf_for_icon (icon,
size_in_pixels,
size_in_pixels,
......
......@@ -86,7 +86,8 @@ GtkObject * nautilus_icon_factory_get (void);
guint nautilus_get_icon_size_for_zoom_level (NautilusZoomLevel zoom_level);
/* Choose the appropriate icon, but don't render it yet. */
NautilusScalableIcon *nautilus_icon_factory_get_icon_for_file (NautilusFile *file);
NautilusScalableIcon *nautilus_icon_factory_get_icon_for_file (NautilusFile *file,
const char *modifier);
NautilusScalableIcon *nautilus_icon_factory_get_icon_by_name (const char *icon_name);
GList * nautilus_icon_factory_get_emblem_icons_for_file (NautilusFile *file);
......
......@@ -54,6 +54,7 @@ struct NautilusIconCanvasItemDetails {
GdkFont *font;
ArtIRect embedded_text_rect;
char *embedded_text_file_URI;
char *modifier;
/* Size of the text at current font. */
int text_width;
......@@ -75,7 +76,8 @@ enum {
ARG_HIGHLIGHTED_FOR_SELECTION,
ARG_HIGHLIGHTED_AS_KEYBOARD_FOCUS,
ARG_HIGHLIGHTED_FOR_DROP,
ARG_TEXT_SOURCE
ARG_TEXT_SOURCE,
ARG_MODIFIER
};
typedef enum {
......@@ -136,6 +138,8 @@ static void nautilus_icon_canvas_item_bounds (GnomeCanvasItem
double *y1,
double *x2,
double *y2);
static void nautilus_icon_canvas_item_set_modifier (NautilusIconCanvasItem *item,
const char* modifier);
/* private */
static void draw_or_measure_label_text (NautilusIconCanvasItem *item,
......@@ -186,6 +190,8 @@ nautilus_icon_canvas_item_initialize_class (NautilusIconCanvasItemClass *class)
GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HIGHLIGHTED_FOR_DROP);
gtk_object_add_arg_type ("NautilusIconCanvasItem::text_source",
GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TEXT_SOURCE);
gtk_object_add_arg_type ("NautilusIconCanvasItem::modifier",
GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_MODIFIER);
object_class->destroy = nautilus_icon_canvas_item_destroy;
object_class->set_arg = nautilus_icon_canvas_item_set_arg;
......@@ -248,7 +254,13 @@ nautilus_icon_canvas_item_destroy (GtkObject *object)
if (details->font != NULL) {
gdk_font_unref (details->font);
}
if (details->embedded_text_file_URI)
g_free(details->embedded_text_file_URI);
if (details->modifier)
g_free(details->modifier);
g_free (details);
NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object));
......@@ -323,6 +335,8 @@ nautilus_icon_canvas_item_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
return;
}
details->is_highlighted_for_drop = GTK_VALUE_BOOL (*arg);
nautilus_icon_canvas_item_set_modifier(NAUTILUS_ICON_CANVAS_ITEM (object),
details->is_highlighted_for_drop ? "accept" : "");
break;
case ARG_TEXT_SOURCE:
......@@ -333,6 +347,14 @@ nautilus_icon_canvas_item_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
g_free (details->embedded_text_file_URI);
details->embedded_text_file_URI = g_strdup (GTK_VALUE_STRING (*arg));
break;
case ARG_MODIFIER:
if (nautilus_strcmp (details->modifier, GTK_VALUE_STRING (*arg)) == 0) {
return;
}
nautilus_icon_canvas_item_set_modifier(NAUTILUS_ICON_CANVAS_ITEM (object), GTK_VALUE_STRING (*arg));
break;
default:
g_warning ("nautilus_icons_view_item_item_set_arg on unknown argument");
......@@ -375,6 +397,10 @@ nautilus_icon_canvas_item_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
case ARG_TEXT_SOURCE:
GTK_VALUE_STRING (*arg) = g_strdup (details->embedded_text_file_URI);
break;
case ARG_MODIFIER:
GTK_VALUE_STRING (*arg) = g_strdup (details->modifier);
break;
default:
arg->type = GTK_TYPE_INVALID;
......@@ -398,6 +424,33 @@ nautilus_icon_canvas_item_get_image (NautilusIconCanvasItem *item,
return details->pixbuf;
}
const char*
nautilus_icon_canvas_item_get_modifier(NautilusIconCanvasItem *item)
{
return item->details->modifier;
}
void
nautilus_icon_canvas_item_set_modifier(NautilusIconCanvasItem *item, const char* modifier)
{
GnomeCanvasItem *canvas_item;
/* if they're the same, there's nothing to do */
if (!modifier && !item->details->modifier)
return;
if (modifier && item->details->modifier && !strcmp(modifier, item->details->modifier))
return;
if (item->details->modifier != NULL)
g_free(item->details->modifier);
item->details->modifier = strdup(modifier);
/* we must update the image, since the modifier has changed */
canvas_item = GNOME_CANVAS_ITEM(item);
nautilus_icon_container_request_update_by_item(NAUTILUS_ICON_CONTAINER(canvas_item->canvas), item);
}
void
nautilus_icon_canvas_item_set_image (NautilusIconCanvasItem *item,
GdkPixbuf *image,
......
......@@ -73,6 +73,7 @@ void nautilus_icon_canvas_item_set_emblems (NautilusIconCanva
void nautilus_icon_canvas_item_set_show_stretch_handles (NautilusIconCanvasItem *item,
gboolean show_stretch_handles);
const char *nautilus_icon_canvas_item_get_modifier (NautilusIconCanvasItem *item);
/* geometry and hit testing */
gboolean nautilus_icon_canvas_item_hit_test_rectangle (NautilusIconCanvasItem *item,
......
......@@ -1815,8 +1815,9 @@ nautilus_icon_container_initialize_class (NautilusIconContainerClass *class)
object_class->type,
GTK_SIGNAL_OFFSET (NautilusIconContainerClass,
get_icon_images),
nautilus_gtk_marshal_POINTER__POINTER_POINTER,
GTK_TYPE_POINTER, 2,
nautilus_gtk_marshal_POINTER__POINTER_POINTER_POINTER,
GTK_TYPE_POINTER, 3,
GTK_TYPE_POINTER,
GTK_TYPE_POINTER,
GTK_TYPE_POINTER);
signals[GET_ICON_TEXT]
......@@ -2231,6 +2232,7 @@ update_icon (NautilusIconContainer *container, NautilusIcon *icon)
signals[GET_ICON_IMAGES],
icon->data,
&emblem_icons,
nautilus_icon_canvas_item_get_modifier(icon->item),
&scalable_icon);
g_assert (scalable_icon != NULL);
......@@ -2401,6 +2403,32 @@ nautilus_icon_container_request_update (NautilusIconContainer *container,
}
}
/**
* nautilus_icon_container_request_update_by_item:
* @container: A NautilusIconContainer.
* @item: Icon canvas item.
*
* Update the icon with this data.
**/
void
nautilus_icon_container_request_update_by_item (NautilusIconContainer *container,
NautilusIconCanvasItem *item)
{
NautilusIcon *icon;
GList *p;
g_return_if_fail (NAUTILUS_IS_ICON_CONTAINER (container));
g_return_if_fail (item != NULL);
for (p = container->details->icons; p != NULL; p = p->next) {
icon = p->data;
if (icon->item == item) {
update_icon (container, icon);
return;
}
}
}
/* zooming */
int
......
......@@ -27,6 +27,7 @@
#include <libgnomeui/gnome-canvas.h>
#include "nautilus-icon-factory.h"
#include "nautilus-icon-canvas-item.h"
typedef struct NautilusIconContainer NautilusIconContainer;
typedef struct NautilusIconContainerClass NautilusIconContainerClass;
......@@ -112,6 +113,8 @@ gboolean nautilus_icon_container_remove (NautilusIconContaine
NautilusIconData *data);
void nautilus_icon_container_request_update (NautilusIconContainer *view,
NautilusIconData *data);
void nautilus_icon_container_request_update_by_item (NautilusIconContainer *view,
NautilusIconCanvasItem *item);
void nautilus_icon_container_request_update_all (NautilusIconContainer *container);
/* operations on all icons */
......
......@@ -158,6 +158,7 @@ struct NautilusScalableIcon {
char *uri;
char *name;
char *modifier;
};
/* The key to a hash table that holds the scaled icons as pixbufs.
......@@ -190,7 +191,8 @@ static char * nautilus_icon_factory_get_thumbnail_uri (NautilusFi
static NautilusIconFactory * nautilus_icon_factory_new (const char *theme_name);
static void nautilus_icon_factory_set_theme (const char *theme_name);
static NautilusScalableIcon *nautilus_scalable_icon_get (const char *uri,
const char *name);
const char *name,
const char *modifier);
static guint nautilus_scalable_icon_hash (gconstpointer p);
static gboolean nautilus_scalable_icon_equal (gconstpointer a,
gconstpointer b);
......@@ -467,11 +469,11 @@ nautilus_icon_factory_get_icon_name_for_regular_file (NautilusFile *file)
/* Get the icon name for a file. */
static const char *
nautilus_icon_factory_get_icon_name_for_file (NautilusFile *file)
{
{
/* Get an icon name based on the file's type. */
switch (nautilus_file_get_file_type (file)) {
case GNOME_VFS_FILE_TYPE_DIRECTORY:
return ICON_NAME_DIRECTORY;
return ICON_NAME_DIRECTORY;
case GNOME_VFS_FILE_TYPE_FIFO:
return ICON_NAME_FIFO;
case GNOME_VFS_FILE_TYPE_SOCKET:
......@@ -586,7 +588,7 @@ get_themed_icon_file_path (const char *theme_name,
/* Choose the file name to load, taking into account theme vs. non-theme icons. */
static char *
get_icon_file_path (const char *name, guint size_in_pixels, ArtIRect *text_rect)
get_icon_file_path (const char *name, const char* modifier, guint size_in_pixels, ArtIRect *text_rect)
{
gboolean use_theme_icon;
const char *theme_name;
......@@ -611,6 +613,19 @@ get_icon_file_path (const char *name, guint size_in_pixels, ArtIRect *text_rect)
}
/* Now we know whether or not to use the theme. */
/* if there's a modifier, try using that first */
if (modifier && strlen(modifier)) {
gchar* modified_name = g_strdup_printf("%s-%s", name, modifier);
path = get_themed_icon_file_path (use_theme_icon ? theme_name : NULL,
modified_name,
size_in_pixels,
text_rect);
g_free(modified_name);
if (path)
return path;
}
return get_themed_icon_file_path (use_theme_icon ? theme_name : NULL,
name,
size_in_pixels,
......@@ -634,7 +649,8 @@ icon_theme_changed_callback (NautilusPreferences *preferences,
/* Get or create a scalable icon. */
static NautilusScalableIcon *
nautilus_scalable_icon_get (const char *uri,
const char *name)
const char *name,
const char *modifier)
{
GHashTable *hash_table;
NautilusScalableIcon icon_key, *icon;
......@@ -645,12 +661,14 @@ nautilus_scalable_icon_get (const char *uri,
/* Check to see if it's already in the table. */
icon_key.uri = (char *) uri;
icon_key.name = (char *) name;
icon_key.modifier = (char *) modifier;
icon = g_hash_table_lookup (hash_table, &icon_key);
if (icon == NULL) {
/* Not in the table, so create it and put it in. */
icon = g_new0 (NautilusScalableIcon, 1);
icon->uri = g_strdup (uri);
icon->name = g_strdup (name);
icon->modifier = g_strdup (modifier);
g_hash_table_insert (hash_table, icon, icon);
}
......@@ -684,6 +702,8 @@ nautilus_scalable_icon_unref (NautilusScalableIcon *icon)
g_free (icon->uri);
g_free (icon->name);
if (icon->modifier)
g_free(icon->modifier);
g_free (icon);
}
......@@ -705,6 +725,11 @@ nautilus_scalable_icon_hash (gconstpointer p)
hash ^= g_str_hash (icon->name);
}
hash <<= 4;
if (icon->modifier != NULL) {
hash ^= g_str_hash (icon->modifier);
}
return hash;
}
......@@ -718,11 +743,12 @@ nautilus_scalable_icon_equal (gconstpointer a,
icon_b = b;
return nautilus_strcmp (icon_a->uri, icon_b->uri) == 0
&& nautilus_strcmp (icon_a->name, icon_b->name) == 0;
&& nautilus_strcmp (icon_a->name, icon_b->name) == 0
&& nautilus_strcmp (icon_a->modifier, icon_b->modifier) == 0;
}
NautilusScalableIcon *
nautilus_icon_factory_get_icon_for_file (NautilusFile *file)
nautilus_icon_factory_get_icon_for_file (NautilusFile *file, const char* modifier)
{
char *uri, *file_uri;
const char *name;
......@@ -754,7 +780,7 @@ nautilus_icon_factory_get_icon_for_file (NautilusFile *file)
name = nautilus_icon_factory_get_icon_name_for_file (file);
/* Create the icon or find it in the cache if it's already there. */
scalable_icon = nautilus_scalable_icon_get (uri, name);