summaryrefslogtreecommitdiff
path: root/gtk/gtkcssnode.c
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2015-03-05 20:29:37 +0100
committerBenjamin Otte <otte@redhat.com>2015-03-18 15:23:33 +0100
commit8640bc47b1e7208bc5e3b7a77ef5cf321c74db88 (patch)
tree132f229a1d925ca014175b36ffd8c3a5589bfc08 /gtk/gtkcssnode.c
parentd0d9f5a302f5febccd368ab59a59725b57743587 (diff)
downloadgtk+-8640bc47b1e7208bc5e3b7a77ef5cf321c74db88.tar.gz
cssnode: Add properties
Diffstat (limited to 'gtk/gtkcssnode.c')
-rw-r--r--gtk/gtkcssnode.c201
1 files changed, 196 insertions, 5 deletions
diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c
index cda2ab85fe..a316689b34 100644
--- a/gtk/gtkcssnode.c
+++ b/gtk/gtkcssnode.c
@@ -24,6 +24,7 @@
#include "gtkintl.h"
#include "gtkmarshalers.h"
#include "gtksettingsprivate.h"
+#include "gtktypebuiltins.h"
/* When these change we do a full restyling. Otherwise we try to figure out
* if we need to change things. */
@@ -38,7 +39,18 @@ enum {
LAST_SIGNAL
};
+enum {
+ PROP_0,
+ PROP_CLASSES,
+ PROP_ID,
+ PROP_STATE,
+ PROP_VISIBLE,
+ PROP_WIDGET_TYPE,
+ NUM_PROPERTIES
+};
+
static guint cssnode_signals[LAST_SIGNAL] = { 0 };
+static GParamSpec *cssnode_properties[NUM_PROPERTIES];
static GtkStyleProviderPrivate *
gtk_css_node_get_style_provider_or_null (GtkCssNode *cssnode)
@@ -70,6 +82,76 @@ gtk_css_node_set_invalid (GtkCssNode *node,
}
static void
+gtk_css_node_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkCssNode *cssnode = GTK_CSS_NODE (object);
+
+ switch (property_id)
+ {
+ case PROP_CLASSES:
+ g_value_take_boxed (value, gtk_css_node_get_classes (cssnode));
+ break;
+
+ case PROP_ID:
+ g_value_set_string (value, gtk_css_node_get_id (cssnode));
+ break;
+
+ case PROP_STATE:
+ g_value_set_flags (value, gtk_css_node_get_state (cssnode));
+ break;
+
+ case PROP_VISIBLE:
+ g_value_set_boolean (value, gtk_css_node_get_visible (cssnode));
+ break;
+
+ case PROP_WIDGET_TYPE:
+ g_value_set_gtype (value, gtk_css_node_get_widget_type (cssnode));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+gtk_css_node_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkCssNode *cssnode = GTK_CSS_NODE (object);
+
+ switch (property_id)
+ {
+ case PROP_CLASSES:
+ gtk_css_node_set_classes (cssnode, g_value_get_boxed (value));
+ break;
+
+ case PROP_ID:
+ gtk_css_node_set_id (cssnode, g_value_get_string (value));
+ break;
+
+ case PROP_STATE:
+ gtk_css_node_set_state (cssnode, g_value_get_flags (value));
+ break;
+
+ case PROP_VISIBLE:
+ gtk_css_node_set_visible (cssnode, g_value_get_boolean (value));
+ break;
+
+ case PROP_WIDGET_TYPE:
+ gtk_css_node_set_widget_type (cssnode, g_value_get_gtype (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
gtk_css_node_dispose (GObject *object)
{
GtkCssNode *cssnode = GTK_CSS_NODE (object);
@@ -404,6 +486,8 @@ gtk_css_node_class_init (GtkCssNodeClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->get_property = gtk_css_node_get_property;
+ object_class->set_property = gtk_css_node_set_property;
object_class->dispose = gtk_css_node_dispose;
object_class->finalize = gtk_css_node_finalize;
@@ -449,6 +533,40 @@ gtk_css_node_class_init (GtkCssNodeClass *klass)
_gtk_marshal_VOID__OBJECT_OBJECT,
G_TYPE_NONE, 2,
GTK_TYPE_CSS_STYLE, GTK_TYPE_CSS_STYLE);
+
+ cssnode_properties[PROP_CLASSES] =
+ g_param_spec_boxed ("classes", "Classes",
+ "List of classes",
+ G_TYPE_STRV,
+ G_PARAM_READWRITE
+ | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+ cssnode_properties[PROP_ID] =
+ g_param_spec_string ("id", "ID",
+ "Unique ID",
+ NULL,
+ G_PARAM_READWRITE
+ | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+ cssnode_properties[PROP_STATE] =
+ g_param_spec_flags ("state", "State",
+ "State flags",
+ GTK_TYPE_STATE_FLAGS,
+ 0,
+ G_PARAM_READWRITE
+ | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+ cssnode_properties[PROP_VISIBLE] =
+ g_param_spec_boolean ("visible", "Visible",
+ "If other nodes can see this node",
+ TRUE,
+ G_PARAM_READWRITE
+ | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+ cssnode_properties[PROP_WIDGET_TYPE] =
+ g_param_spec_gtype ("widget-type", "Widget type",
+ "GType of the widget",
+ G_TYPE_NONE,
+ G_PARAM_READWRITE
+ | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, NUM_PROPERTIES, cssnode_properties);
}
static void
@@ -763,6 +881,7 @@ gtk_css_node_set_visible (GtkCssNode *cssnode,
return;
cssnode->visible = visible;
+ g_object_notify_by_pspec (G_OBJECT (cssnode), cssnode_properties[PROP_VISIBLE]);
if (cssnode->parent)
gtk_css_node_set_children_changed (cssnode->parent);
@@ -779,7 +898,10 @@ gtk_css_node_set_widget_type (GtkCssNode *cssnode,
GType widget_type)
{
if (gtk_css_node_declaration_set_type (&cssnode->decl, widget_type))
- gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_NAME);
+ {
+ gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_NAME);
+ g_object_notify_by_pspec (G_OBJECT (cssnode), cssnode_properties[PROP_WIDGET_TYPE]);
+ }
}
GType
@@ -793,7 +915,10 @@ gtk_css_node_set_id (GtkCssNode *cssnode,
const char *id)
{
if (gtk_css_node_declaration_set_id (&cssnode->decl, id))
- gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_ID);
+ {
+ gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_ID);
+ g_object_notify_by_pspec (G_OBJECT (cssnode), cssnode_properties[PROP_ID]);
+ }
}
const char *
@@ -807,7 +932,10 @@ gtk_css_node_set_state (GtkCssNode *cssnode,
GtkStateFlags state_flags)
{
if (gtk_css_node_declaration_set_state (&cssnode->decl, state_flags))
- gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_STATE);
+ {
+ gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_STATE);
+ g_object_notify_by_pspec (G_OBJECT (cssnode), cssnode_properties[PROP_STATE]);
+ }
}
GtkStateFlags
@@ -829,12 +957,72 @@ gtk_css_node_get_junction_sides (GtkCssNode *cssnode)
return gtk_css_node_declaration_get_junction_sides (cssnode->decl);
}
+static void
+gtk_css_node_clear_classes (GtkCssNode *cssnode)
+{
+ GList *list, *l;
+
+ list = gtk_css_node_declaration_list_classes (cssnode->decl);
+
+ for (l = list; l; l = l->next)
+ {
+ gtk_css_node_remove_class (cssnode, GPOINTER_TO_UINT (l->data));
+ }
+
+ g_list_free (list);
+}
+
+void
+gtk_css_node_set_classes (GtkCssNode *cssnode,
+ const char **classes)
+{
+ guint i;
+
+ g_object_freeze_notify (G_OBJECT (cssnode));
+
+ gtk_css_node_clear_classes (cssnode);
+
+ if (classes)
+ {
+ for (i = 0; classes[i] != NULL; i++)
+ {
+ gtk_css_node_add_class (cssnode, g_quark_from_string (classes[i]));
+ }
+ }
+
+ g_object_thaw_notify (G_OBJECT (cssnode));
+}
+
+char **
+gtk_css_node_get_classes (GtkCssNode *cssnode)
+{
+ GList *list, *l;
+ GPtrArray *result;
+
+ list = gtk_css_node_declaration_list_classes (cssnode->decl);
+ result = g_ptr_array_new ();
+
+ for (l = list; l; l = l->next)
+ {
+ g_ptr_array_add (result, g_strdup (g_quark_to_string (GPOINTER_TO_UINT (l->data))));
+ }
+
+ g_ptr_array_add (result, NULL);
+
+ g_list_free (list);
+
+ return (char **) g_ptr_array_free (result, FALSE);
+}
+
void
gtk_css_node_add_class (GtkCssNode *cssnode,
GQuark style_class)
{
if (gtk_css_node_declaration_add_class (&cssnode->decl, style_class))
- gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_CLASS);
+ {
+ gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_CLASS);
+ g_object_notify_by_pspec (G_OBJECT (cssnode), cssnode_properties[PROP_CLASSES]);
+ }
}
void
@@ -842,7 +1030,10 @@ gtk_css_node_remove_class (GtkCssNode *cssnode,
GQuark style_class)
{
if (gtk_css_node_declaration_remove_class (&cssnode->decl, style_class))
- gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_CLASS);
+ {
+ gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_CLASS);
+ g_object_notify_by_pspec (G_OBJECT (cssnode), cssnode_properties[PROP_CLASSES]);
+ }
}
gboolean