diff options
author | Matthias Clasen <mclasen@redhat.com> | 2015-12-28 01:09:54 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2016-01-03 09:19:30 -0500 |
commit | 68edc47f6a1585c90d8cace2f65c61a2a413b79e (patch) | |
tree | 58bf74ba106dcea1d070440e676970092beb450b /gtk/gtkcssnode.c | |
parent | a6624d803ece178e467230e285cd9d4561b09ca1 (diff) | |
download | gtk+-68edc47f6a1585c90d8cace2f65c61a2a413b79e.tar.gz |
Add a function to dump CSS nodes and styles
Add a gtk_style_context_to_string function that can serialize
a CSS node or tree of nodes, optionally including CSS properties
as well.
This will be useful in writing tests.
Diffstat (limited to 'gtk/gtkcssnode.c')
-rw-r--r-- | gtk/gtkcssnode.c | 190 |
1 files changed, 189 insertions, 1 deletions
diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c index fca7de0cec..4bae4e51ea 100644 --- a/gtk/gtkcssnode.c +++ b/gtk/gtkcssnode.c @@ -25,6 +25,8 @@ #include "gtkmarshalers.h" #include "gtksettingsprivate.h" #include "gtktypebuiltins.h" +#include "gtkcssstylepropertyprivate.h" +#include "gtkcsssectionprivate.h" /* * CSS nodes are the backbone of the GtkStyleContext implementation and @@ -1510,7 +1512,7 @@ GtkStyleProviderPrivate * gtk_css_node_get_style_provider (GtkCssNode *cssnode) { GtkStyleProviderPrivate *result; - + result = gtk_css_node_get_style_provider_or_null (cssnode); if (result) return result; @@ -1520,3 +1522,189 @@ gtk_css_node_get_style_provider (GtkCssNode *cssnode) return GTK_STYLE_PROVIDER_PRIVATE (_gtk_settings_get_style_cascade (gtk_settings_get_default (), 1)); } + +static void +append_id (GtkCssNode *cssnode, + GString *string) +{ + const char *id; + + id = gtk_css_node_get_id (cssnode); + if (id) + { + g_string_append (string, " id="); + g_string_append (string, id); + } +} + +static void +append_visible (GtkCssNode *cssnode, + GString *string) +{ + g_string_append_printf (string, " visible=%d", gtk_css_node_get_visible (cssnode)); +} + +static void +append_state (GtkCssNode *cssnode, + GString *string) + +{ + GtkStateFlags state; + + state = gtk_css_node_get_state (cssnode); + if (state) + { + GFlagsClass *fclass; + gint i; + gboolean first = TRUE; + + g_string_append (string, " state="); + fclass = g_type_class_ref (GTK_TYPE_STATE_FLAGS); + for (i = 0; i < fclass->n_values; i++) + { + if (state & fclass->values[i].value) + { + if (first) + first = FALSE; + else + g_string_append_c (string, '|'); + g_string_append (string, fclass->values[i].value_nick); + } + } + g_type_class_unref (fclass); + } +} + +static void +append_classes (GtkCssNode *cssnode, + GString *string) +{ + const GQuark *classes; + guint n_classes; + + classes = gtk_css_node_list_classes (cssnode, &n_classes); + if (n_classes > 0) + { + int i; + + g_string_append (string, " classes="); + for (i = 0; i < n_classes; i++) + { + if (i > 0) + g_string_append_c (string, ','); + g_string_append (string, g_quark_to_string (classes[i])); + } + } +} + +static gboolean +gtk_css_node_has_initial_value (GtkCssNode *cssnode, + GtkCssStyleProperty *prop) +{ + GtkCssNode *parent_node; + GtkCssStyle *style, *parent_style; + GtkCssValue *value, *initial, *computed; + GtkCssProvider *provider; + gboolean is_initial; + guint id; + + id = _gtk_css_style_property_get_id (prop); + style = gtk_css_node_get_style (cssnode); + value = gtk_css_style_get_value (style, id); + + parent_node = gtk_css_node_get_parent (cssnode); + parent_style = parent_node ? gtk_css_node_get_style (parent_node) : NULL; + provider = gtk_css_node_get_style_provider (cssnode); + + initial = _gtk_css_style_property_get_initial_value (prop); + computed = _gtk_css_value_compute (initial, id, provider, style, parent_style); + + is_initial = _gtk_css_value_equal (value, computed); + + _gtk_css_value_unref (computed); + + return is_initial; +} + +static void +append_value (GtkCssNode *cssnode, + GtkCssStyleProperty *prop, + GString *string, + guint indent) +{ + GtkCssValue *value; + GtkCssStyle *style; + GtkCssSection *section; + const char *name; + guint id; + + id = _gtk_css_style_property_get_id (prop); + name = _gtk_style_property_get_name (GTK_STYLE_PROPERTY (prop)); + style = gtk_css_node_get_style (cssnode); + value = gtk_css_style_get_value (style, id); + + g_string_append_printf (string, "%*s%s: ", indent, "", name); + + _gtk_css_value_print (value, string); + + section = gtk_css_style_get_section (style, id); + if (section) + { + g_string_append (string, " ("); + _gtk_css_section_print (section, string); + g_string_append (string, ")"); + } + + g_string_append_c (string, '\n'); +} + +static void +append_style (GtkCssNode *cssnode, + GtkStyleContextPrintFlags flags, + GString *string, + guint indent) +{ + int i; + + if (!(flags & GTK_STYLE_CONTEXT_PRINT_SHOW_STYLE)) + return; + + for (i = 0; i < _gtk_css_style_property_get_n_properties (); i++) + { + GtkCssStyleProperty *prop; + + prop = _gtk_css_style_property_lookup_by_id (i); + + if ((flags & GTK_STYLE_CONTEXT_PRINT_SHOW_INITIAL) || + !gtk_css_node_has_initial_value (cssnode, prop)) + append_value (cssnode, prop, string, indent); + } +} + +void +gtk_css_node_print (GtkCssNode *cssnode, + GtkStyleContextPrintFlags flags, + GString *string, + guint indent) +{ + GtkCssNode *node; + + g_string_append_printf (string, "%*s", indent, ""); + if (gtk_css_node_get_name (cssnode)) + g_string_append (string, gtk_css_node_get_name (cssnode)); + else + g_string_append (string, g_type_name (gtk_css_node_get_widget_type (cssnode))); + append_id (cssnode, string); + append_visible (cssnode, string); + append_state (cssnode, string); + append_classes (cssnode, string); + g_string_append_c (string, '\n'); + + append_style (cssnode, flags, string, indent + 2); + + if (flags & GTK_STYLE_CONTEXT_PRINT_RECURSE) + { + for (node = gtk_css_node_get_first_child (cssnode); node; node = gtk_css_node_get_next_sibling (node)) + gtk_css_node_print (node, flags, string, indent + 2); + } +} |