~andrewsomething/imagination/debian

« back to all changes in this revision

Viewing changes to src/imgcellrendererpixbuf.c

  • Committer: Andrew Starr-Bochicchio
  • Date: 2009-09-29 23:38:39 UTC
  • mfrom: (1.1.2)
  • Revision ID: a.starr.b@gmail.com-20090929233839-ucjnl2f35kw5fbx8
Tags: 2.0-1
* New upstream release. (Closes: #543218).
* debian/control: Build-depend on xsltproc, docbook-xsl, quilt,
  and doc-base.
* debian/imagination.doc-base: Register docs.
* debian/patches/10_link_math_lib.patch:
 - Add '-lm' to link to the math lib.
* debian/README.source: Explain quilt.
* debian/rules: Add quilt magic.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
** Copyright (C) 2009 Tadej Borovšak <tadeboro@gmail.com>
 
3
**  
 
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.
 
8
** 
 
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.
 
13
** 
 
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.
 
17
*/
 
18
 
 
19
#include "imgcellrendererpixbuf.h"
 
20
 
 
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
 
25
 
 
26
#define HORIZ_F 0.3
 
27
#define VERT_F  0.5
 
28
#define BORDER  2
 
29
 
 
30
/* Properties */
 
31
enum
 
32
{
 
33
        P_0,
 
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 */
 
39
};
 
40
 
 
41
#define IMG_CELL_RENDERER_PIXBUF_GET_PRIVATE( obj ) \
 
42
        ( G_TYPE_INSTANCE_GET_PRIVATE( ( obj ), \
 
43
                                                                   IMG_TYPE_CELL_RENDERER_PIXBUF, \
 
44
                                                                   ImgCellRendererPixbufPrivate ) )
 
45
 
 
46
typedef struct _ImgCellRendererPixbufPrivate ImgCellRendererPixbufPrivate;
 
47
struct _ImgCellRendererPixbufPrivate
 
48
{
 
49
        gboolean   has_text;
 
50
        GdkPixbuf *text_ico;
 
51
        GdkPixbuf *transition;
 
52
        GdkPixbuf *pixbuf;
 
53
        gdouble    zoom;
 
54
};
 
55
 
 
56
/* ****************************************************************************
 
57
 * Local declarations
 
58
 * ************************************************************************* */
 
59
static void
 
60
img_cell_renderer_pixbuf_set_property( GObject      *object,
 
61
                                                                           guint         prop_id,
 
62
                                                                           const GValue *value,
 
63
                                                                           GParamSpec   *pspec );
 
64
 
 
65
static void
 
66
img_cell_renderer_pixbuf_get_property( GObject    *object,
 
67
                                                                           guint       prop_id,
 
68
                                                                           GValue     *value,
 
69
                                                                           GParamSpec *pspec );
 
70
 
 
71
static void
 
72
img_cell_renderer_pixbuf_render( GtkCellRenderer      *cell,
 
73
                                                                 GdkDrawable          *window,
 
74
                                                                 GtkWidget            *widget,
 
75
                                                                 GdkRectangle         *background_a,
 
76
                                                                 GdkRectangle         *cell_a,
 
77
                                                                 GdkRectangle         *expose_a,
 
78
                                                                 GtkCellRendererState  state );
 
79
 
 
80
static void
 
81
img_cell_renderer_pixbuf_get_size( GtkCellRenderer *cell,
 
82
                                                                   GtkWidget       *widget,
 
83
                                                                   GdkRectangle    *cell_area,
 
84
                                                                   gint            *x_off,
 
85
                                                                   gint            *y_off,
 
86
                                                                   gint            *width,
 
87
                                                                   gint            *height );
 
88
 
 
89
 
 
90
static void
 
91
img_cell_renderer_pixbuf_finalize( GObject *object );
 
92
 
 
93
/* ****************************************************************************
 
94
 * Initialization
 
95
 * ************************************************************************* */
 
96
G_DEFINE_TYPE( ImgCellRendererPixbuf,
 
97
                           img_cell_renderer_pixbuf,
 
98
                           GTK_TYPE_CELL_RENDERER );
 
99
 
 
100
static void
 
101
img_cell_renderer_pixbuf_class_init( ImgCellRendererPixbufClass *klass )
 
102
{
 
103
        GParamSpec           *spec;
 
104
        GObjectClass         *gobject_class = G_OBJECT_CLASS( klass );
 
105
        GtkCellRendererClass *renderer_class = GTK_CELL_RENDERER_CLASS( klass );
 
106
 
 
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;
 
110
 
 
111
        renderer_class->render = img_cell_renderer_pixbuf_render;
 
112
        renderer_class->get_size = img_cell_renderer_pixbuf_get_size;
 
113
 
 
114
        spec = g_param_spec_boolean( "has-text",
 
115
                                                                 "Has text",
 
116
                                                                 "Indicates whether text indicator should be "
 
117
                                                                 "drawn or not.",
 
118
                                                                 FALSE,
 
119
                                                                 IMG_PARAM_READWRITE );
 
120
        g_object_class_install_property( gobject_class, P_HAS_TEXT, spec );
 
121
 
 
122
        spec = g_param_spec_object( "text-ico",
 
123
                                                                "Text icon",
 
124
                                                                "Icon for text indicator.",
 
125
                                                                GDK_TYPE_PIXBUF,
 
126
                                                                IMG_PARAM_READWRITE );
 
127
        g_object_class_install_property( gobject_class, P_TEXT_ICO, spec );
 
128
 
 
129
        spec = g_param_spec_object( "transition",
 
130
                                                                "Transition",
 
131
                                                                "Indicates what ind of transition is applied "
 
132
                                                                "onto the slide.",
 
133
                                                                GDK_TYPE_PIXBUF,
 
134
                                                                IMG_PARAM_READWRITE );
 
135
        g_object_class_install_property( gobject_class, P_TRANSITION, spec );
 
136
 
 
137
        spec = g_param_spec_object( "pixbuf",
 
138
                                                                "Pixbuf",
 
139
                                                                "Main pixbuf to be drawn.",
 
140
                                                                GDK_TYPE_PIXBUF,
 
141
                                                                IMG_PARAM_READWRITE );
 
142
        g_object_class_install_property( gobject_class, P_PIXBUF, spec );
 
143
 
 
144
        spec = g_param_spec_double( "zoom",
 
145
                                                                "Zoom",
 
146
                                                                "Zoom factor at which to draw image.",
 
147
                                                                0.1, 3.0, 1.0,
 
148
                                                                IMG_PARAM_READWRITE );
 
149
        g_object_class_install_property( gobject_class, P_ZOOM, spec );
 
150
 
 
151
        g_type_class_add_private( gobject_class,
 
152
                                                          sizeof( ImgCellRendererPixbufPrivate ) );
 
153
}
 
154
 
 
155
static void
 
156
img_cell_renderer_pixbuf_init( ImgCellRendererPixbuf *cell )
 
157
{
 
158
        ImgCellRendererPixbufPrivate *priv;
 
159
 
 
160
        priv = IMG_CELL_RENDERER_PIXBUF_GET_PRIVATE( cell );
 
161
        priv->has_text = FALSE;
 
162
        priv->text_ico = NULL;
 
163
        priv->transition = NULL;
 
164
        priv->pixbuf = NULL;
 
165
        priv->zoom = 1.0;
 
166
}
 
167
 
 
168
/* ****************************************************************************
 
169
 * Local Declarations
 
170
 * ************************************************************************* */
 
171
static void
 
172
img_cell_renderer_pixbuf_set_property( GObject      *object,
 
173
                                                                           guint         prop_id,
 
174
                                                                           const GValue *value,
 
175
                                                                           GParamSpec   *pspec )
 
176
{
 
177
        ImgCellRendererPixbufPrivate *priv;
 
178
 
 
179
        g_return_if_fail( IMG_IS_CELL_RENDERER_PIXBUF( object ) );
 
180
        priv = IMG_CELL_RENDERER_PIXBUF_GET_PRIVATE( object );
 
181
 
 
182
        switch( prop_id )
 
183
        {
 
184
                case P_HAS_TEXT:
 
185
                        priv->has_text = g_value_get_boolean( value );
 
186
                        break;
 
187
 
 
188
                case P_TEXT_ICO:
 
189
                        if( priv->text_ico )
 
190
                                g_object_unref( G_OBJECT( priv->text_ico ) );
 
191
                        priv->text_ico = g_value_dup_object( value );
 
192
                        break;
 
193
 
 
194
                case P_TRANSITION:
 
195
                        if( priv->transition )
 
196
                                g_object_unref( G_OBJECT( priv->transition ) );
 
197
                        priv->transition = g_value_dup_object( value );
 
198
                        break;
 
199
 
 
200
                case P_PIXBUF:
 
201
                        if( priv->pixbuf )
 
202
                                g_object_unref( G_OBJECT( priv->pixbuf ) );
 
203
                        priv->pixbuf = g_value_dup_object( value );
 
204
                        break;
 
205
 
 
206
                case P_ZOOM:
 
207
                        priv->zoom = g_value_get_double( value );
 
208
                        break;
 
209
 
 
210
                default:
 
211
                        G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec );
 
212
                        break;
 
213
        }
 
214
}
 
