File: | ctk/ctkcssnode.c |
Warning: | line 187, column 1 Potential memory leak |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* CTK - The GIMP Toolkit | |||
2 | * Copyright (C) 2014 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 "ctkcssnodeprivate.h" | |||
21 | ||||
22 | #include "ctkcssanimatedstyleprivate.h" | |||
23 | #include "ctkcsssectionprivate.h" | |||
24 | #include "ctkcssstylepropertyprivate.h" | |||
25 | #include "ctkintl.h" | |||
26 | #include "ctkmarshalers.h" | |||
27 | #include "ctksettingsprivate.h" | |||
28 | #include "ctktypebuiltins.h" | |||
29 | ||||
30 | /* | |||
31 | * CSS nodes are the backbone of the CtkStyleContext implementation and | |||
32 | * replace the role that CtkWidgetPath played in the past. A CSS node has | |||
33 | * an element name and a state, and can have an id and style classes, which | |||
34 | * is what is needed to determine the matching CSS selectors. CSS nodes have | |||
35 | * a 'visible' property, which makes it possible to temporarily 'hide' them | |||
36 | * from CSS matching - e.g. an invisible node will not affect :nth-child | |||
37 | * matching and so forth. | |||
38 | * | |||
39 | * The API to manage states, names, ids and classes of CSS nodes is: | |||
40 | * - ctk_css_node_get/set_state. States are represented as CtkStateFlags | |||
41 | * - ctk_css_node_get/set_name. Names are represented as interned strings | |||
42 | * - ctk_css_node_get/set_id. Ids are represented as interned strings | |||
43 | * - ctk_css_node_add/remove/has_class and ctk_css_node_list_classes. Style | |||
44 | * classes are represented as quarks. | |||
45 | * | |||
46 | * CSS nodes are organized in a dom-like tree, and there is API to navigate | |||
47 | * and manipulate this tree: | |||
48 | * - ctk_css_node_set_parent | |||
49 | * - ctk_css_node_insert_before/after | |||
50 | * - ctk_css_node_get_parent | |||
51 | * - ctk_css_node_get_first/last_child | |||
52 | * - ctk_css_node_get_previous/next_sibling | |||
53 | * Note that parents keep a reference on their children in this tree. | |||
54 | * | |||
55 | * Every widget has one or more CSS nodes - the first one gets created | |||
56 | * automatically by CtkStyleContext. To set the name of the main node, | |||
57 | * call ctk_widget_class_set_css_name() in class_init(). Widget implementations | |||
58 | * can and should add subnodes as suitable. | |||
59 | * | |||
60 | * Best practice is: | |||
61 | * - For permanent subnodes, create them in init(), and keep a pointer | |||
62 | * to the node (you don't have to keep a reference, cleanup will be | |||
63 | * automatic by means of the parent node getting cleaned up by the | |||
64 | * style context). | |||
65 | * - For transient nodes, create/destroy them when the conditions that | |||
66 | * warrant their existence change. | |||
67 | * - Keep the state of all your nodes up-to-date. This probably requires | |||
68 | * a ::state-flags-changed (and possibly ::direction-changed) handler, | |||
69 | * as well as code to update the state in other places. Note that CTK+ | |||
70 | * does this automatically for the widget's main CSS node. | |||
71 | * - The sibling ordering in the CSS node tree is supposed to correspond | |||
72 | * to the visible order of content: top-to-bottom and left-to-right. | |||
73 | * Reorder your nodes to maintain this correlation. In particular for | |||
74 | * horizontally layed out widgets, this will require listening to | |||
75 | * ::direction-changed. | |||
76 | * - The draw function should just use ctk_style_context_save_to_node() to | |||
77 | * 'switch' to the right node, not make any other changes to the style | |||
78 | * context. | |||
79 | * | |||
80 | * A noteworthy difference between ctk_style_context_save() and | |||
81 | * ctk_style_context_save_to_node() is that the former inherits all the | |||
82 | * style classes from the main CSS node, which often leads to unintended | |||
83 | * inheritance. | |||
84 | */ | |||
85 | ||||
86 | /* When these change we do a full restyling. Otherwise we try to figure out | |||
87 | * if we need to change things. */ | |||
88 | #define CTK_CSS_RADICAL_CHANGE((1ULL << 2) | (1ULL << 1) | (1ULL << 0) | ( 1ULL << 32) | (1ULL << 33)) (CTK_CSS_CHANGE_ID(1ULL << 2) | CTK_CSS_CHANGE_NAME(1ULL << 1) | CTK_CSS_CHANGE_CLASS(1ULL << 0) | CTK_CSS_CHANGE_SOURCE(1ULL << 32) | CTK_CSS_CHANGE_PARENT_STYLE(1ULL << 33)) | |||
89 | ||||
90 | G_DEFINE_TYPE (CtkCssNode, ctk_css_node, G_TYPE_OBJECT)static void ctk_css_node_init (CtkCssNode *self); static void ctk_css_node_class_init (CtkCssNodeClass *klass); static GType ctk_css_node_get_type_once (void); static gpointer ctk_css_node_parent_class = ((void*)0); static gint CtkCssNode_private_offset; static void ctk_css_node_class_intern_init (gpointer klass) { ctk_css_node_parent_class = g_type_class_peek_parent (klass); if (CtkCssNode_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkCssNode_private_offset ); ctk_css_node_class_init ((CtkCssNodeClass*) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_css_node_get_instance_private (CtkCssNode *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkCssNode_private_offset)))); } GType ctk_css_node_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_css_node_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_css_node_get_type_once (void ) { GType g_define_type_id = g_type_register_static_simple (( (GType) ((20) << (2))), g_intern_static_string ("CtkCssNode" ), sizeof (CtkCssNodeClass), (GClassInitFunc)(void (*)(void)) ctk_css_node_class_intern_init, sizeof (CtkCssNode), (GInstanceInitFunc )(void (*)(void)) ctk_css_node_init, (GTypeFlags) 0); { {{};} } return g_define_type_id; } | |||
91 | ||||
92 | enum { | |||
93 | NODE_ADDED, | |||
94 | NODE_REMOVED, | |||
95 | STYLE_CHANGED, | |||
96 | LAST_SIGNAL | |||
97 | }; | |||
98 | ||||
99 | enum { | |||
100 | PROP_0, | |||
101 | PROP_CLASSES, | |||
102 | PROP_ID, | |||
103 | PROP_NAME, | |||
104 | PROP_STATE, | |||
105 | PROP_VISIBLE, | |||
106 | PROP_WIDGET_TYPE, | |||
107 | NUM_PROPERTIES | |||
108 | }; | |||
109 | ||||
110 | struct _CtkCssNodeStyleChange { | |||
111 | CtkCssStyle *old_style; | |||
112 | CtkCssStyle *new_style; | |||
113 | }; | |||
114 | ||||
115 | static guint cssnode_signals[LAST_SIGNAL] = { 0 }; | |||
116 | static GParamSpec *cssnode_properties[NUM_PROPERTIES]; | |||
117 | ||||
118 | static CtkStyleProviderPrivate * | |||
119 | ctk_css_node_get_style_provider_or_null (CtkCssNode *cssnode) | |||
120 | { | |||
121 | return CTK_CSS_NODE_GET_CLASS (cssnode)((((CtkCssNodeClass*) (((GTypeInstance*) ((cssnode)))->g_class ))))->get_style_provider (cssnode); | |||
122 | } | |||
123 | ||||
124 | static void | |||
125 | ctk_css_node_set_invalid (CtkCssNode *node, | |||
126 | gboolean invalid) | |||
127 | { | |||
128 | if (node->invalid == invalid) | |||
129 | return; | |||
130 | ||||
131 | node->invalid = invalid; | |||
132 | ||||
133 | if (node->visible) | |||
134 | { | |||
135 | if (node->parent) | |||
136 | { | |||
137 | if (invalid) | |||
138 | ctk_css_node_set_invalid (node->parent, TRUE(!(0))); | |||
139 | } | |||
140 | else | |||
141 | { | |||
142 | if (invalid) | |||
143 | CTK_CSS_NODE_GET_CLASS (node)((((CtkCssNodeClass*) (((GTypeInstance*) ((node)))->g_class ))))->queue_validate (node); | |||
144 | else | |||
145 | CTK_CSS_NODE_GET_CLASS (node)((((CtkCssNodeClass*) (((GTypeInstance*) ((node)))->g_class ))))->dequeue_validate (node); | |||
146 | } | |||
147 | } | |||
148 | } | |||
149 | ||||
150 | static void | |||
151 | ctk_css_node_get_property (GObject *object, | |||
152 | guint property_id, | |||
153 | GValue *value, | |||
154 | GParamSpec *pspec) | |||
155 | { | |||
156 | CtkCssNode *cssnode = CTK_CSS_NODE (object)((((CtkCssNode*) (void *) g_type_check_instance_cast ((GTypeInstance *) (object), ((ctk_css_node_get_type ())))))); | |||
157 | ||||
158 | switch (property_id) | |||
| ||||
159 | { | |||
160 | case PROP_CLASSES: | |||
161 | g_value_take_boxed (value, ctk_css_node_get_classes (cssnode)); | |||
162 | break; | |||
163 | ||||
164 | case PROP_ID: | |||
165 | g_value_set_string (value, ctk_css_node_get_id (cssnode)); | |||
166 | break; | |||
167 | ||||
168 | case PROP_NAME: | |||
169 | g_value_set_string (value, ctk_css_node_get_name (cssnode)); | |||
170 | break; | |||
171 | ||||
172 | case PROP_STATE: | |||
173 | g_value_set_flags (value, ctk_css_node_get_state (cssnode)); | |||
174 | break; | |||
175 | ||||
176 | case PROP_VISIBLE: | |||
177 | g_value_set_boolean (value, ctk_css_node_get_visible (cssnode)); | |||
178 | break; | |||
179 | ||||
180 | case PROP_WIDGET_TYPE: | |||
181 | g_value_set_gtype (value, ctk_css_node_get_widget_type (cssnode)); | |||
182 | break; | |||
183 | ||||
184 | default: | |||
185 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((property_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctkcssnode.c", 185, ("property"), _glib__property_id, _glib__pspec ->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) ( _glib__pspec))->g_class))->g_type)))), (g_type_name ((( (((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); | |||
186 | } | |||
187 | } | |||
| ||||
188 | ||||
189 | static void | |||
190 | ctk_css_node_set_property (GObject *object, | |||
191 | guint property_id, | |||
192 | const GValue *value, | |||
193 | GParamSpec *pspec) | |||
194 | { | |||
195 | CtkCssNode *cssnode = CTK_CSS_NODE (object)((((CtkCssNode*) (void *) g_type_check_instance_cast ((GTypeInstance *) (object), ((ctk_css_node_get_type ())))))); | |||
196 | ||||
197 | switch (property_id) | |||
198 | { | |||
199 | case PROP_CLASSES: | |||
200 | ctk_css_node_set_classes (cssnode, g_value_get_boxed (value)); | |||
201 | break; | |||
202 | ||||
203 | case PROP_ID: | |||
204 | ctk_css_node_set_id (cssnode, g_value_get_string (value)); | |||
205 | break; | |||
206 | ||||
207 | case PROP_NAME: | |||
208 | ctk_css_node_set_name (cssnode, g_value_get_string (value)); | |||
209 | break; | |||
210 | ||||
211 | case PROP_STATE: | |||
212 | ctk_css_node_set_state (cssnode, g_value_get_flags (value)); | |||
213 | break; | |||
214 | ||||
215 | case PROP_VISIBLE: | |||
216 | ctk_css_node_set_visible (cssnode, g_value_get_boolean (value)); | |||
217 | break; | |||
218 | ||||
219 | case PROP_WIDGET_TYPE: | |||
220 | ctk_css_node_set_widget_type (cssnode, g_value_get_gtype (value)); | |||
221 | break; | |||
222 | ||||
223 | default: | |||
224 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((property_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctkcssnode.c", 224, ("property"), _glib__property_id, _glib__pspec ->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) ( _glib__pspec))->g_class))->g_type)))), (g_type_name ((( (((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); | |||
225 | } | |||
226 | } | |||
227 | ||||
228 | static void | |||
229 | ctk_css_node_dispose (GObject *object) | |||
230 | { | |||
231 | CtkCssNode *cssnode = CTK_CSS_NODE (object)((((CtkCssNode*) (void *) g_type_check_instance_cast ((GTypeInstance *) (object), ((ctk_css_node_get_type ())))))); | |||
232 | ||||
233 | while (cssnode->first_child) | |||
234 | { | |||
235 | ctk_css_node_set_parent (cssnode->first_child, NULL((void*)0)); | |||
236 | } | |||
237 | ||||
238 | ctk_css_node_set_invalid (cssnode, FALSE(0)); | |||
239 | ||||
240 | g_clear_pointer (&cssnode->cache, ctk_css_node_style_cache_unref)do { _Static_assert (sizeof *(&cssnode->cache) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ ((& cssnode->cache)) _pp = (&cssnode->cache); __typeof__ (*(&cssnode->cache)) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (ctk_css_node_style_cache_unref) (_ptr); } while (0); | |||
241 | ||||
242 | G_OBJECT_CLASS (ctk_css_node_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_css_node_parent_class)), (((GType) ((20) << (2 ))))))))->dispose (object); | |||
243 | } | |||
244 | ||||
245 | static void | |||
246 | ctk_css_node_finalize (GObject *object) | |||
247 | { | |||
248 | CtkCssNode *cssnode = CTK_CSS_NODE (object)((((CtkCssNode*) (void *) g_type_check_instance_cast ((GTypeInstance *) (object), ((ctk_css_node_get_type ())))))); | |||
249 | ||||
250 | if (cssnode->style) | |||
251 | g_object_unref (cssnode->style); | |||
252 | ctk_css_node_declaration_unref (cssnode->decl); | |||
253 | ||||
254 | G_OBJECT_CLASS (ctk_css_node_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_css_node_parent_class)), (((GType) ((20) << (2 ))))))))->finalize (object); | |||
255 | } | |||
256 | ||||
257 | static gboolean | |||
258 | ctk_css_node_is_first_child (CtkCssNode *node) | |||
259 | { | |||
260 | CtkCssNode *iter; | |||
261 | ||||
262 | for (iter = node->previous_sibling; | |||
263 | iter != NULL((void*)0); | |||
264 | iter = iter->previous_sibling) | |||
265 | { | |||
266 | if (iter->visible) | |||
267 | return FALSE(0); | |||
268 | } | |||
269 | return TRUE(!(0)); | |||
270 | } | |||
271 | ||||
272 | static gboolean | |||
273 | ctk_css_node_is_last_child (CtkCssNode *node) | |||
274 | { | |||
275 | CtkCssNode *iter; | |||
276 | ||||
277 | for (iter = node->next_sibling; | |||
278 | iter != NULL((void*)0); | |||
279 | iter = iter->next_sibling) | |||
280 | { | |||
281 | if (iter->visible) | |||
282 | return FALSE(0); | |||
283 | } | |||
284 | return TRUE(!(0)); | |||
285 | } | |||
286 | ||||
287 | static gboolean | |||
288 | may_use_global_parent_cache (CtkCssNode *node) | |||
289 | { | |||
290 | CtkStyleProviderPrivate *provider; | |||
291 | CtkCssNode *parent; | |||
292 | ||||
293 | parent = ctk_css_node_get_parent (node); | |||
294 | if (parent == NULL((void*)0)) | |||
295 | return FALSE(0); | |||
296 | ||||
297 | provider = ctk_css_node_get_style_provider_or_null (node); | |||
298 | if (provider != NULL((void*)0) && provider != ctk_css_node_get_style_provider (parent)) | |||
299 | return FALSE(0); | |||
300 | ||||
301 | return TRUE(!(0)); | |||
302 | } | |||
303 | ||||
304 | static CtkCssStyle * | |||
305 | lookup_in_global_parent_cache (CtkCssNode *node, | |||
306 | const CtkCssNodeDeclaration *decl) | |||
307 | { | |||
308 | CtkCssNode *parent; | |||
309 | ||||
310 | parent = node->parent; | |||
311 | ||||
312 | if (parent == NULL((void*)0) || | |||
313 | !may_use_global_parent_cache (node)) | |||
314 | return NULL((void*)0); | |||
315 | ||||
316 | if (parent->cache == NULL((void*)0)) | |||
317 | return NULL((void*)0); | |||
318 | ||||
319 | g_assert (node->cache == NULL)do { if (node->cache == ((void*)0)) ; else g_assertion_message_expr ("Ctk", "ctkcssnode.c", 319, ((const char*) (__func__)), "node->cache == NULL" ); } while (0); | |||
320 | node->cache = ctk_css_node_style_cache_lookup (parent->cache, | |||
321 | decl, | |||
322 | ctk_css_node_is_first_child (node), | |||
323 | ctk_css_node_is_last_child (node)); | |||
324 | if (node->cache == NULL((void*)0)) | |||
325 | return NULL((void*)0); | |||
326 | ||||
327 | return ctk_css_node_style_cache_get_style (node->cache); | |||
328 | } | |||
329 | ||||
330 | static void | |||
331 | store_in_global_parent_cache (CtkCssNode *node, | |||
332 | const CtkCssNodeDeclaration *decl, | |||
333 | CtkCssStyle *style) | |||
334 | { | |||
335 | CtkCssNode *parent; | |||
336 | ||||
337 | g_assert (CTK_IS_CSS_STATIC_STYLE (style))do { if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) (style); GType __t = ((ctk_css_static_style_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0) ); else __r = g_type_check_instance_is_a (__inst, __t); __r; } ))))) ; else g_assertion_message_expr ("Ctk", "ctkcssnode.c", 337, ((const char*) (__func__)), "CTK_IS_CSS_STATIC_STYLE (style)" ); } while (0); | |||
338 | ||||
339 | parent = node->parent; | |||
340 | ||||
341 | if (parent == NULL((void*)0) || | |||
342 | !may_use_global_parent_cache (node)) | |||
343 | return; | |||
344 | ||||
345 | if (parent->cache == NULL((void*)0)) | |||
346 | parent->cache = ctk_css_node_style_cache_new (parent->style); | |||
347 | ||||
348 | node->cache = ctk_css_node_style_cache_insert (parent->cache, | |||
349 | (CtkCssNodeDeclaration *) decl, | |||
350 | ctk_css_node_is_first_child (node), | |||
351 | ctk_css_node_is_last_child (node), | |||
352 | style); | |||
353 | } | |||
354 | ||||
355 | static CtkCssStyle * | |||
356 | ctk_css_node_create_style (CtkCssNode *cssnode) | |||
357 | { | |||
358 | const CtkCssNodeDeclaration *decl; | |||
359 | CtkCssMatcher matcher; | |||
360 | CtkCssStyle *parent; | |||
361 | CtkCssStyle *style; | |||
362 | ||||
363 | decl = ctk_css_node_get_declaration (cssnode); | |||
364 | parent = cssnode->parent ? cssnode->parent->style : NULL((void*)0); | |||
365 | ||||
366 | style = lookup_in_global_parent_cache (cssnode, decl); | |||
367 | if (style) | |||
368 | return g_object_ref (style)((__typeof__ (style)) (g_object_ref) (style)); | |||
369 | ||||
370 | if (ctk_css_node_init_matcher (cssnode, &matcher)) | |||
371 | style = ctk_css_static_style_new_compute (ctk_css_node_get_style_provider (cssnode), | |||
372 | &matcher, | |||
373 | parent); | |||
374 | else | |||
375 | style = ctk_css_static_style_new_compute (ctk_css_node_get_style_provider (cssnode), | |||
376 | NULL((void*)0), | |||
377 | parent); | |||
378 | ||||
379 | store_in_global_parent_cache (cssnode, decl, style); | |||
380 | ||||
381 | return style; | |||
382 | } | |||
383 | ||||
384 | static gboolean | |||
385 | should_create_transitions (CtkCssChange change) | |||
386 | { | |||
387 | return (change & CTK_CSS_CHANGE_ANIMATIONS(1ULL << 35)) == 0; | |||
388 | } | |||
389 | ||||
390 | static gboolean | |||
391 | ctk_css_style_needs_recreation (CtkCssStyle *style, | |||
392 | CtkCssChange change) | |||
393 | { | |||
394 | /* Try to avoid invalidating if we can */ | |||
395 | if (change & CTK_CSS_RADICAL_CHANGE((1ULL << 2) | (1ULL << 1) | (1ULL << 0) | ( 1ULL << 32) | (1ULL << 33))) | |||
396 | return TRUE(!(0)); | |||
397 | ||||
398 | if (CTK_IS_CSS_ANIMATED_STYLE (style)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( style); GType __t = ((ctk_css_animated_style_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) | |||
399 | style = CTK_CSS_ANIMATED_STYLE (style)((((CtkCssAnimatedStyle*) (void *) g_type_check_instance_cast ((GTypeInstance*) (style), ((ctk_css_animated_style_get_type ()))))))->style; | |||
400 | ||||
401 | if (ctk_css_static_style_get_change (CTK_CSS_STATIC_STYLE (style)((((CtkCssStaticStyle*) (void *) g_type_check_instance_cast ( (GTypeInstance*) (style), ((ctk_css_static_style_get_type ()) )))))) & change) | |||
402 | return TRUE(!(0)); | |||
403 | else | |||
404 | return FALSE(0); | |||
405 | } | |||
406 | ||||
407 | static CtkCssStyle * | |||
408 | ctk_css_node_real_update_style (CtkCssNode *cssnode, | |||
409 | CtkCssChange change, | |||
410 | gint64 timestamp, | |||
411 | CtkCssStyle *style) | |||
412 | { | |||
413 | CtkCssStyle *static_style, *new_static_style, *new_style; | |||
414 | ||||
415 | if (CTK_IS_CSS_ANIMATED_STYLE (style)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( style); GType __t = ((ctk_css_animated_style_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) | |||
416 | { | |||
417 | static_style = CTK_CSS_ANIMATED_STYLE (style)((((CtkCssAnimatedStyle*) (void *) g_type_check_instance_cast ((GTypeInstance*) (style), ((ctk_css_animated_style_get_type ()))))))->style; | |||
418 | } | |||
419 | else | |||
420 | { | |||
421 | static_style = style; | |||
422 | } | |||
423 | ||||
424 | if (ctk_css_style_needs_recreation (static_style, change)) | |||
425 | new_static_style = ctk_css_node_create_style (cssnode); | |||
426 | else | |||
427 | new_static_style = g_object_ref (static_style)((__typeof__ (static_style)) (g_object_ref) (static_style)); | |||
428 | ||||
429 | if (new_static_style != static_style || (change & CTK_CSS_CHANGE_ANIMATIONS(1ULL << 35))) | |||
430 | { | |||
431 | CtkCssNode *parent = ctk_css_node_get_parent (cssnode); | |||
432 | new_style = ctk_css_animated_style_new (new_static_style, | |||
433 | parent ? ctk_css_node_get_style (parent) : NULL((void*)0), | |||
434 | timestamp, | |||
435 | ctk_css_node_get_style_provider (cssnode), | |||
436 | should_create_transitions (change) ? style : NULL((void*)0)); | |||
437 | ||||
438 | /* Clear the cache again, the static style we looked up above | |||
439 | * may have populated it. */ | |||
440 | g_clear_pointer (&cssnode->cache, ctk_css_node_style_cache_unref)do { _Static_assert (sizeof *(&cssnode->cache) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ ((& cssnode->cache)) _pp = (&cssnode->cache); __typeof__ (*(&cssnode->cache)) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (ctk_css_node_style_cache_unref) (_ptr); } while (0); | |||
441 | } | |||
442 | else if (static_style != style && (change & CTK_CSS_CHANGE_TIMESTAMP(1ULL << 34))) | |||
443 | { | |||
444 | new_style = ctk_css_animated_style_new_advance (CTK_CSS_ANIMATED_STYLE (style)((((CtkCssAnimatedStyle*) (void *) g_type_check_instance_cast ((GTypeInstance*) (style), ((ctk_css_animated_style_get_type ())))))), | |||
445 | static_style, | |||
446 | timestamp); | |||
447 | } | |||
448 | else | |||
449 | { | |||
450 | new_style = g_object_ref (style)((__typeof__ (style)) (g_object_ref) (style)); | |||
451 | } | |||
452 | ||||
453 | if (!ctk_css_style_is_static (new_style)) | |||
454 | ctk_css_node_set_invalid (cssnode, TRUE(!(0))); | |||
455 | ||||
456 | g_object_unref (new_static_style); | |||
457 | ||||
458 | return new_style; | |||
459 | } | |||
460 | ||||
461 | static void | |||
462 | ctk_css_node_real_invalidate (CtkCssNode *node G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
463 | { | |||
464 | } | |||
465 | ||||
466 | static void | |||
467 | ctk_css_node_real_queue_validate (CtkCssNode *node G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
468 | { | |||
469 | } | |||
470 | ||||
471 | static void | |||
472 | ctk_css_node_real_dequeue_validate (CtkCssNode *node G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
473 | { | |||
474 | } | |||
475 | ||||
476 | static void | |||
477 | ctk_css_node_real_validate (CtkCssNode *node G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
478 | { | |||
479 | } | |||
480 | ||||
481 | gboolean | |||
482 | ctk_css_node_real_init_matcher (CtkCssNode *cssnode, | |||
483 | CtkCssMatcher *matcher) | |||
484 | { | |||
485 | _ctk_css_matcher_node_init (matcher, cssnode); | |||
486 | ||||
487 | return TRUE(!(0)); | |||
488 | } | |||
489 | ||||
490 | static CtkWidgetPath * | |||
491 | ctk_css_node_real_create_widget_path (CtkCssNode *cssnode G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
492 | { | |||
493 | return ctk_widget_path_new (); | |||
494 | } | |||
495 | ||||
496 | static const CtkWidgetPath * | |||
497 | ctk_css_node_real_get_widget_path (CtkCssNode *cssnode G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
498 | { | |||
499 | return NULL((void*)0); | |||
500 | } | |||
501 | ||||
502 | static CtkStyleProviderPrivate * | |||
503 | ctk_css_node_real_get_style_provider (CtkCssNode *cssnode G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
504 | { | |||
505 | return NULL((void*)0); | |||
506 | } | |||
507 | ||||
508 | static CdkFrameClock * | |||
509 | ctk_css_node_real_get_frame_clock (CtkCssNode *cssnode G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
510 | { | |||
511 | return NULL((void*)0); | |||
512 | } | |||
513 | ||||
514 | static void | |||
515 | ctk_css_node_real_node_removed (CtkCssNode *parent G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
516 | CtkCssNode *node, | |||
517 | CtkCssNode *previous G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
518 | { | |||
519 | if (node->previous_sibling) | |||
520 | node->previous_sibling->next_sibling = node->next_sibling; | |||
521 | else | |||
522 | node->parent->first_child = node->next_sibling; | |||
523 | ||||
524 | if (node->next_sibling) | |||
525 | node->next_sibling->previous_sibling = node->previous_sibling; | |||
526 | else | |||
527 | node->parent->last_child = node->previous_sibling; | |||
528 | ||||
529 | node->previous_sibling = NULL((void*)0); | |||
530 | node->next_sibling = NULL((void*)0); | |||
531 | node->parent = NULL((void*)0); | |||
532 | } | |||
533 | ||||
534 | static void | |||
535 | ctk_css_node_real_node_added (CtkCssNode *parent, | |||
536 | CtkCssNode *node, | |||
537 | CtkCssNode *new_previous) | |||
538 | { | |||
539 | if (new_previous) | |||
540 | { | |||
541 | node->previous_sibling = new_previous; | |||
542 | node->next_sibling = new_previous->next_sibling; | |||
543 | new_previous->next_sibling = node; | |||
544 | } | |||
545 | else | |||
546 | { | |||
547 | node->next_sibling = parent->first_child; | |||
548 | parent->first_child = node; | |||
549 | } | |||
550 | ||||
551 | if (node->next_sibling) | |||
552 | node->next_sibling->previous_sibling = node; | |||
553 | else | |||
554 | parent->last_child = node; | |||
555 | ||||
556 | node->parent = parent; | |||
557 | } | |||
558 | ||||
559 | static void | |||
560 | ctk_css_node_real_style_changed (CtkCssNode *cssnode, | |||
561 | CtkCssStyleChange *change) | |||
562 | { | |||
563 | g_set_object (&cssnode->style, ctk_css_style_change_get_new_style (change))(__extension__ ({ _Static_assert (sizeof *(&cssnode->style ) == sizeof (ctk_css_style_change_get_new_style (change)), "Expression evaluates to false" ); union { char *in; GObject **out; } _object_ptr; _object_ptr .in = (char *) (&cssnode->style); (void) (0 ? *(&cssnode ->style) = (ctk_css_style_change_get_new_style (change)), ( 0) : (0)); (g_set_object) (_object_ptr.out, (GObject *) ctk_css_style_change_get_new_style (change)); })); | |||
564 | } | |||
565 | ||||
566 | static void | |||
567 | ctk_css_node_class_init (CtkCssNodeClass *klass) | |||
568 | { | |||
569 | GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((klass)), (((GType) ((20) << (2)))))))); | |||
570 | ||||
571 | object_class->get_property = ctk_css_node_get_property; | |||
572 | object_class->set_property = ctk_css_node_set_property; | |||
573 | object_class->dispose = ctk_css_node_dispose; | |||
574 | object_class->finalize = ctk_css_node_finalize; | |||
575 | ||||
576 | klass->update_style = ctk_css_node_real_update_style; | |||
577 | klass->invalidate = ctk_css_node_real_invalidate; | |||
578 | klass->validate = ctk_css_node_real_validate; | |||
579 | klass->queue_validate = ctk_css_node_real_queue_validate; | |||
580 | klass->dequeue_validate = ctk_css_node_real_dequeue_validate; | |||
581 | klass->init_matcher = ctk_css_node_real_init_matcher; | |||
582 | klass->create_widget_path = ctk_css_node_real_create_widget_path; | |||
583 | klass->get_widget_path = ctk_css_node_real_get_widget_path; | |||
584 | klass->get_style_provider = ctk_css_node_real_get_style_provider; | |||
585 | klass->get_frame_clock = ctk_css_node_real_get_frame_clock; | |||
586 | ||||
587 | klass->node_added = ctk_css_node_real_node_added; | |||
588 | klass->node_removed = ctk_css_node_real_node_removed; | |||
589 | klass->style_changed = ctk_css_node_real_style_changed; | |||
590 | ||||
591 | cssnode_signals[NODE_ADDED] = | |||
592 | g_signal_new (I_("node-added")g_intern_static_string ("node-added"), | |||
593 | G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type), | |||
594 | G_SIGNAL_RUN_LAST, | |||
595 | G_STRUCT_OFFSET (CtkCssNodeClass, node_added)((glong) __builtin_offsetof(CtkCssNodeClass, node_added)), | |||
596 | NULL((void*)0), NULL((void*)0), | |||
597 | _ctk_marshal_VOID__OBJECT_OBJECT, | |||
598 | G_TYPE_NONE((GType) ((1) << (2))), 2, | |||
599 | CTK_TYPE_CSS_NODE(ctk_css_node_get_type ()), CTK_TYPE_CSS_NODE(ctk_css_node_get_type ())); | |||
600 | g_signal_set_va_marshaller (cssnode_signals[NODE_ADDED], | |||
601 | G_TYPE_FROM_CLASS (klass)(((GTypeClass*) (klass))->g_type), | |||
602 | _ctk_marshal_VOID__OBJECT_OBJECTv); | |||
603 | ||||
604 | cssnode_signals[NODE_REMOVED] = | |||
605 | g_signal_new (I_("node-removed")g_intern_static_string ("node-removed"), | |||
606 | G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type), | |||
607 | G_SIGNAL_RUN_LAST, | |||
608 | G_STRUCT_OFFSET (CtkCssNodeClass, node_removed)((glong) __builtin_offsetof(CtkCssNodeClass, node_removed)), | |||
609 | NULL((void*)0), NULL((void*)0), | |||
610 | _ctk_marshal_VOID__OBJECT_OBJECT, | |||
611 | G_TYPE_NONE((GType) ((1) << (2))), 2, | |||
612 | CTK_TYPE_CSS_NODE(ctk_css_node_get_type ()), CTK_TYPE_CSS_NODE(ctk_css_node_get_type ())); | |||
613 | g_signal_set_va_marshaller (cssnode_signals[NODE_REMOVED], | |||
614 | G_TYPE_FROM_CLASS (klass)(((GTypeClass*) (klass))->g_type), | |||
615 | _ctk_marshal_VOID__OBJECT_OBJECTv); | |||
616 | ||||
617 | cssnode_signals[STYLE_CHANGED] = | |||
618 | g_signal_new (I_("style-changed")g_intern_static_string ("style-changed"), | |||
619 | G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type), | |||
620 | G_SIGNAL_RUN_LAST, | |||
621 | G_STRUCT_OFFSET (CtkCssNodeClass, style_changed)((glong) __builtin_offsetof(CtkCssNodeClass, style_changed)), | |||
622 | NULL((void*)0), NULL((void*)0), | |||
623 | NULL((void*)0), | |||
624 | G_TYPE_NONE((GType) ((1) << (2))), 1, | |||
625 | G_TYPE_POINTER((GType) ((17) << (2)))); | |||
626 | ||||
627 | cssnode_properties[PROP_CLASSES] = | |||
628 | g_param_spec_boxed ("classes", P_("Style Classes")g_dgettext("ctk30" "-properties","Style Classes"), P_("List of classes")g_dgettext("ctk30" "-properties","List of classes"), | |||
629 | G_TYPE_STRV(g_strv_get_type ()), | |||
630 | G_PARAM_READWRITE | |||
631 | | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB )); | |||
632 | cssnode_properties[PROP_ID] = | |||
633 | g_param_spec_string ("id", P_("ID")g_dgettext("ctk30" "-properties","ID"), P_("Unique ID")g_dgettext("ctk30" "-properties","Unique ID"), | |||
634 | NULL((void*)0), | |||
635 | G_PARAM_READWRITE | |||
636 | | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB )); | |||
637 | cssnode_properties[PROP_NAME] = | |||
638 | g_param_spec_string ("name", P_("Name")g_dgettext("ctk30" "-properties","Name"), "Name identifying the type of node", | |||
639 | NULL((void*)0), | |||
640 | G_PARAM_READWRITE | |||
641 | | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB )); | |||
642 | cssnode_properties[PROP_STATE] = | |||
643 | g_param_spec_flags ("state", P_("State")g_dgettext("ctk30" "-properties","State"), P_("State flags")g_dgettext("ctk30" "-properties","State flags"), | |||
644 | CTK_TYPE_STATE_FLAGS(ctk_state_flags_get_type ()), | |||
645 | 0, | |||
646 | G_PARAM_READWRITE | |||
647 | | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB )); | |||
648 | cssnode_properties[PROP_VISIBLE] = | |||
649 | g_param_spec_boolean ("visible", P_("Visible")g_dgettext("ctk30" "-properties","Visible"), P_("If other nodes can see this node")g_dgettext("ctk30" "-properties","If other nodes can see this node" ), | |||
650 | TRUE(!(0)), | |||
651 | G_PARAM_READWRITE | |||
652 | | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB )); | |||
653 | cssnode_properties[PROP_WIDGET_TYPE] = | |||
654 | g_param_spec_gtype ("widget-type", P_("Widget type")g_dgettext("ctk30" "-properties","Widget type"), P_("GType of the widget")g_dgettext("ctk30" "-properties","GType of the widget"), | |||
655 | G_TYPE_NONE((GType) ((1) << (2))), | |||
656 | G_PARAM_READWRITE | |||
657 | | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB )); | |||
658 | ||||
659 | g_object_class_install_properties (object_class, NUM_PROPERTIES, cssnode_properties); | |||
660 | } | |||
661 | ||||
662 | static void | |||
663 | ctk_css_node_init (CtkCssNode *cssnode) | |||
664 | { | |||
665 | cssnode->decl = ctk_css_node_declaration_new (); | |||
666 | ||||
667 | cssnode->style = g_object_ref (ctk_css_static_style_get_default ())((__typeof__ (ctk_css_static_style_get_default ())) (g_object_ref ) (ctk_css_static_style_get_default ())); | |||
668 | ||||
669 | cssnode->visible = TRUE(!(0)); | |||
670 | } | |||
671 | ||||
672 | /** | |||
673 | * ctk_css_node_new: | |||
674 | * | |||
675 | * Creates a new CSS node. | |||
676 | * | |||
677 | * Returns: (transfer full): the new CSS node | |||
678 | */ | |||
679 | CtkCssNode * | |||
680 | ctk_css_node_new (void) | |||
681 | { | |||
682 | return g_object_new (CTK_TYPE_CSS_NODE(ctk_css_node_get_type ()), NULL((void*)0)); | |||
683 | } | |||
684 | ||||
685 | static CdkFrameClock * | |||
686 | ctk_css_node_get_frame_clock_or_null (CtkCssNode *cssnode) | |||
687 | { | |||
688 | while (cssnode->parent) | |||
689 | cssnode = cssnode->parent; | |||
690 | ||||
691 | return CTK_CSS_NODE_GET_CLASS (cssnode)((((CtkCssNodeClass*) (((GTypeInstance*) ((cssnode)))->g_class ))))->get_frame_clock (cssnode); | |||
692 | } | |||
693 | ||||
694 | static gint64 | |||
695 | ctk_css_node_get_timestamp (CtkCssNode *cssnode) | |||
696 | { | |||
697 | CdkFrameClock *frameclock; | |||
698 | ||||
699 | frameclock = ctk_css_node_get_frame_clock_or_null (cssnode); | |||
700 | if (frameclock == NULL((void*)0)) | |||
701 | return 0; | |||
702 | ||||
703 | return cdk_frame_clock_get_frame_time (frameclock); | |||
704 | } | |||
705 | ||||
706 | static void | |||
707 | ctk_css_node_parent_was_unset (CtkCssNode *node) | |||
708 | { | |||
709 | if (node->visible && node->invalid) | |||
710 | CTK_CSS_NODE_GET_CLASS (node)((((CtkCssNodeClass*) (((GTypeInstance*) ((node)))->g_class ))))->queue_validate (node); | |||
711 | } | |||
712 | ||||
713 | static void | |||
714 | ctk_css_node_parent_will_be_set (CtkCssNode *node) | |||
715 | { | |||
716 | if (node->visible && node->invalid) | |||
717 | CTK_CSS_NODE_GET_CLASS (node)((((CtkCssNodeClass*) (((GTypeInstance*) ((node)))->g_class ))))->dequeue_validate (node); | |||
718 | } | |||
719 | ||||
720 | static void | |||
721 | ctk_css_node_invalidate_style (CtkCssNode *cssnode) | |||
722 | { | |||
723 | if (cssnode->style_is_invalid) | |||
724 | return; | |||
725 | ||||
726 | cssnode->style_is_invalid = TRUE(!(0)); | |||
727 | ctk_css_node_set_invalid (cssnode, TRUE(!(0))); | |||
728 | ||||
729 | if (cssnode->first_child) | |||
730 | ctk_css_node_invalidate_style (cssnode->first_child); | |||
731 | ||||
732 | if (cssnode->next_sibling) | |||
733 | ctk_css_node_invalidate_style (cssnode->next_sibling); | |||
734 | } | |||
735 | ||||
736 | static void | |||
737 | ctk_css_node_reposition (CtkCssNode *node, | |||
738 | CtkCssNode *new_parent, | |||
739 | CtkCssNode *previous) | |||
740 | { | |||
741 | CtkCssNode *old_parent; | |||
742 | ||||
743 | g_assert (! (new_parent == NULL && previous != NULL))do { if (! (new_parent == ((void*)0) && previous != ( (void*)0))) ; else g_assertion_message_expr ("Ctk", "ctkcssnode.c" , 743, ((const char*) (__func__)), "! (new_parent == NULL && previous != NULL)" ); } while (0); | |||
744 | ||||
745 | old_parent = node->parent; | |||
746 | /* Take a reference here so the whole function has a reference */ | |||
747 | g_object_ref (node)((__typeof__ (node)) (g_object_ref) (node)); | |||
748 | ||||
749 | if (node->visible) | |||
750 | { | |||
751 | if (node->next_sibling) | |||
752 | ctk_css_node_invalidate (node->next_sibling, | |||
753 | CTK_CSS_CHANGE_ANY_SIBLING((1ULL << 8) | (1ULL << 9) | (1ULL << 10) | ((1ULL << 11) | (1ULL << 12) | (1ULL << 13 ) | (1ULL << 14)) | (1ULL << 15)) | |||
754 | | CTK_CSS_CHANGE_NTH_CHILD(1ULL << 5) | |||
755 | | (node->previous_sibling ? 0 : CTK_CSS_CHANGE_FIRST_CHILD(1ULL << 3))); | |||
756 | else if (node->previous_sibling) | |||
757 | ctk_css_node_invalidate (node->previous_sibling, CTK_CSS_CHANGE_LAST_CHILD(1ULL << 4)); | |||
758 | } | |||
759 | ||||
760 | if (old_parent != NULL((void*)0)) | |||
761 | { | |||
762 | g_signal_emit (old_parent, cssnode_signals[NODE_REMOVED], 0, node, node->previous_sibling); | |||
763 | if (old_parent->first_child && node->visible) | |||
764 | ctk_css_node_invalidate (old_parent->first_child, CTK_CSS_CHANGE_NTH_LAST_CHILD(1ULL << 6)); | |||
765 | } | |||
766 | ||||
767 | if (old_parent != new_parent) | |||
768 | { | |||
769 | if (old_parent == NULL((void*)0)) | |||
770 | { | |||
771 | ctk_css_node_parent_will_be_set (node); | |||
772 | } | |||
773 | else | |||
774 | { | |||
775 | g_object_unref (node); | |||
776 | } | |||
777 | ||||
778 | if (ctk_css_node_get_style_provider_or_null (node) == NULL((void*)0)) | |||
779 | ctk_css_node_invalidate_style_provider (node); | |||
780 | ctk_css_node_invalidate (node, CTK_CSS_CHANGE_TIMESTAMP(1ULL << 34) | CTK_CSS_CHANGE_ANIMATIONS(1ULL << 35)); | |||
781 | ||||
782 | if (new_parent) | |||
783 | { | |||
784 | g_object_ref (node)((__typeof__ (node)) (g_object_ref) (node)); | |||
785 | ||||
786 | if (node->pending_changes) | |||
787 | new_parent->needs_propagation = TRUE(!(0)); | |||
788 | if (node->invalid && node->visible) | |||
789 | ctk_css_node_set_invalid (new_parent, TRUE(!(0))); | |||
790 | } | |||
791 | else | |||
792 | { | |||
793 | ctk_css_node_parent_was_unset (node); | |||
794 | } | |||
795 | } | |||
796 | ||||
797 | if (new_parent) | |||
798 | { | |||
799 | g_signal_emit (new_parent, cssnode_signals[NODE_ADDED], 0, node, previous); | |||
800 | if (node->visible) | |||
801 | ctk_css_node_invalidate (new_parent->first_child, CTK_CSS_CHANGE_NTH_LAST_CHILD(1ULL << 6)); | |||
802 | } | |||
803 | ||||
804 | if (node->visible) | |||
805 | { | |||
806 | if (node->next_sibling) | |||
807 | { | |||
808 | if (node->previous_sibling == NULL((void*)0)) | |||
809 | ctk_css_node_invalidate (node->next_sibling, CTK_CSS_CHANGE_FIRST_CHILD(1ULL << 3)); | |||
810 | else | |||
811 | ctk_css_node_invalidate_style (node->next_sibling); | |||
812 | } | |||
813 | else if (node->previous_sibling) | |||
814 | { | |||
815 | ctk_css_node_invalidate (node->previous_sibling, CTK_CSS_CHANGE_LAST_CHILD(1ULL << 4)); | |||
816 | } | |||
817 | } | |||
818 | else | |||
819 | { | |||
820 | if (node->next_sibling) | |||
821 | ctk_css_node_invalidate_style (node->next_sibling); | |||
822 | } | |||
823 | ||||
824 | ctk_css_node_invalidate (node, CTK_CSS_CHANGE_ANY_PARENT((1ULL << 16) | (1ULL << 24) | (1ULL << 17) | (1ULL << 26) | (1ULL << 18) | (1ULL << 25 ) | ((1ULL << 19) | (1ULL << 20) | (1ULL << 21) | (1ULL << 22)) | ((1ULL << 27) | (1ULL << 28) | (1ULL << 29) | (1ULL << 30)) | (1ULL << 23) | (1ULL << 31)) | |||
825 | | CTK_CSS_CHANGE_ANY_SIBLING((1ULL << 8) | (1ULL << 9) | (1ULL << 10) | ((1ULL << 11) | (1ULL << 12) | (1ULL << 13 ) | (1ULL << 14)) | (1ULL << 15)) | |||
826 | | CTK_CSS_CHANGE_NTH_CHILD(1ULL << 5) | |||
827 | | (node->previous_sibling ? 0 : CTK_CSS_CHANGE_FIRST_CHILD(1ULL << 3)) | |||
828 | | (node->next_sibling ? 0 : CTK_CSS_CHANGE_LAST_CHILD(1ULL << 4))); | |||
829 | ||||
830 | g_object_unref (node); | |||
831 | } | |||
832 | ||||
833 | void | |||
834 | ctk_css_node_set_parent (CtkCssNode *node, | |||
835 | CtkCssNode *parent) | |||
836 | { | |||
837 | if (node->parent == parent) | |||
838 | return; | |||
839 | ||||
840 | ctk_css_node_reposition (node, parent, parent ? parent->last_child : NULL((void*)0)); | |||
841 | } | |||
842 | ||||
843 | /* If previous_sibling is NULL, insert at the beginning */ | |||
844 | void | |||
845 | ctk_css_node_insert_after (CtkCssNode *parent, | |||
846 | CtkCssNode *cssnode, | |||
847 | CtkCssNode *previous_sibling) | |||
848 | { | |||
849 | g_return_if_fail (previous_sibling == NULL || previous_sibling->parent == parent)do { if ((previous_sibling == ((void*)0) || previous_sibling-> parent == parent)) { } else { g_return_if_fail_warning ("Ctk" , ((const char*) (__func__)), "previous_sibling == NULL || previous_sibling->parent == parent" ); return; } } while (0); | |||
850 | g_return_if_fail (cssnode != previous_sibling)do { if ((cssnode != previous_sibling)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "cssnode != previous_sibling" ); return; } } while (0); | |||
851 | ||||
852 | if (cssnode->previous_sibling == previous_sibling && | |||
853 | cssnode->parent == parent) | |||
854 | return; | |||
855 | ||||
856 | ctk_css_node_reposition (cssnode, | |||
857 | parent, | |||
858 | previous_sibling); | |||
859 | } | |||
860 | ||||
861 | /* If next_sibling is NULL, insert at the end */ | |||
862 | void | |||
863 | ctk_css_node_insert_before (CtkCssNode *parent, | |||
864 | CtkCssNode *cssnode, | |||
865 | CtkCssNode *next_sibling) | |||
866 | { | |||
867 | g_return_if_fail (next_sibling == NULL || next_sibling->parent == parent)do { if ((next_sibling == ((void*)0) || next_sibling->parent == parent)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "next_sibling == NULL || next_sibling->parent == parent" ); return; } } while (0); | |||
868 | g_return_if_fail (cssnode != next_sibling)do { if ((cssnode != next_sibling)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "cssnode != next_sibling" ); return; } } while (0); | |||
869 | ||||
870 | if (cssnode->next_sibling == next_sibling && | |||
871 | cssnode->parent == parent) | |||
872 | return; | |||
873 | ||||
874 | ctk_css_node_reposition (cssnode, | |||
875 | parent, | |||
876 | next_sibling ? next_sibling->previous_sibling : parent->last_child); | |||
877 | } | |||
878 | ||||
879 | void | |||
880 | ctk_css_node_reverse_children (CtkCssNode *cssnode) | |||
881 | { | |||
882 | CtkCssNode *end; | |||
883 | ||||
884 | end = cssnode->last_child; | |||
885 | while (cssnode->first_child != end) | |||
886 | { | |||
887 | ctk_css_node_reposition (cssnode->first_child, | |||
888 | cssnode, | |||
889 | end); | |||
890 | } | |||
891 | ||||
892 | } | |||
893 | ||||
894 | CtkCssNode * | |||
895 | ctk_css_node_get_parent (CtkCssNode *cssnode) | |||
896 | { | |||
897 | return cssnode->parent; | |||
898 | } | |||
899 | ||||
900 | CtkCssNode * | |||
901 | ctk_css_node_get_first_child (CtkCssNode *cssnode) | |||
902 | { | |||
903 | return cssnode->first_child; | |||
904 | } | |||
905 | ||||
906 | CtkCssNode * | |||
907 | ctk_css_node_get_last_child (CtkCssNode *cssnode) | |||
908 | { | |||
909 | return cssnode->last_child; | |||
910 | } | |||
911 | ||||
912 | CtkCssNode * | |||
913 | ctk_css_node_get_previous_sibling (CtkCssNode *cssnode) | |||
914 | { | |||
915 | return cssnode->previous_sibling; | |||
916 | } | |||
917 | ||||
918 | CtkCssNode * | |||
919 | ctk_css_node_get_next_sibling (CtkCssNode *cssnode) | |||
920 | { | |||
921 | return cssnode->next_sibling; | |||
922 | } | |||
923 | ||||
924 | static gboolean | |||
925 | ctk_css_node_set_style (CtkCssNode *cssnode, | |||
926 | CtkCssStyle *style) | |||
927 | { | |||
928 | CtkCssStyleChange change; | |||
929 | gboolean style_changed; | |||
930 | ||||
931 | if (cssnode->style == style) | |||
932 | return FALSE(0); | |||
933 | ||||
934 | ctk_css_style_change_init (&change, cssnode->style, style); | |||
935 | ||||
936 | style_changed = ctk_css_style_change_has_change (&change); | |||
937 | if (style_changed) | |||
938 | { | |||
939 | g_signal_emit (cssnode, cssnode_signals[STYLE_CHANGED], 0, &change); | |||
940 | } | |||
941 | else if (cssnode->style != style && | |||
942 | (CTK_IS_CSS_ANIMATED_STYLE (cssnode->style)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( cssnode->style); GType __t = ((ctk_css_animated_style_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))) || CTK_IS_CSS_ANIMATED_STYLE (style)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( style); GType __t = ((ctk_css_animated_style_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) | |||
943 | { | |||
944 | /* This is when animations are starting/stopping but they didn't change any CSS this frame */ | |||
945 | g_set_object (&cssnode->style, style)(__extension__ ({ _Static_assert (sizeof *(&cssnode->style ) == sizeof (style), "Expression evaluates to false"); union { char *in; GObject **out; } _object_ptr; _object_ptr.in = (char *) (&cssnode->style); (void) (0 ? *(&cssnode-> style) = (style), (0) : (0)); (g_set_object) (_object_ptr.out , (GObject *) style); })); | |||
946 | } | |||
947 | ||||
948 | ctk_css_style_change_finish (&change); | |||
949 | ||||
950 | return style_changed; | |||
951 | } | |||
952 | ||||
953 | static void | |||
954 | ctk_css_node_propagate_pending_changes (CtkCssNode *cssnode, | |||
955 | gboolean style_changed) | |||
956 | { | |||
957 | CtkCssChange change, child_change; | |||
958 | CtkCssNode *child; | |||
959 | ||||
960 | change = _ctk_css_change_for_child (cssnode->pending_changes); | |||
961 | if (style_changed) | |||
962 | change |= CTK_CSS_CHANGE_PARENT_STYLE(1ULL << 33); | |||
963 | ||||
964 | if (!cssnode->needs_propagation && change == 0) | |||
965 | return; | |||
966 | ||||
967 | for (child = ctk_css_node_get_first_child (cssnode); | |||
968 | child; | |||
969 | child = ctk_css_node_get_next_sibling (child)) | |||
970 | { | |||
971 | child_change = child->pending_changes; | |||
972 | ctk_css_node_invalidate (child, change); | |||
973 | if (child->visible) | |||
974 | change |= _ctk_css_change_for_sibling (child_change); | |||
975 | } | |||
976 | ||||
977 | cssnode->needs_propagation = FALSE(0); | |||
978 | } | |||
979 | ||||
980 | static gboolean | |||
981 | ctk_css_node_needs_new_style (CtkCssNode *cssnode) | |||
982 | { | |||
983 | return cssnode->style_is_invalid || cssnode->needs_propagation; | |||
984 | } | |||
985 | ||||
986 | static void | |||
987 | ctk_css_node_ensure_style (CtkCssNode *cssnode, | |||
988 | gint64 current_time) | |||
989 | { | |||
990 | gboolean style_changed; | |||
991 | ||||
992 | if (!ctk_css_node_needs_new_style (cssnode)) | |||
993 | return; | |||
994 | ||||
995 | if (cssnode->parent) | |||
996 | ctk_css_node_ensure_style (cssnode->parent, current_time); | |||
997 | ||||
998 | if (cssnode->style_is_invalid) | |||
999 | { | |||
1000 | CtkCssStyle *new_style; | |||
1001 | ||||
1002 | if (cssnode->previous_sibling) | |||
1003 | ctk_css_node_ensure_style (cssnode->previous_sibling, current_time); | |||
1004 | ||||
1005 | g_clear_pointer (&cssnode->cache, ctk_css_node_style_cache_unref)do { _Static_assert (sizeof *(&cssnode->cache) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ ((& cssnode->cache)) _pp = (&cssnode->cache); __typeof__ (*(&cssnode->cache)) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (ctk_css_node_style_cache_unref) (_ptr); } while (0); | |||
1006 | ||||
1007 | new_style = CTK_CSS_NODE_GET_CLASS (cssnode)((((CtkCssNodeClass*) (((GTypeInstance*) ((cssnode)))->g_class ))))->update_style (cssnode, | |||
1008 | cssnode->pending_changes, | |||
1009 | current_time, | |||
1010 | cssnode->style); | |||
1011 | ||||
1012 | style_changed = ctk_css_node_set_style (cssnode, new_style); | |||
1013 | g_object_unref (new_style); | |||
1014 | } | |||
1015 | else | |||
1016 | { | |||
1017 | style_changed = FALSE(0); | |||
1018 | } | |||
1019 | ||||
1020 | ctk_css_node_propagate_pending_changes (cssnode, style_changed); | |||
1021 | ||||
1022 | cssnode->pending_changes = 0; | |||
1023 | cssnode->style_is_invalid = FALSE(0); | |||
1024 | } | |||
1025 | ||||
1026 | CtkCssStyle * | |||
1027 | ctk_css_node_get_style (CtkCssNode *cssnode) | |||
1028 | { | |||
1029 | if (ctk_css_node_needs_new_style (cssnode)) | |||
1030 | { | |||
1031 | gint64 timestamp = ctk_css_node_get_timestamp (cssnode); | |||
1032 | ||||
1033 | ctk_css_node_ensure_style (cssnode, timestamp); | |||
1034 | } | |||
1035 | ||||
1036 | return cssnode->style; | |||
1037 | } | |||
1038 | ||||
1039 | void | |||
1040 | ctk_css_node_set_visible (CtkCssNode *cssnode, | |||
1041 | gboolean visible) | |||
1042 | { | |||
1043 | CtkCssNode *iter; | |||
1044 | ||||
1045 | if (cssnode->visible == visible) | |||
1046 | return; | |||
1047 | ||||
1048 | cssnode->visible = visible; | |||
1049 | g_object_notify_by_pspec (G_OBJECT (cssnode)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((cssnode)), (((GType) ((20) << (2)))))))), cssnode_properties[PROP_VISIBLE]); | |||
1050 | ||||
1051 | if (cssnode->invalid) | |||
1052 | { | |||
1053 | if (cssnode->visible) | |||
1054 | { | |||
1055 | if (cssnode->parent) | |||
1056 | ctk_css_node_set_invalid (cssnode->parent, TRUE(!(0))); | |||
1057 | else | |||
1058 | CTK_CSS_NODE_GET_CLASS (cssnode)((((CtkCssNodeClass*) (((GTypeInstance*) ((cssnode)))->g_class ))))->queue_validate (cssnode); | |||
1059 | } | |||
1060 | else | |||
1061 | { | |||
1062 | if (cssnode->parent == NULL((void*)0)) | |||
1063 | CTK_CSS_NODE_GET_CLASS (cssnode)((((CtkCssNodeClass*) (((GTypeInstance*) ((cssnode)))->g_class ))))->dequeue_validate (cssnode); | |||
1064 | } | |||
1065 | } | |||
1066 | ||||
1067 | if (cssnode->next_sibling) | |||
1068 | { | |||
1069 | ctk_css_node_invalidate (cssnode->next_sibling, CTK_CSS_CHANGE_ANY_SIBLING((1ULL << 8) | (1ULL << 9) | (1ULL << 10) | ((1ULL << 11) | (1ULL << 12) | (1ULL << 13 ) | (1ULL << 14)) | (1ULL << 15)) | CTK_CSS_CHANGE_NTH_CHILD(1ULL << 5)); | |||
1070 | if (ctk_css_node_is_first_child (cssnode)) | |||
1071 | { | |||
1072 | for (iter = cssnode->next_sibling; | |||
1073 | iter != NULL((void*)0); | |||
1074 | iter = iter->next_sibling) | |||
1075 | { | |||
1076 | ctk_css_node_invalidate (iter, CTK_CSS_CHANGE_FIRST_CHILD(1ULL << 3)); | |||
1077 | if (iter->visible) | |||
1078 | break; | |||
1079 | } | |||
1080 | } | |||
1081 | } | |||
1082 | ||||
1083 | if (cssnode->previous_sibling) | |||
1084 | { | |||
1085 | if (ctk_css_node_is_last_child (cssnode)) | |||
1086 | { | |||
1087 | for (iter = cssnode->previous_sibling; | |||
1088 | iter != NULL((void*)0); | |||
1089 | iter = iter->previous_sibling) | |||
1090 | { | |||
1091 | ctk_css_node_invalidate (iter, CTK_CSS_CHANGE_LAST_CHILD(1ULL << 4)); | |||
1092 | if (iter->visible) | |||
1093 | break; | |||
1094 | } | |||
1095 | } | |||
1096 | ctk_css_node_invalidate (cssnode->parent->first_child, CTK_CSS_CHANGE_NTH_LAST_CHILD(1ULL << 6)); | |||
1097 | } | |||
1098 | } | |||
1099 | ||||
1100 | gboolean | |||
1101 | ctk_css_node_get_visible (CtkCssNode *cssnode) | |||
1102 | { | |||
1103 | return cssnode->visible; | |||
1104 | } | |||
1105 | ||||
1106 | void | |||
1107 | ctk_css_node_set_name (CtkCssNode *cssnode, | |||
1108 | /*interned*/ const char *name) | |||
1109 | { | |||
1110 | if (ctk_css_node_declaration_set_name (&cssnode->decl, name)) | |||
1111 | { | |||
1112 | ctk_css_node_invalidate (cssnode, CTK_CSS_CHANGE_NAME(1ULL << 1)); | |||
1113 | g_object_notify_by_pspec (G_OBJECT (cssnode)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((cssnode)), (((GType) ((20) << (2)))))))), cssnode_properties[PROP_NAME]); | |||
1114 | } | |||
1115 | } | |||
1116 | ||||
1117 | /* interned */ const char * | |||
1118 | ctk_css_node_get_name (CtkCssNode *cssnode) | |||
1119 | { | |||
1120 | return ctk_css_node_declaration_get_name (cssnode->decl); | |||
1121 | } | |||
1122 | ||||
1123 | void | |||
1124 | ctk_css_node_set_widget_type (CtkCssNode *cssnode, | |||
1125 | GType widget_type) | |||
1126 | { | |||
1127 | if (ctk_css_node_declaration_set_type (&cssnode->decl, widget_type)) | |||
1128 | { | |||
1129 | ctk_css_node_invalidate (cssnode, CTK_CSS_CHANGE_NAME(1ULL << 1)); | |||
1130 | g_object_notify_by_pspec (G_OBJECT (cssnode)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((cssnode)), (((GType) ((20) << (2)))))))), cssnode_properties[PROP_WIDGET_TYPE]); | |||
1131 | } | |||
1132 | } | |||
1133 | ||||
1134 | GType | |||
1135 | ctk_css_node_get_widget_type (CtkCssNode *cssnode) | |||
1136 | { | |||
1137 | return ctk_css_node_declaration_get_type (cssnode->decl); | |||
1138 | } | |||
1139 | ||||
1140 | void | |||
1141 | ctk_css_node_set_id (CtkCssNode *cssnode, | |||
1142 | /* interned */ const char *id) | |||
1143 | { | |||
1144 | if (ctk_css_node_declaration_set_id (&cssnode->decl, id)) | |||
1145 | { | |||
1146 | ctk_css_node_invalidate (cssnode, CTK_CSS_CHANGE_ID(1ULL << 2)); | |||
1147 | g_object_notify_by_pspec (G_OBJECT (cssnode)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((cssnode)), (((GType) ((20) << (2)))))))), cssnode_properties[PROP_ID]); | |||
1148 | } | |||
1149 | } | |||
1150 | ||||
1151 | /* interned */ const char * | |||
1152 | ctk_css_node_get_id (CtkCssNode *cssnode) | |||
1153 | { | |||
1154 | return ctk_css_node_declaration_get_id (cssnode->decl); | |||
1155 | } | |||
1156 | ||||
1157 | void | |||
1158 | ctk_css_node_set_state (CtkCssNode *cssnode, | |||
1159 | CtkStateFlags state_flags) | |||
1160 | { | |||
1161 | if (ctk_css_node_declaration_set_state (&cssnode->decl, state_flags)) | |||
1162 | { | |||
1163 | ctk_css_node_invalidate (cssnode, CTK_CSS_CHANGE_STATE(1ULL << 7)); | |||
1164 | g_object_notify_by_pspec (G_OBJECT (cssnode)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((cssnode)), (((GType) ((20) << (2)))))))), cssnode_properties[PROP_STATE]); | |||
1165 | } | |||
1166 | } | |||
1167 | ||||
1168 | CtkStateFlags | |||
1169 | ctk_css_node_get_state (CtkCssNode *cssnode) | |||
1170 | { | |||
1171 | return ctk_css_node_declaration_get_state (cssnode->decl); | |||
1172 | } | |||
1173 | ||||
1174 | void | |||
1175 | ctk_css_node_set_junction_sides (CtkCssNode *cssnode, | |||
1176 | CtkJunctionSides junction_sides) | |||
1177 | { | |||
1178 | ctk_css_node_declaration_set_junction_sides (&cssnode->decl, junction_sides); | |||
1179 | } | |||
1180 | ||||
1181 | CtkJunctionSides | |||
1182 | ctk_css_node_get_junction_sides (CtkCssNode *cssnode) | |||
1183 | { | |||
1184 | return ctk_css_node_declaration_get_junction_sides (cssnode->decl); | |||
1185 | } | |||
1186 | ||||
1187 | static void | |||
1188 | ctk_css_node_clear_classes (CtkCssNode *cssnode) | |||
1189 | { | |||
1190 | if (ctk_css_node_declaration_clear_classes (&cssnode->decl)) | |||
1191 | { | |||
1192 | ctk_css_node_invalidate (cssnode, CTK_CSS_CHANGE_CLASS(1ULL << 0)); | |||
1193 | g_object_notify_by_pspec (G_OBJECT (cssnode)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((cssnode)), (((GType) ((20) << (2)))))))), cssnode_properties[PROP_CLASSES]); | |||
1194 | } | |||
1195 | } | |||
1196 | ||||
1197 | void | |||
1198 | ctk_css_node_set_classes (CtkCssNode *cssnode, | |||
1199 | const char **classes) | |||
1200 | { | |||
1201 | guint i; | |||
1202 | ||||
1203 | g_object_freeze_notify (G_OBJECT (cssnode)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((cssnode)), (((GType) ((20) << (2))))))))); | |||
1204 | ||||
1205 | ctk_css_node_clear_classes (cssnode); | |||
1206 | ||||
1207 | if (classes) | |||
1208 | { | |||
1209 | for (i = 0; classes[i] != NULL((void*)0); i++) | |||
1210 | { | |||
1211 | ctk_css_node_add_class (cssnode, g_quark_from_string (classes[i])); | |||
1212 | } | |||
1213 | } | |||
1214 | ||||
1215 | g_object_thaw_notify (G_OBJECT (cssnode)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((cssnode)), (((GType) ((20) << (2))))))))); | |||
1216 | } | |||
1217 | ||||
1218 | char ** | |||
1219 | ctk_css_node_get_classes (CtkCssNode *cssnode) | |||
1220 | { | |||
1221 | const GQuark *classes; | |||
1222 | char **result; | |||
1223 | guint n_classes, i, j; | |||
1224 | ||||
1225 | classes = ctk_css_node_declaration_get_classes (cssnode->decl, &n_classes); | |||
1226 | result = g_new (char *, n_classes + 1)((char * *) g_malloc_n ((n_classes + 1), sizeof (char *))); | |||
1227 | ||||
1228 | for (i = n_classes, j = 0; i-- > 0; ++j) | |||
1229 | { | |||
1230 | result[j] = g_strdup (g_quark_to_string (classes[i]))g_strdup_inline (g_quark_to_string (classes[i])); | |||
1231 | } | |||
1232 | ||||
1233 | result[n_classes] = NULL((void*)0); | |||
1234 | return result; | |||
1235 | } | |||
1236 | ||||
1237 | void | |||
1238 | ctk_css_node_add_class (CtkCssNode *cssnode, | |||
1239 | GQuark style_class) | |||
1240 | { | |||
1241 | if (ctk_css_node_declaration_add_class (&cssnode->decl, style_class)) | |||
1242 | { | |||
1243 | ctk_css_node_invalidate (cssnode, CTK_CSS_CHANGE_CLASS(1ULL << 0)); | |||
1244 | g_object_notify_by_pspec (G_OBJECT (cssnode)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((cssnode)), (((GType) ((20) << (2)))))))), cssnode_properties[PROP_CLASSES]); | |||
1245 | } | |||
1246 | } | |||
1247 | ||||
1248 | void | |||
1249 | ctk_css_node_remove_class (CtkCssNode *cssnode, | |||
1250 | GQuark style_class) | |||
1251 | { | |||
1252 | if (ctk_css_node_declaration_remove_class (&cssnode->decl, style_class)) | |||
1253 | { | |||
1254 | ctk_css_node_invalidate (cssnode, CTK_CSS_CHANGE_CLASS(1ULL << 0)); | |||
1255 | g_object_notify_by_pspec (G_OBJECT (cssnode)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((cssnode)), (((GType) ((20) << (2)))))))), cssnode_properties[PROP_CLASSES]); | |||
1256 | } | |||
1257 | } | |||
1258 | ||||
1259 | gboolean | |||
1260 | ctk_css_node_has_class (CtkCssNode *cssnode, | |||
1261 | GQuark style_class) | |||
1262 | { | |||
1263 | return ctk_css_node_declaration_has_class (cssnode->decl, style_class); | |||
1264 | } | |||
1265 | ||||
1266 | const GQuark * | |||
1267 | ctk_css_node_list_classes (CtkCssNode *cssnode, | |||
1268 | guint *n_classes) | |||
1269 | { | |||
1270 | return ctk_css_node_declaration_get_classes (cssnode->decl, n_classes); | |||
1271 | } | |||
1272 | ||||
1273 | void | |||
1274 | ctk_css_node_add_region (CtkCssNode *cssnode, | |||
1275 | GQuark region, | |||
1276 | CtkRegionFlags flags) | |||
1277 | { | |||
1278 | ctk_css_node_declaration_add_region (&cssnode->decl, region, flags); | |||
1279 | } | |||
1280 | ||||
1281 | void | |||
1282 | ctk_css_node_remove_region (CtkCssNode *cssnode, | |||
1283 | GQuark region) | |||
1284 | { | |||
1285 | ctk_css_node_declaration_remove_region (&cssnode->decl, region); | |||
1286 | } | |||
1287 | ||||
1288 | gboolean | |||
1289 | ctk_css_node_has_region (CtkCssNode *cssnode, | |||
1290 | GQuark region, | |||
1291 | CtkRegionFlags *out_flags) | |||
1292 | { | |||
1293 | return ctk_css_node_declaration_has_region (cssnode->decl, region, out_flags); | |||
1294 | } | |||
1295 | ||||
1296 | GList * | |||
1297 | ctk_css_node_list_regions (CtkCssNode *cssnode) | |||
1298 | { | |||
1299 | return ctk_css_node_declaration_list_regions (cssnode->decl); | |||
1300 | } | |||
1301 | ||||
1302 | ||||
1303 | const CtkCssNodeDeclaration * | |||
1304 | ctk_css_node_get_declaration (CtkCssNode *cssnode) | |||
1305 | { | |||
1306 | return cssnode->decl; | |||
1307 | } | |||
1308 | ||||
1309 | void | |||
1310 | ctk_css_node_invalidate_style_provider (CtkCssNode *cssnode) | |||
1311 | { | |||
1312 | CtkCssNode *child; | |||
1313 | ||||
1314 | ctk_css_node_invalidate (cssnode, CTK_CSS_CHANGE_SOURCE(1ULL << 32)); | |||
1315 | ||||
1316 | for (child = cssnode->first_child; | |||
1317 | child; | |||
1318 | child = child->next_sibling) | |||
1319 | { | |||
1320 | if (ctk_css_node_get_style_provider_or_null (child) == NULL((void*)0)) | |||
1321 | ctk_css_node_invalidate_style_provider (child); | |||
1322 | } | |||
1323 | } | |||
1324 | ||||
1325 | static void | |||
1326 | ctk_css_node_invalidate_timestamp (CtkCssNode *cssnode) | |||
1327 | { | |||
1328 | CtkCssNode *child; | |||
1329 | ||||
1330 | if (!cssnode->invalid) | |||
1331 | return; | |||
1332 | ||||
1333 | if (!ctk_css_style_is_static (cssnode->style)) | |||
1334 | ctk_css_node_invalidate (cssnode, CTK_CSS_CHANGE_TIMESTAMP(1ULL << 34)); | |||
1335 | ||||
1336 | for (child = cssnode->first_child; child; child = child->next_sibling) | |||
1337 | { | |||
1338 | ctk_css_node_invalidate_timestamp (child); | |||
1339 | } | |||
1340 | } | |||
1341 | ||||
1342 | void | |||
1343 | ctk_css_node_invalidate_frame_clock (CtkCssNode *cssnode, | |||
1344 | gboolean just_timestamp) | |||
1345 | { | |||
1346 | /* frame clock is handled by the top level */ | |||
1347 | if (cssnode->parent) | |||
1348 | return; | |||
1349 | ||||
1350 | ctk_css_node_invalidate_timestamp (cssnode); | |||
1351 | ||||
1352 | if (!just_timestamp) | |||
1353 | ctk_css_node_invalidate (cssnode, CTK_CSS_CHANGE_ANIMATIONS(1ULL << 35)); | |||
1354 | } | |||
1355 | ||||
1356 | void | |||
1357 | ctk_css_node_invalidate (CtkCssNode *cssnode, | |||
1358 | CtkCssChange change) | |||
1359 | { | |||
1360 | if (!cssnode->invalid) | |||
1361 | change &= ~CTK_CSS_CHANGE_TIMESTAMP(1ULL << 34); | |||
1362 | ||||
1363 | if (change == 0) | |||
1364 | return; | |||
1365 | ||||
1366 | cssnode->pending_changes |= change; | |||
1367 | ||||
1368 | CTK_CSS_NODE_GET_CLASS (cssnode)((((CtkCssNodeClass*) (((GTypeInstance*) ((cssnode)))->g_class ))))->invalidate (cssnode); | |||
1369 | ||||
1370 | if (cssnode->parent) | |||
1371 | cssnode->parent->needs_propagation = TRUE(!(0)); | |||
1372 | ctk_css_node_invalidate_style (cssnode); | |||
1373 | } | |||
1374 | ||||
1375 | void | |||
1376 | ctk_css_node_validate_internal (CtkCssNode *cssnode, | |||
1377 | gint64 timestamp) | |||
1378 | { | |||
1379 | CtkCssNode *child; | |||
1380 | ||||
1381 | if (!cssnode->invalid) | |||
1382 | return; | |||
1383 | ||||
1384 | ctk_css_node_ensure_style (cssnode, timestamp); | |||
1385 | ||||
1386 | /* need to set to FALSE then to TRUE here to make it chain up */ | |||
1387 | ctk_css_node_set_invalid (cssnode, FALSE(0)); | |||
1388 | if (!ctk_css_style_is_static (cssnode->style)) | |||
1389 | ctk_css_node_set_invalid (cssnode, TRUE(!(0))); | |||
1390 | ||||
1391 | CTK_CSS_NODE_GET_CLASS (cssnode)((((CtkCssNodeClass*) (((GTypeInstance*) ((cssnode)))->g_class ))))->validate (cssnode); | |||
1392 | ||||
1393 | for (child = ctk_css_node_get_first_child (cssnode); | |||
1394 | child; | |||
1395 | child = ctk_css_node_get_next_sibling (child)) | |||
1396 | { | |||
1397 | if (child->visible) | |||
1398 | ctk_css_node_validate_internal (child, timestamp); | |||
1399 | } | |||
1400 | } | |||
1401 | ||||
1402 | void | |||
1403 | ctk_css_node_validate (CtkCssNode *cssnode) | |||
1404 | { | |||
1405 | gint64 timestamp; | |||
1406 | ||||
1407 | timestamp = ctk_css_node_get_timestamp (cssnode); | |||
1408 | ||||
1409 | ctk_css_node_validate_internal (cssnode, timestamp); | |||
1410 | } | |||
1411 | ||||
1412 | gboolean | |||
1413 | ctk_css_node_init_matcher (CtkCssNode *cssnode, | |||
1414 | CtkCssMatcher *matcher) | |||
1415 | { | |||
1416 | return CTK_CSS_NODE_GET_CLASS (cssnode)((((CtkCssNodeClass*) (((GTypeInstance*) ((cssnode)))->g_class ))))->init_matcher (cssnode, matcher); | |||
1417 | } | |||
1418 | ||||
1419 | CtkWidgetPath * | |||
1420 | ctk_css_node_create_widget_path (CtkCssNode *cssnode) | |||
1421 | { | |||
1422 | return CTK_CSS_NODE_GET_CLASS (cssnode)((((CtkCssNodeClass*) (((GTypeInstance*) ((cssnode)))->g_class ))))->create_widget_path (cssnode); | |||
1423 | } | |||
1424 | ||||
1425 | const CtkWidgetPath * | |||
1426 | ctk_css_node_get_widget_path (CtkCssNode *cssnode) | |||
1427 | { | |||
1428 | return CTK_CSS_NODE_GET_CLASS (cssnode)((((CtkCssNodeClass*) (((GTypeInstance*) ((cssnode)))->g_class ))))->get_widget_path (cssnode); | |||
1429 | } | |||
1430 | ||||
1431 | CtkStyleProviderPrivate * | |||
1432 | ctk_css_node_get_style_provider (CtkCssNode *cssnode) | |||
1433 | { | |||
1434 | CtkStyleProviderPrivate *result; | |||
1435 | CtkSettings *settings; | |||
1436 | ||||
1437 | result = ctk_css_node_get_style_provider_or_null (cssnode); | |||
1438 | if (result) | |||
1439 | return result; | |||
1440 | ||||
1441 | if (cssnode->parent) | |||
1442 | return ctk_css_node_get_style_provider (cssnode->parent); | |||
1443 | ||||
1444 | settings = ctk_settings_get_default (); | |||
1445 | if (!settings) | |||
1446 | return NULL((void*)0); | |||
1447 | ||||
1448 | return CTK_STYLE_PROVIDER_PRIVATE (_ctk_settings_get_style_cascade (settings, 1))((((CtkStyleProviderPrivate*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((_ctk_settings_get_style_cascade (settings , 1))), ((_ctk_style_provider_private_get_type ())))))); | |||
1449 | } | |||
1450 | ||||
1451 | void | |||
1452 | ctk_css_node_print (CtkCssNode *cssnode, | |||
1453 | CtkStyleContextPrintFlags flags, | |||
1454 | GString *string, | |||
1455 | guint indent) | |||
1456 | { | |||
1457 | gboolean need_newline = FALSE(0); | |||
1458 | ||||
1459 | g_string_append_printf (string, "%*s", indent, ""); | |||
1460 | ||||
1461 | if (!cssnode->visible) | |||
1462 | g_string_append_c (string, '[')g_string_append_c_inline (string, '['); | |||
1463 | ||||
1464 | ctk_css_node_declaration_print (cssnode->decl, string); | |||
1465 | ||||
1466 | if (!cssnode->visible) | |||
1467 | g_string_append_c (string, ']')g_string_append_c_inline (string, ']'); | |||
1468 | ||||
1469 | g_string_append_c (string, '\n')g_string_append_c_inline (string, '\n'); | |||
1470 | ||||
1471 | if (flags & CTK_STYLE_CONTEXT_PRINT_SHOW_STYLE) | |||
1472 | need_newline = ctk_css_style_print (ctk_css_node_get_style (cssnode), string, indent + 2, TRUE(!(0))); | |||
1473 | ||||
1474 | if (flags & CTK_STYLE_CONTEXT_PRINT_RECURSE) | |||
1475 | { | |||
1476 | CtkCssNode *node; | |||
1477 | ||||
1478 | if (need_newline && ctk_css_node_get_first_child (cssnode)) | |||
1479 | g_string_append_c (string, '\n')g_string_append_c_inline (string, '\n'); | |||
1480 | ||||
1481 | for (node = ctk_css_node_get_first_child (cssnode); node; node = ctk_css_node_get_next_sibling (node)) | |||
1482 | ctk_css_node_print (node, flags, string, indent + 2); | |||
1483 | } | |||
1484 | } |