1 /* GTK - 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 #ifndef __GTK_CSS_NODE_PRIVATE_H__
19 #define __GTK_CSS_NODE_PRIVATE_H__
20 
21 #include "gtkcountingbloomfilterprivate.h"
22 #include "gtkcssnodedeclarationprivate.h"
23 #include "gtkcssnodestylecacheprivate.h"
24 #include "gtkcssstylechangeprivate.h"
25 #include "gtkbitmaskprivate.h"
26 #include "gtkcsstypesprivate.h"
27 #include "gtkstylecontext.h"
28 
29 G_BEGIN_DECLS
30 
31 #define GTK_TYPE_CSS_NODE           (gtk_css_node_get_type ())
32 #define GTK_CSS_NODE(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_NODE, GtkCssNode))
33 #define GTK_CSS_NODE_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_NODE, GtkCssNodeClass))
34 #define GTK_IS_CSS_NODE(obj)        (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_NODE))
35 #define GTK_IS_CSS_NODE_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_NODE))
36 #define GTK_CSS_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_NODE, GtkCssNodeClass))
37 
38 typedef struct _GtkCssNodeClass         GtkCssNodeClass;
39 
40 struct _GtkCssNode
41 {
42   GObject object;
43 
44   GtkCssNode *parent;
45   GtkCssNode *previous_sibling;
46   GtkCssNode *next_sibling;
47   GtkCssNode *first_child;
48   GtkCssNode *last_child;
49 
50   GtkCssNodeDeclaration *decl;
51   GtkCssStyle           *style;
52   GtkCssNodeStyleCache  *cache;                 /* cache for children to look up styles */
53 
54   GtkCssChange           pending_changes;       /* changes that accumulated since the style was last computed */
55 
56   guint                  visible :1;            /* node will be skipped when validating or computing styles */
57   guint                  invalid :1;            /* node or a child needs to be validated (even if just for animation) */
58   guint                  needs_propagation :1;  /* children have state changes that need to be propagated to their siblings */
59   /* Two invariants hold for this variable:
60    * style_is_invalid == TRUE  =>  next_sibling->style_is_invalid == TRUE
61    * style_is_invalid == FALSE =>  first_child->style_is_invalid == TRUE
62    * So if a valid style is computed, one has to previously ensure that the parent's and the previous sibling's style
63    * are valid. This allows both validation and invalidation to run in O(nodes-in-tree) */
64   guint                  style_is_invalid :1;   /* the style needs to be recomputed */
65 };
66 
67 struct _GtkCssNodeClass
68 {
69   GObjectClass object_class;
70 
71   void                  (* node_added)                  (GtkCssNode            *cssnode,
72                                                          GtkCssNode            *child,
73                                                          GtkCssNode            *previous);
74   void                  (* node_removed)                (GtkCssNode            *cssnode,
75                                                          GtkCssNode            *child,
76                                                          GtkCssNode            *previous);
77   void                  (* style_changed)               (GtkCssNode            *cssnode,
78                                                          GtkCssStyleChange     *style_change);
79 
80   /* get style provider to use or NULL to use parent's */
81   GtkStyleProvider *    (* get_style_provider)          (GtkCssNode            *cssnode);
82   /* get frame clock or NULL (only relevant for root node) */
83   GdkFrameClock *       (* get_frame_clock)             (GtkCssNode            *cssnode);
84   GtkCssStyle *         (* update_style)                (GtkCssNode            *cssnode,
85                                                          const GtkCountingBloomFilter *filter,
86                                                          GtkCssChange           pending_changes,
87                                                          gint64                 timestamp,
88                                                          GtkCssStyle           *old_style);
89   void                  (* invalidate)                  (GtkCssNode            *node);
90   void                  (* queue_validate)              (GtkCssNode            *node);
91   void                  (* dequeue_validate)            (GtkCssNode            *node);
92   void                  (* validate)                    (GtkCssNode            *node);
93 };
94 
95 GType                   gtk_css_node_get_type           (void) G_GNUC_CONST;
96 
97 GtkCssNode *            gtk_css_node_new                (void);
98 
99 void                    gtk_css_node_set_parent         (GtkCssNode            *cssnode,
100                                                          GtkCssNode            *parent);
101 void                    gtk_css_node_insert_after       (GtkCssNode            *parent,
102                                                          GtkCssNode            *cssnode,
103                                                          GtkCssNode            *previous_sibling);
104 void                    gtk_css_node_insert_before      (GtkCssNode            *parent,
105                                                          GtkCssNode            *cssnode,
106                                                          GtkCssNode            *next_sibling);
107 
108 GtkCssNode *            gtk_css_node_get_parent         (GtkCssNode            *cssnode) G_GNUC_PURE;
109 GtkCssNode *            gtk_css_node_get_first_child    (GtkCssNode            *cssnode) G_GNUC_PURE;
110 GtkCssNode *            gtk_css_node_get_last_child     (GtkCssNode            *cssnode) G_GNUC_PURE;
111 GtkCssNode *            gtk_css_node_get_previous_sibling(GtkCssNode           *cssnode) G_GNUC_PURE;
112 GtkCssNode *            gtk_css_node_get_next_sibling   (GtkCssNode            *cssnode) G_GNUC_PURE;
113 
114 void                    gtk_css_node_set_visible        (GtkCssNode            *cssnode,
115                                                          gboolean               visible);
116 gboolean                gtk_css_node_get_visible        (GtkCssNode            *cssnode) G_GNUC_PURE;
117 
118 void                    gtk_css_node_set_name           (GtkCssNode            *cssnode,
119                                                          GQuark                 name);
120 GQuark                  gtk_css_node_get_name           (GtkCssNode            *cssnode) G_GNUC_PURE;
121 void                    gtk_css_node_set_id             (GtkCssNode            *cssnode,
122                                                          GQuark                 id);
123 GQuark                  gtk_css_node_get_id             (GtkCssNode            *cssnode) G_GNUC_PURE;
124 void                    gtk_css_node_set_state          (GtkCssNode            *cssnode,
125                                                          GtkStateFlags          state_flags);
126 GtkStateFlags           gtk_css_node_get_state          (GtkCssNode            *cssnode) G_GNUC_PURE;
127 void                    gtk_css_node_set_classes        (GtkCssNode            *cssnode,
128                                                          const char           **classes);
129 char **                 gtk_css_node_get_classes        (GtkCssNode            *cssnode);
130 void                    gtk_css_node_add_class          (GtkCssNode            *cssnode,
131                                                          GQuark                 style_class);
132 void                    gtk_css_node_remove_class       (GtkCssNode            *cssnode,
133                                                          GQuark                 style_class);
134 gboolean                gtk_css_node_has_class          (GtkCssNode            *cssnode,
135                                                          GQuark                 style_class) G_GNUC_PURE;
136 const GQuark *          gtk_css_node_list_classes       (GtkCssNode            *cssnode,
137                                                          guint                 *n_classes);
138 
139 const GtkCssNodeDeclaration *
140                         gtk_css_node_get_declaration    (GtkCssNode            *cssnode) G_GNUC_PURE;
141 GtkCssStyle *           gtk_css_node_get_style          (GtkCssNode            *cssnode) G_GNUC_PURE;
142 
143 
144 void                    gtk_css_node_invalidate_style_provider
145                                                         (GtkCssNode            *cssnode);
146 void                    gtk_css_node_invalidate_frame_clock
147                                                         (GtkCssNode            *cssnode,
148                                                          gboolean               just_timestamp);
149 void                    gtk_css_node_invalidate         (GtkCssNode            *cssnode,
150                                                          GtkCssChange           change);
151 void                    gtk_css_node_validate           (GtkCssNode            *cssnode);
152 
153 GtkStyleProvider *      gtk_css_node_get_style_provider (GtkCssNode            *cssnode) G_GNUC_PURE;
154 
155 void                    gtk_css_node_print              (GtkCssNode                *cssnode,
156                                                          GtkStyleContextPrintFlags  flags,
157                                                          GString                   *string,
158                                                          guint                      indent);
159 
160 G_END_DECLS
161 
162 #endif /* __GTK_CSS_NODE_PRIVATE_H__ */
163