r3768: Updated years.
[rox-filer.git] / ROX-Filer / src / cell_icon.c
blobe5c46043a3c8095448d9bd10104a5715b42fbec0
1 /*
2 * $Id$
4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2005, the ROX-Filer team.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
22 /* cell_icon.c - a GtkCellRenderer used for the icons in details mode
24 * Based on gtkcellrendererpixbuf.c.
27 #include "config.h"
29 #include <gtk/gtk.h>
30 #include <string.h>
32 #include "global.h"
34 #include "view_details.h"
35 #include "cell_icon.h"
36 #include "filer.h"
37 #include "display.h"
38 #include "diritem.h"
39 #include "pixmaps.h"
40 #include "type.h"
41 #include "support.h"
42 #include "fscache.h"
44 typedef struct _CellIcon CellIcon;
45 typedef struct _CellIconClass CellIconClass;
47 struct _CellIcon {
48 GtkCellRenderer parent;
50 ViewDetails *view_details;
51 ViewItem *item;
52 GdkColor background;
55 struct _CellIconClass {
56 GtkCellRendererClass parent_class;
60 /* Static prototypes */
61 static void cell_icon_set_property(GObject *object, guint param_id,
62 const GValue *value, GParamSpec *pspec);
63 static void cell_icon_init (CellIcon *cell);
64 static void cell_icon_class_init (CellIconClass *class);
65 static void cell_icon_get_size (GtkCellRenderer *cell,
66 GtkWidget *widget,
67 GdkRectangle *rectangle,
68 gint *x_offset,
69 gint *y_offset,
70 gint *width,
71 gint *height);
72 static void cell_icon_render (GtkCellRenderer *cell,
73 GdkWindow *window,
74 GtkWidget *widget,
75 GdkRectangle *background_area,
76 GdkRectangle *cell_area,
77 GdkRectangle *expose_area,
78 guint flags);
79 static GtkType cell_icon_get_type(void);
81 enum {
82 PROP_ZERO,
83 PROP_ITEM,
84 PROP_BACKGROUND_GDK,
87 /****************************************************************
88 * EXTERNAL INTERFACE *
89 ****************************************************************/
91 GtkCellRenderer *cell_icon_new(ViewDetails *view_details)
93 GtkCellRenderer *cell;
95 cell = GTK_CELL_RENDERER(g_object_new(cell_icon_get_type(), NULL));
96 ((CellIcon *) cell)->view_details = view_details;
98 return cell;
101 /****************************************************************
102 * INTERNAL FUNCTIONS *
103 ****************************************************************/
106 static GtkType cell_icon_get_type(void)
108 static GtkType cell_icon_type = 0;
110 if (!cell_icon_type)
112 static const GTypeInfo cell_icon_info =
114 sizeof (CellIconClass),
115 NULL, /* base_init */
116 NULL, /* base_finalize */
117 (GClassInitFunc) cell_icon_class_init,
118 NULL, /* class_finalize */
119 NULL, /* class_data */
120 sizeof (CellIcon),
121 0, /* n_preallocs */
122 (GInstanceInitFunc) cell_icon_init,
125 cell_icon_type = g_type_register_static(GTK_TYPE_CELL_RENDERER,
126 "CellIcon",
127 &cell_icon_info, 0);
130 return cell_icon_type;
133 static void cell_icon_init(CellIcon *icon)
135 icon->view_details = NULL;
138 static void cell_icon_class_init(CellIconClass *class)
140 GObjectClass *object_class = G_OBJECT_CLASS(class);
141 GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS(class);
143 object_class->set_property = cell_icon_set_property;
145 cell_class->get_size = cell_icon_get_size;
146 cell_class->render = cell_icon_render;
148 g_object_class_install_property(object_class,
149 PROP_ITEM,
150 g_param_spec_pointer("item",
151 "DirItem",
152 "The item to render.",
153 G_PARAM_WRITABLE));
155 g_object_class_install_property(object_class,
156 PROP_BACKGROUND_GDK,
157 g_param_spec_boxed("background_gdk",
158 "Background color",
159 "Background color as a GdkColor",
160 GDK_TYPE_COLOR,
161 G_PARAM_WRITABLE));
164 static void cell_icon_set_property(GObject *object, guint param_id,
165 const GValue *value, GParamSpec *pspec)
167 CellIcon *icon = (CellIcon *) object;
169 switch (param_id)
171 case PROP_ITEM:
172 icon->item = (ViewItem *) g_value_get_pointer(value);
173 break;
174 case PROP_BACKGROUND_GDK:
176 GdkColor *bg = g_value_get_boxed(value);
177 if (bg)
179 icon->background.red = bg->red;
180 icon->background.green = bg->green;
181 icon->background.blue = bg->blue;
183 break;
185 default:
186 G_OBJECT_WARN_INVALID_PROPERTY_ID(object,
187 param_id, pspec);
188 break;
192 /* Return the size to display this icon at. If huge, ensures that the image
193 * exists in that size, if present at all.
195 static DisplayStyle get_style(GtkCellRenderer *cell)
197 CellIcon *icon = (CellIcon *) cell;
198 ViewItem *view_item = icon->item;
199 DisplayStyle size;
200 DirItem *item = view_item->item;
202 if (!view_item->image)
204 FilerWindow *filer_window = icon->view_details->filer_window;
206 if (filer_window->show_thumbs && item->base_type == TYPE_FILE)
208 const guchar *path;
210 path = make_path(filer_window->real_path,
211 item->leafname);
213 view_item->image = g_fscache_lookup_full(pixmap_cache,
214 path, FSCACHE_LOOKUP_ONLY_NEW, NULL);
216 if (!view_item->image)
218 view_item->image = di_image(item);
219 if (view_item->image)
220 g_object_ref(view_item->image);
224 size = icon->view_details->filer_window->display_style_wanted;
226 if (size == AUTO_SIZE_ICONS)
228 if (!view_item->image || view_item->image == di_image(item))
229 size = SMALL_ICONS;
230 else
231 size = HUGE_ICONS;
233 if (size == HUGE_ICONS && view_item->image &&
234 !view_item->image->huge_pixbuf)
235 pixmap_make_huge(view_item->image);
237 return size;
240 static void cell_icon_get_size(GtkCellRenderer *cell,
241 GtkWidget *widget,
242 GdkRectangle *cell_area,
243 gint *x_offset,
244 gint *y_offset,
245 gint *width,
246 gint *height)
248 MaskedPixmap *image;
249 DisplayStyle size;
250 int w, h;
252 size = get_style(cell);
253 image = ((CellIcon *) cell)->item->image;
255 if (x_offset)
256 *x_offset = 0;
257 if (y_offset)
258 *y_offset = 0;
260 switch (size)
262 case SMALL_ICONS:
263 w = SMALL_WIDTH;
264 h = SMALL_HEIGHT;
265 break;
266 case LARGE_ICONS:
267 if (image)
269 w = image->width;
270 h = image->height;
272 else
274 w = ICON_WIDTH;
275 h = ICON_HEIGHT;
277 break;
278 case HUGE_ICONS:
279 if (image)
281 w = image->huge_width;
282 h = image->huge_height;
284 else
286 w = HUGE_WIDTH;
287 h = HUGE_HEIGHT;
289 break;
290 default:
291 w = 2;
292 h = 2;
293 break;
296 if (width)
297 *width = w;
298 if (height)
299 *height = h;
302 static void cell_icon_render(GtkCellRenderer *cell,
303 GdkWindow *window,
304 GtkWidget *widget,
305 GdkRectangle *background_area,
306 GdkRectangle *cell_area,
307 GdkRectangle *expose_area,
308 guint flags)
310 CellIcon *icon = (CellIcon *) cell;
311 ViewItem *view_item = icon->item;
312 DirItem *item;
313 DisplayStyle size;
314 gboolean selected = (flags & GTK_CELL_RENDERER_SELECTED) != 0;
316 g_return_if_fail(view_item != NULL);
318 item = view_item->item;
319 size = get_style(cell);
321 /* Draw the icon */
323 if (!view_item->image)
324 return;
326 switch (size)
328 case SMALL_ICONS:
330 GdkRectangle area = *cell_area;
331 area.width = MIN(area.width, SMALL_WIDTH);
332 area.x = cell_area->x + cell_area->width - area.width;
333 draw_small_icon(window, &area, item,
334 view_item->image, selected);
336 break;
338 case LARGE_ICONS:
339 draw_large_icon(window, cell_area, item,
340 view_item->image, selected);
341 break;
342 case HUGE_ICONS:
343 if (!di_image(item)->huge_pixbuf)
344 pixmap_make_huge(di_image(item));
345 draw_huge_icon(window, cell_area, item,
346 view_item->image, selected);
347 break;
348 default:
349 g_warning("Unknown size %d\n", size);
350 break;