2008-04-21 Emmanuele Bassi <ebassi@openedhand.com>
[clutter-gtk] / clutter-gtk / gtk-clutter-util.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #include <gdk-pixbuf/gdk-pixbuf.h>
6 #include <gtk/gtk.h>
7 #include <clutter/clutter.h>
8
9 #include "gtk-clutter-util.h"
10
11 /**
12  * SECTION:gtk-clutter-util
13  * @short_description: Utility functions for integrating Clutter in GTK+
14  *
15  * FIXME
16  *
17  */
18
19 static inline void
20 gtk_clutter_get_component (GtkWidget    *widget,
21                            GtkRcFlags    component,
22                            GtkStateType  state,
23                            ClutterColor *color)
24 {
25   GtkStyle *style = gtk_widget_get_style (widget);
26   GdkColor gtk_color = { 0, };
27
28   switch (component)
29     {
30     case GTK_RC_FG:
31       gtk_color = style->fg[state];
32       break;
33
34     case GTK_RC_BG:
35       gtk_color = style->bg[state];
36       break;
37
38     case GTK_RC_TEXT:
39       gtk_color = style->text[state];
40       break;
41
42     case GTK_RC_BASE:
43       gtk_color = style->base[state];
44       break;
45
46     default:
47       g_assert_not_reached ();
48       break;
49     }
50
51   color->red   = (guint8) ((gtk_color.red   / 65535.0) * 255);
52   color->green = (guint8) ((gtk_color.green / 65535.0) * 255);
53   color->blue  = (guint8) ((gtk_color.blue  / 65535.0) * 255);
54 }
55
56 /**
57  * gtk_clutter_get_fg_color:
58  * @widget:
59  * @state:
60  * @color:
61  *
62  * FIXME
63  *
64  * Since: 0.8
65  */
66 void
67 gtk_clutter_get_fg_color (GtkWidget    *widget,
68                           GtkStateType  state,
69                           ClutterColor *color)
70 {
71   g_return_if_fail (GTK_IS_WIDGET (widget));
72   g_return_if_fail (state >= GTK_STATE_NORMAL &&
73                     state <= GTK_STATE_INSENSITIVE);
74   g_return_if_fail (color != NULL);
75
76   gtk_clutter_get_component (widget, GTK_RC_FG, state, color);
77 }
78
79 /**
80  * gtk_clutter_get_bg_color:
81  * @widget:
82  * @state:
83  * @color:
84  *
85  * FIXME
86  *
87  * Since: 0.8
88  */
89 void
90 gtk_clutter_get_bg_color (GtkWidget    *widget,
91                           GtkStateType  state,
92                           ClutterColor *color)
93 {
94   g_return_if_fail (GTK_IS_WIDGET (widget));
95   g_return_if_fail (state >= GTK_STATE_NORMAL &&
96                     state <= GTK_STATE_INSENSITIVE);
97   g_return_if_fail (color != NULL);
98
99   gtk_clutter_get_component (widget, GTK_RC_BG, state, color);
100 }
101
102 /**
103  * gtk_clutter_get_text_color:
104  * @widget:
105  * @state:
106  * @color:
107  *
108  * FIXME
109  *
110  * Since: 0.8
111  */
112 void
113 gtk_clutter_get_text_color (GtkWidget    *widget,
114                             GtkStateType  state,
115                             ClutterColor *color)
116 {
117   g_return_if_fail (GTK_IS_WIDGET (widget));
118   g_return_if_fail (state >= GTK_STATE_NORMAL &&
119                     state <= GTK_STATE_INSENSITIVE);
120   g_return_if_fail (color != NULL);
121
122   gtk_clutter_get_component (widget, GTK_RC_TEXT, state, color);
123 }
124
125 /**
126  * gtk_clutter_get_base_color:
127  * @widget:
128  * @state:
129  * @color:
130  *
131  * FIXME
132  *
133  * Since: 0.8
134  */
135 void
136 gtk_clutter_get_base_color (GtkWidget    *widget,
137                             GtkStateType  state,
138                             ClutterColor *color)
139 {
140   g_return_if_fail (GTK_IS_WIDGET (widget));
141   g_return_if_fail (state >= GTK_STATE_NORMAL &&
142                     state <= GTK_STATE_INSENSITIVE);
143   g_return_if_fail (color != NULL);
144
145   gtk_clutter_get_component (widget, GTK_RC_BASE, state, color);
146 }
147
148 /**
149  * gtk_clutter_texture_new_from_pixbuf:
150  * @pixbuf: a #GdkPixbuf
151  *
152  * FIXME
153  *
154  * Return value: the newly created #ClutterTexture
155  *
156  * Since: 0.8
157  */
158 ClutterActor *
159 gtk_clutter_texture_new_from_pixbuf (GdkPixbuf *pixbuf)
160 {
161   ClutterActor *retval;
162   GError *error;
163
164   g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
165
166   retval = clutter_texture_new ();
167
168   error = NULL;
169   clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (retval),
170                                      gdk_pixbuf_get_pixels (pixbuf),
171                                      gdk_pixbuf_get_has_alpha (pixbuf),
172                                      gdk_pixbuf_get_width (pixbuf),
173                                      gdk_pixbuf_get_height (pixbuf),
174                                      gdk_pixbuf_get_rowstride (pixbuf),
175                                      4, 0,
176                                      &error);
177   if (error)
178     {
179       g_warning ("Unable to set the pixbuf: %s", error->message);
180       g_error_free (error);
181     }
182
183   return retval; 
184 }
185
186 /**
187  * gtk_clutter_texture_new_from_stock:
188  * @widget: a #GtkWidget
189  * @stock_id: FIXME
190  * @size: FIXME
191  *
192  * FIXME
193  *
194  * Return value: the newly created #ClutterTexture
195  *
196  * Since: 0.8
197  */
198 ClutterActor *
199 gtk_clutter_texture_new_from_stock (GtkWidget   *widget,
200                                     const gchar *stock_id,
201                                     GtkIconSize  size)
202 {
203   GdkPixbuf *pixbuf;
204   ClutterActor *retval;
205
206   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
207   g_return_val_if_fail (stock_id != NULL, NULL);
208   g_return_val_if_fail (size > GTK_ICON_SIZE_INVALID || size == -1, NULL);
209
210   pixbuf = gtk_widget_render_icon (widget, stock_id, size, NULL);
211   if (!pixbuf)
212     pixbuf = gtk_widget_render_icon (widget,
213                                      GTK_STOCK_MISSING_IMAGE, size,
214                                      NULL);
215
216   retval = gtk_clutter_texture_new_from_pixbuf (pixbuf);
217   g_object_unref (pixbuf);
218
219   return retval;
220 }
221
222 /**
223  * gtk_clutter_texture_new_from_icon_name:
224  * @widget: a #GtkWidget
225  * @icon_name: FIXME
226  * @size: FIXME
227  *
228  * FIXME
229  *
230  * Return value: the newly created #ClutterTexture
231  *
232  * Since: 0.8
233  */
234 ClutterActor *
235 gtk_clutter_texture_new_from_icon_name (GtkWidget   *widget,
236                                         const gchar *icon_name,
237                                         GtkIconSize  size)
238 {
239   GtkSettings *settings;
240   GtkIconTheme *icon_theme;
241   gint width, height;
242   GdkPixbuf *pixbuf;
243   GError *error;
244   ClutterActor *retval;
245
246   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
247   g_return_val_if_fail (icon_name != NULL, NULL);
248   g_return_val_if_fail (size > GTK_ICON_SIZE_INVALID || size == -1, NULL);
249
250   if (gtk_widget_has_screen (widget))
251     {
252       GdkScreen *screen;
253
254       screen = gtk_widget_get_screen (widget);
255       settings = gtk_settings_get_for_screen (screen);
256       icon_theme = gtk_icon_theme_get_for_screen (screen);
257     }
258   else
259     {
260       settings = gtk_settings_get_default ();
261       icon_theme = gtk_icon_theme_get_default ();
262     }
263
264   if (!gtk_icon_size_lookup_for_settings (settings, size, &width, &height))
265     {
266       g_warning ("Invalid icon size");
267       width = height = 48;
268     }
269
270   error = NULL;
271   pixbuf = gtk_icon_theme_load_icon (icon_theme,
272                                      icon_name,
273                                      MIN (width, height), 0,
274                                      &error);
275   if (error)
276     {
277       g_error_free (error);
278       return gtk_clutter_texture_new_from_stock (widget,
279                                                  GTK_STOCK_MISSING_IMAGE,
280                                                  size);
281     }
282
283   retval = gtk_clutter_texture_new_from_pixbuf (pixbuf);
284   g_object_unref (pixbuf);
285
286   return retval; 
287 }