]> Pileus Git - ~andy/gtk/blob - gtk/gtkcellrenderer.c
x
[~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 <config.h>
21 #include "gtkalias.h"
22 #include "gtkcellrenderer.h"
23 #include "gtkintl.h"
24 #include "gtkmarshalers.h"
25 #include "gtktreeprivate.h"
26
27 static void gtk_cell_renderer_init       (GtkCellRenderer      *cell);
28 static void gtk_cell_renderer_class_init (GtkCellRendererClass *class);
29 static void gtk_cell_renderer_get_property  (GObject              *object,
30                                              guint                 param_id,
31                                              GValue               *value,
32                                              GParamSpec           *pspec);
33 static void gtk_cell_renderer_set_property  (GObject              *object,
34                                              guint                 param_id,
35                                              const GValue         *value,
36                                              GParamSpec           *pspec);
37 static void set_cell_bg_color               (GtkCellRenderer      *cell,
38                                              GdkColor             *color);
39
40
41 #define GTK_CELL_RENDERER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_CELL_RENDERER, GtkCellRendererPrivate))
42
43 typedef struct _GtkCellRendererPrivate GtkCellRendererPrivate;
44 struct _GtkCellRendererPrivate
45 {
46   GdkColor cell_background;
47 };
48
49
50 enum {
51   PROP_ZERO,
52   PROP_MODE,
53   PROP_VISIBLE,
54   PROP_SENSITIVE,
55   PROP_XALIGN,
56   PROP_YALIGN,
57   PROP_XPAD,
58   PROP_YPAD,
59   PROP_WIDTH,
60   PROP_HEIGHT,
61   PROP_IS_EXPANDER,
62   PROP_IS_EXPANDED,
63   PROP_CELL_BACKGROUND,
64   PROP_CELL_BACKGROUND_GDK,
65   PROP_CELL_BACKGROUND_SET
66 };
67
68 /* Signal IDs */
69 enum {
70   EDITING_CANCELED,
71   EDITING_STARTED,
72   LAST_SIGNAL
73 };
74
75 static guint cell_renderer_signals[LAST_SIGNAL] = { 0 };
76
77
78 GType
79 gtk_cell_renderer_get_type (void)
80 {
81   static GType cell_type = 0;
82
83   if (!cell_type)
84     {
85       static const GTypeInfo cell_info =
86       {
87         sizeof (GtkCellRendererClass),
88         NULL,           /* base_init */
89         NULL,           /* base_finalize */
90         (GClassInitFunc) gtk_cell_renderer_class_init,
91         NULL,           /* class_finalize */
92         NULL,           /* class_data */
93         sizeof (GtkCellRenderer),
94         0,              /* n_preallocs */
95         (GInstanceInitFunc) gtk_cell_renderer_init,
96         NULL,           /* value_table */
97       };
98
99       cell_type = g_type_register_static (GTK_TYPE_OBJECT, "GtkCellRenderer", 
100                                           &cell_info, G_TYPE_FLAG_ABSTRACT);
101     }
102
103   return cell_type;
104 }
105
106 static void
107 gtk_cell_renderer_init (GtkCellRenderer *cell)
108 {
109   cell->mode = GTK_CELL_RENDERER_MODE_INERT;
110   cell->visible = TRUE;
111   cell->width = -1;
112   cell->height = -1;
113   cell->xalign = 0.5;
114   cell->yalign = 0.5;
115   cell->xpad = 0;
116   cell->ypad = 0;
117   cell->sensitive = TRUE;
118   cell->is_expander = FALSE;
119   cell->is_expanded = FALSE;
120   cell->editing = FALSE;
121 }
122
123 static void
124 gtk_cell_renderer_class_init (GtkCellRendererClass *class)
125 {
126   GObjectClass *object_class = G_OBJECT_CLASS (class);
127
128   object_class->get_property = gtk_cell_renderer_get_property;
129   object_class->set_property = gtk_cell_renderer_set_property;
130
131   class->render = NULL;
132   class->get_size = NULL;
133
134   /**
135    * GtkCellRenderer::editing-canceled:
136    * @renderer: the object which received the signal
137    *
138    * This signal gets emitted when the user cancels the process of editing a
139    * cell.  For example, an editable cell renderer could be written to cancel
140    * editing when the user presses Escape. 
141    *
142    * See also: gtk_cell_renderer_editing_canceled()
143    *
144    * Since: 2.4
145    */
146   cell_renderer_signals[EDITING_CANCELED] =
147     g_signal_new ("editing-canceled",
148                   G_OBJECT_CLASS_TYPE (object_class),
149                   G_SIGNAL_RUN_FIRST,
150                   G_STRUCT_OFFSET (GtkCellRendererClass, editing_canceled),
151                   NULL, NULL,
152                   _gtk_marshal_VOID__VOID,
153                   G_TYPE_NONE, 0);
154
155   /**
156    * GtkCellRenderer::editing-started:
157    * @renderer: the object which received the signal
158    * @editable: the #GtkCellEditable
159    * @path: the path identifying the edited cell
160    *
161    * This signal gets emitted when a cell starts to be edited.
162    * The indended use of this signal is to do special setup
163    * on @editable, e.g. adding a #GtkEntryCompletion or setting
164    * up additional columns in a #GtkComboBox.
165    *
166    * Note that GTK+ doesn't guarantee that cell renderers will
167    * continue to use the same kind of widget for editing in future
168    * releases, therefore you should check the type of @editable
169    * before doing any specific setup, as in the following example:
170    *
171    * <informalexample><programlisting>
172    * static void
173    * text_editing_started (GtkCellRenderer *cell,
174    *                       GtkCellEditable *editable,
175    *                       const gchar     *path,
176    *                       gpointer         data)
177    * {
178    *   if (GTK_IS_ENTRY (editable)) 
179    *     {
180    *       GtkEntry *entry = GTK_ENTRY (editable);
181    *       <!-- -->
182    *       /<!-- -->* ... create a GtkEntryCompletion *<!-- -->/
183    *       <!-- -->
184    *       gtk_entry_set_completion (entry, completion);
185    *     }
186    * }
187    * </programlisting></informalexample>
188    *
189    * Since: 2.6
190    */
191   cell_renderer_signals[EDITING_STARTED] =
192     g_signal_new ("editing-started",
193                   G_OBJECT_CLASS_TYPE (object_class),
194                   G_SIGNAL_RUN_FIRST,
195                   G_STRUCT_OFFSET (GtkCellRendererClass, editing_started),
196                   NULL, NULL,
197                   _gtk_marshal_VOID__OBJECT_STRING,
198                   G_TYPE_NONE, 2,
199                   GTK_TYPE_CELL_EDITABLE,
200                   G_TYPE_STRING);
201
202   g_object_class_install_property (object_class,
203                                    PROP_MODE,
204                                    g_param_spec_enum ("mode",
205                                                       P_("mode"),
206                                                       P_("Editable mode of the CellRenderer"),
207                                                       GTK_TYPE_CELL_RENDERER_MODE,
208                                                       GTK_CELL_RENDERER_MODE_INERT,
209                                                       G_PARAM_READABLE |
210                                                       G_PARAM_WRITABLE));
211
212   g_object_class_install_property (object_class,
213                                    PROP_VISIBLE,
214                                    g_param_spec_boolean ("visible",
215                                                          P_("visible"),
216                                                          P_("Display the cell"),
217                                                          TRUE,
218                                                          G_PARAM_READWRITE));
219   g_object_class_install_property (object_class,
220                                    PROP_SENSITIVE,
221                                    g_param_spec_boolean ("sensitive",
222                                                          P_("Sensitive"),
223                                                          P_("Display the cell sensitive"),
224                                                          TRUE,
225                                                          G_PARAM_READWRITE));
226
227   g_object_class_install_property (object_class,
228                                    PROP_XALIGN,
229                                    g_param_spec_float ("xalign",
230                                                        P_("xalign"),
231                                                        P_("The x-align"),
232                                                        0.0,
233                                                        1.0,
234                                                        0.5,
235                                                        G_PARAM_READABLE |
236                                                        G_PARAM_WRITABLE));
237
238   g_object_class_install_property (object_class,
239                                    PROP_YALIGN,
240                                    g_param_spec_float ("yalign",
241                                                        P_("yalign"),
242                                                        P_("The y-align"),
243                                                        0.0,
244                                                        1.0,
245                                                        0.5,
246                                                        G_PARAM_READABLE |
247                                                        G_PARAM_WRITABLE));
248
249   g_object_class_install_property (object_class,
250                                    PROP_XPAD,
251                                    g_param_spec_uint ("xpad",
252                                                       P_("xpad"),
253                                                       P_("The xpad"),
254                                                       0,
255                                                       G_MAXUINT,
256                                                       0,
257                                                       G_PARAM_READABLE |
258                                                       G_PARAM_WRITABLE));
259
260   g_object_class_install_property (object_class,
261                                    PROP_YPAD,
262                                    g_param_spec_uint ("ypad",
263                                                       P_("ypad"),
264                                                       P_("The ypad"),
265                                                       0,
266                                                       G_MAXUINT,
267                                                       0,
268                                                       G_PARAM_READABLE |
269                                                       G_PARAM_WRITABLE));
270
271   g_object_class_install_property (object_class,
272                                    PROP_WIDTH,
273                                    g_param_spec_int ("width",
274                                                      P_("width"),
275                                                      P_("The fixed width"),
276                                                      -1,
277                                                      G_MAXINT,
278                                                      -1,
279                                                      G_PARAM_READABLE |
280                                                      G_PARAM_WRITABLE));
281
282   g_object_class_install_property (object_class,
283                                    PROP_HEIGHT,
284                                    g_param_spec_int ("height",
285                                                      P_("height"),
286                                                      P_("The fixed height"),
287                                                      -1,
288                                                      G_MAXINT,
289                                                      -1,
290                                                      G_PARAM_READABLE |
291                                                      G_PARAM_WRITABLE));
292
293   g_object_class_install_property (object_class,
294                                    PROP_IS_EXPANDER,
295                                    g_param_spec_boolean ("is-expander",
296                                                          P_("Is Expander"),
297                                                          P_("Row has children"),
298                                                          FALSE,
299                                                          G_PARAM_READABLE |
300                                                          G_PARAM_WRITABLE));
301
302
303   g_object_class_install_property (object_class,
304                                    PROP_IS_EXPANDED,
305                                    g_param_spec_boolean ("is-expanded",
306                                                          P_("Is Expanded"),
307                                                          P_("Row is an expander row, and is expanded"),
308                                                          FALSE,
309                                                          G_PARAM_READABLE |
310                                                          G_PARAM_WRITABLE));
311
312   g_object_class_install_property (object_class,
313                                    PROP_CELL_BACKGROUND,
314                                    g_param_spec_string ("cell-background",
315                                                         P_("Cell background color name"),
316                                                         P_("Cell background color as a string"),
317                                                         NULL,
318                                                         G_PARAM_WRITABLE));
319
320   g_object_class_install_property (object_class,
321                                    PROP_CELL_BACKGROUND_GDK,
322                                    g_param_spec_boxed ("cell-background-gdk",
323                                                        P_("Cell background color"),
324                                                        P_("Cell background color as a GdkColor"),
325                                                        GDK_TYPE_COLOR,
326                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
327
328
329 #define ADD_SET_PROP(propname, propval, nick, blurb) g_object_class_install_property (object_class, propval, g_param_spec_boolean (propname, nick, blurb, FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE))
330
331   ADD_SET_PROP ("cell-background-set", PROP_CELL_BACKGROUND_SET,
332                 P_("Cell background set"),
333                 P_("Whether this tag affects the cell background color"));
334
335   g_type_class_add_private (object_class, sizeof (GtkCellRendererPrivate));
336 }
337
338 static void
339 gtk_cell_renderer_get_property (GObject     *object,
340                                 guint        param_id,
341                                 GValue      *value,
342                                 GParamSpec  *pspec)
343 {
344   GtkCellRenderer *cell = GTK_CELL_RENDERER (object);
345   GtkCellRendererPrivate *priv = GTK_CELL_RENDERER_GET_PRIVATE (object);
346
347   switch (param_id)
348     {
349     case PROP_MODE:
350       g_value_set_enum (value, cell->mode);
351       break;
352     case PROP_VISIBLE:
353       g_value_set_boolean (value, cell->visible);
354       break;
355     case PROP_SENSITIVE:
356       g_value_set_boolean (value, cell->sensitive);
357       break;
358     case PROP_XALIGN:
359       g_value_set_float (value, cell->xalign);
360       break;
361     case PROP_YALIGN:
362       g_value_set_float (value, cell->yalign);
363       break;
364     case PROP_XPAD:
365       g_value_set_uint (value, cell->xpad);
366       break;
367     case PROP_YPAD:
368       g_value_set_uint (value, cell->ypad);
369       break;
370     case PROP_WIDTH:
371       g_value_set_int (value, cell->width);
372       break;
373     case PROP_HEIGHT:
374       g_value_set_int (value, cell->height);
375       break;
376     case PROP_IS_EXPANDER:
377       g_value_set_boolean (value, cell->is_expander);
378       break;
379     case PROP_IS_EXPANDED:
380       g_value_set_boolean (value, cell->is_expanded);
381       break;
382     case PROP_CELL_BACKGROUND_GDK:
383       {
384         GdkColor color;
385
386         color.red = priv->cell_background.red;
387         color.green = priv->cell_background.green;
388         color.blue = priv->cell_background.blue;
389
390         g_value_set_boxed (value, &color);
391       }
392       break;
393     case PROP_CELL_BACKGROUND_SET:
394       g_value_set_boolean (value, cell->cell_background_set);
395       break;
396     case PROP_CELL_BACKGROUND:
397     default:
398       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
399       break;
400     }
401
402 }
403
404 static void
405 gtk_cell_renderer_set_property (GObject      *object,
406                                 guint         param_id,
407                                 const GValue *value,
408                                 GParamSpec   *pspec)
409 {
410   GtkCellRenderer *cell = GTK_CELL_RENDERER (object);
411
412   switch (param_id)
413     {
414     case PROP_MODE:
415       cell->mode = g_value_get_enum (value);
416       break;
417     case PROP_VISIBLE:
418       cell->visible = g_value_get_boolean (value);
419       break;
420     case PROP_SENSITIVE:
421       cell->sensitive = g_value_get_boolean (value);
422       break;
423     case PROP_XALIGN:
424       cell->xalign = g_value_get_float (value);
425       break;
426     case PROP_YALIGN:
427       cell->yalign = g_value_get_float (value);
428       break;
429     case PROP_XPAD:
430       cell->xpad = g_value_get_uint (value);
431       break;
432     case PROP_YPAD:
433       cell->ypad = g_value_get_uint (value);
434       break;
435     case PROP_WIDTH:
436       cell->width = g_value_get_int (value);
437       break;
438     case PROP_HEIGHT:
439       cell->height = g_value_get_int (value);
440       break;
441     case PROP_IS_EXPANDER:
442       cell->is_expander = g_value_get_boolean (value);
443       break;
444     case PROP_IS_EXPANDED:
445       cell->is_expanded = g_value_get_boolean (value);
446       break;
447     case PROP_CELL_BACKGROUND:
448       {
449         GdkColor color;
450
451         if (!g_value_get_string (value))
452           set_cell_bg_color (cell, NULL);
453         else if (gdk_color_parse (g_value_get_string (value), &color))
454           set_cell_bg_color (cell, &color);
455         else
456           g_warning ("Don't know color `%s'", g_value_get_string (value));
457
458         g_object_notify (object, "cell_background_gdk");
459       }
460       break;
461     case PROP_CELL_BACKGROUND_GDK:
462       set_cell_bg_color (cell, g_value_get_boxed (value));
463       break;
464     case PROP_CELL_BACKGROUND_SET:
465       cell->cell_background_set = g_value_get_boolean (value);
466       break;
467     default:
468       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
469       break;
470     }
471 }
472
473 static void
474 set_cell_bg_color (GtkCellRenderer *cell,
475                    GdkColor        *color)
476 {
477   GtkCellRendererPrivate *priv = GTK_CELL_RENDERER_GET_PRIVATE (cell);
478
479   if (color)
480     {
481       if (!cell->cell_background_set)
482         {
483           cell->cell_background_set = TRUE;
484           g_object_notify (G_OBJECT (cell), "cell_background_set");
485         }
486
487       priv->cell_background.red = color->red;
488       priv->cell_background.green = color->green;
489       priv->cell_background.blue = color->blue;
490     }
491   else
492     {
493       if (cell->cell_background_set)
494         {
495           cell->cell_background_set = FALSE;
496           g_object_notify (G_OBJECT (cell), "cell_background_set");
497         }
498     }
499 }
500
501 /**
502  * gtk_cell_renderer_get_size:
503  * @cell: a #GtkCellRenderer
504  * @widget: the widget the renderer is rendering to
505  * @cell_area: The area a cell will be allocated, or %NULL
506  * @x_offset: location to return x offset of cell relative to @cell_area, or %NULL
507  * @y_offset: location to return y offset of cell relative to @cell_area, or %NULL
508  * @width: location to return width needed to render a cell, or %NULL
509  * @height: location to return height needed to render a cell, or %NULL
510  *
511  * Obtains the width and height needed to render the cell. Used by view widgets
512  * to determine the appropriate size for the cell_area passed to
513  * gtk_cell_renderer_render().  If @cell_area is not %NULL, fills in the x and y
514  * offsets (if set) of the cell relative to this location.  Please note that the
515  * values set in @width and @height, as well as those in @x_offset and @y_offset
516  * are inclusive of the xpad and ypad properties.
517  **/
518 void
519 gtk_cell_renderer_get_size (GtkCellRenderer *cell,
520                             GtkWidget       *widget,
521                             GdkRectangle    *cell_area,
522                             gint            *x_offset,
523                             gint            *y_offset,
524                             gint            *width,
525                             gint            *height)
526 {
527   gint *real_width = width;
528   gint *real_height = height;
529
530   g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
531   g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->get_size != NULL);
532
533   if (width && cell->width != -1)
534     {
535       real_width = NULL;
536       *width = cell->width;
537     }
538   if (height && cell->height != -1)
539     {
540       real_height = NULL;
541       *height = cell->height;
542     }
543
544   GTK_CELL_RENDERER_GET_CLASS (cell)->get_size (cell,
545                                                 widget,
546                                                 cell_area,
547                                                 x_offset,
548                                                 y_offset,
549                                                 real_width,
550                                                 real_height);
551 }
552
553 /**
554  * gtk_cell_renderer_render:
555  * @cell: a #GtkCellRenderer
556  * @window: a #GdkDrawable to draw to
557  * @widget: the widget owning @window
558  * @background_area: entire cell area (including tree expanders and maybe padding on the sides)
559  * @cell_area: area normally rendered by a cell renderer
560  * @expose_area: area that actually needs updating
561  * @flags: flags that affect rendering
562  *
563  * Invokes the virtual render function of the #GtkCellRenderer. The three
564  * passed-in rectangles are areas of @window. Most renderers will draw within
565  * @cell_area; the xalign, yalign, xpad, and ypad fields of the #GtkCellRenderer
566  * should be honored with respect to @cell_area. @background_area includes the
567  * blank space around the cell, and also the area containing the tree expander;
568  * so the @background_area rectangles for all cells tile to cover the entire
569  * @window.  @expose_area is a clip rectangle.
570  *
571  **/
572 void
573 gtk_cell_renderer_render (GtkCellRenderer     *cell,
574                           GdkWindow           *window,
575                           GtkWidget           *widget,
576                           GdkRectangle        *background_area,
577                           GdkRectangle        *cell_area,
578                           GdkRectangle        *expose_area,
579                           GtkCellRendererState flags)
580 {
581   gboolean selected = FALSE;
582   GtkCellRendererPrivate *priv = GTK_CELL_RENDERER_GET_PRIVATE (cell);
583
584   g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
585   g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->render != NULL);
586
587   selected = (flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED;
588
589   if (cell->cell_background_set && !selected)
590     {
591       GdkColor color;
592       GdkGC *gc;
593
594       color.red = priv->cell_background.red;
595       color.green = priv->cell_background.green;
596       color.blue = priv->cell_background.blue;
597
598       gc = gdk_gc_new (window);
599       gdk_gc_set_rgb_fg_color (gc, &color);
600       gdk_draw_rectangle (window, gc, TRUE,
601                           background_area->x, background_area->y,
602                           background_area->width, background_area->height);
603       g_object_unref (gc);
604     }
605
606   GTK_CELL_RENDERER_GET_CLASS (cell)->render (cell,
607                                               window,
608                                               widget,
609                                               background_area,
610                                               cell_area,
611                                               expose_area,
612                                               flags);
613 }
614
615 /**
616  * gtk_cell_renderer_activate:
617  * @cell: a #GtkCellRenderer
618  * @event: a #GdkEvent
619  * @widget: widget that received the event
620  * @path: widget-dependent string representation of the event location; e.g. for #GtkTreeView, a string representation of #GtkTreePath
621  * @background_area: background area as passed to @gtk_cell_renderer_render
622  * @cell_area: cell area as passed to @gtk_cell_renderer_render
623  * @flags: render flags
624  *
625  * Passes an activate event to the cell renderer for possible processing.  Some
626  * cell renderers may use events; for example, #GtkCellRendererToggle toggles
627  * when it gets a mouse click.
628  *
629  * Return value: %TRUE if the event was consumed/handled
630  **/
631 gboolean
632 gtk_cell_renderer_activate (GtkCellRenderer      *cell,
633                             GdkEvent             *event,
634                             GtkWidget            *widget,
635                             const gchar          *path,
636                             GdkRectangle         *background_area,
637                             GdkRectangle         *cell_area,
638                             GtkCellRendererState  flags)
639 {
640   g_return_val_if_fail (GTK_IS_CELL_RENDERER (cell), FALSE);
641
642   if (cell->mode != GTK_CELL_RENDERER_MODE_ACTIVATABLE)
643     return FALSE;
644
645   if (GTK_CELL_RENDERER_GET_CLASS (cell)->activate == NULL)
646     return FALSE;
647
648   return GTK_CELL_RENDERER_GET_CLASS (cell)->activate (cell,
649                                                        event,
650                                                        widget,
651                                                        path,
652                                                        background_area,
653                                                        cell_area,
654                                                        flags);
655 }
656
657 /**
658  * gtk_cell_renderer_start_editing:
659  * @cell: a #GtkCellRenderer
660  * @event: a #GdkEvent
661  * @widget: widget that received the event
662  * @path: widget-dependent string representation of the event location; e.g. for #GtkTreeView, a string representation of #GtkTreePath
663  * @background_area: background area as passed to @gtk_cell_renderer_render
664  * @cell_area: cell area as passed to @gtk_cell_renderer_render
665  * @flags: render flags
666  * 
667  * Passes an activate event to the cell renderer for possible processing.
668  * 
669  * Return value: A new #GtkCellEditable, or %NULL
670  **/
671 GtkCellEditable *
672 gtk_cell_renderer_start_editing (GtkCellRenderer      *cell,
673                                  GdkEvent             *event,
674                                  GtkWidget            *widget,
675                                  const gchar          *path,
676                                  GdkRectangle         *background_area,
677                                  GdkRectangle         *cell_area,
678                                  GtkCellRendererState  flags)
679
680 {
681   GtkCellEditable *editable;
682
683   g_return_val_if_fail (GTK_IS_CELL_RENDERER (cell), NULL);
684
685   if (cell->mode != GTK_CELL_RENDERER_MODE_EDITABLE)
686     return NULL;
687
688   if (GTK_CELL_RENDERER_GET_CLASS (cell)->start_editing == NULL)
689     return NULL;
690
691   editable = GTK_CELL_RENDERER_GET_CLASS (cell)->start_editing (cell,
692                                                                 event,
693                                                                 widget,
694                                                                 path,
695                                                                 background_area,
696                                                                 cell_area,
697                                                                 flags);
698
699   g_signal_emit (cell, 
700                  cell_renderer_signals[EDITING_STARTED], 0,
701                  editable, path);
702
703   cell->editing = TRUE;
704
705   return editable;
706 }
707
708 /**
709  * gtk_cell_renderer_set_fixed_size:
710  * @cell: A #GtkCellRenderer
711  * @width: the width of the cell renderer, or -1
712  * @height: the height of the cell renderer, or -1
713  * 
714  * Sets the renderer size to be explicit, independent of the properties set.
715  **/
716 void
717 gtk_cell_renderer_set_fixed_size (GtkCellRenderer *cell,
718                                   gint             width,
719                                   gint             height)
720 {
721   g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
722   g_return_if_fail (width >= -1 && height >= -1);
723
724   if ((width != cell->width) || (height != cell->height))
725     {
726       g_object_freeze_notify (G_OBJECT (cell));
727
728       if (width != cell->width)
729         {
730           cell->width = width;
731           g_object_notify (G_OBJECT (cell), "width");
732         }
733
734       if (height != cell->height)
735         {
736           cell->height = height;
737           g_object_notify (G_OBJECT (cell), "height");
738         }
739
740       g_object_thaw_notify (G_OBJECT (cell));
741     }
742 }
743
744 /**
745  * gtk_cell_renderer_get_fixed_size:
746  * @cell: A #GtkCellRenderer
747  * @width: location to fill in with the fixed width of the widget, or %NULL
748  * @height: location to fill in with the fixed height of the widget, or %NULL
749  * 
750  * Fills in @width and @height with the appropriate size of @cell.
751  **/
752 void
753 gtk_cell_renderer_get_fixed_size (GtkCellRenderer *cell,
754                                   gint            *width,
755                                   gint            *height)
756 {
757   g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
758
759   if (width)
760     (* width) = cell->width;
761   if (height)
762     (* height) = cell->height;
763 }
764
765 /**
766  * gtk_cell_renderer_editing_canceled:
767  * @cell: A #GtkCellRenderer
768  * 
769  * Causes the cell renderer to emit the "editing-canceled" signal.  This
770  * function is for use only by implementations of cell renderers that need to
771  * notify the client program that an editing process was canceled and the
772  * changes were not committed.
773  *
774  * Since: 2.4
775  * Deprecated: Use gtk_cell_renderer_stop_editing() instead
776  **/
777 void
778 gtk_cell_renderer_editing_canceled (GtkCellRenderer *cell)
779 {
780   g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
781
782   gtk_cell_renderer_stop_editing (cell, TRUE);
783 }
784
785 /**
786  * gtk_cell_renderer_stop_editing:
787  * @cell: A #GtkCellRenderer
788  * @canceled: %TRUE if the editing has been canceled
789  * 
790  * Informs the cell renderer that the editing is stopped.
791  * If @canceled is %TRUE, the cell renderer will emit the "editing-canceled" 
792  * signal. This function should be called by cell renderer implementations 
793  * in response to the "editing-done" signal of #GtkCellEditable.
794  *
795  * Since: 2.6
796  **/
797 void
798 gtk_cell_renderer_stop_editing (GtkCellRenderer *cell,
799                                 gboolean         canceled)
800 {
801   g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
802
803   if (cell->editing)
804     {
805       cell->editing = FALSE;
806       if (canceled)
807         g_signal_emit (cell, cell_renderer_signals[EDITING_CANCELED], 0);
808     }
809 }
810