[gtk+/gtk-style-context: 186/260] Move all theming stack to use GtkStateFlags.



commit af72e1663af72191947512eb0c0e722dddbcba4c
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon Aug 16 19:09:34 2010 +0200

    Move all theming stack to use GtkStateFlags.
    
    This support goes from the theming engines, which are able to retrieve
    style for different combined states to the CSS provider, where several
    state pseudo-classes may be specified, such as:
    
    GtkButton:active:prelight {}

 gtk/gtkcssprovider.c   |  152 ++++++++++++++--------
 gtk/gtkstylecontext.c  |   11 +-
 gtk/gtkstylecontext.h  |    6 +-
 gtk/gtkstyleset.c      |  338 ++++++++++++++++++++++++++++++------------------
 gtk/gtkstyleset.h      |   45 +++----
 gtk/gtkthemingengine.c |  141 +++------------------
 gtk/gtkthemingengine.h |    6 +-
 7 files changed, 354 insertions(+), 345 deletions(-)
---
diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c
index 85dcdbb..0ca90fb 100644
--- a/gtk/gtkcssprovider.c
+++ b/gtk/gtkcssprovider.c
@@ -72,7 +72,7 @@ struct SelectorElement
 struct SelectorPath
 {
   GSList *elements;
-  GtkStateType state;
+  GtkStateFlags state;
   guint ref_count;
 };
 
@@ -149,7 +149,6 @@ selector_path_new (void)
   SelectorPath *path;
 
   path = g_slice_new0 (SelectorPath);
-  path->state = GTK_STATE_NORMAL;
   path->ref_count = 1;
 
   return path;
@@ -541,7 +540,7 @@ struct StylePriorityInfo
 {
   guint64 score;
   GHashTable *style;
-  GtkStateType state;
+  GtkStateFlags state;
 };
 
 static GArray *
@@ -654,10 +653,7 @@ gtk_css_provider_get_style (GtkStyleProvider *provider,
               !gtk_style_set_lookup_property (prop, NULL, NULL))
             continue;
 
-          if (info->state == GTK_STATE_NORMAL)
-            gtk_style_set_set_default (set, key, value);
-          else
-            gtk_style_set_set_property (set, key, info->state, value);
+          gtk_style_set_set_property (set, key, info->state, value);
         }
     }
 
@@ -880,14 +876,12 @@ css_provider_commit (GtkCssProvider *css_provider)
 }
 
 static GTokenType
