1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 2015 Benjamin Otte <otte@gnome.org>
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 "gtkcssstylechangeprivate.h"
21 
22 #include "gtkcssstylepropertyprivate.h"
23 
24 static void
compute_change(GtkCssStyleChange * change)25 compute_change (GtkCssStyleChange *change)
26 {
27   gboolean color_changed = FALSE;
28 
29   if (change->old_style->core != change->new_style->core)
30     {
31       gtk_css_core_values_compute_changes_and_affects (change->old_style,
32                                                        change->new_style,
33                                                        &change->changes,
34                                                        &change->affects);
35       color_changed = _gtk_bitmask_get (change->changes, GTK_CSS_PROPERTY_COLOR);
36     }
37 
38   if (change->old_style->background != change->new_style->background)
39     gtk_css_background_values_compute_changes_and_affects (change->old_style,
40                                                            change->new_style,
41                                                            &change->changes,
42                                                            &change->affects);
43 
44   if (change->old_style->border != change->new_style->border ||
45       (color_changed && (change->old_style->border->border_top_color == NULL ||
46                          change->old_style->border->border_right_color == NULL ||
47                          change->old_style->border->border_bottom_color == NULL ||
48                          change->old_style->border->border_left_color == NULL)))
49     gtk_css_border_values_compute_changes_and_affects (change->old_style,
50                                                        change->new_style,
51                                                        &change->changes,
52                                                        &change->affects);
53 
54   if (change->old_style->icon != change->new_style->icon)
55     gtk_css_icon_values_compute_changes_and_affects (change->old_style,
56                                                      change->new_style,
57                                                      &change->changes,
58                                                      &change->affects);
59 
60   if (change->old_style->outline != change->new_style->outline ||
61       (color_changed && change->old_style->outline->outline_color == NULL))
62     gtk_css_outline_values_compute_changes_and_affects (change->old_style,
63                                                         change->new_style,
64                                                         &change->changes,
65                                                         &change->affects);
66 
67   if (change->old_style->font != change->new_style->font ||
68       (color_changed && (change->old_style->font->caret_color == NULL ||
69                          change->old_style->font->secondary_caret_color == NULL)))
70     gtk_css_font_values_compute_changes_and_affects (change->old_style,
71                                                      change->new_style,
72                                                      &change->changes,
73                                                      &change->affects);
74 
75   if (change->old_style->font_variant != change->new_style->font_variant ||
76       (color_changed && change->old_style->font_variant->text_decoration_color == NULL))
77     gtk_css_font_variant_values_compute_changes_and_affects (change->old_style,
78                                                              change->new_style,
79                                                              &change->changes,
80                                                              &change->affects);
81 
82   if (change->old_style->animation != change->new_style->animation)
83     gtk_css_animation_values_compute_changes_and_affects (change->old_style,
84                                                           change->new_style,
85                                                           &change->changes,
86                                                           &change->affects);
87 
88   if (change->old_style->transition != change->new_style->transition)
89     gtk_css_transition_values_compute_changes_and_affects (change->old_style,
90                                                            change->new_style,
91                                                            &change->changes,
92                                                            &change->affects);
93 
94   if (change->old_style->size != change->new_style->size)
95     gtk_css_size_values_compute_changes_and_affects (change->old_style,
96                                                      change->new_style,
97                                                      &change->changes,
98                                                      &change->affects);
99 
100   if (change->old_style->other != change->new_style->other)
101     gtk_css_other_values_compute_changes_and_affects (change->old_style,
102                                                       change->new_style,
103                                                       &change->changes,
104                                                       &change->affects);
105 }
106 
107 void
gtk_css_style_change_init(GtkCssStyleChange * change,GtkCssStyle * old_style,GtkCssStyle * new_style)108 gtk_css_style_change_init (GtkCssStyleChange *change,
109                            GtkCssStyle       *old_style,
110                            GtkCssStyle       *new_style)
111 {
112   change->old_style = g_object_ref (old_style);
113   change->new_style = g_object_ref (new_style);
114 
115   change->affects = 0;
116   change->changes = _gtk_bitmask_new ();
117 
118   if (old_style != new_style)
119     compute_change (change);
120 }
121 
122 void
gtk_css_style_change_finish(GtkCssStyleChange * change)123 gtk_css_style_change_finish (GtkCssStyleChange *change)
124 {
125   g_object_unref (change->old_style);
126   g_object_unref (change->new_style);
127   _gtk_bitmask_free (change->changes);
128 }
129 
130 GtkCssStyle *
gtk_css_style_change_get_old_style(GtkCssStyleChange * change)131 gtk_css_style_change_get_old_style (GtkCssStyleChange *change)
132 {
133   return change->old_style;
134 }
135 
136 GtkCssStyle *
gtk_css_style_change_get_new_style(GtkCssStyleChange * change)137 gtk_css_style_change_get_new_style (GtkCssStyleChange *change)
138 {
139   return change->new_style;
140 }
141 
142 gboolean
gtk_css_style_change_has_change(GtkCssStyleChange * change)143 gtk_css_style_change_has_change (GtkCssStyleChange *change)
144 {
145   return !_gtk_bitmask_is_empty (change->changes);
146 }
147 
148 gboolean
gtk_css_style_change_affects(GtkCssStyleChange * change,GtkCssAffects affects)149 gtk_css_style_change_affects (GtkCssStyleChange *change,
150                               GtkCssAffects      affects)
151 {
152   return (change->affects & affects) != 0;
153 }
154 
155 gboolean
gtk_css_style_change_changes_property(GtkCssStyleChange * change,guint id)156 gtk_css_style_change_changes_property (GtkCssStyleChange *change,
157                                        guint              id)
158 {
159   return _gtk_bitmask_get (change->changes, id);
160 }
161 
162 void
gtk_css_style_change_print(GtkCssStyleChange * change,GString * string)163 gtk_css_style_change_print (GtkCssStyleChange *change,
164                             GString           *string)
165 {
166   int i;
167   GtkCssStyle *old = gtk_css_style_change_get_old_style (change);
168   GtkCssStyle *new = gtk_css_style_change_get_new_style (change);
169 
170   for (i = 0; i < GTK_CSS_PROPERTY_N_PROPERTIES; i ++)
171     {
172       if (gtk_css_style_change_changes_property (change, i))
173         {
174           GtkCssStyleProperty *prop;
175           GtkCssValue *value;
176           const char *name;
177 
178           prop = _gtk_css_style_property_lookup_by_id (i);
179           name = _gtk_style_property_get_name (GTK_STYLE_PROPERTY (prop));
180 
181           g_string_append_printf (string, "%s: ", name);
182           value = gtk_css_style_get_value (old, i);
183           _gtk_css_value_print (value, string);
184           g_string_append (string, "\n");
185 
186           g_string_append_printf (string, "%s: ", name);
187           value = gtk_css_style_get_value (new, i);
188           _gtk_css_value_print (value, string);
189           g_string_append (string, "\n");
190         }
191     }
192 
193 }
194 
195 char *
gtk_css_style_change_to_string(GtkCssStyleChange * change)196 gtk_css_style_change_to_string (GtkCssStyleChange *change)
197 {
198   GString *string = g_string_new ("");
199 
200   gtk_css_style_change_print (change, string);
201 
202   return g_string_free (string, FALSE);
203 }
204