Mercurial > geeqie.yaz
annotate src/cellrenderericon.c @ 670:a484500de88d
Improve editor commands error display:
- display all errors (not only syntax errors)
- display errors from Preferences (checks are made on Apply or OK)
author | zas_ |
---|---|
date | Fri, 16 May 2008 09:10:56 +0000 |
parents | 0a2b8210ef1d |
children | 631d626c1f6b |
rev | line source |
---|---|
9 | 1 /* cellrenderericon.c, based on: |
2 * | |
3 * gtkcellrendererpixbuf.c | |
4 * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com> | |
5 * | |
6 * This library is free software; you can redistribute it and/or | |
7 * modify it under the terms of the GNU Library General Public | |
8 * License as published by the Free Software Foundation; either | |
9 * version 2 of the License, or (at your option) any later version. | |
10 * | |
11 * This library is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * Library General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU Library General Public | |
17 * License along with this library; if not, write to the | |
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
19 * Boston, MA 02111-1307, USA. | |
20 */ | |
21 | |
22 #include <stdlib.h> | |
23 #include "cellrenderericon.h" | |
24 #include "intl.h" | |
25 | |
26 | |
27 #define FIXED_ICON_SIZE_MAX 512 | |
28 | |
29 static void gqv_cell_renderer_icon_get_property(GObject *object, | |
442 | 30 guint param_id, |
31 GValue *value, | |
32 GParamSpec *pspec); | |
9 | 33 static void gqv_cell_renderer_icon_set_property(GObject *object, |
34 guint param_id, | |
35 const GValue *value, | |
36 GParamSpec *pspec); | |
37 static void gqv_cell_renderer_icon_init(GQvCellRendererIcon *celltext); | |
38 static void gqv_cell_renderer_icon_class_init(GQvCellRendererIconClass *class); | |
39 static void gqv_cell_renderer_icon_finalize(GObject *object); | |
40 static void gqv_cell_renderer_icon_get_size(GtkCellRenderer *cell, | |
41 GtkWidget *widget, | |
42 GdkRectangle *rectangle, | |
43 gint *x_offset, | |
44 gint *y_offset, | |
45 gint *width, | |
46 gint *height); | |
47 static void gqv_cell_renderer_icon_render(GtkCellRenderer *cell, | |
48 GdkWindow *window, | |
49 GtkWidget *widget, | |
50 GdkRectangle *background_area, | |
51 GdkRectangle *cell_area, | |
52 GdkRectangle *expose_area, | |
53 GtkCellRendererState flags); | |
54 | |
55 | |
56 enum { | |
57 PROP_ZERO, | |
58 PROP_PIXBUF, | |
59 PROP_TEXT, | |
60 PROP_BACKGROUND_GDK, | |
61 PROP_FOREGROUND_GDK, | |
62 PROP_FOCUSED, | |
63 PROP_FIXED_WIDTH, | |
64 PROP_FIXED_HEIGHT, | |
65 | |
66 PROP_BACKGROUND_SET, | |
67 PROP_FOREGROUND_SET, | |
68 PROP_SHOW_TEXT | |
69 }; | |
70 | |
71 static gpointer parent_class; | |
72 | |
73 GType | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
74 gqv_cell_renderer_icon_get_type(void) |
9 | 75 { |
76 static GType cell_icon_type = 0; | |
77 | |
78 if (!cell_icon_type) | |
79 { | |
80 static const GTypeInfo cell_icon_info = | |
81 { | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
82 sizeof(GQvCellRendererIconClass), |
9 | 83 NULL, /* base_init */ |
84 NULL, /* base_finalize */ | |
85 (GClassInitFunc) gqv_cell_renderer_icon_class_init, | |
86 NULL, /* class_finalize */ | |
87 NULL, /* class_data */ | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
88 sizeof(GQvCellRendererIcon), |
9 | 89 0, /* n_preallocs */ |
534 | 90 (GInstanceInitFunc) gqv_cell_renderer_icon_init, |
91 }; | |
9 | 92 |
534 | 93 cell_icon_type = g_type_register_static(GTK_TYPE_CELL_RENDERER, |
94 "GQvCellRendererIcon", | |
95 &cell_icon_info, 0); | |
96 } | |
9 | 97 |
98 return cell_icon_type; | |
99 } | |
100 | |
101 static void | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
102 gqv_cell_renderer_icon_init(GQvCellRendererIcon *cellicon) |
9 | 103 { |
104 GTK_CELL_RENDERER(cellicon)->xpad = 2; | |
105 GTK_CELL_RENDERER(cellicon)->ypad = 2; | |
106 } | |
107 | |
108 static void | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
109 gqv_cell_renderer_icon_class_init(GQvCellRendererIconClass *class) |
9 | 110 { |
513
985fdfebd89e
Remove whitespace between function name and first parenthesis for the sake of consistency. (pass 2)
zas_
parents:
512
diff
changeset
|
111 GObjectClass *object_class = G_OBJECT_CLASS(class); |
985fdfebd89e
Remove whitespace between function name and first parenthesis for the sake of consistency. (pass 2)
zas_
parents:
512
diff
changeset
|
112 GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS(class); |
9 | 113 |
513
985fdfebd89e
Remove whitespace between function name and first parenthesis for the sake of consistency. (pass 2)
zas_
parents:
512
diff
changeset
|
114 parent_class = g_type_class_peek_parent(class); |
9 | 115 |
116 object_class->finalize = gqv_cell_renderer_icon_finalize; | |
117 | |
118 object_class->get_property = gqv_cell_renderer_icon_get_property; | |
119 object_class->set_property = gqv_cell_renderer_icon_set_property; | |
120 | |
121 cell_class->get_size = gqv_cell_renderer_icon_get_size; | |
122 cell_class->render = gqv_cell_renderer_icon_render; | |
123 | |
124 g_object_class_install_property(object_class, | |
125 PROP_PIXBUF, | |
126 g_param_spec_object("pixbuf", | |
127 _("Pixbuf Object"), | |
128 _("The pixbuf to render"), | |
129 GDK_TYPE_PIXBUF, | |
130 G_PARAM_READWRITE)); | |
131 | |
132 g_object_class_install_property(object_class, | |
133 PROP_TEXT, | |
134 g_param_spec_string("text", | |
135 _("Text"), | |
136 _("Text to render"), | |
137 NULL, | |
138 G_PARAM_READWRITE)); | |
139 | |
140 g_object_class_install_property(object_class, | |
141 PROP_BACKGROUND_GDK, | |
142 g_param_spec_boxed("background_gdk", | |
143 _("Background color"), | |
144 _("Background color as a GdkColor"), | |
145 GDK_TYPE_COLOR, | |
146 G_PARAM_READWRITE)); | |
147 | |
148 g_object_class_install_property(object_class, | |
149 PROP_FOREGROUND_GDK, | |
150 g_param_spec_boxed("foreground_gdk", | |
151 _("Foreground color"), | |
152 _("Foreground color as a GdkColor"), | |
153 GDK_TYPE_COLOR, | |
154 G_PARAM_READWRITE)); | |
155 | |
156 g_object_class_install_property(object_class, | |
157 PROP_FOCUSED, | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
158 g_param_spec_boolean("has_focus", |
9 | 159 _("Focus"), |
160 _("Draw focus indicator"), | |
161 FALSE, | |
162 G_PARAM_READWRITE)); | |
163 | |
164 g_object_class_install_property(object_class, | |
165 PROP_FIXED_WIDTH, | |
166 g_param_spec_int("fixed_width", | |
167 _("Fixed width"), | |
168 _("Width of cell"), | |
169 -1, FIXED_ICON_SIZE_MAX, | |
170 -1, | |
171 G_PARAM_READWRITE)); | |
172 | |
173 g_object_class_install_property(object_class, | |
174 PROP_FIXED_HEIGHT, | |
175 g_param_spec_int("fixed_height", | |
176 _("Fixed height"), | |
177 _("Height of icon excluding text"), | |
178 -1, FIXED_ICON_SIZE_MAX, | |
179 -1, | |
180 G_PARAM_READWRITE)); | |
181 | |
182 g_object_class_install_property(object_class, | |
183 PROP_BACKGROUND_SET, | |
184 g_param_spec_boolean("background_set", | |
185 _("Background set"), | |
186 _("Whether this tag affects the background color"), | |
187 FALSE, | |
188 G_PARAM_READWRITE)); | |
189 | |
190 g_object_class_install_property(object_class, | |
191 PROP_FOREGROUND_SET, | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
192 g_param_spec_boolean("foreground_set", |
9 | 193 _("Foreground set"), |
194 _("Whether this tag affects the foreground color"), | |
195 FALSE, | |
196 G_PARAM_READWRITE)); | |
197 | |
198 g_object_class_install_property(object_class, | |
199 PROP_SHOW_TEXT, | |
200 g_param_spec_boolean("show_text", | |
201 _("Show text"), | |
202 _("Whether the text is displayed"), | |
203 TRUE, | |
204 G_PARAM_READWRITE)); | |
205 } | |
206 | |
207 static void | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
208 gqv_cell_renderer_icon_finalize(GObject *object) |
9 | 209 { |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
210 GQvCellRendererIcon *cellicon = GQV_CELL_RENDERER_ICON(object); |
9 | 211 |
513
985fdfebd89e
Remove whitespace between function name and first parenthesis for the sake of consistency. (pass 2)
zas_
parents:
512
diff
changeset
|
212 if (cellicon->pixbuf) g_object_unref(cellicon->pixbuf); |
9 | 213 |
214 g_free(cellicon->text); | |
215 | |
513
985fdfebd89e
Remove whitespace between function name and first parenthesis for the sake of consistency. (pass 2)
zas_
parents:
512
diff
changeset
|
216 (*(G_OBJECT_CLASS(parent_class))->finalize)(object); |
9 | 217 } |
218 | |
219 static void | |
220 gqv_cell_renderer_icon_get_property(GObject *object, | |
221 guint param_id, | |
222 GValue *value, | |
223 GParamSpec *pspec) | |
224 { | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
225 GQvCellRendererIcon *cellicon = GQV_CELL_RENDERER_ICON(object); |
442 | 226 |
9 | 227 switch (param_id) |
534 | 228 { |
229 case PROP_PIXBUF: | |
230 g_value_set_object(value, cellicon->pixbuf ? G_OBJECT(cellicon->pixbuf) : NULL); | |
9 | 231 break; |
232 case PROP_TEXT: | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
233 g_value_set_string(value, cellicon->text); |
9 | 234 break; |
235 case PROP_BACKGROUND_GDK: | |
236 { | |
237 GdkColor color; | |
238 | |
239 color.red = cellicon->background.red; | |
240 color.green = cellicon->background.green; | |
241 color.blue = cellicon->background.blue; | |
242 | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
243 g_value_set_boxed(value, &color); |
9 | 244 } |
245 break; | |
246 case PROP_FOREGROUND_GDK: | |
247 { | |
248 GdkColor color; | |
249 | |
250 color.red = cellicon->foreground.red; | |
251 color.green = cellicon->foreground.green; | |
252 color.blue = cellicon->foreground.blue; | |
253 | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
254 g_value_set_boxed(value, &color); |
9 | 255 } |
256 break; | |
257 case PROP_FOCUSED: | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
258 g_value_set_boolean(value, cellicon->focused); |
9 | 259 break; |
260 case PROP_FIXED_WIDTH: | |
261 g_value_set_int(value, cellicon->fixed_width); | |
262 break; | |
263 case PROP_FIXED_HEIGHT: | |
264 g_value_set_int(value, cellicon->fixed_height); | |
265 break; | |
266 case PROP_BACKGROUND_SET: | |
267 g_value_set_boolean(value, cellicon->background_set); | |
268 break; | |
269 case PROP_FOREGROUND_SET: | |
270 g_value_set_boolean(value, cellicon->foreground_set); | |
271 break; | |
272 case PROP_SHOW_TEXT: | |
273 g_value_set_boolean(value, cellicon->show_text); | |
274 break; | |
275 default: | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
276 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); |
9 | 277 break; |
278 } | |
279 } | |
280 | |
281 static void | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
282 set_bg_color(GQvCellRendererIcon *cellicon, |
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
283 GdkColor *color) |
9 | 284 { |
285 if (color) | |
286 { | |
287 if (!cellicon->background_set) | |
288 { | |
289 cellicon->background_set = TRUE; | |
290 g_object_notify(G_OBJECT(cellicon), "background_set"); | |
291 } | |
292 | |
293 cellicon->background.red = color->red; | |
294 cellicon->background.green = color->green; | |
295 cellicon->background.blue = color->blue; | |
296 } | |
297 else | |
298 { | |
299 if (cellicon->background_set) | |
300 { | |
301 cellicon->background_set = FALSE; | |
302 g_object_notify(G_OBJECT(cellicon), "background_set"); | |
303 } | |
304 } | |
305 } | |
306 | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
307 static void set_fg_color(GQvCellRendererIcon *cellicon, |
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
308 GdkColor *color) |
9 | 309 { |
310 if (color) | |
311 { | |
312 if (!cellicon->foreground_set) | |
313 { | |
314 cellicon->foreground_set = TRUE; | |
315 g_object_notify(G_OBJECT(cellicon), "foreground_set"); | |
316 } | |
317 | |
318 cellicon->foreground.red = color->red; | |
319 cellicon->foreground.green = color->green; | |
320 cellicon->foreground.blue = color->blue; | |
321 } | |
322 else | |
323 { | |
324 if (cellicon->foreground_set) | |
325 { | |
326 cellicon->foreground_set = FALSE; | |
327 g_object_notify(G_OBJECT(cellicon), "foreground_set"); | |
328 } | |
329 } | |
330 } | |
331 | |
332 static void | |
333 gqv_cell_renderer_icon_set_property(GObject *object, | |
334 guint param_id, | |
335 const GValue *value, | |
336 GParamSpec *pspec) | |
337 { | |
513
985fdfebd89e
Remove whitespace between function name and first parenthesis for the sake of consistency. (pass 2)
zas_
parents:
512
diff
changeset
|
338 GQvCellRendererIcon *cellicon = GQV_CELL_RENDERER_ICON(object); |
442 | 339 |
9 | 340 switch (param_id) |
534 | 341 { |
342 case PROP_PIXBUF: | |
9 | 343 { |
534 | 344 GdkPixbuf *pixbuf; |
9 | 345 |
534 | 346 pixbuf = (GdkPixbuf*) g_value_get_object(value); |
347 if (pixbuf) g_object_ref(pixbuf); | |
348 if (cellicon->pixbuf) g_object_unref(cellicon->pixbuf); | |
349 cellicon->pixbuf = pixbuf; | |
350 } | |
9 | 351 break; |
352 case PROP_TEXT: | |
353 { | |
354 gchar *text; | |
355 | |
356 text = cellicon->text; | |
357 cellicon->text = g_strdup(g_value_get_string(value)); | |
358 g_free(text); | |
359 | |
360 g_object_notify(object, "text"); | |
361 } | |
362 break; | |
363 case PROP_BACKGROUND_GDK: | |
364 set_bg_color(cellicon, g_value_get_boxed(value)); | |
365 break; | |
366 case PROP_FOREGROUND_GDK: | |
367 set_fg_color(cellicon, g_value_get_boxed(value)); | |
368 break; | |
369 case PROP_FOCUSED: | |
370 cellicon->focused = g_value_get_boolean(value); | |
371 break; | |
372 case PROP_FIXED_WIDTH: | |
373 cellicon->fixed_width = g_value_get_int(value); | |
374 break; | |
375 case PROP_FIXED_HEIGHT: | |
376 cellicon->fixed_height = g_value_get_int(value); | |
377 break; | |
378 case PROP_BACKGROUND_SET: | |
379 cellicon->background_set = g_value_get_boolean(value); | |
380 break; | |
381 case PROP_FOREGROUND_SET: | |
382 cellicon->foreground_set = g_value_get_boolean(value); | |
383 break; | |
384 case PROP_SHOW_TEXT: | |
385 cellicon->show_text = g_value_get_boolean(value); | |
386 break; | |
387 default: | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
388 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); |
9 | 389 break; |
534 | 390 } |
9 | 391 } |
392 | |
393 static PangoLayout * | |
394 gqv_cell_renderer_icon_get_layout(GQvCellRendererIcon *cellicon, GtkWidget *widget, gboolean will_render) | |
395 { | |
396 PangoLayout *layout; | |
397 gint width; | |
398 | |
399 width = (cellicon->fixed_width > 0) ? cellicon->fixed_width * PANGO_SCALE : -1; | |
400 | |
401 layout = gtk_widget_create_pango_layout(widget, cellicon->text); | |
402 pango_layout_set_width(layout, width); | |
403 pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); | |
404 pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); | |
405 | |
406 if (will_render) | |
407 { | |
408 PangoAttrList *attr_list; | |
409 | |
410 attr_list = pango_attr_list_new(); | |
411 | |
412 if (cellicon->foreground_set) | |
413 { | |
414 PangoColor color; | |
415 PangoAttribute *attr; | |
416 | |
417 color = cellicon->foreground; | |
418 | |
419 attr = pango_attr_foreground_new(color.red, color.green, color.blue); | |
420 | |
421 attr->start_index = 0; | |
422 attr->end_index = G_MAXINT; | |
423 pango_attr_list_insert(attr_list, attr); | |
424 } | |
425 | |
426 pango_layout_set_attributes(layout, attr_list); | |
427 pango_attr_list_unref(attr_list); | |
428 } | |
429 | |
430 return layout; | |
431 } | |
432 | |
433 /** | |
434 * gqv_cell_renderer_icon_new: | |
442 | 435 * |
9 | 436 * Creates a new #GQvCellRendererIcon. Adjust rendering |
437 * parameters using object properties. Object properties can be set | |
438 * globally (with g_object_set()). Also, with #GtkTreeViewColumn, you | |
439 * can bind a property to a value in a #GtkTreeModel. For example, you | |
440 * can bind the "pixbuf" property on the cell renderer to a pixbuf value | |
441 * in the model, thus rendering a different image in each row of the | |
442 * #GtkTreeView. | |
442 | 443 * |
9 | 444 * Return value: the new cell renderer |
445 **/ | |
446 GtkCellRenderer * | |
447 gqv_cell_renderer_icon_new(void) | |
448 { | |
534 | 449 return g_object_new(GQV_TYPE_CELL_RENDERER_ICON, NULL); |
9 | 450 } |
451 | |
452 static void | |
453 gqv_cell_renderer_icon_get_size(GtkCellRenderer *cell, | |
454 GtkWidget *widget, | |
455 GdkRectangle *cell_area, | |
456 gint *x_offset, | |
457 gint *y_offset, | |
458 gint *width, | |
459 gint *height) | |
460 { | |
461 GQvCellRendererIcon *cellicon = (GQvCellRendererIcon *) cell; | |
462 gint calc_width; | |
463 gint calc_height; | |
464 | |
465 if (cellicon->fixed_width > 0) | |
466 { | |
467 calc_width = cellicon->fixed_width; | |
468 } | |
469 else | |
470 { | |
471 calc_width = (cellicon->pixbuf) ? gdk_pixbuf_get_width(cellicon->pixbuf) : 0; | |
472 } | |
473 | |
474 if (cellicon->fixed_height > 0) | |
475 { | |
476 calc_height = cellicon->fixed_height; | |
477 } | |
478 else | |
479 { | |
480 calc_height = (cellicon->pixbuf) ? gdk_pixbuf_get_height(cellicon->pixbuf) : 0; | |
481 } | |
482 | |
483 if (cellicon->show_text && cellicon->text) | |
484 { | |
485 PangoLayout *layout; | |
486 PangoRectangle rect; | |
487 | |
488 layout = gqv_cell_renderer_icon_get_layout(cellicon, widget, FALSE); | |
489 pango_layout_get_pixel_extents(layout, NULL, &rect); | |
490 g_object_unref(layout); | |
491 | |
492 calc_width = MAX(calc_width, rect.width); | |
493 calc_height += rect.height; | |
494 } | |
495 | |
496 calc_width += (gint)cell->xpad * 2; | |
497 calc_height += (gint)cell->ypad * 2; | |
498 | |
499 if (x_offset) *x_offset = 0; | |
500 if (y_offset) *y_offset = 0; | |
501 | |
502 if (cell_area && calc_width > 0 && calc_height > 0) | |
503 { | |
504 if (x_offset) | |
505 { | |
506 *x_offset = (cell->xalign * (cell_area->width - calc_width - 2 * cell->xpad)); | |
513
985fdfebd89e
Remove whitespace between function name and first parenthesis for the sake of consistency. (pass 2)
zas_
parents:
512
diff
changeset
|
507 *x_offset = MAX(*x_offset, 0) + cell->xpad; |
9 | 508 } |
509 if (y_offset) | |
510 { | |
511 *y_offset = (cell->yalign * (cell_area->height - calc_height - 2 * cell->ypad)); | |
513
985fdfebd89e
Remove whitespace between function name and first parenthesis for the sake of consistency. (pass 2)
zas_
parents:
512
diff
changeset
|
512 *y_offset = MAX(*y_offset, 0) + cell->ypad; |
9 | 513 } |
514 } | |
515 | |
516 if (width) *width = calc_width; | |
517 if (height) *height = calc_height; | |
518 } | |
519 | |
520 static void | |
521 gqv_cell_renderer_icon_render(GtkCellRenderer *cell, | |
522 GdkWindow *window, | |
523 GtkWidget *widget, | |
524 GdkRectangle *background_area, | |
525 GdkRectangle *cell_area, | |
526 GdkRectangle *expose_area, | |
527 GtkCellRendererState flags) | |
528 | |
529 { | |
530 GQvCellRendererIcon *cellicon = (GQvCellRendererIcon *) cell; | |
531 GdkPixbuf *pixbuf; | |
532 const gchar *text; | |
533 GdkRectangle cell_rect; | |
534 GtkStateType state; | |
535 | |
536 pixbuf = cellicon->pixbuf; | |
537 text = cellicon->text; | |
538 | |
539 if (!pixbuf && !text) return; | |
540 | |
541 gqv_cell_renderer_icon_get_size(cell, widget, cell_area, | |
542 &cell_rect.x, &cell_rect.y, | |
543 &cell_rect.width, &cell_rect.height); | |
544 | |
545 cell_rect.x += cell->xpad; | |
546 cell_rect.y += cell->ypad; | |
547 cell_rect.width -= cell->xpad * 2; | |
548 cell_rect.height -= cell->ypad * 2; | |
549 | |
550 if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED) | |
551 { | |
552 if (GTK_WIDGET_HAS_FOCUS(widget)) | |
553 state = GTK_STATE_SELECTED; | |
554 else | |
555 state = GTK_STATE_ACTIVE; | |
556 } | |
557 else | |
558 { | |
559 if (GTK_WIDGET_STATE(widget) == GTK_STATE_INSENSITIVE) | |
560 state = GTK_STATE_INSENSITIVE; | |
561 else | |
562 state = GTK_STATE_NORMAL; | |
563 } | |
564 | |
565 if (pixbuf) | |
566 { | |
567 GdkRectangle pix_rect; | |
568 GdkRectangle draw_rect; | |
569 | |
570 pix_rect.width = gdk_pixbuf_get_width(pixbuf); | |
571 pix_rect.height = gdk_pixbuf_get_height(pixbuf); | |
572 | |
573 pix_rect.x = cell_area->x + (cell_area->width - pix_rect.width) / 2; | |
574 | |
575 if (cellicon->fixed_height > 0) | |
576 { | |
577 pix_rect.y = cell_area->y + cell->ypad + (cellicon->fixed_height - pix_rect.height) / 2; | |
578 } | |
579 else | |
580 { | |
581 pix_rect.y = cell_area->y + cell_rect.y; | |
582 } | |
583 | |
584 if (gdk_rectangle_intersect(cell_area, &pix_rect, &draw_rect) && | |
585 gdk_rectangle_intersect(expose_area, &draw_rect, &draw_rect)) | |
586 { | |
587 gdk_draw_pixbuf(window, | |
588 widget->style->black_gc, | |
589 pixbuf, | |
590 /* pixbuf 0, 0 is at pix_rect.x, pix_rect.y */ | |
591 draw_rect.x - pix_rect.x, | |
592 draw_rect.y - pix_rect.y, | |
593 draw_rect.x, | |
594 draw_rect.y, | |
595 draw_rect.width, | |
596 draw_rect.height, | |
597 GDK_RGB_DITHER_NORMAL, | |
598 0, 0); | |
599 } | |
600 } | |
601 | |
602 if (cellicon->show_text && text) | |
603 { | |
604 PangoLayout *layout; | |
605 PangoRectangle text_rect; | |
606 GdkRectangle pix_rect; | |
442 | 607 GdkRectangle draw_rect; |
9 | 608 |
609 layout = gqv_cell_renderer_icon_get_layout(cellicon, widget, TRUE); | |
610 pango_layout_get_pixel_extents(layout, NULL, &text_rect); | |
611 | |
612 pix_rect.width = text_rect.width; | |
613 pix_rect.height = text_rect.height; | |
614 pix_rect.x = cell_area->x + cell->xpad + (cell_rect.width - text_rect.width + 1) / 2; | |
615 pix_rect.y = cell_area->y + cell->ypad + (cell_rect.height - text_rect.height); | |
616 | |
617 if (gdk_rectangle_intersect(cell_area, &pix_rect, &draw_rect) && | |
618 gdk_rectangle_intersect(expose_area, &draw_rect, &draw_rect)) | |
619 { | |
620 gtk_paint_layout(widget->style, window, | |
621 state, TRUE, | |
622 cell_area, widget, | |
623 "cellrenderertext", | |
624 pix_rect.x - text_rect.x, pix_rect.y, | |
625 layout); | |
626 } | |
627 | |
628 g_object_unref(layout); | |
629 } | |
630 | |
534 | 631 if (cellicon->focused && GTK_WIDGET_HAS_FOCUS(widget)) |
9 | 632 { |
633 gtk_paint_focus(widget->style, window, | |
634 state, | |
635 cell_area, widget, | |
636 "cellrendererfocus", | |
637 cell_area->x, cell_area->y, | |
638 cell_area->width, cell_area->height); | |
639 } | |
640 } |