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/nautilus-gdk-pixbuf-extensions.c | |
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/nautilus-gdk-pixbuf-extensions.c')
-rw-r--r-- | libnautilus/nautilus-gdk-pixbuf-extensions.c | 295 |
1 files changed, 295 insertions, 0 deletions
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); + } + } +} |