1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 2011 Red Hat, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "config.h"
19
20 #include "gtkcssiconthemevalueprivate.h"
21
22 #include "gtkicontheme.h"
23 #include "gtksettingsprivate.h"
24 #include "gtkstyleproviderprivate.h"
25
26 /*
27 * The idea behind this value (and the '-gtk-icon-theme' CSS property) is
28 * to track changes to the icon theme.
29 *
30 * We create a new instance of this value whenever the icon theme changes
31 * (via emitting the changed signal). So as long as the icon theme does
32 * not change, we will compute the same value. We can then compare values
33 * by pointer to see if the icon theme changed.
34 */
35
36 struct _GtkCssValue {
37 GTK_CSS_VALUE_BASE
38 GtkIconTheme *icontheme;
39 guint changed_id;
40 };
41
42 static void
gtk_css_value_icon_theme_disconnect_handler(GtkCssValue * value)43 gtk_css_value_icon_theme_disconnect_handler (GtkCssValue *value)
44 {
45 if (value->changed_id == 0)
46 return;
47
48 g_object_set_data (G_OBJECT (value->icontheme), "-gtk-css-value", NULL);
49
50 g_signal_handler_disconnect (value->icontheme, value->changed_id);
51 value->changed_id = 0;
52 }
53
54 static void
gtk_css_value_icon_theme_changed_cb(GtkIconTheme * icontheme,GtkCssValue * value)55 gtk_css_value_icon_theme_changed_cb (GtkIconTheme *icontheme,
56 GtkCssValue *value)
57 {
58 gtk_css_value_icon_theme_disconnect_handler (value);
59 }
60
61 static void
gtk_css_value_icon_theme_free(GtkCssValue * value)62 gtk_css_value_icon_theme_free (GtkCssValue *value)
63 {
64 gtk_css_value_icon_theme_disconnect_handler (value);
65
66 if (value->icontheme)
67 g_object_unref (value->icontheme);
68
69 g_slice_free (GtkCssValue, value);
70 }
71
72 static GtkCssValue *
gtk_css_value_icon_theme_compute(GtkCssValue * icon_theme,guint property_id,GtkStyleProviderPrivate * provider,GtkCssStyle * style,GtkCssStyle * parent_style)73 gtk_css_value_icon_theme_compute (GtkCssValue *icon_theme,
74 guint property_id,
75 GtkStyleProviderPrivate *provider,
76 GtkCssStyle *style,
77 GtkCssStyle *parent_style)
78 {
79 GtkIconTheme *icontheme;
80
81 if (icon_theme->icontheme)
82 icontheme = icon_theme->icontheme;
83 else
84 icontheme = gtk_icon_theme_get_for_screen (_gtk_settings_get_screen (_gtk_style_provider_private_get_settings (provider)));
85
86 return gtk_css_icon_theme_value_new (icontheme);
87 }
88
89 static gboolean
gtk_css_value_icon_theme_equal(const GtkCssValue * value1,const GtkCssValue * value2)90 gtk_css_value_icon_theme_equal (const GtkCssValue *value1,
91 const GtkCssValue *value2)
92 {
93 return FALSE;
94 }
95
96 static GtkCssValue *
gtk_css_value_icon_theme_transition(GtkCssValue * start,GtkCssValue * end,guint property_id,double progress)97 gtk_css_value_icon_theme_transition (GtkCssValue *start,
98 GtkCssValue *end,
99 guint property_id,
100 double progress)
101 {
102 return NULL;
103 }
104
105 static void
gtk_css_value_icon_theme_print(const GtkCssValue * icon_theme,GString * string)106 gtk_css_value_icon_theme_print (const GtkCssValue *icon_theme,
107 GString *string)
108 {
109 g_string_append (string, "initial");
110 }
111
112 static const GtkCssValueClass GTK_CSS_VALUE_ICON_THEME = {
113 gtk_css_value_icon_theme_free,
114 gtk_css_value_icon_theme_compute,
115 gtk_css_value_icon_theme_equal,
116 gtk_css_value_icon_theme_transition,
117 gtk_css_value_icon_theme_print
118 };
119
120 static GtkCssValue default_icon_theme_value = { >K_CSS_VALUE_ICON_THEME, 1, NULL, 0 };
121
122 GtkCssValue *
gtk_css_icon_theme_value_new(GtkIconTheme * icontheme)123 gtk_css_icon_theme_value_new (GtkIconTheme *icontheme)
124 {
125 GtkCssValue *result;
126
127 if (icontheme == NULL)
128 return _gtk_css_value_ref (&default_icon_theme_value);
129
130 result = g_object_get_data (G_OBJECT (icontheme), "-gtk-css-value");
131 if (result)
132 return _gtk_css_value_ref (result);
133
134 result = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_ICON_THEME);
135 result->icontheme = g_object_ref (icontheme);
136
137 g_object_set_data (G_OBJECT (icontheme), "-gtk-css-value", result);
138 result->changed_id = g_signal_connect (icontheme, "changed", G_CALLBACK (gtk_css_value_icon_theme_changed_cb), result);
139
140 return result;
141 }
142
143 GtkCssValue *
gtk_css_icon_theme_value_parse(GtkCssParser * parser)144 gtk_css_icon_theme_value_parse (GtkCssParser *parser)
145 {
146 GtkIconTheme *icontheme;
147 GtkCssValue *result;
148 char *s;
149
150 s = _gtk_css_parser_read_string (parser);
151 if (s == NULL)
152 return NULL;
153
154 icontheme = gtk_icon_theme_new ();
155 gtk_icon_theme_set_custom_theme (icontheme, s);
156
157 result = gtk_css_icon_theme_value_new (icontheme);
158
159 g_object_unref (icontheme);
160 g_free (s);
161
162 return result;
163 }
164
165 GtkIconTheme *
gtk_css_icon_theme_value_get_icon_theme(GtkCssValue * value)166 gtk_css_icon_theme_value_get_icon_theme (GtkCssValue *value)
167 {
168 g_return_val_if_fail (value->class == >K_CSS_VALUE_ICON_THEME, NULL);
169
170 return value->icontheme;
171 }
172