-parse_pseudo_class (GtkCssProvider *css_provider,
-                    GScanner       *scanner,
-                    SelectorPath   *selector,
-                    GtkRegionFlags *flags)
+parse_nth_child (GtkCssProvider *css_provider,
+                 GScanner       *scanner,
+                 GtkRegionFlags *flags)
 {
   ParserSymbol symbol;
 
-  css_provider_push_scope (css_provider, SCOPE_PSEUDO_CLASS);
   g_scanner_get_next_token (scanner);
 
   if (scanner->token != G_TOKEN_SYMBOL)
@@ -941,13 +935,51 @@ parse_pseudo_class (GtkCssProvider *css_provider,
     *flags = GTK_REGION_LAST;
   else
     {
-      GtkStateType state;
+      *flags = 0;
+      return G_TOKEN_SYMBOL;
+    }
+
+  return G_TOKEN_NONE;
+}
+
+static GTokenType
+parse_pseudo_class (GtkCssProvider *css_provider,
+                    GScanner       *scanner,
+                    SelectorPath   *selector)
+{
+  GtkStateType state;
 
-      state = GPOINTER_TO_INT (scanner->value.v_symbol);
-      selector->state = state;
+  g_scanner_get_next_token (scanner);
+
+  if (scanner->token != G_TOKEN_SYMBOL)
+    return G_TOKEN_SYMBOL;
+
+  state = GPOINTER_TO_INT (scanner->value.v_symbol);
+
+  switch (state)
+    {
+    case GTK_STATE_ACTIVE:
+      selector->state |= GTK_STATE_FLAG_ACTIVE;
+      break;
+    case GTK_STATE_PRELIGHT:
+      selector->state |= GTK_STATE_FLAG_PRELIGHT;
+      break;
+    case GTK_STATE_SELECTED:
+      selector->state |= GTK_STATE_FLAG_SELECTED;
+      break;
+    case GTK_STATE_INSENSITIVE:
+      selector->state |= GTK_STATE_FLAG_INSENSITIVE;
+      break;
+    case GTK_STATE_INCONSISTENT:
+      selector->state |= GTK_STATE_FLAG_INCONSISTENT;
+      break;
+    case GTK_STATE_FOCUSED:
+      selector->state |= GTK_STATE_FLAG_FOCUSED;
+      break;
+    default:
+      return G_TOKEN_SYMBOL;
     }
 
-  css_provider_pop_scope (css_provider);
   return G_TOKEN_NONE;
 }
 
@@ -1030,18 +1062,39 @@ parse_selector (GtkCssProvider  *css_provider,
 
           region_name = g_strdup (scanner->value.v_identifier);
 
-          /* Parse nth-child type pseudo-class, and
-           * possibly a state pseudo-class after it.
-           */
-          while (path->state == GTK_STATE_NORMAL &&
-                 g_scanner_peek_next_token (scanner) == ':')
+          if (g_scanner_peek_next_token (scanner) == ':')
             {
-              GTokenType token;
+              ParserSymbol symbol;
 
               g_scanner_get_next_token (scanner);
+              css_provider_push_scope (css_provider, SCOPE_PSEUDO_CLASS);
+
+              /* Check for the next token being nth-child, parse in that
+               * case, and fallback into common state parsing if not.
+               */
+              if (g_scanner_peek_next_token (scanner) != G_TOKEN_SYMBOL)
+                return G_TOKEN_SYMBOL;
+
+              symbol = GPOINTER_TO_INT (scanner->next_value.v_symbol);
+
+              if (symbol == SYMBOL_FIRST_CHILD ||
+                  symbol == SYMBOL_LAST_CHILD ||
+                  symbol == SYMBOL_NTH_CHILD)
+                {
+                  GTokenType token;
 
-              if ((token = parse_pseudo_class (css_provider, scanner, path, &flags)) != G_TOKEN_NONE)
-                return token;
+                  if ((token = parse_nth_child (css_provider, scanner, &flags)) != G_TOKEN_NONE)
+                    return token;
+
+                  css_provider_pop_scope (css_provider);
+                }
+              else
+                {
+                  css_provider_pop_scope (css_provider);
+                  selector_path_prepend_region (path, region_name, 0);
+                  g_free (region_name);
+                  break;
+                }
             }
 
           selector_path_prepend_region (path, region_name, flags);
@@ -1054,10 +1107,6 @@ parse_selector (GtkCssProvider  *css_provider,
 
       g_scanner_get_next_token (scanner);
 
-      /* State is the last element in the selector */
-      if (path->state != GTK_STATE_NORMAL)
-        break;
-
       if (scanner->token == '>')
         {
           selector_path_prepend_combinator (path, COMBINATOR_CHILD);
@@ -1065,35 +1114,25 @@ parse_selector (GtkCssProvider  *css_provider,
         }
     }
 
-  if (scanner->token == ':' &&
-      path->state == GTK_STATE_NORMAL)
+  if (scanner->token == ':')
     {
-      GtkRegionFlags flags = 0;
-      GTokenType token;
-
       /* Add glob selector if path is empty */
       if (selector_path_depth (path) == 0)
         selector_path_prepend_glob (path);
 
-      if ((token = parse_pseudo_class (css_provider, scanner, path, &flags)) != G_TOKEN_NONE)
-        return token;
+      css_provider_push_scope (css_provider, SCOPE_PSEUDO_CLASS);
 
-      if (flags != 0)
+      while (scanner->token == ':')
         {
-          /* This means either a standalone :nth-child
-           * selector, or on a invalid element type.
-           */
-          return G_TOKEN_SYMBOL;
+          GTokenType token;
+
+          if ((token = parse_pseudo_class (css_provider, scanner, path)) != G_TOKEN_NONE)
+            return token;
+
+          g_scanner_get_next_token (scanner);
         }
 
-      g_scanner_get_next_token (scanner);
-    }
-  else if (scanner->token == G_TOKEN_SYMBOL)
-    {
-      /* A new pseudo-class was starting, but the state was already
-       * parsed, so nothing is supposed to go after that.
-       */
-      return G_TOKEN_LEFT_CURLY;
+      css_provider_pop_scope (css_provider);
     }
 
   return G_TOKEN_NONE;
@@ -1652,20 +1691,14 @@ gtk_css_provider_get_default (void)
         "@tooltip_bg_color: #eee1b3; \n"
         "@tooltip_fg_color: #000; \n"
         "\n"
-        "*, GtkTreeView > GtkButton {\n"
+        "*,\n"
+        "GtkTreeView > GtkButton {\n"
         "  background-color: @bg_color;\n"
         "  foreground-color: @fg_color;\n"
         "  text-color: @text_color; \n"
         "  base-color: @base_color; \n"
         "}\n"
         "\n"
-        "*:active {\n"
-        "  background-color: #c4c2bd;\n"
-        "  foreground-color: #000000;\n"
-        "  text-color: #c4c2bd; \n"
-        "  base-color: #9c9a94; \n"
-        "}\n"
-        "\n"
         "*:prelight {\n"
         "  background-color: #eeebe7;\n"
         "  foreground-color: #000000;\n"
@@ -1701,6 +1734,13 @@ gtk_css_provider_get_default (void)
         "GtkToggleButton:prelight {\n"
         "  text-color: #000; \n"
         "}\n"
+        "\n"
+        ".button:active {\n"
+        "  background-color: #c4c2bd;\n"
+        "  foreground-color: #000000;\n"
+        "  text-color: #c4c2bd; \n"
+        "  base-color: #9c9a94; \n"
+        "}\n"
         "\n";
 
       provider = gtk_css_provider_new ();
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index 41b607f..cd3b2c0 100644
--- a/gtk/gtkstylecontext.c
+++ b/gtk/gtkstylecontext.c
@@ -343,7 +343,7 @@ rebuild_properties (GtkStyleContext *context)
         }
     }
 
-  gtk_style_set_get (priv->store, GTK_STATE_NORMAL,
+  gtk_style_set_get (priv->store, 0,
                      "engine", &priv->theming_engine,
                      NULL);
 }
@@ -488,14 +488,13 @@ gtk_style_context_remove_provider (GtkStyleContext  *context,
 void
 gtk_style_context_get_property (GtkStyleContext *context,
                                 const gchar     *property,
-                                GtkStateType     state,
+                                GtkStateFlags    state,
                                 GValue          *value)
 {
   GtkStyleContextPrivate *priv;
 
   g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
   g_return_if_fail (property != NULL);
-  g_return_if_fail (state < GTK_STATE_LAST);
   g_return_if_fail (value != NULL);
 
   priv = context->priv;
@@ -504,13 +503,12 @@ gtk_style_context_get_property (GtkStyleContext *context,
 
 void
 gtk_style_context_get_valist (GtkStyleContext *context,
-                              GtkStateType     state,
+                              GtkStateFlags    state,
                               va_list          args)
 {
   GtkStyleContextPrivate *priv;
 
   g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
-  g_return_if_fail (state < GTK_STATE_LAST);
 
   priv = context->priv;
   gtk_style_set_get_valist (priv->store, state, args);
@@ -518,14 +516,13 @@ gtk_style_context_get_valist (GtkStyleContext *context,
 
 void
 gtk_style_context_get (GtkStyleContext *context,
-                       GtkStateType     state,
+                       GtkStateFlags    state,
                        ...)
 {
   GtkStyleContextPrivate *priv;
   va_list args;
 
   g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
-  g_return_if_fail (state < GTK_STATE_LAST);
 
   priv = context->priv;
 
diff --git a/gtk/gtkstylecontext.h b/gtk/gtkstylecontext.h
index bf0d872..833ca71 100644
--- a/gtk/gtkstylecontext.h
+++ b/gtk/gtkstylecontext.h
@@ -61,13 +61,13 @@ void gtk_style_context_restore (GtkStyleContext *context);
 
 void gtk_style_context_get_property (GtkStyleContext *context,
                                      const gchar     *property,
-                                     GtkStateType     state,
+                                     GtkStateFlags    state,
                                      GValue          *value);
 void gtk_style_context_get_valist   (GtkStyleContext *context,
-                                     GtkStateType     state,
+                                     GtkStateFlags    state,
                                      va_list          args);
 void gtk_style_context_get          (GtkStyleContext *context,
-                                     GtkStateType     state,
+                                     GtkStateFlags    state,
                                      ...) G_GNUC_NULL_TERMINATED;
 
 void          gtk_style_context_set_state    (GtkStyleContext *context,
diff --git a/gtk/gtkstyleset.c b/gtk/gtkstyleset.c
index e8b96cc..7c42f1f 100644
--- a/gtk/gtkstyleset.c
+++ b/gtk/gtkstyleset.c
@@ -33,6 +33,7 @@
 typedef struct GtkStyleSetPrivate GtkStyleSetPrivate;
 typedef struct PropertyData PropertyData;
 typedef struct PropertyNode PropertyNode;
+typedef struct ValueData ValueData;
 
 struct PropertyNode
 {
@@ -42,10 +43,15 @@ struct PropertyNode
   GtkStylePropertyParser parse_func;
 };
 
+struct ValueData
+{
+  GtkStateFlags state;
+  GValue value;
+};
+
 struct PropertyData
 {
-  GValue default_value;
-  GValue values[GTK_STATE_LAST];
+  GArray *values;
 };
 
 struct GtkStyleSetPrivate
@@ -97,6 +103,7 @@ property_data_new (void)
   PropertyData *data;
 
   data = g_slice_new0 (PropertyData);
+  data->values = g_array_new (FALSE, FALSE, sizeof (ValueData));
 
   return data;
 }
@@ -104,17 +111,138 @@ property_data_new (void)
 static void
 property_data_free (PropertyData *data)
 {
-  gint i;
+  guint i;
 
-  for (i = 0; i <= GTK_STATE_INSENSITIVE; i++)
+  for (i = 0; i < data->values->len; i++)
     {
-      if (G_IS_VALUE (&data->values[i]))
-        g_value_unset (&data->values[i]);
+      ValueData *value_data;
+
+      value_data = &g_array_index (data->values, ValueData, i);
+
+      if (G_IS_VALUE (&value_data->value))
+        g_value_unset (&value_data->value);
     }
 
   g_slice_free (PropertyData, data);
 }
 
+static gboolean
+property_data_find_position (PropertyData  *data,
+                             GtkStateFlags  state,
+                             guint         *pos)
+{
+  gint min, max, mid;
+  gboolean found = FALSE;
+  guint position;
+
+  if (pos)
+    *pos = 0;
+
+  if (data->values->len == 0)
+    return FALSE;
+
+  /* Find position for the given state, or the position where
+   * it would be if not found, the array is ordered by the
+   * state flags.
+   */
+  min = 0;
+  max = data->values->len - 1;
+
+  do
+    {
+      ValueData *value_data;
+
+      mid = (min + max) / 2;
+      value_data = &g_array_index (data->values, ValueData, mid);
+
+      if (value_data->state == state)
+        {
+          found = TRUE;
+          position = mid;
+        }
+      else if (value_data->state < state)
+          position = min = mid + 1;
+      else
+        {
+          max = mid - 1;
+          position = mid;
+        }
+    }
+  while (!found && min <= max);
+
+  if (pos)
+    *pos = position;
+
+  return found;
+}
+
+static GValue *
+property_data_get_value (PropertyData  *data,
+                         GtkStateFlags  state)
+{
+  ValueData *val_data;
+  guint pos;
+
+  if (!property_data_find_position (data, state, &pos))
+    {
+      ValueData new = { 0 };
+
+      //val_data = &g_array_index (data->values, ValueData, pos);
+      new.state = state;
+      g_array_insert_val (data->values, pos, new);
+    }
+
+  val_data = &g_array_index (data->values, ValueData, pos);
+
+  return &val_data->value;
+}
+
+static GValue *
+property_data_match_state (PropertyData  *data,
+                           GtkStateFlags  state)
+{
+  guint pos;
+  gint i;
+
+  if (property_data_find_position (data, state, &pos))
+    {
+      ValueData *val_data;
+
+      /* Exact match */
+      val_data = &g_array_index (data->values, ValueData, pos);
+      return &val_data->value;
+    }
+
+  if (pos >= data->values->len)
+    pos = data->values->len - 1;
+
+  /* No exact match, go downwards the list to find
+   * the closest match to the given state flags, as
+   * a side effect, there is an implicit precedence
+   * of higher flags over the smaller ones.
+   */
+  for (i = pos; i >= 0; i--)
+    {
+      ValueData *val_data;
+
+      val_data = &g_array_index (data->values, ValueData, i);
+
+       /* Check whether any of the requested
+        * flags are set, and no other flags are.
+        *
+        * Also, no flags acts as a wildcard, such
+        * value should be always in the first position
+        * in the array (if present) anyways.
+        */
+      if (val_data->state == 0 ||
+          ((val_data->state & state) != 0 &&
+           (val_data->state & ~state) == 0))
+        return &val_data->value;
+    }
+
+  return NULL;
+}
+
 static void
 gtk_style_set_init (GtkStyleSet *set)
 {
@@ -331,12 +459,11 @@ gtk_style_set_lookup_color (GtkStyleSet *set,
   return g_hash_table_lookup (priv->color_map, name);
 }
 
-static void
-set_property_internal (GtkStyleSet  *set,
-                       const gchar  *property,
-                       gboolean      is_default,
-                       GtkStateType  state,
-                       const GValue *value)
+void
+gtk_style_set_set_property (GtkStyleSet   *set,
+                            const gchar   *property,
+                            GtkStateFlags  state,
+                            const GValue  *value)
 {
   GtkStyleSetPrivate *priv;
   PropertyNode *node;
@@ -344,6 +471,10 @@ set_property_internal (GtkStyleSet  *set,
   GType value_type;
   GValue *val;
 
+  g_return_if_fail (GTK_IS_STYLE_SET (set));
+  g_return_if_fail (property != NULL);
+  g_return_if_fail (value != NULL);
+
   value_type = G_VALUE_TYPE (value);
   node = property_node_lookup (g_quark_try_string (property));
 
@@ -359,7 +490,7 @@ set_property_internal (GtkStyleSet  *set,
       g_return_if_fail (value_type == GDK_TYPE_COLOR || value_type == GTK_TYPE_SYMBOLIC_COLOR);
     }
   else
-    g_return_if_fail (node->property_type == G_VALUE_TYPE (value));
+    g_return_if_fail (node->property_type == value_type);
 
   priv = set->priv;
   prop = g_hash_table_lookup (priv->properties,
@@ -373,10 +504,7 @@ set_property_internal (GtkStyleSet  *set,
                            prop);
     }
 
-  if (is_default)
-    val = &prop->default_value;
-  else
-    val = &prop->values[state];
+  val = property_data_get_value (prop, state);
 
   if (G_VALUE_TYPE (val) == value_type)
     g_value_reset (val);
@@ -392,41 +520,14 @@ set_property_internal (GtkStyleSet  *set,
 }
 
 void
-gtk_style_set_set_default (GtkStyleSet  *set,
-                           const gchar  *property,
-                           const GValue *value)
-{
-  g_return_if_fail (GTK_IS_STYLE_SET (set));
-  g_return_if_fail (property != NULL);
-  g_return_if_fail (value != NULL);
-
-  set_property_internal (set, property, TRUE, GTK_STATE_NORMAL, value);
-}
-
-void
-gtk_style_set_set_property (GtkStyleSet  *set,
-                            const gchar  *property,
-                            GtkStateType  state,
-                            const GValue *value)
-{
-  g_return_if_fail (GTK_IS_STYLE_SET (set));
-  g_return_if_fail (property != NULL);
-  g_return_if_fail (state < GTK_STATE_LAST);
-  g_return_if_fail (value != NULL);
-
-  set_property_internal (set, property, FALSE, state, value);
-}
-
-void
-gtk_style_set_set_valist (GtkStyleSet  *set,
-                          GtkStateType  state,
-                          va_list       args)
+gtk_style_set_set_valist (GtkStyleSet   *set,
+                          GtkStateFlags  state,
+                          va_list        args)
 {
   GtkStyleSetPrivate *priv;
   const gchar *property_name;
 
   g_return_if_fail (GTK_IS_STYLE_SET (set));
-  g_return_if_fail (state < GTK_STATE_LAST);
 
   priv = set->priv;
   property_name = va_arg (args, const gchar *);
@@ -436,6 +537,7 @@ gtk_style_set_set_valist (GtkStyleSet  *set,
       PropertyNode *node;
       PropertyData *prop;
       gchar *error = NULL;
+      GValue *val;
 
       node = property_node_lookup (g_quark_try_string (property_name));
 
@@ -456,14 +558,19 @@ gtk_style_set_set_valist (GtkStyleSet  *set,
                                prop);
         }
 
-      g_value_init (&prop->values[state], node->property_type);
-      G_VALUE_COLLECT (&prop->values[state], args, 0, &error);
+      val = property_data_get_value (prop, state);
+
+      if (G_IS_VALUE (val))
+        g_value_unset (val);
+
+      g_value_init (val, node->property_type);
+      G_VALUE_COLLECT (val, args, 0, &error);
 
       if (error)
         {
           g_warning ("Could not set style property \"%s\": %s", property_name, error);
-          g_value_unset (&prop->values[state]);
-	  g_free (error);
+          g_value_unset (val);
+          g_free (error);
           break;
         }
 
@@ -472,14 +579,13 @@ gtk_style_set_set_valist (GtkStyleSet  *set,
 }
 
 void
-gtk_style_set_set (GtkStyleSet  *set,
-                   GtkStateType  state,
+gtk_style_set_set (GtkStyleSet   *set,
+                   GtkStateFlags  state,
                    ...)
 {
   va_list args;
 
   g_return_if_fail (GTK_IS_STYLE_SET (set));
-  g_return_if_fail (state < GTK_STATE_LAST);
 
   va_start (args, state);
   gtk_style_set_set_valist (set, state, args);
@@ -505,10 +611,10 @@ resolve_color (GtkStyleSet *set,
 }
 
 gboolean
-gtk_style_set_get_property (GtkStyleSet  *set,
-                            const gchar  *property,
-                            GtkStateType  state,
-                            GValue       *value)
+gtk_style_set_get_property (GtkStyleSet   *set,
+                            const gchar   *property,
+                            GtkStateFlags  state,
+                            GValue        *value)
 {
   GtkStyleSetPrivate *priv;
   PropertyNode *node;
@@ -517,7 +623,6 @@ gtk_style_set_get_property (GtkStyleSet  *set,
 
   g_return_val_if_fail (GTK_IS_STYLE_SET (set), FALSE);
   g_return_val_if_fail (property != NULL, FALSE);
-  g_return_val_if_fail (state < GTK_STATE_LAST, FALSE);
   g_return_val_if_fail (value != NULL, FALSE);
 
   node = property_node_lookup (g_quark_try_string (property));
@@ -537,11 +642,9 @@ gtk_style_set_get_property (GtkStyleSet  *set,
 
   g_value_init (value, node->property_type);
 
-  if (G_IS_VALUE (&prop->values[state]))
-    val = &prop->values[state];
-  else if (G_IS_VALUE (&prop->default_value))
-    val = &prop->default_value;
-  else
+  val = property_data_match_state (prop, state);
+
+  if (!val && G_IS_VALUE (&node->default_value))
     val = &node->default_value;
 
   g_return_val_if_fail (G_IS_VALUE (val), FALSE);
@@ -560,15 +663,14 @@ gtk_style_set_get_property (GtkStyleSet  *set,
 }
 
 void
-gtk_style_set_get_valist (GtkStyleSet  *set,
-                          GtkStateType  state,
-                          va_list       args)
+gtk_style_set_get_valist (GtkStyleSet   *set,
+                          GtkStateFlags  state,
+                          va_list        args)
 {
   GtkStyleSetPrivate *priv;
   const gchar *property_name;
 
   g_return_if_fail (GTK_IS_STYLE_SET (set));
-  g_return_if_fail (state < GTK_STATE_LAST);
 
   priv = set->priv;
   property_name = va_arg (args, const gchar *);
@@ -604,14 +706,9 @@ gtk_style_set_get_valist (GtkStyleSet  *set,
           GValue *val = NULL;
 
           if (prop)
-            {
-              if (G_IS_VALUE (&prop->values[state]))
-                val = &prop->values[state];
-              else if (G_IS_VALUE (&prop->default_value))
-                val = &prop->default_value;
-            }
+            val = property_data_match_state (prop, state);
 
-          if (!val)
+          if (!val && G_IS_VALUE (&node->default_value))
             val = &node->default_value;
 
           if (G_VALUE_TYPE (val) == GTK_TYPE_SYMBOLIC_COLOR)
@@ -637,14 +734,13 @@ gtk_style_set_get_valist (GtkStyleSet  *set,
 }
 
 void
-gtk_style_set_get (GtkStyleSet  *set,
-                   GtkStateType  state,
+gtk_style_set_get (GtkStyleSet   *set,
+                   GtkStateFlags  state,
                    ...)
 {
   va_list args;
 
   g_return_if_fail (GTK_IS_STYLE_SET (set));
-  g_return_if_fail (state < GTK_STATE_LAST);
 
   va_start (args, state);
   gtk_style_set_get_valist (set, state, args);
@@ -652,17 +748,17 @@ gtk_style_set_get (GtkStyleSet  *set,
 }
 
 void
-gtk_style_set_unset_property (GtkStyleSet  *set,
-                              const gchar  *property,
-                              GtkStateType  state)
+gtk_style_set_unset_property (GtkStyleSet   *set,
+                              const gchar   *property,
+                              GtkStateFlags  state)
 {
   GtkStyleSetPrivate *priv;
   PropertyNode *node;
   PropertyData *prop;
+  guint pos;
 
   g_return_if_fail (GTK_IS_STYLE_SET (set));
   g_return_if_fail (property != NULL);
-  g_return_if_fail (state < GTK_STATE_LAST);
 
   node = property_node_lookup (g_quark_try_string (property));
 
@@ -679,7 +775,17 @@ gtk_style_set_unset_property (GtkStyleSet  *set,
   if (!prop)
     return;
 
-  g_value_unset (&prop->values[state]);
+  if (property_data_find_position (prop, state, &pos))
+    {
+      ValueData *data;
+
+      data = &g_array_index (prop->values, ValueData, pos);
+
+      if (G_IS_VALUE (&data->value))
+        g_value_unset (&data->value);
+
+      g_array_remove_index (prop->values, pos);
+    }
 }
 
 void
@@ -735,62 +841,38 @@ gtk_style_set_merge (GtkStyleSet       *set,
   while (g_hash_table_iter_next (&iter, &key, &value))
     {
       PropertyData *prop_to_merge = value;
-      PropertyData *prop = NULL;
-      GtkStateType i;
+      PropertyData *prop;
+      guint i;
 
-      for (i = GTK_STATE_NORMAL; i < GTK_STATE_LAST; i++)
+      prop = g_hash_table_lookup (priv->properties, key);
+
+      if (!prop)
         {
-          if (G_VALUE_TYPE (&prop_to_merge->values[i]) == G_TYPE_INVALID)
-            continue;
+          prop = property_data_new ();
+          g_hash_table_insert (priv->properties, key, prop);
+        }
 
-          if (!prop)
-            prop = g_hash_table_lookup (priv->properties, key);
+      for (i = 0; i < prop_to_merge->values->len; i++)
+        {
+          ValueData *data;
+          GValue *value;
 
-          if (!prop)
-            {
-              prop = property_data_new ();
-              g_hash_table_insert (priv->properties, key, prop);
-            }
+          data = &g_array_index (prop_to_merge->values, ValueData, i);
+          value = property_data_get_value (prop, data->state);
 
-          if (replace ||
-              G_VALUE_TYPE (&prop->values[i]) == G_TYPE_INVALID)
+          if (replace || !G_IS_VALUE (value))
             {
-              if (!G_IS_VALUE (&prop->values[i]))
-                g_value_init (&prop->values[i], G_VALUE_TYPE (&prop_to_merge->values[i]));
-              else if (G_VALUE_TYPE (&prop->values[i]) != G_VALUE_TYPE (&prop_to_merge->values[i]))
+              if (!G_IS_VALUE (value))
+                g_value_init (value, G_VALUE_TYPE (&data->value));
+              else if (G_VALUE_TYPE (value) != G_VALUE_TYPE (&data->value))
                 {
-                  g_value_unset (&prop->values[i]);
-                  g_value_init (&prop->values[i], G_VALUE_TYPE (&prop_to_merge->values[i]));
+                  g_value_unset (value);
+                  g_value_init (value, G_VALUE_TYPE (&data->value));
                 }
 
-              g_value_copy (&prop_to_merge->values[i],
-                            &prop->values[i]);
+              g_value_copy (&data->value, value);
             }
         }
-
-      if (G_IS_VALUE (&prop_to_merge->default_value) &&
-          (replace || !prop || !G_IS_VALUE (&prop->default_value)))
-        {
-          if (!prop)
-            prop = g_hash_table_lookup (priv->properties, key);
-
-          if (!prop)
-            {
-              prop = property_data_new ();
-              g_hash_table_insert (priv->properties, key, prop);
-            }
-
-          if (!G_IS_VALUE (&prop->default_value))
-            g_value_init (&prop->default_value, G_VALUE_TYPE (&prop_to_merge->default_value));
-          else if (G_VALUE_TYPE (&prop->default_value) != G_VALUE_TYPE (&prop_to_merge->default_value))
-            {
-              g_value_unset (&prop->default_value);
-              g_value_init (&prop->default_value, G_VALUE_TYPE (&prop_to_merge->default_value));
-            }
-
-          g_value_copy (&prop_to_merge->default_value,
-                        &prop->default_value);
-        }
     }
 }
 
diff --git a/gtk/gtkstyleset.h b/gtk/gtkstyleset.h
index cf46a2f..8b8750c 100644
--- a/gtk/gtkstyleset.h
+++ b/gtk/gtkstyleset.h
@@ -71,34 +71,31 @@ void               gtk_style_set_map_color    (GtkStyleSet      *set,
 GtkSymbolicColor * gtk_style_set_lookup_color (GtkStyleSet *set,
                                                const gchar *name);
 
-void     gtk_style_set_set_default  (GtkStyleSet  *set,
-                                     const gchar  *property,
-                                     const GValue *value);
-void     gtk_style_set_set_property (GtkStyleSet  *set,
-                                     const gchar  *property,
-                                     GtkStateType  state,
-                                     const GValue *value);
-void     gtk_style_set_set_valist   (GtkStyleSet  *set,
-                                     GtkStateType  state,
-                                     va_list       args);
-void     gtk_style_set_set          (GtkStyleSet  *set,
-                                     GtkStateType  state,
+void     gtk_style_set_set_property (GtkStyleSet   *set,
+                                     const gchar   *property,
+                                     GtkStateFlags  state,
+                                     const GValue  *value);
+void     gtk_style_set_set_valist   (GtkStyleSet   *set,
+                                     GtkStateFlags  state,
+                                     va_list        args);
+void     gtk_style_set_set          (GtkStyleSet   *set,
+                                     GtkStateFlags  state,
                                      ...) G_GNUC_NULL_TERMINATED;
 
-gboolean gtk_style_set_get_property (GtkStyleSet  *set,
-                                     const gchar  *property,
-                                     GtkStateType  state,
-                                     GValue       *value);
-void     gtk_style_set_get_valist   (GtkStyleSet  *set,
-                                     GtkStateType  state,
-                                     va_list       args);
-void     gtk_style_set_get          (GtkStyleSet  *set,
-                                     GtkStateType  state,
+gboolean gtk_style_set_get_property (GtkStyleSet   *set,
+                                     const gchar   *property,
+                                     GtkStateFlags  state,
+                                     GValue        *value);
+void     gtk_style_set_get_valist   (GtkStyleSet   *set,
+                                     GtkStateFlags  state,
+                                     va_list        args);
+void     gtk_style_set_get          (GtkStyleSet   *set,
+                                     GtkStateFlags  state,
                                      ...) G_GNUC_NULL_TERMINATED;
 
-void     gtk_style_set_unset_property (GtkStyleSet  *set,
-                                       const gchar  *property,
-                                       GtkStateType  state);
+void     gtk_style_set_unset_property (GtkStyleSet   *set,
+                                       const gchar   *property,
+                                       GtkStateFlags  state);
 
 void     gtk_style_set_clear          (GtkStyleSet  *set);
 
diff --git a/gtk/gtkthemingengine.c b/gtk/gtkthemingengine.c
index f90946b..a7a740b 100644
--- a/gtk/gtkthemingengine.c
+++ b/gtk/gtkthemingengine.c
@@ -216,14 +216,13 @@ gtk_theming_engine_register_property (GtkThemingEngine       *engine,
 void
 gtk_theming_engine_get_property (GtkThemingEngine *engine,
                                  const gchar      *property,
-                                 GtkStateType      state,
+                                 GtkStateFlags     state,
                                  GValue           *value)
 {
   GtkThemingEnginePrivate *priv;
 
   g_return_if_fail (GTK_IS_THEMING_ENGINE (engine));
   g_return_if_fail (property != NULL);
-  g_return_if_fail (state < GTK_STATE_LAST);
   g_return_if_fail (value != NULL);
 
   priv = engine->priv;
@@ -232,13 +231,12 @@ gtk_theming_engine_get_property (GtkThemingEngine *engine,
 
 void
 gtk_theming_engine_get_valist (GtkThemingEngine *engine,
-                               GtkStateType      state,
+                               GtkStateFlags     state,
                                va_list           args)
 {
   GtkThemingEnginePrivate *priv;
 
   g_return_if_fail (GTK_IS_THEMING_ENGINE (engine));
-  g_return_if_fail (state < GTK_STATE_LAST);
 
   priv = engine->priv;
   gtk_style_context_get_valist (priv->context, state, args);
@@ -246,14 +244,13 @@ gtk_theming_engine_get_valist (GtkThemingEngine *engine,
 
 void
 gtk_theming_engine_get (GtkThemingEngine *engine,
-                        GtkStateType      state,
+                        GtkStateFlags     state,
                         ...)
 {
   GtkThemingEnginePrivate *priv;
   va_list args;
 
   g_return_if_fail (GTK_IS_THEMING_ENGINE (engine));
-  g_return_if_fail (state < GTK_STATE_LAST);
 
   priv = engine->priv;
 
@@ -509,19 +506,13 @@ gtk_theming_engine_render_check (GtkThemingEngine *engine,
   GdkColor *fg_color, *base_color, *text_color;
   const GtkWidgetPath *path;
   GtkStateFlags flags;
-  GtkStateType state;
   gint exterior_size, interior_size, thickness, pad;
 
   flags = gtk_theming_engine_get_state (engine);
   path = gtk_theming_engine_get_path (engine);
   cairo_save (cr);
 
-  if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else
-    state = GTK_STATE_NORMAL;
-
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "foreground-color", &fg_color,
                           "base-color", &base_color,
                           "text-color", &text_color,
@@ -625,7 +616,6 @@ gtk_theming_engine_render_option (GtkThemingEngine *engine,
   GtkStateFlags flags;
   GdkColor *base_color, *fg_color, *text_color;
   const GtkWidgetPath *path;
-  GtkStateType state;
   gint exterior_size, interior_size, pad, thickness;
   gdouble radius;
 
@@ -637,12 +627,7 @@ gtk_theming_engine_render_option (GtkThemingEngine *engine,
 
   cairo_save (cr);
 
-  if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else
-    state = GTK_STATE_NORMAL;
-
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "foreground-color", &fg_color,
                           "base-color", &base_color,
                           "text-color", &text_color,
@@ -758,21 +743,13 @@ gtk_theming_engine_render_arrow (GtkThemingEngine *engine,
                                  gdouble           size)
 {
   GtkStateFlags flags;
-  GtkStateType state;
   GdkColor *fg_color;
 
   cairo_save (cr);
 
   flags = gtk_theming_engine_get_state (engine);
 
-  if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else if (flags & GTK_STATE_FLAG_INSENSITIVE)
-    state = GTK_STATE_INSENSITIVE;
-  else
-    state = GTK_STATE_NORMAL;
-
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "foreground-color", &fg_color,
                           NULL);
 
@@ -900,29 +877,17 @@ gtk_theming_engine_render_background (GtkThemingEngine *engine,
                                       gdouble           height)
 {
   GtkStateFlags flags;
-  GtkStateType state;
   GdkColor *color;
 
   cairo_save (cr);
   flags = gtk_theming_engine_get_state (engine);
 
-  if (flags & GTK_STATE_FLAG_ACTIVE)
-    state = GTK_STATE_ACTIVE;
-  else if (flags & GTK_STATE_FLAG_SELECTED)
-    state = GTK_STATE_SELECTED;
-  else if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else if (flags & GTK_STATE_FLAG_INSENSITIVE)
-    state = GTK_STATE_INSENSITIVE;
-  else
-    state = GTK_STATE_NORMAL;
-
   if (gtk_theming_engine_has_class (engine, "entry"))
-    gtk_theming_engine_get (engine, state,
+    gtk_theming_engine_get (engine, flags,
                             "base-color", &color,
                             NULL);
   else
-    gtk_theming_engine_get (engine, state,
+    gtk_theming_engine_get (engine, flags,
                             "background-color", &color,
                             NULL);
 
@@ -958,23 +923,15 @@ gtk_theming_engine_render_frame (GtkThemingEngine *engine,
                                  gdouble           height)
 {
   GtkStateFlags flags;
-  GtkStateType state;
   GdkColor lighter, darker;
   GdkColor *bg_color;
 
   cairo_save (cr);
   flags = gtk_theming_engine_get_state (engine);
 
-  if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else if (flags & GTK_STATE_FLAG_INSENSITIVE)
-    state = GTK_STATE_INSENSITIVE;
-  else
-    state = GTK_STATE_NORMAL;
-
   cairo_set_line_width (cr, 1);
 
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "background-color", &bg_color,
                           NULL);
   color_shade (bg_color, 0.7, &darker);
@@ -1125,7 +1082,6 @@ gtk_theming_engine_render_expander (GtkThemingEngine *engine,
 {
   GtkStateFlags flags;
   GdkColor *bg_color, *fg_color, *base_color;
-  GtkStateType state;
   double vertical_overshoot;
   int diameter;
   double radius;
@@ -1139,14 +1095,7 @@ gtk_theming_engine_render_expander (GtkThemingEngine *engine,
   cairo_save (cr);
   flags = gtk_theming_engine_get_state (engine);
 
-  if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else if (flags & GTK_STATE_FLAG_INSENSITIVE)
-    state = GTK_STATE_INSENSITIVE;
-  else
-    state = GTK_STATE_NORMAL;
-
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "foreground-color", &fg_color,
                           "background-color", &bg_color,
                           "base-color", &base_color,
@@ -1241,7 +1190,6 @@ gtk_theming_engine_render_focus (GtkThemingEngine *engine,
                                  gdouble           height)
 {
   GtkStateFlags flags;
-  GtkStateType state;
   GdkColor *color;
   gint line_width;
   gint8 *dash_list;
@@ -1249,14 +1197,7 @@ gtk_theming_engine_render_focus (GtkThemingEngine *engine,
   cairo_save (cr);
   flags = gtk_theming_engine_get_state (engine);
 
-  if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else if (flags & GTK_STATE_FLAG_INSENSITIVE)
-    state = GTK_STATE_INSENSITIVE;
-  else
-    state = GTK_STATE_NORMAL;
-
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "foreground-color", &color,
                           NULL);
 
@@ -1320,7 +1261,6 @@ gtk_theming_engine_render_line (GtkThemingEngine *engine,
 {
   GdkColor *bg_color, darker, lighter;
   GtkStateFlags flags;
-  GtkStateType state;
   gint i, thickness, thickness_dark, thickness_light, len;
   cairo_matrix_t matrix;
   gdouble angle;
@@ -1333,14 +1273,7 @@ gtk_theming_engine_render_line (GtkThemingEngine *engine,
   flags = gtk_theming_engine_get_state (engine);
   cairo_save (cr);
 
-  if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else if (flags & GTK_STATE_FLAG_INSENSITIVE)
-    state = GTK_STATE_INSENSITIVE;
-  else
-    state = GTK_STATE_NORMAL;
-
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "background-color", &bg_color,
                           NULL);
   color_shade (bg_color, 0.7, &darker);
@@ -1535,7 +1468,6 @@ gtk_theming_engine_render_layout (GtkThemingEngine *engine,
 {
   GdkColor *fg_color;
   GtkStateFlags flags;
-  GtkStateType state;
   GdkScreen *screen;
 
   cairo_save (cr);
@@ -1543,24 +1475,13 @@ gtk_theming_engine_render_layout (GtkThemingEngine *engine,
 
   /* FIXME: Set clipping */
 
-  if (flags & GTK_STATE_FLAG_ACTIVE)
-    state = GTK_STATE_ACTIVE;
-  else if (flags & GTK_STATE_FLAG_SELECTED)
-    state = GTK_STATE_SELECTED;
-  else if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else if (flags & GTK_STATE_FLAG_INSENSITIVE)
-    state = GTK_STATE_INSENSITIVE;
-  else
-    state = GTK_STATE_NORMAL;
-
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "foreground-color", &fg_color,
                           NULL);
 
   screen = gtk_theming_engine_get_screen (engine);
 
-  if (state == GTK_STATE_INSENSITIVE)
+  if (gtk_theming_engine_is_state_set (engine, GTK_STATE_INSENSITIVE))
     {
       PangoLayout *insensitive_layout;
 
@@ -1629,7 +1550,6 @@ gtk_theming_engine_render_frame_gap (GtkThemingEngine *engine,
                                      gdouble           xy1_gap)
 {
   GtkStateFlags flags;
-  GtkStateType state;
   GdkColor *bg_color;
   GdkColor lighter, darker;
   guint sides;
@@ -1637,16 +1557,9 @@ gtk_theming_engine_render_frame_gap (GtkThemingEngine *engine,
   cairo_save (cr);
   flags = gtk_theming_engine_get_state (engine);
 
-  if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else if (flags & GTK_STATE_FLAG_INSENSITIVE)
-    state = GTK_STATE_INSENSITIVE;
-  else
-    state = GTK_STATE_NORMAL;
-
   cairo_set_line_width (cr, 1);
 
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "background-color", &bg_color,
                           NULL);
   color_shade (bg_color, 0.7, &darker);
@@ -1786,25 +1699,15 @@ gtk_theming_engine_render_extension (GtkThemingEngine *engine,
                                      GtkPositionType   gap_side)
 {
   GtkStateFlags flags;
-  GtkStateType state;
   GdkColor *bg_color;
   GdkColor lighter, darker;
 
   cairo_save (cr);
   flags = gtk_theming_engine_get_state (engine);
 
-  if (flags & GTK_STATE_FLAG_ACTIVE)
-    state = GTK_STATE_ACTIVE;
-  else if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else if (flags & GTK_STATE_FLAG_INSENSITIVE)
-    state = GTK_STATE_INSENSITIVE;
-  else
-    state = GTK_STATE_NORMAL;
-
   cairo_set_line_width (cr, 1);
 
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "background-color", &bg_color,
                           NULL);
   color_shade (bg_color, 0.7, &darker);
@@ -1956,7 +1859,6 @@ gtk_theming_engine_render_handle (GtkThemingEngine *engine,
                                   GtkOrientation    orientation)
 {
   GtkStateFlags flags;
-  GtkStateType state;
   GdkColor *bg_color;
   GdkColor lighter, darker;
   gint xx, yy;
@@ -1964,18 +1866,9 @@ gtk_theming_engine_render_handle (GtkThemingEngine *engine,
   cairo_save (cr);
   flags = gtk_theming_engine_get_state (engine);
 
-  if (flags & GTK_STATE_FLAG_ACTIVE)
-    state = GTK_STATE_ACTIVE;
-  else if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else if (flags & GTK_STATE_FLAG_INSENSITIVE)
-    state = GTK_STATE_INSENSITIVE;
-  else
-    state = GTK_STATE_NORMAL;
-
   cairo_set_line_width (cr, 1);
 
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "background-color", &bg_color,
                           NULL);
   color_shade (bg_color, 0.7, &darker);
diff --git a/gtk/gtkthemingengine.h b/gtk/gtkthemingengine.h
index 9696206..326fc63 100644
--- a/gtk/gtkthemingengine.h
+++ b/gtk/gtkthemingengine.h
@@ -147,13 +147,13 @@ void gtk_theming_engine_register_property (GtkThemingEngine       *engine,
 
 void gtk_theming_engine_get_property (GtkThemingEngine *engine,
                                       const gchar      *property,
-                                      GtkStateType      state,
+                                      GtkStateFlags     state,
                                       GValue           *value);
 void gtk_theming_engine_get_valist   (GtkThemingEngine *engine,
-                                      GtkStateType      state,
+                                      GtkStateFlags     state,
                                       va_list           args);
 void gtk_theming_engine_get          (GtkThemingEngine *engine,
-                                      GtkStateType      state,
+                                      GtkStateFlags     state,
                                       ...) G_GNUC_NULL_TERMINATED;
 
 void gtk_theming_engine_get_style_property (GtkThemingEngine *engine,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]