[gtk+/wip/cssnode3: 40/88] cssnode: Add a matcher for nodes
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/cssnode3: 40/88] cssnode: Add a matcher for nodes
- Date: Thu, 5 Mar 2015 19:54:10 +0000 (UTC)
commit 4c70e54c993af7a6904f2891180621a6ecf2ee7f
Author: Benjamin Otte <otte redhat com>
Date: Mon Feb 9 16:41:06 2015 +0100
cssnode: Add a matcher for nodes
... and use that matcher by default - ie for transient nodes.
gtk/gtkcssmatcher.c | 179 ++++++++++++++++++++++++++++++++++++++++++++
gtk/gtkcssmatcherprivate.h | 9 ++
gtk/gtkcssnode.c | 18 +----
3 files changed, 189 insertions(+), 17 deletions(-)
---
diff --git a/gtk/gtkcssmatcher.c b/gtk/gtkcssmatcher.c
index 7d92ec8..374b567 100644
--- a/gtk/gtkcssmatcher.c
+++ b/gtk/gtkcssmatcher.c
@@ -20,6 +20,7 @@
#include "gtkcssmatcherprivate.h"
#include "gtkcssnodedeclarationprivate.h"
+#include "gtkcssnodeprivate.h"
#include "gtkwidgetpath.h"
/* GTK_CSS_MATCHER_WIDGET_PATH */
@@ -240,6 +241,184 @@ _gtk_css_matcher_init (GtkCssMatcher *matcher,
return TRUE;
}
+/* GTK_CSS_MATCHER_NODE */
+
+static gboolean
+gtk_css_matcher_node_get_parent (GtkCssMatcher *matcher,
+ const GtkCssMatcher *child)
+{
+ GtkCssNode *node;
+
+ node = gtk_css_node_get_parent (child->node.node);
+ if (node == NULL)
+ return FALSE;
+
+ return gtk_css_node_init_matcher (node, matcher, NULL);
+}
+
+static gboolean
+gtk_css_matcher_node_get_previous (GtkCssMatcher *matcher,
+ const GtkCssMatcher *next)
+{
+ GtkCssNode *node;
+
+ node = gtk_css_node_get_previous_sibling (next->node.node);
+ if (node == NULL)
+ return FALSE;
+
+ return gtk_css_node_init_matcher (node, matcher, NULL);
+}
+
+static GtkStateFlags
+gtk_css_matcher_node_get_state (const GtkCssMatcher *matcher)
+{
+ return gtk_css_node_get_state (matcher->node.node);
+}
+
+static gboolean
+gtk_css_matcher_node_has_type (const GtkCssMatcher *matcher,
+ GType type)
+{
+ return g_type_is_a (gtk_css_node_get_widget_type (matcher->node.node), type);
+}
+
+static gboolean
+gtk_css_matcher_node_has_class (const GtkCssMatcher *matcher,
+ GQuark class_name)
+{
+ return gtk_css_node_has_class (matcher->node.node, class_name);
+}
+
+static gboolean
+gtk_css_matcher_node_has_id (const GtkCssMatcher *matcher,
+ const char *id)
+{
+ return gtk_css_node_get_id (matcher->node.node) == g_intern_string (id);
+}
+
+static gboolean
+gtk_css_matcher_node_has_regions (const GtkCssMatcher *matcher)
+{
+ GList *regions;
+ gboolean result;
+
+ regions = gtk_css_node_list_regions (matcher->node.node);
+ result = regions != NULL;
+ g_list_free (regions);
+
+ return result;
+}
+
+static gboolean
+gtk_css_matcher_node_has_region (const GtkCssMatcher *matcher,
+ const char *region,
+ GtkRegionFlags flags)
+{
+ GtkRegionFlags region_flags;
+ GQuark region_quark;
+
+ region_quark = g_quark_try_string (region);
+ if (!region_quark)
+ return FALSE;
+
+ if (!gtk_css_node_has_region (matcher->node.node, region_quark, ®ion_flags))
+ return FALSE;
+
+ if ((flags & region_flags) != flags)
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+gtk_css_matcher_node_nth_child (GtkCssNode *node,
+ int a,
+ int b)
+{
+ while (b-- > 0)
+ {
+ if (node == NULL)
+ return FALSE;
+
+ node = gtk_css_node_get_previous_sibling (node);
+ }
+
+ if (a == 0)
+ return node == NULL;
+ else if (a == 1)
+ return TRUE;
+
+ b = 0;
+ while (node)
+ {
+ b++;
+ node = gtk_css_node_get_previous_sibling (node);
+ }
+
+ return b % a == 0;
+}
+
+static gboolean
+gtk_css_matcher_node_nth_last_child (GtkCssNode *node,
+ int a,
+ int b)
+{
+ while (b-- > 0)
+ {
+ if (node == NULL)
+ return FALSE;
+
+ node = gtk_css_node_get_next_sibling (node);
+ }
+
+ if (a == 0)
+ return node == NULL;
+ else if (a == 1)
+ return TRUE;
+
+ b = 0;
+ while (node)
+ {
+ b++;
+ node = gtk_css_node_get_next_sibling (node);
+ }
+
+ return b % a == 0;
+}
+
+static gboolean
+gtk_css_matcher_node_has_position (const GtkCssMatcher *matcher,
+ gboolean forward,
+ int a,
+ int b)
+{
+ if (forward)
+ return gtk_css_matcher_node_nth_child (matcher->node.node, a, b);
+ else
+ return gtk_css_matcher_node_nth_last_child (matcher->node.node, a, b);
+}
+
+static const GtkCssMatcherClass GTK_CSS_MATCHER_NODE = {
+ gtk_css_matcher_node_get_parent,
+ gtk_css_matcher_node_get_previous,
+ gtk_css_matcher_node_get_state,
+ gtk_css_matcher_node_has_type,
+ gtk_css_matcher_node_has_class,
+ gtk_css_matcher_node_has_id,
+ gtk_css_matcher_node_has_regions,
+ gtk_css_matcher_node_has_region,
+ gtk_css_matcher_node_has_position,
+ FALSE
+};
+
+void
+_gtk_css_matcher_node_init (GtkCssMatcher *matcher,
+ GtkCssNode *node)
+{
+ matcher->node.klass = >K_CSS_MATCHER_NODE;
+ matcher->node.node = node;
+}
+
/* GTK_CSS_MATCHER_WIDGET_ANY */
static gboolean
diff --git a/gtk/gtkcssmatcherprivate.h b/gtk/gtkcssmatcherprivate.h
index e517501..1a788f3 100644
--- a/gtk/gtkcssmatcherprivate.h
+++ b/gtk/gtkcssmatcherprivate.h
@@ -24,6 +24,7 @@
G_BEGIN_DECLS
+typedef struct _GtkCssMatcherNode GtkCssMatcherNode;
typedef struct _GtkCssMatcherSuperset GtkCssMatcherSuperset;
typedef struct _GtkCssMatcherWidgetPath GtkCssMatcherWidgetPath;
typedef struct _GtkCssMatcherClass GtkCssMatcherClass;
@@ -60,6 +61,11 @@ struct _GtkCssMatcherWidgetPath {
guint sibling_index;
};
+struct _GtkCssMatcherNode {
+ const GtkCssMatcherClass *klass;
+ GtkCssNode *node;
+};
+
struct _GtkCssMatcherSuperset {
const GtkCssMatcherClass *klass;
const GtkCssMatcher *subset;
@@ -69,12 +75,15 @@ struct _GtkCssMatcherSuperset {
union _GtkCssMatcher {
const GtkCssMatcherClass *klass;
GtkCssMatcherWidgetPath path;
+ GtkCssMatcherNode node;
GtkCssMatcherSuperset superset;
};
gboolean _gtk_css_matcher_init (GtkCssMatcher *matcher,
const GtkWidgetPath *path,
const GtkCssNodeDeclaration *decl)
G_GNUC_WARN_UNUSED_RESULT;
+void _gtk_css_matcher_node_init (GtkCssMatcher *matcher,
+ GtkCssNode *node);
void _gtk_css_matcher_any_init (GtkCssMatcher *matcher);
void _gtk_css_matcher_superset_init (GtkCssMatcher *matcher,
const GtkCssMatcher *subset,
diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c
index 377fb63..a04ba3b 100644
--- a/gtk/gtkcssnode.c
+++ b/gtk/gtkcssnode.c
@@ -301,24 +301,8 @@ gtk_css_node_real_init_matcher (GtkCssNode *cssnode,
GtkCssMatcher *matcher,
GtkWidgetPath **path_out)
{
- GtkWidgetPath *path;
-
- path = gtk_css_node_create_widget_path (cssnode);
-
- if (!_gtk_css_matcher_init (matcher, path, NULL))
- {
- gtk_widget_path_free (path);
- return FALSE;
- }
-
- if (path_out == NULL)
- {
- gtk_widget_path_free (path);
- g_assert_not_reached ();
- return FALSE;
- }
+ _gtk_css_matcher_node_init (matcher, cssnode);
- *path_out = path;
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]