2
* C Implementation: ptkfileiconrenderer
4
* Description: PtkFileIconRenderer is used to render file icons
7
* Author: Hong Jen Yee (PCMan) <pcman.tw (AT) gmail.com>, (C) 2006
9
* Copyright: See COPYING file that comes with this distribution
11
* Part of this class is taken from GtkCellRendererPixbuf written by
12
* Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
17
#include "ptk-file-icon-renderer.h"
20
ptk_file_icon_renderer_init ( PtkFileIconRenderer *renderer );
23
ptk_file_icon_renderer_class_init ( PtkFileIconRendererClass *klass );
26
ptk_file_icon_renderer_get_property ( GObject *object,
32
ptk_file_icon_renderer_set_property ( GObject *object,
38
ptk_file_icon_renderer_finalize ( GObject *gobject );
42
ptk_file_icon_renderer_get_size ( GtkCellRenderer *cell,
44
GdkRectangle *cell_area,
52
ptk_file_icon_renderer_render ( GtkCellRenderer *cell,
55
GdkRectangle *background_area,
56
GdkRectangle *cell_area,
57
GdkRectangle *expose_area,
67
static gpointer parent_class;
69
static GdkPixbuf* link_icon = NULL;
71
/* GdkPixbuf RGBA C-Source image dump */
73
#pragma align 4 (link_icon_data)
76
static const guint8 link_icon_data[] __attribute__ ((__aligned__ (4))) =
78
static const guint8 link_icon_data[] =
81
/* Pixbuf magic (0x47646b50) */
83
/* length: header (24) + pixel_data (400) */
85
/* pixdata_type (0x1010002) */
94
"\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200"
95
"\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200"
96
"\200\377\0\0\0\377\200\200\200\377\377\377\377\377\377\377\377\377\377"
97
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
98
"\377\377\377\377\377\377\0\0\0\377\200\200\200\377\377\377\377\377\0"
99
"\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377"
100
"\377\377\377\0\0\0\377\200\200\200\377\377\377\377\377\0\0\0\377\0\0"
101
"\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
102
"\377\0\0\0\377\200\200\200\377\377\377\377\377\0\0\0\377\0\0\0\377\0"
103
"\0\0\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\0\0\0\377"
104
"\200\200\200\377\377\377\377\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0"
105
"\377\0\0\0\377\0\0\0\377\377\377\377\377\0\0\0\377\200\200\200\377\377"
106
"\377\377\377\0\0\0\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0"
107
"\0\377\0\0\0\377\377\377\377\377\0\0\0\377\200\200\200\377\377\377\377"
108
"\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0"
109
"\377\0\0\0\377\377\377\377\377\0\0\0\377\200\200\200\377\377\377\377"
110
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
111
"\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377"
112
"\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
113
"\0\0\0\377\0\0\0\377"
117
/***************************************************************************
119
* ptk_file_icon_renderer_get_type: here we register our type with
120
* the GObject type system if we
121
* haven't done so yet. Everything
122
* else is done in the callbacks.
124
***************************************************************************/
127
ptk_file_icon_renderer_get_type ( void )
129
static GType renderer_type = 0;
130
if ( G_UNLIKELY( !renderer_type ) )
132
static const GTypeInfo renderer_info =
134
sizeof ( PtkFileIconRendererClass ),
135
NULL, /* base_init */
136
NULL, /* base_finalize */
137
( GClassInitFunc ) ptk_file_icon_renderer_class_init,
138
NULL, /* class_finalize */
139
NULL, /* class_data */
140
sizeof ( PtkFileIconRenderer ),
142
( GInstanceInitFunc ) ptk_file_icon_renderer_init,
145
/* Derive from GtkCellRendererPixbuf */
146
renderer_type = g_type_register_static ( GTK_TYPE_CELL_RENDERER_PIXBUF,
147
"PtkFileIconRenderer",
152
return renderer_type;
156
/***************************************************************************
158
* ptk_file_icon_renderer_init: set some default properties of the
159
* parent (GtkCellRendererPixbuf).
161
***************************************************************************/
164
ptk_file_icon_renderer_init ( PtkFileIconRenderer *renderer )
168
link_icon = gdk_pixbuf_new_from_inline(
169
sizeof(link_icon_data),
172
g_object_add_weak_pointer( G_OBJECT(link_icon), (gpointer)&link_icon );
175
gdk_pixbuf_ref( (link_icon) );
179
/***************************************************************************
181
* ptk_file_icon_renderer_class_init:
183
***************************************************************************/
186
ptk_file_icon_renderer_class_init ( PtkFileIconRendererClass *klass )
188
GtkCellRendererClass * parent_renderer_class = GTK_CELL_RENDERER_CLASS( klass );
189
GObjectClass *object_class = G_OBJECT_CLASS( klass );
191
parent_class = g_type_class_peek_parent ( klass );
192
object_class->finalize = ptk_file_icon_renderer_finalize;
194
/* Hook up functions to set and get our
195
* custom cell renderer properties */
196
object_class->get_property = ptk_file_icon_renderer_get_property;
197
object_class->set_property = ptk_file_icon_renderer_set_property;
199
parent_renderer_class->get_size = ptk_file_icon_renderer_get_size;
200
parent_renderer_class->render = ptk_file_icon_renderer_render;
202
g_object_class_install_property ( object_class,
204
g_param_spec_pointer ( "info",
207
G_PARAM_READWRITE ) );
208
g_object_class_install_property ( object_class,
210
g_param_spec_boolean ( "follow-state",
212
"Whether the rendered pixbuf should be "
213
"colorized according to the state",
215
G_PARAM_READWRITE ) );
219
/***************************************************************************
221
* ptk_file_icon_renderer_finalize: free any resources here
223
***************************************************************************/
226
ptk_file_icon_renderer_finalize ( GObject *object )
228
PtkFileIconRenderer* renderer = PTK_FILE_ICON_RENDERER(object);
230
vfs_file_info_unref( renderer->info );
232
gdk_pixbuf_unref( (link_icon) );
233
( * G_OBJECT_CLASS ( parent_class ) ->finalize ) ( object );
236
/***************************************************************************
238
* ptk_file_icon_renderer_get_property: as it says
240
***************************************************************************/
243
ptk_file_icon_renderer_get_property ( GObject *object,
248
PtkFileIconRenderer * renderer = PTK_FILE_ICON_RENDERER( object );
253
g_value_set_long(value, renderer->flags);
258
vfs_file_info_ref( renderer->info );
259
g_value_set_pointer( value, renderer->info );
261
case PROP_FOLLOW_STATE:
262
g_value_set_boolean ( value, renderer->follow_state );
265
G_OBJECT_WARN_INVALID_PROPERTY_ID ( object, param_id, psec );
271
/***************************************************************************
273
* ptk_file_icon_renderer_set_property: as it says
275
***************************************************************************/
278
ptk_file_icon_renderer_set_property ( GObject *object,
283
PtkFileIconRenderer * renderer = PTK_FILE_ICON_RENDERER ( object );
289
vfs_file_info_unref( renderer->info );
290
renderer->info = g_value_get_pointer( value );
295
renderer->flags = g_value_get_long(value);
299
case PROP_FOLLOW_STATE:
300
renderer->follow_state = g_value_get_boolean ( value );
304
G_OBJECT_WARN_INVALID_PROPERTY_ID( object, param_id, pspec );
309
/***************************************************************************
311
* ptk_file_icon_renderer_new: return a new cell renderer instance
313
***************************************************************************/
316
ptk_file_icon_renderer_new ( void )
318
return ( GtkCellRenderer* ) g_object_new( PTK_TYPE_FILE_ICON_RENDERER, NULL );
323
create_colorized_pixbuf ( GdkPixbuf *src,
324
GdkColor *new_color )
327
gint width, height, has_alpha, src_row_stride, dst_row_stride;
328
gint red_value, green_value, blue_value;
329
guchar *target_pixels;
330
guchar *original_pixels;
335
red_value = new_color->red / 255.0;
336
green_value = new_color->green / 255.0;
337
blue_value = new_color->blue / 255.0;
339
dest = gdk_pixbuf_new ( gdk_pixbuf_get_colorspace ( src ),
340
gdk_pixbuf_get_has_alpha ( src ),
341
gdk_pixbuf_get_bits_per_sample ( src ),
342
gdk_pixbuf_get_width ( src ),
343
gdk_pixbuf_get_height ( src ) );
345
has_alpha = gdk_pixbuf_get_has_alpha ( src );
346
width = gdk_pixbuf_get_width ( src );
347
height = gdk_pixbuf_get_height ( src );
348
src_row_stride = gdk_pixbuf_get_rowstride ( src );
349
dst_row_stride = gdk_pixbuf_get_rowstride ( dest );
350
target_pixels = gdk_pixbuf_get_pixels ( dest );
351
original_pixels = gdk_pixbuf_get_pixels ( src );
353
for ( i = 0; i < height; i++ )
355
pixdest = target_pixels + i * dst_row_stride;
356
pixsrc = original_pixels + i * src_row_stride;
357
for ( j = 0; j < width; j++ )
359
*pixdest++ = ( *pixsrc++ * red_value ) >> 8;
360
*pixdest++ = ( *pixsrc++ * green_value ) >> 8;
361
*pixdest++ = ( *pixsrc++ * blue_value ) >> 8;
364
*pixdest++ = *pixsrc++;
372
/***************************************************************************
374
* ptk_file_icon_renderer_render: crucial - do the rendering.
376
***************************************************************************/
379
ptk_file_icon_renderer_render ( GtkCellRenderer *cell,
382
GdkRectangle *background_area,
383
GdkRectangle *cell_area,
384
GdkRectangle *expose_area,
387
GtkCellRendererPixbuf * cellpixbuf = ( GtkCellRendererPixbuf * ) cell;
390
GdkPixbuf *invisible = NULL;
391
GdkPixbuf *colorized = NULL;
392
GdkRectangle pix_rect;
393
GdkRectangle draw_rect;
396
#if GTK_CHECK_VERSION( 2, 8, 0 )
401
GtkCellRendererClass* parent_renderer_class;
403
parent_renderer_class = GTK_CELL_RENDERER_CLASS( parent_class );
405
parent_renderer_class->get_size ( cell, widget, cell_area,
411
pix_rect.x += cell_area->x;
412
pix_rect.y += cell_area->y;
413
pix_rect.width -= cell->xpad * 2;
414
pix_rect.height -= cell->ypad * 2;
416
if ( !gdk_rectangle_intersect ( cell_area, &pix_rect, &draw_rect ) ||
417
!gdk_rectangle_intersect ( expose_area, &draw_rect, &draw_rect ) )
420
pixbuf = cellpixbuf->pixbuf;
422
if ( cell->is_expander )
424
if ( cell->is_expanded &&
425
cellpixbuf->pixbuf_expander_open != NULL )
426
pixbuf = cellpixbuf->pixbuf_expander_open;
427
else if ( !cell->is_expanded &&
428
cellpixbuf->pixbuf_expander_closed != NULL )
429
pixbuf = cellpixbuf->pixbuf_expander_closed;
435
if ( PTK_FILE_ICON_RENDERER( cell ) ->follow_state )
437
if ( GTK_WIDGET_STATE ( widget ) == GTK_STATE_INSENSITIVE || !cell->sensitive )
439
GtkIconSource * source;
441
source = gtk_icon_source_new ();
442
gtk_icon_source_set_pixbuf ( source, pixbuf );
443
/* The size here is arbitrary; since size isn't
444
* wildcarded in the source, it isn't supposed to be
445
* scaled by the engine function
447
gtk_icon_source_set_size ( source, GTK_ICON_SIZE_SMALL_TOOLBAR );
448
gtk_icon_source_set_size_wildcarded ( source, FALSE );
450
invisible = gtk_style_render_icon ( widget->style,
452
gtk_widget_get_direction ( widget ),
453
GTK_STATE_INSENSITIVE,
457
"gtkcellrendererpixbuf" );
459
gtk_icon_source_free ( source );
462
else if ( ( flags & ( GTK_CELL_RENDERER_SELECTED /*|GTK_CELL_RENDERER_PRELIT*/ ) ) != 0 )
467
if ( ( flags & GTK_CELL_RENDERER_SELECTED ) != 0 )
469
if ( GTK_WIDGET_HAS_FOCUS ( widget ) )
470
state = GTK_STATE_SELECTED;
472
state = GTK_STATE_ACTIVE;
473
color = &widget->style->base[ state ];
477
state = GTK_STATE_PRELIGHT;
480
colorized = create_colorized_pixbuf ( pixbuf,
486
#if GTK_CHECK_VERSION(2, 8, 0)
487
cr = gdk_cairo_create ( window );
488
gdk_cairo_set_source_pixbuf ( cr, pixbuf, pix_rect.x, pix_rect.y );
489
gdk_cairo_rectangle ( cr, &draw_rect );
492
gdk_draw_pixbuf ( GDK_DRAWABLE ( window ), NULL, pixbuf, 0, 0,
493
pix_rect.x, pix_rect.y, pix_rect.width, pix_rect.height,
494
GDK_RGB_DITHER_NORMAL, 0, 0 );
497
file = PTK_FILE_ICON_RENDERER( cell )->info;
500
if ( vfs_file_info_is_symlink( file ) )
502
#if GTK_CHECK_VERSION(2, 8, 0)
503
gdk_cairo_set_source_pixbuf ( cr, link_icon,
508
gdk_cairo_rectangle ( cr, &draw_rect );
512
gdk_draw_pixbuf ( GDK_DRAWABLE ( window ), NULL, link_icon, 0, 0,
513
pix_rect.x - 2, pix_rect.y - 2,
514
-1, -1, GDK_RGB_DITHER_NORMAL,
520
#if GTK_CHECK_VERSION(2, 8, 0)
521
cairo_destroy ( cr );
525
g_object_unref ( invisible );
528
g_object_unref ( colorized );
532
void ptk_file_icon_renderer_get_size ( GtkCellRenderer *cell,
534
GdkRectangle *cell_area,
540
GTK_CELL_RENDERER_CLASS( parent_class )->get_size( cell, widget, cell_area,
544
if ( *width > *height )
546
else if ( *width < *height )