gnome-shell-3.6.3.1/src/st/st-theme-context.c

No issues found

  1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
  2 /*
  3  * st-theme-context.c: holds global information about a tree of styled objects
  4  *
  5  * Copyright 2009, 2010 Red Hat, Inc.
  6  * Copyright 2009 Florian Mç«Żllner
  7  *
  8  * This program is free software; you can redistribute it and/or modify
  9  * it under the terms of the GNU Lesser General Public License as
 10  * published by the Free Software Foundation, either version 2.1 of
 11  * the License, or (at your option) any later version.
 12  *
 13  * This program is distributed in the hope it will be useful, but WITHOUT ANY
 14  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 15  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 16  * more details.
 17  *
 18  * You should have received a copy of the GNU Lesser General Public License
 19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
 20  */
 21 
 22 #include <config.h>
 23 
 24 #include "st-texture-cache.h"
 25 #include "st-theme.h"
 26 #include "st-theme-context.h"
 27 
 28 struct _StThemeContext {
 29   GObject parent;
 30 
 31   PangoFontDescription *font;
 32   StThemeNode *root_node;
 33   StTheme *theme;
 34 };
 35 
 36 struct _StThemeContextClass {
 37   GObjectClass parent_class;
 38 };
 39 
 40 #define DEFAULT_FONT "sans-serif 10"
 41 
 42 enum
 43 {
 44   CHANGED,
 45 
 46   LAST_SIGNAL
 47 };
 48 
 49 static guint signals[LAST_SIGNAL] = { 0, };
 50 
 51 G_DEFINE_TYPE (StThemeContext, st_theme_context, G_TYPE_OBJECT)
 52 
 53 static void on_icon_theme_changed (StTextureCache *cache,
 54                                    StThemeContext *context);
 55 static void st_theme_context_changed (StThemeContext *context);
 56 
 57 static void
 58 st_theme_context_finalize (GObject *object)
 59 {
 60   StThemeContext *context = ST_THEME_CONTEXT (object);
 61 
 62   g_signal_handlers_disconnect_by_func (st_texture_cache_get_default (),
 63                                        (gpointer) on_icon_theme_changed,
 64                                        context);
 65   g_signal_handlers_disconnect_by_func (clutter_get_default_backend (),
 66                                         (gpointer) st_theme_context_changed,
 67                                         context);
 68 
 69   if (context->root_node)
 70     g_object_unref (context->root_node);
 71   if (context->theme)
 72     g_object_unref (context->theme);
 73 
 74   pango_font_description_free (context->font);
 75 
 76   G_OBJECT_CLASS (st_theme_context_parent_class)->finalize (object);
 77 }
 78 
 79 static void
 80 st_theme_context_class_init (StThemeContextClass *klass)
 81 {
 82   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 83 
 84   object_class->finalize = st_theme_context_finalize;
 85 
 86   signals[CHANGED] =
 87     g_signal_new ("changed",
 88                   G_TYPE_FROM_CLASS (klass),
 89                   G_SIGNAL_RUN_LAST,
 90                   0, /* no default handler slot */
 91                   NULL, NULL, NULL,
 92                   G_TYPE_NONE, 0);
 93 }
 94 
 95 static void
 96 st_theme_context_init (StThemeContext *context)
 97 {
 98   context->font = pango_font_description_from_string (DEFAULT_FONT);
 99 
100   g_signal_connect (st_texture_cache_get_default (),
101                     "icon-theme-changed",
102                     G_CALLBACK (on_icon_theme_changed),
103                     context);
104   g_signal_connect_swapped (clutter_get_default_backend (),
105                             "resolution-changed",
106                             G_CALLBACK (st_theme_context_changed),
107                             context);
108 }
109 
110 /**
111  * st_theme_context_new:
112  *
113  * Create a new theme context not associated with any #ClutterStage.
114  * This can be useful in testing scenarios, or if using StThemeContext
115  * with something other than #ClutterActor objects, but you generally
116  * should use st_theme_context_get_for_stage() instead.
117  */
118 StThemeContext *
119 st_theme_context_new (void)
120 {
121   StThemeContext *context;
122 
123   context = g_object_new (ST_TYPE_THEME_CONTEXT, NULL);
124 
125   return context;
126 }
127 
128 static void
129 on_stage_destroy (ClutterStage *stage)
130 {
131   StThemeContext *context = st_theme_context_get_for_stage (stage);
132 
133   g_object_set_data (G_OBJECT (stage), "st-theme-context", NULL);
134   g_object_unref (context);
135 }
136 
137 static gboolean
138 emit_changed (StThemeContext *context)
139 {
140   g_signal_emit (context, signals[CHANGED], 0);
141   return FALSE;
142 }
143 
144 static void
145 st_theme_context_changed (StThemeContext *context)
146 {
147   StThemeNode *old_root = context->root_node;
148   context->root_node = NULL;
149 
150   emit_changed (context);
151 
152   if (old_root)
153     g_object_unref (old_root);
154 }
155 
156 static void
157 on_icon_theme_changed (StTextureCache *cache,
158                        StThemeContext *context)
159 {
160   /* Note that an icon theme change isn't really a change of the StThemeContext;
161    * the style information has changed. But since the style factors into the
162    * icon_name => icon lookup, faking a theme context change is a good way
163    * to force users such as StIcon to look up icons again. Don't bother recreating
164    * the root node, though. */
165   g_idle_add ((GSourceFunc) emit_changed, context);
166 }
167 
168 /**
169  * st_theme_context_get_for_stage:
170  * @stage: a #ClutterStage
171  *
172  * Gets a singleton theme context associated with the stage.
173  *
174  * Return value: (transfer none): the singleton theme context for the stage
175  */
176 StThemeContext *
177 st_theme_context_get_for_stage (ClutterStage *stage)
178 {
179   StThemeContext *context;
180 
181   g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
182 
183   context = g_object_get_data (G_OBJECT (stage), "st-theme-context");
184   if (context)
185     return context;
186 
187   context = st_theme_context_new ();
188   g_object_set_data (G_OBJECT (stage), "st-theme-context", context);
189   g_signal_connect (stage, "destroy",
190                     G_CALLBACK (on_stage_destroy), NULL);
191 
192   return context;
193 }
194 
195 /**
196  * st_theme_context_set_theme:
197  * @context: a #StThemeContext
198  *
199  * Sets the default set of theme stylesheets for the context. This theme will
200  * be used for the root node and for nodes descending from it, unless some other
201  * style is explicitely specified.
202  */
203 void
204 st_theme_context_set_theme (StThemeContext          *context,
205                             StTheme                 *theme)
206 {
207   g_return_if_fail (ST_IS_THEME_CONTEXT (context));
208   g_return_if_fail (theme == NULL || ST_IS_THEME (theme));
209 
210   if (context->theme != theme)
211     {
212       if (context->theme)
213         g_object_unref (context->theme);
214 
215       context->theme = theme;
216 
217       if (context->theme)
218         g_object_ref (context->theme);
219 
220       st_theme_context_changed (context);
221     }
222 }
223 
224 /**
225  * st_theme_context_get_theme:
226  * @context: a #StThemeContext
227  *
228  * Gets the default theme for the context. See st_theme_context_set_theme()
229  *
230  * Return value: (transfer none): the default theme for the context
231  */
232 StTheme *
233 st_theme_context_get_theme (StThemeContext *context)
234 {
235   g_return_val_if_fail (ST_IS_THEME_CONTEXT (context), NULL);
236 
237   return context->theme;
238 }
239 
240 /**
241  * st_theme_context_set_font:
242  * @context: a #StThemeContext
243  * @font: the default font for theme context
244  *
245  * Sets the default font for the theme context. This is the font that
246  * is inherited by the root node of the tree of theme nodes. If the
247  * font is not overriden, then this font will be used. If the font is
248  * partially modified (for example, with 'font-size: 110%', then that
249  * modification is based on this font.
250  */
251 void
252 st_theme_context_set_font (StThemeContext             *context,
253                            const PangoFontDescription *font)
254 {
255   g_return_if_fail (ST_IS_THEME_CONTEXT (context));
256   g_return_if_fail (font != NULL);
257 
258   if (context->font == font ||
259       pango_font_description_equal (context->font, font))
260     return;
261 
262   pango_font_description_free (context->font);
263   context->font = pango_font_description_copy (font);
264   st_theme_context_changed (context);
265 }
266 
267 /**
268  * st_theme_context_get_font:
269  * @context: a #StThemeContext
270  *
271  * Gets the default font for the theme context. See st_theme_context_set_font().
272  *
273  * Return value: the default font for the theme context.
274  */
275 const PangoFontDescription *
276 st_theme_context_get_font (StThemeContext *context)
277 {
278   g_return_val_if_fail (ST_IS_THEME_CONTEXT (context), NULL);
279 
280   return context->font;
281 }
282 
283 /**
284  * st_theme_context_get_root_node:
285  * @context: a #StThemeContext
286  *
287  * Gets the root node of the tree of theme style nodes that associated with this
288  * context. For the node tree associated with a stage, this node represents
289  * styles applied to the stage itself.
290  *
291  * Return value: (transfer none): the root node of the context's style tree
292  */
293 StThemeNode *
294 st_theme_context_get_root_node (StThemeContext *context)
295 {
296   if (context->root_node == NULL)
297     context->root_node = st_theme_node_new (context, NULL, context->theme,
298                                             G_TYPE_NONE, NULL, NULL, NULL, NULL);
299 
300   return context->root_node;
301 }