[gtk+/gtk-style-context: 70/206] Refurbish GtkWidgetPath API.
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/gtk-style-context: 70/206] Refurbish GtkWidgetPath API.
- Date: Mon, 23 Aug 2010 17:20:48 +0000 (UTC)
commit f3c219559fa225798de273971b3d13077b02a315
Author: Carlos Garnacho <carlosg gnome org>
Date: Wed Apr 21 01:27:46 2010 +0200
Refurbish GtkWidgetPath API.
The foreach() function is now gone, there's now API to get
GTypes and names from the position in the path.
gtk/gtkcssprovider.c | 115 ++++++++++++++++--------------
gtk/gtkwidget.c | 4 +-
gtk/gtkwidgetpath.c | 191 +++++++++++++++++++++++++++-----------------------
gtk/gtkwidgetpath.h | 32 +++++----
4 files changed, 185 insertions(+), 157 deletions(-)
---
diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c
index 8fbddc2..039f4a0 100644
--- a/gtk/gtkcssprovider.c
+++ b/gtk/gtkcssprovider.c
@@ -271,15 +271,12 @@ struct ComparePathData
};
static gboolean
-compare_path_foreach (GType type,
- const gchar *name,
- gpointer user_data)
+compare_selector_element (GtkWidgetPath *path,
+ guint index,
+ SelectorElement *elem,
+ guint8 *score)
{
- ComparePathData *data;
- SelectorElement *elem;
-
- data = user_data;
- elem = data->iter->data;
+ *score = 0;
if (elem->elem_type == SELECTOR_TYPE_NAME)
{
@@ -295,8 +292,7 @@ compare_path_foreach (GType type,
/* Type couldn't be resolved, so the selector
* clearly doesn't affect the given widget path
*/
- data->score = 0;
- return TRUE;
+ return FALSE;
}
elem->elem_type = SELECTOR_GTYPE;
@@ -305,84 +301,95 @@ compare_path_foreach (GType type,
if (elem->elem_type == SELECTOR_GTYPE)
{
+ GType type;
+
+ type = gtk_widget_path_get_element_type (path, index);
+
if (!g_type_is_a (type, elem->type))
- {
- /* Selector definitely doesn't match */
- if (elem->combinator == COMBINATOR_CHILD)
- {
- data->score = 0;
- return TRUE;
- }
- else
- {
- /* Keep checking descendants for a match */
- return FALSE;
- }
- }
- else if (type == elem->type)
- data->score |= 0xF;
+ return FALSE;
+
+ if (type == elem->type)
+ *score |= 0xF;
else
{
GType parent = type;
- guint8 score = 0xE;
+
+ *score = 0xE;
while ((parent = g_type_parent (parent)) != G_TYPE_INVALID)
{
if (parent == elem->type)
break;
- score--;
+ *score -= 1;
- if (score == 1)
+ if (*score == 1)
{
g_warning ("Hierarchy is higher than expected.");
break;
}
}
-
- data->score |= score;
}
+
+ return TRUE;
}
else if (elem->elem_type == SELECTOR_GLOB)
{
/* Treat as lowest matching type */
- data->score++;
- }
-
- data->iter = data->iter->next;
-
- if (data->iter)
- {
- data->score <<= 4;
- return FALSE;
+ *score = 1;
+ return TRUE;
}
- return TRUE;
+ return FALSE;
}
static guint64
compare_selector (GtkWidgetPath *path,
SelectorPath *selector)
{
- ComparePathData data;
+ GSList *elements = selector->elements;
+ gboolean match = TRUE;
+ guint64 score = 0;
+ guint i = 0;
+
+ while (elements && match &&
+ i < gtk_widget_path_length (path))
+ {
+ SelectorElement *elem;
+ guint8 elem_score;
- data.score = 0;
- data.path = selector;
- data.iter = selector->elements;
+ elem = elements->data;
+ elements = elements->next;
- gtk_widget_path_foreach (path,
- compare_path_foreach,
- &data);
+ match = compare_selector_element (path, i, elem, &elem_score);
+ i++;
- if (data.iter)
- {
- /* There is remaining data to compare,
- * so don't take it as a match.
- */
- data.score = 0;
+ if (!match && elem->combinator == COMBINATOR_DESCENDANT)
+ {
+ /* With descendant combinators there may
+ * be intermediate chidren in the hierarchy
+ */
+ match = TRUE;
+ }
+
+ if (match)
+ {
+ score <<= 4;
+ score |= elem_score;
+ }
}
- return data.score;
+ /* If there are pending selector
+ * elements to compare, it's not
+ * a match.
+ */
+ if (elements)
+ match = FALSE;
+
+ if (!match)
+ score = 0;
+
+ return score;
}
typedef struct StylePriorityInfo StylePriorityInfo;
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 6b91f8b..e53b151 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -11581,9 +11581,7 @@ gtk_widget_get_path (GtkWidget *widget)
while (widget)
{
- gtk_widget_path_prepend_widget_desc (path,
- G_OBJECT_TYPE (widget),
- widget->name);
+ gtk_widget_path_prepend_type (path, G_OBJECT_TYPE (widget));
widget = widget->parent;
}
diff --git a/gtk/gtkwidgetpath.c b/gtk/gtkwidgetpath.c
index 2af624f..a6cfccc 100644
--- a/gtk/gtkwidgetpath.c
+++ b/gtk/gtkwidgetpath.c
@@ -34,8 +34,7 @@ struct GtkPathElement
struct GtkWidgetPath
{
- GSList *elems;
- GSList *last; /* Last element contains the described widget */
+ GArray *elems; /* First element contains the described widget */
};
GtkWidgetPath *
@@ -44,139 +43,157 @@ gtk_widget_path_new (void)
GtkWidgetPath *path;
path = g_slice_new0 (GtkWidgetPath);
+ path->elems = g_array_new (FALSE, TRUE, sizeof (GtkPathElement));
return path;
}
-static GtkPathElement *
-path_element_new (GType type,
- const gchar *name)
+GtkWidgetPath *
+gtk_widget_path_copy (const GtkWidgetPath *path)
{
- GtkPathElement *elem;
+ GtkWidgetPath *new_path;
+ guint i;
- elem = g_slice_new (GtkPathElement);
- elem->type = type;
- elem->name = g_strdup (name);
+ g_return_val_if_fail (path != NULL, NULL);
- return elem;
-}
+ new_path = gtk_widget_path_new ();
-static void
-path_element_free (GtkPathElement *elem)
-{
- g_free (elem->name);
- g_slice_free (GtkPathElement, elem);
+ for (i = 0; i < path->elems->len; i++)
+ {
+ GtkPathElement *elem, new = { 0 };
+
+ elem = &g_array_index (path->elems, GtkPathElement, i);
+
+ new.type = elem->type;
+ new.name = g_strdup (elem->name);
+
+ g_array_append_val (new_path->elems, new);
+ }
+
+ return new_path;
}
void
-gtk_widget_path_prepend_widget_desc (GtkWidgetPath *path,
- GType type,
- const gchar *name)
+gtk_widget_path_free (GtkWidgetPath *path)
{
+ guint i;
+
g_return_if_fail (path != NULL);
- g_return_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET));
- if (!path->elems)
+ for (i = 0; i < path->elems->len; i++)
{
- path->elems = g_slist_prepend (NULL, path_element_new (type, name));
- path->last = path->elems;
- }
- else
- {
- path->last->next = g_slist_alloc ();
- path->last->next->data = path_element_new (type, name);
- path->last = path->last->next;
+ GtkPathElement *elem;
+
+ elem = &g_array_index (path->elems, GtkPathElement, i);
+ g_free (elem->name);
}
+
+ g_array_free (path->elems, TRUE);
+ g_slice_free (GtkWidgetPath, path);
}
-GtkWidgetPath *
-gtk_widget_path_copy (GtkWidgetPath *path)
+guint
+gtk_widget_path_length (GtkWidgetPath *path)
{
- GtkWidgetPath *new_path;
- GSList *elems;
-
- new_path = gtk_widget_path_new ();
- elems = path->elems;
+ g_return_val_if_fail (path != NULL, 0);
- while (elems)
- {
- GtkPathElement *elem;
- GSList *link;
+ return path->elems->len;
+}
- elem = elems->data;
- link = g_slist_alloc ();
- link->data = path_element_new (elem->type, elem->name);
+guint
+gtk_widget_path_prepend_type (GtkWidgetPath *path,
+ GType type)
+{
+ GtkPathElement new = { 0 };
- if (!new_path->elems)
- new_path->last = new_path->elems = link;
- else
- {
- new_path->last->next = link;
- new_path->last = link;
- }
+ g_return_val_if_fail (path != NULL, 0);
+ g_return_val_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET), 0);
- elems = elems->next;
- }
+ new.type = type;
+ g_array_append_val (path->elems, new);
- return new_path;
+ return path->elems->len - 1;
}
-void
-gtk_widget_path_free (GtkWidgetPath *path)
+GType
+gtk_widget_path_get_element_type (GtkWidgetPath *path,
+ guint pos)
{
- g_return_if_fail (path != NULL);
+ GtkPathElement *elem;
- g_slist_foreach (path->elems, (GFunc) path_element_free, NULL);
- g_slist_free (path->elems);
+ g_return_val_if_fail (path != NULL, G_TYPE_INVALID);
+ g_return_val_if_fail (pos < path->elems->len, G_TYPE_INVALID);
- g_slice_free (GtkWidgetPath, path);
+ elem = &g_array_index (path->elems, GtkPathElement, pos);
+ return elem->type;
}
-gboolean
-gtk_widget_path_has_parent (GtkWidgetPath *path,
- GType type)
+void
+gtk_widget_path_set_element_type (GtkWidgetPath *path,
+ guint pos,
+ GType type)
{
- g_return_val_if_fail (path != NULL, FALSE);
- g_return_val_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET), FALSE);
+ GtkPathElement *elem;
- GSList *elems = path->elems;
+ g_return_if_fail (path != NULL);
+ g_return_if_fail (pos < path->elems->len);
+ g_return_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET));
- while (elems)
- {
- GtkPathElement *elem;
+ elem = &g_array_index (path->elems, GtkPathElement, pos);
+ elem->type = type;
+}
- elem = elems->data;
+G_CONST_RETURN gchar *
+gtk_widget_path_get_element_name (GtkWidgetPath *path,
+ guint pos)
+{
+ GtkPathElement *elem;
- if (elem->type == type ||
- g_type_is_a (elem->type, type))
- return TRUE;
+ g_return_val_if_fail (path != NULL, NULL);
+ g_return_val_if_fail (pos < path->elems->len, NULL);
- elems = elems->next;
- }
-
- return FALSE;
+ elem = &g_array_index (path->elems, GtkPathElement, pos);
+ return elem->name;
}
void
-gtk_widget_path_foreach (GtkWidgetPath *path,
- GtkWidgetPathForeachFunc func,
- gpointer user_data)
+gtk_widget_path_set_element_name (GtkWidgetPath *path,
+ guint pos,
+ const gchar *name)
{
- GSList *elems;
+ GtkPathElement *elem;
g_return_if_fail (path != NULL);
- g_return_if_fail (func != NULL);
+ g_return_if_fail (pos < path->elems->len);
+ g_return_if_fail (name != NULL);
+
+ elem = &g_array_index (path->elems, GtkPathElement, pos);
+
+ if (elem->name)
+ g_free (elem->name);
+
+ elem->name = g_strdup (name);
+}
+
+gboolean
+gtk_widget_path_has_parent (const GtkWidgetPath *path,
+ GType type)
+{
+ guint i;
- elems = path->elems;
+ g_return_val_if_fail (path != NULL, FALSE);
+ g_return_val_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET), FALSE);
- while (elems)
+ for (i = 1; i < path->elems->len; i++)
{
GtkPathElement *elem;
- elem = elems->data;
- elems = elems->next;
+ elem = &g_array_index (path->elems, GtkPathElement, i);
- if ((func) (elem->type, elem->name, user_data))
- return;
+ if (elem->type == type ||
+ g_type_is_a (elem->type, type))
+ return TRUE;
}
+
+ return FALSE;
}
diff --git a/gtk/gtkwidgetpath.h b/gtk/gtkwidgetpath.h
index 664562c..3846988 100644
--- a/gtk/gtkwidgetpath.h
+++ b/gtk/gtkwidgetpath.h
@@ -21,31 +21,37 @@
#define __GTK_WIDGET_PATH_H__
#include <glib-object.h>
+#include "gtkenums.h"
G_BEGIN_DECLS
typedef struct GtkWidgetPath GtkWidgetPath;
-typedef gboolean (* GtkWidgetPathForeachFunc) (GType type,
- const gchar *name,
- gpointer user_data);
GtkWidgetPath * gtk_widget_path_new (void);
-void gtk_widget_path_prepend_widget_desc (GtkWidgetPath *path,
- GType type,
- const gchar *name);
+GtkWidgetPath * gtk_widget_path_copy (const GtkWidgetPath *path);
+void gtk_widget_path_free (GtkWidgetPath *path);
-GtkWidgetPath * gtk_widget_path_copy (GtkWidgetPath *path);
-void gtk_widget_path_free (GtkWidgetPath *path);
+guint gtk_widget_path_length (GtkWidgetPath *path);
-gboolean gtk_widget_path_has_parent (GtkWidgetPath *path,
- GType type);
+guint gtk_widget_path_prepend_type (GtkWidgetPath *path,
+ GType type);
-void gtk_widget_path_foreach (GtkWidgetPath *path,
- GtkWidgetPathForeachFunc func,
- gpointer user_data);
+GType gtk_widget_path_get_element_type (GtkWidgetPath *path,
+ guint pos);
+void gtk_widget_path_set_element_type (GtkWidgetPath *path,
+ guint pos,
+ GType type);
+G_CONST_RETURN gchar * gtk_widget_path_get_element_name (GtkWidgetPath *path,
+ guint pos);
+void gtk_widget_path_set_element_name (GtkWidgetPath *path,
+ guint pos,
+ const gchar *name);
+
+gboolean gtk_widget_path_has_parent (const GtkWidgetPath *path,
+ GType type);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]