diff options
author | Benjamin Otte <otte@redhat.com> | 2016-03-26 03:31:39 +0100 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2016-04-08 16:18:31 +0200 |
commit | 0f9526578aa58c8f3480f1671c0f2923562cb844 (patch) | |
tree | 80606d00d528f91e8790258424c0ee0484064e9e | |
parent | afe70c456804024c62c982af3fac1a078c20422b (diff) | |
download | gtk+-0f9526578aa58c8f3480f1671c0f2923562cb844.tar.gz |
cssdeclaration: Turn into abstract base class
This is in preparation for allowing to parse style properties like
-GtkWidget-focus-width.
-rw-r--r-- | gtk/Makefile.am | 12 | ||||
-rw-r--r-- | gtk/gtkcssdeclaration.c | 103 | ||||
-rw-r--r-- | gtk/gtkcssdeclarationprivate.h | 10 | ||||
-rw-r--r-- | gtk/gtkcsskeyframes.c | 41 | ||||
-rw-r--r-- | gtk/gtkcsslonghanddeclaration.c | 177 | ||||
-rw-r--r-- | gtk/gtkcsslonghanddeclarationprivate.h | 62 | ||||
-rw-r--r-- | gtk/gtkcssshorthanddeclaration.c | 203 | ||||
-rw-r--r-- | gtk/gtkcssshorthanddeclarationprivate.h | 64 | ||||
-rw-r--r-- | gtk/inspector/cssruleviewrow.c | 2 |
9 files changed, 579 insertions, 95 deletions
diff --git a/gtk/Makefile.am b/gtk/Makefile.am index c68a0ae952..699037e5f2 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -425,6 +425,7 @@ gtk_private_h_sources = \ gtkcsskeyframeruleprivate.h \ gtkcsskeyframesprivate.h \ gtkcsskeyframesruleprivate.h \ + gtkcsslonghanddeclarationprivate.h \ gtkcsslookupprivate.h \ gtkcssmatcherprivate.h \ gtkcssnodeprivate.h \ @@ -445,6 +446,7 @@ gtk_private_h_sources = \ gtkcssselectorprivate.h \ gtkcssshadowsvalueprivate.h \ gtkcssshadowvalueprivate.h \ + gtkcssshorthanddeclarationprivate.h \ gtkcssshorthandpropertyprivate.h \ gtkcssstaticstyleprivate.h \ gtkcssstringvalueprivate.h \ @@ -706,6 +708,7 @@ gtk_base_c_sources = \ gtkcsskeyframerule.c \ gtkcsskeyframes.c \ gtkcsskeyframesrule.c \ + gtkcsslonghanddeclaration.c \ gtkcsslookup.c \ gtkcssmatcher.c \ gtkcssnode.c \ @@ -725,18 +728,19 @@ gtk_base_c_sources = \ gtkcsssection.c \ gtkcssselector.c \ gtkcssstringvalue.c \ - gtkcssstyle.c \ - gtkcssstylechange.c \ - gtkcssstyledeclaration.c \ - gtkcssstylerule.c \ gtkcssshadowsvalue.c \ gtkcssshadowvalue.c \ + gtkcssshorthanddeclaration.c \ gtkcssshorthandproperty.c \ gtkcssshorthandpropertyimpl.c \ gtkcssstaticstyle.c \ + gtkcssstyle.c \ + gtkcssstylechange.c \ + gtkcssstyledeclaration.c \ gtkcssstylefuncs.c \ gtkcssstyleproperty.c \ gtkcssstylepropertyimpl.c \ + gtkcssstylerule.c \ gtkcssstylesheet.c \ gtkcsstokenizer.c \ gtkcsstokensource.c \ diff --git a/gtk/gtkcssdeclaration.c b/gtk/gtkcssdeclaration.c index 0782cfa7d1..dd83827bd4 100644 --- a/gtk/gtkcssdeclaration.c +++ b/gtk/gtkcssdeclaration.c @@ -21,35 +21,20 @@ #include "gtkcssdeclarationprivate.h" +#include "gtkcsslonghanddeclarationprivate.h" +#include "gtkcssshorthanddeclarationprivate.h" #include "gtkstylepropertyprivate.h" typedef struct _GtkCssDeclarationPrivate GtkCssDeclarationPrivate; struct _GtkCssDeclarationPrivate { GtkCssStyleDeclaration *style; - GtkStyleProperty *prop; - GtkCssValue *value; }; -G_DEFINE_TYPE_WITH_PRIVATE (GtkCssDeclaration, gtk_css_declaration, G_TYPE_OBJECT) - -static void -gtk_css_declaration_finalize (GObject *object) -{ - GtkCssDeclaration *declaration = GTK_CSS_DECLARATION (object); - GtkCssDeclarationPrivate *priv = gtk_css_declaration_get_instance_private (declaration); - - if (priv->value) - _gtk_css_value_unref (priv->value); - - G_OBJECT_CLASS (gtk_css_declaration_parent_class)->finalize (object); -} +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GtkCssDeclaration, gtk_css_declaration, G_TYPE_OBJECT) static void gtk_css_declaration_class_init (GtkCssDeclarationClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = gtk_css_declaration_finalize; } static void @@ -61,64 +46,34 @@ GtkCssDeclaration * gtk_css_declaration_new_parse (GtkCssStyleDeclaration *style, GtkCssTokenSource *source) { - GtkCssDeclarationPrivate *priv; const GtkCssToken *token; - GtkCssDeclaration *decl; + GtkStyleProperty *prop; char *name; - decl = g_object_new (GTK_TYPE_CSS_DECLARATION, NULL); - priv = gtk_css_declaration_get_instance_private (decl); - - gtk_css_token_source_set_consumer (source, G_OBJECT (decl)); - - priv->style = style; token = gtk_css_token_source_get_token (source); if (!gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT)) { gtk_css_token_source_error (source, "Expected a property name"); gtk_css_token_source_consume_all (source); - g_object_unref (decl); return NULL; } name = g_utf8_strdown (token->string.string, -1); - priv->prop = _gtk_style_property_lookup (name); - if (priv->prop == NULL) - { - gtk_css_token_source_unknown (source, "Unknown property name '%s'", token->string.string); - gtk_css_token_source_consume_all (source); - g_object_unref (decl); - g_free (name); - return NULL; - } - else if (!g_str_equal (name, _gtk_style_property_get_name (priv->prop))) - gtk_css_token_source_deprecated (source, - "The '%s' property has been renamed to '%s'", - name, _gtk_style_property_get_name (priv->prop)); - gtk_css_token_source_consume_token (source); + prop = _gtk_style_property_lookup (name); g_free (name); - - token = gtk_css_token_source_get_token (source); - if (!gtk_css_token_is (token, GTK_CSS_TOKEN_COLON)) + if (GTK_IS_CSS_STYLE_PROPERTY (prop)) + return gtk_css_longhand_declaration_new_parse (style, source); + else if (GTK_IS_CSS_SHORTHAND_PROPERTY (prop)) + return gtk_css_shorthand_declaration_new_parse (style, source); + else { - gtk_css_token_source_error (source, "No colon following property name"); + gtk_css_token_source_error (source, "Property name does not define a valid property"); gtk_css_token_source_consume_all (source); - g_object_unref (decl); return NULL; } - gtk_css_token_source_consume_token (source); - - priv->value = gtk_style_property_token_parse (priv->prop, source); - if (priv->value == NULL) - { - g_object_unref (decl); - return NULL; - } - - return decl; } -const char * -gtk_css_declaration_get_name (GtkCssDeclaration *decl) +GtkCssStyleDeclaration * +gtk_css_declaration_get_style (GtkCssDeclaration *decl) { GtkCssDeclarationPrivate *priv; @@ -126,18 +81,36 @@ gtk_css_declaration_get_name (GtkCssDeclaration *decl) priv = gtk_css_declaration_get_instance_private (decl); - return _gtk_style_property_get_name (priv->prop); + return priv->style; } -GtkCssValue * -gtk_css_declaration_get_value (GtkCssDeclaration *decl) +const char * +gtk_css_declaration_get_name (GtkCssDeclaration *decl) { - GtkCssDeclarationPrivate *priv; - g_return_val_if_fail (GTK_IS_CSS_DECLARATION (decl), NULL); - priv = gtk_css_declaration_get_instance_private (decl); + return GTK_CSS_DECLARATION_GET_CLASS (decl)->get_name (decl); +} + +void +gtk_css_declaration_print_value (GtkCssDeclaration *decl, + GString *string) +{ + g_return_if_fail (GTK_IS_CSS_DECLARATION (decl)); + g_return_if_fail (string != NULL); - return priv->value; + return GTK_CSS_DECLARATION_GET_CLASS (decl)->print_value (decl, string); } +char * +gtk_css_declaration_get_value_string (GtkCssDeclaration *decl) +{ + GString *string; + + g_return_val_if_fail (GTK_IS_CSS_DECLARATION (decl), NULL); + + string = g_string_new (NULL); + gtk_css_declaration_print_value (decl, string); + + return g_string_free (string, FALSE); +} diff --git a/gtk/gtkcssdeclarationprivate.h b/gtk/gtkcssdeclarationprivate.h index ffb6c25856..f41b9b4ee2 100644 --- a/gtk/gtkcssdeclarationprivate.h +++ b/gtk/gtkcssdeclarationprivate.h @@ -44,6 +44,10 @@ struct _GtkCssDeclaration struct _GtkCssDeclarationClass { GObjectClass parent_class; + + const char * (* get_name) (GtkCssDeclaration *decl); + void (* print_value) (GtkCssDeclaration *decl, + GString *string); }; GType gtk_css_declaration_get_type (void) G_GNUC_CONST; @@ -52,7 +56,11 @@ GtkCssDeclaration * gtk_css_declaration_new_parse (GtkCssStyleDecl GtkCssTokenSource *source); const char * gtk_css_declaration_get_name (GtkCssDeclaration *decl); -GtkCssValue * gtk_css_declaration_get_value (GtkCssDeclaration *decl); +GtkCssStyleDeclaration *gtk_css_declaration_get_style (GtkCssDeclaration *decl); + +void gtk_css_declaration_print_value (GtkCssDeclaration *decl, + GString *string); +char * gtk_css_declaration_get_value_string (GtkCssDeclaration *decl); G_END_DECLS diff --git a/gtk/gtkcsskeyframes.c b/gtk/gtkcsskeyframes.c index c1ea28df78..2c2a55b943 100644 --- a/gtk/gtkcsskeyframes.c +++ b/gtk/gtkcsskeyframes.c @@ -20,10 +20,10 @@ #include "gtkcsskeyframesprivate.h" #include "gtkcssarrayvalueprivate.h" -#include "gtkcssdeclarationprivate.h" #include "gtkcsskeyframeruleprivate.h" +#include "gtkcsslonghanddeclarationprivate.h" +#include "gtkcssshorthanddeclarationprivate.h" #include "gtkcssshorthandpropertyprivate.h" -#include "gtkcssstylepropertyprivate.h" #include "gtkstylepropertyprivate.h" #include <stdlib.h> @@ -405,34 +405,27 @@ gtk_css_keyframes_new_from_rule (GtkCssKeyframesRule *rule) for (k = 0; k < gtk_css_style_declaration_get_length (style); k++) { GtkCssDeclaration *decl = gtk_css_style_declaration_get_declaration (style, k); - GtkStyleProperty *property; - GtkCssValue *value; - property = _gtk_style_property_lookup (gtk_css_declaration_get_name (decl)); - if (property == NULL) - continue; - - value = gtk_css_declaration_get_value (decl); - if (GTK_IS_CSS_SHORTHAND_PROPERTY (property)) + if (GTK_IS_CSS_LONGHAND_DECLARATION (decl)) { - GtkCssShorthandProperty *shorthand = GTK_CSS_SHORTHAND_PROPERTY (property); + GtkCssLonghandDeclaration *longhand = GTK_CSS_LONGHAND_DECLARATION (decl); + keyframes_set_value (keyframes, + offset_idx, + gtk_css_longhand_declaration_get_property (longhand), + _gtk_css_value_ref (gtk_css_longhand_declaration_get_value (longhand))); + } + else if (GTK_IS_CSS_SHORTHAND_DECLARATION (decl)) + { + GtkCssShorthandDeclaration *shorthand = GTK_CSS_SHORTHAND_DECLARATION (decl); - for (l = 0; l < _gtk_css_shorthand_property_get_n_subproperties (shorthand); l++) + for (l = 0; l < gtk_css_shorthand_declaration_get_length (shorthand); l++) { - GtkCssStyleProperty *child = _gtk_css_shorthand_property_get_subproperty (shorthand, l); - GtkCssValue *sub = _gtk_css_array_value_get_nth (value, l); - - keyframes_set_value (keyframes, offset_idx, child, _gtk_css_value_ref (sub)); + keyframes_set_value (keyframes, + offset_idx, + gtk_css_shorthand_declaration_get_subproperty (shorthand, l), + _gtk_css_value_ref (gtk_css_shorthand_declaration_get_value (shorthand, l))); } } - else if (GTK_IS_CSS_STYLE_PROPERTY (property)) - { - keyframes_set_value (keyframes, offset_idx, GTK_CSS_STYLE_PROPERTY (property), _gtk_css_value_ref (value)); - } - else - { - g_assert_not_reached (); - } } } } diff --git a/gtk/gtkcsslonghanddeclaration.c b/gtk/gtkcsslonghanddeclaration.c new file mode 100644 index 0000000000..086b06e981 --- /dev/null +++ b/gtk/gtkcsslonghanddeclaration.c @@ -0,0 +1,177 @@ +/* + * Copyright © 2016 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: Benjamin Otte <otte@gnome.org> + */ + +#include "config.h" + +#include "gtkcsslonghanddeclarationprivate.h" + +#include "gtkcssstylepropertyprivate.h" + +typedef struct _GtkCssLonghandDeclarationPrivate GtkCssLonghandDeclarationPrivate; +struct _GtkCssLonghandDeclarationPrivate { + GtkCssStyleProperty *prop; + GtkCssValue *value; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GtkCssLonghandDeclaration, gtk_css_longhand_declaration, GTK_TYPE_CSS_DECLARATION) + +static void +gtk_css_longhand_declaration_finalize (GObject *object) +{ + GtkCssLonghandDeclaration *longhand_declaration = GTK_CSS_LONGHAND_DECLARATION (object); + GtkCssLonghandDeclarationPrivate *priv = gtk_css_longhand_declaration_get_instance_private (longhand_declaration); + + if (priv->value) + _gtk_css_value_unref (priv->value); + + G_OBJECT_CLASS (gtk_css_longhand_declaration_parent_class)->finalize (object); +} + +static const char * +gtk_css_longhand_declaration_get_name (GtkCssDeclaration *decl) +{ + GtkCssLonghandDeclaration *longhand_declaration = GTK_CSS_LONGHAND_DECLARATION (decl); + GtkCssLonghandDeclarationPrivate *priv = gtk_css_longhand_declaration_get_instance_private (longhand_declaration); + + return _gtk_style_property_get_name (GTK_STYLE_PROPERTY (priv->prop)); +} + +static void +gtk_css_longhand_declaration_print_value (GtkCssDeclaration *decl, + GString *string) +{ + GtkCssLonghandDeclaration *longhand_declaration = GTK_CSS_LONGHAND_DECLARATION (decl); + GtkCssLonghandDeclarationPrivate *priv = gtk_css_longhand_declaration_get_instance_private (longhand_declaration); + + _gtk_css_value_print (priv->value, string); +} + +static void +gtk_css_longhand_declaration_class_init (GtkCssLonghandDeclarationClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkCssDeclarationClass *decl_class = GTK_CSS_DECLARATION_CLASS (klass); + + object_class->finalize = gtk_css_longhand_declaration_finalize; + + decl_class->get_name = gtk_css_longhand_declaration_get_name; + decl_class->print_value = gtk_css_longhand_declaration_print_value; +} + +static void +gtk_css_longhand_declaration_init (GtkCssLonghandDeclaration *longhand_declaration) +{ +} + +GtkCssDeclaration * +gtk_css_longhand_declaration_new_parse (GtkCssStyleDeclaration *style, + GtkCssTokenSource *source) +{ + GtkCssLonghandDeclarationPrivate *priv; + const GtkCssToken *token; + GtkCssLonghandDeclaration *decl; + char *name; + + decl = g_object_new (GTK_TYPE_CSS_LONGHAND_DECLARATION, + NULL); + priv = gtk_css_longhand_declaration_get_instance_private (decl); + + gtk_css_token_source_set_consumer (source, G_OBJECT (decl)); + + token = gtk_css_token_source_get_token (source); + if (!gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT)) + { + gtk_css_token_source_error (source, "Expected a property name"); + gtk_css_token_source_consume_all (source); + g_object_unref (decl); + return NULL; + } + name = g_utf8_strdown (token->string.string, -1); + priv->prop = (GtkCssStyleProperty *) _gtk_style_property_lookup (name); + if (!GTK_IS_CSS_STYLE_PROPERTY (priv->prop)) + { + gtk_css_token_source_unknown (source, "Property name '%s' is not a CSS property", token->string.string); + gtk_css_token_source_consume_all (source); + g_object_unref (decl); + g_free (name); + return NULL; + } + else if (!g_str_equal (name, _gtk_style_property_get_name (GTK_STYLE_PROPERTY (priv->prop)))) + gtk_css_token_source_deprecated (source, + "The '%s' property has been renamed to '%s'", + name, _gtk_style_property_get_name (GTK_STYLE_PROPERTY (priv->prop))); + gtk_css_token_source_consume_token (source); + g_free (name); + + token = gtk_css_token_source_get_token (source); + if (!gtk_css_token_is (token, GTK_CSS_TOKEN_COLON)) + { + gtk_css_token_source_error (source, "No colon following property name"); + gtk_css_token_source_consume_all (source); + g_object_unref (decl); + return NULL; + } + gtk_css_token_source_consume_token (source); + + priv->value = gtk_style_property_token_parse (GTK_STYLE_PROPERTY (priv->prop), source); + if (priv->value == NULL) + { + g_object_unref (decl); + return NULL; + } + + return GTK_CSS_DECLARATION (decl); +} + +guint +gtk_css_longhand_declaration_get_id (GtkCssLonghandDeclaration *decl) +{ + GtkCssLonghandDeclarationPrivate *priv; + + g_return_val_if_fail (GTK_IS_CSS_LONGHAND_DECLARATION (decl), 0); + + priv = gtk_css_longhand_declaration_get_instance_private (decl); + + return _gtk_css_style_property_get_id (priv->prop); +} + +GtkCssStyleProperty * +gtk_css_longhand_declaration_get_property (GtkCssLonghandDeclaration *decl) +{ + GtkCssLonghandDeclarationPrivate *priv; + + g_return_val_if_fail (GTK_IS_CSS_LONGHAND_DECLARATION (decl), 0); + + priv = gtk_css_longhand_declaration_get_instance_private (decl); + + return priv->prop; +} + +GtkCssValue * +gtk_css_longhand_declaration_get_value (GtkCssLonghandDeclaration *decl) +{ + GtkCssLonghandDeclarationPrivate *priv; + + g_return_val_if_fail (GTK_IS_CSS_LONGHAND_DECLARATION (decl), NULL); + + priv = gtk_css_longhand_declaration_get_instance_private (decl); + + return priv->value; +} + diff --git a/gtk/gtkcsslonghanddeclarationprivate.h b/gtk/gtkcsslonghanddeclarationprivate.h new file mode 100644 index 0000000000..c383c68f9c --- /dev/null +++ b/gtk/gtkcsslonghanddeclarationprivate.h @@ -0,0 +1,62 @@ +/* + * Copyright © 2016 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: Benjamin Otte <otte@gnome.org> + */ + +#ifndef __GTK_CSS_LONGHAND_DECLARATION_PRIVATE_H__ +#define __GTK_CSS_LONGHAND_DECLARATION_PRIVATE_H__ + +#include "gtk/gtkcssdeclarationprivate.h" + +#include "gtk/gtkcssstylepropertyprivate.h" +#include "gtk/gtkcssvalueprivate.h" + +G_BEGIN_DECLS + +#define GTK_TYPE_CSS_LONGHAND_DECLARATION (gtk_css_longhand_declaration_get_type ()) +#define GTK_CSS_LONGHAND_DECLARATION(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_LONGHAND_DECLARATION, GtkCssLonghandDeclaration)) +#define GTK_CSS_LONGHAND_DECLARATION_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_LONGHAND_DECLARATION, GtkCssLonghandDeclarationClass)) +#define GTK_IS_CSS_LONGHAND_DECLARATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_LONGHAND_DECLARATION)) +#define GTK_IS_CSS_LONGHAND_DECLARATION_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_LONGHAND_DECLARATION)) +#define GTK_CSS_LONGHAND_DECLARATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_LONGHAND_DECLARATION, GtkCssLonghandDeclarationClass)) + +typedef struct _GtkCssLonghandDeclaration GtkCssLonghandDeclaration; +typedef struct _GtkCssLonghandDeclarationClass GtkCssLonghandDeclarationClass; + +struct _GtkCssLonghandDeclaration +{ + GtkCssDeclaration parent; +}; + +struct _GtkCssLonghandDeclarationClass +{ + GtkCssDeclarationClass parent_class; +}; + +GType gtk_css_longhand_declaration_get_type (void) G_GNUC_CONST; + +GtkCssDeclaration * gtk_css_longhand_declaration_new_parse (GtkCssStyleDeclaration *style, + GtkCssTokenSource *source); + +guint gtk_css_longhand_declaration_get_id (GtkCssLonghandDeclaration *decl); +GtkCssStyleProperty * gtk_css_longhand_declaration_get_property (GtkCssLonghandDeclaration *decl); +GtkCssValue * gtk_css_longhand_declaration_get_value (GtkCssLonghandDeclaration *decl); + + +G_END_DECLS + +#endif /* __GTK_CSS_LONGHAND_DECLARATION_PRIVATE_H__ */ diff --git a/gtk/gtkcssshorthanddeclaration.c b/gtk/gtkcssshorthanddeclaration.c new file mode 100644 index 0000000000..5b9b1a39d5 --- /dev/null +++ b/gtk/gtkcssshorthanddeclaration.c @@ -0,0 +1,203 @@ +/* + * Copyright © 2016 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: Benjamin Otte <otte@gnome.org> + */ + +#include "config.h" + +#include "gtkcssshorthanddeclarationprivate.h" + +#include "gtkcssarrayvalueprivate.h" +#include "gtkcssshorthandpropertyprivate.h" + +typedef struct _GtkCssShorthandDeclarationPrivate GtkCssShorthandDeclarationPrivate; +struct _GtkCssShorthandDeclarationPrivate { + GtkCssShorthandProperty *prop; + GtkCssValue **values; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GtkCssShorthandDeclaration, gtk_css_shorthand_declaration, GTK_TYPE_CSS_DECLARATION) + +static void +gtk_css_shorthand_declaration_finalize (GObject *object) +{ + GtkCssShorthandDeclaration *shorthand = GTK_CSS_SHORTHAND_DECLARATION (object); + GtkCssShorthandDeclarationPrivate *priv = gtk_css_shorthand_declaration_get_instance_private (shorthand); + guint i; + + if (priv->values) + { + for (i = 0; i < gtk_css_shorthand_declaration_get_length (shorthand); i++) + { + _gtk_css_value_unref (priv->values[i]); + } + g_free (priv->values); + } + + G_OBJECT_CLASS (gtk_css_shorthand_declaration_parent_class)->finalize (object); +} + +static const char * +gtk_css_shorthand_declaration_get_name (GtkCssDeclaration *decl) +{ + GtkCssShorthandDeclaration *shorthand_declaration = GTK_CSS_SHORTHAND_DECLARATION (decl); + GtkCssShorthandDeclarationPrivate *priv = gtk_css_shorthand_declaration_get_instance_private (shorthand_declaration); + + return _gtk_style_property_get_name (GTK_STYLE_PROPERTY (priv->prop)); +} + +static void +gtk_css_shorthand_declaration_print_value (GtkCssDeclaration *decl, + GString *string) +{ + GtkCssShorthandDeclaration *shorthand = GTK_CSS_SHORTHAND_DECLARATION (decl); + GtkCssShorthandDeclarationPrivate *priv = gtk_css_shorthand_declaration_get_instance_private (shorthand); + guint i; + + /* XXX */ + for (i = 0; i < gtk_css_shorthand_declaration_get_length (shorthand); i++) + { + if (i > 0) + g_string_append (string, ", "); + _gtk_css_value_print (priv->values[i], string); + } +} + +static void +gtk_css_shorthand_declaration_class_init (GtkCssShorthandDeclarationClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkCssDeclarationClass *decl_class = GTK_CSS_DECLARATION_CLASS (klass); + + object_class->finalize = gtk_css_shorthand_declaration_finalize; + + decl_class->get_name = gtk_css_shorthand_declaration_get_name; + decl_class->print_value = gtk_css_shorthand_declaration_print_value; +} + +static void +gtk_css_shorthand_declaration_init (GtkCssShorthandDeclaration *shorthand_declaration) +{ +} + +GtkCssDeclaration * +gtk_css_shorthand_declaration_new_parse (GtkCssStyleDeclaration *style, + GtkCssTokenSource *source) +{ + GtkCssShorthandDeclarationPrivate *priv; + const GtkCssToken *token; + GtkCssShorthandDeclaration *decl; + GtkCssValue *array; + guint i; + char *name; + + decl = g_object_new (GTK_TYPE_CSS_SHORTHAND_DECLARATION, NULL); + priv = gtk_css_shorthand_declaration_get_instance_private (decl); + + gtk_css_token_source_set_consumer (source, G_OBJECT (decl)); + + token = gtk_css_token_source_get_token (source); + if (!gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT)) + { + gtk_css_token_source_error (source, "Expected a property name"); + gtk_css_token_source_consume_all (source); + g_object_unref (decl); + return NULL; + } + name = g_utf8_strdown (token->string.string, -1); + priv->prop = (GtkCssShorthandProperty *) _gtk_style_property_lookup (name); + if (!GTK_IS_CSS_SHORTHAND_PROPERTY (priv->prop)) + { + gtk_css_token_source_unknown (source, "Property name '%s' is not a shorthand property", token->string.string); + gtk_css_token_source_consume_all (source); + g_object_unref (decl); + g_free (name); + return NULL; + } + else if (!g_str_equal (name, _gtk_style_property_get_name (GTK_STYLE_PROPERTY (priv->prop)))) + gtk_css_token_source_deprecated (source, + "The '%s' property has been renamed to '%s'", + name, _gtk_style_property_get_name (GTK_STYLE_PROPERTY (priv->prop))); + gtk_css_token_source_consume_token (source); + g_free (name); + + token = gtk_css_token_source_get_token (source); + if (!gtk_css_token_is (token, GTK_CSS_TOKEN_COLON)) + { + gtk_css_token_source_error (source, "No colon following property name"); + gtk_css_token_source_consume_all (source); + g_object_unref (decl); + return NULL; + } + gtk_css_token_source_consume_token (source); + + array = gtk_style_property_token_parse (GTK_STYLE_PROPERTY (priv->prop), source); + if (array == NULL) + { + g_object_unref (decl); + return NULL; + } + priv->values = g_new (GtkCssValue *, gtk_css_shorthand_declaration_get_length (decl)); + for (i = 0; i < gtk_css_shorthand_declaration_get_length (decl); i++) + { + priv->values[i] = _gtk_css_value_ref (_gtk_css_array_value_get_nth (array, i)); + } + _gtk_css_value_unref (array); + + return GTK_CSS_DECLARATION (decl); +} + +guint +gtk_css_shorthand_declaration_get_length (GtkCssShorthandDeclaration *decl) +{ + GtkCssShorthandDeclarationPrivate *priv; + + g_return_val_if_fail (GTK_IS_CSS_SHORTHAND_DECLARATION (decl), 0); + + priv = gtk_css_shorthand_declaration_get_instance_private (decl); + + return _gtk_css_shorthand_property_get_n_subproperties (priv->prop); +} + +GtkCssStyleProperty * +gtk_css_shorthand_declaration_get_subproperty (GtkCssShorthandDeclaration *decl, + guint id) +{ + GtkCssShorthandDeclarationPrivate *priv; + + g_return_val_if_fail (GTK_IS_CSS_SHORTHAND_DECLARATION (decl), NULL); + g_return_val_if_fail (id < gtk_css_shorthand_declaration_get_length (decl), NULL); + + priv = gtk_css_shorthand_declaration_get_instance_private (decl); + + return _gtk_css_shorthand_property_get_subproperty (priv->prop, id); +} + +GtkCssValue * +gtk_css_shorthand_declaration_get_value (GtkCssShorthandDeclaration *decl, + guint id) +{ + GtkCssShorthandDeclarationPrivate *priv; + + g_return_val_if_fail (GTK_IS_CSS_SHORTHAND_DECLARATION (decl), NULL); + g_return_val_if_fail (id < gtk_css_shorthand_declaration_get_length (decl), NULL); + + priv = gtk_css_shorthand_declaration_get_instance_private (decl); + + return priv->values[id]; +} + diff --git a/gtk/gtkcssshorthanddeclarationprivate.h b/gtk/gtkcssshorthanddeclarationprivate.h new file mode 100644 index 0000000000..48269bb70e --- /dev/null +++ b/gtk/gtkcssshorthanddeclarationprivate.h @@ -0,0 +1,64 @@ +/* + * Copyright © 2016 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: Benjamin Otte <otte@gnome.org> + */ + +#ifndef __GTK_CSS_SHORTHAND_DECLARATION_PRIVATE_H__ +#define __GTK_CSS_SHORTHAND_DECLARATION_PRIVATE_H__ + +#include "gtk/gtkcssdeclarationprivate.h" + +#include "gtk/gtkcssshorthandpropertyprivate.h" +#include "gtk/gtkcssvalueprivate.h" + +G_BEGIN_DECLS + +#define GTK_TYPE_CSS_SHORTHAND_DECLARATION (gtk_css_shorthand_declaration_get_type ()) +#define GTK_CSS_SHORTHAND_DECLARATION(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_SHORTHAND_DECLARATION, GtkCssShorthandDeclaration)) +#define GTK_CSS_SHORTHAND_DECLARATION_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_SHORTHAND_DECLARATION, GtkCssShorthandDeclarationClass)) +#define GTK_IS_CSS_SHORTHAND_DECLARATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_SHORTHAND_DECLARATION)) +#define GTK_IS_CSS_SHORTHAND_DECLARATION_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_SHORTHAND_DECLARATION)) +#define GTK_CSS_SHORTHAND_DECLARATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_SHORTHAND_DECLARATION, GtkCssShorthandDeclarationClass)) + +typedef struct _GtkCssShorthandDeclaration GtkCssShorthandDeclaration; +typedef struct _GtkCssShorthandDeclarationClass GtkCssShorthandDeclarationClass; + +struct _GtkCssShorthandDeclaration +{ + GtkCssDeclaration parent; +}; + +struct _GtkCssShorthandDeclarationClass +{ + GtkCssDeclarationClass parent_class; +}; + +GType gtk_css_shorthand_declaration_get_type (void) G_GNUC_CONST; + +GtkCssDeclaration * gtk_css_shorthand_declaration_new_parse (GtkCssStyleDeclaration *style, + GtkCssTokenSource *source); + +guint gtk_css_shorthand_declaration_get_length (GtkCssShorthandDeclaration *decl); +GtkCssStyleProperty * gtk_css_shorthand_declaration_get_subproperty (GtkCssShorthandDeclaration *decl, + guint id); +GtkCssValue * gtk_css_shorthand_declaration_get_value (GtkCssShorthandDeclaration *decl, + guint id); + + +G_END_DECLS + +#endif /* __GTK_CSS_SHORTHAND_DECLARATION_PRIVATE_H__ */ diff --git a/gtk/inspector/cssruleviewrow.c b/gtk/inspector/cssruleviewrow.c index b143c2465b..4fcfe9dc73 100644 --- a/gtk/inspector/cssruleviewrow.c +++ b/gtk/inspector/cssruleviewrow.c @@ -127,7 +127,7 @@ update_style_label (GtkInspectorCssRuleViewRow *row) g_string_append (string, "\n"); g_string_append (string, gtk_css_declaration_get_name (decl)); g_string_append (string, ": "); - _gtk_css_value_print (gtk_css_declaration_get_value (decl), string); + gtk_css_declaration_print_value (decl, string); g_string_append (string, ";"); } gtk_label_set_text (GTK_LABEL (priv->style_label), string->str); |