]> Pileus Git - ~andy/gtk/blob - gtk/gtkcellrenderer.c
f468247a6b1977e95cf87e71b1cbcf37facfc149
[~andy/gtk] / gtk / gtkcellrenderer.c
1 /* gtkcellrenderer.c
2  * Copyright (C) 2000  Red Hat, Inc. Jonathan Blandford
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 #include "gtkcellrenderer.h"
21 #include "gtkintl.h"
22
23 static void gtk_cell_renderer_init       (GtkCellRenderer      *cell);
24 static void gtk_cell_renderer_class_init (GtkCellRendererClass *class);
25 static void gtk_cell_renderer_get_property  (GObject              *object,
26                                              guint                 param_id,
27                                              GValue               *value,
28                                              GParamSpec           *pspec);
29 static void gtk_cell_renderer_set_property  (GObject              *object,
30                                              guint                 param_id,
31                                              const GValue         *value,
32                                              GParamSpec           *pspec);
33
34
35 enum {
36   PROP_ZERO,
37   PROP_MODE,
38   PROP_VISIBLE,
39   PROP_XALIGN,
40   PROP_YALIGN,
41   PROP_XPAD,
42   PROP_YPAD,
43   PROP_WIDTH,
44   PROP_HEIGHT,
45   PROP_IS_EXPANDER,
46   PROP_IS_EXPANDED,
47 };
48
49
50 GtkType
51 gtk_cell_renderer_get_type (void)
52 {
53   static GtkType cell_type = 0;
54
55   if (!cell_type)
56     {
57       static const GTypeInfo cell_info =
58       {
59         sizeof (GtkCellRendererClass),
60         NULL,           /* base_init */
61         NULL,           /* base_finalize */
62         (GClassInitFunc) gtk_cell_renderer_class_init,
63         NULL,           /* class_finalize */
64         NULL,           /* class_data */
65         sizeof (GtkCellRenderer),
66         0,
67         (GInstanceInitFunc) gtk_cell_renderer_init,
68       };
69
70       cell_type = g_type_register_static (GTK_TYPE_OBJECT, "GtkCellRenderer", &cell_info, 0);
71     }
72
73   return cell_type;
74 }
75
76 static void
77 gtk_cell_renderer_init (GtkCellRenderer *cell)
78 {
79   cell->mode = GTK_CELL_RENDERER_MODE_INERT;
80   cell->visible = TRUE;
81   cell->width = -1;
82   cell->height = -1;
83   cell->xalign = 0.5;
84   cell->yalign = 0.5;
85   cell->xpad = 0;
86   cell->ypad = 0;
87 }
88
89 static void
90 gtk_cell_renderer_class_init (GtkCellRendererClass *class)
91 {
92   GObjectClass *object_class = G_OBJECT_CLASS (class);
93
94   object_class->get_property = gtk_cell_renderer_get_property;
95   object_class->set_property = gtk_cell_renderer_set_property;
96
97   class->render = NULL;
98   class->get_size = NULL;
99
100   g_object_class_install_property (object_class,
101                                    PROP_MODE,
102                                    g_param_spec_enum ("mode",
103                                                       _("mode"),
104                                                       _("Editable mode of the CellRenderer"),
105                                                       GTK_TYPE_CELL_RENDERER_MODE,
106                                                       GTK_CELL_RENDERER_MODE_INERT,
107                                                       G_PARAM_READABLE |
108                                                       G_PARAM_WRITABLE));
109
110   g_object_class_install_property (object_class,
111                                    PROP_VISIBLE,
112                                    g_param_spec_boolean ("visible",
113                                                          _("visible"),
114                                                          _("Display the cell"),
115                                                          TRUE,
116                                                          G_PARAM_READABLE |
117                                                          G_PARAM_WRITABLE));
118
119   g_object_class_install_property (object_class,
120                                    PROP_XALIGN,
121                                    g_param_spec_float ("xalign",
122                                                        _("xalign"),
123                                                        _("The x-align."),
124                                                        0.0,
125                                                        1.0,
126                                                        0.0,
127                                                        G_PARAM_READABLE |
128                                                        G_PARAM_WRITABLE));
129
130   g_object_class_install_property (object_class,
131                                    PROP_YALIGN,
132                                    g_param_spec_float ("yalign",
133                                                        _("yalign"),
134                                                        _("The y-align."),
135                                                        0.0,
136                                                        1.0,
137                                                        0.5,
138                                                        G_PARAM_READABLE |
139                                                        G_PARAM_WRITABLE));
140
141   g_object_class_install_property (object_class,
142                                    PROP_XPAD,
143                                    g_param_spec_uint ("xpad",
144                                                       _("xpad"),
145                                                       _("The xpad."),
146                                                       0,
147                                                       100,
148                                                       2,
149                                                       G_PARAM_READABLE |
150                                                       G_PARAM_WRITABLE));
151
152   g_object_class_install_property (object_class,
153                                    PROP_YPAD,
154                                    g_param_spec_uint ("ypad",
155                                                       _("ypad"),
156                                                       _("The ypad."),
157                                                       0,
158                                                       100,
159                                                       2,
160                                                       G_PARAM_READABLE |
161                                                       G_PARAM_WRITABLE));
162
163   g_object_class_install_property (object_class,
164                                    PROP_WIDTH,
165                                    g_param_spec_int ("width",
166                                                      _("width"),
167                                                      _("The fixed width."),
168                                                      -1,
169                                                      100,
170                                                      -1,
171                                                      G_PARAM_READABLE |
172                                                      G_PARAM_WRITABLE));
173
174   g_object_class_install_property (object_class,
175                                    PROP_HEIGHT,
176                                    g_param_spec_int ("height",
177                                                      _("height"),
178                                                      _("The fixed height."),
179                                                      -1,
180                                                      100,
181                                                      -1,
182                                                      G_PARAM_READABLE |
183                                                      G_PARAM_WRITABLE));
184
185   g_object_class_install_property (object_class,
186                                    PROP_IS_EXPANDER,
187                                    g_param_spec_boolean ("is_expander",
188                                                          _("Is Expander"),
189                                                          _("Row has children."),
190                                                          FALSE,
191                                                          G_PARAM_READABLE |
192                                                          G_PARAM_WRITABLE));
193
194
195   g_object_class_install_property (object_class,
196                                    PROP_IS_EXPANDED,
197                                    g_param_spec_boolean ("is_expanded",
198                                                          _("Is Expanded"),
199                                                          _("Row is an expander row, and is expanded"),
200                                                          FALSE,
201                                                          G_PARAM_READABLE |
202                                                          G_PARAM_WRITABLE));
203 }
204
205 static void
206 gtk_cell_renderer_get_property (GObject     *object,
207                                 guint        param_id,
208                                 GValue      *value,
209                                 GParamSpec  *pspec)
210 {
211   GtkCellRenderer *cell = GTK_CELL_RENDERER (object);
212
213   switch (param_id)
214     {
215     case PROP_MODE:
216       g_value_set_enum (value, cell->mode);
217       break;
218     case PROP_VISIBLE:
219       g_value_set_boolean (value, cell->visible);
220       break;
221     case PROP_XALIGN:
222       g_value_set_float (value, cell->xalign);
223       break;
224     case PROP_YALIGN:
225       g_value_set_float (value, cell->yalign);
226       break;
227     case PROP_XPAD:
228       g_value_set_uint (value, cell->xpad);
229       break;
230     case PROP_YPAD:
231       g_value_set_uint (value, cell->ypad);
232       break;
233     case PROP_WIDTH:
234       g_value_set_int (value, cell->width);
235       break;
236     case PROP_HEIGHT:
237       g_value_set_int (value, cell->height);
238       break;
239     case PROP_IS_EXPANDER:
240       g_value_set_int (value, cell->is_expander);
241       break;
242     case PROP_IS_EXPANDED:
243       g_value_set_int (value, cell->is_expanded);
244       break;
245     default:
246       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
247       break;
248     }
249
250 }
251
252 static void
253 gtk_cell_renderer_set_property (GObject      *object,
254                                 guint         param_id,
255                                 const GValue *value,
256                                 GParamSpec   *pspec)
257 {
258   GtkCellRenderer *cell = GTK_CELL_RENDERER (object);
259
260   switch (param_id)
261     {
262     case PROP_MODE:
263       cell->mode = g_value_get_enum (value);
264       g_object_notify (object, "mode");
265       break;
266     case PROP_VISIBLE:
267       cell->visible = g_value_get_boolean (value);
268       g_object_notify (object, "visible");
269       break;
270     case PROP_XALIGN:
271       cell->xalign = g_value_get_float (value);
272       g_object_notify (object, "xalign");
273       break;
274     case PROP_YALIGN:
275       cell->yalign = g_value_get_float (value);
276       g_object_notify (object, "yalign");
277       break;
278     case PROP_XPAD:
279       cell->xpad = g_value_get_uint (value);
280       g_object_notify (object, "xpad");
281       break;
282     case PROP_YPAD:
283       cell->ypad = g_value_get_uint (value);
284       g_object_notify (object, "ypad");
285       break;
286     case PROP_WIDTH:
287       cell->width = g_value_get_int (value);
288       g_object_notify (object, "width");
289       break;
290     case PROP_HEIGHT:
291       cell->height = g_value_get_int (value);
292       g_object_notify (object, "height");
293       break;
294     case PROP_IS_EXPANDER:
295       cell->is_expander = g_value_get_boolean (value);
296       g_object_notify (object, "is_expander");
297       break;
298     case PROP_IS_EXPANDED:
299       cell->is_expanded = g_value_get_boolean (value);
300       g_object_notify (object, "is_expanded");
301       break;
302     default:
303       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
304       break;
305     }
306 }
307
308 /**
309  * gtk_cell_renderer_get_size:
310  * @cell: a #GtkCellRenderer
311  * @widget: the widget the renderer is rendering to
312  * @cell_area: The area a cell will be allocated, or %NULL
313  * @x_offset: location to return x offset of cell relative to @cell_area, or %NULL
314  * @y_offset: location to return y offset of cell relative to @cell_area, or %NULL
315  * @width: location to return width needed to render a cell, or %NULL
316  * @height: location to return height needed to render a cell, or %NULL
317  *
318  * Obtains the width and height needed to render the cell. Used by view widgets
319  * to determine the appropriate size for the cell_area passed to
320  * gtk_cell_renderer_render().  If @cell_area is not %NULL, fills in the x and y
321  * offsets (if set) of the cell relative to this location.
322  **/
323 void
324 gtk_cell_renderer_get_size (GtkCellRenderer *cell,
325                             GtkWidget       *widget,
326                             GdkRectangle    *cell_area,
327                             gint            *x_offset,
328                             gint            *y_offset,
329                             gint            *width,
330                             gint            *height)
331 {
332   gint *real_width = NULL;
333   gint *real_height = NULL;
334
335   g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
336   g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->get_size != NULL);
337
338   if (width)
339     {
340       if (cell->width == -1)
341         real_width = width;
342       else
343         *width = cell->width;
344     }
345   if (height)
346     {
347       if (cell->height == -1)
348         real_height = height;
349       else
350         *height = cell->height;
351     }
352
353   if (real_width || real_height)
354     GTK_CELL_RENDERER_GET_CLASS (cell)->get_size (cell, widget, cell_area, x_offset, y_offset, real_width, real_height);
355 }
356
357 /**
358  * gtk_cell_renderer_render:
359  * @cell: a #GtkCellRenderer
360  * @window: a #GdkDrawable to draw to
361  * @widget: the widget owning @window
362  * @background_area: entire cell area (including tree expanders and maybe padding on the sides)
363  * @cell_area: area normally rendered by a cell renderer
364  * @expose_area: area that actually needs updating
365  * @flags: flags that affect rendering
366  *
367  * Invokes the virtual render function of the #GtkCellRenderer. The
368  * three passed-in rectangles are areas of @window. Most renderers
369  * will draw to @cell_area; the xalign, yalign, xpad, and ypad fields
370  * of the #GtkCellRenderer should be honored with respect to
371  * @cell_area. @background_area includes the blank space around the
372  * cell, and also the area containing the tree expander; so the
373  * @background_area rectangles for all cells tile to cover the entire
374  * @window. Cell renderers can use the @background_area to draw custom expanders, for
375  * example. @expose_area is a clip rectangle.
376  *
377  **/
378 void
379 gtk_cell_renderer_render (GtkCellRenderer     *cell,
380                           GdkWindow           *window,
381                           GtkWidget           *widget,
382                           GdkRectangle        *background_area,
383                           GdkRectangle        *cell_area,
384                           GdkRectangle        *expose_area,
385                           GtkCellRendererState flags)
386 {
387   /* It's actually okay to pass in a NULL cell, as we run into that
388    * a lot
389    */
390   if (cell == NULL)
391     return;
392   g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
393   g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->render != NULL);
394
395   GTK_CELL_RENDERER_GET_CLASS (cell)->render (cell,
396                                               window,
397                                               widget,
398                                               background_area,
399                                               cell_area,
400                                               expose_area,
401                                               flags);
402 }
403
404 /**
405  * gtk_cell_renderer_activate:
406  * @cell: a #GtkCellRenderer
407  * @event: a #GdkEvent
408  * @widget: widget that received the event
409  * @path: widget-dependent string representation of the event location; e.g. for #GtkTreeView, a string representation of #GtkTreePath
410  * @background_area: background area as passed to gtk_cell_renderer_render()
411  * @cell_area: cell area as passed to gtk_cell_renderer_render()
412  * @flags: render flags
413  *
414  * Passes an activate event to the cell renderer for possible processing.  Some
415  * cell renderers may use events; for example, #GtkCellRendererToggle toggles
416  * when it gets a mouse click.
417  *
418  * Return value: %TRUE if the event was consumed/handled
419  **/
420 gboolean
421 gtk_cell_renderer_activate (GtkCellRenderer      *cell,
422                             GdkEvent             *event,
423                             GtkWidget            *widget,
424                             gchar                *path,
425                             GdkRectangle         *background_area,
426                             GdkRectangle         *cell_area,
427                             GtkCellRendererState  flags)
428 {
429   g_return_val_if_fail (GTK_IS_CELL_RENDERER (cell), FALSE);
430
431   if (cell->mode != GTK_CELL_RENDERER_MODE_ACTIVATABLE)
432     return FALSE;
433
434   if (GTK_CELL_RENDERER_GET_CLASS (cell)->activate == NULL)
435     return FALSE;
436
437   return GTK_CELL_RENDERER_GET_CLASS (cell)->activate (cell,
438                                                        event,
439                                                        widget,
440                                                        path,
441                                                        background_area,
442                                                        cell_area,
443                                                        flags);
444 }
445
446
447 /**
448  * gtk_cell_renderer_start_editing:
449  * @cell: a #GtkCellRenderer
450  * @event: a #GdkEvent
451  * @widget: widget that received the event
452  * @path: widget-dependent string representation of the event location; e.g. for #GtkTreeView, a string representation of #GtkTreePath
453  * @background_area: background area as passed to gtk_cell_renderer_render()
454  * @cell_area: cell area as passed to gtk_cell_renderer_render()
455  * @flags: render flags
456  * 
457  * Passes an activate event to the cell renderer for possible processing.
458  * 
459  * Return value: A new #GtkCellEditable, or %NULL
460  **/
461 GtkCellEditable *
462 gtk_cell_renderer_start_editing (GtkCellRenderer      *cell,
463                                  GdkEvent             *event,
464                                  GtkWidget            *widget,
465                                  gchar                *path,
466                                  GdkRectangle         *background_area,
467                                  GdkRectangle         *cell_area,
468                                  GtkCellRendererState  flags)
469
470 {
471   g_return_val_if_fail (GTK_IS_CELL_RENDERER (cell), NULL);
472
473   if (cell->mode != GTK_CELL_RENDERER_MODE_EDITABLE)
474     return NULL;
475
476   if (GTK_CELL_RENDERER_GET_CLASS (cell)->start_editing == NULL)
477     return NULL;
478
479   
480   return GTK_CELL_RENDERER_GET_CLASS (cell)->start_editing (cell,
481                                                             event,
482                                                             widget,
483                                                             path,
484                                                             background_area,
485                                                             cell_area,
486                                                             flags);
487 }
488
489 /**
490  * gtk_cell_renderer_set_fixed_size:
491  * @cell: A #GtkCellRenderer
492  * @width: the width of the cell renderer, or -1
493  * @height: the height of the cell renderer, or -1
494  * 
495  * Sets the renderer size to be explicit, independent of the properties set.
496  **/
497 void
498 gtk_cell_renderer_set_fixed_size (GtkCellRenderer *cell,
499                                   gint             width,
500                                   gint             height)
501 {
502   g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
503   g_return_if_fail (width >= -1 && height >= -1);
504
505   if ((width != cell->width) || (height != cell->height))
506     {
507       g_object_freeze_notify (G_OBJECT (cell));
508
509       if (width != cell->width)
510         {
511           cell->width = width;
512           g_object_notify (G_OBJECT (cell), "width");
513         }
514
515       if (height != cell->height)
516         {
517           cell->height = height;
518           g_object_notify (G_OBJECT (cell), "height");
519         }
520
521       g_object_thaw_notify (G_OBJECT (cell));
522     }
523 }
524
525 /**
526  * gtk_cell_renderer_get_fixed_size:
527  * @cell: A #GtkCellRenderer
528  * @width: location to fill in with the fixed width of the widget, or %NULL
529  * @height: location to fill in with the fixed height of the widget, or %NULL
530  * 
531  * Fills in @width and @height with the appropriate size of @cell.
532  **/
533 void
534 gtk_cell_renderer_get_fixed_size (GtkCellRenderer *cell,
535                                   gint            *width,
536                                   gint            *height)
537 {
538   g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
539
540   if (width)
541     (* width) = cell->width;
542   if (height)
543     (* height) = cell->height;
544 }