[libadwaita/wip/exalm/spring-animation-swipes: 1/3] Add spring animations
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libadwaita/wip/exalm/spring-animation-swipes: 1/3] Add spring animations
- Date: Sat, 4 Dec 2021 17:46:28 +0000 (UTC)
commit 3dd88d0423b60610771d8da258cefb1d57ced95b
Author: Manuel Genovés <manuel genoves gmail com>
Date: Wed Dec 1 00:56:54 2021 +0100
Add spring animations
src/adw-spring-animation.c | 501 +++++++++++++++++++++++++++++++++++++++++++++
src/adw-spring-animation.h | 67 ++++++
src/adw-spring-params.c | 111 ++++++++++
src/adw-spring-params.h | 47 +++++
src/adwaita.h | 2 +
src/meson.build | 4 +
6 files changed, 732 insertions(+)
---
diff --git a/src/adw-spring-animation.c b/src/adw-spring-animation.c
new file mode 100644
index 00000000..041441e0
--- /dev/null
+++ b/src/adw-spring-animation.c
@@ -0,0 +1,501 @@
+/*
+ * Copyright (C) 2021 Manuel Genovés <manuel genoves gmail com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "config.h"
+
+#include "adw-spring-animation.h"
+#include "adw-spring-params.h"
+
+#include "adw-animation-private.h"
+#include "adw-animation-util.h"
+
+#define DELTA 0.001
+
+struct _AdwSpringAnimation
+{
+ AdwAnimation parent_instance;
+
+ double value_from;
+ double value_to;
+
+ AdwSpringParams *spring_params;
+
+ double initial_velocity;
+ double epsilon;
+
+ guint estimated_duration; /*ms*/
+};
+
+struct _AdwSpringAnimationClass
+{
+ AdwAnimationClass parent_class;
+};
+
+G_DEFINE_TYPE (AdwSpringAnimation, adw_spring_animation, ADW_TYPE_ANIMATION)
+
+enum {
+ PROP_0,
+ PROP_VALUE_FROM,
+ PROP_VALUE_TO,
+ PROP_SPRING_PARAMS,
+ PROP_INITIAL_VELOCITY,
+ PROP_EPSILON,
+ PROP_ESTIMATED_DURATION,
+ LAST_PROP,
+};
+
+static GParamSpec *props[LAST_PROP];
+
+/* Based on RBBSpringAnimation from RBBAnimation, MIT license.
+ * https://github.com/robb/RBBAnimation/blob/master/RBBAnimation/RBBSpringAnimation.m
+ */
+static double
+oscillate (AdwAnimation *animation,
+ guint time)
+{
+ AdwSpringAnimation *self = ADW_SPRING_ANIMATION (animation);
+
+ double b = adw_spring_params_get_damping (self->spring_params);
+ double m = adw_spring_params_get_mass (self->spring_params);
+ double k = adw_spring_params_get_stiffness (self->spring_params);
+ double v0 = self->initial_velocity;
+
+ double t = time / 1000.0;
+
+ double beta = b / (2 * m);
+ double omega0 = sqrt (k / m);
+
+ double x0 = -1;
+
+ double envelope = exp (-beta * t);
+
+ /*
+ * Solutions of the form C1*e^(lambda1*x) + C2*e^(lambda2*x)
+ * for the differential equation m*ẍ+b*ẋ+kx = 0
+ */
+
+ /* Underdamped */
+ if (beta < omega0) {
+ double omega1 = sqrt ((omega0 * omega0) - (beta * beta));
+
+ return -x0 + envelope * (x0 * cos (omega1 * t) + ((beta * x0 + v0) / omega1) * sin (omega1 * t));
+ }
+
+ /* Overdamped */
+ if (beta > omega0) {
+ double omega2 = sqrt ((beta * beta) - (omega0 * omega0));
+
+ return -x0 + envelope * (x0 * cosh (omega2 * t) + ((beta * x0 + v0) / omega2) * sinh (omega2 * t));
+ }
+
+ /* Critically damped */
+ return -x0 + envelope * (x0 + (beta * x0 + v0) * t);
+}
+
+static guint
+adw_spring_animation_estimate_duration (AdwAnimation *animation)
+{
+ AdwSpringAnimation *self = ADW_SPRING_ANIMATION (animation);
+
+ double damping = adw_spring_params_get_damping (self->spring_params);
+ double mass = adw_spring_params_get_mass (self->spring_params);
+ double stiffness = adw_spring_params_get_stiffness (self->spring_params);
+
+ double beta = damping / (2 * mass);
+ double omega0;
+ double x0, y0;
+ double x1, y1;
+ double m;
+
+ if (beta <= 0)
+ return ADW_DURATION_INFINITE;
+
+ omega0 = sqrt (stiffness / mass);
+
+ /*
+ * As first ansatz for the overdamped solution,
+ * and general estimation for the oscillating ones
+ * we take the value of the envelope when it's < epsilon
+ */
+ x0 = -log (self->epsilon) / beta;
+
+ if (beta <= omega0)
+ return x0 * 1000;
+
+ /*
+ * Since the overdamped solution decays way slower than the envelope
+ * we need to use the value of the oscillation itself.
+ * Newton's root finding method is a good candidate in this particular case:
+ * https://en.wikipedia.org/wiki/Newton%27s_method
+ */
+ y0 = oscillate (animation, x0);
+ m = (oscillate (animation, x0 + DELTA) - y0) / DELTA;
+
+ x1 = (1 - y0 + m * x0) / m;
+ y1 = oscillate (animation, x1);
+
+ while (ABS (1 - y1) > self->epsilon) {
+ x0 = x1;
+ y0 = y1;
+
+ m = (oscillate (animation, x0 + DELTA) - y0) / DELTA;
+
+ x1 = (1 - y0 + m * x0) / m;
+ y1 = oscillate (animation, x1);
+ }
+
+ return x1 * 1000;
+}
+
+static void
+set_estimated_duration (AdwSpringAnimation *self)
+{
+ if (!self->spring_params)
+ return;
+
+ self->estimated_duration = adw_spring_animation_estimate_duration (ADW_ANIMATION (self));
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ESTIMATED_DURATION]);
+}
+
+static double
+adw_spring_animation_calculate_value (AdwAnimation *animation,
+ guint t)
+{
+ AdwSpringAnimation *self = ADW_SPRING_ANIMATION (animation);
+
+ if (t >= self->estimated_duration)
+ return self->value_to;
+
+ return adw_lerp (self->value_from, self->value_to, oscillate (animation, t));
+}
+
+static void
+adw_spring_animation_constructed (GObject *object)
+{
+ AdwSpringAnimation *self = ADW_SPRING_ANIMATION (object);
+
+ G_OBJECT_CLASS (adw_spring_animation_parent_class)->constructed (object);
+
+ set_estimated_duration (self);
+}
+
+static void
+adw_spring_animation_dispose (GObject *object)
+{
+ AdwSpringAnimation *self = ADW_SPRING_ANIMATION (object);
+
+ adw_spring_params_unref (self->spring_params);
+
+ G_OBJECT_CLASS (adw_spring_animation_parent_class)->dispose (object);
+}
+
+static void
+adw_spring_animation_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ AdwSpringAnimation *self = ADW_SPRING_ANIMATION (object);
+
+ switch (prop_id) {
+ case PROP_VALUE_FROM:
+ g_value_set_double (value, adw_spring_animation_get_value_from (self));
+ break;
+
+ case PROP_VALUE_TO:
+ g_value_set_double (value, adw_spring_animation_get_value_to (self));
+ break;
+
+ case PROP_SPRING_PARAMS:
+ g_value_set_boxed (value, adw_spring_animation_get_spring_params (self));
+ break;
+
+ case PROP_INITIAL_VELOCITY:
+ g_value_set_double (value, adw_spring_animation_get_initial_velocity (self));
+ break;
+
+ case PROP_EPSILON:
+ g_value_set_double (value, adw_spring_animation_get_epsilon (self));
+ break;
+
+ case PROP_ESTIMATED_DURATION:
+ g_value_set_uint (value, adw_spring_animation_get_estimated_duration (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+adw_spring_animation_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ AdwSpringAnimation *self = ADW_SPRING_ANIMATION (object);
+
+ switch (prop_id) {
+ case PROP_VALUE_FROM:
+ adw_spring_animation_set_value_from (self, g_value_get_double (value));
+ break;
+
+ case PROP_VALUE_TO:
+ adw_spring_animation_set_value_to (self, g_value_get_double (value));
+ break;
+
+ case PROP_SPRING_PARAMS:
+ adw_spring_animation_set_spring_params (self, g_value_get_boxed (value));
+ break;
+
+ case PROP_INITIAL_VELOCITY:
+ adw_spring_animation_set_initial_velocity (self, g_value_get_double (value));
+ break;
+
+ case PROP_EPSILON:
+ adw_spring_animation_set_epsilon (self, g_value_get_double (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+adw_spring_animation_class_init (AdwSpringAnimationClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ AdwAnimationClass *animation_class = ADW_ANIMATION_CLASS (klass);
+
+ object_class->constructed = adw_spring_animation_constructed;
+ object_class->dispose = adw_spring_animation_dispose;
+ object_class->set_property = adw_spring_animation_set_property;
+ object_class->get_property = adw_spring_animation_get_property;
+
+ animation_class->estimate_duration = adw_spring_animation_estimate_duration;
+ animation_class->calculate_value = adw_spring_animation_calculate_value;
+
+ props[PROP_VALUE_FROM] =
+ g_param_spec_double ("value-from",
+ "Initial value",
+ "The value to animate from",
+ -G_MAXDOUBLE,
+ G_MAXDOUBLE,
+ 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
+
+ props[PROP_VALUE_TO] =
+ g_param_spec_double ("value-to",
+ "Final value",
+ "The value to animate to",
+ -G_MAXDOUBLE,
+ G_MAXDOUBLE,
+ 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
+
+ props[PROP_SPRING_PARAMS] =
+ g_param_spec_boxed ("spring-params",
+ "Spring parameters",
+ "Physical parameters describing the spring",
+ ADW_TYPE_SPRING_PARAMS,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
+
+ props[PROP_INITIAL_VELOCITY] =
+ g_param_spec_double ("initial-velocity",
+ "Initial velocity",
+ "The initial velocity to start te animation with",
+ -G_MAXDOUBLE,
+ G_MAXDOUBLE,
+ 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
+
+ props[PROP_EPSILON] =
+ g_param_spec_double ("epsilon",
+ "Epsilon",
+ "Precision of the spring",
+ 0,
+ G_MAXDOUBLE,
+ 0.001,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
+
+ props[PROP_ESTIMATED_DURATION] =
+ g_param_spec_uint ("estimated-duration",
+ "Estimated duration",
+ "Estimated duration of the animation in milliseconds",
+ 0,
+ ADW_DURATION_INFINITE,
+ 0,
+ G_PARAM_READABLE);
+
+ g_object_class_install_properties (object_class, LAST_PROP, props);
+}
+
+static void
+adw_spring_animation_init (AdwSpringAnimation *self)
+{
+}
+
+AdwAnimation *
+adw_spring_animation_new (GtkWidget *widget,
+ double from,
+ double to,
+ AdwSpringParams *spring_params,
+ AdwAnimationTarget *target)
+{
+ AdwAnimation *animation;
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+ g_return_val_if_fail (spring_params != NULL, NULL);
+ g_return_val_if_fail (ADW_IS_ANIMATION_TARGET (target), NULL);
+
+ animation = g_object_new (ADW_TYPE_SPRING_ANIMATION,
+ "widget", widget,
+ "value-from", from,
+ "value-to", to,
+ "spring-params", spring_params,
+ "target", target,
+ NULL);
+ g_object_unref (target);
+ adw_spring_params_unref (spring_params);
+
+ return animation;
+}
+
+double
+adw_spring_animation_get_value_from (AdwSpringAnimation *self)
+{
+ g_return_val_if_fail (ADW_IS_SPRING_ANIMATION (self), 0.0);
+
+ return self->value_from;
+}
+
+void
+adw_spring_animation_set_value_from (AdwSpringAnimation *self,
+ double value)
+{
+ g_return_if_fail (ADW_IS_SPRING_ANIMATION (self));
+
+ if (self->value_from == value)
+ return;
+
+ self->value_from = value;
+
+ set_estimated_duration (self);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_VALUE_FROM]);
+}
+
+double
+adw_spring_animation_get_value_to (AdwSpringAnimation *self)
+{
+ g_return_val_if_fail (ADW_IS_SPRING_ANIMATION (self), 0.0);
+
+ return self->value_to;
+}
+
+void
+adw_spring_animation_set_value_to (AdwSpringAnimation *self,
+ double value)
+{
+ g_return_if_fail (ADW_IS_SPRING_ANIMATION (self));
+
+ if (self->value_to == value)
+ return;
+
+ self->value_to = value;
+
+ set_estimated_duration (self);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_VALUE_TO]);
+}
+
+AdwSpringParams *
+adw_spring_animation_get_spring_params (AdwSpringAnimation *self)
+{
+ g_return_val_if_fail (ADW_IS_SPRING_ANIMATION (self), NULL);
+
+ return self->spring_params;
+}
+
+void
+adw_spring_animation_set_spring_params (AdwSpringAnimation *self,
+ AdwSpringParams *spring_params)
+{
+ g_return_if_fail (ADW_IS_SPRING_ANIMATION (self));
+ g_return_if_fail (spring_params != NULL);
+
+ if (self->spring_params == spring_params)
+ return;
+
+ if (self->spring_params != NULL)
+ adw_spring_params_unref (self->spring_params);
+
+ self->spring_params = spring_params;
+
+ adw_spring_params_ref (self->spring_params);
+
+ set_estimated_duration (self);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SPRING_PARAMS]);
+}
+
+double
+adw_spring_animation_get_initial_velocity (AdwSpringAnimation *self)
+{
+ g_return_val_if_fail (ADW_IS_SPRING_ANIMATION (self), 0.0);
+
+ return self->initial_velocity;
+}
+
+void
+adw_spring_animation_set_initial_velocity (AdwSpringAnimation *self,
+ double value)
+{
+ g_return_if_fail (ADW_IS_SPRING_ANIMATION (self));
+
+ if (self->initial_velocity == value)
+ return;
+
+ self->initial_velocity = value;
+
+ set_estimated_duration (self);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_INITIAL_VELOCITY]);
+}
+
+double
+adw_spring_animation_get_epsilon (AdwSpringAnimation *self)
+{
+ g_return_val_if_fail (ADW_IS_SPRING_ANIMATION (self), 0.0);
+
+ return self->epsilon;
+}
+
+void
+adw_spring_animation_set_epsilon (AdwSpringAnimation *self,
+ double value)
+{
+ g_return_if_fail (ADW_IS_SPRING_ANIMATION (self));
+ g_return_if_fail (value > 0.0);
+
+ if (self->epsilon == value)
+ return;
+
+ self->epsilon = value;
+
+ set_estimated_duration (self);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_EPSILON]);
+}
+
+guint
+adw_spring_animation_get_estimated_duration (AdwSpringAnimation *self)
+{
+ g_return_val_if_fail (ADW_IS_SPRING_ANIMATION (self), 0);
+
+ return self->estimated_duration;
+}
diff --git a/src/adw-spring-animation.h b/src/adw-spring-animation.h
new file mode 100644
index 00000000..ceff798b
--- /dev/null
+++ b/src/adw-spring-animation.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2021 Manuel Genovés <manuel genoves gmail com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#pragma once
+
+#if !defined(_ADWAITA_INSIDE) && !defined(ADWAITA_COMPILATION)
+#error "Only <adwaita.h> can be included directly."
+#endif
+
+#include "adw-version.h"
+
+#include <gtk/gtk.h>
+
+#include "adw-animation.h"
+#include "adw-spring-params.h"
+
+G_BEGIN_DECLS
+
+#define ADW_TYPE_SPRING_ANIMATION (adw_spring_animation_get_type())
+
+ADW_AVAILABLE_IN_ALL
+GDK_DECLARE_INTERNAL_TYPE (AdwSpringAnimation, adw_spring_animation, ADW, SPRING_ANIMATION, AdwAnimation)
+
+ADW_AVAILABLE_IN_ALL
+AdwAnimation *adw_spring_animation_new (GtkWidget *widget,
+ double from,
+ double to,
+ AdwSpringParams *spring_params,
+ AdwAnimationTarget *target) G_GNUC_WARN_UNUSED_RESULT;
+
+ADW_AVAILABLE_IN_ALL
+double adw_spring_animation_get_value_from (AdwSpringAnimation *self);
+ADW_AVAILABLE_IN_ALL
+void adw_spring_animation_set_value_from (AdwSpringAnimation *self,
+ double value);
+
+ADW_AVAILABLE_IN_ALL
+double adw_spring_animation_get_value_to (AdwSpringAnimation *self);
+ADW_AVAILABLE_IN_ALL
+void adw_spring_animation_set_value_to (AdwSpringAnimation *self,
+ double value);
+
+ADW_AVAILABLE_IN_ALL
+AdwSpringParams *adw_spring_animation_get_spring_params (AdwSpringAnimation *self);
+ADW_AVAILABLE_IN_ALL
+void adw_spring_animation_set_spring_params (AdwSpringAnimation *self,
+ AdwSpringParams *spring_params);
+
+ADW_AVAILABLE_IN_ALL
+double adw_spring_animation_get_initial_velocity (AdwSpringAnimation *self);
+ADW_AVAILABLE_IN_ALL
+void adw_spring_animation_set_initial_velocity (AdwSpringAnimation *self,
+ double value);
+
+ADW_AVAILABLE_IN_ALL
+double adw_spring_animation_get_epsilon (AdwSpringAnimation *self);
+ADW_AVAILABLE_IN_ALL
+void adw_spring_animation_set_epsilon (AdwSpringAnimation *self,
+ double value);
+
+ADW_AVAILABLE_IN_ALL
+guint adw_spring_animation_get_estimated_duration (AdwSpringAnimation *self);
+
+G_END_DECLS
diff --git a/src/adw-spring-params.c b/src/adw-spring-params.c
new file mode 100644
index 00000000..80a1a1ec
--- /dev/null
+++ b/src/adw-spring-params.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2021 Manuel Genovés <manuel genoves gmail com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+
+#include "config.h"
+
+#include "adw-spring-params.h"
+
+#include <math.h>
+
+G_DEFINE_BOXED_TYPE (AdwSpringParams, adw_spring_params,
+ adw_spring_params_ref, adw_spring_params_unref)
+
+struct _AdwSpringParams
+{
+ gatomicrefcount ref_count;
+
+ double damping;
+ double mass;
+ double stiffness;
+};
+
+AdwSpringParams *
+adw_spring_params_new (double damping_ratio,
+ double mass,
+ double stiffness)
+{
+ double critical_damping;
+ double damping;
+
+ g_return_val_if_fail (damping_ratio >= 0.0, NULL);
+
+ critical_damping = 2 * sqrt (mass * stiffness);
+ damping = damping_ratio * critical_damping;
+
+ return adw_spring_params_new_full (damping, mass, stiffness);
+}
+
+AdwSpringParams *
+adw_spring_params_new_full (double damping,
+ double mass,
+ double stiffness)
+{
+ AdwSpringParams *self;
+
+ g_return_val_if_fail (damping >= 0.0, NULL);
+ g_return_val_if_fail (mass > 0.0, NULL);
+ g_return_val_if_fail (stiffness > 0.0, NULL);
+
+ self = g_slice_new0 (AdwSpringParams);
+
+ g_atomic_ref_count_init (&self->ref_count);
+
+ self->damping = damping;
+ self->mass = mass;
+ self->stiffness = stiffness;
+
+ return self;
+}
+
+AdwSpringParams *
+adw_spring_params_new_default (void)
+{
+ return adw_spring_params_new_full (10, 1, 100);
+}
+
+AdwSpringParams *
+adw_spring_params_ref (AdwSpringParams *self)
+{
+ g_return_val_if_fail (self != NULL, NULL);
+
+ g_atomic_ref_count_inc (&self->ref_count);
+
+ return self;
+}
+
+void
+adw_spring_params_unref (AdwSpringParams *self)
+{
+ g_return_if_fail (self != NULL);
+
+ if (g_atomic_ref_count_dec (&self->ref_count))
+ g_slice_free (AdwSpringParams, self);
+}
+
+
+double
+adw_spring_params_get_damping (AdwSpringParams *self)
+{
+ g_return_val_if_fail (self != NULL, 0.0);
+
+ return self->damping;
+}
+
+double
+adw_spring_params_get_mass (AdwSpringParams *self)
+{
+ g_return_val_if_fail (self != NULL, 0.0);
+
+ return self->mass;
+}
+
+double
+adw_spring_params_get_stiffness (AdwSpringParams *self)
+{
+ g_return_val_if_fail (self != NULL, 0.0);
+
+ return self->stiffness;
+}
diff --git a/src/adw-spring-params.h b/src/adw-spring-params.h
new file mode 100644
index 00000000..eeb3e9fe
--- /dev/null
+++ b/src/adw-spring-params.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 Manuel Genovés <manuel genoves gmail com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+
+#pragma once
+
+#include "adw-version.h"
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define ADW_TYPE_SPRING_PARAMS (adw_spring_params_get_type())
+
+typedef struct _AdwSpringParams AdwSpringParams;
+
+ADW_AVAILABLE_IN_ALL
+GType adw_spring_params_get_type (void) G_GNUC_CONST;
+
+ADW_AVAILABLE_IN_ALL
+AdwSpringParams *adw_spring_params_new_full (double damping,
+ double mass,
+ double stiffness) G_GNUC_WARN_UNUSED_RESULT;
+ADW_AVAILABLE_IN_ALL
+AdwSpringParams *adw_spring_params_new (double damping_ratio,
+ double mass,
+ double stiffness) G_GNUC_WARN_UNUSED_RESULT;
+ADW_AVAILABLE_IN_ALL
+AdwSpringParams *adw_spring_params_new_default (void) G_GNUC_WARN_UNUSED_RESULT;
+
+ADW_AVAILABLE_IN_ALL
+AdwSpringParams *adw_spring_params_ref (AdwSpringParams *self);
+ADW_AVAILABLE_IN_ALL
+void adw_spring_params_unref (AdwSpringParams *self);
+
+ADW_AVAILABLE_IN_ALL
+double adw_spring_params_get_damping (AdwSpringParams *self);
+ADW_AVAILABLE_IN_ALL
+double adw_spring_params_get_mass (AdwSpringParams *self);
+ADW_AVAILABLE_IN_ALL
+double adw_spring_params_get_stiffness (AdwSpringParams *self);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (AdwSpringParams, adw_spring_params_unref)
+
+G_END_DECLS
diff --git a/src/adwaita.h b/src/adwaita.h
index 62e2e154..3371b1c9 100644
--- a/src/adwaita.h
+++ b/src/adwaita.h
@@ -52,6 +52,8 @@ G_BEGIN_DECLS
#include "adw-preferences-row.h"
#include "adw-preferences-window.h"
#include "adw-split-button.h"
+#include "adw-spring-animation.h"
+#include "adw-spring-params.h"
#include "adw-squeezer.h"
#include "adw-status-page.h"
#include "adw-style-manager.h"
diff --git a/src/meson.build b/src/meson.build
index 041e4df5..10a38153 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -111,6 +111,8 @@ src_headers = [
'adw-preferences-row.h',
'adw-preferences-window.h',
'adw-split-button.h',
+ 'adw-spring-animation.h',
+ 'adw-spring-params.h',
'adw-squeezer.h',
'adw-status-page.h',
'adw-style-manager.h',
@@ -177,6 +179,8 @@ src_sources = [
'adw-settings.c',
'adw-shadow-helper.c',
'adw-split-button.c',
+ 'adw-spring-animation.c',
+ 'adw-spring-params.c',
'adw-squeezer.c',
'adw-style-manager.c',
'adw-status-page.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]