[libadwaita/wip/exalm/spring-animation-swipes: 25/36] Add Clamp property




commit 232cd20872fe466329c28f2b01f163ae1bf99c53
Author: Manuel Genovés <manuel genoves gmail com>
Date:   Sun Dec 5 19:22:07 2021 +0100

    Add Clamp property

 src/adw-spring-animation.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++
 src/adw-spring-animation.h |  6 +++++
 2 files changed, 68 insertions(+)
---
diff --git a/src/adw-spring-animation.c b/src/adw-spring-animation.c
index 9e2c99c5..7b67e5f4 100644
--- a/src/adw-spring-animation.c
+++ b/src/adw-spring-animation.c
@@ -25,6 +25,7 @@ struct _AdwSpringAnimation
 
   double initial_velocity;
   double epsilon;
+  gboolean clamp;
 
   guint estimated_duration; /*ms*/
 };
@@ -43,6 +44,7 @@ enum {
   PROP_SPRING_PARAMS,
   PROP_INITIAL_VELOCITY,
   PROP_EPSILON,
+  PROP_CLAMP,
   PROP_ESTIMATED_DURATION,
   LAST_PROP,
 };
@@ -100,6 +102,23 @@ oscillate (AdwAnimation *animation,
   return self->value_to + envelope * (x0 + (beta * x0 + v0) * t);
 }
 
+static guint
+get_first_zero (AdwAnimation *animation)
+{
+  AdwSpringAnimation *self = ADW_SPRING_ANIMATION (animation);
+  guint i = 0;
+  double y = oscillate (animation, 0);
+
+  while (self->value_to > y) {
+    if (i>20000)
+      return 0;
+    y = oscillate (animation, i);
+    i++;
+  }
+
+  return i;
+}
+
 static guint
 adw_spring_animation_estimate_duration (AdwAnimation *animation)
 {
@@ -120,6 +139,9 @@ adw_spring_animation_estimate_duration (AdwAnimation *animation)
   if (beta <= 0)
     return ADW_DURATION_INFINITE;
 
+  if (self->clamp)
+    return get_first_zero (animation);
+
   omega0 = sqrt (stiffness / mass);
 
   /*
@@ -232,6 +254,10 @@ adw_spring_animation_get_property (GObject    *object,
     g_value_set_double (value, adw_spring_animation_get_epsilon (self));
     break;
 
+  case PROP_CLAMP:
+    g_value_set_boolean (value, adw_spring_animation_get_clamp (self));
+    break;
+
   case PROP_ESTIMATED_DURATION:
     g_value_set_uint (value, adw_spring_animation_get_estimated_duration (self));
     break;
@@ -270,6 +296,10 @@ adw_spring_animation_set_property (GObject      *object,
     adw_spring_animation_set_epsilon (self, g_value_get_double (value));
     break;
 
+  case PROP_CLAMP:
+    adw_spring_animation_set_clamp (self, g_value_get_boolean (value));
+    break;
+
   default:
     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   }
@@ -332,6 +362,13 @@ adw_spring_animation_class_init (AdwSpringAnimationClass *klass)
                          0.001,
                          G_PARAM_READWRITE);
 
+  props[PROP_CLAMP] =
+    g_param_spec_boolean ("clamp",
+                          "Clamp",
+                          "Clamp the animation between value-from and value-to",
+                          FALSE,
+                          G_PARAM_READWRITE);
+
   props[PROP_ESTIMATED_DURATION] =
     g_param_spec_uint ("estimated-duration",
                        "Estimated duration",
@@ -348,6 +385,7 @@ static void
 adw_spring_animation_init (AdwSpringAnimation *self)
 {
   self->epsilon = 0.001;
+  self->clamp = FALSE;
 }
 
 AdwAnimation *
@@ -503,6 +541,30 @@ adw_spring_animation_set_epsilon (AdwSpringAnimation *self,
   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_EPSILON]);
 }
 
+gboolean
+adw_spring_animation_get_clamp (AdwSpringAnimation *self)
+{
+  g_return_val_if_fail (ADW_IS_SPRING_ANIMATION (self), FALSE);
+
+  return self->clamp;
+}
+
+void
+adw_spring_animation_set_clamp (AdwSpringAnimation *self,
+                                gboolean            value)
+{
+  g_return_if_fail (ADW_IS_SPRING_ANIMATION (self));
+
+  if (self->clamp == value)
+    return;
+
+  self->clamp = value;
+
+  set_estimated_duration (self);
+
+  g_object_notify_by_pspec (G_OBJECT (self), props[PROP_CLAMP]);
+}
+
 guint
 adw_spring_animation_get_estimated_duration (AdwSpringAnimation *self)
 {
diff --git a/src/adw-spring-animation.h b/src/adw-spring-animation.h
index ceff798b..0859eca3 100644
--- a/src/adw-spring-animation.h
+++ b/src/adw-spring-animation.h
@@ -61,6 +61,12 @@ ADW_AVAILABLE_IN_ALL
 void   adw_spring_animation_set_epsilon (AdwSpringAnimation *self,
                                          double              value);
 
+ADW_AVAILABLE_IN_ALL
+gboolean adw_spring_animation_get_clamp (AdwSpringAnimation *self);
+ADW_AVAILABLE_IN_ALL
+void     adw_spring_animation_set_clamp (AdwSpringAnimation *self,
+                                         gboolean            value);
+
 ADW_AVAILABLE_IN_ALL
 guint adw_spring_animation_get_estimated_duration (AdwSpringAnimation *self);
 


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