[gtk/wip/ebassi/animations: 186/190] Port easing GtkCssValue to GtkTimingFunction



commit 9bf52a274ce5a7c3b911feb2dc7fcc39622f2e0a
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Tue Jul 30 17:10:31 2019 +0100

    Port easing GtkCssValue to GtkTimingFunction
    
    We can share the logic, parsing, and serialization code.

 gtk/gtkcsseasevalue.c         | 279 +++---------------------------------------
 gtk/gtkcsseasevalueprivate.h  |   5 +-
 gtk/gtkcssstylepropertyimpl.c |   6 +-
 3 files changed, 18 insertions(+), 272 deletions(-)
---
diff --git a/gtk/gtkcsseasevalue.c b/gtk/gtkcsseasevalue.c
index 4d79f4fe29..8a985dd4a2 100644
--- a/gtk/gtkcsseasevalue.c
+++ b/gtk/gtkcsseasevalue.c
@@ -18,34 +18,19 @@
 #include "config.h"
 
 #include "gtkcsseasevalueprivate.h"
+#include "gtktimingfunctionprivate.h"
 
 #include <math.h>
 
-typedef enum {
-  GTK_CSS_EASE_CUBIC_BEZIER,
-  GTK_CSS_EASE_STEPS
-} GtkCssEaseType;
-
 struct _GtkCssValue {
   GTK_CSS_VALUE_BASE
-  GtkCssEaseType type;
-  union {
-    struct {
-      double x1;
-      double y1;
-      double x2;
-      double y2;
-    } cubic;
-    struct {
-      guint steps;
-      gboolean start;
-    } steps;
-  } u;
+  GtkTimingFunction *tm;
 };
 
 static void
 gtk_css_value_ease_free (GtkCssValue *value)
 {
+  gtk_timing_function_unref (value->tm);
   g_slice_free (GtkCssValue, value);
 }
 
@@ -63,23 +48,7 @@ static gboolean
 gtk_css_value_ease_equal (const GtkCssValue *ease1,
                           const GtkCssValue *ease2)
 {
-  if (ease1->type != ease2->type)
-    return FALSE;
-  
-  switch (ease1->type)
-    {
-    case GTK_CSS_EASE_CUBIC_BEZIER:
-      return ease1->u.cubic.x1 == ease2->u.cubic.x1 &&
-             ease1->u.cubic.y1 == ease2->u.cubic.y1 &&
-             ease1->u.cubic.x2 == ease2->u.cubic.x2 &&
-             ease1->u.cubic.y2 == ease2->u.cubic.y2;
-    case GTK_CSS_EASE_STEPS:
-      return ease1->u.steps.steps == ease2->u.steps.steps &&
-             ease1->u.steps.start == ease2->u.steps.start;
-    default:
-      g_assert_not_reached ();
-      return FALSE;
-    }
+  return gtk_timing_function_equal (ease1->tm, ease2->tm);
 }
 
 static GtkCssValue *
@@ -95,43 +64,7 @@ static void
 gtk_css_value_ease_print (const GtkCssValue *ease,
                           GString           *string)
 {
-  switch (ease->type)
-    {
-    case GTK_CSS_EASE_CUBIC_BEZIER:
-      if (ease->u.cubic.x1 == 0.25 && ease->u.cubic.y1 == 0.1 &&
-          ease->u.cubic.x2 == 0.25 && ease->u.cubic.y2 == 1.0)
-        g_string_append (string, "ease");
-      else if (ease->u.cubic.x1 == 0.0 && ease->u.cubic.y1 == 0.0 &&
-               ease->u.cubic.x2 == 1.0 && ease->u.cubic.y2 == 1.0)
-        g_string_append (string, "linear");
-      else if (ease->u.cubic.x1 == 0.42 && ease->u.cubic.y1 == 0.0 &&
-               ease->u.cubic.x2 == 1.0  && ease->u.cubic.y2 == 1.0)
-        g_string_append (string, "ease-in");
-      else if (ease->u.cubic.x1 == 0.0  && ease->u.cubic.y1 == 0.0 &&
-               ease->u.cubic.x2 == 0.58 && ease->u.cubic.y2 == 1.0)
-        g_string_append (string, "ease-out");
-      else if (ease->u.cubic.x1 == 0.42 && ease->u.cubic.y1 == 0.0 &&
-               ease->u.cubic.x2 == 0.58 && ease->u.cubic.y2 == 1.0)
-        g_string_append (string, "ease-in-out");
-      else
-        g_string_append_printf (string, "cubic-bezier(%g,%g,%g,%g)", 
-                                ease->u.cubic.x1, ease->u.cubic.y1,
-                                ease->u.cubic.x2, ease->u.cubic.y2);
-      break;
-    case GTK_CSS_EASE_STEPS:
-      if (ease->u.steps.steps == 1)
-        {
-          g_string_append (string, ease->u.steps.start ? "step-start" : "step-end");
-        }
-      else
-        {
-          g_string_append_printf (string, "steps(%u%s)", ease->u.steps.steps, ease->u.steps.start ? ",start" 
: "");
-        }
-      break;
-    default:
-      g_assert_not_reached ();
-      break;
-    }
+  gtk_timing_function_print (ease->tm, string);
 }
 
 static const GtkCssValueClass GTK_CSS_VALUE_EASE = {
@@ -145,42 +78,12 @@ static const GtkCssValueClass GTK_CSS_VALUE_EASE = {
 };
 
 GtkCssValue *
-_gtk_css_ease_value_new_cubic_bezier (double x1,
-                                      double y1,
-                                      double x2,
-                                      double y2)
+_gtk_css_ease_value_new_ease (void)
 {
   GtkCssValue *value;
 
-  g_return_val_if_fail (x1 >= 0.0, NULL);
-  g_return_val_if_fail (x1 <= 1.0, NULL);
-  g_return_val_if_fail (x2 >= 0.0, NULL);
-  g_return_val_if_fail (x2 <= 1.0, NULL);
-
-  value = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_EASE);
-  
-  value->type = GTK_CSS_EASE_CUBIC_BEZIER;
-  value->u.cubic.x1 = x1;
-  value->u.cubic.y1 = y1;
-  value->u.cubic.x2 = x2;
-  value->u.cubic.y2 = y2;
-
-  return value;
-}
-
-static GtkCssValue *
-_gtk_css_ease_value_new_steps (guint n_steps,
-                               gboolean start)
-{
-  GtkCssValue *value;
-
-  g_return_val_if_fail (n_steps > 0, NULL);
-
   value = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_EASE);
