[gtk/wip/otte/css: 8/18] cross-fade: Use gtk_css_parser_consume_any()
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/css: 8/18] cross-fade: Use gtk_css_parser_consume_any()
- Date: Sun, 31 Mar 2019 15:01:27 +0000 (UTC)
commit 9dc49ded7bde019c20071a75fdc6cba2c80dcf3b
Author: Benjamin Otte <otte redhat com>
Date: Sat Mar 30 12:04:51 2019 +0100
cross-fade: Use gtk_css_parser_consume_any()
.. and gtk_css_parser_consume_function().
gtk_css_parser_consume_any() is a new function that implements the CSS
spec's any combinator ||.
gtk/gtkcssimagecrossfade.c | 95 ++++++++++++++++++++++++++++------------------
gtk/gtkcssparser.c | 39 +++++++++++++++++++
gtk/gtkcssparserprivate.h | 17 +++++++++
3 files changed, 114 insertions(+), 37 deletions(-)
---
diff --git a/gtk/gtkcssimagecrossfade.c b/gtk/gtkcssimagecrossfade.c
index 4a5736370b..30e87f61ea 100644
--- a/gtk/gtkcssimagecrossfade.c
+++ b/gtk/gtkcssimagecrossfade.c
@@ -230,59 +230,80 @@ gtk_css_image_cross_fade_snapshot (GtkCssImage *image,
}
static gboolean
-gtk_css_image_cross_fade_parse (GtkCssImage *image,
- GtkCssParser *parser)
+parse_progress (GtkCssParser *parser,
+ gpointer option_data,
+ gpointer user_data)
{
- GtkCssImageCrossFade *self = GTK_CSS_IMAGE_CROSS_FADE (image);
- double progress;
+ double *progress = option_data;
+ GtkCssValue *number;
+
+ number = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_PERCENT | GTK_CSS_POSITIVE_ONLY);
+ if (number == NULL)
+ return FALSE;
+ *progress = _gtk_css_number_value_get (number, 1);
+ _gtk_css_value_unref (number);
- if (!_gtk_css_parser_try (parser, "cross-fade(", TRUE))
+ if (*progress > 1.0)
{
- _gtk_css_parser_error (parser, "Expected 'cross-fade('");
+ _gtk_css_parser_error (parser, "Percentages over 100%% are not allowed");
return FALSE;
}
- if (gtk_css_number_value_can_parse (parser))
- {
- GtkCssValue *number;
-
- number = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_PERCENT | GTK_CSS_POSITIVE_ONLY);
- if (number == NULL)
- return FALSE;
- progress = _gtk_css_number_value_get (number, 1);
- _gtk_css_value_unref (number);
-
- if (progress > 1.0)
- {
- _gtk_css_parser_error (parser, "Percentages over 100%% are not allowed");
- return FALSE;
- }
- }
- else
- progress = 0.5;
+ return TRUE;
+}
- image = _gtk_css_image_new_parse (parser);
- if (image == NULL)
+static gboolean
+parse_image (GtkCssParser *parser,
+ gpointer option_data,
+ gpointer user_data)
+{
+ GtkCssImage **image = option_data;
+
+ *image = _gtk_css_image_new_parse (parser);
+ if (*image == NULL)
return FALSE;
- gtk_css_image_cross_fade_add (self, progress, image);
+ return TRUE;
+}
- if (_gtk_css_parser_try (parser, ",", TRUE))
+static guint
+gtk_css_image_cross_fade_parse_arg (GtkCssParser *parser,
+ guint arg,
+ gpointer data)
+{
+ GtkCssImageCrossFade *self = data;
+ double progress = -1.0;
+ GtkCssImage *image = NULL;
+ GtkCssParseOption options[] =
{
- /* XXX: allow parsing colors here */
- image = _gtk_css_image_new_parse (parser);
- if (image == NULL)
- return FALSE;
- gtk_css_image_cross_fade_add (self, 1.0 - progress, image);
- }
+ { (void *) gtk_css_number_value_can_parse, parse_progress, &progress },
+ { NULL, parse_image, &image },
+ };
+
+ if (!gtk_css_parser_consume_any (parser, options, G_N_ELEMENTS (options), self))
+ return 0;
+
+ g_assert (image != NULL);
+
+ /* XXX */
+ if (progress < 0)
+ progress = 1.0 - self->total_progress;
+ gtk_css_image_cross_fade_add (self, progress, image);
- if (!_gtk_css_parser_try (parser, ")", TRUE))
+ return 1;
+}
+
+static gboolean
+gtk_css_image_cross_fade_parse (GtkCssImage *image,
+ GtkCssParser *parser)
+{
+ if (!gtk_css_parser_has_function (parser, "cross-fade"))
{
- _gtk_css_parser_error (parser, "Missing closing bracket");
+ _gtk_css_parser_error (parser, "Expected 'cross-fade('");
return FALSE;
}
- return TRUE;
+ return gtk_css_parser_consume_function (parser, 1, G_MAXUINT, gtk_css_image_cross_fade_parse_arg, image);
}
static void
diff --git a/gtk/gtkcssparser.c b/gtk/gtkcssparser.c
index b43a975173..806cc2701c 100644
--- a/gtk/gtkcssparser.c
+++ b/gtk/gtkcssparser.c
@@ -1210,3 +1210,42 @@ gtk_css_parser_consume_function (GtkCssParser *self,
return result;
}
+gsize
+gtk_css_parser_consume_any (GtkCssParser *parser,
+ const GtkCssParseOption *options,
+ gsize n_options,
+ gpointer user_data)
+{
+ gsize result;
+ gsize i;
+
+ g_return_val_if_fail (parser != NULL, 0);
+ g_return_val_if_fail (options != NULL, 0);
+ g_return_val_if_fail (n_options < sizeof (gsize) * 8 - 1, 0);
+
+ result = 0;
+ while (result != (1 << n_options) - 1)
+ {
+ for (i = 0; i < n_options; i++)
+ {
+ if (result & (1 << i))
+ continue;
+ if (options[i].can_parse && !options[i].can_parse (parser, options[i].data, user_data))
+ continue;
+ if (!options[i].parse (parser, options[i].data, user_data))
+ return 0;
+ result |= 1 << i;
+ break;
+ }
+ if (i == n_options)
+ break;
+ }
+ if (result == 0)
+ {
+ _gtk_css_parser_error (parser, "No valid value given");
+ return result;
+ }
+
+ return result;
+}
+
diff --git a/gtk/gtkcssparserprivate.h b/gtk/gtkcssparserprivate.h
index 019d417f16..e4b763a826 100644
--- a/gtk/gtkcssparserprivate.h
+++ b/gtk/gtkcssparserprivate.h
@@ -31,6 +31,19 @@ typedef void (* GtkCssParserErrorFunc) (GtkCssParser *parser,
const GError *error,
gpointer user_data);
+typedef struct _GtkCssParseOption GtkCssParseOption;
+
+struct _GtkCssParseOption
+{
+ gboolean (* can_parse) (GtkCssParser *parser,
+ gpointer option_data,
+ gpointer user_data);
+ gboolean (* parse) (GtkCssParser *parser,
+ gpointer option_data,
+ gpointer user_data);
+ gpointer data;
+};
+
GtkCssParser * _gtk_css_parser_new (const char *data,
GFile *file,
GtkCssParserErrorFunc error_func,
@@ -90,6 +103,10 @@ gboolean gtk_css_parser_consume_function (GtkCssParser *self,
guint max_args,
guint (* parse_func) (GtkCssParser *, guint, gpointer),
gpointer data);
+gsize gtk_css_parser_consume_any (GtkCssParser *parser,
+ const GtkCssParseOption *options,
+ gsize n_options,
+ gpointer user_data);
gboolean _gtk_css_parser_has_number (GtkCssParser *parser);
char * _gtk_css_parser_read_string (GtkCssParser *parser);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]