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