diff options
author | Darin Adler <darin@src.gnome.org> | 2000-04-04 01:00:13 +0000 |
---|---|---|
committer | Darin Adler <darin@src.gnome.org> | 2000-04-04 01:00:13 +0000 |
commit | 276a5a1001a00ad0f0be1525b6b730c01c144ebe (patch) | |
tree | b20e2ea85450a60995cd474c3d8fdab14448a028 /libnautilus | |
parent | 2fe15f1645d39857e32adcdb375c93ec1bb2a3ed (diff) | |
download | nautilus-276a5a1001a00ad0f0be1525b6b730c01c144ebe.tar.gz |
First cut at tiled background images.
First cut at tiled background images.
There's no UI for setting them yet, they are only in
the icon view, and they don't work properly with scrolling yet.
* libnautilus/Makefile.am:
* libnautilus/nautilus-gdk-extensions.c:
* libnautilus/nautilus-gdk-extensions.h:
* libnautilus/nautilus-gdk-pixbuf-extensions.c:
* libnautilus/nautilus-gdk-pixbuf-extensions.h:
Split the GdkPixbuf stuff into its own file.
* libnautilus/nautilus-background.c:
(nautilus_background_destroy): Fixed a bunch of leaks
and added new code to stop pixbuf loading.
(nautilus_background_draw): Added call to draw tiled
background image. Converted gradients to use gdk_rgb
instead of gdk_color.
(nautilus_background_get_tile_image_uri): Implemented.
(nautilus_background_set_color): Added short-circuit
for background image case.
(load_image_callback),
(nautilus_background_set_tile_image_uri): Implemented.
Include code to load in the tiled image when its URI is set.
(nautilus_background_receive_dropped_color): Set the
tile image to NULL when a color is dropped.
* libnautilus/nautilus-gdk-extensions.c:
* libnautilus/nautilus-gdk-extensions.h:
(nautilus_fill_rectangle_with_color),
(nautilus_fill_rectangle_with_color),
(nautilus_interpolate_color): Changed from gdk_color
to gdk_rgb.
(nautilus_parse_rgb_with_white_default): Added function
for gdk_rgb similar to what we already have for gdk_color.
* libnautilus/nautilus-icon-canvas-item.c:
* libnautilus/nautilus-icon-container.c:
* libnautilus/nautilus-list.c:
Use gdk-pixbuf extensions in new location.
* libnautilus/nautilus-metadata.h:
Added metadata keys for background images.
* src/ntl-view.c:
Added lots of stronger checks for NAUTILUS_IS_VIEW since
this is where we run into trouble with a bug I ran into.
* src/file-manager/icon-view.c: Added code to handle
the new background images.
(create_icon_container): Keep around the handler ID when
connecting to the "changed" message of the background so
we can block the handler as needed.
(fm_icon_view_begin_loading): Load the background image
as well as the background color. We need to block the
background changed signal handler so we don't get
confused while the color but not the image is set up.
(fm_icon_view_background_changed_callback): Save the
background image URI as well as the background color in
the metadata.
Diffstat (limited to 'libnautilus')
-rw-r--r-- | libnautilus/Makefile.am | 2 | ||||
-rw-r--r-- | libnautilus/nautilus-background.c | 160 | ||||
-rw-r--r-- | libnautilus/nautilus-gdk-extensions.c | 140 | ||||
-rw-r--r-- | libnautilus/nautilus-gdk-extensions.h | 43 | ||||
-rw-r--r-- | libnautilus/nautilus-gdk-pixbuf-extensions.c | 295 | ||||
-rw-r--r-- | libnautilus/nautilus-gdk-pixbuf-extensions.h | 59 | ||||
-rw-r--r-- | libnautilus/nautilus-icon-canvas-item.c | 1 | ||||
-rw-r--r-- | libnautilus/nautilus-icon-container.c | 2 | ||||
-rw-r--r-- | libnautilus/nautilus-list.c | 2 | ||||
-rw-r--r-- | libnautilus/nautilus-metadata.h | 42 |
10 files changed, 574 insertions, 172 deletions
diff --git a/libnautilus/Makefile.am b/libnautilus/Makefile.am index 2182da01d..7259cbbbf 100644 --- a/libnautilus/Makefile.am +++ b/libnautilus/Makefile.am @@ -39,6 +39,7 @@ libnautilusinclude_HEADERS= \ nautilus-file-utilities.h \ nautilus-file.h \ nautilus-gdk-extensions.h \ + nautilus-gdk-pixbuf-extensions.h \ nautilus-glib-extensions.h \ nautilus-global-preferences.h \ nautilus-gnome-extensions.h \ @@ -75,6 +76,7 @@ libnautilus_la_SOURCES=$(nautilus_idl_sources) \ nautilus-file-utilities.c \ nautilus-file.c \ nautilus-gdk-extensions.c \ + nautilus-gdk-pixbuf-extensions.c \ nautilus-glib-extensions.c \ nautilus-global-preferences.c \ nautilus-gnome-extensions.c \ diff --git a/libnautilus/nautilus-background.c b/libnautilus/nautilus-background.c index 5a5aea867..944875a26 100644 --- a/libnautilus/nautilus-background.c +++ b/libnautilus/nautilus-background.c @@ -27,27 +27,27 @@ #include <gtk/gtksignal.h> #include "nautilus-gdk-extensions.h" +#include "nautilus-gdk-pixbuf-extensions.h" #include "nautilus-background-canvas-group.h" #include "nautilus-lib-self-check-functions.h" #include "nautilus-gtk-macros.h" #include "nautilus-string.h" -static void nautilus_background_initialize_class (gpointer klass); -static void nautilus_background_initialize (gpointer object, - gpointer klass); -static void nautilus_background_destroy (GtkObject *object); - -static void nautilus_background_draw_flat_box (GtkStyle *style, - GdkWindow *window, - GtkStateType state_type, - GtkShadowType shadow_type, - GdkRectangle *area, - GtkWidget *widget, - gchar *detail, - gint x, - gint y, - gint width, - gint height); +static void nautilus_background_initialize_class (gpointer klass); +static void nautilus_background_initialize (gpointer object, + gpointer klass); +static void nautilus_background_destroy (GtkObject *object); +static void nautilus_background_draw_flat_box (GtkStyle *style, + GdkWindow *window, + GtkStateType state_type, + GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, + char *detail, + int x, + int y, + int width, + int height); NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusBackground, nautilus_background, GTK_TYPE_OBJECT) @@ -62,6 +62,8 @@ struct NautilusBackgroundDetails { char *color; char *tile_image_uri; + GdkPixbuf *tile_image; + NautilusPixbufLoadHandle *load_tile_image_handle; }; static void @@ -101,6 +103,14 @@ nautilus_background_destroy (GtkObject *object) NautilusBackground *background; background = NAUTILUS_BACKGROUND (object); + + nautilus_cancel_gdk_pixbuf_load (background->details->load_tile_image_handle); + + g_free (background->details->color); + g_free (background->details->tile_image_uri); + if (background->details->tile_image != NULL) { + gdk_pixbuf_unref (background->details->tile_image); + } g_free (background->details); NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); @@ -119,24 +129,36 @@ nautilus_background_draw (NautilusBackground *background, GdkColormap *colormap, const GdkRectangle *rectangle) { - char *start_color_spec; - char *end_color_spec; - GdkColor start_color; - GdkColor end_color; + char *start_color_spec, *end_color_spec; + guint32 start_rgb, end_rgb; gboolean horizontal_gradient; - start_color_spec = nautilus_gradient_get_start_color_spec (background->details->color); - end_color_spec = nautilus_gradient_get_end_color_spec (background->details->color); - horizontal_gradient = nautilus_gradient_is_horizontal (background->details->color); - - nautilus_gdk_color_parse_with_white_default (start_color_spec, &start_color); - nautilus_gdk_color_parse_with_white_default (end_color_spec, &end_color); - - g_free (start_color_spec); - g_free (end_color_spec); - - nautilus_fill_rectangle_with_gradient (drawable, gc, colormap, rectangle, - &start_color, &end_color, horizontal_gradient); + if (background->details->tile_image != NULL) { + nautilus_gdk_pixbuf_render_to_drawable_tiled (background->details->tile_image, + drawable, + gc, + rectangle, + GDK_RGB_DITHER_NORMAL, + 0, 0); + } else { + start_color_spec = nautilus_gradient_get_start_color_spec (background->details->color); + end_color_spec = nautilus_gradient_get_end_color_spec (background->details->color); + horizontal_gradient = nautilus_gradient_is_horizontal (background->details->color); + + start_rgb = nautilus_parse_rgb_with_white_default (start_color_spec); + end_rgb = nautilus_parse_rgb_with_white_default (end_color_spec); + + g_free (start_color_spec); + g_free (end_color_spec); + + nautilus_fill_rectangle_with_gradient (drawable, + gc, + colormap, + rectangle, + start_rgb, + end_rgb, + horizontal_gradient); + } } char * @@ -147,19 +169,67 @@ nautilus_background_get_color (NautilusBackground *background) return g_strdup (background->details->color); } +char * +nautilus_background_get_tile_image_uri (NautilusBackground *background) +{ + g_return_val_if_fail (NAUTILUS_IS_BACKGROUND (background), NULL); + + return g_strdup (background->details->tile_image_uri); +} + void nautilus_background_set_color (NautilusBackground *background, const char *color) { g_return_if_fail (NAUTILUS_IS_BACKGROUND (background)); + if (nautilus_strcmp (background->details->color, color) == 0) { + return; + } + g_free (background->details->color); background->details->color = g_strdup (color); gtk_signal_emit (GTK_OBJECT (background), signals[CHANGED]); } -#if 0 +static void +load_image_callback (GnomeVFSResult error, + GdkPixbuf *pixbuf, + gpointer callback_data) +{ + NautilusBackground *background; + + background = NAUTILUS_BACKGROUND (callback_data); + + g_assert (background->details->tile_image == NULL); + g_assert (background->details->load_tile_image_handle != NULL); + + background->details->load_tile_image_handle = NULL; + + /* Just ignore errors. */ + if (pixbuf == NULL) { + return; + } + + gdk_pixbuf_ref (pixbuf); + background->details->tile_image = pixbuf; + + gtk_signal_emit (GTK_OBJECT (background), signals[CHANGED]); +} + +static void +start_loading_tile_image (NautilusBackground *background) +{ + if (background->details->tile_image_uri == NULL) { + return; + } + + background->details->load_tile_image_handle = + nautilus_gdk_pixbuf_load_async (background->details->tile_image_uri, + load_image_callback, + background); +} void nautilus_background_set_tile_image_uri (NautilusBackground *background, @@ -167,14 +237,24 @@ nautilus_background_set_tile_image_uri (NautilusBackground *background, { g_return_if_fail (NAUTILUS_IS_BACKGROUND (background)); - g_free (background->details->color); - background->details->color = g_strdup (color); + if (nautilus_strcmp (background->details->tile_image_uri, image_uri) == 0) { + return; + } + + nautilus_cancel_gdk_pixbuf_load (background->details->load_tile_image_handle); + background->details->load_tile_image_handle = NULL; + + g_free (background->details->tile_image_uri); + if (background->details->tile_image != NULL) { + gdk_pixbuf_unref (background->details->tile_image); + background->details->tile_image = NULL; + } + background->details->tile_image_uri = g_strdup (image_uri); + start_loading_tile_image (background); gtk_signal_emit (GTK_OBJECT (background), signals[CHANGED]); } -#endif - static GtkStyleClass * nautilus_gtk_style_get_default_class (void) { @@ -253,7 +333,7 @@ nautilus_background_draw_flat_box (GtkStyle *style, rectangle.height = height; nautilus_background_draw (background, window, gc, - gtk_widget_get_colormap(widget), + gtk_widget_get_colormap (widget), &rectangle); gdk_gc_unref (gc); @@ -297,8 +377,7 @@ nautilus_background_set_widget_style (NautilusBackground *background, /* Set up the colors in the style. */ start_color_spec = nautilus_gradient_get_start_color_spec (background->details->color); - nautilus_gdk_color_parse_with_white_default - (start_color_spec, &color); + nautilus_gdk_color_parse_with_white_default (start_color_spec, &color); g_free (start_color_spec); style->bg[GTK_STATE_NORMAL] = color; style->base[GTK_STATE_NORMAL] = color; @@ -436,6 +515,7 @@ nautilus_background_receive_dropped_color (NautilusBackground *background, g_free (color_spec); nautilus_background_set_color (background, new_gradient_spec); + nautilus_background_set_tile_image_uri (background, NULL); g_free (new_gradient_spec); } diff --git a/libnautilus/nautilus-gdk-extensions.c b/libnautilus/nautilus-gdk-extensions.c index d4048ffbe..d9a9ca1da 100644 --- a/libnautilus/nautilus-gdk-extensions.c +++ b/libnautilus/nautilus-gdk-extensions.c @@ -63,12 +63,12 @@ void nautilus_fill_rectangle_with_color (GdkDrawable *drawable, GdkGC *gc, const GdkRectangle *rectangle, - const GdkColor *color) + guint32 rgb) { GdkGCValues saved_values; gdk_gc_get_values(gc, &saved_values); - gdk_gc_set_foreground (gc, (GdkColor *) color); + gdk_rgb_gc_set_foreground (gc, rgb); nautilus_fill_rectangle (drawable, gc, rectangle); gdk_gc_set_foreground (gc, &saved_values.foreground); } @@ -93,8 +93,8 @@ nautilus_fill_rectangle_with_gradient (GdkDrawable *drawable, GdkGC *gc, GdkColormap *colormap, const GdkRectangle *rectangle, - const GdkColor *start_color, - const GdkColor *end_color, + guint32 start_rgb, + guint32 end_rgb, gboolean horizontal) { GdkRectangle band_box; @@ -104,12 +104,11 @@ nautilus_fill_rectangle_with_gradient (GdkDrawable *drawable, guint16 last_band_size; gdouble multiplier; gint band; + guint32 band_rgb; g_return_if_fail (drawable != NULL); g_return_if_fail (gc != NULL); g_return_if_fail (rectangle != NULL); - g_return_if_fail (start_color != NULL); - g_return_if_fail (end_color != NULL); g_return_if_fail (horizontal == FALSE || horizontal == TRUE); /* Set up the band box so we can access it the same way for horizontal or vertical. */ @@ -129,21 +128,16 @@ nautilus_fill_rectangle_with_gradient (GdkDrawable *drawable, /* Fill each band with a separate nautilus_draw_rectangle call. */ for (band = 0; band < num_bands; band++) { - GdkColor band_color; - /* Compute a new color value for each band. */ - nautilus_interpolate_color (band * multiplier, start_color, end_color, &band_color); - if (!gdk_colormap_alloc_color (colormap, &band_color, FALSE, TRUE)) - g_warning ("could not allocate color for gradient"); - else { - /* Last band may need to be a bit smaller to avoid writing outside the box. - * This is more efficient than changing and restoring the clip. - */ - if (band == num_bands - 1) - *size = last_band_size; - - nautilus_fill_rectangle_with_color (drawable, gc, &band_box, &band_color); - } + band_rgb = nautilus_interpolate_color (band * multiplier, start_rgb, end_rgb); + + /* Last band may need to be a bit smaller to avoid writing outside the box. + * This is more efficient than changing and restoring the clip. + */ + if (band == num_bands - 1) + *size = last_band_size; + + nautilus_fill_rectangle_with_color (drawable, gc, &band_box, band_rgb); *position += *size; } } @@ -201,21 +195,20 @@ nautilus_rectangle_inset (GdkRectangle *rectangle, * instead do the interpolation in the best color space for expressing * human perception. */ -void +guint32 nautilus_interpolate_color (gdouble ratio, - const GdkColor *start_color, - const GdkColor *end_color, - GdkColor *interpolated_color) + guint32 start_rgb, + guint32 end_rgb) { - g_return_if_fail (ratio >= 0.0); - g_return_if_fail (ratio <= 1.0); - g_return_if_fail (start_color); - g_return_if_fail (end_color); - g_return_if_fail (interpolated_color); - - interpolated_color->red = start_color->red * (1.0 - ratio) + end_color->red * ratio; - interpolated_color->green = start_color->green * (1.0 - ratio) + end_color->green * ratio; - interpolated_color->blue = start_color->blue * (1.0 - ratio) + end_color->blue * ratio; + guchar red, green, blue; + + g_return_val_if_fail (ratio >= 0.0, 0); + g_return_val_if_fail (ratio <= 1.0, 0); + + red = ((start_rgb >> 16) & 0xFF) * (1.0 - ratio) + ((end_rgb >> 16) & 0xFF) * ratio; + green = ((start_rgb >> 8) & 0xFF) * (1.0 - ratio) + ((end_rgb >> 8) & 0xFF) * ratio; + blue = (start_rgb & 0xFF) * (1.0 - ratio) + (end_rgb & 0xFF) * ratio; + return (((red << 8) | green) << 8) | blue; } /** @@ -436,6 +429,28 @@ nautilus_gdk_color_parse_with_white_default (const char *color_spec, } /** + * nautilus_parse_rgb_with_white_default + * @color_spec: A color spec. + * Returns: An rgb value. + * + * The same as gdk_color_parse, except sets the color to white if + * the spec. can't be parsed instead of returning a boolean flag + * and returns a guint32 rgb value instead of a GdkColor. + */ +guint32 +nautilus_parse_rgb_with_white_default (const char *color_spec) +{ + GdkColor color; + + if (color_spec == NULL || !gdk_color_parse (color_spec, &color)) { + return 0xFFFFFF; + } + return ((color.red << 8) & 0xFF0000) + | (color.green & 0xFF00) + | ((color.blue >> 8) & 0xFF); +} + +/** * nautilus_gdk_font_equal * @font_a_null_allowed: A font or NULL. * @font_b_null_allowed: A font or NULL. @@ -453,31 +468,6 @@ nautilus_gdk_font_equal (GdkFont *font_a_null_allowed, return gdk_font_equal (font_a_null_allowed, font_b_null_allowed); } -/** - * nautilus_gdk_pixbuf_list_ref - * @pixbuf_list: A list of GdkPixbuf objects. - * - * Refs all the pixbufs. - **/ -void -nautilus_gdk_pixbuf_list_ref (GList *pixbuf_list) -{ - g_list_foreach (pixbuf_list, (GFunc) gdk_pixbuf_ref, NULL); -} - -/** - * nautilus_gdk_pixbuf_list_free - * @pixbuf_list: A list of GdkPixbuf objects. - * - * Unrefs all the pixbufs, then frees the list. - **/ -void -nautilus_gdk_pixbuf_list_free (GList *pixbuf_list) -{ - g_list_foreach (pixbuf_list, (GFunc) gdk_pixbuf_unref, NULL); - g_list_free (pixbuf_list); -} - #if ! defined (NAUTILUS_OMIT_SELF_CHECK) static char * @@ -488,28 +478,6 @@ nautilus_gdk_color_as_hex_string (GdkColor color) } static char * -nautilus_self_check_interpolate (gdouble ratio, - gushort r1, gushort g1, gushort b1, - gushort r2, gushort g2, gushort b2) -{ - GdkColor start_color; - GdkColor end_color; - GdkColor interpolated_color; - - start_color.red = r1; - start_color.green = g1; - start_color.blue = b1; - - end_color.red = r2; - end_color.green = g2; - end_color.blue = b2; - - nautilus_interpolate_color (ratio, &start_color, &end_color, &interpolated_color); - - return nautilus_gdk_color_as_hex_string (interpolated_color); -} - -static char * nautilus_self_check_parse (const char *color_spec) { GdkColor color; @@ -522,14 +490,10 @@ void nautilus_self_check_gdk_extensions (void) { /* nautilus_interpolate_color */ - NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0, 0, 0), - "rgb:0000/0000/0000"); - NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF), - "rgb:0000/0000/0000"); - NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_interpolate (0.5, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF), - "rgb:7FFF/7FFF/7FFF"); - NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_interpolate (1.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF), - "rgb:FFFF/FFFF/FFFF"); + NAUTILUS_CHECK_INTEGER_RESULT (nautilus_interpolate_color (0.0, 0, 0), 0); + NAUTILUS_CHECK_INTEGER_RESULT (nautilus_interpolate_color (0.0, 0, 0xFFFFFF), 0); + NAUTILUS_CHECK_INTEGER_RESULT (nautilus_interpolate_color (0.5, 0, 0xFFFFFF), 0x7F7F7F); + NAUTILUS_CHECK_INTEGER_RESULT (nautilus_interpolate_color (1.0, 0, 0xFFFFFF), 0xFFFFFF); /* nautilus_fill_rectangle */ /* Make a GdkImage and fill it, maybe? */ diff --git a/libnautilus/nautilus-gdk-extensions.h b/libnautilus/nautilus-gdk-extensions.h index de4f7162b..6b9eead97 100644 --- a/libnautilus/nautilus-gdk-extensions.h +++ b/libnautilus/nautilus-gdk-extensions.h @@ -35,12 +35,10 @@ char * nautilus_gradient_new (const char *start_color, const char *end_color, gboolean is_horizontal); - gboolean nautilus_gradient_is_gradient (const char *gradient_spec); char * nautilus_gradient_get_start_color_spec (const char *gradient_spec); char * nautilus_gradient_get_end_color_spec (const char *gradient_spec); gboolean nautilus_gradient_is_horizontal (const char *gradient_spec); - char * nautilus_gradient_set_left_color_spec (const char *gradient_spec, const char *left_color); char * nautilus_gradient_set_top_color_spec (const char *gradient_spec, @@ -53,11 +51,14 @@ char * nautilus_gradient_set_bottom_color_spec (const char *gradie /* A version of parse_color that substitutes a default color instead of returning a boolean to indicate it cannot be parsed. */ -void nautilus_gdk_color_parse_with_default (const char *color_spec, +void nautilus_gdk_coolor_parse_with_default (const char *color_spec, const GdkColor *default_color, - GdkColor *color); + GdkColor *parsed_color); void nautilus_gdk_color_parse_with_white_default (const char *color_spec, - GdkColor *color); + GdkColor *parsed_color); +guint32 nautilus_parse_rgb_with_default (const char *color_spec, + guint32 default_rgb); +guint32 nautilus_parse_rgb_with_white_default (const char *color_spec); /* Fill routines that take GdkRectangle parameters instead of four integers. */ void nautilus_fill_rectangle (GdkDrawable *drawable, @@ -66,36 +67,28 @@ void nautilus_fill_rectangle (GdkDrawable *drawab void nautilus_fill_rectangle_with_color (GdkDrawable *drawable, GdkGC *gc, const GdkRectangle *rectangle, - const GdkColor *color); + guint32 rgb); void nautilus_fill_rectangle_with_gradient (GdkDrawable *drawable, GdkGC *gc, GdkColormap *colormap, const GdkRectangle *rectangle, - const GdkColor *start_color, - const GdkColor *end_color, + guint32 start_rgb, + guint32 end_rgb, gboolean horizontal_gradient); /* Misc GdkRectangle helper functions */ -gboolean nautilus_rectangle_contains (const GdkRectangle *rectangle, - int x, - int y); - -void nautilus_rectangle_inset (GdkRectangle *rectangle, - int x, - int y); +gboolean nautilus_rectangle_contains (const GdkRectangle *rectangle, + int x, + int y); +void nautilus_rectangle_inset (GdkRectangle *rectangle, + int x, + int y); /* A basic operation we use for drawing gradients is interpolating two colors.*/ -void nautilus_interpolate_color (gdouble ratio, - const GdkColor *start_color, - const GdkColor *end_color, - GdkColor *interpolated_color); - +guint32 nautilus_interpolate_color (gdouble ratio, + guint32 start_rgb, + guint32 end_rgb); gboolean nautilus_gdk_font_equal (GdkFont *font_a_null_allowed, GdkFont *font_b_null_allowed); -/* Convenience functions for lists of GdkPixbuf objects. */ -void nautilus_gdk_pixbuf_list_ref (GList *pixbuf_list); -void nautilus_gdk_pixbuf_list_unref (GList *pixbuf_list); -void nautilus_gdk_pixbuf_list_free (GList *pixbuf_list); - #endif /* NAUTILUS_GDK_EXTENSIONS_H */ diff --git a/libnautilus/nautilus-gdk-pixbuf-extensions.c b/libnautilus/nautilus-gdk-pixbuf-extensions.c new file mode 100644 index 000000000..705fb1a54 --- /dev/null +++ b/libnautilus/nautilus-gdk-pixbuf-extensions.c @@ -0,0 +1,295 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* nautilus-gdk-pixbuf-extensions.c: Routines to augment what's in gdk-pixbuf. + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Darin Adler <darin@eazel.com> +*/ + +#include <config.h> +#include "nautilus-gdk-pixbuf-extensions.h" + +#include <gdk-pixbuf/gdk-pixbuf-loader.h> +#include <libgnomevfs/gnome-vfs-ops.h> +#include <libgnomevfs/gnome-vfs-async-ops.h> + +#define LOAD_BUFFER_SIZE 4096 + +struct NautilusPixbufLoadHandle { + GnomeVFSAsyncHandle *vfs_handle; + NautilusPixbufLoadCallback callback; + gpointer callback_data; + GdkPixbufLoader *loader; + char buffer[LOAD_BUFFER_SIZE]; +}; + +static void file_opened_callback (GnomeVFSAsyncHandle *vfs_handle, + GnomeVFSResult result, + gpointer callback_data); +static void file_read_callback (GnomeVFSAsyncHandle *vfs_handle, + GnomeVFSResult result, + gpointer buffer, + GnomeVFSFileSize bytes_requested, + GnomeVFSFileSize bytes_read, + gpointer callback_data); +static void file_closed_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer callback_data); +static void load_done (NautilusPixbufLoadHandle *handle, + GnomeVFSResult result, + GdkPixbuf *pixbuf); + +/** + * nautilus_gdk_pixbuf_list_ref + * @pixbuf_list: A list of GdkPixbuf objects. + * + * Refs all the pixbufs. + **/ +void +nautilus_gdk_pixbuf_list_ref (GList *pixbuf_list) +{ + g_list_foreach (pixbuf_list, (GFunc) gdk_pixbuf_ref, NULL); +} + +/** + * nautilus_gdk_pixbuf_list_free + * @pixbuf_list: A list of GdkPixbuf objects. + * + * Unrefs all the pixbufs, then frees the list. + **/ +void +nautilus_gdk_pixbuf_list_free (GList *pixbuf_list) +{ + g_list_foreach (pixbuf_list, (GFunc) gdk_pixbuf_unref, NULL); + g_list_free (pixbuf_list); +} + +GdkPixbuf * +nautilus_gdk_pixbuf_load (const char *uri) +{ + GnomeVFSResult result; + GnomeVFSHandle *handle; + char buffer[LOAD_BUFFER_SIZE]; + GnomeVFSFileSize bytes_read; + GdkPixbufLoader *loader; + GdkPixbuf *pixbuf; + + g_return_val_if_fail (uri != NULL, NULL); + + result = gnome_vfs_open (&handle, + uri, + GNOME_VFS_OPEN_READ); + if (result != GNOME_VFS_OK) { + return NULL; + } + + loader = gdk_pixbuf_loader_new (); + while (1) { + result = gnome_vfs_read (handle, + buffer, + sizeof (buffer), + &bytes_read); + if (result != GNOME_VFS_OK) { + break; + } + if (bytes_read == 0) { + break; + } + if (!gdk_pixbuf_loader_write (loader, + buffer, + bytes_read)) { + result = GNOME_VFS_ERROR_WRONGFORMAT; + break; + } + } + + if (result != GNOME_VFS_OK) { + gtk_object_unref (GTK_OBJECT (loader)); + gnome_vfs_close (handle); + return NULL; + } + + gnome_vfs_close (handle); + + pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); + if (pixbuf != NULL) { + gdk_pixbuf_ref (pixbuf); + } + gtk_object_unref (GTK_OBJECT (loader)); + + return pixbuf; +} + +NautilusPixbufLoadHandle * +nautilus_gdk_pixbuf_load_async (const char *uri, + NautilusPixbufLoadCallback callback, + gpointer callback_data) +{ + NautilusPixbufLoadHandle *handle; + GnomeVFSResult result; + + handle = g_new0 (NautilusPixbufLoadHandle, 1); + handle->callback = callback; + handle->callback_data = callback_data; + + result = gnome_vfs_async_open (&handle->vfs_handle, + uri, + GNOME_VFS_OPEN_READ, + file_opened_callback, + handle); + if (result != GNOME_VFS_OK) { + load_done (handle, result, NULL); + return NULL; + } + + return handle; +} + +static void +file_opened_callback (GnomeVFSAsyncHandle *vfs_handle, + GnomeVFSResult result, + gpointer callback_data) +{ + NautilusPixbufLoadHandle *handle; + + handle = callback_data; + g_assert (handle->vfs_handle == vfs_handle); + + if (result != GNOME_VFS_OK) { + load_done (handle, result, NULL); + return; + } + + handle->loader = gdk_pixbuf_loader_new (); + + gnome_vfs_async_read (handle->vfs_handle, + handle->buffer, + sizeof (handle->buffer), + file_read_callback, + handle); +} + +static void +file_read_callback (GnomeVFSAsyncHandle *vfs_handle, + GnomeVFSResult result, + gpointer buffer, + GnomeVFSFileSize bytes_requested, + GnomeVFSFileSize bytes_read, + gpointer callback_data) +{ + NautilusPixbufLoadHandle *handle; + GdkPixbuf *pixbuf; + + handle = callback_data; + g_assert (handle->vfs_handle == vfs_handle); + g_assert (handle->buffer == buffer); + + if (result == GNOME_VFS_OK && bytes_read != 0) { + if (!gdk_pixbuf_loader_write (handle->loader, + buffer, + bytes_read)) { + result = GNOME_VFS_ERROR_WRONGFORMAT; + } + gnome_vfs_async_read (handle->vfs_handle, + handle->buffer, + sizeof (handle->buffer), + file_read_callback, + handle); + return; + } + + if (result != GNOME_VFS_OK) { + pixbuf = NULL; + } else { + pixbuf = gdk_pixbuf_loader_get_pixbuf (handle->loader); + } + + load_done (handle, result, pixbuf); +} + +static void +file_closed_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer callback_data) +{ + g_assert (callback_data == NULL); +} + +static void +free_pixbuf_load_handle (NautilusPixbufLoadHandle *handle) +{ + if (handle->loader != NULL) { + gtk_object_unref (GTK_OBJECT (handle->loader)); + } + g_free (handle); +} + +static void +load_done (NautilusPixbufLoadHandle *handle, + GnomeVFSResult result, + GdkPixbuf *pixbuf) +{ + if (handle->vfs_handle != NULL) { + gnome_vfs_async_close (handle->vfs_handle, file_closed_callback, NULL); + } + (* handle->callback) (result, pixbuf, handle->callback_data); + free_pixbuf_load_handle (handle); +} + +void +nautilus_cancel_gdk_pixbuf_load (NautilusPixbufLoadHandle *handle) +{ + if (handle == NULL) { + return; + } + if (handle->vfs_handle != NULL) { + gnome_vfs_async_cancel (handle->vfs_handle); + } + free_pixbuf_load_handle (handle); +} + +void +nautilus_gdk_pixbuf_render_to_drawable_tiled (GdkPixbuf *pixbuf, + GdkDrawable *drawable, + GdkGC *gc, + const GdkRectangle *rect, + GdkRgbDither dither, + int x_dither, + int y_dither) +{ + int x, y; + int width, height; + + for (x = rect->x; + x < rect->x + rect->width; + x += gdk_pixbuf_get_width (pixbuf)) { + width = MIN (gdk_pixbuf_get_width (pixbuf), rect->x + rect->width - x); + + for (y = rect->y; + y < rect->y + rect->height; + y += gdk_pixbuf_get_height (pixbuf)) { + height = MIN (gdk_pixbuf_get_height (pixbuf), rect->y + rect->height - y); + + gdk_pixbuf_render_to_drawable (pixbuf, drawable, gc, + 0, 0, + x, y, width, height, + dither, x_dither, y_dither); + } + } +} diff --git a/libnautilus/nautilus-gdk-pixbuf-extensions.h b/libnautilus/nautilus-gdk-pixbuf-extensions.h new file mode 100644 index 000000000..6019e5048 --- /dev/null +++ b/libnautilus/nautilus-gdk-pixbuf-extensions.h @@ -0,0 +1,59 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* nautilus-gdk-pixbuf-extensions.h: Routines to augment what's in gdk-pixbuf. + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Darin Adler <darin@eazel.com> +*/ + +#ifndef NAUTILUS_GDK_PIXBUF_EXTENSIONS_H +#define NAUTILUS_GDK_PIXBUF_EXTENSIONS_H + +#include <gdk-pixbuf/gdk-pixbuf.h> +#include <libgnomevfs/gnome-vfs-types.h> + +typedef struct NautilusPixbufLoadHandle NautilusPixbufLoadHandle; +typedef void (* NautilusPixbufLoadCallback) (GnomeVFSResult error, + GdkPixbuf *pixbuf, + gpointer callback_data); + +/* Convenience functions for lists of GdkPixbuf objects. */ +void nautilus_gdk_pixbuf_list_ref (GList *pixbuf_list); +void nautilus_gdk_pixbuf_list_unref (GList *pixbuf_list); +void nautilus_gdk_pixbuf_list_free (GList *pixbuf_list); + +/* Loading a GdkPixbuf with a URI. */ +GdkPixbuf * nautilus_gdk_pixbuf_load (const char *uri); + +/* Same thing async. */ +NautilusPixbufLoadHandle *nautilus_gdk_pixbuf_load_async (const char *uri, + NautilusPixbufLoadCallback callback, + gpointer callback_data); +void nautilus_cancel_gdk_pixbuf_load (NautilusPixbufLoadHandle *handle); + +/* Draw a GdkPixbuf tiled. */ +void nautilus_gdk_pixbuf_render_to_drawable_tiled (GdkPixbuf *pixbuf, + GdkDrawable *drawable, + GdkGC *gc, + const GdkRectangle *destination_rectangle, + GdkRgbDither dither, + int x_dither, + int y_dither); + +#endif /* NAUTILUS_GDK_PIXBUF_EXTENSIONS_H */ diff --git a/libnautilus/nautilus-icon-canvas-item.c b/libnautilus/nautilus-icon-canvas-item.c index b9ecaacfd..607392d2d 100644 --- a/libnautilus/nautilus-icon-canvas-item.c +++ b/libnautilus/nautilus-icon-canvas-item.c @@ -37,6 +37,7 @@ #include "nautilus-string.h" #include "nautilus-glib-extensions.h" #include "nautilus-gdk-extensions.h" +#include "nautilus-gdk-pixbuf-extensions.h" #include "nautilus-gtk-macros.h" #include "nautilus-gnome-extensions.h" #include "nautilus-graphic-effects.h" diff --git a/libnautilus/nautilus-icon-container.c b/libnautilus/nautilus-icon-container.c index d364b41bc..22ccda7de 100644 --- a/libnautilus/nautilus-icon-container.c +++ b/libnautilus/nautilus-icon-container.c @@ -35,7 +35,7 @@ #include <gdk-pixbuf/gnome-canvas-pixbuf.h> #include "nautilus-glib-extensions.h" -#include "nautilus-gdk-extensions.h" +#include "nautilus-gdk-pixbuf-extensions.h" #include "nautilus-gtk-extensions.h" #include "nautilus-gnome-extensions.h" #include "nautilus-gtk-macros.h" diff --git a/libnautilus/nautilus-list.c b/libnautilus/nautilus-list.c index 75c35a565..d681ef9bc 100644 --- a/libnautilus/nautilus-list.c +++ b/libnautilus/nautilus-list.c @@ -30,8 +30,8 @@ #include "nautilus-list.h" #include <gtk/gtkdnd.h> -#include "nautilus-gdk-extensions.h" #include "nautilus-glib-extensions.h" +#include "nautilus-gdk-pixbuf-extensions.h" #include "nautilus-gtk-macros.h" #include "nautilus-background.h" #include "nautilus-list-column-title.h" diff --git a/libnautilus/nautilus-metadata.h b/libnautilus/nautilus-metadata.h index de5b2046c..ee4a0ff3b 100644 --- a/libnautilus/nautilus-metadata.h +++ b/libnautilus/nautilus-metadata.h @@ -29,22 +29,30 @@ * should define its key here, so we can keep track of the whole set easily. */ -#define NAUTILUS_CUSTOM_ICON_METADATA_KEY "CUSTOM_ICON" -#define NAUTILUS_NOTES_METADATA_KEY "NOTES" -#define NAUTILUS_ANNOTATION_METADATA_KEY "ANNOTATION" -#define NAUTILUS_INITIAL_VIEW_METADATA_KEY "INITIAL_VIEW" -#define NAUTILUS_CONTENT_VIEWS_METADATA_KEY "CONTENT_VIEWS" - -#define ICON_VIEW_BACKGROUND_COLOR_METADATA_KEY "ICON_VIEW_BACKGROUND_COLOR" -#define ICON_VIEW_ZOOM_LEVEL_METADATA_KEY "ICON_VIEW_ZOOM_LEVEL" -#define ICON_VIEW_ICON_POSITION_METADATA_KEY "ICON_POSITION" -#define ICON_VIEW_ICON_SCALE_METADATA_KEY "ICON_SCALE" - -#define LIST_VIEW_BACKGROUND_COLOR_METADATA_KEY "LIST_VIEW_BACKGROUND_COLOR" -#define LIST_VIEW_ZOOM_LEVEL_METADATA_KEY "LIST_VIEW_ZOOM_LEVEL" -#define LIST_VIEW_SORT_COLUMN_METADATA_KEY "LIST_VIEW_SORT_COLUMN" -#define LIST_VIEW_SORT_REVERSED_METADATA_KEY "LIST_VIEW_SORT_REVERSED" - -#define INDEX_PANEL_BACKGROUND_COLOR_METADATA_KEY "INDEX_PANEL_BACKGROUND_COLOR" +/* Per-directory */ + +#define NAUTILUS_CUSTOM_ICON_METADATA_KEY "CUSTOM_ICON" +#define NAUTILUS_NOTES_METADATA_KEY "NOTES" +#define NAUTILUS_ANNOTATION_METADATA_KEY "ANNOTATION" +#define NAUTILUS_INITIAL_VIEW_METADATA_KEY "INITIAL_VIEW" +#define NAUTILUS_CONTENT_VIEWS_METADATA_KEY "CONTENT_VIEWS" + +#define ICON_VIEW_BACKGROUND_COLOR_METADATA_KEY "ICON_VIEW_BACKGROUND_COLOR" +#define NAUTILUS_ICON_VIEW_BACKGROUND_IMAGE_METADATA_KEY "ICON_VIEW_BACKGROUND_IMAGE" +#define ICON_VIEW_ZOOM_LEVEL_METADATA_KEY "ICON_VIEW_ZOOM_LEVEL" + +#define LIST_VIEW_BACKGROUND_COLOR_METADATA_KEY "LIST_VIEW_BACKGROUND_COLOR" +#define LIST_VIEW_BACKGROUND_IMAGE_METADATA_KEY "LIST_VIEW_BACKGROUND_IMAGE" +#define LIST_VIEW_ZOOM_LEVEL_METADATA_KEY "LIST_VIEW_ZOOM_LEVEL" +#define LIST_VIEW_SORT_COLUMN_METADATA_KEY "LIST_VIEW_SORT_COLUMN" +#define LIST_VIEW_SORT_REVERSED_METADATA_KEY "LIST_VIEW_SORT_REVERSED" + +#define INDEX_PANEL_BACKGROUND_COLOR_METADATA_KEY "INDEX_PANEL_BACKGROUND_COLOR" +#define NAUTILUS_INDEX_PANEL_BACKGROUND_IMAGE_METADATA_KEY "INDEX_PANEL_BACKGROUND_IMAGE" + +/* Per-file */ + +#define ICON_VIEW_ICON_POSITION_METADATA_KEY "ICON_POSITION" +#define ICON_VIEW_ICON_SCALE_METADATA_KEY "ICON_SCALE" #endif /* NAUTILUS_METADATA_H */ |