From 7e430340688808f075fc63e1986b8343e027ec2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Sat, 15 Feb 2020 09:55:27 +0100 Subject: [PATCH] widget: Add css-classes property Mirroring the values added and removed via {add,remove}_css_class(). --- docs/reference/gtk/gtk4-sections.txt | 2 + gtk/gtkwidget.c | 74 ++++++++++++++++++++++++++++ gtk/gtkwidget.h | 5 ++ 3 files changed, 81 insertions(+) diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt index 8b91e2dfab..a7b1be5e5e 100644 --- a/docs/reference/gtk/gtk4-sections.txt +++ b/docs/reference/gtk/gtk4-sections.txt @@ -4191,6 +4191,8 @@ gtk_widget_get_css_name gtk_widget_add_css_class gtk_widget_remove_css_class gtk_widget_has_css_class +gtk_widget_get_css_classes +gtk_widget_set_css_classes gtk_widget_get_style_context diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 5ea1f97613..4090a45616 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -557,6 +557,7 @@ enum { PROP_EXPAND, PROP_SCALE_FACTOR, PROP_CSS_NAME, + PROP_CSS_CLASSES, PROP_LAYOUT_MANAGER, NUM_PROPERTIES }; @@ -1325,6 +1326,18 @@ gtk_widget_class_init (GtkWidgetClass *klass) NULL, GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + /** + * GtkWidget:css-classes: + * + * A list of css classes applied to this widget. + */ + widget_props[PROP_CSS_CLASSES] = + g_param_spec_boxed ("classes", + P_("Style Classes"), + P_("List of classes"), + G_TYPE_STRV, + GTK_PARAM_READWRITE); + /** * GtkWidget:layout-manager: * @@ -1886,6 +1899,9 @@ gtk_widget_set_property (GObject *object, if (g_value_get_string (value) != NULL) gtk_css_node_set_name (priv->cssnode, g_quark_from_string (g_value_get_string (value))); break; + case PROP_CSS_CLASSES: + gtk_widget_set_css_classes (widget, g_value_get_boxed (value)); + break; case PROP_LAYOUT_MANAGER: gtk_widget_set_layout_manager (widget, g_value_dup_object (value)); break; @@ -2032,6 +2048,9 @@ gtk_widget_get_property (GObject *object, case PROP_CSS_NAME: g_value_set_string (value, g_quark_to_string (gtk_css_node_get_name (priv->cssnode))); break; + case PROP_CSS_CLASSES: + g_value_take_boxed (value, gtk_widget_get_css_classes (widget)); + break; case PROP_LAYOUT_MANAGER: g_value_set_object (value, gtk_widget_get_layout_manager (widget)); break; @@ -13141,6 +13160,7 @@ gtk_widget_add_css_class (GtkWidget *widget, g_return_if_fail (css_class[0] != '.'); gtk_css_node_add_class (priv->cssnode, g_quark_from_string (css_class)); + g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_CSS_CLASSES]); } /** @@ -13169,6 +13189,7 @@ gtk_widget_remove_css_class (GtkWidget *widget, return; gtk_css_node_remove_class (priv->cssnode, class_quark); + g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_CSS_CLASSES]); } /** @@ -13200,3 +13221,56 @@ gtk_widget_has_css_class (GtkWidget *widget, return gtk_css_node_has_class (priv->cssnode, class_quark); } + +/** + * gtk_widget_get_css_classes: + * @widget: a #GtkWidget + * + * Returns the list of css classes applied to @widget. + * + * Returns: (transfer full): a %NULL-terminated list of + * css classes currently applied to @widget. The returned + * list can be freed using g_strfreev. + */ +char ** +gtk_widget_get_css_classes (GtkWidget *widget) +{ + GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); + const GQuark *classes; + guint n_classes; + char **strv; + guint i; + + g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); + + classes = gtk_css_node_list_classes (priv->cssnode, &n_classes); + strv = g_new (char *, n_classes + 1); + + for (i = 0; i < n_classes; i++) + strv[i] = g_strdup (g_quark_to_string (classes[i])); + + strv[n_classes] = NULL; + + return strv; +} + +/** + * gtk_widget_set_css_classes: + * @widget: a #GtkWidget + * @classes: (transfer none): %NULL-terminated list + * of css classes to apply to @widget. + * + * Will clear all css classes applied to @widget + * and replace them with @classes. + */ +void +gtk_widget_set_css_classes (GtkWidget *widget, + const char **classes) +{ + GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); + + g_return_if_fail (GTK_IS_WIDGET (widget)); + + gtk_css_node_set_classes (priv->cssnode, classes); + g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_CSS_CLASSES]); +} diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h index 718b3be13b..e97854b93a 100644 --- a/gtk/gtkwidget.h +++ b/gtk/gtkwidget.h @@ -981,6 +981,11 @@ void gtk_widget_remove_css_class (GtkWidget *widget, GDK_AVAILABLE_IN_ALL gboolean gtk_widget_has_css_class (GtkWidget *widget, const char *css_class); +GDK_AVAILABLE_IN_ALL +char ** gtk_widget_get_css_classes (GtkWidget *widget); +GDK_AVAILABLE_IN_ALL +void gtk_widget_set_css_classes (GtkWidget *widget, + const char **classes);