2
** Copyright (C) 2009 Tadej Borovšak <tadeboro@gmail.com>
4
** This program is free software; you can redistribute it and/or modify
5
** it under the terms of the GNU General Public License as published by
6
** the Free Software Foundation; either version 2 of the License, or
7
** (at your option) any later version.
9
** This program is distributed in the hope that it will be useful,
10
** but WITHOUT ANY WARRANTY; without even the implied warranty of
11
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
** GNU General Public License for more details.
14
** You should have received a copy of the GNU General Public License
15
** along with this program; if not, write to the Free Software
16
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
#include "imgcellrendererpixbuf.h"
21
#define IMG_PARAM_DEFAULTS \
22
G_PARAM_STATIC_NICK | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB
23
#define IMG_PARAM_READWRITE \
24
G_PARAM_WRITABLE | G_PARAM_READABLE | IMG_PARAM_DEFAULTS
34
P_HAS_TEXT, /* Does selected slide contains text? */
35
P_TEXT_ICO, /* Icon describing text */
36
P_TRANSITION, /* Transition pixbuf */
37
P_PIXBUF, /* Main pixbuf to be rendered */
38
P_ZOOM /* Zoom factor */
41
#define IMG_CELL_RENDERER_PIXBUF_GET_PRIVATE( obj ) \
42
( G_TYPE_INSTANCE_GET_PRIVATE( ( obj ), \
43
IMG_TYPE_CELL_RENDERER_PIXBUF, \
44
ImgCellRendererPixbufPrivate ) )
46
typedef struct _ImgCellRendererPixbufPrivate ImgCellRendererPixbufPrivate;
47
struct _ImgCellRendererPixbufPrivate
51
GdkPixbuf *transition;
56
/* ****************************************************************************
58
* ************************************************************************* */
60
img_cell_renderer_pixbuf_set_property( GObject *object,
66
img_cell_renderer_pixbuf_get_property( GObject *object,
72
img_cell_renderer_pixbuf_render( GtkCellRenderer *cell,
75
GdkRectangle *background_a,
77
GdkRectangle *expose_a,
78
GtkCellRendererState state );
81
img_cell_renderer_pixbuf_get_size( GtkCellRenderer *cell,
83
GdkRectangle *cell_area,
91
img_cell_renderer_pixbuf_finalize( GObject *object );
93
/* ****************************************************************************
95
* ************************************************************************* */
96
G_DEFINE_TYPE( ImgCellRendererPixbuf,
97
img_cell_renderer_pixbuf,
98
GTK_TYPE_CELL_RENDERER );
101
img_cell_renderer_pixbuf_class_init( ImgCellRendererPixbufClass *klass )
104
GObjectClass *gobject_class = G_OBJECT_CLASS( klass );
105
GtkCellRendererClass *renderer_class = GTK_CELL_RENDERER_CLASS( klass );
107
gobject_class->set_property = img_cell_renderer_pixbuf_set_property;
108
gobject_class->get_property = img_cell_renderer_pixbuf_get_property;
109
gobject_class->finalize = img_cell_renderer_pixbuf_finalize;
111
renderer_class->render = img_cell_renderer_pixbuf_render;
112
renderer_class->get_size = img_cell_renderer_pixbuf_get_size;
114
spec = g_param_spec_boolean( "has-text",
116
"Indicates whether text indicator should be "
119
IMG_PARAM_READWRITE );
120
g_object_class_install_property( gobject_class, P_HAS_TEXT, spec );
122
spec = g_param_spec_object( "text-ico",
124
"Icon for text indicator.",
126
IMG_PARAM_READWRITE );
127
g_object_class_install_property( gobject_class, P_TEXT_ICO, spec );
129
spec = g_param_spec_object( "transition",
131
"Indicates what ind of transition is applied "
134
IMG_PARAM_READWRITE );
135
g_object_class_install_property( gobject_class, P_TRANSITION, spec );
137
spec = g_param_spec_object( "pixbuf",
139
"Main pixbuf to be drawn.",
141
IMG_PARAM_READWRITE );
142
g_object_class_install_property( gobject_class, P_PIXBUF, spec );
144
spec = g_param_spec_double( "zoom",
146
"Zoom factor at which to draw image.",
148
IMG_PARAM_READWRITE );
149
g_object_class_install_property( gobject_class, P_ZOOM, spec );
151
g_type_class_add_private( gobject_class,
152
sizeof( ImgCellRendererPixbufPrivate ) );
156
img_cell_renderer_pixbuf_init( ImgCellRendererPixbuf *cell )
158
ImgCellRendererPixbufPrivate *priv;
160
priv = IMG_CELL_RENDERER_PIXBUF_GET_PRIVATE( cell );
161
priv->has_text = FALSE;
162
priv->text_ico = NULL;
163
priv->transition = NULL;
168
/* ****************************************************************************
170
* ************************************************************************* */
172
img_cell_renderer_pixbuf_set_property( GObject *object,
177
ImgCellRendererPixbufPrivate *priv;
179
g_return_if_fail( IMG_IS_CELL_RENDERER_PIXBUF( object ) );
180
priv = IMG_CELL_RENDERER_PIXBUF_GET_PRIVATE( object );
185
priv->has_text = g_value_get_boolean( value );
190
g_object_unref( G_OBJECT( priv->text_ico ) );
191
priv->text_ico = g_value_dup_object( value );
195
if( priv->transition )
196
g_object_unref( G_OBJECT( priv->transition ) );
197
priv->transition = g_value_dup_object( value );
202
g_object_unref( G_OBJECT( priv->pixbuf ) );
203
priv->pixbuf = g_value_dup_object( value );
207
priv->zoom = g_value_get_double( value );
211
G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec );
217
img_cell_renderer_pixbuf_get_property( GObject *object,
222
ImgCellRendererPixbufPrivate *priv;
224
g_return_if_fail( IMG_IS_CELL_RENDERER_PIXBUF( object ) );
225
priv = IMG_CELL_RENDERER_PIXBUF_GET_PRIVATE( object );
230
g_value_set_boolean( value, priv->has_text );
234
g_value_set_object( value, priv->text_ico );
238
g_value_set_object( value, priv->transition );
242
g_value_set_object( value, priv->pixbuf );
246
g_value_set_double( value, priv->zoom );
250
G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec );
256
img_cell_renderer_pixbuf_render( GtkCellRenderer *cell,
259
GdkRectangle *background_a,
260
GdkRectangle *cell_a,
261
GdkRectangle *expose_a,
262
GtkCellRendererState state )
264
ImgCellRendererPixbufPrivate *priv;
266
/* Drawing context */
273
priv = IMG_CELL_RENDERER_PIXBUF_GET_PRIVATE( cell );
276
img_cell_renderer_pixbuf_get_size( cell, widget, cell_a, &rect.x,
277
&rect.y, &rect.width, &rect.height );
278
rect.x += cell_a->x + cell->xpad;
279
rect.y += cell_a->y + cell->ypad;
280
rect.width -= 2 * cell->xpad;
281
rect.height -= 2 * cell->ypad;
283
/* Check for overlaping */
284
if( ! gdk_rectangle_intersect( cell_a, &rect, &draw_rect ) ||
285
! gdk_rectangle_intersect( expose_a, &draw_rect, &draw_rect ) )
288
/* Draw indicators */
289
cr = gdk_cairo_create( window );
291
/* Draw base image */
293
cairo_translate( cr, rect.x, rect.y );
294
cairo_scale( cr, priv->zoom, priv->zoom );
295
gdk_cairo_set_source_pixbuf( cr, priv->pixbuf, 0, 0 );
299
if( priv->has_text && priv->text_ico )
307
w = gdk_pixbuf_get_width( priv->text_ico );
308
h = gdk_pixbuf_get_height( priv->text_ico );
309
wf = (gdouble)w / ( rect.width - 2 * BORDER );
310
hf = (gdouble)h / ( rect.height - 4 * BORDER );
311
cf = MIN( MIN( 1.0, HORIZ_F / wf ), MIN( 1.0, VERT_F / hf ) );
314
cairo_translate( cr, rect.x + rect.width - BORDER,
316
cairo_scale( cr, cf, cf );
317
gdk_cairo_set_source_pixbuf( cr, priv->text_ico, -w, 0 );
322
if( priv->transition )
330
w = gdk_pixbuf_get_width( priv->transition );
331
h = gdk_pixbuf_get_height( priv->transition );
332
wf = (gdouble)w / ( rect.width - 2 * BORDER );
333
hf = (gdouble)h / ( rect.height - 4 * BORDER );
334
cf = MIN( MIN( 1.0, HORIZ_F / wf ), MIN( 1.0, VERT_F / hf ) );
336
cairo_translate( cr, rect.x + rect.width - BORDER,
337
rect.y + rect.height - BORDER );
338
cairo_scale( cr, cf, cf );
339
gdk_cairo_set_source_pixbuf( cr, priv->transition, - w, - h );
347
img_cell_renderer_pixbuf_get_size( GtkCellRenderer *cell,
349
GdkRectangle *cell_area,
356
ImgCellRendererPixbufPrivate *priv;
357
/* Calculated values */
362
priv = IMG_CELL_RENDERER_PIXBUF_GET_PRIVATE( cell );
367
w = gdk_pixbuf_get_width( priv->pixbuf ) * priv->zoom;
368
h = gdk_pixbuf_get_height( priv->pixbuf ) * priv->zoom;
371
calc_off = ( w > 0 && h > 0 ? TRUE : FALSE );
374
w += (gint)cell->xpad * 2;
375
h += (gint)cell->ypad * 2;
377
/* Calculate offsets */
378
if( cell_area && calc_off )
384
dir = ( gtk_widget_get_direction( widget ) == GTK_TEXT_DIR_LTR );
386
*x_off = ( dir ? cell->xalign : 1.0 - cell->xalign ) *
387
( cell_area->width - w );
388
*x_off = MAX( *x_off, 0 );
393
*y_off = cell->yalign * ( cell_area->height - h );
394
*y_off = MAX( *y_off, 0 );
405
/* Return dimensions */
413
img_cell_renderer_pixbuf_finalize( GObject *object )
415
ImgCellRendererPixbufPrivate *priv;
417
priv = IMG_CELL_RENDERER_PIXBUF_GET_PRIVATE( object );
420
g_object_unref( priv->text_ico );
421
if( priv->transition )
422
g_object_unref( priv->transition );
424
g_object_unref( priv->pixbuf );
426
G_OBJECT_CLASS( img_cell_renderer_pixbuf_parent_class )->finalize( object );
430
/* ****************************************************************************
432
* ************************************************************************* */
434
img_cell_renderer_pixbuf_new( void )
436
return( g_object_new( IMG_TYPE_CELL_RENDERER_PIXBUF, NULL ) );