215
 
 
216
static void
 
217
img_cell_renderer_pixbuf_get_property( GObject    *object,
 
218
                                                                           guint       prop_id,
 
219
                                                                           GValue     *value,
 
220
                                                                           GParamSpec *pspec )
 
221
{
 
222
        ImgCellRendererPixbufPrivate *priv;
 
223
 
 
224
        g_return_if_fail( IMG_IS_CELL_RENDERER_PIXBUF( object ) );
 
225
        priv = IMG_CELL_RENDERER_PIXBUF_GET_PRIVATE( object );
 
226
 
 
227
        switch( prop_id )
 
228
        {
 
229
                case P_HAS_TEXT:
 
230
                        g_value_set_boolean( value, priv->has_text );
 
231
                        break;
 
232
 
 
233
                case P_TEXT_ICO:
 
234
                        g_value_set_object( value, priv->text_ico );
 
235
                        break;
 
236
 
 
237
                case P_TRANSITION:
 
238
                        g_value_set_object( value, priv->transition );
 
239
                        break;
 
240
 
 
241
                case P_PIXBUF:
 
242
                        g_value_set_object( value, priv->pixbuf );
 
243
                        break;
 
244
 
 
245
                case P_ZOOM:
 
246
                        g_value_set_double( value, priv->zoom );
 
247
                        break;
 
248
 
 
249
                default:
 
250
                        G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec );
 
251
                        break;
 
252
        }
 
