r3247: Experimental extended attributes support for setting MIME types
[rox-filer.git] / ROX-Filer / src / cell_icon.c
blob08248acd4658aafbb8e1656b71c2e52087a734b3
1 /*
2 * $Id$
4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2003, 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 "display.h"
37 #include "diritem.h"
38 #include "pixmaps.h"
39 #include "filer.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 &&
207 strcmp(item->mime_type->media_type, "image") == 0)
209 const guchar *path;
211 path = make_path(filer_window->real_path,
212 item->leafname);
214 view_item->image = g_fscache_lookup_full(pixmap_cache,
215 path, FSCACHE_LOOKUP_ONLY_NEW, NULL);
217 if (!view_item->image)
219 view_item->image = item->image;
220 if (view_item->image)
221 g_object_ref(view_item->image);
225 size = icon->view_details->filer_window->display_style_wanted;
227 if (size == AUTO_SIZE_ICONS)
229 if (!view_item->image || view_item->image == item->image)
230 size = SMALL_ICONS;
231 else
232 size = HUGE_ICONS;
234 if (size == HUGE_ICONS && view_item->image &&
235 !view_item->image->huge_pixbuf)
236 pixmap_make_huge(view_item->image);
238 return size;
241 static void cell_icon_get_size(GtkCellRenderer *cell,
242 GtkWidget *widget,
243 GdkRectangle *cell_area,
244 gint *x_offset,
245 gint *y_offset,
246 gint *width,
247 gint *height)
249 MaskedPixmap *image;
250 DisplayStyle size;
251 int w, h;
253 size = get_style(cell);
254 image = ((CellIcon *) cell)->item->image;
256 if (x_offset)
257 *x_offset = 0;
258 if (y_offset)
259 *y_offset = 0;
261 switch (size)
263 case SMALL_ICONS:
264 w = SMALL_WIDTH;
265 h = SMALL_HEIGHT;
266 break;
267 case LARGE_ICONS:
268 if (image)
270 w = image->width;
271 h = image->height;
273 else
275 w = ICON_WIDTH;
276 h = ICON_HEIGHT;
278 break;
279 case HUGE_ICONS:
280 if (image)
282 w = image->huge_width;
283 h = image->huge_height;
285 else
287 w = HUGE_WIDTH;
288 h = HUGE_HEIGHT;
290 break;
291 default:
292 w = 2;
293 h = 2;
294 break;
297 if (width)
298 *width = w;
299 if (height)
300 *height = h;
303 static void cell_icon_render(GtkCellRenderer *cell,
304 GdkWindow *window,
305 GtkWidget *widget,
306 GdkRectangle *background_area,
307 GdkRectangle *cell_area,
308 GdkRectangle *expose_area,
309 guint flags)
311 CellIcon *icon = (CellIcon *) cell;
312 ViewItem *view_item = icon->item;
313 DirItem *item;
314 DisplayStyle size;
315 gboolean selected = (flags & GTK_CELL_RENDERER_SELECTED) != 0;
317 g_return_if_fail(view_item != NULL);
319 item = view_item->item;
320 size = get_style(cell);
322 /* Draw the icon */
324 if (!view_item->image)
325 return;
327 switch (size)
329 case SMALL_ICONS:
331 GdkRectangle area = *cell_area;
332 area.width = MIN(area.width, SMALL_WIDTH);
333 area.x = cell_area->x + cell_area->width - area.width;
334 draw_small_icon(window, &area, item,
335 view_item->image, selected);
337 break;
339 case LARGE_ICONS:
340 draw_large_icon(window, cell_area, item,
341 view_item->image, selected);
342 break;
343 case HUGE_ICONS:
344 if (!item->image->huge_pixbuf)
345 pixmap_make_huge(item->image);
346 draw_huge_icon(window, cell_area, item,
347 view_item->image, selected);
348 break;
349 default:
350 g_warning("Unknown size %d\n", size);
351 break;