-  
-  value->type = GTK_CSS_EASE_STEPS;
-  value->u.steps.steps = n_steps;
-  value->u.steps.start = start;
+  value->tm = gtk_ease ();
 
   return value;
 }
@@ -224,131 +127,19 @@ _gtk_css_ease_value_can_parse (GtkCssParser *parser)
   return FALSE;
 }
 
-static guint
-gtk_css_ease_value_parse_cubic_bezier_arg (GtkCssParser *parser,
-                                           guint         arg,
-                                           gpointer      data)
-{
-  double *values = data;
-
-  if (!gtk_css_parser_consume_number (parser, &values[arg]))
-    return 0;
-
-  if (arg % 2 == 0)
-    {
-      if (values[arg] < 0 || values[arg] > 1.0)
-        {
-          gtk_css_parser_error_value (parser, "value %g out of range. Must be from 0.0 to 1.0", values[arg]);
-          return 0;
-        }
-    }
-
-  return 1;
-}
-
-static GtkCssValue *
-gtk_css_ease_value_parse_cubic_bezier (GtkCssParser *parser)
-{
-  double values[4];
-
-  if (!gtk_css_parser_consume_function (parser, 4, 4, gtk_css_ease_value_parse_cubic_bezier_arg, values))
-    return NULL;
-
-  return _gtk_css_ease_value_new_cubic_bezier (values[0], values[1], values[2], values[3]);
-}
-
-typedef struct 
-{
-  int n_steps;
-  gboolean start;
-} ParseStepsData;
-
-static guint
-gtk_css_ease_value_parse_steps_arg (GtkCssParser *parser,
-                                    guint         arg,
-                                    gpointer      data_)
-{
-  ParseStepsData *data = data_;
-
-  switch (arg)
-  {
-    case 0:
-      if (!gtk_css_parser_consume_integer (parser, &data->n_steps))
-        {
-          return 0;
-        }
-      else if (data->n_steps < 1)
-        {
-          gtk_css_parser_error_value (parser, "Number of steps must be > 0");
-          return 0;
-        }
-      return 1;
-
-    case 1:
-      if (gtk_css_parser_try_ident (parser, "start"))
-        data->start = TRUE;
-      else if (gtk_css_parser_try_ident (parser, "end"))
-        data->start = FALSE;
-      else
-        {
-          gtk_css_parser_error_syntax (parser, "Only allowed values are 'start' and 'end'");
-          return 0;
-        }
-      return 1;
-
-    default:
-      g_return_val_if_reached (0);
-  }
-}
-
-static GtkCssValue *
-gtk_css_ease_value_parse_steps (GtkCssParser *parser)
-{
-  ParseStepsData data = { 0, FALSE };  
-
-  if (!gtk_css_parser_consume_function (parser, 1, 2, gtk_css_ease_value_parse_steps_arg, &data))
-    return NULL;
-
-  return _gtk_css_ease_value_new_steps (data.n_steps, data.start);
-}
-
 GtkCssValue *
 _gtk_css_ease_value_parse (GtkCssParser *parser)
 {
-  guint i;
+  GtkCssValue *value;
+  GtkTimingFunction *tm;
 
-  g_return_val_if_fail (parser != NULL, NULL);
+  if (!gtk_timing_function_parser_parse (parser, &tm))
+    return NULL;
 
-  for (i = 0; i < G_N_ELEMENTS (parser_values); i++)
-    {
-      if (parser_values[i].is_function)
-        {
-          if (gtk_css_parser_has_function (parser, parser_values[i].name))
-            {
-              if (parser_values[i].is_bezier)
-                return gtk_css_ease_value_parse_cubic_bezier (parser);
-              else
-                return gtk_css_ease_value_parse_steps (parser);
-            }
-        }
-      else
-        {
-          if (gtk_css_parser_try_ident (parser, parser_values[i].name))
-            {
-              if (parser_values[i].is_bezier)
-                return _gtk_css_ease_value_new_cubic_bezier (parser_values[i].values[0],
-                                                             parser_values[i].values[1],
-                                                             parser_values[i].values[2],
-                                                             parser_values[i].values[3]);
-              else
-                return _gtk_css_ease_value_new_steps (parser_values[i].values[0],
-                                                      parser_values[i].values[1] != 0.0);
-            }
-        }
-    }
+  value = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_EASE);
+  value->tm = tm;
 