253
}
 
254
 
 
255
static void
 
256
img_cell_renderer_pixbuf_render( GtkCellRenderer      *cell,
 
257
                                                                 GdkDrawable          *window,
 
258
                                                                 GtkWidget            *widget,
 
259
                                                                 GdkRectangle         *background_a,
 
260
                                                                 GdkRectangle         *cell_a,
 
261
                                                                 GdkRectangle         *expose_a,
 
262
                                                                 GtkCellRendererState  state )
 
263
{
 
264
        ImgCellRendererPixbufPrivate *priv;
 
265
 
 
266
        /* Drawing context */
 
267
        cairo_t *cr;
 
268
 
 
269
        /* Rectangles */
 
270
        GdkRectangle rect,
 
271
                                 draw_rect;
 
272
 
 
273
        priv = IMG_CELL_RENDERER_PIXBUF_GET_PRIVATE( cell );
 
274
 
 
275
        /* Get image size */
 
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;
 
282
 
 
283
        /* Check for overlaping */
 
284
        if( ! gdk_rectangle_intersect( cell_a, &rect, &draw_rect ) ||
 
285
                ! gdk_rectangle_intersect( expose_a, &draw_rect, &draw_rect ) )
 
286
                return;
 
287
 
 
288
        /* Draw indicators */
 
289
        cr = gdk_cairo_create( window );
 
290
 
 
291
        /* Draw base image */
 
292
        cairo_save( cr );
 
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 );
 
296
        cairo_paint( cr );
 
297
        cairo_restore( cr );
 
298
 
 
299
        if( priv->has_text && priv->text_ico )
 
300
        {
 
301
                gint    w,
 
302
                                h;
 
303
                gdouble wf,
 
304
                                hf,
 
305
                                cf;
 
306
 
 
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 ) );
 
312
 
 
313
                cairo_save( cr );
 
314
                cairo_translate( cr, rect.x + rect.width - BORDER,
 
315
                                                         rect.y + BORDER );
 
316
                cairo_scale( cr, cf, cf );
 
