From 468f216b1cc12872c1c3af155bd0ba8a4965f780 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 14 Apr 2010 23:36:48 +0200 Subject: [PATCH] GtkCssProvider: Add state parsing. Now state is now defined as a pseudoclass in the CSS format, selectors like: GtkWidget:active { } GtkButton:insensitive { } GtkCalendar:prelight { } (also :hover is accepted) ... define the style for the given state. --- gtk/gtkcssprovider.c | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c index eb10b2ea75..c401133f2d 100644 --- a/gtk/gtkcssprovider.c +++ b/gtk/gtkcssprovider.c @@ -44,7 +44,6 @@ enum SelectorElementType { struct SelectorElement { SelectorElementType elem_type; - GtkStateType state; union { @@ -56,6 +55,7 @@ struct SelectorElement struct SelectorPath { GSList *elements; + GtkStateType state; guint ref_count; }; @@ -78,6 +78,7 @@ struct GtkCssProviderPrivate enum ParserScope { SCOPE_SELECTOR, + SCOPE_PSEUDO_CLASS, SCOPE_DECLARATION, SCOPE_VALUE }; @@ -110,6 +111,7 @@ selector_path_new (void) SelectorPath *path; path = g_slice_new0 (SelectorPath); + path->state = GTK_STATE_NORMAL; path->ref_count = 1; return path; @@ -209,6 +211,12 @@ gtk_css_provider_init (GtkCssProvider *css_provider) scanner = g_scanner_new (NULL); /* scanner->input_name = path; */ + g_scanner_scope_add_symbol (scanner, SCOPE_PSEUDO_CLASS, "active", GUINT_TO_POINTER (GTK_STATE_ACTIVE)); + g_scanner_scope_add_symbol (scanner, SCOPE_PSEUDO_CLASS, "prelight", GUINT_TO_POINTER (GTK_STATE_PRELIGHT)); + g_scanner_scope_add_symbol (scanner, SCOPE_PSEUDO_CLASS, "hover", GUINT_TO_POINTER (GTK_STATE_PRELIGHT)); + g_scanner_scope_add_symbol (scanner, SCOPE_PSEUDO_CLASS, "selected", GUINT_TO_POINTER (GTK_STATE_SELECTED)); + g_scanner_scope_add_symbol (scanner, SCOPE_PSEUDO_CLASS, "insensitive", GUINT_TO_POINTER (GTK_STATE_INSENSITIVE)); + priv->scanner = scanner; css_provider_apply_scope (css_provider, SCOPE_SELECTOR); } @@ -330,6 +338,7 @@ struct StylePriorityInfo { guint64 score; GHashTable *style; + GtkStateType state; }; static GtkStyleSet * @@ -360,6 +369,7 @@ gtk_style_get_style (GtkStyleProvider *provider, new.score = score; new.style = info->style; + new.state = info->path->state; for (j = 0; j < priority_info->len; j++) { @@ -389,7 +399,7 @@ gtk_style_get_style (GtkStyleProvider *provider, g_hash_table_iter_init (&iter, info->style); while (g_hash_table_iter_next (&iter, &key, &value)) - gtk_style_set_set_property (set, key, GTK_STATE_NORMAL, value); + gtk_style_set_set_property (set, key, info->state, value); } g_array_free (priority_info, TRUE); @@ -546,8 +556,9 @@ css_provider_commit (GtkCssProvider *css_provider) } static GTokenType -parse_selector (GScanner *scanner, - SelectorPath **selector_out) +parse_selector (GtkCssProvider *css_provider, + GScanner *scanner, + SelectorPath **selector_out) { SelectorPath *path; @@ -588,6 +599,24 @@ parse_selector (GScanner *scanner, return G_TOKEN_IDENTIFIER; } + if (scanner->token == ':') + { + /* Pseudo-class scanning */ + css_provider_push_scope (css_provider, SCOPE_PSEUDO_CLASS); + g_scanner_get_next_token (scanner); + + if (scanner->token != G_TOKEN_SYMBOL) + { + selector_path_unref (path); + return G_TOKEN_SYMBOL; + } + + path->state = GPOINTER_TO_INT (scanner->value.v_symbol); + + g_scanner_get_next_token (scanner); + css_provider_pop_scope (css_provider); + } + *selector_out = path; return G_TOKEN_NONE; @@ -648,7 +677,7 @@ parse_rule (GtkCssProvider *css_provider, priv = GTK_CSS_PROVIDER_GET_PRIVATE (css_provider); css_provider_push_scope (css_provider, SCOPE_SELECTOR); - expected_token = parse_selector (scanner, &selector); + expected_token = parse_selector (css_provider, scanner, &selector); if (expected_token != G_TOKEN_NONE) return expected_token; @@ -659,7 +688,7 @@ parse_rule (GtkCssProvider *css_provider, { g_scanner_get_next_token (scanner); - expected_token = parse_selector (scanner, &selector); + expected_token = parse_selector (css_provider, scanner, &selector); if (expected_token != G_TOKEN_NONE) return expected_token;