r4523: Updated headers:
[rox-filer/ma.git] / ROX-Filer / src / cell_icon.c
blobaceb5fba51cbbf2c4abd4d987de4d1ab0275c6a0
1 /*
2 * ROX-Filer, filer for the ROX desktop project
3 * Copyright (C) 2006, Thomas Leonard and others (see changelog for details).
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
8 * any later version.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17 * Place, Suite 330, Boston, MA 02111-1307 USA
20 /* cell_icon.c - a GtkCellRenderer used for the icons in details mode
22 * Based on gtkcellrendererpixbuf.c.
25 #include "config.h"
27 #include <gtk/gtk.h>
28 #include <string.h>
30 #include "global.h"
32 #include "view_details.h"
33 #include "cell_icon.h"
34 #include "filer.h"
35 #include "display.h"
36 #include "diritem.h"
37 #include "pixmaps.h"
38 #include "type.h"
39 #include "support.h"
40 #include "fscache.h"
42 typedef struct _CellIcon CellIcon;
43 typedef struct _CellIconClass CellIconClass;
45 struct _CellIcon {
46 GtkCellRenderer parent;
48 ViewDetails *view_details;
49 ViewItem *item;
50 GdkColor background;
53 struct _CellIconClass {
54 GtkCellRendererClass parent_class;
58 /* Static prototypes */
59 static void cell_icon_set_property(GObject *object, guint param_id,
60 const GValue *value, GParamSpec *pspec);
61 static void cell_icon_init (CellIcon *cell);
62 static void cell_icon_class_init (CellIconClass *class);
63 static void cell_icon_get_size (GtkCellRenderer *cell,
64 GtkWidget *widget,
65 GdkRectangle *rectangle,
66 gint *x_offset,
67 gint *y_offset,
68 gint *width,
69 gint *height);
70 static void cell_icon_render (GtkCellRenderer *cell,
71 GdkWindow *window,
72 GtkWidget *widget,
73 GdkRectangle *background_area,
74 GdkRectangle *cell_area,
75 GdkRectangle *expose_area,
76 guint flags);
77 static GtkType cell_icon_get_type(void);
79 enum {
80 PROP_ZERO,
81 PROP_ITEM,
82 PROP_BACKGROUND_GDK,
85 /****************************************************************
86 * EXTERNAL INTERFACE *
87 ****************************************************************/
89 GtkCellRenderer *cell_icon_new(ViewDetails *view_details)
91 GtkCellRenderer *cell;
93 cell = GTK_CELL_RENDERER(g_object_new(cell_icon_get_type(), NULL));
94 ((CellIcon *) cell)->view_details = view_details;
96 return cell;
99 /****************************************************************
100 * INTERNAL FUNCTIONS *
101 ****************************************************************/
104 static GtkType cell_icon_get_type(void)
106 static GtkType cell_icon_type = 0;
108 if (!cell_icon_type)
110 static const GTypeInfo cell_icon_info =
112 sizeof (CellIconClass),
113 NULL, /* base_init */
114 NULL, /* base_finalize */
115 (GClassInitFunc) cell_icon_class_init,
116 NULL, /* class_finalize */
117 NULL, /* class_data */
118 sizeof (CellIcon),
119 0, /* n_preallocs */
120 (GInstanceInitFunc) cell_icon_init,
123 cell_icon_type = g_type_register_static(GTK_TYPE_CELL_RENDERER,
124 "CellIcon",
125 &cell_icon_info, 0);
128 return cell_icon_type;
131 static void cell_icon_init(CellIcon *icon)
133 icon->view_details = NULL;
136 static void cell_icon_class_init(CellIconClass *class)
138 GObjectClass *object_class = G_OBJECT_CLASS(class);
139 GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS(class);
141 object_class->set_property = cell_icon_set_property;
143 cell_class->get_size = cell_icon_get_size;
144 cell_class->render = cell_icon_render;
146 g_object_class_install_property(object_class,
147 PROP_ITEM,
148 g_param_spec_pointer("item",
149 "DirItem",
150 "The item to render.",
151 G_PARAM_WRITABLE));
153 g_object_class_install_property(object_class,
154 PROP_BACKGROUND_GDK,
155 g_param_spec_boxed("background_gdk",
156 "Background color",
157 "Background color as a GdkColor",
158 GDK_TYPE_COLOR,
159 G_PARAM_WRITABLE));
162 static void cell_icon_set_property(GObject *object, guint param_id,
163 const GValue *value, GParamSpec *pspec)
165 CellIcon *icon = (CellIcon *) object;
167 switch (param_id)
169 case PROP_ITEM:
170 icon->item = (ViewItem *) g_value_get_pointer(value);
171 break;
172 case PROP_BACKGROUND_GDK:
174 GdkColor *bg = g_value_get_boxed(value);
175 if (bg)
177 icon->background.red = bg->red;
178 icon->background.green = bg->green;
179 icon->background.blue = bg->blue;
181 break;
183 default:
184 G_OBJECT_WARN_INVALID_PROPERTY_ID(object,
185 param_id, pspec);
186 break;
190 /* Return the size to display this icon at. If huge, ensures that the image
191 * exists in that size, if present at all.
193 static DisplayStyle get_style(GtkCellRenderer *cell)
195 CellIcon *icon = (CellIcon *) cell;
196 ViewItem *view_item = icon->item;
197 DisplayStyle size;
198 DirItem *item = view_item->item;
200 if (!view_item->image)
202 FilerWindow *filer_window = icon->view_details->filer_window;
204 if (filer_window->show_thumbs && item->base_type == TYPE_FILE)
206 const guchar *path;
208 path = make_path(filer_window->real_path,
209 item->leafname);
211 view_item->image = g_fscache_lookup_full(pixmap_cache,
212 path, FSCACHE_LOOKUP_ONLY_NEW, NULL);
214 if (!view_item->image)
216 view_item->image = di_image(item);
217 if (view_item->image)
218 g_object_ref(view_item->image);
222 size = icon->view_details->filer_window->display_style_wanted;
224 if (size == AUTO_SIZE_ICONS)
226 if (!view_item->image || view_item->image == di_image(item))
227 size = SMALL_ICONS;
228 else
229 size = HUGE_ICONS;
231 if (size == HUGE_ICONS && view_item->image &&
232 !view_item->image->huge_pixbuf)
233 pixmap_make_huge(view_item->image);
235 return size;
238 static void cell_icon_get_size(GtkCellRenderer *cell,
239 GtkWidget *widget,
240 GdkRectangle *cell_area,
241 gint *x_offset,
242 gint *y_offset,
243 gint *width,
244 gint *height)
246 MaskedPixmap *image;
247 DisplayStyle size;
248 int w, h;
250 size = get_style(cell);
251 image = ((CellIcon *) cell)->item->image;
253 if (x_offset)
254 *x_offset = 0;
255 if (y_offset)
256 *y_offset = 0;
258 switch (size)
260 case SMALL_ICONS:
261 w = SMALL_WIDTH;
262 h = SMALL_HEIGHT;
263 break;
264 case LARGE_ICONS:
265 if (image)
267 w = image->width;
268 h = image->height;
270 else
272 w = ICON_WIDTH;
273 h = ICON_HEIGHT;
275 break;
276 case HUGE_ICONS:
277 if (image)
279 w = image->huge_width;
280 h = image->huge_height;
282 else
284 w = HUGE_WIDTH;
285 h = HUGE_HEIGHT;
287 break;
288 default:
289 w = 2;
290 h = 2;
291 break;
294 if (width)
295 *width = w;
296 if (height)
297 *height = h;
300 static void cell_icon_render(GtkCellRenderer *cell,
301 GdkWindow *window,
302 GtkWidget *widget,
303 GdkRectangle *background_area,
304 GdkRectangle *cell_area,
305 GdkRectangle *expose_area,
306 guint flags)
308 CellIcon *icon = (CellIcon *) cell;
309 ViewItem *view_item = icon->item;
310 DirItem *item;
311 DisplayStyle size;
312 gboolean selected = (flags & GTK_CELL_RENDERER_SELECTED) != 0;
313 GdkColor *color;
315 g_return_if_fail(view_item != NULL);
317 item = view_item->item;
318 size = get_style(cell);
319 color = &widget->style->base[icon->view_details->filer_window->selection_state];
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, color);
336 break;
338 case LARGE_ICONS:
339 draw_large_icon(window, cell_area, item,
340 view_item->image, selected, color);
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, color);
347 break;
348 default:
349 g_warning("Unknown size %d\n", size);
350 break;