]> Pileus Git - ~andy/gtk/blob - gtk/gtkcellrenderertext.c
urg, removed implementation of gtk_marshal_VOID__INT_INT_INT_INT. if
[~andy/gtk] / gtk / gtkcellrenderertext.c
1 /* gtkcellrenderertext.c
2  * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
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 <stdlib.h>
21 #include "gtkcellrenderertext.h"
22
23 #ifndef _
24 #define _(x) x
25 #endif
26
27 static void gtk_cell_renderer_text_init       (GtkCellRendererText      *celltext);
28 static void gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class);
29
30 static void gtk_cell_renderer_text_get_param  (GObject                  *object,
31                                                guint                     param_id,
32                                                GValue                   *value,
33                                                GParamSpec               *pspec,
34                                                const gchar              *trailer);
35 static void gtk_cell_renderer_text_set_param  (GObject                  *object,
36                                                guint                     param_id,
37                                                GValue                   *value,
38                                                GParamSpec               *pspec,
39                                                const gchar              *trailer);
40 static void gtk_cell_renderer_text_get_size   (GtkCellRenderer          *cell,
41                                                GtkWidget                *widget,
42                                                gint                     *width,
43                                                gint                     *height);
44 static void gtk_cell_renderer_text_render     (GtkCellRenderer          *cell,
45                                                GdkWindow                *window,
46                                                GtkWidget                *widget,
47                                                GdkRectangle             *background_area,
48                                                GdkRectangle             *cell_area,
49                                                GdkRectangle             *expose_area,
50                                                guint                     flags);
51
52
53 enum {
54   PROP_ZERO,
55   PROP_TEXT,
56   PROP_FONT,
57   PROP_BACKGROUND,
58   PROP_BACKGROUND_GDK,
59   PROP_FOREGROUND,
60   PROP_FOREGROUND_GDK,
61   PROP_STRIKETHROUGH,
62   PROP_UNDERLINE,
63   PROP_EDITABLE,
64   PROP_ITALIC,
65   PROP_BOLD
66 };
67
68 GtkType
69 gtk_cell_renderer_text_get_type (void)
70 {
71   static GtkType cell_text_type = 0;
72
73   if (!cell_text_type)
74     {
75       static const GTypeInfo cell_text_info =
76       {
77         sizeof (GtkCellRendererTextClass),
78         NULL,           /* base_init */
79         NULL,           /* base_finalize */
80         (GClassInitFunc) gtk_cell_renderer_text_class_init,
81         NULL,           /* class_finalize */
82         NULL,           /* class_data */
83         sizeof (GtkCellRendererText),
84         0,              /* n_preallocs */
85         (GInstanceInitFunc) gtk_cell_renderer_text_init,
86       };
87
88       cell_text_type = g_type_register_static (GTK_TYPE_CELL_RENDERER, "GtkCellRendererText", &cell_text_info, 0);
89     }
90
91   return cell_text_type;
92 }
93
94 static void
95 gtk_cell_renderer_text_init (GtkCellRendererText *celltext)
96 {
97   celltext->attr_list = pango_attr_list_new ();
98   GTK_CELL_RENDERER (celltext)->xalign = 0.0;
99   GTK_CELL_RENDERER (celltext)->yalign = 0.5;
100   GTK_CELL_RENDERER (celltext)->xpad = 2;
101   GTK_CELL_RENDERER (celltext)->ypad = 2;
102   celltext->underline = FALSE;
103 }
104
105 static void
106 gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class)
107 {
108   GObjectClass *object_class = G_OBJECT_CLASS (class);
109   GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);
110
111   object_class->get_param = gtk_cell_renderer_text_get_param;
112   object_class->set_param = gtk_cell_renderer_text_set_param;
113
114   cell_class->get_size = gtk_cell_renderer_text_get_size;
115   cell_class->render = gtk_cell_renderer_text_render;
116
117   g_object_class_install_param (object_class,
118                                 PROP_TEXT,
119                                 g_param_spec_string ("text",
120                                                      _("Text String"),
121                                                      _("The text of the renderer."),
122                                                      "",
123                                                      G_PARAM_READABLE |
124                                                      G_PARAM_WRITABLE));
125
126   g_object_class_install_param (object_class,
127                                 PROP_FONT,
128                                 g_param_spec_string ("font",
129                                                      _("Font String"),
130                                                      _("The string of the font."),
131                                                      "",
132                                                      G_PARAM_WRITABLE));
133
134   g_object_class_install_param (object_class,
135                                 PROP_BACKGROUND,
136                                 g_param_spec_string ("background",
137                                                      _("Background Color string"),
138                                                      _("The color for the background of the text."),
139                                                      "white",
140                                                      G_PARAM_WRITABLE));
141
142   g_object_class_install_param (object_class,
143                                 PROP_FOREGROUND,
144                                 g_param_spec_string ("foreground",
145                                                      _("Foreground Color string"),
146                                                      _("The color for the background of the text."),
147                                                      "black",
148                                                      G_PARAM_WRITABLE));
149
150   g_object_class_install_param (object_class,
151                                 PROP_STRIKETHROUGH,
152                                 g_param_spec_boolean ("strikethrough",
153                                                       _("Strikethrough"),
154                                                       _("Draw a line through the text."),
155                                                       FALSE,
156                                                       G_PARAM_READABLE |
157                                                       G_PARAM_WRITABLE));
158
159   g_object_class_install_param (object_class,
160                                 PROP_UNDERLINE,
161                                 g_param_spec_boolean ("underline",
162                                                       _("Underline"),
163                                                       _("Underline the text."),
164                                                       FALSE,
165                                                       G_PARAM_READABLE |
166                                                       G_PARAM_WRITABLE));
167
168   g_object_class_install_param (object_class,
169                                 PROP_EDITABLE,
170                                 g_param_spec_boolean ("editable",
171                                                       _("Editable"),
172                                                       _("Make the text editable."),
173                                                       FALSE,
174                                                       G_PARAM_READABLE |
175                                                       G_PARAM_WRITABLE));
176
177   g_object_class_install_param (object_class,
178                                 PROP_ITALIC,
179                                 g_param_spec_boolean ("italic",
180                                                       _("Italic"),
181                                                       _("Make the text italic."),
182                                                       FALSE,
183                                                       G_PARAM_WRITABLE));
184
185   g_object_class_install_param (object_class,
186                                 PROP_BOLD,
187                                 g_param_spec_boolean ("bold",
188                                                       _("Bold"),
189                                                       _("Make the text bold."),
190                                                       FALSE,
191                                                       G_PARAM_WRITABLE));
192 }
193
194 static void
195 gtk_cell_renderer_text_get_param (GObject        *object,
196                                   guint           param_id,
197                                   GValue         *value,
198                                   GParamSpec     *pspec,
199                                   const gchar    *trailer)
200 {
201   GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (object);
202   PangoAttrIterator *attr_iter;
203   PangoAttribute *attr;
204
205   switch (param_id)
206     {
207     case PROP_TEXT:
208       g_value_init (value, G_TYPE_STRING);
209       g_value_set_string (value, celltext->text);
210       break;
211     case PROP_STRIKETHROUGH:
212       g_value_init (value, G_TYPE_BOOLEAN);
213       attr_iter = pango_attr_list_get_iterator (celltext->attr_list);
214       attr = pango_attr_iterator_get (attr_iter,
215                                       PANGO_ATTR_STRIKETHROUGH);
216       g_value_set_boolean (value, ((PangoAttrInt*) attr)->value);
217       break;
218     case PROP_UNDERLINE:
219       g_value_init (value, G_TYPE_BOOLEAN);
220       g_value_set_boolean (value, celltext->underline);
221       break;
222     case PROP_EDITABLE:
223       g_value_init (value, G_TYPE_BOOLEAN);
224       g_value_set_boolean (value, celltext->editable);
225       break;
226     default:
227       break;
228     }
229 }
230
231
232 static void
233 gtk_cell_renderer_text_set_param (GObject     *object,
234                                   guint        param_id,
235                                   GValue      *value,
236                                   GParamSpec  *pspec,
237                                   const gchar *trailer)
238 {
239   GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (object);
240
241   GdkColor color;
242   PangoFontDescription *font_desc;
243   gchar *string;
244   PangoAttribute *attribute;
245   gchar *font;
246
247   switch (param_id)
248     {
249     case PROP_TEXT:
250       g_free (celltext->text);
251       celltext->text = g_value_dup_string (value);
252       break;
253     case PROP_FONT:
254       font = g_value_get_string (value);
255
256       if (font)
257         {
258           font_desc = pango_font_description_from_string (font);
259           attribute = pango_attr_font_desc_new (font_desc);
260           attribute->start_index = 0;
261           attribute->end_index = G_MAXINT;
262           pango_font_description_free (font_desc);
263           pango_attr_list_change (celltext->attr_list,
264                                   attribute);
265         }
266       break;
267     case PROP_BACKGROUND:
268       string = g_value_get_string (value);
269       if (string && gdk_color_parse (string, &color))
270         {
271           attribute = pango_attr_background_new (color.red,
272                                                  color.green,
273                                                  color.blue);
274           attribute->start_index = 0;
275           attribute->end_index = G_MAXINT;
276           pango_attr_list_change (celltext->attr_list,
277                                   attribute);
278         }
279       break;
280     case PROP_BACKGROUND_GDK:
281       break;
282     case PROP_FOREGROUND:
283       string = g_value_get_string (value);
284       if (string && gdk_color_parse (string, &color))
285         {
286           attribute = pango_attr_foreground_new (color.red,
287                                                  color.green,
288                                                  color.blue);
289           attribute->start_index = 0;
290           attribute->end_index = G_MAXINT;
291           pango_attr_list_change (celltext->attr_list,
292                                   attribute);
293         }
294       break;
295     case PROP_FOREGROUND_GDK:
296       break;
297     case PROP_STRIKETHROUGH:
298       attribute = pango_attr_strikethrough_new (g_value_get_boolean (value));
299       attribute->start_index = 0;
300       attribute->end_index = G_MAXINT;
301       pango_attr_list_change (celltext->attr_list,
302                               attribute);
303       break;
304     case PROP_UNDERLINE:
305       celltext->underline = g_value_get_boolean (value);
306       attribute = pango_attr_underline_new (celltext->underline ?
307                                             PANGO_UNDERLINE_SINGLE :
308                                             PANGO_UNDERLINE_NONE);
309       attribute->start_index = 0;
310       attribute->end_index = G_MAXINT;
311       pango_attr_list_change (celltext->attr_list,
312                               attribute);
313       break;
314     case PROP_EDITABLE:
315       break;
316     case PROP_ITALIC:
317       attribute = pango_attr_style_new (g_value_get_boolean (value) ?
318                                         PANGO_STYLE_ITALIC :
319                                         PANGO_STYLE_NORMAL);
320       attribute->start_index = 0;
321       attribute->end_index = G_MAXINT;
322       pango_attr_list_change (celltext->attr_list,
323                               attribute);
324       break;
325     case PROP_BOLD:
326       attribute = pango_attr_weight_new (g_value_get_boolean (value) ?
327                                          PANGO_WEIGHT_BOLD :
328                                          PANGO_WEIGHT_NORMAL);
329       attribute->start_index = 0;
330       attribute->end_index = G_MAXINT;
331       pango_attr_list_change (celltext->attr_list,
332                               attribute);
333       break;
334     default:
335       break;
336     }
337 }
338
339 GtkCellRenderer *
340 gtk_cell_renderer_text_new (void)
341 {
342   return GTK_CELL_RENDERER (gtk_type_new (gtk_cell_renderer_text_get_type ()));
343 }
344
345 static void
346 gtk_cell_renderer_text_get_size (GtkCellRenderer *cell,
347                                  GtkWidget       *widget,
348                                  gint            *width,
349                                  gint            *height)
350 {
351   GtkCellRendererText *celltext = (GtkCellRendererText *)cell;
352   PangoRectangle rect;
353   PangoLayout *layout;
354   PangoAttribute *attr;
355   PangoUnderline underline;
356
357   layout = gtk_widget_create_pango_layout (widget, celltext->text);
358   underline = celltext->underline ?
359     PANGO_UNDERLINE_DOUBLE :
360     PANGO_UNDERLINE_NONE;
361
362   attr = pango_attr_underline_new (underline);
363   attr->start_index = 0;
364   attr->end_index = G_MAXINT;
365
366   pango_attr_list_change (celltext->attr_list, attr);
367   pango_layout_set_attributes (layout, celltext->attr_list);
368   pango_layout_set_width (layout, -1);
369   pango_layout_get_pixel_extents (layout, NULL, &rect);
370
371   if (width)
372     *width = GTK_CELL_RENDERER (celltext)->xpad * 2 + rect.width;
373
374   if (height)
375     *height = GTK_CELL_RENDERER (celltext)->ypad * 2 + rect.height;
376
377   g_object_unref (G_OBJECT (layout));
378 }
379
380 static void
381 gtk_cell_renderer_text_render (GtkCellRenderer    *cell,
382                                GdkWindow          *window,
383                                GtkWidget          *widget,
384                                GdkRectangle       *background_area,
385                                GdkRectangle       *cell_area,
386                                GdkRectangle       *expose_area,
387                                guint               flags)
388
389 {
390   GtkCellRendererText *celltext = (GtkCellRendererText *) cell;
391   PangoRectangle rect;
392   PangoLayout *layout;
393   PangoAttribute *attr;
394   PangoUnderline underline;
395
396   gint real_xoffset;
397   gint real_yoffset;
398
399   GdkGC *font_gc = NULL;
400
401   if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED)
402     font_gc = widget->style->fg_gc [GTK_STATE_SELECTED];
403   else
404     font_gc = widget->style->fg_gc [GTK_STATE_NORMAL];
405
406   layout = gtk_widget_create_pango_layout (widget, celltext->text);
407
408   if (celltext->underline)
409     underline = PANGO_UNDERLINE_SINGLE;
410   else
411     underline = PANGO_UNDERLINE_NONE;
412
413   attr = pango_attr_underline_new (underline);
414   attr->start_index = 0;
415   attr->end_index = G_MAXINT;
416   pango_attr_list_change (celltext->attr_list, attr);
417   pango_layout_set_attributes (layout, celltext->attr_list);
418
419   pango_layout_set_width (layout, -1);
420   pango_layout_get_pixel_extents (layout, NULL, &rect);
421
422   if ((flags & GTK_CELL_RENDERER_PRELIT) == GTK_CELL_RENDERER_PRELIT)
423     underline = (celltext->underline) ? PANGO_UNDERLINE_DOUBLE:PANGO_UNDERLINE_SINGLE;
424   else
425     underline = (celltext->underline) ? PANGO_UNDERLINE_SINGLE:PANGO_UNDERLINE_NONE;
426
427   attr = pango_attr_underline_new (underline);
428   attr->start_index = 0;
429   attr->end_index = G_MAXINT;
430   pango_attr_list_change (celltext->attr_list, attr);
431   pango_layout_set_attributes (layout, celltext->attr_list);
432
433   gdk_gc_set_clip_rectangle (font_gc, cell_area);
434
435   real_xoffset = cell->xalign * (cell_area->width - rect.width - (2 * cell->xpad));
436   real_xoffset = MAX (real_xoffset, 0) + cell->xpad;
437   real_yoffset = cell->yalign * (cell_area->height - rect.height - (2 * cell->ypad));
438   real_yoffset = MAX (real_yoffset, 0) + cell->ypad;
439
440   gdk_draw_layout (window,
441                    font_gc,
442                    cell_area->x + real_xoffset,
443                    cell_area->y + real_yoffset,
444                    layout);
445
446   g_object_unref (G_OBJECT (layout));
447
448   gdk_gc_set_clip_rectangle (font_gc, NULL);
449 }