317
                gdk_cairo_set_source_pixbuf( cr, priv->text_ico, -w, 0 );
 
318
                cairo_paint( cr );
 
319
                cairo_restore( cr );
 
320
        }
 
321
 
 
322
        if( priv->transition )
 
323
        {
 
324
                gint    w,
 
325
                                h;
 
326
                gdouble wf,
 
327
                                hf,
 
328
                                cf;
 
329
 
 
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 ) );
 
335
 
 
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 );
 
340
                cairo_paint( cr );
 
341
        }
 
342
 
 
343
        cairo_destroy( cr );
 
344
}
 
345
 
 
346
static void
 
347
img_cell_renderer_pixbuf_get_size( GtkCellRenderer *cell,
 
348
                                                                   GtkWidget       *widget,
 
349
                                                                   GdkRectangle    *cell_area,
 
350
                                                                   gint            *x_off,
 
351
                                                                   gint            *y_off,
 
352
                                                                   gint            *width,
 
353
                                                                   gint            *height )
 
354
{
 
355
        /* Private data */
 
356
        ImgCellRendererPixbufPrivate *priv;
 
357
        /* Calculated values */
 
358
        gboolean calc_off;
 
359
        gint     w = 0,
 
360
                         h = 0;
 
361
 
 
362
        priv = IMG_CELL_RENDERER_PIXBUF_GET_PRIVATE( cell );
 
363
 
 
364
        /* Get image size */
 
365
        if( priv->pixbuf )
 
366
        {
 
367
                w = gdk_pixbuf_get_width( priv->pixbuf )  * priv->zoom;
 
368
                h = gdk_pixbuf_get_height( priv->pixbuf ) * priv->zoom;
 
369
        }
 
370
 
 
371
        calc_off = ( w > 0 && h > 0 ? TRUE : FALSE );
 
372
 
 
373
        /* Add padding */
 
374
        w += (gint)cell->xpad * 2;
 
375
        h += (gint)cell->ypad * 2;
 
376
 
 
377
        /* Calculate offsets */
 
378
        if( cell_area && calc_off )
 
379
        {
 
380
                if( x_off )
 
381
                {
 
382
                        gboolean dir;
 
383
                        
 
384
                        dir = ( gtk_widget_get_direction( widget ) == GTK_TEXT_DIR_LTR );
 
385
 
 
386
                        *x_off = ( dir ? cell->xalign : 1.0 - cell->xalign ) *
 
387
                                         ( cell_area->width - w );
 
388
                        *x_off = MAX( *x_off, 0 );
 
389
                }
 
390
 
 
391
                if( y_off )
 
392
                {
 
393
                        *y_off = cell->yalign * ( cell_area->height - h );
 
394
                        *y_off = MAX( *y_off, 0 );
 
395
                }
 
396
        }
 
397
        else
 
398
        {
 
399
                if( x_off )
 
400
                        *y_off = 0;
 
401
                if( y_off )
 
402
                        *y_off = 0;
 
403
        }
 
404
 
 
405
        /* Return dimensions */
 
406
        if( width )
 
407
                *width = w;
 
408
        if( height )
 
409
                *height = h;
 
410
}
 
411
 
 
412
static void
 
413
img_cell_renderer_pixbuf_finalize( GObject *object )
 
414
{
 
415
        ImgCellRendererPixbufPrivate *priv;
 
416
 
 
417
        priv = IMG_CELL_RENDERER_PIXBUF_GET_PRIVATE( object );
 
418
 
 
419
        if( priv->text_ico )
 
420
                g_object_unref( priv->text_ico );
 
421
        if( priv->transition )
 
422
                g_object_unref( priv->transition );
 
423
        if( priv->pixbuf )
 
424
                g_object_unref( priv->pixbuf );
 
425
 
 
426
        G_OBJECT_CLASS( img_cell_renderer_pixbuf_parent_class )->finalize( object );
 
427
}
 
428
 
 
429
 
 
430
/* ****************************************************************************
 
431
 * Public API
 
432
 * ************************************************************************* */
 
433
GtkCellRenderer *
 
434
img_cell_renderer_pixbuf_new( void )
 
435
{
 
436
        return( g_object_new( IMG_TYPE_CELL_RENDERER_PIXBUF, NULL ) );
 
437
}
 
438