Mercurial > geeqie
annotate src/cellrenderericon.c @ 1064:90dcc0060e22
follow Exiv2 SVN changes
author | nadvornik |
---|---|
date | Tue, 14 Oct 2008 21:24:34 +0000 |
parents | 1646720364cf |
children | c9949c19a6d0 |
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 | |
852 | 29 #define TOGGLE_WIDTH 13 |
30 #define TOGGLE_SPACING 18 | |
31 | |
32 | |
9 | 33 static void gqv_cell_renderer_icon_get_property(GObject *object, |
442 | 34 guint param_id, |
35 GValue *value, | |
36 GParamSpec *pspec); | |
9 | 37 static void gqv_cell_renderer_icon_set_property(GObject *object, |
38 guint param_id, | |
39 const GValue *value, | |
40 GParamSpec *pspec); | |
41 static void gqv_cell_renderer_icon_init(GQvCellRendererIcon *celltext); | |
42 static void gqv_cell_renderer_icon_class_init(GQvCellRendererIconClass *class); | |
43 static void gqv_cell_renderer_icon_finalize(GObject *object); | |
44 static void gqv_cell_renderer_icon_get_size(GtkCellRenderer *cell, | |
45 GtkWidget *widget, | |
46 GdkRectangle *rectangle, | |
47 gint *x_offset, | |
48 gint *y_offset, | |
49 gint *width, | |
50 gint *height); | |
51 static void gqv_cell_renderer_icon_render(GtkCellRenderer *cell, | |
52 GdkWindow *window, | |
53 GtkWidget *widget, | |
54 GdkRectangle *background_area, | |
55 GdkRectangle *cell_area, | |
56 GdkRectangle *expose_area, | |
57 GtkCellRendererState flags); | |
58 | |
966 | 59 static gint gqv_cell_renderer_icon_activate (GtkCellRenderer *cell, |
60 GdkEvent *event, | |
61 GtkWidget *widget, | |
62 const gchar *path, | |
63 GdkRectangle *background_area, | |
64 GdkRectangle *cell_area, | |
65 GtkCellRendererState flags); | |
66 | |
67 enum { | |
68 TOGGLED, | |
69 LAST_SIGNAL | |
70 }; | |
9 | 71 |
72 enum { | |
73 PROP_ZERO, | |
74 PROP_PIXBUF, | |
75 PROP_TEXT, | |
76 PROP_BACKGROUND_GDK, | |
77 PROP_FOREGROUND_GDK, | |
78 PROP_FOCUSED, | |
79 PROP_FIXED_WIDTH, | |
80 PROP_FIXED_HEIGHT, | |
81 | |
82 PROP_BACKGROUND_SET, | |
83 PROP_FOREGROUND_SET, | |
852 | 84 PROP_SHOW_TEXT, |
85 PROP_SHOW_MARKS, | |
86 PROP_NUM_MARKS, | |
966 | 87 PROP_MARKS, |
88 PROP_TOGGLED | |
9 | 89 }; |
90 | |
966 | 91 static guint toggle_cell_signals[LAST_SIGNAL] = { 0 }; |
92 | |
9 | 93 static gpointer parent_class; |
94 | |
95 GType | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
96 gqv_cell_renderer_icon_get_type(void) |
9 | 97 { |
98 static GType cell_icon_type = 0; | |
99 | |
100 if (!cell_icon_type) | |
101 { | |
102 static const GTypeInfo cell_icon_info = | |
103 { | |
691 | 104 sizeof(GQvCellRendererIconClass), /* class_size */ |
9 | 105 NULL, /* base_init */ |
106 NULL, /* base_finalize */ | |
691 | 107 (GClassInitFunc) gqv_cell_renderer_icon_class_init, /* class_init */ |
9 | 108 NULL, /* class_finalize */ |
109 NULL, /* class_data */ | |
691 | 110 sizeof(GQvCellRendererIcon), /* instance_size */ |
9 | 111 0, /* n_preallocs */ |
691 | 112 (GInstanceInitFunc) gqv_cell_renderer_icon_init, /* instance_init */ |
113 NULL, /* value_table */ | |
534 | 114 }; |
9 | 115 |
534 | 116 cell_icon_type = g_type_register_static(GTK_TYPE_CELL_RENDERER, |
117 "GQvCellRendererIcon", | |
118 &cell_icon_info, 0); | |
119 } | |
9 | 120 |
121 return cell_icon_type; | |
122 } | |
123 | |
124 static void | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
125 gqv_cell_renderer_icon_init(GQvCellRendererIcon *cellicon) |
9 | 126 { |
966 | 127 GTK_CELL_RENDERER(cellicon)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE; |
9 | 128 GTK_CELL_RENDERER(cellicon)->xpad = 2; |
129 GTK_CELL_RENDERER(cellicon)->ypad = 2; | |
130 } | |
131 | |
132 static void | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
133 gqv_cell_renderer_icon_class_init(GQvCellRendererIconClass *class) |
9 | 134 { |
513
985fdfebd89e
Remove whitespace between function name and first parenthesis for the sake of consistency. (pass 2)
zas_
parents:
512
diff
changeset
|
135 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
|
136 GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS(class); |
9 | 137 |
513
985fdfebd89e
Remove whitespace between function name and first parenthesis for the sake of consistency. (pass 2)
zas_
parents:
512
diff
changeset
|
138 parent_class = g_type_class_peek_parent(class); |
9 | 139 |
140 object_class->finalize = gqv_cell_renderer_icon_finalize; | |
141 | |
142 object_class->get_property = gqv_cell_renderer_icon_get_property; | |
143 object_class->set_property = gqv_cell_renderer_icon_set_property; | |
144 | |
145 cell_class->get_size = gqv_cell_renderer_icon_get_size; | |
146 cell_class->render = gqv_cell_renderer_icon_render; | |
966 | 147 cell_class->activate = gqv_cell_renderer_icon_activate; |
9 | 148 |
149 g_object_class_install_property(object_class, | |
150 PROP_PIXBUF, | |
151 g_param_spec_object("pixbuf", | |
152 _("Pixbuf Object"), | |
153 _("The pixbuf to render"), | |
154 GDK_TYPE_PIXBUF, | |
155 G_PARAM_READWRITE)); | |
156 | |
157 g_object_class_install_property(object_class, | |
158 PROP_TEXT, | |
159 g_param_spec_string("text", | |
160 _("Text"), | |
161 _("Text to render"), | |
162 NULL, | |
163 G_PARAM_READWRITE)); | |
164 | |
165 g_object_class_install_property(object_class, | |
166 PROP_BACKGROUND_GDK, | |
167 g_param_spec_boxed("background_gdk", | |
168 _("Background color"), | |
169 _("Background color as a GdkColor"), | |
170 GDK_TYPE_COLOR, | |
171 G_PARAM_READWRITE)); | |
172 | |
173 g_object_class_install_property(object_class, | |
174 PROP_FOREGROUND_GDK, | |
175 g_param_spec_boxed("foreground_gdk", | |
176 _("Foreground color"), | |
177 _("Foreground color as a GdkColor"), | |
178 GDK_TYPE_COLOR, | |
179 G_PARAM_READWRITE)); | |
180 | |
181 g_object_class_install_property(object_class, | |
182 PROP_FOCUSED, | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
183 g_param_spec_boolean("has_focus", |
9 | 184 _("Focus"), |
185 _("Draw focus indicator"), | |
186 FALSE, | |
187 G_PARAM_READWRITE)); | |
188 | |
189 g_object_class_install_property(object_class, | |
190 PROP_FIXED_WIDTH, | |
191 g_param_spec_int("fixed_width", | |
192 _("Fixed width"), | |
193 _("Width of cell"), | |
194 -1, FIXED_ICON_SIZE_MAX, | |
195 -1, | |
196 G_PARAM_READWRITE)); | |
197 | |
198 g_object_class_install_property(object_class, | |
199 PROP_FIXED_HEIGHT, | |
200 g_param_spec_int("fixed_height", | |
201 _("Fixed height"), | |
202 _("Height of icon excluding text"), | |
203 -1, FIXED_ICON_SIZE_MAX, | |
204 -1, | |
205 G_PARAM_READWRITE)); | |
206 | |
207 g_object_class_install_property(object_class, | |
208 PROP_BACKGROUND_SET, | |
209 g_param_spec_boolean("background_set", | |
210 _("Background set"), | |
211 _("Whether this tag affects the background color"), | |
212 FALSE, | |
213 G_PARAM_READWRITE)); | |
214 | |
215 g_object_class_install_property(object_class, | |
216 PROP_FOREGROUND_SET, | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
217 g_param_spec_boolean("foreground_set", |
9 | 218 _("Foreground set"), |
219 _("Whether this tag affects the foreground color"), | |
220 FALSE, | |
221 G_PARAM_READWRITE)); | |
222 | |
223 g_object_class_install_property(object_class, | |
224 PROP_SHOW_TEXT, | |
225 g_param_spec_boolean("show_text", | |
226 _("Show text"), | |
227 _("Whether the text is displayed"), | |
228 TRUE, | |
229 G_PARAM_READWRITE)); | |
852 | 230 |
231 g_object_class_install_property(object_class, | |
232 PROP_SHOW_MARKS, | |
233 g_param_spec_boolean("show_marks", | |
234 _("Show marks"), | |
235 _("Whether the marks are displayed"), | |
236 TRUE, | |
237 G_PARAM_READWRITE)); | |
238 | |
239 g_object_class_install_property(object_class, | |
240 PROP_NUM_MARKS, | |
241 g_param_spec_int("num_marks", | |
242 _("Number of marks"), | |
243 _("Number of marks"), | |
244 0, 32, | |
245 6, | |
246 G_PARAM_READWRITE)); | |
247 | |
248 g_object_class_install_property(object_class, | |
249 PROP_MARKS, | |
250 g_param_spec_uint("marks", | |
251 _("Marks"), | |
252 _("Marks bit array"), | |
253 0, 0xffffffff, | |
254 0, | |
255 G_PARAM_READWRITE)); | |
966 | 256 |
257 g_object_class_install_property(object_class, | |
258 PROP_TOGGLED, | |
259 g_param_spec_uint("toggled_mark", | |
260 _("Toggled mark"), | |
261 _("Toggled mark"), | |
262 0, 32, | |
263 0, | |
264 G_PARAM_READWRITE)); | |
995 | 265 toggle_cell_signals[TOGGLED] = |
966 | 266 g_signal_new ("toggled", |
267 G_OBJECT_CLASS_TYPE (object_class), | |
268 G_SIGNAL_RUN_LAST, | |
269 G_STRUCT_OFFSET (GQvCellRendererIconClass, toggled), | |
270 NULL, NULL, | |
271 g_cclosure_marshal_VOID__STRING, | |
272 G_TYPE_NONE, 1, | |
273 G_TYPE_STRING); | |
274 | |
9 | 275 } |
276 | |
277 static void | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
278 gqv_cell_renderer_icon_finalize(GObject *object) |
9 | 279 { |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
280 GQvCellRendererIcon *cellicon = GQV_CELL_RENDERER_ICON(object); |
9 | 281 |
513
985fdfebd89e
Remove whitespace between function name and first parenthesis for the sake of consistency. (pass 2)
zas_
parents:
512
diff
changeset
|
282 if (cellicon->pixbuf) g_object_unref(cellicon->pixbuf); |
9 | 283 |
284 g_free(cellicon->text); | |
285 | |
513
985fdfebd89e
Remove whitespace between function name and first parenthesis for the sake of consistency. (pass 2)
zas_
parents:
512
diff
changeset
|
286 (*(G_OBJECT_CLASS(parent_class))->finalize)(object); |
9 | 287 } |
288 | |
289 static void | |
290 gqv_cell_renderer_icon_get_property(GObject *object, | |
291 guint param_id, | |
292 GValue *value, | |
293 GParamSpec *pspec) | |
294 { | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
295 GQvCellRendererIcon *cellicon = GQV_CELL_RENDERER_ICON(object); |
442 | 296 |
9 | 297 switch (param_id) |
534 | 298 { |
299 case PROP_PIXBUF: | |
300 g_value_set_object(value, cellicon->pixbuf ? G_OBJECT(cellicon->pixbuf) : NULL); | |
9 | 301 break; |
302 case PROP_TEXT: | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
303 g_value_set_string(value, cellicon->text); |
9 | 304 break; |
305 case PROP_BACKGROUND_GDK: | |
306 { | |
307 GdkColor color; | |
308 | |
309 color.red = cellicon->background.red; | |
310 color.green = cellicon->background.green; | |
311 color.blue = cellicon->background.blue; | |
312 | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
313 g_value_set_boxed(value, &color); |
9 | 314 } |
315 break; | |
316 case PROP_FOREGROUND_GDK: | |
317 { | |
318 GdkColor color; | |
319 | |
320 color.red = cellicon->foreground.red; | |
321 color.green = cellicon->foreground.green; | |
322 color.blue = cellicon->foreground.blue; | |
323 | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
324 g_value_set_boxed(value, &color); |
9 | 325 } |
326 break; | |
327 case PROP_FOCUSED: | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
328 g_value_set_boolean(value, cellicon->focused); |
9 | 329 break; |
330 case PROP_FIXED_WIDTH: | |
331 g_value_set_int(value, cellicon->fixed_width); | |
332 break; | |
333 case PROP_FIXED_HEIGHT: | |
334 g_value_set_int(value, cellicon->fixed_height); | |
335 break; | |
336 case PROP_BACKGROUND_SET: | |
337 g_value_set_boolean(value, cellicon->background_set); | |
338 break; | |
339 case PROP_FOREGROUND_SET: | |
340 g_value_set_boolean(value, cellicon->foreground_set); | |
341 break; | |
342 case PROP_SHOW_TEXT: | |
343 g_value_set_boolean(value, cellicon->show_text); | |
344 break; | |
852 | 345 case PROP_SHOW_MARKS: |
346 g_value_set_boolean(value, cellicon->show_marks); | |
347 break; | |
348 case PROP_NUM_MARKS: | |
349 g_value_set_int(value, cellicon->num_marks); | |
350 break; | |
351 case PROP_MARKS: | |
352 g_value_set_uint(value, cellicon->marks); | |
353 break; | |
966 | 354 case PROP_TOGGLED: |
355 g_value_set_uint(value, cellicon->toggled_mark); | |
356 break; | |
9 | 357 default: |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
358 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); |
9 | 359 break; |
360 } | |
361 } | |
362 | |
363 static void | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
364 set_bg_color(GQvCellRendererIcon *cellicon, |
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
365 GdkColor *color) |
9 | 366 { |
367 if (color) | |
368 { | |
369 if (!cellicon->background_set) | |
370 { | |
371 cellicon->background_set = TRUE; | |
372 g_object_notify(G_OBJECT(cellicon), "background_set"); | |
373 } | |
374 | |
375 cellicon->background.red = color->red; | |
376 cellicon->background.green = color->green; | |
377 cellicon->background.blue = color->blue; | |
378 } | |
379 else | |
380 { | |
381 if (cellicon->background_set) | |
382 { | |
383 cellicon->background_set = FALSE; | |
384 g_object_notify(G_OBJECT(cellicon), "background_set"); | |
385 } | |
386 } | |
387 } | |
388 | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
389 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
|
390 GdkColor *color) |
9 | 391 { |
392 if (color) | |
393 { | |
394 if (!cellicon->foreground_set) | |
395 { | |
396 cellicon->foreground_set = TRUE; | |
397 g_object_notify(G_OBJECT(cellicon), "foreground_set"); | |
398 } | |
399 | |
400 cellicon->foreground.red = color->red; | |
401 cellicon->foreground.green = color->green; | |
402 cellicon->foreground.blue = color->blue; | |
403 } | |
404 else | |
405 { | |
406 if (cellicon->foreground_set) | |
407 { | |
408 cellicon->foreground_set = FALSE; | |
409 g_object_notify(G_OBJECT(cellicon), "foreground_set"); | |
410 } | |
411 } | |
412 } | |
413 | |
414 static void | |
415 gqv_cell_renderer_icon_set_property(GObject *object, | |
416 guint param_id, | |
417 const GValue *value, | |
418 GParamSpec *pspec) | |
419 { | |
513
985fdfebd89e
Remove whitespace between function name and first parenthesis for the sake of consistency. (pass 2)
zas_
parents:
512
diff
changeset
|
420 GQvCellRendererIcon *cellicon = GQV_CELL_RENDERER_ICON(object); |
442 | 421 |
9 | 422 switch (param_id) |
534 | 423 { |
424 case PROP_PIXBUF: | |
9 | 425 { |
534 | 426 GdkPixbuf *pixbuf; |
9 | 427 |
1001 | 428 pixbuf = (GdkPixbuf *) g_value_get_object(value); |
534 | 429 if (pixbuf) g_object_ref(pixbuf); |
430 if (cellicon->pixbuf) g_object_unref(cellicon->pixbuf); | |
431 cellicon->pixbuf = pixbuf; | |
432 } | |
9 | 433 break; |
434 case PROP_TEXT: | |
435 { | |
436 gchar *text; | |
437 | |
438 text = cellicon->text; | |
439 cellicon->text = g_strdup(g_value_get_string(value)); | |
440 g_free(text); | |
441 | |
442 g_object_notify(object, "text"); | |
443 } | |
444 break; | |
445 case PROP_BACKGROUND_GDK: | |
446 set_bg_color(cellicon, g_value_get_boxed(value)); | |
447 break; | |
448 case PROP_FOREGROUND_GDK: | |
449 set_fg_color(cellicon, g_value_get_boxed(value)); | |
450 break; | |
451 case PROP_FOCUSED: | |
452 cellicon->focused = g_value_get_boolean(value); | |
453 break; | |
454 case PROP_FIXED_WIDTH: | |
455 cellicon->fixed_width = g_value_get_int(value); | |
456 break; | |
457 case PROP_FIXED_HEIGHT: | |
458 cellicon->fixed_height = g_value_get_int(value); | |
459 break; | |
460 case PROP_BACKGROUND_SET: | |
461 cellicon->background_set = g_value_get_boolean(value); | |
462 break; | |
463 case PROP_FOREGROUND_SET: | |
464 cellicon->foreground_set = g_value_get_boolean(value); | |
465 break; | |
466 case PROP_SHOW_TEXT: | |
467 cellicon->show_text = g_value_get_boolean(value); | |
468 break; | |
852 | 469 case PROP_SHOW_MARKS: |
470 cellicon->show_marks = g_value_get_boolean(value); | |
471 break; | |
472 case PROP_NUM_MARKS: | |
473 cellicon->num_marks = g_value_get_int(value); | |
474 break; | |
475 case PROP_MARKS: | |
476 cellicon->marks = g_value_get_uint(value); | |
477 break; | |
9 | 478 default: |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
446
diff
changeset
|
479 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); |
9 | 480 break; |
534 | 481 } |
9 | 482 } |
483 | |
484 static PangoLayout * | |
485 gqv_cell_renderer_icon_get_layout(GQvCellRendererIcon *cellicon, GtkWidget *widget, gboolean will_render) | |
486 { | |
487 PangoLayout *layout; | |
488 gint width; | |
489 | |
490 width = (cellicon->fixed_width > 0) ? cellicon->fixed_width * PANGO_SCALE : -1; | |
491 | |
492 layout = gtk_widget_create_pango_layout(widget, cellicon->text); | |
493 pango_layout_set_width(layout, width); | |
494 pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); | |
495 pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); | |
496 | |
497 if (will_render) | |
498 { | |
499 PangoAttrList *attr_list; | |
500 | |
501 attr_list = pango_attr_list_new(); | |
502 | |
503 if (cellicon->foreground_set) | |
504 { | |
505 PangoColor color; | |
506 PangoAttribute *attr; | |
507 | |
508 color = cellicon->foreground; | |
509 | |
510 attr = pango_attr_foreground_new(color.red, color.green, color.blue); | |
511 | |
512 attr->start_index = 0; | |
513 attr->end_index = G_MAXINT; | |
514 pango_attr_list_insert(attr_list, attr); | |
515 } | |
516 | |
517 pango_layout_set_attributes(layout, attr_list); | |
518 pango_attr_list_unref(attr_list); | |
519 } | |
520 | |
521 return layout; | |
522 } | |
523 | |
524 /** | |
525 * gqv_cell_renderer_icon_new: | |
442 | 526 * |
9 | 527 * Creates a new #GQvCellRendererIcon. Adjust rendering |
528 * parameters using object properties. Object properties can be set | |
529 * globally (with g_object_set()). Also, with #GtkTreeViewColumn, you | |
530 * can bind a property to a value in a #GtkTreeModel. For example, you | |
531 * can bind the "pixbuf" property on the cell renderer to a pixbuf value | |
532 * in the model, thus rendering a different image in each row of the | |
533 * #GtkTreeView. | |
442 | 534 * |
9 | 535 * Return value: the new cell renderer |
536 **/ | |
537 GtkCellRenderer * | |
538 gqv_cell_renderer_icon_new(void) | |
539 { | |
534 | 540 return g_object_new(GQV_TYPE_CELL_RENDERER_ICON, NULL); |
9 | 541 } |
542 | |
543 static void | |
544 gqv_cell_renderer_icon_get_size(GtkCellRenderer *cell, | |
545 GtkWidget *widget, | |
546 GdkRectangle *cell_area, | |
547 gint *x_offset, | |
548 gint *y_offset, | |
549 gint *width, | |
550 gint *height) | |
551 { | |
552 GQvCellRendererIcon *cellicon = (GQvCellRendererIcon *) cell; | |
553 gint calc_width; | |
554 gint calc_height; | |
555 | |
556 if (cellicon->fixed_width > 0) | |
557 { | |
558 calc_width = cellicon->fixed_width; | |
559 } | |
560 else | |
561 { | |
562 calc_width = (cellicon->pixbuf) ? gdk_pixbuf_get_width(cellicon->pixbuf) : 0; | |
563 } | |
564 | |
565 if (cellicon->fixed_height > 0) | |
566 { | |
567 calc_height = cellicon->fixed_height; | |
568 } | |
569 else | |
570 { | |
571 calc_height = (cellicon->pixbuf) ? gdk_pixbuf_get_height(cellicon->pixbuf) : 0; | |
572 } | |
573 | |
574 if (cellicon->show_text && cellicon->text) | |
575 { | |
576 PangoLayout *layout; | |
577 PangoRectangle rect; | |
578 | |
579 layout = gqv_cell_renderer_icon_get_layout(cellicon, widget, FALSE); | |
580 pango_layout_get_pixel_extents(layout, NULL, &rect); | |
581 g_object_unref(layout); | |
582 | |
583 calc_width = MAX(calc_width, rect.width); | |
584 calc_height += rect.height; | |
585 } | |
586 | |
852 | 587 if (cellicon->show_marks) |
588 { | |
589 calc_height += TOGGLE_SPACING; | |
590 calc_width = MAX(calc_width, TOGGLE_SPACING * cellicon->num_marks); | |
591 } | |
592 | |
9 | 593 calc_width += (gint)cell->xpad * 2; |
594 calc_height += (gint)cell->ypad * 2; | |
595 | |
596 if (x_offset) *x_offset = 0; | |
597 if (y_offset) *y_offset = 0; | |
598 | |
599 if (cell_area && calc_width > 0 && calc_height > 0) | |
600 { | |
601 if (x_offset) | |
602 { | |
603 *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
|
604 *x_offset = MAX(*x_offset, 0) + cell->xpad; |
9 | 605 } |
606 if (y_offset) | |
607 { | |
608 *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
|
609 *y_offset = MAX(*y_offset, 0) + cell->ypad; |
9 | 610 } |
611 } | |
612 | |
613 if (width) *width = calc_width; | |
614 if (height) *height = calc_height; | |
615 } | |
616 | |
617 static void | |
618 gqv_cell_renderer_icon_render(GtkCellRenderer *cell, | |
619 GdkWindow *window, | |
620 GtkWidget *widget, | |
621 GdkRectangle *background_area, | |
622 GdkRectangle *cell_area, | |
623 GdkRectangle *expose_area, | |
624 GtkCellRendererState flags) | |
625 | |
626 { | |
627 GQvCellRendererIcon *cellicon = (GQvCellRendererIcon *) cell; | |
628 GdkPixbuf *pixbuf; | |
629 const gchar *text; | |
630 GdkRectangle cell_rect; | |
631 GtkStateType state; | |
632 | |
633 pixbuf = cellicon->pixbuf; | |
634 text = cellicon->text; | |
635 | |
636 if (!pixbuf && !text) return; | |
637 | |
638 gqv_cell_renderer_icon_get_size(cell, widget, cell_area, | |
639 &cell_rect.x, &cell_rect.y, | |
640 &cell_rect.width, &cell_rect.height); | |
641 | |
642 cell_rect.x += cell->xpad; | |
643 cell_rect.y += cell->ypad; | |
644 cell_rect.width -= cell->xpad * 2; | |
645 cell_rect.height -= cell->ypad * 2; | |
646 | |
647 if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED) | |
648 { | |
649 if (GTK_WIDGET_HAS_FOCUS(widget)) | |
650 state = GTK_STATE_SELECTED; | |
651 else | |
652 state = GTK_STATE_ACTIVE; | |
653 } | |
654 else | |
655 { | |
656 if (GTK_WIDGET_STATE(widget) == GTK_STATE_INSENSITIVE) | |
657 state = GTK_STATE_INSENSITIVE; | |
658 else | |
659 state = GTK_STATE_NORMAL; | |
660 } | |
661 | |
662 if (pixbuf) | |
663 { | |
664 GdkRectangle pix_rect; | |
665 GdkRectangle draw_rect; | |
666 | |
667 pix_rect.width = gdk_pixbuf_get_width(pixbuf); | |
668 pix_rect.height = gdk_pixbuf_get_height(pixbuf); | |
669 | |
670 pix_rect.x = cell_area->x + (cell_area->width - pix_rect.width) / 2; | |
671 | |
672 if (cellicon->fixed_height > 0) | |
673 { | |
674 pix_rect.y = cell_area->y + cell->ypad + (cellicon->fixed_height - pix_rect.height) / 2; | |
675 } | |
676 else | |
677 { | |
678 pix_rect.y = cell_area->y + cell_rect.y; | |
679 } | |
680 | |
681 if (gdk_rectangle_intersect(cell_area, &pix_rect, &draw_rect) && | |
682 gdk_rectangle_intersect(expose_area, &draw_rect, &draw_rect)) | |
683 { | |
684 gdk_draw_pixbuf(window, | |
685 widget->style->black_gc, | |
686 pixbuf, | |
687 /* pixbuf 0, 0 is at pix_rect.x, pix_rect.y */ | |
688 draw_rect.x - pix_rect.x, | |
689 draw_rect.y - pix_rect.y, | |
690 draw_rect.x, | |
691 draw_rect.y, | |
692 draw_rect.width, | |
693 draw_rect.height, | |
694 GDK_RGB_DITHER_NORMAL, | |
695 0, 0); | |
696 } | |
697 } | |
698 | |
699 if (cellicon->show_text && text) | |
700 { | |
701 PangoLayout *layout; | |
702 PangoRectangle text_rect; | |
703 GdkRectangle pix_rect; | |
442 | 704 GdkRectangle draw_rect; |
9 | 705 |
706 layout = gqv_cell_renderer_icon_get_layout(cellicon, widget, TRUE); | |
707 pango_layout_get_pixel_extents(layout, NULL, &text_rect); | |
708 | |
709 pix_rect.width = text_rect.width; | |
710 pix_rect.height = text_rect.height; | |
711 pix_rect.x = cell_area->x + cell->xpad + (cell_rect.width - text_rect.width + 1) / 2; | |
712 pix_rect.y = cell_area->y + cell->ypad + (cell_rect.height - text_rect.height); | |
852 | 713 |
714 if (cellicon->show_marks) | |
715 { | |
716 pix_rect.y -= TOGGLE_SPACING; | |
717 } | |
9 | 718 |
719 if (gdk_rectangle_intersect(cell_area, &pix_rect, &draw_rect) && | |
720 gdk_rectangle_intersect(expose_area, &draw_rect, &draw_rect)) | |
721 { | |
722 gtk_paint_layout(widget->style, window, | |
723 state, TRUE, | |
724 cell_area, widget, | |
725 "cellrenderertext", | |
726 pix_rect.x - text_rect.x, pix_rect.y, | |
727 layout); | |
728 } | |
729 | |
730 g_object_unref(layout); | |
731 } | |
732 | |
852 | 733 if (cellicon->show_marks) |
734 { | |
735 GdkRectangle pix_rect; | |
736 GdkRectangle draw_rect; | |
737 gint i; | |
738 | |
739 pix_rect.width = TOGGLE_SPACING * cellicon->num_marks; | |
740 pix_rect.height = TOGGLE_SPACING; | |
741 pix_rect.x = cell_area->x + cell->xpad + (cell_rect.width - pix_rect.width + 1) / 2 + (TOGGLE_SPACING - TOGGLE_WIDTH) / 2; | |
742 pix_rect.y = cell_area->y + cell->ypad + (cell_rect.height - pix_rect.height) + (TOGGLE_SPACING - TOGGLE_WIDTH) / 2; | |
743 | |
853 | 744 if (gdk_rectangle_intersect(cell_area, &pix_rect, &draw_rect) && |
745 gdk_rectangle_intersect(expose_area, &draw_rect, &draw_rect)) | |
852 | 746 { |
853 | 747 for (i = 0; i < cellicon->num_marks; i++) |
748 { | |
749 gtk_paint_check (widget->style, window, | |
750 state, (cellicon->marks & (1 << i)) ? GTK_SHADOW_IN : GTK_SHADOW_OUT, | |
751 cell_area, widget, "cellcheck", | |
752 pix_rect.x + i * TOGGLE_SPACING + (TOGGLE_WIDTH - TOGGLE_SPACING) / 2, | |
753 pix_rect.y, | |
754 TOGGLE_WIDTH, TOGGLE_WIDTH); | |
755 } | |
852 | 756 } |
757 } | |
758 | |
534 | 759 if (cellicon->focused && GTK_WIDGET_HAS_FOCUS(widget)) |
9 | 760 { |
761 gtk_paint_focus(widget->style, window, | |
762 state, | |
763 cell_area, widget, | |
764 "cellrendererfocus", | |
765 cell_area->x, cell_area->y, | |
766 cell_area->width, cell_area->height); | |
767 } | |
768 } | |
966 | 769 |
770 static gint | |
771 gqv_cell_renderer_icon_activate (GtkCellRenderer *cell, | |
772 GdkEvent *event, | |
773 GtkWidget *widget, | |
774 const gchar *path, | |
775 GdkRectangle *background_area, | |
776 GdkRectangle *cell_area, | |
777 GtkCellRendererState flags) | |
778 { | |
779 GQvCellRendererIcon *cellicon = (GQvCellRendererIcon *) cell; | |
780 GdkEventButton *bevent = &event->button; | |
781 | |
782 if (cellicon->show_marks && | |
783 event->type == GDK_BUTTON_PRESS && | |
784 !(bevent->state & GDK_SHIFT_MASK ) && | |
785 !(bevent->state & GDK_CONTROL_MASK )) | |
786 { | |
787 GdkRectangle rect; | |
788 GdkRectangle cell_rect; | |
789 gint i; | |
790 | |
791 gqv_cell_renderer_icon_get_size(cell, widget, cell_area, | |
792 &cell_rect.x, &cell_rect.y, | |
793 &cell_rect.width, &cell_rect.height); | |
794 | |
795 cell_rect.x += cell->xpad; | |
796 cell_rect.y += cell->ypad; | |
797 cell_rect.width -= cell->xpad * 2; | |
798 cell_rect.height -= cell->ypad * 2; | |
799 | |
800 rect.width = TOGGLE_WIDTH; | |
801 rect.height = TOGGLE_WIDTH; | |
802 rect.y = cell_area->y + cell->ypad + (cell_rect.height - TOGGLE_SPACING) + (TOGGLE_SPACING - TOGGLE_WIDTH) / 2; | |
803 for (i = 0; i < cellicon->num_marks; i++) | |
804 { | |
805 rect.x = cell_area->x + cell->xpad + (cell_rect.width - TOGGLE_SPACING * cellicon->num_marks + 1) / 2 + i * TOGGLE_SPACING; | |
806 | |
807 if (bevent->x >= rect.x && bevent->x < rect.x + rect.width && | |
808 bevent->y >= rect.y && bevent->y < rect.y + rect.height) | |
809 { | |
810 cellicon->toggled_mark = i; | |
811 g_signal_emit (cell, toggle_cell_signals[TOGGLED], 0, path); | |
812 break; | |
813 } | |
814 } | |
815 } | |
816 return FALSE; | |
817 } | |
1055
1646720364cf
Adding a vim modeline to all files - patch by Klaus Ethgen
nadvornik
parents:
1001
diff
changeset
|
818 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ |