]> Pileus Git - ~andy/gtk/blob - gtk/gtkcellrenderer.c
8b1396622678f441067c380f4b14a5a653f43637
[~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       break;
265     case PROP_VISIBLE:
266       cell->visible = g_value_get_boolean (value);
267       break;
268     case PROP_XALIGN:
269       cell->xalign = g_value_get_float (value);
270       break;
271     case PROP_YALIGN:
272       cell->yalign = g_value_get_float (value);
273       break;
274     case PROP_XPAD:
275       cell->xpad = g_value_get_uint (value);
276       break;
277     case PROP_YPAD:
278       cell->ypad = g_value_get_uint (value);
279       break;
280     case PROP_WIDTH:
281       cell->width = g_value_get_int (value);
282       break;
283     case PROP_HEIGHT:
284       cell->height = g_value_get_int (value);
285       break;
286     case PROP_IS_EXPANDER:
287       cell->is_expander = g_value_get_boolean (value);
288       break;
289     case PROP_IS_EXPANDED:
290       cell->is_expanded = g_value_get_boolean (value);
291       break;
292     default:
293       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
294       break;
295     }
296 }
297
298 /**
299  * gtk_cell_renderer_get_size:
300  * @cell: a #GtkCellRenderer
301  * @widget: the widget the renderer is rendering to
302  * @cell_area: The area a cell will be allocated, or %NULL
303  * @x_offset: location to return x offset of cell relative to @cell_area, or %NULL
304  * @y_offset: location to return y offset of cell relative to @cell_area, or %NULL
305  * @width: location to return width needed to render a cell, or %NULL
306  * @height: location to return height needed to render a cell, or %NULL
307  *
308  * Obtains the width and height needed to render the cell. Used by view widgets
309  * to determine the appropriate size for the cell_area passed to
310  * gtk_cell_renderer_render().  If @cell_area is not %NULL, fills in the x and y
311  * offsets (if set) of the cell relative to this location.  Please note that the
312  * values set in @width and @height, as well as those in @x_offset and @y_offset
313  * are inclusive of the xpad and ypad properties.
314  **/
315 void
316 gtk_cell_renderer_get_size (GtkCellRenderer *cell,
317                             GtkWidget       *widget,
318                             GdkRectangle    *cell_area,
319                             gint            *x_offset,
320                             gint            *y_offset,
321                             gint            *width,
322                             gint            *height)
323 {
324   gint *real_width = width;
325   gint *real_height = height;
326
327   g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
328   g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->get_size != NULL);
329
330   if (width && cell->width != -1)
331     {
332       real_width = NULL;
333       *width = cell->width;
334     }
335   if (height && cell->height != -1)
336     {
337       real_height = NULL;
338       *height = cell->height;
339     }
340
341   GTK_CELL_RENDERER_GET_CLASS (cell)->get_size (cell, widget, cell_area, x_offset, y_offset, real_width, real_height);
342 }
343
344 /**
345  * gtk_cell_renderer_render:
346  * @cell: a #GtkCellRenderer
347  * @window: a #GdkDrawable to draw to
348  * @widget: the widget owning @window
349  * @background_area: entire cell area (including tree expanders and maybe padding on the sides)
350  * @cell_area: area normally rendered by a cell renderer
351  * @expose_area: area that actually needs updating
352  * @flags: flags that affect rendering
353  *
354  * Invokes the virtual render function of the #GtkCellRenderer. The three
355  * passed-in rectangles are areas of @window. Most renderers will draw within
356  * @cell_area; the xalign, yalign, xpad, and ypad fields of the #GtkCellRenderer
357  * should be honored with respect to @cell_area. @background_area includes the
358  * blank space around the cell, and also the area containing the tree expander;
359  * so the @background_area rectangles for all cells tile to cover the entire
360  * @window.  @expose_area is a clip rectangle.
361  *
362  **/
363 void
364 gtk_cell_renderer_render (GtkCellRenderer     *cell,
365                           GdkWindow           *window,
366                           GtkWidget           *widget,
367                           GdkRectangle        *background_area,
368                           GdkRectangle        *cell_area,
369                           GdkRectangle        *expose_area,
370                           GtkCellRendererState flags)
371 {
372   g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
373   g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->render != NULL);
374
375   GTK_CELL_RENDERER_GET_CLASS (cell)->render (cell,
376                                               window,
377                                               widget,
378                                               background_area,
379                                               cell_area,
380                                               expose_area,
381                                               flags);
382 }
383
384 /**
385  * gtk_cell_renderer_activate:
386  * @cell: a #GtkCellRenderer
387  * @event: a #GdkEvent
388  * @widget: widget that received the event
389  * @path: widget-dependent string representation of the event location; e.g. for #GtkTreeView, a string representation of #GtkTreePath
390  * @background_area: background area as passed to @gtk_cell_renderer_render
391  * @cell_area: cell area as passed to @gtk_cell_renderer_render
392  * @flags: render flags
393  *
394  * Passes an activate event to the cell renderer for possible processing.  Some
395  * cell renderers may use events; for example, #GtkCellRendererToggle toggles
396  * when it gets a mouse click.
397  *
398  * Return value: %TRUE if the event was consumed/handled
399  **/
400 gboolean
401 gtk_cell_renderer_activate (GtkCellRenderer      *cell,
402                             GdkEvent             *event,
403                             GtkWidget            *widget,
404                             const gchar          *path,
405                             GdkRectangle         *background_area,
406                             GdkRectangle         *cell_area,
407                             GtkCellRendererState  flags)
408 {
409   g_return_val_if_fail (GTK_IS_CELL_RENDERER (cell), FALSE);
410
411   if (cell->mode != GTK_CELL_RENDERER_MODE_ACTIVATABLE)
412     return FALSE;
413
414   if (GTK_CELL_RENDERER_GET_CLASS (cell)->activate == NULL)
415     return FALSE;
416
417   return GTK_CELL_RENDERER_GET_CLASS (cell)->activate (cell,
418                                                        event,
419                                                        widget,
420                                                        path,
421                                                        background_area,
422                                                        cell_area,
423                                                        flags);
424 }
425
426 /**
427  * gtk_cell_renderer_start_editing:
428  * @cell: a #GtkCellRenderer
429  * @event: a #GdkEvent
430  * @widget: widget that received the event
431  * @path: widget-dependent string representation of the event location; e.g. for #GtkTreeView, a string representation of #GtkTreePath
432  * @background_area: background area as passed to @gtk_cell_renderer_render
433  * @cell_area: cell area as passed to @gtk_cell_renderer_render
434  * @flags: render flags
435  * 
436  * Passes an activate event to the cell renderer for possible processing.
437  * 
438  * Return value: A new #GtkCellEditable, or %NULL
439  **/
440 GtkCellEditable *
441 gtk_cell_renderer_start_editing (GtkCellRenderer      *cell,
442                                  GdkEvent             *event,
443                                  GtkWidget            *widget,
444                                  const gchar          *path,
445                                  GdkRectangle         *background_area,
446                                  GdkRectangle         *cell_area,
447                                  GtkCellRendererState  flags)
448
449 {
450   g_return_val_if_fail (GTK_IS_CELL_RENDERER (cell), NULL);
451
452   if (cell->mode != GTK_CELL_RENDERER_MODE_EDITABLE)
453     return NULL;
454
455   if (GTK_CELL_RENDERER_GET_CLASS (cell)->start_editing == NULL)
456     return NULL;
457
458   
459   return GTK_CELL_RENDERER_GET_CLASS (cell)->start_editing (cell,
460                                                             event,
461                                                             widget,
462                                                             path,
463                                                             background_area,
464                                                             cell_area,
465                                                             flags);
466 }
467
468 /**
469  * gtk_cell_renderer_set_fixed_size:
470  * @cell: A #GtkCellRenderer
471  * @width: the width of the cell renderer, or -1
472  * @height: the height of the cell renderer, or -1
473  * 
474  * Sets the renderer size to be explicit, independent of the properties set.
475  **/
476 void
477 gtk_cell_renderer_set_fixed_size (GtkCellRenderer *cell,
478                                   gint             width,
479                                   gint             height)
480 {
481   g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
482   g_return_if_fail (width >= -1 && height >= -1);
483
484   if ((width != cell->width) || (height != cell->height))
485     {
486       g_object_freeze_notify (G_OBJECT (cell));
487
488       if (width != cell->width)
489         {
490           cell->width = width;
491           g_object_notify (G_OBJECT (cell), "width");
492         }
493
494       if (height != cell->height)
495         {
496           cell->height = height;
497           g_object_notify (G_OBJECT (cell), "height");
498         }
499
500       g_object_thaw_notify (G_OBJECT (cell));
501     }
502 }
503
504 /**
505  * gtk_cell_renderer_get_fixed_size:
506  * @cell: A #GtkCellRenderer
507  * @width: location to fill in with the fixed width of the widget, or %NULL
508  * @height: location to fill in with the fixed height of the widget, or %NULL
509  * 
510  * Fills in @width and @height with the appropriate size of @cell.
511  **/
512 void
513 gtk_cell_renderer_get_fixed_size (GtkCellRenderer *cell,
514                                   gint            *width,
515                                   gint            *height)
516 {
517   g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
518
519   if (width)
520     (* width) = cell->width;
521   if (height)
522     (* height) = cell->height;
523 }