[gtk+/wip/cssvalue: 8/142] css: Add selector change types



commit 1514ee59c67a3cbec7ab33ae9f819ff0a884480b
Author: Benjamin Otte <otte redhat com>
Date:   Sat Mar 17 19:23:53 2012 +0100

    css: Add selector change types
    
    This allows querying selectors for which changes would change their
    "matchingness".

 gtk/gtkcssselector.c        |  109 +++++++++++++++++++++++++++++++++++++++++--
 gtk/gtkcssselectorprivate.h |    3 +-
 gtk/gtkcsstypes.c           |   56 ++++++++++++++++++++++
 gtk/gtkcsstypesprivate.h    |   34 +++++++++++++
 4 files changed, 196 insertions(+), 6 deletions(-)
---
diff --git a/gtk/gtkcssselector.c b/gtk/gtkcssselector.c
index d5373d0..b622582 100644
--- a/gtk/gtkcssselector.c
+++ b/gtk/gtkcssselector.c
@@ -29,10 +29,11 @@ typedef struct _GtkCssSelectorClass GtkCssSelectorClass;
 struct _GtkCssSelectorClass {
   const char        *name;
 
-  void              (* print)   (const GtkCssSelector       *selector,
-                                 GString                    *string);
-  gboolean          (* match)   (const GtkCssSelector       *selector,
-                                 const GtkCssMatcher        *matcher);
+  void              (* print)       (const GtkCssSelector       *selector,
+                                     GString                    *string);
+  gboolean          (* match)       (const GtkCssSelector       *selector,
+                                     const GtkCssMatcher        *matcher);
+  GtkCssChange      (* get_change)  (const GtkCssSelector       *selector);
 
   guint         increase_id_specificity :1;
   guint         increase_class_specificity :1;
@@ -57,6 +58,15 @@ gtk_css_selector_match (const GtkCssSelector *selector,
   return selector->class->match (selector, matcher);
 }
 
+static GtkCssChange
+gtk_css_selector_get_change (const GtkCssSelector *selector)
+{
+  if (selector == NULL)
+    return 0;
+
+  return selector->class->get_change (selector);
+}
+
 static const GtkCssSelector *
 gtk_css_selector_previous (const GtkCssSelector *selector)
 {
@@ -91,10 +101,17 @@ gtk_css_selector_descendant_match (const GtkCssSelector *selector,
   return FALSE;
 }
 
+static GtkCssChange
+gtk_css_selector_descendant_get_change (const GtkCssSelector *selector)
+{
+  return _gtk_css_change_for_child (gtk_css_selector_get_change (gtk_css_selector_previous (selector)));
+}
+
 static const GtkCssSelectorClass GTK_CSS_SELECTOR_DESCENDANT = {
   "descendant",
   gtk_css_selector_descendant_print,
   gtk_css_selector_descendant_match,
+  gtk_css_selector_descendant_get_change,
   FALSE, FALSE, FALSE
 };
 
@@ -119,10 +136,17 @@ gtk_css_selector_child_match (const GtkCssSelector *selector,
   return gtk_css_selector_match (gtk_css_selector_previous (selector), &parent);
 }
 
+static GtkCssChange
+gtk_css_selector_child_get_change (const GtkCssSelector *selector)
+{
+  return _gtk_css_change_for_child (gtk_css_selector_get_change (gtk_css_selector_previous (selector)));
+}
+
 static const GtkCssSelectorClass GTK_CSS_SELECTOR_CHILD = {
   "child",
   gtk_css_selector_child_print,
   gtk_css_selector_child_match,
+  gtk_css_selector_child_get_change,
   FALSE, FALSE, FALSE
 };
 
@@ -152,10 +176,17 @@ gtk_css_selector_sibling_match (const GtkCssSelector *selector,
   return FALSE;
 }
 
+static GtkCssChange
+gtk_css_selector_sibling_get_change (const GtkCssSelector *selector)
+{
+  return _gtk_css_change_for_sibling (gtk_css_selector_get_change (gtk_css_selector_previous (selector)));
+}
+
 static const GtkCssSelectorClass GTK_CSS_SELECTOR_SIBLING = {
   "sibling",
   gtk_css_selector_sibling_print,
   gtk_css_selector_sibling_match,
+  gtk_css_selector_sibling_get_change,
   FALSE, FALSE, FALSE
 };
 
@@ -180,10 +211,17 @@ gtk_css_selector_adjacent_match (const GtkCssSelector *selector,
   return gtk_css_selector_match (gtk_css_selector_previous (selector), &previous);
 }
 
+static GtkCssChange
+gtk_css_selector_adjacent_get_change (const GtkCssSelector *selector)
+{
+  return _gtk_css_change_for_sibling (gtk_css_selector_get_change (gtk_css_selector_previous (selector)));
+}
+
 static const GtkCssSelectorClass GTK_CSS_SELECTOR_ADJACENT = {
   "adjacent",
   gtk_css_selector_adjacent_print,
   gtk_css_selector_adjacent_match,
+  gtk_css_selector_adjacent_get_change,
   FALSE, FALSE, FALSE
 };
 
@@ -213,10 +251,17 @@ gtk_css_selector_any_match (const GtkCssSelector *selector,
   return gtk_css_selector_match (previous, matcher);
 }
 
+static GtkCssChange
+gtk_css_selector_any_get_change (const GtkCssSelector *selector)
+{
+  return gtk_css_selector_get_change (gtk_css_selector_previous (selector));
+}
+
 static const GtkCssSelectorClass GTK_CSS_SELECTOR_ANY = {
   "any",
   gtk_css_selector_any_print,
   gtk_css_selector_any_match,
+  gtk_css_selector_any_get_change,
   FALSE, FALSE, FALSE
 };
 
@@ -239,10 +284,17 @@ gtk_css_selector_name_match (const GtkCssSelector *selector,
   return gtk_css_selector_match (gtk_css_selector_previous (selector), matcher);
 }
 
+static GtkCssChange
+gtk_css_selector_name_get_change (const GtkCssSelector *selector)
+{
+  return gtk_css_selector_get_change (gtk_css_selector_previous (selector)) | GTK_CSS_CHANGE_NAME;
+}
+
 static const GtkCssSelectorClass GTK_CSS_SELECTOR_NAME = {
   "name",
   gtk_css_selector_name_print,
   gtk_css_selector_name_match,
+  gtk_css_selector_name_get_change,
   FALSE, FALSE, TRUE
 };
 
@@ -272,10 +324,23 @@ gtk_css_selector_region_match (const GtkCssSelector *selector,
   return gtk_css_selector_match (previous, matcher);
 }
 
+static GtkCssChange
+gtk_css_selector_region_get_change (const GtkCssSelector *selector)
+{
+  GtkCssChange change;
+
+  change = gtk_css_selector_get_change (gtk_css_selector_previous (selector));
+  change |= GTK_CSS_CHANGE_REGION;
+  change |= _gtk_css_change_for_child (change);
+
+  return change;
+}
+
 static const GtkCssSelectorClass GTK_CSS_SELECTOR_REGION = {
   "region",
   gtk_css_selector_region_print,
   gtk_css_selector_region_match,
+  gtk_css_selector_region_get_change,
   FALSE, FALSE, TRUE
 };
 
@@ -299,10 +364,17 @@ gtk_css_selector_class_match (const GtkCssSelector *selector,
   return gtk_css_selector_match (gtk_css_selector_previous (selector), matcher);
 }
 
+static GtkCssChange
+gtk_css_selector_class_get_change (const GtkCssSelector *selector)
+{
+  return gtk_css_selector_get_change (gtk_css_selector_previous (selector)) | GTK_CSS_CHANGE_CLASS;
+}
+
 static const GtkCssSelectorClass GTK_CSS_SELECTOR_CLASS = {
   "class",
   gtk_css_selector_class_print,
   gtk_css_selector_class_match,
+  gtk_css_selector_class_get_change,
   FALSE, TRUE, FALSE
 };
 
@@ -326,10 +398,17 @@ gtk_css_selector_id_match (const GtkCssSelector *selector,
   return gtk_css_selector_match (gtk_css_selector_previous (selector), matcher);
 }
 
+static GtkCssChange
+gtk_css_selector_id_get_change (const GtkCssSelector *selector)
+{
+  return gtk_css_selector_get_change (gtk_css_selector_previous (selector)) | GTK_CSS_CHANGE_ID;
+}
+
 static const GtkCssSelectorClass GTK_CSS_SELECTOR_ID = {
   "id",
   gtk_css_selector_id_print,
   gtk_css_selector_id_match,
+  gtk_css_selector_id_get_change,
   TRUE, FALSE, FALSE
 };
 
@@ -377,10 +456,17 @@ gtk_css_selector_pseudoclass_state_match (const GtkCssSelector *selector,
   return gtk_css_selector_match (gtk_css_selector_previous (selector), matcher);
 }
 
+static GtkCssChange
+gtk_css_selector_pseudoclass_state_get_change (const GtkCssSelector *selector)
+{
+  return gtk_css_selector_get_change (gtk_css_selector_previous (selector)) | GTK_CSS_CHANGE_STATE;
+}
+
 static const GtkCssSelectorClass GTK_CSS_SELECTOR_PSEUDOCLASS_STATE = {
   "pseudoclass-state",
   gtk_css_selector_pseudoclass_state_print,
   gtk_css_selector_pseudoclass_state_match,
+  gtk_css_selector_pseudoclass_state_get_change,
   FALSE, TRUE, FALSE
 };
 
@@ -487,10 +573,17 @@ gtk_css_selector_pseudoclass_region_match (const GtkCssSelector *selector,
   return gtk_css_selector_match (previous, matcher);
 }
 
+static GtkCssChange
+gtk_css_selector_pseudoclass_region_get_change (const GtkCssSelector *selector)
+{
+  return gtk_css_selector_get_change (gtk_css_selector_previous (selector)) | GTK_CSS_CHANGE_POSITION;
+}
+
 static const GtkCssSelectorClass GTK_CSS_SELECTOR_PSEUDOCLASS_REGION = {
   "pseudoclass-region",
   gtk_css_selector_pseudoclass_region_print,
   gtk_css_selector_pseudoclass_region_match,
+  gtk_css_selector_pseudoclass_region_get_change,
   FALSE, TRUE, FALSE
 };
 
@@ -815,6 +908,14 @@ _gtk_css_selector_to_string (const GtkCssSelector *selector)
   return g_string_free (string, FALSE);
 }
 
+GtkCssChange
+_gtk_css_selector_get_change (const GtkCssSelector *selector)
+{
+  g_return_val_if_fail (selector != NULL, 0);
+
+  return gtk_css_selector_get_change (selector);
+}
+
 /**
  * _gtk_css_selector_matches:
  * @selector: the selector
diff --git a/gtk/gtkcssselectorprivate.h b/gtk/gtkcssselectorprivate.h
index e1d7623..6430054 100644
--- a/gtk/gtkcssselectorprivate.h
+++ b/gtk/gtkcssselectorprivate.h
@@ -18,8 +18,6 @@
 #ifndef __GTK_CSS_SELECTOR_PRIVATE_H__
 #define __GTK_CSS_SELECTOR_PRIVATE_H__
 
-#include <gtk/gtkenums.h>
-#include <gtk/gtktypes.h>
 #include "gtk/gtkcssmatcherprivate.h"
 #include "gtk/gtkcssparserprivate.h"
 
@@ -36,6 +34,7 @@ void              _gtk_css_selector_print           (const GtkCssSelector   *sel
 
 GtkStateFlags     _gtk_css_selector_get_state_flags (const GtkCssSelector   *selector);
 
+GtkCssChange      _gtk_css_selector_get_change      (const GtkCssSelector   *selector);
 gboolean          _gtk_css_selector_matches         (const GtkCssSelector   *selector,
                                                      const GtkCssMatcher    *matcher);
 int               _gtk_css_selector_compare         (const GtkCssSelector   *a,
diff --git a/gtk/gtkcsstypes.c b/gtk/gtkcsstypes.c
index 508a3db..0133c72 100644
--- a/gtk/gtkcsstypes.c
+++ b/gtk/gtkcsstypes.c
@@ -36,6 +36,62 @@ DEFINE_BOXED_TYPE_WITH_COPY_FUNC (GtkCssBorderCornerRadius, _gtk_css_border_corn
 DEFINE_BOXED_TYPE_WITH_COPY_FUNC (GtkCssBorderImageRepeat, _gtk_css_border_image_repeat)
 DEFINE_BOXED_TYPE_WITH_COPY_FUNC (GtkCssNumber, _gtk_css_number)
 
+typedef struct _GtkCssChangeTranslation GtkCssChangeTranslation;
+struct _GtkCssChangeTranslation {
+  GtkCssChange from;
+  GtkCssChange to;
+};
+
+static GtkCssChange
+gtk_css_change_translate (GtkCssChange                   match,
+                         const GtkCssChangeTranslation *translations,
+                         guint                         n_translations)
+{
+  GtkCssChange result = match;
+  guint i;
+
+  for (i = 0; i < n_translations; i++)
+    {
+      if (match & translations[i].from)
+        {
+          result &= ~translations[i].from;
+          result |= translations[i].to;
+        }
+    }
+
+  return result;
+}
+
+GtkCssChange
+_gtk_css_change_for_sibling (GtkCssChange match)
+{
+  static const GtkCssChangeTranslation table[] = {
+    { GTK_CSS_CHANGE_CLASS, GTK_CSS_CHANGE_SIBLING_CLASS },
+    { GTK_CSS_CHANGE_NAME, GTK_CSS_CHANGE_SIBLING_NAME },
+    { GTK_CSS_CHANGE_POSITION, GTK_CSS_CHANGE_SIBLING_POSITION },
+    { GTK_CSS_CHANGE_STATE, GTK_CSS_CHANGE_SIBLING_STATE },
+  };
+
+  return gtk_css_change_translate (match, table, G_N_ELEMENTS (table)); 
+}
+
+GtkCssChange
+_gtk_css_change_for_child (GtkCssChange match)
+{
+  static const GtkCssChangeTranslation table[] = {
+    { GTK_CSS_CHANGE_CLASS, GTK_CSS_CHANGE_PARENT_CLASS },
+    { GTK_CSS_CHANGE_NAME, GTK_CSS_CHANGE_PARENT_NAME },
+    { GTK_CSS_CHANGE_POSITION, GTK_CSS_CHANGE_PARENT_POSITION },
+    { GTK_CSS_CHANGE_STATE, GTK_CSS_CHANGE_PARENT_STATE },
+    { GTK_CSS_CHANGE_SIBLING_CLASS, GTK_CSS_CHANGE_PARENT_SIBLING_CLASS },
+    { GTK_CSS_CHANGE_SIBLING_NAME, GTK_CSS_CHANGE_PARENT_SIBLING_NAME },
+    { GTK_CSS_CHANGE_SIBLING_POSITION, GTK_CSS_CHANGE_PARENT_SIBLING_POSITION },
+    { GTK_CSS_CHANGE_SIBLING_STATE, GTK_CSS_CHANGE_PARENT_SIBLING_STATE }
+  };
+
+  return gtk_css_change_translate (match, table, G_N_ELEMENTS (table)); 
+}
+
 void
 _gtk_css_number_init (GtkCssNumber *number,
                       double        value,
diff --git a/gtk/gtkcsstypesprivate.h b/gtk/gtkcsstypesprivate.h
index 7f23931..c064b86 100644
--- a/gtk/gtkcsstypesprivate.h
+++ b/gtk/gtkcsstypesprivate.h
@@ -23,6 +23,37 @@
 
 G_BEGIN_DECLS
 
+typedef enum { /*< skip >*/
+  GTK_CSS_CHANGE_CLASS                    = (1 <<  0),
+  GTK_CSS_CHANGE_NAME                     = (1 <<  1),
+  GTK_CSS_CHANGE_ID                       = GTK_CSS_CHANGE_NAME,
+  GTK_CSS_CHANGE_REGION                   = GTK_CSS_CHANGE_NAME,
+  GTK_CSS_CHANGE_POSITION                 = (1 <<  2),
+  GTK_CSS_CHANGE_STATE                    = (1 <<  3),
+  GTK_CSS_CHANGE_SIBLING_CLASS            = (1 <<  4),
+  GTK_CSS_CHANGE_SIBLING_NAME             = (1 <<  5),
+  GTK_CSS_CHANGE_SIBLING_POSITION         = (1 <<  6),
+  GTK_CSS_CHANGE_SIBLING_STATE            = (1 <<  7),
+  GTK_CSS_CHANGE_PARENT_CLASS             = (1 <<  8),
+  GTK_CSS_CHANGE_PARENT_NAME              = (1 <<  9),
+  GTK_CSS_CHANGE_PARENT_POSITION          = (1 << 10),
+  GTK_CSS_CHANGE_PARENT_STATE             = (1 << 11),
+  GTK_CSS_CHANGE_PARENT_SIBLING_CLASS     = (1 << 12),
+  GTK_CSS_CHANGE_PARENT_SIBLING_NAME      = (1 << 13),
+  GTK_CSS_CHANGE_PARENT_SIBLING_POSITION  = (1 << 14),
+  GTK_CSS_CHANGE_PARENT_SIBLING_STATE     = (1 << 15),
+  /* add more */
+} GtkCssChange;
+
+#define GTK_CSS_CHANGE_ANY ((1 << 16) - 1)
+#define GTK_CSS_CHANGE_ANY_SELF (GTK_CSS_CHANGE_CLASS | GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_POSITION | GTK_CSS_CHANGE_STATE)
+#define GTK_CSS_CHANGE_ANY_SIBLING (GTK_CSS_CHANGE_SIBLING_CLASS | GTK_CSS_CHANGE_SIBLING_NAME | \
+                                    GTK_CSS_CHANGE_SIBLING_POSITION | GTK_CSS_CHANGE_SIBLING_STATE)
+#define GTK_CSS_CHANGE_ANY_PARENT (GTK_CSS_CHANGE_PARENT_CLASS | GTK_CSS_CHANGE_PARENT_SIBLING_CLASS | \
+                                   GTK_CSS_CHANGE_PARENT_NAME | GTK_CSS_CHANGE_PARENT_SIBLING_NAME | \
+                                   GTK_CSS_CHANGE_PARENT_POSITION | GTK_CSS_CHANGE_PARENT_SIBLING_POSITION | \
+                                   GTK_CSS_CHANGE_PARENT_STATE | GTK_CSS_CHANGE_PARENT_SIBLING_STATE)
+
 typedef enum {
   GTK_CSS_INHERIT,
   GTK_CSS_INITIAL
@@ -142,6 +173,9 @@ GType           _gtk_css_border_corner_radius_get_type          (void);
 GType           _gtk_css_border_image_repeat_get_type           (void);
 GType           _gtk_css_number_get_type                        (void);
 
+GtkCssChange    _gtk_css_change_for_sibling                      (GtkCssChange       match);
+GtkCssChange    _gtk_css_change_for_child                        (GtkCssChange       match);
+
 #define GTK_CSS_NUMBER_INIT(_value,_unit) { (_value), (_unit) }
 void            _gtk_css_number_init                            (GtkCssNumber       *number,
                                                                  double              value,



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