evolution-3.6.4/widgets/table/e-cell-pixbuf.c

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 }