Mercurial > pidgin.yaz
comparison src/gtkcellview.c @ 10708:d0d1d631ed49
[gaim-migrate @ 12297]
Add some files I missed that are necessary for Gtk 2.4 support, actually
commit the makefile changes to compile on Gtk 2.4, fix building with Gtk 2.6
which I broke. And some Gtk 2.2 support too, which should be considered
experimental (where experimental means "almost completely broken"). Also a
couple of tweaks which might make Gaim continue working after upgrading Gtk
without rebuilding Gaim, but I haven't actually tested that.
committer: Tailor Script <tailor@pidgin.im>
author | Stu Tomlinson <stu@nosnilmot.com> |
---|---|
date | Sun, 20 Mar 2005 17:37:31 +0000 |
parents | |
children | 7ab959eb857e |
comparison
equal
deleted
inserted
replaced
10707:7672a83c04da | 10708:d0d1d631ed49 |
---|---|
1 /* gtkellview.c | |
2 * Copyright (C) 2002, 2003 Kristian Rietveld <kris@gtk.org> | |
3 * | |
4 * This library is free software; you can redistribute it and/or | |
5 * modify it under the terms of the GNU Library General Public | |
6 * License as published by the Free Software Foundation; either | |
7 * version 2 of the License, or (at your option) any later version. | |
8 * | |
9 * This library is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 * Library General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU Library General Public | |
15 * License along with this library; if not, write to the | |
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
17 * Boston, MA 02111-1307, USA. | |
18 */ | |
19 | |
20 /* | |
21 #include <config.h> | |
22 */ | |
23 #include "gtkcellview.h" | |
24 #include <gtk/gtkversion.h> | |
25 #if !GTK_CHECK_VERSION(2,6,0) | |
26 #if GTK_CHECK_VERSION(2,4,0) | |
27 #include <gtk/gtkcelllayout.h> | |
28 #else | |
29 #include "gtkcelllayout.h" | |
30 #endif | |
31 #include <gtk/gtksignal.h> | |
32 #include <gtk/gtkcellrenderertext.h> | |
33 #include <gtk/gtkcellrendererpixbuf.h> | |
34 #include <gobject/gmarshal.h> | |
35 | |
36 #ifdef ENABLE_NLS | |
37 # include <libintl.h> | |
38 # define _(x) gettext(x) | |
39 # ifdef gettext_noop | |
40 # define N_(String) gettext_noop (String) | |
41 # else | |
42 # define N_(String) (String) | |
43 # endif | |
44 #else | |
45 # define N_(String) (String) | |
46 # define _(x) (x) | |
47 #endif | |
48 | |
49 typedef struct _GtkCellViewCellInfo GtkCellViewCellInfo; | |
50 struct _GtkCellViewCellInfo | |
51 { | |
52 GtkCellRenderer *cell; | |
53 | |
54 gint requested_width; | |
55 gint real_width; | |
56 guint expand : 1; | |
57 guint pack : 1; | |
58 | |
59 GSList *attributes; | |
60 | |
61 GtkCellLayoutDataFunc func; | |
62 gpointer func_data; | |
63 GDestroyNotify destroy; | |
64 }; | |
65 | |
66 struct _GtkCellViewPrivate | |
67 { | |
68 GtkTreeModel *model; | |
69 GtkTreeRowReference *displayed_row; | |
70 GList *cell_list; | |
71 gint spacing; | |
72 | |
73 GdkColor background; | |
74 gboolean background_set; | |
75 }; | |
76 | |
77 | |
78 static void gtk_cell_view_class_init (GtkCellViewClass *klass); | |
79 static void gtk_cell_view_cell_layout_init (GtkCellLayoutIface *iface); | |
80 static void gtk_cell_view_get_property (GObject *object, | |
81 guint param_id, | |
82 GValue *value, | |
83 GParamSpec *pspec); | |
84 static void gtk_cell_view_set_property (GObject *object, | |
85 guint param_id, | |
86 const GValue *value, | |
87 GParamSpec *pspec); | |
88 static void gtk_cell_view_init (GtkCellView *cellview); | |
89 static void gtk_cell_view_finalize (GObject *object); | |
90 static void gtk_cell_view_style_set (GtkWidget *widget, | |
91 GtkStyle *previous_style); | |
92 static void gtk_cell_view_size_request (GtkWidget *widget, | |
93 GtkRequisition *requisition); | |
94 static void gtk_cell_view_size_allocate (GtkWidget *widget, | |
95 GtkAllocation *allocation); | |
96 static gboolean gtk_cell_view_expose (GtkWidget *widget, | |
97 GdkEventExpose *event); | |
98 static void gtk_cell_view_set_valuesv (GtkCellView *cellview, | |
99 GtkCellRenderer *renderer, | |
100 va_list args); | |
101 static GtkCellViewCellInfo *gtk_cell_view_get_cell_info (GtkCellView *cellview, | |
102 GtkCellRenderer *renderer); | |
103 static void gtk_cell_view_set_cell_data (GtkCellView *cellview); | |
104 | |
105 | |
106 static void gtk_cell_view_cell_layout_pack_start (GtkCellLayout *layout, | |
107 GtkCellRenderer *renderer, | |
108 gboolean expand); | |
109 static void gtk_cell_view_cell_layout_pack_end (GtkCellLayout *layout, | |
110 GtkCellRenderer *renderer, | |
111 gboolean expand); | |
112 static void gtk_cell_view_cell_layout_add_attribute (GtkCellLayout *layout, | |
113 GtkCellRenderer *renderer, | |
114 const gchar *attribute, | |
115 gint column); | |
116 static void gtk_cell_view_cell_layout_clear (GtkCellLayout *layout); | |
117 static void gtk_cell_view_cell_layout_clear_attributes (GtkCellLayout *layout, | |
118 GtkCellRenderer *renderer); | |
119 static void gtk_cell_view_cell_layout_set_cell_data_func (GtkCellLayout *layout, | |
120 GtkCellRenderer *cell, | |
121 GtkCellLayoutDataFunc func, | |
122 gpointer func_data, | |
123 GDestroyNotify destroy); | |
124 static void gtk_cell_view_cell_layout_reorder (GtkCellLayout *layout, | |
125 GtkCellRenderer *cell, | |
126 gint position); | |
127 | |
128 | |
129 enum | |
130 { | |
131 PROP_0, | |
132 PROP_BACKGROUND, | |
133 PROP_BACKGROUND_GDK, | |
134 PROP_BACKGROUND_SET | |
135 }; | |
136 | |
137 static GtkObjectClass *parent_class = NULL; | |
138 | |
139 | |
140 GType | |
141 gtk_cell_view_get_type (void) | |
142 { | |
143 static GType cell_view_type = 0; | |
144 | |
145 if (!cell_view_type) | |
146 { | |
147 static const GTypeInfo cell_view_info = | |
148 { | |
149 sizeof (GtkCellViewClass), | |
150 NULL, /* base_init */ | |
151 NULL, /* base_finalize */ | |
152 (GClassInitFunc) gtk_cell_view_class_init, | |
153 NULL, /* class_finalize */ | |
154 NULL, /* class_data */ | |
155 sizeof (GtkCellView), | |
156 0, | |
157 (GInstanceInitFunc) gtk_cell_view_init | |
158 }; | |
159 | |
160 static const GInterfaceInfo cell_layout_info = | |
161 { | |
162 (GInterfaceInitFunc) gtk_cell_view_cell_layout_init, | |
163 NULL, | |
164 NULL | |
165 }; | |
166 | |
167 cell_view_type = g_type_register_static (GTK_TYPE_WIDGET, "GaimGtkCellView", | |
168 &cell_view_info, 0); | |
169 | |
170 g_type_add_interface_static (cell_view_type, GTK_TYPE_CELL_LAYOUT, | |
171 &cell_layout_info); | |
172 } | |
173 | |
174 return cell_view_type; | |
175 } | |
176 | |
177 static void | |
178 gtk_cell_view_class_init (GtkCellViewClass *klass) | |
179 { | |
180 GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | |
181 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); | |
182 | |
183 parent_class = g_type_class_peek_parent (klass); | |
184 | |
185 gobject_class->get_property = gtk_cell_view_get_property; | |
186 gobject_class->set_property = gtk_cell_view_set_property; | |
187 gobject_class->finalize = gtk_cell_view_finalize; | |
188 | |
189 widget_class->expose_event = gtk_cell_view_expose; | |
190 widget_class->size_allocate = gtk_cell_view_size_allocate; | |
191 widget_class->size_request = gtk_cell_view_size_request; | |
192 widget_class->style_set = gtk_cell_view_style_set; | |
193 | |
194 /* properties */ | |
195 g_object_class_install_property (gobject_class, | |
196 PROP_BACKGROUND, | |
197 g_param_spec_string ("background", | |
198 _("Background color name"), | |
199 _("Background color as a string"), | |
200 NULL, | |
201 G_PARAM_WRITABLE)); | |
202 g_object_class_install_property (gobject_class, | |
203 PROP_BACKGROUND_GDK, | |
204 g_param_spec_boxed ("background_gdk", | |
205 _("Background color"), | |
206 _("Background color as a GdkColor"), | |
207 GDK_TYPE_COLOR, | |
208 G_PARAM_READABLE | G_PARAM_WRITABLE)); | |
209 | |
210 #define ADD_SET_PROP(propname, propval, nick, blurb) g_object_class_install_property (gobject_class, propval, g_param_spec_boolean (propname, nick, blurb, FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE)) | |
211 | |
212 ADD_SET_PROP ("background_set", PROP_BACKGROUND_SET, | |
213 _("Background set"), | |
214 _("Whether this tag affects the background color")); | |
215 } | |
216 | |
217 static void | |
218 gtk_cell_view_cell_layout_init (GtkCellLayoutIface *iface) | |
219 { | |
220 iface->pack_start = gtk_cell_view_cell_layout_pack_start; | |
221 iface->pack_end = gtk_cell_view_cell_layout_pack_end; | |
222 iface->clear = gtk_cell_view_cell_layout_clear; | |
223 iface->add_attribute = gtk_cell_view_cell_layout_add_attribute; | |
224 iface->set_cell_data_func = gtk_cell_view_cell_layout_set_cell_data_func; | |
225 iface->clear_attributes = gtk_cell_view_cell_layout_clear_attributes; | |
226 iface->reorder = gtk_cell_view_cell_layout_reorder; | |
227 } | |
228 | |
229 static void | |
230 gtk_cell_view_get_property (GObject *object, | |
231 guint param_id, | |
232 GValue *value, | |
233 GParamSpec *pspec) | |
234 { | |
235 GtkCellView *view = GTK_CELL_VIEW (object); | |
236 | |
237 switch (param_id) | |
238 { | |
239 case PROP_BACKGROUND_GDK: | |
240 { | |
241 GdkColor color; | |
242 | |
243 color = view->priv->background; | |
244 | |
245 g_value_set_boxed (value, &color); | |
246 } | |
247 break; | |
248 case PROP_BACKGROUND_SET: | |
249 g_value_set_boolean (value, view->priv->background_set); | |
250 break; | |
251 default: | |
252 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); | |
253 break; | |
254 } | |
255 } | |
256 | |
257 static void | |
258 gtk_cell_view_set_property (GObject *object, | |
259 guint param_id, | |
260 const GValue *value, | |
261 GParamSpec *pspec) | |
262 { | |
263 GtkCellView *view = GTK_CELL_VIEW (object); | |
264 | |
265 switch (param_id) | |
266 { | |
267 case PROP_BACKGROUND: | |
268 { | |
269 GdkColor color; | |
270 | |
271 if (!g_value_get_string (value)) | |
272 gtk_cell_view_set_background_color (view, NULL); | |
273 else if (gdk_color_parse (g_value_get_string (value), &color)) | |
274 gtk_cell_view_set_background_color (view, &color); | |
275 else | |
276 g_warning ("Don't know color `%s'", g_value_get_string (value)); | |
277 | |
278 g_object_notify (object, "background_gdk"); | |
279 } | |
280 break; | |
281 case PROP_BACKGROUND_GDK: | |
282 gtk_cell_view_set_background_color (view, g_value_get_boxed (value)); | |
283 break; | |
284 case PROP_BACKGROUND_SET: | |
285 view->priv->background_set = g_value_get_boolean (value); | |
286 break; | |
287 default: | |
288 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); | |
289 break; | |
290 } | |
291 } | |
292 | |
293 static void | |
294 gtk_cell_view_init (GtkCellView *cellview) | |
295 { | |
296 GTK_WIDGET_SET_FLAGS (cellview, GTK_NO_WINDOW); | |
297 | |
298 cellview->priv = g_new0(GtkCellViewPrivate,1); | |
299 } | |
300 | |
301 static void | |
302 gtk_cell_view_style_set (GtkWidget *widget, | |
303 GtkStyle *previous_style) | |
304 { | |
305 if (previous_style && GTK_WIDGET_REALIZED (widget)) | |
306 gdk_window_set_background (widget->window, | |
307 &widget->style->base[GTK_WIDGET_STATE (widget)]); | |
308 } | |
309 | |
310 static void | |
311 gtk_cell_view_finalize (GObject *object) | |
312 { | |
313 GtkCellView *cellview = GTK_CELL_VIEW (object); | |
314 | |
315 gtk_cell_view_cell_layout_clear (GTK_CELL_LAYOUT (cellview)); | |
316 | |
317 if (cellview->priv->model) | |
318 g_object_unref (cellview->priv->model); | |
319 | |
320 if (cellview->priv->displayed_row) | |
321 gtk_tree_row_reference_free (cellview->priv->displayed_row); | |
322 | |
323 if (G_OBJECT_CLASS (parent_class)->finalize) | |
324 (* G_OBJECT_CLASS (parent_class)->finalize) (object); | |
325 | |
326 g_free (cellview->priv); | |
327 } | |
328 | |
329 static void | |
330 gtk_cell_view_size_request (GtkWidget *widget, | |
331 GtkRequisition *requisition) | |
332 { | |
333 GList *i; | |
334 gboolean first_cell = TRUE; | |
335 GtkCellView *cellview; | |
336 | |
337 cellview = GTK_CELL_VIEW (widget); | |
338 | |
339 requisition->width = 0; | |
340 requisition->height = 0; | |
341 | |
342 if (cellview->priv->displayed_row) | |
343 gtk_cell_view_set_cell_data (cellview); | |
344 | |
345 for (i = cellview->priv->cell_list; i; i = i->next) | |
346 { | |
347 gint width, height; | |
348 GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data; | |
349 | |
350 if (!info->cell->visible) | |
351 continue; | |
352 | |
353 if (!first_cell) | |
354 requisition->width += cellview->priv->spacing; | |
355 | |
356 gtk_cell_renderer_get_size (info->cell, widget, NULL, NULL, NULL, | |
357 &width, &height); | |
358 | |
359 info->requested_width = width; | |
360 requisition->width += width; | |
361 requisition->height = MAX (requisition->height, height); | |
362 | |
363 first_cell = FALSE; | |
364 } | |
365 } | |
366 | |
367 static void | |
368 gtk_cell_view_size_allocate (GtkWidget *widget, | |
369 GtkAllocation *allocation) | |
370 { | |
371 GList *i; | |
372 gint expand_cell_count = 0; | |
373 gint full_requested_width = 0; | |
374 gint extra_space; | |
375 GtkCellView *cellview; | |
376 | |
377 widget->allocation = *allocation; | |
378 | |
379 cellview = GTK_CELL_VIEW (widget); | |
380 | |
381 /* checking how much extra space we have */ | |
382 for (i = cellview->priv->cell_list; i; i = i->next) | |
383 { | |
384 GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data; | |
385 | |
386 if (!info->cell->visible) | |
387 continue; | |
388 | |
389 if (info->expand) | |
390 expand_cell_count++; | |
391 | |
392 full_requested_width += info->requested_width; | |
393 } | |
394 | |
395 extra_space = widget->allocation.width - full_requested_width; | |
396 if (extra_space < 0) | |
397 extra_space = 0; | |
398 else if (extra_space > 0 && expand_cell_count > 0) | |
399 extra_space /= expand_cell_count; | |
400 | |
401 /* iterate list for PACK_START cells */ | |
402 for (i = cellview->priv->cell_list; i; i = i->next) | |
403 { | |
404 GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data; | |
405 | |
406 if (info->pack == GTK_PACK_END) | |
407 continue; | |
408 | |
409 if (!info->cell->visible) | |
410 continue; | |
411 | |
412 info->real_width = info->requested_width + (info->expand ? extra_space : 0); | |
413 } | |
414 | |
415 /* iterate list for PACK_END cells */ | |
416 for (i = cellview->priv->cell_list; i; i = i->next) | |
417 { | |
418 GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data; | |
419 | |
420 if (info->pack == GTK_PACK_START) | |
421 continue; | |
422 | |
423 if (!info->cell->visible) | |
424 continue; | |
425 | |
426 info->real_width = info->requested_width + (info->expand ? extra_space : 0); | |
427 } | |
428 } | |
429 | |
430 static gboolean | |
431 gtk_cell_view_expose (GtkWidget *widget, | |
432 GdkEventExpose *event) | |
433 { | |
434 GList *i; | |
435 GtkCellView *cellview; | |
436 GdkRectangle area; | |
437 GtkCellRendererState state; | |
438 gboolean rtl = (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL); | |
439 | |
440 cellview = GTK_CELL_VIEW (widget); | |
441 | |
442 if (! GTK_WIDGET_DRAWABLE (widget)) | |
443 return FALSE; | |
444 | |
445 /* "blank" background */ | |
446 if (cellview->priv->background_set) | |
447 { | |
448 GdkGC *gc; | |
449 | |
450 gc = gdk_gc_new (GTK_WIDGET (cellview)->window); | |
451 gdk_gc_set_rgb_fg_color (gc, &cellview->priv->background); | |
452 | |
453 gdk_draw_rectangle (GTK_WIDGET (cellview)->window, | |
454 gc, | |
455 TRUE, | |
456 | |
457 /*0, 0,*/ | |
458 widget->allocation.x, | |
459 widget->allocation.y, | |
460 | |
461 widget->allocation.width, | |
462 widget->allocation.height); | |
463 | |
464 g_object_unref (G_OBJECT (gc)); | |
465 } | |
466 | |
467 /* set cell data (if available) */ | |
468 if (cellview->priv->displayed_row) | |
469 gtk_cell_view_set_cell_data (cellview); | |
470 else if (cellview->priv->model) | |
471 return FALSE; | |
472 | |
473 /* render cells */ | |
474 area = widget->allocation; | |
475 | |
476 /* we draw on our very own window, initialize x and y to zero */ | |
477 area.x = widget->allocation.x + (rtl ? widget->allocation.width : 0); | |
478 area.y = widget->allocation.y; | |
479 | |
480 if (GTK_WIDGET_STATE (widget) == GTK_STATE_PRELIGHT) | |
481 state = GTK_CELL_RENDERER_PRELIT; | |
482 else | |
483 state = 0; | |
484 | |
485 /* PACK_START */ | |
486 for (i = cellview->priv->cell_list; i; i = i->next) | |
487 { | |
488 GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data; | |
489 | |
490 if (info->pack == GTK_PACK_END) | |
491 continue; | |
492 | |
493 if (!info->cell->visible) | |
494 continue; | |
495 | |
496 area.width = info->real_width; | |
497 if (rtl) | |
498 area.x -= area.width; | |
499 | |
500 gtk_cell_renderer_render (info->cell, | |
501 event->window, | |
502 widget, | |
503 /* FIXME! */ | |
504 &area, &area, &event->area, state); | |
505 | |
506 if (!rtl) | |
507 area.x += info->real_width; | |
508 } | |
509 | |
510 area.x = rtl ? widget->allocation.x : (widget->allocation.x + widget->allocation.width); | |
511 | |
512 /* PACK_END */ | |
513 for (i = cellview->priv->cell_list; i; i = i->next) | |
514 { | |
515 GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data; | |
516 | |
517 if (info->pack == GTK_PACK_START) | |
518 continue; | |
519 | |
520 if (!info->cell->visible) | |
521 continue; | |
522 | |
523 area.width = info->real_width; | |
524 if (!rtl) | |
525 area.x -= area.width; | |
526 | |
527 gtk_cell_renderer_render (info->cell, | |
528 widget->window, | |
529 widget, | |
530 /* FIXME ! */ | |
531 &area, &area, &event->area, state); | |
532 if (rtl) | |
533 area.x += info->real_width; | |
534 } | |
535 | |
536 return FALSE; | |
537 } | |
538 | |
539 static GtkCellViewCellInfo * | |
540 gtk_cell_view_get_cell_info (GtkCellView *cellview, | |
541 GtkCellRenderer *renderer) | |
542 { | |
543 GList *i; | |
544 | |
545 for (i = cellview->priv->cell_list; i; i = i->next) | |
546 { | |
547 GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data; | |
548 | |
549 if (info->cell == renderer) | |
550 return info; | |
551 } | |
552 | |
553 return NULL; | |
554 } | |
555 | |
556 static void | |
557 gtk_cell_view_set_cell_data (GtkCellView *cellview) | |
558 { | |
559 GList *i; | |
560 GtkTreeIter iter; | |
561 GtkTreePath *path; | |
562 | |
563 g_return_if_fail (cellview->priv->displayed_row != NULL); | |
564 | |
565 path = gtk_tree_row_reference_get_path (cellview->priv->displayed_row); | |
566 gtk_tree_model_get_iter (cellview->priv->model, &iter, path); | |
567 gtk_tree_path_free (path); | |
568 | |
569 for (i = cellview->priv->cell_list; i; i = i->next) | |
570 { | |
571 GSList *j; | |
572 GtkCellViewCellInfo *info = i->data; | |
573 | |
574 g_object_freeze_notify (G_OBJECT (info->cell)); | |
575 | |
576 for (j = info->attributes; j && j->next; j = j->next->next) | |
577 { | |
578 gchar *property = j->data; | |
579 gint column = GPOINTER_TO_INT (j->next->data); | |
580 GValue value = {0, }; | |
581 | |
582 gtk_tree_model_get_value (cellview->priv->model, &iter, | |
583 column, &value); | |
584 g_object_set_property (G_OBJECT (info->cell), | |
585 property, &value); | |
586 g_value_unset (&value); | |
587 } | |
588 | |
589 if (info->func) | |
590 (* info->func) (GTK_CELL_LAYOUT (cellview), | |
591 info->cell, | |
592 cellview->priv->model, | |
593 &iter, | |
594 info->func_data); | |
595 | |
596 g_object_thaw_notify (G_OBJECT (info->cell)); | |
597 } | |
598 } | |
599 | |
600 /* GtkCellLayout implementation */ | |
601 static void | |
602 gtk_cell_view_cell_layout_pack_start (GtkCellLayout *layout, | |
603 GtkCellRenderer *renderer, | |
604 gboolean expand) | |
605 { | |
606 GtkCellViewCellInfo *info; | |
607 GtkCellView *cellview = GTK_CELL_VIEW (layout); | |
608 | |
609 g_return_if_fail (GTK_IS_CELL_VIEW (cellview)); | |
610 g_return_if_fail (GTK_IS_CELL_RENDERER (renderer)); | |
611 g_return_if_fail (!gtk_cell_view_get_cell_info (cellview, renderer)); | |
612 | |
613 g_object_ref (G_OBJECT (renderer)); | |
614 gtk_object_sink (GTK_OBJECT (renderer)); | |
615 | |
616 info = g_new0 (GtkCellViewCellInfo, 1); | |
617 info->cell = renderer; | |
618 info->expand = expand ? TRUE : FALSE; | |
619 info->pack = GTK_PACK_START; | |
620 | |
621 cellview->priv->cell_list = g_list_append (cellview->priv->cell_list, info); | |
622 } | |
623 | |
624 static void | |
625 gtk_cell_view_cell_layout_pack_end (GtkCellLayout *layout, | |
626 GtkCellRenderer *renderer, | |
627 gboolean expand) | |
628 { | |
629 GtkCellViewCellInfo *info; | |
630 GtkCellView *cellview = GTK_CELL_VIEW (layout); | |
631 | |
632 g_return_if_fail (GTK_IS_CELL_VIEW (cellview)); | |
633 g_return_if_fail (GTK_IS_CELL_RENDERER (renderer)); | |
634 g_return_if_fail (!gtk_cell_view_get_cell_info (cellview, renderer)); | |
635 | |
636 g_object_ref (G_OBJECT (renderer)); | |
637 gtk_object_sink (GTK_OBJECT (renderer)); | |
638 | |
639 info = g_new0 (GtkCellViewCellInfo, 1); | |
640 info->cell = renderer; | |
641 info->expand = expand ? TRUE : FALSE; | |
642 info->pack = GTK_PACK_END; | |
643 | |
644 cellview->priv->cell_list = g_list_append (cellview->priv->cell_list, info); | |
645 } | |
646 | |
647 static void | |
648 gtk_cell_view_cell_layout_add_attribute (GtkCellLayout *layout, | |
649 GtkCellRenderer *renderer, | |
650 const gchar *attribute, | |
651 gint column) | |
652 { | |
653 GtkCellViewCellInfo *info; | |
654 GtkCellView *cellview = GTK_CELL_VIEW (layout); | |
655 | |
656 g_return_if_fail (GTK_IS_CELL_VIEW (cellview)); | |
657 info = gtk_cell_view_get_cell_info (cellview, renderer); | |
658 g_return_if_fail (info != NULL); | |
659 | |
660 info->attributes = g_slist_prepend (info->attributes, | |
661 GINT_TO_POINTER (column)); | |
662 info->attributes = g_slist_prepend (info->attributes, | |
663 g_strdup (attribute)); | |
664 } | |
665 | |
666 static void | |
667 gtk_cell_view_cell_layout_clear (GtkCellLayout *layout) | |
668 { | |
669 GtkCellView *cellview = GTK_CELL_VIEW (layout); | |
670 | |
671 g_return_if_fail (GTK_IS_CELL_VIEW (cellview)); | |
672 | |
673 while (cellview->priv->cell_list) | |
674 { | |
675 GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)cellview->priv->cell_list->data; | |
676 | |
677 gtk_cell_view_cell_layout_clear_attributes (layout, info->cell); | |
678 g_object_unref (G_OBJECT (info->cell)); | |
679 g_free (info); | |
680 cellview->priv->cell_list = g_list_delete_link (cellview->priv->cell_list, | |
681 cellview->priv->cell_list); | |
682 } | |
683 } | |
684 | |
685 static void | |
686 gtk_cell_view_cell_layout_set_cell_data_func (GtkCellLayout *layout, | |
687 GtkCellRenderer *cell, | |
688 GtkCellLayoutDataFunc func, | |
689 gpointer func_data, | |
690 GDestroyNotify destroy) | |
691 { | |
692 GtkCellView *cellview = GTK_CELL_VIEW (layout); | |
693 GtkCellViewCellInfo *info; | |
694 | |
695 g_return_if_fail (GTK_IS_CELL_VIEW (cellview)); | |
696 | |
697 info = gtk_cell_view_get_cell_info (cellview, cell); | |
698 g_return_if_fail (info != NULL); | |
699 | |
700 if (info->destroy) | |
701 { | |
702 GDestroyNotify d = info->destroy; | |
703 | |
704 info->destroy = NULL; | |
705 d (info->func_data); | |
706 } | |
707 | |
708 info->func = func; | |
709 info->func_data = func_data; | |
710 info->destroy = destroy; | |
711 } | |
712 | |
713 static void | |
714 gtk_cell_view_cell_layout_clear_attributes (GtkCellLayout *layout, | |
715 GtkCellRenderer *renderer) | |
716 { | |
717 GtkCellViewCellInfo *info; | |
718 GtkCellView *cellview = GTK_CELL_VIEW (layout); | |
719 GSList *list; | |
720 | |
721 g_return_if_fail (GTK_IS_CELL_VIEW (cellview)); | |
722 g_return_if_fail (GTK_IS_CELL_RENDERER (renderer)); | |
723 | |
724 info = gtk_cell_view_get_cell_info (cellview, renderer); | |
725 if (info != NULL) | |
726 { | |
727 list = info->attributes; | |
728 while (list && list->next) | |
729 { | |
730 g_free (list->data); | |
731 list = list->next->next; | |
732 } | |
733 | |
734 g_slist_free (info->attributes); | |
735 info->attributes = NULL; | |
736 } | |
737 } | |
738 | |
739 static void | |
740 gtk_cell_view_cell_layout_reorder (GtkCellLayout *layout, | |
741 GtkCellRenderer *cell, | |
742 gint position) | |
743 { | |
744 GList *link; | |
745 GtkCellViewCellInfo *info; | |
746 GtkCellView *cellview = GTK_CELL_VIEW (layout); | |
747 | |
748 g_return_if_fail (GTK_IS_CELL_VIEW (cellview)); | |
749 g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); | |
750 | |
751 info = gtk_cell_view_get_cell_info (cellview, cell); | |
752 | |
753 g_return_if_fail (info != NULL); | |
754 g_return_if_fail (position >= 0); | |
755 | |
756 link = g_list_find (cellview->priv->cell_list, info); | |
757 | |
758 g_return_if_fail (link != NULL); | |
759 | |
760 cellview->priv->cell_list = g_list_remove_link (cellview->priv->cell_list, | |
761 link); | |
762 cellview->priv->cell_list = g_list_insert (cellview->priv->cell_list, | |
763 info, position); | |
764 | |
765 gtk_widget_queue_draw (GTK_WIDGET (cellview)); | |
766 } | |
767 | |
768 /* public API */ | |
769 GtkWidget * | |
770 gtk_cell_view_new (void) | |
771 { | |
772 GtkCellView *cellview; | |
773 | |
774 cellview = GTK_CELL_VIEW (g_object_new (gtk_cell_view_get_type (), NULL)); | |
775 | |
776 return GTK_WIDGET (cellview); | |
777 } | |
778 | |
779 GtkWidget * | |
780 gtk_cell_view_new_with_text (const gchar *text) | |
781 { | |
782 GtkCellView *cellview; | |
783 GtkCellRenderer *renderer; | |
784 GValue value = {0, }; | |
785 | |
786 cellview = GTK_CELL_VIEW (gtk_cell_view_new ()); | |
787 | |
788 renderer = gtk_cell_renderer_text_new (); | |
789 gtk_cell_view_cell_layout_pack_start (GTK_CELL_LAYOUT (cellview), | |
790 renderer, TRUE); | |
791 | |
792 g_value_init (&value, G_TYPE_STRING); | |
793 g_value_set_string (&value, text); | |
794 gtk_cell_view_set_values (cellview, renderer, "text", &value, NULL); | |
795 g_value_unset (&value); | |
796 | |
797 return GTK_WIDGET (cellview); | |
798 } | |
799 | |
800 GtkWidget * | |
801 gtk_cell_view_new_with_markup (const gchar *markup) | |
802 { | |
803 GtkCellView *cellview; | |
804 GtkCellRenderer *renderer; | |
805 GValue value = {0, }; | |
806 | |
807 cellview = GTK_CELL_VIEW (gtk_cell_view_new ()); | |
808 | |
809 renderer = gtk_cell_renderer_text_new (); | |
810 gtk_cell_view_cell_layout_pack_start (GTK_CELL_LAYOUT (cellview), | |
811 renderer, TRUE); | |
812 | |
813 g_value_init (&value, G_TYPE_STRING); | |
814 g_value_set_string (&value, markup); | |
815 gtk_cell_view_set_values (cellview, renderer, "markup", &value, NULL); | |
816 g_value_unset (&value); | |
817 | |
818 return GTK_WIDGET (cellview); | |
819 } | |
820 | |
821 GtkWidget * | |
822 gtk_cell_view_new_with_pixbuf (GdkPixbuf *pixbuf) | |
823 { | |
824 GtkCellView *cellview; | |
825 GtkCellRenderer *renderer; | |
826 GValue value = {0, }; | |
827 | |
828 cellview = GTK_CELL_VIEW (gtk_cell_view_new ()); | |
829 | |
830 renderer = gtk_cell_renderer_pixbuf_new (); | |
831 gtk_cell_view_cell_layout_pack_start (GTK_CELL_LAYOUT (cellview), | |
832 renderer, TRUE); | |
833 | |
834 g_value_init (&value, GDK_TYPE_PIXBUF); | |
835 g_value_set_object (&value, pixbuf); | |
836 gtk_cell_view_set_values (cellview, renderer, "pixbuf", &value, NULL); | |
837 g_value_unset (&value); | |
838 | |
839 return GTK_WIDGET (cellview); | |
840 } | |
841 | |
842 void | |
843 gtk_cell_view_set_value (GtkCellView *cell_view, | |
844 GtkCellRenderer *renderer, | |
845 gchar *property, | |
846 GValue *value) | |
847 { | |
848 g_return_if_fail (GTK_IS_CELL_VIEW (cell_view)); | |
849 g_return_if_fail (GTK_IS_CELL_RENDERER (renderer)); | |
850 | |
851 g_object_set_property (G_OBJECT (renderer), property, value); | |
852 | |
853 /* force resize and redraw */ | |
854 gtk_widget_queue_resize (GTK_WIDGET (cell_view)); | |
855 gtk_widget_queue_draw (GTK_WIDGET (cell_view)); | |
856 } | |
857 | |
858 static void | |
859 gtk_cell_view_set_valuesv (GtkCellView *cell_view, | |
860 GtkCellRenderer *renderer, | |
861 va_list args) | |
862 { | |
863 gchar *attribute; | |
864 GValue *value; | |
865 | |
866 attribute = va_arg (args, gchar *); | |
867 | |
868 while (attribute) | |
869 { | |
870 value = va_arg (args, GValue *); | |
871 gtk_cell_view_set_value (cell_view, renderer, attribute, value); | |
872 attribute = va_arg (args, gchar *); | |
873 } | |
874 } | |
875 | |
876 void | |
877 gtk_cell_view_set_values (GtkCellView *cell_view, | |
878 GtkCellRenderer *renderer, | |
879 ...) | |
880 { | |
881 va_list args; | |
882 | |
883 g_return_if_fail (GTK_IS_CELL_VIEW (cell_view)); | |
884 g_return_if_fail (GTK_IS_CELL_RENDERER (renderer)); | |
885 g_return_if_fail (gtk_cell_view_get_cell_info (cell_view, renderer)); | |
886 | |
887 va_start (args, renderer); | |
888 gtk_cell_view_set_valuesv (cell_view, renderer, args); | |
889 va_end (args); | |
890 } | |
891 | |
892 void | |
893 gtk_cell_view_set_model (GtkCellView *cell_view, | |
894 GtkTreeModel *model) | |
895 { | |
896 g_return_if_fail (GTK_IS_CELL_VIEW (cell_view)); | |
897 g_return_if_fail (GTK_IS_TREE_MODEL (model)); | |
898 | |
899 if (cell_view->priv->model) | |
900 { | |
901 if (cell_view->priv->displayed_row) | |
902 gtk_tree_row_reference_free (cell_view->priv->displayed_row); | |
903 cell_view->priv->displayed_row = NULL; | |
904 | |
905 g_object_unref (G_OBJECT (cell_view->priv->model)); | |
906 cell_view->priv->model = NULL; | |
907 } | |
908 | |
909 cell_view->priv->model = model; | |
910 | |
911 if (cell_view->priv->model) | |
912 g_object_ref (G_OBJECT (cell_view->priv->model)); | |
913 } | |
914 | |
915 /** | |
916 * gtk_cell_view_set_displayed_row: | |
917 * @cell_view: a #GtkCellView | |
918 * @path: a #GtkTreePath or %NULL to unset. | |
919 * | |
920 * Sets the row of the model that is currently displayed | |
921 * by the #GtkCellView. If the path is unset, then the | |
922 * contents of the cellview "stick" at their last value; | |
923 * this is not normally a desired result, but may be | |
924 * a needed intermediate state if say, the model for | |
925 * the #GtkCellView becomes temporarily empty. | |
926 **/ | |
927 void | |
928 gtk_cell_view_set_displayed_row (GtkCellView *cell_view, | |
929 GtkTreePath *path) | |
930 { | |
931 g_return_if_fail (GTK_IS_CELL_VIEW (cell_view)); | |
932 g_return_if_fail (GTK_IS_TREE_MODEL (cell_view->priv->model)); | |
933 | |
934 if (cell_view->priv->displayed_row) | |
935 gtk_tree_row_reference_free (cell_view->priv->displayed_row); | |
936 | |
937 if (path) | |
938 { | |
939 cell_view->priv->displayed_row = | |
940 gtk_tree_row_reference_new (cell_view->priv->model, path); | |
941 } | |
942 else | |
943 cell_view->priv->displayed_row = NULL; | |
944 | |
945 /* force resize and redraw */ | |
946 gtk_widget_queue_resize (GTK_WIDGET (cell_view)); | |
947 gtk_widget_queue_draw (GTK_WIDGET (cell_view)); | |
948 } | |
949 | |
950 GtkTreePath * | |
951 gtk_cell_view_get_displayed_row (GtkCellView *cell_view) | |
952 { | |
953 g_return_val_if_fail (GTK_IS_CELL_VIEW (cell_view), NULL); | |
954 | |
955 if (!cell_view->priv->displayed_row) | |
956 return NULL; | |
957 | |
958 return gtk_tree_row_reference_get_path (cell_view->priv->displayed_row); | |
959 } | |
960 | |
961 gboolean | |
962 gtk_cell_view_get_size_of_row (GtkCellView *cell_view, | |
963 GtkTreePath *path, | |
964 GtkRequisition *requisition) | |
965 { | |
966 GtkTreeRowReference *tmp; | |
967 GtkRequisition req; | |
968 | |
969 g_return_val_if_fail (GTK_IS_CELL_VIEW (cell_view), FALSE); | |
970 g_return_val_if_fail (path != NULL, FALSE); | |
971 g_return_val_if_fail (requisition != NULL, FALSE); | |
972 | |
973 tmp = cell_view->priv->displayed_row; | |
974 cell_view->priv->displayed_row = | |
975 gtk_tree_row_reference_new (cell_view->priv->model, path); | |
976 | |
977 gtk_cell_view_size_request (GTK_WIDGET (cell_view), requisition); | |
978 | |
979 gtk_tree_row_reference_free (cell_view->priv->displayed_row); | |
980 cell_view->priv->displayed_row = tmp; | |
981 | |
982 /* restore actual size info */ | |
983 gtk_cell_view_size_request (GTK_WIDGET (cell_view), &req); | |
984 | |
985 return TRUE; | |
986 } | |
987 | |
988 void | |
989 gtk_cell_view_set_background_color (GtkCellView *view, | |
990 const GdkColor *color) | |
991 { | |
992 g_return_if_fail (GTK_IS_CELL_VIEW (view)); | |
993 | |
994 if (color) | |
995 { | |
996 if (!view->priv->background_set) | |
997 { | |
998 view->priv->background_set = TRUE; | |
999 g_object_notify (G_OBJECT (view), "background_set"); | |
1000 } | |
1001 | |
1002 view->priv->background = *color; | |
1003 } | |
1004 else | |
1005 { | |
1006 if (view->priv->background_set) | |
1007 { | |
1008 view->priv->background_set = FALSE; | |
1009 g_object_notify (G_OBJECT (view), "background_set"); | |
1010 } | |
1011 } | |
1012 } | |
1013 #endif /* Gtk 2.6 */ |