Index: exo/exo-lazy-cell-renderer.c =================================================================== --- exo/exo-lazy-cell-renderer.c (revision 0) +++ exo/exo-lazy-cell-renderer.c (revision 0) @@ -0,0 +1,121 @@ +/* $Id$ */ +/*- + * Copyright (c) 2005 Benedikt Meurer . + * + * This 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. + * + * This 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 this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + + + +GType +exo_lazy_cell_renderer_get_type (void) +{ + static GType type = G_TYPE_INVALID; + + if (G_UNLIKELY (type == G_TYPE_INVALID)) + { + static const GTypeInfo info = + { + sizeof (ExoLazyCellRendererIface), + NULL, + NULL, + NULL, + NULL, + NULL, + 0, + 0, + NULL, + }; + + type = g_type_register_static (G_TYPE_INTERFACE, I_("ExoLazyCellRenderer"), &info, 0); + g_type_interface_add_prerequisite (type, GTK_TYPE_CELL_RENDERER); + } + + return type; +} + + + +/** + * exo_lazy_cell_renderer_render_and_resize: + * @lazy_cell_renderer : a #ExoLazyCellRenderer instance. + * @window : a #GdkDrawable to draw to. + * @widget : the widget owning @window. + * @background_area : entire cell area (including tree expanders and maybe padding on the sides). + * @cell_area : area normally rendered by a cell renderer. + * @expose_area : area that actually needs updating. + * @flags : flags that affect rendering. + * @x_offset : location to return x offset of cell relative to @cell_area or %NULL. + * @y_offset : location to return y offset of cell relative to @cell_area or %NULL. + * @width : location to return width needed to render a cell, or %NULL. + * @height : location to return height needed to render a cell, or %NULL. + * + * This method is an advanced version of gtk_cell_renderer_render() to support cell + * renderers that lazily determine the really required size for an item cell, e.g. + * an icon renderer for the #ExoIconView, which loads icons only on demand (when + * needed for drawing). + * + * The implementation of this method must return the actual size required for the + * cell in @width and @height and the offset relative to @cell_area in @x_offset + * and @y_offset. The @width and @height must be smaller than the @cell_area + * specified by the caller. + * + * Return value: %TRUE if the @lazy_cell_renderer wants the view to change the + * cell dimensions to whatever it placed in @x_offset, + * @y_offset, @width and @height, else %FALSE. + **/ +gboolean +exo_lazy_cell_renderer_render_and_resize (ExoLazyCellRenderer *lazy_cell_renderer, + GdkWindow *window, + GtkWidget *widget, + GdkRectangle *background_area, + GdkRectangle *cell_area, + GdkRectangle *expose_area, + GtkCellRendererState state, + gint *x_offset, + gint *y_offset, + gint *width, + gint *height) +{ + g_return_val_if_fail (EXO_IS_LAZY_CELL_RENDERER (lazy_cell_renderer), FALSE); + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); + + return (*EXO_LAZY_CELL_RENDERER_GET_IFACE (lazy_cell_renderer)->render_and_resize) (lazy_cell_renderer, + window, + widget, + background_area, + cell_area, + expose_area, + state, + x_offset, + y_offset, + width, + height); +} + + + +#define __EXO_LAZY_CELL_RENDERER_C__ +#include Index: exo/exo-lazy-cell-renderer.h =================================================================== --- exo/exo-lazy-cell-renderer.h (revision 0) +++ exo/exo-lazy-cell-renderer.h (revision 0) @@ -0,0 +1,76 @@ +/* $Id$ */ +/*- + * Copyright (c) 2005 Benedikt Meurer . + * + * This 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. + * + * This 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 this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __EXO_LAZY_CELL_RENDERER_H__ +#define __EXO_LAZY_CELL_RENDERER_H__ + +#include + +G_BEGIN_DECLS; + +typedef struct _ExoLazyCellRendererIface ExoLazyCellRendererIface; +typedef struct _ExoLazyCellRenderer ExoLazyCellRenderer; + +#define EXO_TYPE_LAZY_CELL_RENDERER (exo_lazy_cell_renderer_get_type ()) +#define EXO_LAZY_CELL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EXO_TYPE_LAZY_CELL_RENDERER, ExoLazyCellRenderer)) +#define EXO_IS_LAZY_CELL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EXO_TYPE_LAZY_CELL_RENDERER)) +#define EXO_LAZY_CELL_RENDERER_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), EXO_TYPE_LAZY_CELL_RENDERER, ExoLazyCellRendererIface)) + +struct _ExoLazyCellRendererIface +{ + /*< private >*/ + GTypeInterface __parent__; + + /*< public >*/ + gboolean (*render_and_resize) (ExoLazyCellRenderer *lazy_cell_renderer, + GdkWindow *window, + GtkWidget *widget, + GdkRectangle *background_area, + GdkRectangle *cell_area, + GdkRectangle *expose_area, + GtkCellRendererState state, + gint *x_offset, + gint *y_offset, + gint *width, + gint *height); + + /*< private >*/ + void (*reserved1) (void); + void (*reserved2) (void); + void (*reserved3) (void); +}; + +GType exo_lazy_cell_renderer_get_type (void) G_GNUC_CONST; + +gboolean exo_lazy_cell_renderer_render_and_resize (ExoLazyCellRenderer *lazy_cell_renderer, + GdkWindow *window, + GtkWidget *widget, + GdkRectangle *background_area, + GdkRectangle *cell_area, + GdkRectangle *expose_area, + GtkCellRendererState state, + gint *x_offset, + gint *y_offset, + gint *width, + gint *height); + +G_END_DECLS; + +#endif /* !__EXO_LAZY_CELL_RENDERER_H__ */ Index: exo/exo.h =================================================================== --- exo/exo.h (revision 19014) +++ exo/exo.h (working copy) @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include Index: exo/exo.symbols =================================================================== --- exo/exo.symbols (revision 19014) +++ exo/exo.symbols (working copy) @@ -189,6 +189,14 @@ #endif #endif +/* ExoLazyCellRenderer methods */ +#if IN_HEADER(__EXO_LAZY_CELL_RENDERER_H__) +#if IN_SOURCE(__EXO_LAZY_CELL_RENDERER_C__) +exo_lazy_cell_renderer_get_type G_GNUC_CONST +exo_lazy_cell_renderer_render_and_resize +#endif +#endif + /* exo-md5 functions */ #if IN_HEADER(__EXO_MD5_H__) #if IN_SOURCE(__EXO_MD5_C__) Index: exo/Makefile.am =================================================================== --- exo/Makefile.am (revision 19014) +++ exo/Makefile.am (working copy) @@ -18,6 +18,7 @@ exo-gobject-extensions.h \ exo-icon-bar.h \ exo-icon-view.h \ + exo-lazy-cell-renderer.h \ exo-md5.h \ exo-pango-extensions.h \ exo-string.h \ @@ -60,6 +61,7 @@ exo-gobject-extensions.c \ exo-icon-bar.c \ exo-icon-view.c \ + exo-lazy-cell-renderer.c \ exo-md5.c \ exo-pango-extensions.c \ exo-private.c \ Index: exo/exo-icon-view.c =================================================================== --- exo/exo-icon-view.c (revision 19014) +++ exo/exo-icon-view.c (working copy) @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -298,9 +299,10 @@ struct _ExoIconViewCellInfo { GtkCellRenderer *cell; + guint editing : 1; guint expand : 1; + guint lazy : 1; guint pack : 1; - guint editing : 1; gint position; GSList *attributes; GtkCellLayoutDataFunc func; @@ -2763,6 +2765,10 @@ GdkRectangle cell_area; gboolean rtl; GList *lp; + gint x_offset; + gint y_offset; + gint width; + gint height; if (G_UNLIKELY (icon_view->priv->model == NULL)) return; @@ -2823,11 +2829,31 @@ cell_area.x = x - item->area.x + cell_area.x; cell_area.y = y - item->area.y + cell_area.y; - gtk_cell_renderer_render (info->cell, - drawable, - GTK_WIDGET (icon_view), - &cell_area, &cell_area, area, flags); - + if (!info->lazy) + { + gtk_cell_renderer_render (info->cell, drawable, GTK_WIDGET (icon_view), + &cell_area, &cell_area, area, flags); + } + else if (exo_lazy_cell_renderer_render_and_resize (EXO_LAZY_CELL_RENDERER (info->cell), drawable, + GTK_WIDGET (icon_view), &cell_area, &cell_area, + area, flags, &x_offset, &y_offset, &width, &height)) + { + item->box[info->position].x = x_offset + cell_area.x; + item->box[info->position].y = y_offset + cell_area.y; + item->box[info->position].width = width; + item->box[info->position].height = height; + + if (icon_view->priv->orientation == GTK_ORIENTATION_HORIZONTAL) + { + item->before[info->position] = x_offset; + item->after[info->position] = cell_area.width - width - x_offset; + } + else + { + item->before[info->position] = y_offset; + item->after[info->position] = cell_area.height - height - y_offset; + } + } } } @@ -3841,6 +3867,7 @@ info = g_new0 (ExoIconViewCellInfo, 1); info->cell = renderer; info->expand = expand ? TRUE : FALSE; + info->lazy = EXO_IS_LAZY_CELL_RENDERER (renderer); info->pack = GTK_PACK_START; info->position = icon_view->priv->n_cells; @@ -3869,6 +3896,7 @@ info = g_new0 (ExoIconViewCellInfo, 1); info->cell = renderer; info->expand = expand ? TRUE : FALSE; + info->lazy = EXO_IS_LAZY_CELL_RENDERER (renderer); info->pack = GTK_PACK_END; info->position = icon_view->priv->n_cells;