-  gtk_css_parser_error_syntax (parser, "Expected a valid ease value");
-  return NULL;
+  return value;
 }
 
 double
@@ -362,45 +153,5 @@ _gtk_css_ease_value_transform (const GtkCssValue *ease,
   if (progress >= 1)
     return 1;
 
-  switch (ease->type)
-    {
-    case GTK_CSS_EASE_CUBIC_BEZIER:
-      {
-        static const double epsilon = 0.00001;
-        double tmin, t, tmax;
-
-        tmin = 0.0;
-        tmax = 1.0;
-        t = progress;
-
-        while (tmin < tmax)
-          {
-             double sample;
-             sample = (((1.0 + 3 * ease->u.cubic.x1 - 3 * ease->u.cubic.x2) * t
-                       +      -6 * ease->u.cubic.x1 + 3 * ease->u.cubic.x2) * t
-                       +       3 * ease->u.cubic.x1                       ) * t;
-             if (fabs(sample - progress) < epsilon)
-               break;
-
-             if (progress > sample)
-               tmin = t;
-             else
-               tmax = t;
-             t = (tmax + tmin) * .5;
-          }
-
-        return (((1.0 + 3 * ease->u.cubic.y1 - 3 * ease->u.cubic.y2) * t
-                +      -6 * ease->u.cubic.y1 + 3 * ease->u.cubic.y2) * t
-                +       3 * ease->u.cubic.y1                       ) * t;
-      }
-    case GTK_CSS_EASE_STEPS:
-      progress *= ease->u.steps.steps;
-      progress = floor (progress) + (ease->u.steps.start ? 0 : 1);
-      return progress / ease->u.steps.steps;
-    default:
-      g_assert_not_reached ();
-      return 1.0;
-    }
+  return gtk_timing_function_transform_time (ease->tm, progress, 1.0);
 }
-
-
diff --git a/gtk/gtkcsseasevalueprivate.h b/gtk/gtkcsseasevalueprivate.h
index 6b4dab3717..11faa9b38f 100644
--- a/gtk/gtkcsseasevalueprivate.h
+++ b/gtk/gtkcsseasevalueprivate.h
@@ -25,10 +25,7 @@
 
 G_BEGIN_DECLS
 
-GtkCssValue *   _gtk_css_ease_value_new_cubic_bezier  (double                x1,
-                                                       double                y1,
-                                                       double                x2,
-                                                       double                y2);
+GtkCssValue *   _gtk_css_ease_value_new_ease          (void);
 gboolean        _gtk_css_ease_value_can_parse         (GtkCssParser         *parser);
 GtkCssValue *   _gtk_css_ease_value_parse             (GtkCssParser         *parser);
 
diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c
index a1987b751a..61b04d21f8 100644
--- a/gtk/gtkcssstylepropertyimpl.c
+++ b/gtk/gtkcssstylepropertyimpl.c
@@ -1613,8 +1613,7 @@ _gtk_css_style_property_init_properties (void)
                                           0,
                                           transition_timing_function_parse,
                                           NULL,
-                                          _gtk_css_array_value_new (
-                                            _gtk_css_ease_value_new_cubic_bezier (0.25, 0.1, 0.25, 1.0)));
+                                          _gtk_css_array_value_new (_gtk_css_ease_value_new_ease ()));
   gtk_css_style_property_register        ("transition-delay",
                                           GTK_CSS_PROPERTY_TRANSITION_DELAY,
                                           G_TYPE_NONE,
@@ -1647,8 +1646,7 @@ _gtk_css_style_property_init_properties (void)
                                           0,
                                           transition_timing_function_parse,
                                           NULL,
-                                          _gtk_css_array_value_new (
-                                            _gtk_css_ease_value_new_cubic_bezier (0.25, 0.1, 0.25, 1.0)));
+                                          _gtk_css_array_value_new (_gtk_css_ease_value_new_ease ()));
   gtk_css_style_property_register        ("animation-iteration-count",
                                           GTK_CSS_PROPERTY_ANIMATION_ITERATION_COUNT,
                                           G_TYPE_NONE,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]