No issues found
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2 of the License, or (at your option) version 3.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with the program; if not, see <http://www.gnu.org/licenses/>
14 *
15 *
16 * Authors:
17 * Vladimir Vukicevic <vladimir@ximian.com>
18 *
19 *
20 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
21 *
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdio.h>
29
30 #include <libgnomecanvas/libgnomecanvas.h>
31
32 #include <glib/gi18n.h>
33 #include <gtk/gtk.h>
34 #include "e-cell-pixbuf.h"
35
36 G_DEFINE_TYPE (ECellPixbuf, e_cell_pixbuf, E_TYPE_CELL)
37
38 typedef struct _ECellPixbufView ECellPixbufView;
39
40 struct _ECellPixbufView {
41 ECellView cell_view;
42 GnomeCanvas *canvas;
43 };
44
45 /* Object argument IDs */
46 enum {
47 PROP_0,
48
49 PROP_SELECTED_COLUMN,
50 PROP_FOCUSED_COLUMN,
51 PROP_UNSELECTED_COLUMN
52 };
53
54 /*
55 * ECellPixbuf functions
56 */
57
58 ECell *
59 e_cell_pixbuf_new (void)
60 {
61 return g_object_new (E_TYPE_CELL_PIXBUF, NULL);
62 }
63
64 /*
65 * ECell methods
66 */
67
68 static ECellView *
69 pixbuf_new_view (ECell *ecell,
70 ETableModel *table_model,
71 gpointer e_table_item_view)
72 {
73 ECellPixbufView *pixbuf_view = g_new0 (ECellPixbufView, 1);
74 ETableItem *eti = E_TABLE_ITEM (e_table_item_view);
75 GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
76
77 pixbuf_view->cell_view.ecell = ecell;
78 pixbuf_view->cell_view.e_table_model = table_model;
79 pixbuf_view->cell_view.e_table_item_view = e_table_item_view;
80 pixbuf_view->cell_view.kill_view_cb = NULL;
81 pixbuf_view->cell_view.kill_view_cb_data = NULL;
82
83 pixbuf_view->canvas = canvas;
84
85 return (ECellView *) pixbuf_view;
86 }
87
88 static void
89 pixbuf_kill_view (ECellView *ecell_view)
90 {
91 ECellPixbufView *pixbuf_view = (ECellPixbufView *) ecell_view;
92
93 if (pixbuf_view->cell_view.kill_view_cb)
94 pixbuf_view->cell_view.kill_view_cb (
95 ecell_view, pixbuf_view->cell_view.kill_view_cb_data);
96
97 if (pixbuf_view->cell_view.kill_view_cb_data)
98 g_list_free (pixbuf_view->cell_view.kill_view_cb_data);
99
100 g_free (pixbuf_view);
101 }
102
103 static void
104 pixbuf_draw (ECellView *ecell_view,
105 cairo_t *cr,
106 gint model_col,
107 gint view_col,
108 gint row,
109 ECellFlags flags,
110 gint x1,
111 gint y1,
112 gint x2,
113 gint y2)
114 {
115 GdkPixbuf *cell_pixbuf;
116 gint real_x, real_y;
117 gint pix_w, pix_h;
118
119 cell_pixbuf = e_table_model_value_at (ecell_view->e_table_model,
120 1, row);
121
122 /* we can't make sure we really got a pixbuf since, well, it's a Gdk thing */
123
124 if (x2 - x1 == 0)
125 return;
126
127 if (!cell_pixbuf)
128 return;
129
130 pix_w = gdk_pixbuf_get_width (cell_pixbuf);
131 pix_h = gdk_pixbuf_get_height (cell_pixbuf);
132
133 /* We center the pixbuf within our allocated space */
134 if (x2 - x1 > pix_w) {
135 gint diff = (x2 - x1) - pix_w;
136 real_x = x1 + diff / 2;
137 } else {
138 real_x = x1;
139 }
140
141 if (y2 - y1 > pix_h) {
142 gint diff = (y2 - y1) - pix_h;
143 real_y = y1 + diff / 2;
144 } else {
145 real_y = y1;
146 }
147
148 cairo_save (cr);
149 gdk_cairo_set_source_pixbuf (cr, cell_pixbuf, real_x, real_y);
150 cairo_paint_with_alpha (cr, 1);
151 cairo_restore (cr);
152 }
153
154 static gint
155 pixbuf_event (ECellView *ecell_view,
156 GdkEvent *event,
157 gint model_col,
158 gint view_col,
159 gint row,
160 ECellFlags flags,
161 ECellActions *actions)
162 {
163 /* noop */
164
165 return FALSE;
166 }
167
168 static gint
169 pixbuf_height (ECellView *ecell_view,
170 gint model_col,
171 gint view_col,
172 gint row)
173 {
174 GdkPixbuf *pixbuf;
175 if (row == -1) {
176 if (e_table_model_row_count (ecell_view->e_table_model) > 0) {
177 row = 0;
178 } else {
179 return 6;
180 }
181 }
182
183 pixbuf = (GdkPixbuf *) e_table_model_value_at (ecell_view->e_table_model, 1, row);
184 if (!pixbuf)
185 return 0;
186
187 /* We give ourselves 3 pixels of padding on either side */
188 return gdk_pixbuf_get_height (pixbuf) + 6;
189 }
190
191 /*
192 * ECell::print method
193 */
194 static void
195 pixbuf_print (ECellView *ecell_view,
196 GtkPrintContext *context,
197 gint model_col,
198 gint view_col,
199 gint row,
200 gdouble width,
201 gdouble height)
202 {
203 GdkPixbuf *pixbuf;
204 gint scale;
205 cairo_t *cr = gtk_print_context_get_cairo_context (context);
206
207 pixbuf = (GdkPixbuf *) e_table_model_value_at (ecell_view->e_table_model, 1, row);
208 if (pixbuf == NULL)
209 return;
210
211 scale = gdk_pixbuf_get_height (pixbuf);
212 cairo_save (cr);
213 cairo_translate (cr, 0, (gdouble)(height - scale) / (gdouble) 2);
214 gdk_cairo_set_source_pixbuf (cr, pixbuf, (gdouble) scale, (gdouble) scale);
215 cairo_paint (cr);
216 cairo_restore (cr);
217 }
218
219 static gdouble
220 pixbuf_print_height (ECellView *ecell_view,
221 GtkPrintContext *context,
222 gint model_col,
223 gint view_col,
224 gint row,
225 gdouble width)
226 {
227 GdkPixbuf *pixbuf;
228
229 if (row == -1) {
230 if (e_table_model_row_count (ecell_view->e_table_model) > 0) {
231 row = 0;
232 } else {
233 return 6;
234 }
235 }
236
237 pixbuf = (GdkPixbuf *) e_table_model_value_at (ecell_view->e_table_model, 1, row);
238 if (!pixbuf)
239 return 0;
240
241 /* We give ourselves 3 pixels of padding on either side */
242 return gdk_pixbuf_get_height (pixbuf);
243 }
244
245 static gint
246 pixbuf_max_width (ECellView *ecell_view,
247 gint model_col,
248 gint view_col)
249 {
250 gint pw;
251 gint num_rows, i;
252 gint max_width = -1;
253
254 if (model_col == 0) {
255 num_rows = e_table_model_row_count (ecell_view->e_table_model);
256
257 for (i = 0; i <= num_rows; i++) {
258 GdkPixbuf *pixbuf = (GdkPixbuf *) e_table_model_value_at
259 (ecell_view->e_table_model,
260 1,
261 i);
262 if (!pixbuf)
263 continue;
264 pw = gdk_pixbuf_get_width (pixbuf);
265 if (max_width < pw)
266 max_width = pw;
267 }
268 } else {
269 return -1;
270 }
271
272 return max_width;
273 }
274
275 static void
276 pixbuf_set_property (GObject *object,
277 guint property_id,
278 const GValue *value,
279 GParamSpec *pspec)
280 {
281 ECellPixbuf *pixbuf;
282
283 pixbuf = E_CELL_PIXBUF (object);
284
285 switch (property_id) {
286 case PROP_SELECTED_COLUMN:
287 pixbuf->selected_column = g_value_get_int (value);
288 break;
289
290 case PROP_FOCUSED_COLUMN:
291 pixbuf->focused_column = g_value_get_int (value);
292 break;
293
294 case PROP_UNSELECTED_COLUMN:
295 pixbuf->unselected_column = g_value_get_int (value);
296 break;
297
298 default:
299 return;
300 }
301 }
302
303 /* Get_arg handler for the pixbuf item */
304 static void
305 pixbuf_get_property (GObject *object,
306 guint property_id,
307 GValue *value,
308 GParamSpec *pspec)
309 {
310 ECellPixbuf *pixbuf;
311
312 pixbuf = E_CELL_PIXBUF (object);
313
314 switch (property_id) {
315 case PROP_SELECTED_COLUMN:
316 g_value_set_int (value, pixbuf->selected_column);
317 break;
318
319 case PROP_FOCUSED_COLUMN:
320 g_value_set_int (value, pixbuf->focused_column);
321 break;
322
323 case PROP_UNSELECTED_COLUMN:
324 g_value_set_int (value, pixbuf->unselected_column);
325 break;
326
327 default:
328 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
329 break;
330 }
331 }
332
333 static void
334 e_cell_pixbuf_init (ECellPixbuf *ecp)
335 {
336 ecp->selected_column = -1;
337 ecp->focused_column = -1;
338 ecp->unselected_column = -1;
339 }
340
341 static void
342 e_cell_pixbuf_class_init (ECellPixbufClass *class)
343 {
344 GObjectClass *object_class = G_OBJECT_CLASS (class);
345 ECellClass *ecc = E_CELL_CLASS (class);
346
347 object_class->set_property = pixbuf_set_property;
348 object_class->get_property = pixbuf_get_property;
349
350 ecc->new_view = pixbuf_new_view;
351 ecc->kill_view = pixbuf_kill_view;
352 ecc->draw = pixbuf_draw;
353 ecc->event = pixbuf_event;
354 ecc->height = pixbuf_height;
355 ecc->print = pixbuf_print;
356 ecc->print_height = pixbuf_print_height;
357 ecc->max_width = pixbuf_max_width;
358
359 g_object_class_install_property (
360 object_class,
361 PROP_SELECTED_COLUMN,
362 g_param_spec_int (
363 "selected_column",
364 "Selected Column",
365 NULL,
366 0, G_MAXINT, 0,
367 G_PARAM_READWRITE));
368
369 g_object_class_install_property (
370 object_class,
371 PROP_FOCUSED_COLUMN,
372 g_param_spec_int (
373 "focused_column",
374 "Focused Column",
375 NULL,
376 0, G_MAXINT, 0,
377 G_PARAM_READWRITE));
378
379 g_object_class_install_property (
380 object_class,
381 PROP_UNSELECTED_COLUMN,
382 g_param_spec_int (
383 "unselected_column",
384 "Unselected Column",
385 NULL,
386 0, G_MAXINT, 0,
387 G_PARAM_READWRITE));
388 }