diff --git a/.gitmodules b/.gitmodules
index e69de29..018c244 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "animation/third_party/glm"]
+ path = animation/third_party/glm
+ url = git://github.com/g-truc/glm
diff --git a/animation-glib/bounce/bounce.cpp b/animation-glib/bounce/bounce.cpp
new file mode 100644
index 0000000..72e06d1
--- /dev/null
+++ b/animation-glib/bounce/bounce.cpp
@@ -0,0 +1,349 @@
+/*
+ * animation-glib/bounce/bounce.cpp
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject implementation for a "bounce" animation.
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace agd = animation::geometry::dimension;
+namespace ab = animation::bounce;
+namespace as = animation::stepper;
+namespace at = animation::transform;
+
+struct _AnimationBounceAnimation
+{
+ AnimationTransformAnimation parent_instance;
+};
+
+typedef struct _AnimationBounceAnimationPrivate
+{
+} AnimationBounceAnimationPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (AnimationBounceAnimation,
+ animation_bounce_animation,
+ ANIMATION_TYPE_TRANSFORM_ANIMATION)
+
+enum {
+ PROP_0,
+ PROP_INITIAL_SCALE,
+ PROP_MAXIMUM_SCALE,
+ PROP_N_BOUNCE,
+ PROP_TARGET,
+ PROP_STEPPER,
+ NPROPS
+};
+
+static GParamSpec *animation_bounce_animation_props [NPROPS] = { NULL, };
+
+float
+animation_bounce_animation_get_initial_scale (AnimationBounceAnimation *animation)
+{
+ return LookupTypedInterfaceProp (G_OBJECT (animation))->InitialScale ();
+}
+
+void
+animation_bounce_animation_set_initial_scale (AnimationBounceAnimation *animation,
+ float initial_scale)
+{
+ LookupTypedInterfaceProp (G_OBJECT (animation))->InitialScale (initial_scale);
+}
+
+float
+animation_bounce_animation_get_maximum_scale (AnimationBounceAnimation *animation)
+{
+ return LookupTypedInterfaceProp (G_OBJECT (animation))->MaximumScale ();
+}
+
+void
+animation_bounce_animation_set_maximum_scale (AnimationBounceAnimation *animation,
+ float maximum_scale)
+{
+ LookupTypedInterfaceProp (G_OBJECT (animation))->MaximumScale (maximum_scale);
+}
+
+unsigned int
+animation_bounce_animation_get_n_bounce (AnimationBounceAnimation *animation)
+{
+ return LookupTypedInterfaceProp (G_OBJECT (animation))->NBounce ();
+}
+
+void
+animation_bounce_animation_set_n_bounce (AnimationBounceAnimation *animation,
+ unsigned int n_bounce)
+{
+ LookupTypedInterfaceProp (G_OBJECT (animation))->NBounce (n_bounce);
+}
+
+/**
+ * animation_bounce_animation_get_target:
+ * @animation: An #AnimationBounceAnimation
+ * @out_box: (out caller-allocates): Return location for an #AnimationBox
+ *
+ * Get the box representing the animation target.
+ */
+void
+animation_bounce_animation_get_target (AnimationBounceAnimation *animation,
+ AnimationBox *out_box)
+{
+ g_return_if_fail (out_box != nullptr);
+
+ animation::Box const &box =
+ LookupTypedInterfaceProp (G_OBJECT (animation))->Target ();
+
+ out_box->top_left.x = agd::get <0> (box.topLeft ());
+ out_box->top_left.y = agd::get <1> (box.topLeft ());
+ out_box->bottom_right.x = agd::get <0> (box.bottomRight ());
+ out_box->bottom_right.y = agd::get <1> (box.bottomRight ());
+}
+
+void
+animation_bounce_animation_set_stepper (AnimationBounceAnimation *animation,
+ AnimationStepper *stepper)
+{
+ animation::stepper::Stepper *stepper_ptr = nullptr;
+ g_object_get (stepper, "stepper", (gpointer) &stepper_ptr, NULL);
+
+ LookupTypedInterfaceProp (G_OBJECT (animation))->Stepper (*stepper_ptr);
+}
+
+/**
+ * animation_bounce_animation_get_stepper:
+ * @animation: An #AnimationBounceAnimation
+ *
+ * Returns: (transfer full): Get the stepper for this #AnimationBounceAnimation
+ */
+AnimationStepper *
+animation_bounce_animation_get_stepper (AnimationBounceAnimation *animation)
+{
+ auto const &stepper (LookupTypedInterfaceProp (G_OBJECT (animation))->Stepper ());
+
+ return animation_stepper_wrapper_new ((gpointer) &stepper);
+}
+
+static void
+animation_bounce_animation_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id)
+ {
+ case PROP_INITIAL_SCALE:
+ animation_bounce_animation_set_initial_scale (ANIMATION_BOUNCE_ANIMATION (object),
+ g_value_get_float (value));
+ break;
+ case PROP_MAXIMUM_SCALE:
+ animation_bounce_animation_set_maximum_scale (ANIMATION_BOUNCE_ANIMATION (object),
+ g_value_get_float (value));
+ break;
+ case PROP_N_BOUNCE:
+ animation_bounce_animation_set_n_bounce (ANIMATION_BOUNCE_ANIMATION (object),
+ g_value_get_uint (value));
+ break;
+ case PROP_TARGET:
+ /* No-op here to handle the constructor */
+ break;
+ case PROP_STEPPER:
+ animation_bounce_animation_set_stepper (ANIMATION_BOUNCE_ANIMATION (object),
+ ANIMATION_STEPPER (g_value_get_object (value)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+animation_bounce_animation_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ AnimationBounceAnimation *bounce_animation = ANIMATION_BOUNCE_ANIMATION (object);
+
+ switch (prop_id)
+ {
+ case PROP_INITIAL_SCALE:
+ g_value_set_float (value, animation_bounce_animation_get_initial_scale (bounce_animation));
+ break;
+ case PROP_MAXIMUM_SCALE:
+ g_value_set_float (value, animation_bounce_animation_get_maximum_scale (bounce_animation));
+ break;
+ case PROP_N_BOUNCE:
+ g_value_set_uint (value, animation_bounce_animation_get_n_bounce (bounce_animation));
+ break;
+ case PROP_TARGET:
+ {
+ AnimationBox target;
+ animation_bounce_animation_get_target (bounce_animation, &target);
+
+ g_value_set_boxed (value, &target);
+ break;
+ }
+ case PROP_STEPPER:
+ g_value_take_object (value, animation_bounce_animation_get_stepper (bounce_animation));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static GObject *
+animation_bounce_animation_constructor (GType type,
+ unsigned int n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ replace_named_pointer_prop_in_construct_params_if_null (construct_params,
+ n_construct_params,
+ "stepper",
+ g_value_get_object,
+ g_value_set_object,
+ []() -> gpointer {
+ return animation_linear_stepper_new (300);
+ });
+
+ const char * const wanted_properties[] = {
+ "initial-scale",
+ "maximum-scale",
+ "n-bounce",
+ "target",
+ "stepper",
+ NULL
+ };
+ g_autoptr(GHashTable) properties_table =
+ static_hash_table_of_values_for_specs (wanted_properties,
+ construct_params,
+ n_construct_params);
+
+ auto *interface =
+ static_cast (InterfaceConstructor ::construct (
+ ForwardFromValueHT (properties_table, g_value_get_float, "initial-scale"),
+ ForwardFromValueHT (properties_table, g_value_get_float, "maximum-scale"),
+ ForwardFromValueHT (properties_table, g_value_get_uint, "n-bounce"),
+ ForwardFromValueHT (properties_table, animation_box_from_gvalue, "target"),
+ ForwardFromValueHT (properties_table, animation_stepper_from_gvalue, "stepper")
+ ));
+
+ replace_interface_prop_in_construct_params (construct_params,
+ n_construct_params,
+ g_steal_pointer (&interface));
+
+ return G_OBJECT_CLASS (animation_bounce_animation_parent_class)->constructor (type,
+ n_construct_params,
+ construct_params);
+}
+
+static void
+animation_bounce_animation_init (AnimationBounceAnimation *model)
+{
+}
+
+
+static void
+animation_bounce_animation_class_init (AnimationBounceAnimationClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructor = animation_bounce_animation_constructor;
+ object_class->get_property = animation_bounce_animation_get_property;
+ object_class->set_property = animation_bounce_animation_set_property;
+
+ animation_bounce_animation_props[PROP_INITIAL_SCALE] =
+ g_param_spec_float ("initial-scale",
+ "Initial Scale",
+ "The initial scale of the animation",
+ 0.1f,
+ 1.0f,
+ 0.7f,
+ static_cast (G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ animation_bounce_animation_props[PROP_MAXIMUM_SCALE] =
+ g_param_spec_float ("maximum-scale",
+ "Maximum Scale",
+ "The maximum scale of the animation",
+ 1.0f,
+ 3.0f,
+ 1.2f,
+ static_cast (G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ animation_bounce_animation_props[PROP_N_BOUNCE] =
+ g_param_spec_uint ("n-bounce",
+ "Number of Bounces",
+ "The number of bounces in the animation",
+ 1,
+ 10,
+ 1,
+ static_cast (G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ animation_bounce_animation_props[PROP_TARGET] =
+ g_param_spec_boxed ("target",
+ "Target Box",
+ "Box that we are animating to",
+ ANIMATION_TYPE_BOX,
+ static_cast (G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ animation_bounce_animation_props[PROP_STEPPER] =
+ g_param_spec_object ("stepper",
+ "Stepper",
+ "Stepper to use to progress the animation",
+ ANIMATION_TYPE_STEPPER,
+ static_cast (G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_properties (object_class,
+ NPROPS,
+ animation_bounce_animation_props);
+}
+
+/**
+ * animation_bounce_new:
+ * @initial_scale: Scale factor that the surface will initially have.
+ * @maximum_scale: Scale factor that the surface will have at maximum.
+ * @n_bounce: Number of bounces.
+ * @target: The #AnimationBox that we are animating to.
+ * @stepper: The #AnimationStepper of the animation.
+ *
+ * Returns: (transfer full): A new #AnimationBounceAnimation.
+ */
+AnimationBounceAnimation *
+animation_bounce_new (float initial_scale,
+ float maximum_scale,
+ unsigned int n_bounce,
+ const AnimationBox *target,
+ AnimationStepper *stepper)
+{
+ return ANIMATION_BOUNCE_ANIMATION (g_object_new (ANIMATION_TYPE_BOUNCE_ANIMATION,
+ "initial-scale", initial_scale,
+ "maximum-scale", maximum_scale,
+ "n-bounce", n_bounce,
+ "target", target,
+ "stepper", stepper,
+ NULL));
+}
diff --git a/animation-glib/bounce/bounce.h b/animation-glib/bounce/bounce.h
new file mode 100644
index 0000000..684f44f
--- /dev/null
+++ b/animation-glib/bounce/bounce.h
@@ -0,0 +1,61 @@
+/*
+ * animation-glib/bounce/bounce.h
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject Interface for "bounce" animation.
+ */
+#pragma once
+
+#include
+
+#include
+#include
+#include
+#include
+
+G_BEGIN_DECLS
+
+#define ANIMATION_TYPE_BOUNCE_ANIMATION animation_bounce_animation_get_type ()
+G_DECLARE_FINAL_TYPE (AnimationBounceAnimation, animation_bounce_animation, ANIMATION, BOUNCE_ANIMATION, AnimationTransformAnimation)
+
+float animation_bounce_animation_get_initial_scale (AnimationBounceAnimation *animation);
+void animation_bounce_animation_set_initial_scale (AnimationBounceAnimation *animation,
+ float initial_scale);
+
+float animation_bounce_animation_get_maximum_scale (AnimationBounceAnimation *animation);
+void animation_bounce_animation_set_maximum_scale (AnimationBounceAnimation *animation,
+ float maximum_scale);
+
+unsigned int animation_bounce_animation_get_n_bounce (AnimationBounceAnimation *animation);
+void animation_bounce_animation_set_n_bounce (AnimationBounceAnimation *animation,
+ unsigned int n_bounce);
+
+void animation_bounce_animation_get_target (AnimationBounceAnimation *animation,
+ AnimationBox *out_box);
+
+void animation_bounce_animation_set_stepper (AnimationBounceAnimation *animation,
+ AnimationStepper *stepper);
+AnimationStepper * animation_bounce_animation_get_stepper (AnimationBounceAnimation *animation);
+
+AnimationBounceAnimation * animation_bounce_new (float initial_scale,
+ float maximum_scale,
+ unsigned int n_bounce,
+ const AnimationBox *target,
+ AnimationStepper *stepper);
+
+G_END_DECLS
+
+#pragma once
diff --git a/animation-glib/bounce/meson.build b/animation-glib/bounce/meson.build
new file mode 100644
index 0000000..0c47361
--- /dev/null
+++ b/animation-glib/bounce/meson.build
@@ -0,0 +1,18 @@
+# /animation/bounce/meson.build
+#
+# Build the libanimation library (bounce animation component).
+#
+# See /LICENCE.md for Copyright information.
+
+bounce_introspectable_sources = files([
+ 'bounce.cpp'
+])
+
+bounce_headers = files([
+ 'bounce.h'
+])
+
+animation_glib_introspectable_sources += bounce_introspectable_sources
+animation_glib_headers += bounce_headers
+
+install_headers(bounce_headers, subdir: join_paths(animation_headers_subdir, 'bounce'))
diff --git a/animation-glib/box.cpp b/animation-glib/box.cpp
new file mode 100644
index 0000000..00af7b3
--- /dev/null
+++ b/animation-glib/box.cpp
@@ -0,0 +1,40 @@
+/*
+ * animation-glib/box.cpp
+ *
+ * Copyright 2018 Endless Mobile, Inc.
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject Interface for "wobbly" textures, box
+ * type implementation.
+ */
+
+#include
+
+static gpointer
+animation_box_copy (gpointer ptr)
+{
+ AnimationBox *src = reinterpret_cast (ptr);
+ AnimationBox *dst = g_new0 (AnimationBox, 1);
+
+ *dst = *src;
+
+ return reinterpret_cast (dst);
+}
+
+G_DEFINE_BOXED_TYPE (AnimationBox,
+ animation_box,
+ animation_box_copy,
+ g_free);
diff --git a/animation-glib/box.h b/animation-glib/box.h
new file mode 100644
index 0000000..b583475
--- /dev/null
+++ b/animation-glib/box.h
@@ -0,0 +1,39 @@
+/*
+ * animation-glib/box.h
+ *
+ * Copyright 2018 Endless Mobile, Inc.
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject Interface for "wobbly" textures, 2D box type.
+ */
+#pragma once
+
+#include
+
+#include
+
+G_BEGIN_DECLS
+
+typedef struct {
+ AnimationVector top_left;
+ AnimationVector bottom_right;
+} AnimationBox;
+
+#define ANIMATION_TYPE_BOX animation_box_get_type ()
+
+GType animation_box_get_type ();
+
+G_END_DECLS
diff --git a/animation-glib/constructor-helpers.cpp b/animation-glib/constructor-helpers.cpp
new file mode 100644
index 0000000..41af673
--- /dev/null
+++ b/animation-glib/constructor-helpers.cpp
@@ -0,0 +1,156 @@
+/*
+ * animation-glib/constructor-helpers.cpp
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * Helpers for constructing C++ objects directly from GObject properties
+ * in a GObject constructor.
+ */
+
+#include
+
+#include "constructor-helpers.h"
+
+GHashTable *
+static_hash_table_of_values_for_specs (const char * const *wanted_properties,
+ GObjectConstructParam *construct_params,
+ unsigned int n_construct_params)
+{
+ g_autoptr(GHashTable) ht = g_hash_table_new (g_str_hash, g_str_equal);
+
+ /* Insert all the properties we intend to
+ * have in the hash table, with NULL as
+ * their value. */
+ for (const char * const *iter = wanted_properties; *iter != NULL; ++iter)
+ g_hash_table_insert (ht,
+ (gpointer) (*iter),
+ NULL);
+
+ /* Now go through all the construct params and insert
+ * their value pointer into the hash table. */
+ for (unsigned int i = 0; i < n_construct_params; ++i)
+ {
+ GParamSpec *pspec = construct_params[i].pspec;
+ GValue *value = construct_params[i].value;
+
+ if (g_hash_table_contains (ht, pspec->name))
+ g_hash_table_insert (ht,
+ (gpointer) pspec->name,
+ value);
+ }
+
+ return reinterpret_cast (g_steal_pointer (&ht));
+}
+
+/**
+ * replace_construct_param:
+ * @construct_params: (array length=n_construct_params) An array of #GObjectConstructParam
+ * @n_construct_params: Number of elements in @construct_params.
+ * @prop_name: The name of the construct prop to replace the value of.
+ * @initialize_func: A function which sets the GValue to something sensible.
+ *
+ * Replace a construction parameter @prop_name in the
+ * passed @construct_params by using the passed @initialize_func.
+ *
+ * This function must always replace one construct parameter, it is
+ * an error to pass a @prop_name that is not in the @construct_params.
+ */
+void
+replace_construct_param (GObjectConstructParam *construct_params,
+ unsigned int n_construct_params,
+ const char *prop_name,
+ AnimationConstructorHelpersInitializeValueFunc initialize_func,
+ gpointer initialize_func_data)
+{
+ /* The prop should always be found in the array so that we can replace
+ * it, this function doesn't support appending the prop. That means
+ * that the relevant prop must always G_PARAM_CONSTRUCT or
+ * G_PARAM_CONSTRUCT_ONLY. */
+ for (unsigned int i = 0; i < n_construct_params; ++i)
+ {
+ if (g_strcmp0 (construct_params[i].pspec->name, prop_name) == 0)
+ {
+ g_value_unset (construct_params[i].value);
+ initialize_func (construct_params[i].value, initialize_func_data);
+ return;
+ }
+ }
+
+ g_assert_not_reached ();
+}
+
+template
+static typename std::result_of ::type
+invoke_function_thunk (Args... args, gpointer lambda)
+{
+ FunctionType *f = reinterpret_cast (lambda);
+
+ return (*f)(args...);
+}
+
+
+void
+replace_named_pointer_prop_in_construct_params (GObjectConstructParam *construct_params,
+ unsigned int n_construct_params,
+ const char *prop_name,
+ gpointer ptr)
+{
+ auto set_value = [ptr](GValue *value) {
+ g_value_init (value, G_TYPE_POINTER);
+ g_value_set_pointer (value, ptr);
+ };
+ replace_construct_param (construct_params,
+ n_construct_params,
+ prop_name,
+ (AnimationConstructorHelpersInitializeValueFunc) invoke_function_thunk ,
+ &set_value);
+}
+
+void
+replace_interface_prop_in_construct_params (GObjectConstructParam *construct_params,
+ unsigned int n_construct_params,
+ gpointer interface)
+{
+ replace_named_pointer_prop_in_construct_params (construct_params,
+ n_construct_params,
+ "interface",
+ interface);
+}
+
+void
+replace_named_pointer_prop_in_construct_params_if_null (GObjectConstructParam *construct_params,
+ unsigned int n_construct_params,
+ const char *prop_name,
+ AnimationConstructorHelpersGValueGetPointerFunc get_func,
+ AnimationConstructorHelpersGValueSetPointerFunc set_func,
+ AnimationConstructorHelpersConstructDefaultValueFunc construct_func)
+{
+ /* The prop should always be found in the array so that we can replace
+ * it, this function doesn't support appending the prop. That means
+ * that the relevant prop must always G_PARAM_CONSTRUCT or
+ * G_PARAM_CONSTRUCT_ONLY. */
+ for (unsigned int i = 0; i < n_construct_params; ++i)
+ {
+ if (g_strcmp0 (construct_params[i].pspec->name, prop_name) == 0)
+ {
+ if (get_func (construct_params[i].value) == nullptr)
+ set_func (construct_params[i].value, construct_func ());
+
+ return;
+ }
+ }
+
+ g_assert_not_reached ();
+}
diff --git a/animation-glib/constructor-helpers.h b/animation-glib/constructor-helpers.h
new file mode 100644
index 0000000..b20f8a6
--- /dev/null
+++ b/animation-glib/constructor-helpers.h
@@ -0,0 +1,163 @@
+/*
+ * animation-glib/constructor-helpers.cpp
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * Helpers for constructing C++ objects directly from GObject properties
+ * in a GObject constructor.
+ */
+
+#pragma once
+
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+G_BEGIN_DECLS
+
+inline GValue *
+lookup_gvalue (GHashTable *ht, const char *key)
+{
+ return reinterpret_cast (g_hash_table_lookup (ht, key));
+}
+
+GHashTable *
+static_hash_table_of_values_for_specs (const char * const *wanted_properties,
+ GObjectConstructParam *construct_params,
+ unsigned int n_construct_params);
+
+typedef void (*AnimationConstructorHelpersInitializeValueFunc) (GValue *value,
+ gpointer user_data);
+
+void replace_construct_param (GObjectConstructParam *construct_params,
+ unsigned int n_construct_params,
+ const char *prop_name,
+ AnimationConstructorHelpersInitializeValueFunc initialize_func,
+ gpointer initialize_func_data);
+
+void replace_named_pointer_prop_in_construct_params (GObjectConstructParam *construct_params,
+ unsigned int n_construct_params,
+ const char *prop_name,
+ gpointer ptr);
+
+void replace_interface_prop_in_construct_params (GObjectConstructParam *construct_params,
+ unsigned int n_construct_params,
+ gpointer interface);
+
+typedef gpointer (*AnimationConstructorHelpersGValueGetPointerFunc) (const GValue *value);
+typedef void (*AnimationConstructorHelpersGValueSetPointerFunc) (GValue *value, gpointer);
+typedef gpointer (*AnimationConstructorHelpersConstructDefaultValueFunc) (void);
+
+void replace_named_pointer_prop_in_construct_params_if_null (GObjectConstructParam *construct_params,
+ unsigned int n_construct_params,
+ const char *prop_name,
+ AnimationConstructorHelpersGValueGetPointerFunc get_func,
+ AnimationConstructorHelpersGValueSetPointerFunc set_func,
+ AnimationConstructorHelpersConstructDefaultValueFunc construct_func);
+
+G_END_DECLS
+
+#ifdef __cplusplus
+inline animation::Box
+animation_box_from_gvalue (GValue *value)
+{
+ AnimationBox *boxed_box = reinterpret_cast (g_value_get_boxed (value));
+
+ if (boxed_box == nullptr)
+ return animation::Box (animation::Point (0, 0),
+ animation::Point (1, 1));
+
+ return animation::Box (animation::Point (boxed_box->top_left.x,
+ boxed_box->top_left.y),
+ animation::Point (boxed_box->bottom_right.x,
+ boxed_box->bottom_right.y));
+}
+
+inline animation::Point
+animation_point_from_gvalue (GValue *value)
+{
+ AnimationVector *boxed_point = reinterpret_cast (g_value_get_boxed (value));
+
+ if (boxed_point == nullptr)
+ return animation::geometry::PointModel (0, 0);
+
+ return animation::Point (boxed_point->x, boxed_point->y);
+}
+
+inline animation::geometry::PointModel
+animation_point_size_t_from_gvalue (GValue *value)
+{
+ AnimationVector *boxed_point = reinterpret_cast (g_value_get_boxed (value));
+
+ if (boxed_point == nullptr)
+ return animation::geometry::PointModel (0, 0);
+
+ return animation::geometry::PointModel (boxed_point->x, boxed_point->y);
+}
+
+inline animation::stepper::Stepper
+animation_stepper_from_gvalue (GValue *value)
+{
+ static const unsigned int DefaultAnimationLength = 300;
+
+ AnimationStepper *stepper =
+ reinterpret_cast (g_value_get_object (value));
+ animation::stepper::Stepper *stepper_ptr = NULL;
+
+ if (stepper != nullptr)
+ {
+ g_object_get (G_OBJECT (stepper), "stepper", &stepper_ptr, NULL);
+ return *stepper_ptr;
+ }
+
+ return animation::stepper::Linear (DefaultAnimationLength);
+}
+
+template
+typename std::result_of ::type ForwardFromValueHT (GHashTable *ht,
+ Marshaller &&m,
+ const char *name)
+{
+ return m (lookup_gvalue (ht, name));
+}
+
+template
+struct InterfaceConstructor
+{
+ template
+ static Interface * construct (ArgTypes&&... args)
+ {
+ return new Interface (args...);
+ }
+};
+
+template
+DerivedType * LookupTypedInterfaceProp (GObject *object)
+{
+ InterfaceType *iface = nullptr;
+ g_object_get (object, "interface", (gpointer) &iface, NULL);
+
+ return static_cast (iface);
+}
+#endif
diff --git a/animation-glib/glide/glide.cpp b/animation-glib/glide/glide.cpp
new file mode 100644
index 0000000..525f959
--- /dev/null
+++ b/animation-glib/glide/glide.cpp
@@ -0,0 +1,404 @@
+/*
+ * animation-glib/glide/glide.cpp
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject implementation for a "glide" animation.
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace agd = animation::geometry::dimension;
+namespace ag = animation::glide;
+namespace at = animation::transform;
+
+struct _AnimationGlideAnimation
+{
+ AnimationTransformAnimation parent_instance;
+};
+
+typedef struct _AnimationGlideAnimationPrivate
+{
+} AnimationGlideAnimationPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (AnimationGlideAnimation,
+ animation_glide_animation,
+ ANIMATION_TYPE_TRANSFORM_ANIMATION)
+
+enum {
+ PROP_0,
+ PROP_INITIAL_DISTANCE,
+ PROP_X_ROTATION_ANGLE_DEGREES,
+ PROP_Y_ROTATION_ANGLE_DEGREES,
+ PROP_X_AXIS_LOCATION_UNIT,
+ PROP_Y_AXIS_LOCATION_UNIT,
+ PROP_SCREEN_WIDTH,
+ PROP_TARGET,
+ PROP_STEPPER,
+ NPROPS
+};
+
+static GParamSpec *animation_glide_animation_props [NPROPS] = { NULL, };
+
+void
+animation_glide_animation_set_initial_distance (AnimationGlideAnimation *animation,
+ float initial_distance)
+{
+ LookupTypedInterfaceProp (G_OBJECT (animation))->InitialDistance (initial_distance);
+}
+
+float
+animation_glide_animation_get_initial_distance (AnimationGlideAnimation *animation)
+{
+ return LookupTypedInterfaceProp (G_OBJECT (animation))->InitialDistance ();
+}
+
+void
+animation_glide_animation_set_x_rotation_angle_degrees (AnimationGlideAnimation *animation,
+ float x_rotation_angle_degrees)
+{
+ LookupTypedInterfaceProp (G_OBJECT (animation))->XRotationAngleDegrees (x_rotation_angle_degrees);
+}
+
+float
+animation_glide_animation_get_x_rotation_angle_degrees (AnimationGlideAnimation *animation)
+{
+ return LookupTypedInterfaceProp (G_OBJECT (animation))->XRotationAngleDegrees ();
+}
+
+void
+animation_glide_animation_set_y_rotation_angle_degrees (AnimationGlideAnimation *animation,
+ float y_rotation_angle_degrees)
+{
+ LookupTypedInterfaceProp (G_OBJECT (animation))->YRotationAngleDegrees (y_rotation_angle_degrees);
+}
+
+float
+animation_glide_animation_get_y_rotation_angle_degrees (AnimationGlideAnimation *animation)
+{
+ return LookupTypedInterfaceProp (G_OBJECT (animation))->YRotationAngleDegrees ();
+}
+
+void
+animation_glide_animation_set_x_axis_location_unit (AnimationGlideAnimation *animation,
+ float x_axis_location_unit)
+{
+ LookupTypedInterfaceProp (G_OBJECT (animation))->XAxisLocationUnit (x_axis_location_unit);
+}
+
+float
+animation_glide_animation_get_x_axis_location_unit (AnimationGlideAnimation *animation)
+{
+ return LookupTypedInterfaceProp (G_OBJECT (animation))->XAxisLocationUnit ();
+}
+
+void
+animation_glide_animation_set_y_axis_location_unit (AnimationGlideAnimation *animation,
+ float y_axis_location_unit)
+{
+ LookupTypedInterfaceProp (G_OBJECT (animation))->YAxisLocationUnit (y_axis_location_unit);
+}
+
+float
+animation_glide_animation_get_y_axis_location_unit (AnimationGlideAnimation *animation)
+{
+ return LookupTypedInterfaceProp (G_OBJECT (animation))->YAxisLocationUnit ();
+}
+
+void
+animation_glide_animation_set_stepper (AnimationGlideAnimation *animation,
+ AnimationStepper *stepper)
+{
+ animation::stepper::Stepper *stepper_ptr = nullptr;
+ g_object_get (stepper, "stepper", (gpointer) &stepper_ptr, NULL);
+
+ LookupTypedInterfaceProp (G_OBJECT (animation))->Stepper (*stepper_ptr);
+}
+
+/**
+ * animation_glide_animation_get_stepper:
+ * @animation: An #AnimationGlideAnimation
+ *
+ * Returns: (transfer full): Get the stepper for this #AnimationGlideAnimation
+ */
+AnimationStepper *
+animation_glide_animation_get_stepper (AnimationGlideAnimation *animation)
+{
+ auto const &stepper (LookupTypedInterfaceProp (G_OBJECT (animation))->Stepper ());
+
+ return animation_stepper_wrapper_new ((gpointer) &stepper);
+}
+
+static void
+animation_glide_animation_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ AnimationGlideAnimation *glide_animation = ANIMATION_GLIDE_ANIMATION (object);
+
+ switch (prop_id)
+ {
+ case PROP_INITIAL_DISTANCE:
+ animation_glide_animation_set_initial_distance (glide_animation, g_value_get_float (value));
+ break;
+ case PROP_X_ROTATION_ANGLE_DEGREES:
+ animation_glide_animation_set_x_rotation_angle_degrees (glide_animation, g_value_get_float (value));
+ break;
+ case PROP_Y_ROTATION_ANGLE_DEGREES:
+ animation_glide_animation_set_y_rotation_angle_degrees (glide_animation, g_value_get_float (value));
+ break;
+ case PROP_X_AXIS_LOCATION_UNIT:
+ animation_glide_animation_set_x_axis_location_unit (glide_animation, g_value_get_float (value));
+ break;
+ case PROP_Y_AXIS_LOCATION_UNIT:
+ animation_glide_animation_set_y_axis_location_unit (glide_animation, g_value_get_float (value));
+ break;
+ case PROP_SCREEN_WIDTH:
+ /* Not writable, except on construction */
+ break;
+ case PROP_TARGET:
+ /* Not writable, except on construction */
+ break;
+ case PROP_STEPPER:
+ animation_glide_animation_set_stepper (glide_animation,
+ ANIMATION_STEPPER (g_value_get_object (value)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+animation_glide_animation_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ AnimationGlideAnimation *glide_animation = ANIMATION_GLIDE_ANIMATION (object);
+
+ switch (prop_id)
+ {
+ case PROP_INITIAL_DISTANCE:
+ g_value_set_float (value, animation_glide_animation_get_initial_distance (glide_animation));
+ break;
+ case PROP_X_ROTATION_ANGLE_DEGREES:
+ g_value_set_float (value, animation_glide_animation_get_x_rotation_angle_degrees (glide_animation));
+ break;
+ case PROP_Y_ROTATION_ANGLE_DEGREES:
+ g_value_set_float (value, animation_glide_animation_get_y_rotation_angle_degrees (glide_animation));
+ break;
+ case PROP_X_AXIS_LOCATION_UNIT:
+ g_value_set_float (value, animation_glide_animation_get_x_axis_location_unit (glide_animation));
+ break;
+ case PROP_Y_AXIS_LOCATION_UNIT:
+ g_value_set_float (value, animation_glide_animation_get_y_axis_location_unit (glide_animation));
+ break;
+ case PROP_SCREEN_WIDTH:
+ /* Not readable */
+ break;
+ case PROP_TARGET:
+ /* Not readable */
+ break;
+ case PROP_STEPPER:
+ g_value_take_object (value, animation_glide_animation_get_stepper (glide_animation));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static GObject *
+animation_glide_animation_constructor (GType type,
+ unsigned int n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ replace_named_pointer_prop_in_construct_params_if_null (construct_params,
+ n_construct_params,
+ "stepper",
+ g_value_get_object,
+ g_value_set_object,
+ []() -> gpointer {
+ return animation_linear_stepper_new (300);
+ });
+
+
+ const char * const wanted_properties[] = {
+ "initial-distance",
+ "x-rotation-angle-degrees",
+ "y-rotation-angle-degrees",
+ "x-axis-location-unit",
+ "y-axis-location-unit",
+ "screen-width",
+ "target",
+ "stepper",
+ NULL
+ };
+ g_autoptr(GHashTable) properties_table =
+ static_hash_table_of_values_for_specs (wanted_properties,
+ construct_params,
+ n_construct_params);
+
+ auto *interface =
+ static_cast (InterfaceConstructor ::construct (
+ ForwardFromValueHT (properties_table, g_value_get_float, "initial-distance"),
+ ForwardFromValueHT (properties_table, g_value_get_float, "x-rotation-angle-degrees"),
+ ForwardFromValueHT (properties_table, g_value_get_float, "y-rotation-angle-degrees"),
+ ForwardFromValueHT (properties_table, g_value_get_float, "x-axis-location-unit"),
+ ForwardFromValueHT (properties_table, g_value_get_float, "y-axis-location-unit"),
+ ForwardFromValueHT (properties_table, g_value_get_uint, "screen-width"),
+ ForwardFromValueHT (properties_table, animation_box_from_gvalue, "target"),
+ ForwardFromValueHT (properties_table, animation_stepper_from_gvalue, "stepper")
+ ));
+
+ replace_interface_prop_in_construct_params (construct_params,
+ n_construct_params,
+ g_steal_pointer (&interface));
+
+ return G_OBJECT_CLASS (animation_glide_animation_parent_class)->constructor (type,
+ n_construct_params,
+ construct_params);
+}
+
+static void
+animation_glide_animation_init (AnimationGlideAnimation *model)
+{
+}
+
+
+static void
+animation_glide_animation_class_init (AnimationGlideAnimationClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructor = animation_glide_animation_constructor;
+ object_class->get_property = animation_glide_animation_get_property;
+ object_class->set_property = animation_glide_animation_set_property;
+
+ animation_glide_animation_props[PROP_INITIAL_DISTANCE] =
+ g_param_spec_float ("initial-distance",
+ "Initial Distance",
+ "The initial distance away from the camera",
+ -1.0f,
+ 1.0f,
+ -0.3f,
+ static_cast (G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ animation_glide_animation_props[PROP_X_ROTATION_ANGLE_DEGREES] =
+ g_param_spec_float ("x-rotation-angle-degrees",
+ "X Rotation Angle Degrees",
+ "Number of degrees on the X axis to rotate",
+ -360.0f,
+ 360.0f,
+ 0.0f,
+ static_cast (G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ animation_glide_animation_props[PROP_Y_ROTATION_ANGLE_DEGREES] =
+ g_param_spec_float ("y-rotation-angle-degrees",
+ "Y Rotation Angle Degrees",
+ "Number of degrees on the Y axis to rotate",
+ -360.0f,
+ 360.0f,
+ 0.0f,
+ static_cast (G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ animation_glide_animation_props[PROP_X_AXIS_LOCATION_UNIT] =
+ g_param_spec_float ("x-axis-location-unit",
+ "X Axis Location Unit",
+ "Unit-coordinates of where the X axis is on the surface",
+ 0.0f,
+ 1.0f,
+ 0.2f,
+ static_cast (G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ animation_glide_animation_props[PROP_Y_AXIS_LOCATION_UNIT] =
+ g_param_spec_float ("y-axis-location-unit",
+ "Y Axis Location Unit",
+ "Unit-coordinates of where the Y axis is on the surface",
+ 0.0f,
+ 1.0f,
+ 0.5f,
+ static_cast (G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ animation_glide_animation_props[PROP_SCREEN_WIDTH] =
+ g_param_spec_uint ("screen-width",
+ "Screen Width",
+ "Width of the screen in pixels",
+ 1,
+ G_MAXUINT,
+ 1,
+ static_cast (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
+ animation_glide_animation_props[PROP_TARGET] =
+ g_param_spec_boxed ("target",
+ "Target Box",
+ "Box that we are animating to",
+ ANIMATION_TYPE_BOX,
+ static_cast (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
+ animation_glide_animation_props[PROP_STEPPER] =
+ g_param_spec_object ("stepper",
+ "Stepper",
+ "Stepper to use to progress the animation",
+ ANIMATION_TYPE_STEPPER,
+ static_cast (G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ g_object_class_install_properties (object_class,
+ NPROPS,
+ animation_glide_animation_props);
+}
+
+/**
+ * animation_glide_new:
+ * @initial_distance: Initial distance frm the camera.
+ * @x_rotation_angle_degrees: Degrees of rotation towards the X axis.
+ * @y_rotation_angle_degrees: Degrees of rotation towards the Y axis.
+ * @y_axis_location_unit: Unit-coordinates of where the X axis is on the surface.
+ * @x_axis_location_unit: Unit-coordinates of where the Y axis is on the surface.
+ * @screen_width: Width of the screen, in pixels.
+ * @target_box: The #AnimationBox that we are animating to.
+ * @length: The length of the animation.
+ *
+ * Returns: (transfer full): A new #AnimationGlideAnimation.
+ */
+AnimationGlideAnimation *
+animation_glide_new (float initial_distance,
+ float x_rotation_angle_degrees,
+ float y_rotation_angle_degrees,
+ float x_axis_location_unit,
+ float y_axis_location_unit,
+ unsigned int screen_width,
+ const AnimationBox *target_box,
+ unsigned int length)
+{
+ return ANIMATION_GLIDE_ANIMATION (g_object_new (ANIMATION_TYPE_GLIDE_ANIMATION,
+ "initial-distance", initial_distance,
+ "x-rotation-angle-degrees", x_rotation_angle_degrees,
+ "y-rotation-angle-degrees", y_rotation_angle_degrees,
+ "x-axis-location-unit", x_axis_location_unit,
+ "y-axis-location-unit", y_axis_location_unit,
+ "screen-width", screen_width,
+ "target", target_box,
+ "length", length,
+ NULL));
+}
diff --git a/animation-glib/glide/glide.h b/animation-glib/glide/glide.h
new file mode 100644
index 0000000..2b2fbb7
--- /dev/null
+++ b/animation-glib/glide/glide.h
@@ -0,0 +1,67 @@
+/*
+ * animation-glib/glide/glide.h
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject Interface for "glide" animation.
+ */
+#pragma once
+
+#include
+
+#include
+#include
+#include
+
+G_BEGIN_DECLS
+
+#define ANIMATION_TYPE_GLIDE_ANIMATION animation_glide_animation_get_type ()
+G_DECLARE_FINAL_TYPE (AnimationGlideAnimation, animation_glide_animation, ANIMATION, GLIDE_ANIMATION, AnimationTransformAnimation)
+
+void animation_glide_animation_set_initial_distance (AnimationGlideAnimation *animation,
+ float initial_distance);
+float animation_glide_animation_get_initial_distance (AnimationGlideAnimation *animation);
+
+void animation_glide_animation_set_x_rotation_angle_degrees (AnimationGlideAnimation *animation,
+ float x_rotation_angle_degrees);
+float animation_glide_animation_get_x_rotation_angle_degrees (AnimationGlideAnimation *animation);
+
+void animation_glide_animation_set_y_rotation_angle_degrees (AnimationGlideAnimation *animation,
+ float y_rotation_angle_degrees);
+float animation_glide_animation_get_y_rotation_angle_degrees (AnimationGlideAnimation *animation);
+
+void animation_glide_animation_set_x_axis_location_unit (AnimationGlideAnimation *animation,
+ float x_axis_location_unit);
+
+float animation_glide_animation_get_x_axis_location_unit (AnimationGlideAnimation *animation);
+void animation_glide_animation_set_y_axis_location_unit (AnimationGlideAnimation *animation,
+ float y_axis_location_unit);
+
+float animation_glide_animation_get_y_axis_location_unit (AnimationGlideAnimation *animation);
+
+void animation_glide_animation_set_stepper (AnimationGlideAnimation *animation,
+ AnimationStepper *stepper);
+AnimationStepper * animation_glide_animation_get_stepper (AnimationGlideAnimation *animation);
+
+AnimationGlideAnimation * animation_glide_new (float initial_distance,
+ float x_rotation_angle_degrees,
+ float y_rotation_angle_degrees,
+ float x_axis_location_unit,
+ float y_axis_location_unit,
+ unsigned int screen_width,
+ const AnimationBox *target_box,
+ unsigned int length);
+
+G_END_DECLS
diff --git a/animation-glib/glide/meson.build b/animation-glib/glide/meson.build
new file mode 100644
index 0000000..d5f1026
--- /dev/null
+++ b/animation-glib/glide/meson.build
@@ -0,0 +1,18 @@
+# /animation/glide/meson.build
+#
+# Build the libanimation library (glide animation component).
+#
+# See /LICENCE.md for Copyright information.
+
+glide_introspectable_sources = files([
+ 'glide.cpp'
+])
+
+glide_headers = files([
+ 'glide.h'
+])
+
+animation_glib_introspectable_sources += glide_introspectable_sources
+animation_glib_headers += glide_headers
+
+install_headers(glide_headers, subdir: join_paths(animation_glib_headers_subdir, 'glide'))
diff --git a/animation-glib/grid/grid.cpp b/animation-glib/grid/grid.cpp
new file mode 100644
index 0000000..2f4881d
--- /dev/null
+++ b/animation-glib/grid/grid.cpp
@@ -0,0 +1,235 @@
+/*
+ * animation-glib/grid/grid.cpp
+ *
+ * Copyright 2018 Endless Mobile, Inc.
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject base class for grid animations.
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+
+namespace agd = animation::geometry::dimension;
+namespace agr = animation::grid;
+
+typedef struct _AnimationGridAnimationPrivate
+{
+ agr::GridAnimation *interface;
+} AnimationGridAnimationPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (AnimationGridAnimation,
+ animation_grid_animation,
+ G_TYPE_OBJECT)
+
+enum {
+ PROP_0,
+ PROP_INTERFACE,
+ NPROPS
+};
+
+static GParamSpec *animation_grid_animation_props [NPROPS] = { NULL, };
+
+gboolean
+animation_grid_animation_step (AnimationGridAnimation *grid_animation,
+ unsigned int ms)
+{
+ AnimationGridAnimationPrivate *priv =
+ reinterpret_cast (animation_grid_animation_get_instance_private (grid_animation));
+
+ return priv->interface->Step (ms);
+}
+
+/**
+ * animation_grid_animation_deform_uv_to_model_space:
+ * @grid_animation: An #AnimationGridAnimation
+ * @uv: An #AnimationVector representing a point in unit coordinate
+ * space to be deformed.
+ * @model_space_point: (out caller-allocates): An #AnimationVector to write
+ * the deformed co-ordinate to.
+ *
+ * Determine where a unit coordinate lies in model space.
+ */
+void
+animation_grid_animation_deform_uv_to_model_space (AnimationGridAnimation *grid_animation,
+ AnimationVector *uv,
+ AnimationVector *model_space_point)
+{
+ AnimationGridAnimationPrivate *priv =
+ reinterpret_cast (animation_grid_animation_get_instance_private (grid_animation));
+
+ g_return_if_fail (model_space_point != NULL);
+
+ animation::Point point (uv->x, uv->y);
+ animation::Point deformed (priv->interface->DeformUVToModelSpace (point));
+
+ model_space_point->x = agd::get <0> (deformed);
+ model_space_point->y = agd::get <1> (deformed);
+}
+
+/**
+ * animation_grid_animation_resolution:
+ * @grid_animation: An #AnimationGridAnimation
+ * @out_resolution: (out caller-allocates): An #AnimationVector specifying the
+ * ideal resolution of the animated surface grid.
+ *
+ * Return the expected grid resolution that would be required to
+ * make this animation look smooth. The renderer should subdivide
+ * the animated surface into this many equal sized chunks.
+ */
+void
+animation_grid_animation_resolution (AnimationGridAnimation *grid_animation,
+ AnimationVector *out_resolution)
+{
+ AnimationGridAnimationPrivate *priv =
+ reinterpret_cast (animation_grid_animation_get_instance_private (grid_animation));
+
+ g_return_if_fail (out_resolution != NULL);
+
+ auto resolution_cpp (priv->interface->Resolution ());
+
+ out_resolution->x = agd::get <0> (resolution_cpp);
+ out_resolution->y = agd::get <1> (resolution_cpp);
+}
+
+/**
+ * animation_grid_animation_extremes:
+ * @grid_animation: A #AnimationGridAnimation
+ * @corners: (array fixed-size=4): The four #AnimationVector4D values
+ * describing the location of the surface corners.
+ * @out_extremes: (array fixed-size=4) (out): The grided four #AnimationVector
+ * values describing the location of the grided surface
+ * surface corners.
+ *
+ * Get the four co-ordinates of a 3D plane which bound the animated surface.
+ */
+void
+animation_grid_animation_extremes (AnimationGridAnimation *grid_animation,
+ AnimationVector const *corners,
+ AnimationVector4D *out_extremes)
+{
+ g_return_if_fail (corners != NULL);
+ g_return_if_fail (out_extremes != NULL);
+
+ AnimationGridAnimationPrivate *priv =
+ reinterpret_cast (animation_grid_animation_get_instance_private (grid_animation));
+
+ std::array points = {
+ animation::Point (corners[0].x, corners[0].y),
+ animation::Point (corners[1].x, corners[1].y),
+ animation::Point (corners[2].x, corners[2].y),
+ animation::Point (corners[3].x, corners[3].y)
+ };
+
+ std::array extremes = priv->interface->Extremes (points);
+
+ agd::assign (out_extremes[0], extremes[0]);
+ agd::assign (out_extremes[1], extremes[1]);
+ agd::assign (out_extremes[2], extremes[2]);
+ agd::assign (out_extremes[3], extremes[3]);
+}
+
+float
+animation_grid_animation_progress (AnimationGridAnimation *grid_animation)
+{
+ AnimationGridAnimationPrivate *priv =
+ reinterpret_cast (animation_grid_animation_get_instance_private (grid_animation));
+
+ return priv->interface->Progress ();
+}
+
+static void
+animation_grid_animation_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ AnimationGridAnimation *grid_animation = ANIMATION_GRID_ANIMATION (object);
+ AnimationGridAnimationPrivate *priv =
+ reinterpret_cast (animation_grid_animation_get_instance_private (grid_animation));
+
+ switch (prop_id)
+ {
+ case PROP_INTERFACE:
+ priv->interface = reinterpret_cast (g_value_get_pointer (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+animation_grid_animation_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ AnimationGridAnimation *grid_animation = ANIMATION_GRID_ANIMATION (object);
+ AnimationGridAnimationPrivate *priv =
+ reinterpret_cast (animation_grid_animation_get_instance_private (grid_animation));
+
+ switch (prop_id)
+ {
+ case PROP_INTERFACE:
+ g_value_set_pointer (value, reinterpret_cast (priv->interface));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+animation_grid_animation_finalize (GObject *object)
+{
+ AnimationGridAnimation *grid_animation = ANIMATION_GRID_ANIMATION (object);
+ AnimationGridAnimationPrivate *priv =
+ reinterpret_cast (animation_grid_animation_get_instance_private (grid_animation));
+
+ delete priv->interface;
+ priv->interface = nullptr;
+
+ G_OBJECT_CLASS (animation_grid_animation_parent_class)->finalize (object);
+}
+
+static void
+animation_grid_animation_init (AnimationGridAnimation *model)
+{
+}
+
+
+static void
+animation_grid_animation_class_init (AnimationGridAnimationClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = animation_grid_animation_get_property;
+ object_class->set_property = animation_grid_animation_set_property;
+ object_class->finalize = animation_grid_animation_finalize;
+
+ animation_grid_animation_props[PROP_INTERFACE] =
+ g_param_spec_pointer ("interface",
+ "Internal Interface",
+ "Internal C++ interface that this class wraps",
+ static_cast (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_properties (object_class,
+ NPROPS,
+ animation_grid_animation_props);
+}
diff --git a/animation-glib/grid/grid.h b/animation-glib/grid/grid.h
new file mode 100644
index 0000000..06afb1b
--- /dev/null
+++ b/animation-glib/grid/grid.h
@@ -0,0 +1,54 @@
+/*
+ * animation-glib/grid/grid.h
+ *
+ * Copyright 2018 Endless Mobile, Inc.
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject base class for grid animations.
+ */
+#pragma once
+
+#include
+
+#include
+#include
+
+G_BEGIN_DECLS
+
+#define ANIMATION_TYPE_GRID_ANIMATION animation_grid_animation_get_type ()
+G_DECLARE_DERIVABLE_TYPE (AnimationGridAnimation, animation_grid_animation, ANIMATION, GRID_ANIMATION, GObject)
+
+struct _AnimationGridAnimationClass {
+ GObjectClass parent_class;
+};
+
+gboolean animation_grid_animation_step (AnimationGridAnimation *grid_animation,
+ unsigned int ms);
+
+float animation_grid_animation_progress (AnimationGridAnimation *grid_animation);
+
+void animation_grid_animation_deform_uv_to_model_space (AnimationGridAnimation *grid_animation,
+ AnimationVector *uv,
+ AnimationVector *model_space_point);
+
+void animation_grid_animation_resolution (AnimationGridAnimation *grid_animation,
+ AnimationVector *out_resolution);
+
+void animation_grid_animation_extremes (AnimationGridAnimation *grid_animation,
+ AnimationVector const *corners,
+ AnimationVector4D *out_extremes);
+
+G_END_DECLS
diff --git a/animation-glib/grid/meson.build b/animation-glib/grid/meson.build
new file mode 100644
index 0000000..d84b1fe
--- /dev/null
+++ b/animation-glib/grid/meson.build
@@ -0,0 +1,32 @@
+# /animation/grid/meson.build
+#
+# Copyright (C) 2017, 2018 Endless Mobile, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Build the libanimation library (grid animation base component GObject interface)
+
+grid_introspectable_sources = files([
+ 'grid.cpp'
+])
+
+grid_headers = files([
+ 'grid.h'
+])
+
+animation_glib_introspectable_sources += grid_introspectable_sources
+animation_glib_headers += grid_headers
+
+install_headers(grid_headers, subdir: join_paths(animation_glib_headers_subdir, 'grid'))
diff --git a/animation-glib/magiclamp/magiclamp.cpp b/animation-glib/magiclamp/magiclamp.cpp
new file mode 100644
index 0000000..eb90b42
--- /dev/null
+++ b/animation-glib/magiclamp/magiclamp.cpp
@@ -0,0 +1,459 @@
+/*
+ * animation-glib/magiclamp/magiclamp.cpp
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject implementation for a "magiclamp" animation.
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace ag = animation::grid;
+namespace agd = animation::geometry::dimension;
+namespace aml = animation::magiclamp;
+
+struct _AnimationMagicLampAnimation
+{
+ AnimationGridAnimation parent_instance;
+};
+
+typedef struct _AnimationMagicLampAnimationPrivate
+{
+} AnimationMagicLampAnimationPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (AnimationMagicLampAnimation,
+ animation_magiclamp_animation,
+ ANIMATION_TYPE_GRID_ANIMATION)
+
+enum {
+ PROP_0,
+ PROP_SOURCE,
+ PROP_TARGET,
+ PROP_RESOLUTION,
+ PROP_BEND_FACTOR,
+ PROP_OFFSET_FACTOR,
+ PROP_STRETCH_FACTOR,
+ PROP_DEFORM_SPEED_FACTOR,
+ PROP_STEPPER,
+ NPROPS
+};
+
+static GParamSpec *animation_magiclamp_animation_props [NPROPS] = { NULL, };
+
+void
+animation_magiclamp_animation_set_source (AnimationMagicLampAnimation *animation,
+ AnimationBox box)
+{
+ LookupTypedInterfaceProp (G_OBJECT (animation))->Source (animation::Box (animation::Point (box.top_left.x,
+ box.top_left.y),
+ animation::Point (box.bottom_right.x,
+ box.bottom_right.y)));
+}
+
+/**
+ * animation_magiclamp_animation_get_source:
+ * @animation: An #AnimationMagicLampAnimation
+ * @out_box: (out caller-allocates): Return location for an #AnimationBox to the source
+ *
+ * Get the source box for this animation.
+ */
+void
+animation_magiclamp_animation_get_source (AnimationMagicLampAnimation *animation,
+ AnimationBox *out_box)
+{
+ g_return_if_fail (out_box != NULL);
+
+ auto box = LookupTypedInterfaceProp (G_OBJECT (animation))->Source ();
+
+ out_box->top_left.x = agd::get <0> (box.topLeft ());
+ out_box->top_left.y = agd::get <1> (box.topLeft ());
+ out_box->bottom_right.x = agd::get <0> (box.bottomRight ());
+ out_box->bottom_right.y = agd::get <1> (box.bottomRight ());
+}
+
+
+/**
+ * animation_magiclamp_animation_get_target:
+ * @animation: An #AnimationMagicLampAnimation
+ * @out_box: (out caller-allocates): Return location for an #AnimationBox to the target
+ *
+ * Get the source box for this animation.
+ */
+void
+animation_magiclamp_animation_get_target (AnimationMagicLampAnimation *animation,
+ AnimationBox *out_box)
+{
+ g_return_if_fail (out_box != NULL);
+
+ auto box = LookupTypedInterfaceProp (G_OBJECT (animation))->Target ();
+
+ out_box->top_left.x = agd::get <0> (box.topLeft ());
+ out_box->top_left.y = agd::get <1> (box.topLeft ());
+ out_box->bottom_right.x = agd::get <0> (box.bottomRight ());
+ out_box->bottom_right.y = agd::get <1> (box.bottomRight ());
+}
+
+void
+animation_magiclamp_animation_set_bend_factor (AnimationMagicLampAnimation *animation,
+ float bend_factor)
+{
+ LookupTypedInterfaceProp (G_OBJECT (animation))->BendFactor (bend_factor);
+}
+
+float
+animation_magiclamp_animation_get_bend_factor (AnimationMagicLampAnimation *animation)
+{
+ return LookupTypedInterfaceProp (G_OBJECT (animation))->BendFactor ();
+}
+
+void
+animation_magiclamp_animation_set_offset_factor (AnimationMagicLampAnimation *animation,
+ float offset_factor)
+{
+ LookupTypedInterfaceProp (G_OBJECT (animation))->OffsetFactor (offset_factor);
+}
+
+float
+animation_magiclamp_animation_get_offset_factor (AnimationMagicLampAnimation *animation)
+{
+ return LookupTypedInterfaceProp (G_OBJECT (animation))->OffsetFactor ();
+}
+
+void
+animation_magiclamp_animation_set_stretch_factor (AnimationMagicLampAnimation *animation,
+ float stretch_factor)
+{
+ LookupTypedInterfaceProp (G_OBJECT (animation))->StretchFactor (stretch_factor);
+}
+
+float
+animation_magiclamp_animation_get_stretch_factor (AnimationMagicLampAnimation *animation)
+{
+ return LookupTypedInterfaceProp (G_OBJECT (animation))->StretchFactor ();
+}
+
+void
+animation_magiclamp_animation_set_deform_speed_factor (AnimationMagicLampAnimation *animation,
+ float deform_speed_factor)
+{
+ LookupTypedInterfaceProp (G_OBJECT (animation))->DeformSpeedFactor (deform_speed_factor);
+}
+
+float
+animation_magiclamp_animation_get_deform_speed_factor (AnimationMagicLampAnimation *animation)
+{
+ return LookupTypedInterfaceProp (G_OBJECT (animation))->DeformSpeedFactor ();
+}
+
+void
+animation_magiclamp_animation_set_stepper (AnimationMagicLampAnimation *animation,
+ AnimationStepper *stepper)
+{
+ animation::stepper::Stepper *stepper_ptr = nullptr;
+ g_object_get (stepper, "stepper", (gpointer) &stepper_ptr, NULL);
+
+ LookupTypedInterfaceProp (G_OBJECT (animation))->Stepper (*stepper_ptr);
+}
+
+/**
+ * animation_magiclamp_animation_get_stepper:
+ * @animation: An #AnimationMagicLampAnimation
+ *
+ * Returns: (transfer full): Get the stepper for this #AnimationMagicLampAnimation
+ */
+AnimationStepper *
+animation_magiclamp_animation_get_stepper (AnimationMagicLampAnimation *animation)
+{
+ auto const &stepper (LookupTypedInterfaceProp (G_OBJECT (animation))->Stepper ());
+
+ return animation_stepper_wrapper_new ((gpointer) &stepper);
+}
+
+static void
+animation_magiclamp_animation_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ AnimationMagicLampAnimation *magiclamp_animation = ANIMATION_MAGIC_LAMP_ANIMATION (object);
+
+ switch (prop_id)
+ {
+ case PROP_SOURCE:
+ {
+ AnimationBox *box = reinterpret_cast (g_value_get_boxed (value));
+
+ if (box != nullptr)
+ animation_magiclamp_animation_set_source (magiclamp_animation, *box);
+ }
+ break;
+ case PROP_TARGET:
+ /* Not writable, except on construction */
+ break;
+ case PROP_RESOLUTION:
+ /* Not writable, except on construction */
+ break;
+ case PROP_BEND_FACTOR:
+ animation_magiclamp_animation_set_bend_factor (magiclamp_animation, g_value_get_float (value));
+ break;
+ case PROP_OFFSET_FACTOR:
+ animation_magiclamp_animation_set_offset_factor (magiclamp_animation, g_value_get_float (value));
+ break;
+ case PROP_STRETCH_FACTOR:
+ animation_magiclamp_animation_set_stretch_factor (magiclamp_animation, g_value_get_float (value));
+ break;
+ case PROP_DEFORM_SPEED_FACTOR:
+ animation_magiclamp_animation_set_deform_speed_factor (magiclamp_animation, g_value_get_float (value));
+ break;
+ case PROP_STEPPER:
+ animation_magiclamp_animation_set_stepper (magiclamp_animation,
+ ANIMATION_STEPPER (g_value_get_object (value)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+animation_magiclamp_animation_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ AnimationMagicLampAnimation *magiclamp_animation = ANIMATION_MAGIC_LAMP_ANIMATION (object);
+
+ switch (prop_id)
+ {
+ case PROP_SOURCE:
+ {
+ AnimationBox box;
+
+ animation_magiclamp_animation_get_source (magiclamp_animation, &box);
+ g_value_set_boxed (value, (gpointer) &box);
+ }
+ break;
+ case PROP_TARGET:
+ {
+ AnimationBox box;
+
+ animation_magiclamp_animation_get_target (magiclamp_animation, &box);
+ g_value_set_boxed (value, (gpointer) &box);
+ }
+ break;
+ case PROP_BEND_FACTOR:
+ g_value_set_float (value, animation_magiclamp_animation_get_bend_factor (magiclamp_animation));
+ break;
+ case PROP_STRETCH_FACTOR:
+ g_value_set_float (value, animation_magiclamp_animation_get_stretch_factor (magiclamp_animation));
+ break;
+ case PROP_OFFSET_FACTOR:
+ g_value_set_float (value, animation_magiclamp_animation_get_offset_factor (magiclamp_animation));
+ break;
+ case PROP_DEFORM_SPEED_FACTOR:
+ g_value_set_float (value, animation_magiclamp_animation_get_deform_speed_factor (magiclamp_animation));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static GObject *
+animation_magiclamp_animation_constructor (GType type,
+ unsigned int n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ replace_named_pointer_prop_in_construct_params_if_null (construct_params,
+ n_construct_params,
+ "stepper",
+ g_value_get_object,
+ g_value_set_object,
+ []() -> gpointer {
+ return animation_linear_stepper_new (300);
+ });
+
+ /* Need to have a grid resolution */
+ replace_named_pointer_prop_in_construct_params_if_null (construct_params,
+ n_construct_params,
+ "resolution",
+ g_value_get_boxed,
+ (AnimationConstructorHelpersGValueSetPointerFunc) g_value_set_boxed,
+ []() -> gpointer {
+ AnimationVector *v = g_new0 (AnimationVector, 1);
+
+ v->x = 10.0;
+ v->y = 10.0;
+
+ return (gpointer) v;
+ });
+
+ const char * const wanted_properties[] = {
+ "source",
+ "target",
+ "resolution",
+ "bend-factor",
+ "offset-factor",
+ "stretch-factor",
+ "deform-speed-factor",
+ "stepper",
+ NULL
+ };
+ g_autoptr(GHashTable) properties_table =
+ static_hash_table_of_values_for_specs (wanted_properties,
+ construct_params,
+ n_construct_params);
+
+ auto *interface =
+ static_cast (InterfaceConstructor ::construct (
+ ForwardFromValueHT (properties_table, animation_box_from_gvalue, "source"),
+ ForwardFromValueHT (properties_table, animation_box_from_gvalue, "target"),
+ ForwardFromValueHT (properties_table, animation_point_size_t_from_gvalue, "resolution"),
+ ForwardFromValueHT (properties_table, g_value_get_float, "bend-factor"),
+ ForwardFromValueHT (properties_table, g_value_get_float, "offset-factor"),
+ ForwardFromValueHT (properties_table, g_value_get_float, "stretch-factor"),
+ ForwardFromValueHT (properties_table, g_value_get_float, "deform-speed-factor"),
+ ForwardFromValueHT (properties_table, animation_stepper_from_gvalue, "stepper")
+ ));
+
+ replace_interface_prop_in_construct_params (construct_params,
+ n_construct_params,
+ g_steal_pointer (&interface));
+
+ return G_OBJECT_CLASS (animation_magiclamp_animation_parent_class)->constructor (type,
+ n_construct_params,
+ construct_params);
+}
+
+static void
+animation_magiclamp_animation_init (AnimationMagicLampAnimation *model)
+{
+}
+
+
+static void
+animation_magiclamp_animation_class_init (AnimationMagicLampAnimationClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructor = animation_magiclamp_animation_constructor;
+ object_class->get_property = animation_magiclamp_animation_get_property;
+ object_class->set_property = animation_magiclamp_animation_set_property;
+
+ animation_magiclamp_animation_props[PROP_SOURCE] =
+ g_param_spec_boxed ("source",
+ "Source Box",
+ "Box that we are animating from",
+ ANIMATION_TYPE_BOX,
+ static_cast (G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ animation_magiclamp_animation_props[PROP_TARGET] =
+ g_param_spec_boxed ("target",
+ "Target Box",
+ "Box that we are animating to",
+ ANIMATION_TYPE_BOX,
+ static_cast (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ animation_magiclamp_animation_props[PROP_RESOLUTION] =
+ g_param_spec_boxed ("resolution",
+ "Resolution",
+ "Grid Resolution",
+ ANIMATION_TYPE_VECTOR,
+ static_cast (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
+ animation_magiclamp_animation_props[PROP_BEND_FACTOR] =
+ g_param_spec_float ("bend-factor",
+ "Bend Factor",
+ "How much the window should bend",
+ 1.0,
+ 20.0,
+ 10.0,
+ static_cast (G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ animation_magiclamp_animation_props[PROP_OFFSET_FACTOR] =
+ g_param_spec_float ("offset-factor",
+ "Offset Factor",
+ "How big the curves of the animation should be",
+ 0.1,
+ 1.0,
+ 0.5,
+ static_cast (G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ animation_magiclamp_animation_props[PROP_STRETCH_FACTOR] =
+ g_param_spec_float ("stretch-factor",
+ "Stretch Factor",
+ "How much the window should stretch when animating",
+ 0.2,
+ 1.0,
+ 0.45,
+ static_cast (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
+ animation_magiclamp_animation_props[PROP_DEFORM_SPEED_FACTOR] =
+ g_param_spec_float ("deform-speed-factor",
+ "Deform Speed Factor",
+ "How quickly the deformation phase should happen",
+ 1.0,
+ 4.0,
+ 2.3,
+ static_cast (G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ animation_magiclamp_animation_props[PROP_STEPPER] =
+ g_param_spec_object ("stepper",
+ "Stepper",
+ "Stepper to use to progress the animation",
+ ANIMATION_TYPE_STEPPER,
+ static_cast (G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ g_object_class_install_properties (object_class,
+ NPROPS,
+ animation_magiclamp_animation_props);
+}
+
+/**
+ * animation_magiclamp_new:
+ * @source_box: The #AnimationBox that we are animating from.
+ * @target_box: The #AnimationBox that we are animating to.
+ * @resolution: The #AnimationVector representing the grid resolution
+ * @bend_factor: How much the window should bend
+ * @offset_factor: How big the curves of the animation should be
+ * @deform_speed_factor: How quickly the deformation should complete.
+ * @stepper: An #AnimationStepper used for progressing the animation.
+ *
+ * Returns: (transfer full): A new #AnimationMagicLampAnimation.
+ */
+AnimationMagicLampAnimation *
+animation_magiclamp_new (const AnimationBox *source_box,
+ const AnimationBox *target_box,
+ const AnimationVector *resolution,
+ float bend_factor,
+ float offset_factor,
+ float stretch_factor,
+ float deform_speed_factor,
+ AnimationStepper *stepper)
+{
+ return ANIMATION_MAGIC_LAMP_ANIMATION (g_object_new (ANIMATION_TYPE_MAGIC_LAMP_ANIMATION,
+ "source", source_box,
+ "target", target_box,
+ "resolution", resolution,
+ "stepper", stepper,
+ NULL));
+}
diff --git a/animation-glib/magiclamp/magiclamp.h b/animation-glib/magiclamp/magiclamp.h
new file mode 100644
index 0000000..ec59f99
--- /dev/null
+++ b/animation-glib/magiclamp/magiclamp.h
@@ -0,0 +1,71 @@
+/*
+ * animation-glib/magiclamp/magiclamp.h
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject Interface for "magiclamp" animation.
+ */
+#pragma once
+
+#include
+
+#include
+#include
+#include
+#include
+
+G_BEGIN_DECLS
+
+#define ANIMATION_TYPE_MAGIC_LAMP_ANIMATION animation_magiclamp_animation_get_type ()
+G_DECLARE_FINAL_TYPE (AnimationMagicLampAnimation, animation_magiclamp_animation, ANIMATION, MAGIC_LAMP_ANIMATION, AnimationGridAnimation)
+
+void animation_magiclamp_animation_set_source (AnimationMagicLampAnimation *animation,
+ AnimationBox box);
+void animation_magiclamp_animation_get_source (AnimationMagicLampAnimation *animation,
+ AnimationBox *out_box);
+
+void animation_magiclamp_animation_get_target (AnimationMagicLampAnimation *animation,
+ AnimationBox *out_box);
+
+void animation_magiclamp_animation_set_bend_factor (AnimationMagicLampAnimation *animation,
+ float bend_factor);
+float animation_magiclamp_animation_get_bend_factor (AnimationMagicLampAnimation *animation);
+
+void animation_magiclamp_animation_set_offset_factor (AnimationMagicLampAnimation *animation,
+ float offset_factor);
+float animation_magiclamp_animation_get_offset_factor (AnimationMagicLampAnimation *animation);
+
+void animation_magiclamp_animation_set_stretch_factor (AnimationMagicLampAnimation *animation,
+ float stretch_factor);
+float animation_magiclamp_animation_get_stretch_factor (AnimationMagicLampAnimation *animation);
+
+void animation_magiclamp_animation_set_deform_speed_factor (AnimationMagicLampAnimation *animation,
+ float deform_speed_factor);
+float animation_magiclamp_animation_get_deform_speed_factor (AnimationMagicLampAnimation *animation);
+
+void animation_magiclamp_animation_set_stepper (AnimationMagicLampAnimation *animation,
+ AnimationStepper *stepper);
+AnimationStepper * animation_magiclamp_animation_get_stepper (AnimationMagicLampAnimation *animation);
+
+AnimationMagicLampAnimation * animation_magiclamp_new (const AnimationBox *source_box,
+ const AnimationBox *target_box,
+ const AnimationVector *resolution,
+ float bend_factor,
+ float offset_factor,
+ float stretch_factor,
+ float deform_speed_factor,
+ AnimationStepper *stepper);
+
+G_END_DECLS
diff --git a/animation-glib/magiclamp/meson.build b/animation-glib/magiclamp/meson.build
new file mode 100644
index 0000000..ba8e089
--- /dev/null
+++ b/animation-glib/magiclamp/meson.build
@@ -0,0 +1,18 @@
+# /animation/magiclamp/meson.build
+#
+# Build the libanimation library (magiclamp animation component).
+#
+# See /LICENCE.md for Copyright information.
+
+magiclamp_introspectable_sources = files([
+ 'magiclamp.cpp'
+])
+
+magiclamp_headers = files([
+ 'magiclamp.h'
+])
+
+animation_glib_introspectable_sources += magiclamp_introspectable_sources
+animation_glib_headers += magiclamp_headers
+
+install_headers(magiclamp_headers, subdir: join_paths(animation_glib_headers_subdir, 'magiclamp'))
diff --git a/animation-glib/meson.build b/animation-glib/meson.build
index fb997bb..a34de9f 100644
--- a/animation-glib/meson.build
+++ b/animation-glib/meson.build
@@ -20,18 +20,48 @@
api_version = '0'
-animation_glib_toplevel_headers = ['vector.h']
-animation_glib_toplevel_introspectable_sources = ['vector.cpp']
+animation_glib_toplevel_headers = files([
+ 'box.h',
+ 'vector.h'
+])
+animation_glib_toplevel_introspectable_sources = files([
+ 'box.cpp',
+ 'vector.cpp',
+ 'vector.h',
+ 'vector4d.h'
+])
+animation_glib_toplevel_private_headers = files([
+ 'constructor-helpers.h',
+ 'vector4d-internal.h'
+])
+animation_glib_toplevel_private_sources = files([
+ 'constructor-helpers.cpp'
+])
+animation_glib_toplevel_introspectable_sources = files([
+ 'box.cpp',
+ 'vector.cpp',
+ 'vector4d.cpp'
+])
-animation_glib_introspectable_sources = []
-animation_glib_private_sources = []
-animation_glib_headers = []
+animation_glib_introspectable_sources = files([])
+animation_glib_private_headers = files([])
+animation_glib_private_sources = files([])
+animation_glib_headers = files([])
animation_glib_headers_subdir = 'animation-glib'
+subdir('bounce')
+subdir('glide')
+subdir('grid')
+subdir('stepper')
+subdir('magiclamp')
+subdir('transform')
subdir('wobbly')
+subdir('zoom')
-animation_glib_introspectable_sources += files(animation_glib_toplevel_introspectable_sources)
-animation_glib_headers += files(animation_glib_toplevel_headers)
+animation_glib_introspectable_sources += animation_glib_toplevel_introspectable_sources
+animation_glib_private_sources += animation_glib_toplevel_private_sources
+animation_glib_headers += animation_glib_toplevel_headers
+animation_glib_private_headers += animation_glib_toplevel_private_headers
install_headers(animation_glib_toplevel_headers, subdir: animation_glib_headers_subdir)
diff --git a/animation-glib/stepper/linear.cpp b/animation-glib/stepper/linear.cpp
new file mode 100644
index 0000000..a2411b0
--- /dev/null
+++ b/animation-glib/stepper/linear.cpp
@@ -0,0 +1,151 @@
+/*
+ * animation-glib/stepper/linear.cpp
+ *
+ * Copyright 2018 Endless Mobile, Inc.
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject wrapper for linear stepper.
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+
+namespace as = animation::stepper;
+
+struct _AnimationLinearStepper
+{
+ GObject parent_instance;
+};
+
+typedef struct _AnimationLinearStepperPrivate
+{
+} AnimationLinearStepperPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (AnimationLinearStepper,
+ animation_linear_stepper,
+ ANIMATION_TYPE_STEPPER_HOLDER)
+
+enum {
+ PROP_0,
+ PROP_LENGTH,
+ NPROPS
+};
+
+static GParamSpec *animation_linear_stepper_properties[NPROPS];
+
+static void
+animation_linear_stepper_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id)
+ {
+ case PROP_LENGTH:
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+animation_linear_stepper_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static GObject *
+animation_linear_stepper_constructor (GType type,
+ unsigned int n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ const char * const wanted_properties[] = {
+ "length",
+ NULL
+ };
+ g_autoptr(GHashTable) properties_table =
+ static_hash_table_of_values_for_specs (wanted_properties,
+ construct_params,
+ n_construct_params);
+
+ auto stepper = as::Linear (ForwardFromValueHT (properties_table, g_value_get_uint, "length"));
+
+ replace_named_pointer_prop_in_construct_params (construct_params,
+ n_construct_params,
+ "stepper",
+ &stepper);
+
+ return G_OBJECT_CLASS (animation_linear_stepper_parent_class)->constructor (type,
+ n_construct_params,
+ construct_params);
+}
+
+static void
+animation_linear_stepper_init (AnimationLinearStepper *model)
+{
+}
+
+static void
+animation_linear_stepper_class_init (AnimationLinearStepperClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructor = animation_linear_stepper_constructor;
+ object_class->get_property = animation_linear_stepper_get_property;
+ object_class->set_property = animation_linear_stepper_set_property;
+
+ animation_linear_stepper_properties[PROP_LENGTH] =
+ g_param_spec_uint ("length",
+ "Length",
+ "How long the animation lasts",
+ 1,
+ 5000,
+ 300,
+ static_cast (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_properties (object_class,
+ NPROPS,
+ animation_linear_stepper_properties);
+}
+
+/**
+ * animation_linear_stepper_new:
+ * @length: Length of the transition in milliseconds.
+ *
+ * Return a new #AnimationStepper which linearly increments progress
+ * every time the step() method is called on it.
+ *
+ * Returns: (transfer full): An #AnimationLinearStepper
+ * implementation of #AnimationStepper
+ */
+AnimationStepper *
+animation_linear_stepper_new (unsigned int length)
+{
+ return ANIMATION_STEPPER (g_object_new (ANIMATION_TYPE_LINEAR_STEPPER,
+ "length", length,
+ NULL));
+}
diff --git a/animation-glib/stepper/linear.h b/animation-glib/stepper/linear.h
new file mode 100644
index 0000000..1c83c5f
--- /dev/null
+++ b/animation-glib/stepper/linear.h
@@ -0,0 +1,36 @@
+/*
+ * animation-glib/stepper/linear.h
+ *
+ * Copyright 2018 Endless Mobile, Inc.
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject class for linear stepper.
+ */
+#pragma once
+
+#include
+
+#include
+#include
+
+G_BEGIN_DECLS
+
+#define ANIMATION_TYPE_LINEAR_STEPPER animation_linear_stepper_get_type ()
+G_DECLARE_FINAL_TYPE (AnimationLinearStepper, animation_linear_stepper, ANIMATION, LINEAR_STEPPER, AnimationStepperHolder)
+
+AnimationStepper * animation_linear_stepper_new (unsigned int length);
+
+G_END_DECLS
diff --git a/animation-glib/stepper/meson.build b/animation-glib/stepper/meson.build
new file mode 100644
index 0000000..8eb30b1
--- /dev/null
+++ b/animation-glib/stepper/meson.build
@@ -0,0 +1,42 @@
+# /animation/stepper/meson.build
+#
+# Meson build file for libanimation stepper GObject classes.
+#
+# Copyright (C) 2017, 2018 Endless Mobile, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Build the libanimation library (stepper base component)
+
+stepper_introspectable_sources = files([
+ 'linear.cpp',
+ 'reverse.cpp',
+ 'stepper.cpp',
+ 'stepper-holder.cpp',
+ 'stepper-wrapper.cpp'
+])
+
+stepper_headers = files([
+ 'linear.h',
+ 'reverse.h',
+ 'stepper.h',
+ 'stepper-holder.h',
+ 'stepper-wrapper.h'
+])
+
+animation_glib_introspectable_sources += stepper_introspectable_sources
+animation_glib_headers += stepper_headers
+
+install_headers(stepper_headers, subdir: join_paths(animation_glib_headers_subdir, 'stepper'))
diff --git a/animation-glib/stepper/reverse.cpp b/animation-glib/stepper/reverse.cpp
new file mode 100644
index 0000000..30f7a4f
--- /dev/null
+++ b/animation-glib/stepper/reverse.cpp
@@ -0,0 +1,173 @@
+/*
+ * animation-glib/stepper/reverse.cpp
+ *
+ * Copyright 2018 Endless Mobile, Inc.
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject wrapper for reverse stepper.
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+
+namespace as = animation::stepper;
+
+struct _AnimationReverseStepper
+{
+ GObject parent_instance;
+};
+
+typedef struct _AnimationReverseStepperPrivate
+{
+ AnimationStepper *base_stepper;
+} AnimationReverseStepperPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (AnimationReverseStepper,
+ animation_reverse_stepper,
+ ANIMATION_TYPE_STEPPER_HOLDER)
+
+enum {
+ PROP_0,
+ PROP_BASE_STEPPER,
+ NPROPS
+};
+
+static GParamSpec *animation_reverse_stepper_properties[NPROPS];
+
+static void
+animation_reverse_stepper_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ AnimationReverseStepper *stepper = ANIMATION_REVERSE_STEPPER (object);
+ AnimationReverseStepperPrivate *priv =
+ reinterpret_cast (animation_reverse_stepper_get_instance_private (stepper));
+
+ switch (prop_id)
+ {
+ case PROP_BASE_STEPPER:
+ priv->base_stepper = ANIMATION_STEPPER (g_value_dup_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+animation_reverse_stepper_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ AnimationReverseStepper *stepper = ANIMATION_REVERSE_STEPPER (object);
+ AnimationReverseStepperPrivate *priv =
+ reinterpret_cast (animation_reverse_stepper_get_instance_private (stepper));
+
+ switch (prop_id)
+ {
+ case PROP_BASE_STEPPER:
+ g_value_set_object (value, G_OBJECT (priv->base_stepper));
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+animation_reverse_stepper_dispose (GObject *object)
+{
+ AnimationReverseStepper *stepper = ANIMATION_REVERSE_STEPPER (object);
+ AnimationReverseStepperPrivate *priv =
+ reinterpret_cast (animation_reverse_stepper_get_instance_private (stepper));
+
+ g_clear_object (&priv->base_stepper);
+}
+
+static GObject *
+animation_reverse_stepper_constructor (GType type,
+ unsigned int n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ const char * const wanted_properties[] = {
+ "base-stepper",
+ NULL
+ };
+ g_autoptr(GHashTable) properties_table =
+ static_hash_table_of_values_for_specs (wanted_properties,
+ construct_params,
+ n_construct_params);
+
+ auto stepper = as::Reverse (ForwardFromValueHT (properties_table,
+ animation_stepper_from_gvalue,
+ "base-stepper"));
+
+ replace_named_pointer_prop_in_construct_params (construct_params,
+ n_construct_params,
+ "stepper",
+ &stepper);
+
+ return G_OBJECT_CLASS (animation_reverse_stepper_parent_class)->constructor (type,
+ n_construct_params,
+ construct_params);
+}
+
+static void
+animation_reverse_stepper_init (AnimationReverseStepper *model)
+{
+}
+
+static void
+animation_reverse_stepper_class_init (AnimationReverseStepperClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructor = animation_reverse_stepper_constructor;
+ object_class->get_property = animation_reverse_stepper_get_property;
+ object_class->set_property = animation_reverse_stepper_set_property;
+ object_class->dispose = animation_reverse_stepper_dispose;
+
+ animation_reverse_stepper_properties[PROP_BASE_STEPPER] =
+ g_param_spec_object ("base-stepper",
+ "Base Stepper",
+ "Stepper to reverse",
+ ANIMATION_TYPE_STEPPER,
+ static_cast (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_properties (object_class,
+ NPROPS,
+ animation_reverse_stepper_properties);
+}
+
+/**
+ * animation_reverse_stepper_new:
+ * @base_stepper: The stepper to reverse.
+ *
+ * Return a new #AnimationStepper which runs @base_stepper in reverse.
+ *
+ * Returns: (transfer full): An #AnimationReverseStepper
+ * implementation of #AnimationStepper
+ */
+AnimationStepper *
+animation_reverse_stepper_new (AnimationStepper *base_stepper)
+{
+ return ANIMATION_STEPPER (g_object_new (ANIMATION_TYPE_REVERSE_STEPPER,
+ "base-stepper", base_stepper,
+ NULL));
+}
diff --git a/animation-glib/stepper/reverse.h b/animation-glib/stepper/reverse.h
new file mode 100644
index 0000000..0a4f625
--- /dev/null
+++ b/animation-glib/stepper/reverse.h
@@ -0,0 +1,36 @@
+/*
+ * animation-glib/stepper/reverse.h
+ *
+ * Copyright 2018 Endless Mobile, Inc.
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject class for reverse stepper.
+ */
+#pragma once
+
+#include
+
+#include
+#include
+
+G_BEGIN_DECLS
+
+#define ANIMATION_TYPE_REVERSE_STEPPER animation_reverse_stepper_get_type ()
+G_DECLARE_FINAL_TYPE (AnimationReverseStepper, animation_reverse_stepper, ANIMATION, REVERSE_STEPPER, AnimationStepperHolder)
+
+AnimationStepper * animation_reverse_stepper_new (AnimationStepper *base_stepper);
+
+G_END_DECLS
diff --git a/animation-glib/stepper/stepper-holder.cpp b/animation-glib/stepper/stepper-holder.cpp
new file mode 100644
index 0000000..d51db15
--- /dev/null
+++ b/animation-glib/stepper/stepper-holder.cpp
@@ -0,0 +1,196 @@
+/*
+ * animation-glib/stepper/stepper-holder.cpp
+ *
+ * Copyright 2018 Endless Mobile, Inc.
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject base class for steppers. Copies the stepper
+ * passed to it in its construct parameters.
+ */
+
+#include
+#include
+
+#include
+#include
+
+namespace as = animation::stepper;
+
+struct _AnimationStepperHolder
+{
+ GObject parent_instance;
+};
+
+typedef struct _AnimationStepperHolderPrivate
+{
+ as::Stepper *stepper;
+} AnimationStepperHolderPrivate;
+
+static void animation_stepper_iface_init (AnimationStepperInterface *stepper_iface);
+
+G_DEFINE_TYPE_WITH_CODE (AnimationStepperHolder,
+ animation_stepper_holder,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (ANIMATION_TYPE_STEPPER, animation_stepper_iface_init)
+ G_ADD_PRIVATE (AnimationStepperHolder))
+
+enum {
+ PROP_0,
+ PROP_STEPPER,
+ NPROPS
+};
+
+static float
+animation_stepper_holder_step (AnimationStepper *stepper,
+ unsigned int ms)
+{
+ AnimationStepperHolderPrivate *priv =
+ reinterpret_cast (animation_stepper_holder_get_instance_private (ANIMATION_STEPPER_HOLDER (stepper)));
+
+ return (*priv->stepper) (ms);
+}
+
+template
+static T *
+copy_ptr_if_set (T *ptr)
+{
+ if (ptr != nullptr)
+ return new T (*ptr);
+
+ return nullptr;
+}
+
+static void
+animation_stepper_holder_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ AnimationStepperHolder *holder = ANIMATION_STEPPER_HOLDER (object);
+ AnimationStepperHolderPrivate *priv =
+ reinterpret_cast (animation_stepper_holder_get_instance_private (holder));
+
+ switch (prop_id)
+ {
+ case PROP_STEPPER:
+ /* We need to copy-construct here as the property is
+ * not transfer full. */
+ priv->stepper = copy_ptr_if_set (reinterpret_cast (g_value_get_pointer (value)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+animation_stepper_holder_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ AnimationStepperHolder *holder = ANIMATION_STEPPER_HOLDER (object);
+ AnimationStepperHolderPrivate *priv =
+ reinterpret_cast (animation_stepper_holder_get_instance_private (holder));
+
+ switch (prop_id)
+ {
+ case PROP_STEPPER:
+ g_value_set_pointer (value, reinterpret_cast (priv->stepper));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+animation_stepper_holder_finalize (GObject *object)
+{
+ AnimationStepperHolder *holder = ANIMATION_STEPPER_HOLDER (object);
+ AnimationStepperHolderPrivate *priv =
+ reinterpret_cast (animation_stepper_holder_get_instance_private (holder));
+
+ delete priv->stepper;
+ priv->stepper = nullptr;
+
+ G_OBJECT_CLASS (animation_stepper_holder_parent_class)->finalize (object);
+}
+
+static GObject *
+animation_stepper_holder_constructor (GType type,
+ unsigned int n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ auto defaultStepperHolder = as::Linear (300);
+
+ /* Check the passed stepper_holder prop to ensure that it is set. If not,
+ * then we need to set it to some sensible default value. */
+ for (unsigned int i = 0; i < n_construct_params; ++i)
+ {
+ if (g_strcmp0 (construct_params[i].pspec->name, "stepper") == 0)
+ {
+ if (g_value_get_pointer (construct_params[i].value) == nullptr)
+ g_value_set_pointer (construct_params[i].value, &defaultStepperHolder);
+ }
+ }
+
+ return G_OBJECT_CLASS (animation_stepper_holder_parent_class)->constructor (type,
+ n_construct_params,
+ construct_params);
+}
+
+static void
+animation_stepper_holder_init (AnimationStepperHolder *stepper_holder)
+{
+}
+
+static void
+animation_stepper_iface_init (AnimationStepperInterface *interface)
+{
+ interface->step = animation_stepper_holder_step;
+}
+
+static void
+animation_stepper_holder_class_init (AnimationStepperHolderClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructor = animation_stepper_holder_constructor;
+ object_class->get_property = animation_stepper_holder_get_property;
+ object_class->set_property = animation_stepper_holder_set_property;
+ object_class->finalize = animation_stepper_holder_finalize;
+
+ g_object_class_override_property (object_class,
+ PROP_STEPPER,
+ "stepper");
+}
+
+/**
+ * animation_stepper_holder_new: (skip):
+ * @interface: A pointer to an interlying stepper implementation.
+ *
+ * Create a new #AnimationStepperHolder, an implementation of
+ * #AnimationStepper which copies the underlying stepper when it
+ * is constructed (thus resetting its internal state, as copying
+ * a C++ lambda default-constructs its closure).
+ *
+ * Returns: (transfer full): A new #AnimationStepper with the underlying
+ * stepper copied.
+ */
+AnimationStepper *
+animation_stepper_holder_new (gpointer interface)
+{
+ return ANIMATION_STEPPER (g_object_new (ANIMATION_TYPE_STEPPER_HOLDER, "stepper", interface, NULL));
+}
diff --git a/animation-glib/stepper/stepper-holder.h b/animation-glib/stepper/stepper-holder.h
new file mode 100644
index 0000000..967ce28
--- /dev/null
+++ b/animation-glib/stepper/stepper-holder.h
@@ -0,0 +1,36 @@
+/*
+ * animation-glib/stepper/stepper-holder.h
+ *
+ * Copyright 2018 Endless Mobile, Inc.
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject base class for steppers, which holds a copy of a stepper.
+ */
+#pragma once
+
+#include
+
+#include
+#include
+
+G_BEGIN_DECLS
+
+#define ANIMATION_TYPE_STEPPER_HOLDER animation_stepper_holder_get_type ()
+G_DECLARE_FINAL_TYPE (AnimationStepperHolder, animation_stepper_holder, ANIMATION, STEPPER_HOLDER, GObject)
+
+AnimationStepper * animation_stepper_holder_new (gpointer interface);
+
+G_END_DECLS
diff --git a/animation-glib/stepper/stepper-wrapper.cpp b/animation-glib/stepper/stepper-wrapper.cpp
new file mode 100644
index 0000000..830b0bd
--- /dev/null
+++ b/animation-glib/stepper/stepper-wrapper.cpp
@@ -0,0 +1,160 @@
+/*
+ * animation-glib/stepper/stepper-wrapper.cpp
+ *
+ * Copyright 2018 Endless Mobile, Inc.
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject base class for steppers. Only observes the stepper passed
+ * to it in its construct parameters - not expected to outlive the stepper.
+ */
+
+#include
+#include
+
+#include
+#include
+
+namespace as = animation::stepper;
+
+struct _AnimationStepperWrapper
+{
+ GObject parent_instance;
+};
+
+typedef struct _AnimationStepperWrapperPrivate
+{
+ as::Stepper *stepper;
+} AnimationStepperWrapperPrivate;
+
+static void animation_stepper_iface_init (AnimationStepperInterface *stepper_iface);
+
+G_DEFINE_TYPE_WITH_CODE (AnimationStepperWrapper,
+ animation_stepper_wrapper,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (ANIMATION_TYPE_STEPPER, animation_stepper_iface_init)
+ G_ADD_PRIVATE (AnimationStepperWrapper))
+
+enum {
+ PROP_0,
+ PROP_STEPPER,
+ NPROPS
+};
+
+static float
+animation_stepper_wrapper_step (AnimationStepper *stepper,
+ unsigned int ms)
+{
+ AnimationStepperWrapperPrivate *priv =
+ reinterpret_cast (animation_stepper_wrapper_get_instance_private (ANIMATION_STEPPER_WRAPPER (stepper)));
+
+ return (*priv->stepper) (ms);
+}
+
+static void
+animation_stepper_wrapper_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ AnimationStepperWrapper *holder = ANIMATION_STEPPER_WRAPPER (object);
+ AnimationStepperWrapperPrivate *priv =
+ reinterpret_cast (animation_stepper_wrapper_get_instance_private (holder));
+
+ switch (prop_id)
+ {
+ case PROP_STEPPER:
+ priv->stepper = reinterpret_cast (g_value_get_pointer (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+animation_stepper_wrapper_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ AnimationStepperWrapper *holder = ANIMATION_STEPPER_WRAPPER (object);
+ AnimationStepperWrapperPrivate *priv =
+ reinterpret_cast (animation_stepper_wrapper_get_instance_private (holder));
+
+ switch (prop_id)
+ {
+ case PROP_STEPPER:
+ g_value_set_pointer (value, reinterpret_cast (priv->stepper));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+animation_stepper_wrapper_finalize (GObject *object)
+{
+ AnimationStepperWrapper *holder = ANIMATION_STEPPER_WRAPPER (object);
+ AnimationStepperWrapperPrivate *priv =
+ reinterpret_cast (animation_stepper_wrapper_get_instance_private (holder));
+
+ delete priv->stepper;
+ priv->stepper = nullptr;
+
+ G_OBJECT_CLASS (animation_stepper_wrapper_parent_class)->finalize (object);
+}
+
+static void
+animation_stepper_wrapper_init (AnimationStepperWrapper *stepper_wrapper)
+{
+}
+
+static void
+animation_stepper_iface_init (AnimationStepperInterface *interface)
+{
+ interface->step = animation_stepper_wrapper_step;
+}
+
+static void
+animation_stepper_wrapper_class_init (AnimationStepperWrapperClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = animation_stepper_wrapper_get_property;
+ object_class->set_property = animation_stepper_wrapper_set_property;
+ object_class->finalize = animation_stepper_wrapper_finalize;
+
+ g_object_class_override_property (object_class,
+ PROP_STEPPER,
+ "stepper");
+}
+
+/**
+ * animation_stepper_wrapper_new: (skip):
+ * @interface: A pointer to an interlying stepper implementation.
+ *
+ * Create a new #AnimationStepperWrapper, an implementation of
+ * #AnimationStepper which only observes the underlying stepper when it
+ * is constructed (keeping its internal state). However, the wrapper
+ * must not outlive the underlying stepper.
+ *
+ * Returns: (transfer full): A new #AnimationStepper with the underlying
+ * stepper merely observed.
+ */
+AnimationStepper *
+animation_stepper_wrapper_new (gpointer interface)
+{
+ return ANIMATION_STEPPER (g_object_new (ANIMATION_TYPE_STEPPER_WRAPPER, "stepper", interface, NULL));
+}
diff --git a/animation-glib/stepper/stepper-wrapper.h b/animation-glib/stepper/stepper-wrapper.h
new file mode 100644
index 0000000..bd59e53
--- /dev/null
+++ b/animation-glib/stepper/stepper-wrapper.h
@@ -0,0 +1,36 @@
+/*
+ * animation-glib/stepper/stepper-wrapper.h
+ *
+ * Copyright 2018 Endless Mobile, Inc.
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject base class for steppers, which holds a copy of a stepper.
+ */
+#pragma once
+
+#include
+
+#include
+#include
+
+G_BEGIN_DECLS
+
+#define ANIMATION_TYPE_STEPPER_WRAPPER animation_stepper_wrapper_get_type ()
+G_DECLARE_FINAL_TYPE (AnimationStepperWrapper, animation_stepper_wrapper, ANIMATION, STEPPER_WRAPPER, GObject)
+
+AnimationStepper * animation_stepper_wrapper_new (gpointer interface);
+
+G_END_DECLS
diff --git a/animation-glib/stepper/stepper.cpp b/animation-glib/stepper/stepper.cpp
new file mode 100644
index 0000000..714f4a2
--- /dev/null
+++ b/animation-glib/stepper/stepper.cpp
@@ -0,0 +1,49 @@
+/*
+ * animation-glib/stepper/stepper.cpp
+ *
+ * Copyright 2018 Endless Mobile, Inc.
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject base interface for steppers.
+ */
+
+#include
+#include
+
+namespace as = animation::stepper;
+
+
+G_DEFINE_INTERFACE (AnimationStepper,
+ animation_stepper,
+ G_TYPE_OBJECT)
+float
+animation_stepper_step (AnimationStepper *stepper,
+ unsigned int ms)
+{
+ g_return_val_if_fail (ANIMATION_IS_STEPPER (stepper), 0.0f);
+
+ return ANIMATION_STEPPER_GET_IFACE (stepper)->step (stepper, ms);
+}
+
+static void
+animation_stepper_default_init (AnimationStepperInterface *iface)
+{
+ g_object_interface_install_property ((gpointer) iface,
+ g_param_spec_pointer ("stepper",
+ "Internal Interface",
+ "Internal C++ interface that this class wraps",
+ static_cast (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
+}
diff --git a/animation-glib/stepper/stepper.h b/animation-glib/stepper/stepper.h
new file mode 100644
index 0000000..40e98f3
--- /dev/null
+++ b/animation-glib/stepper/stepper.h
@@ -0,0 +1,44 @@
+/*
+ * animation-glib/stepper/stepper.h
+ *
+ * Copyright 2018 Endless Mobile, Inc.
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject base interface for steppers.
+ */
+#pragma once
+
+#include
+
+#include
+
+G_BEGIN_DECLS
+
+#define ANIMATION_TYPE_STEPPER animation_stepper_get_type ()
+G_DECLARE_INTERFACE (AnimationStepper, animation_stepper, ANIMATION, STEPPER, GObject)
+
+struct _AnimationStepperInterface
+{
+ GTypeInterface parent_iface;
+
+ float (*step) (AnimationStepper *self,
+ unsigned int ms);
+};
+
+float animation_stepper_step (AnimationStepper *stepper,
+ unsigned int ms);
+
+G_END_DECLS
diff --git a/animation-glib/transform/meson.build b/animation-glib/transform/meson.build
new file mode 100644
index 0000000..6a64bff
--- /dev/null
+++ b/animation-glib/transform/meson.build
@@ -0,0 +1,34 @@
+# /animation/transform/meson.build
+#
+# Toplevel meson build file for libanimation.
+#
+# Copyright (C) 2017, 2018 Endless Mobile, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Build the libanimation library (transform animation base component
+
+transform_introspectable_sources = files([
+ 'transform.cpp'
+])
+
+transform_headers = files([
+ 'transform.h'
+])
+
+animation_glib_introspectable_sources += transform_introspectable_sources
+animation_glib_headers += transform_headers
+
+install_headers(transform_headers, subdir: join_paths(animation_glib_headers_subdir, 'transform'))
diff --git a/animation-glib/transform/transform.cpp b/animation-glib/transform/transform.cpp
new file mode 100644
index 0000000..190fc9d
--- /dev/null
+++ b/animation-glib/transform/transform.cpp
@@ -0,0 +1,202 @@
+/*
+ * animation-glib/transform/transform.cpp
+ *
+ * Copyright 2018 Endless Mobile, Inc.
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject base class for affine transform based animations.
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+
+namespace agd = animation::geometry::dimension;
+namespace at = animation::transform;
+
+typedef struct _AnimationTransformAnimationPrivate
+{
+ at::TransformAnimation *interface;
+} AnimationTransformAnimationPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (AnimationTransformAnimation,
+ animation_transform_animation,
+ G_TYPE_OBJECT)
+
+enum {
+ PROP_0,
+ PROP_INTERFACE,
+ NPROPS
+};
+
+static GParamSpec *animation_transform_animation_props [NPROPS] = { NULL, };
+
+gboolean
+animation_transform_animation_step (AnimationTransformAnimation *transform_animation,
+ unsigned int ms)
+{
+ AnimationTransformAnimationPrivate *priv =
+ reinterpret_cast (animation_transform_animation_get_instance_private (transform_animation));
+
+ return priv->interface->Step (ms);
+}
+
+/**
+ * animation_transform_animation_matrix:
+ * @transform_animation: A #AnimationTransformAnimation
+ *
+ * Get the 4x4 column-major transformation matrix for this
+ * representing the state of this animation.
+ *
+ * Returns: (array fixed-size=16): The 4x4 column-major ordered
+ * transformation matrix.
+ */
+float const *
+animation_transform_animation_matrix (AnimationTransformAnimation *transform_animation)
+{
+ AnimationTransformAnimationPrivate *priv =
+ reinterpret_cast (animation_transform_animation_get_instance_private (transform_animation));
+
+ return priv->interface->Matrix ();
+}
+
+/**
+ * animation_transform_animation_extremes:
+ * @transform_animation: A #AnimationTransformAnimation
+ * @corners: (array fixed-size=4): The four #AnimationVector4D values
+ * describing the location of the surface corners.
+ * @out_extremes: (array fixed-size=4) (out): The transformed four #AnimationVector
+ * values describing the location of the transformed surface
+ * surface corners.
+ *
+ * Get the four co-ordinates of a 3D plane which bound the animated surface.
+ */
+void
+animation_transform_animation_extremes (AnimationTransformAnimation *transform_animation,
+ AnimationVector const *corners,
+ AnimationVector4D *out_extremes)
+{
+ g_return_if_fail (corners != NULL);
+ g_return_if_fail (out_extremes != NULL);
+
+ AnimationTransformAnimationPrivate *priv =
+ reinterpret_cast (animation_transform_animation_get_instance_private (transform_animation));
+
+ std::array points = {
+ animation::Point (corners[0].x, corners[0].y),
+ animation::Point (corners[1].x, corners[1].y),
+ animation::Point (corners[2].x, corners[2].y),
+ animation::Point (corners[3].x, corners[3].y)
+ };
+
+ std::array extremes = priv->interface->Extremes (points);
+
+ agd::assign (out_extremes[0], extremes[0]);
+ agd::assign (out_extremes[1], extremes[1]);
+ agd::assign (out_extremes[2], extremes[2]);
+ agd::assign (out_extremes[3], extremes[3]);
+}
+
+float
+animation_transform_animation_progress (AnimationTransformAnimation *transform_animation)
+{
+ AnimationTransformAnimationPrivate *priv =
+ reinterpret_cast (animation_transform_animation_get_instance_private (transform_animation));
+
+ return priv->interface->Progress ();
+}
+
+static void
+animation_transform_animation_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ AnimationTransformAnimation *transform_animation = ANIMATION_TRANSFORM_ANIMATION (object);
+ AnimationTransformAnimationPrivate *priv =
+ reinterpret_cast (animation_transform_animation_get_instance_private (transform_animation));
+
+ switch (prop_id)
+ {
+ case PROP_INTERFACE:
+ priv->interface = reinterpret_cast (g_value_get_pointer (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+animation_transform_animation_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ AnimationTransformAnimation *transform_animation = ANIMATION_TRANSFORM_ANIMATION (object);
+ AnimationTransformAnimationPrivate *priv =
+ reinterpret_cast (animation_transform_animation_get_instance_private (transform_animation));
+
+ switch (prop_id)
+ {
+ case PROP_INTERFACE:
+ g_value_set_pointer (value, reinterpret_cast (priv->interface));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+animation_transform_animation_finalize (GObject *object)
+{
+ AnimationTransformAnimation *transform_animation = ANIMATION_TRANSFORM_ANIMATION (object);
+ AnimationTransformAnimationPrivate *priv =
+ reinterpret_cast (animation_transform_animation_get_instance_private (transform_animation));
+
+ delete priv->interface;
+ priv->interface = nullptr;
+
+ G_OBJECT_CLASS (animation_transform_animation_parent_class)->finalize (object);
+}
+
+static void
+animation_transform_animation_init (AnimationTransformAnimation *model)
+{
+}
+
+
+static void
+animation_transform_animation_class_init (AnimationTransformAnimationClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = animation_transform_animation_get_property;
+ object_class->set_property = animation_transform_animation_set_property;
+ object_class->finalize = animation_transform_animation_finalize;
+
+ animation_transform_animation_props[PROP_INTERFACE] =
+ g_param_spec_pointer ("interface",
+ "Internal Interface",
+ "Internal C++ interface that this class wraps",
+ static_cast (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_properties (object_class,
+ NPROPS,
+ animation_transform_animation_props);
+}
diff --git a/animation-glib/transform/transform.h b/animation-glib/transform/transform.h
new file mode 100644
index 0000000..58a3be8
--- /dev/null
+++ b/animation-glib/transform/transform.h
@@ -0,0 +1,49 @@
+/*
+ * animation-glib/transform/transform.h
+ *
+ * Copyright 2018 Endless Mobile, Inc.
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject Interface for affine transform animations.
+ */
+#pragma once
+
+#include
+
+#include
+#include
+
+G_BEGIN_DECLS
+
+#define ANIMATION_TYPE_TRANSFORM_ANIMATION animation_transform_animation_get_type ()
+G_DECLARE_DERIVABLE_TYPE (AnimationTransformAnimation, animation_transform_animation, ANIMATION, TRANSFORM_ANIMATION, GObject)
+
+struct _AnimationTransformAnimationClass {
+ GObjectClass parent_class;
+};
+
+gboolean animation_transform_animation_step (AnimationTransformAnimation *transform_animation,
+ unsigned int ms);
+
+float animation_transform_animation_progress (AnimationTransformAnimation *transform_animation);
+
+float const * animation_transform_animation_matrix (AnimationTransformAnimation *transform_animation);
+
+void animation_transform_animation_extremes (AnimationTransformAnimation *transform_animation,
+ AnimationVector const *corners,
+ AnimationVector4D *out_extremes);
+
+G_END_DECLS
diff --git a/animation-glib/vector4d-internal.h b/animation-glib/vector4d-internal.h
new file mode 100644
index 0000000..ca5e305
--- /dev/null
+++ b/animation-glib/vector4d-internal.h
@@ -0,0 +1,99 @@
+/*
+ * animation-glib/vector4d-internal.h
+ *
+ * Copyright 2018 Endless Mobile, Inc.
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject boxed type 4D vector implementation.
+ */
+
+#include
+
+namespace animation
+{
+ namespace geometry
+ {
+ namespace dimension
+ {
+ template <>
+ struct Dimension
+ {
+ typedef double data_type;
+ static const size_t dimensions = 4;
+ };
+
+ template <>
+ struct DimensionAccess
+ {
+ static inline double get (AnimationVector4D const &p)
+ {
+ return p.x;
+ }
+
+ static inline void
+ set (AnimationVector4D &p, double const &value)
+ {
+ p.x = value;
+ }
+ };
+
+ template <>
+ struct DimensionAccess
+ {
+ static inline double get (AnimationVector4D const &p)
+ {
+ return p.y;
+ }
+
+ static inline void
+ set (AnimationVector4D &p, double const &value)
+ {
+ p.y = value;
+ }
+ };
+
+ template <>
+ struct DimensionAccess
+ {
+ static inline double get (AnimationVector4D const &p)
+ {
+ return p.z;
+ }
+
+ static inline void
+ set (AnimationVector4D &p, double const &value)
+ {
+ p.z = value;
+ }
+ };
+
+ template <>
+ struct DimensionAccess
+ {
+ static inline double get (AnimationVector4D const &p)
+ {
+ return p.w;
+ }
+
+ static inline void
+ set (AnimationVector4D &p, double const &value)
+ {
+ p.w = value;
+ }
+ };
+ }
+ }
+}
diff --git a/animation-glib/vector4d.cpp b/animation-glib/vector4d.cpp
new file mode 100644
index 0000000..a705a29
--- /dev/null
+++ b/animation-glib/vector4d.cpp
@@ -0,0 +1,39 @@
+/*
+ * animation-glib/vector4d.cpp
+ *
+ * Copyright 2018 Endless Mobile, Inc.
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject boxed type 4D vector implementation.
+ */
+
+#include
+
+static gpointer
+animation_vector4d_copy (gpointer ptr)
+{
+ AnimationVector4D *src = reinterpret_cast (ptr);
+ AnimationVector4D *dst = g_new0 (AnimationVector4D, 1);
+
+ *dst = *src;
+
+ return reinterpret_cast (dst);
+}
+
+G_DEFINE_BOXED_TYPE (AnimationVector4D,
+ animation_vector4d,
+ animation_vector4d_copy,
+ g_free);
diff --git a/animation-glib/vector4d.h b/animation-glib/vector4d.h
new file mode 100644
index 0000000..ff2b2b5
--- /dev/null
+++ b/animation-glib/vector4d.h
@@ -0,0 +1,39 @@
+/*
+ * animation-glib/vector4d.h
+ *
+ * Copyright 2018 Endless Mobile, Inc.
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject boxed type 4D vector implementation.
+ */
+#pragma once
+
+#include
+
+G_BEGIN_DECLS
+
+typedef struct {
+ double x;
+ double y;
+ double z;
+ double w;
+} AnimationVector4D;
+
+#define ANIMATION_TYPE_VECTOR4D animation_vector4d_get_type ()
+
+GType animation_vector4d_get_type (void);
+
+G_END_DECLS
diff --git a/animation-glib/zoom/meson.build b/animation-glib/zoom/meson.build
new file mode 100644
index 0000000..c206a40
--- /dev/null
+++ b/animation-glib/zoom/meson.build
@@ -0,0 +1,18 @@
+# /animation/zoom/meson.build
+#
+# Build the libanimation library (zoom animation component).
+#
+# See /LICENCE.md for Copyright information.
+
+zoom_introspectable_sources = files([
+ 'zoom.cpp'
+])
+
+zoom_headers = files([
+ 'zoom.h'
+])
+
+animation_glib_introspectable_sources += zoom_introspectable_sources
+animation_glib_headers += zoom_headers
+
+install_headers(zoom_headers, subdir: join_paths(animation_glib_headers_subdir, 'zoom'))
diff --git a/animation-glib/zoom/zoom.cpp b/animation-glib/zoom/zoom.cpp
new file mode 100644
index 0000000..d986c5f
--- /dev/null
+++ b/animation-glib/zoom/zoom.cpp
@@ -0,0 +1,295 @@
+/*
+ * animation-glib/zoom/zoom.cpp
+ *
+ * libanimation 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.
+ *
+ * libanimation 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 eos-companion-app-service. If not, see
+ * .
+ *
+ * GObject interface for a zoom animation.
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace agd = animation::geometry::dimension;
+namespace at = animation::transform;
+namespace az = animation::zoom;
+
+struct _AnimationZoomAnimation
+{
+ AnimationTransformAnimation parent_instance;
+};
+
+typedef struct _AnimationZoomAnimationPrivate
+{
+} AnimationZoomAnimationPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (AnimationZoomAnimation,
+ animation_zoom_animation,
+ ANIMATION_TYPE_TRANSFORM_ANIMATION)
+
+enum {
+ PROP_0,
+ PROP_FROM,
+ PROP_TO,
+ PROP_STEPPER,
+ NPROPS
+};
+
+static GParamSpec *animation_zoom_animation_props [NPROPS] = { NULL, };
+
+void
+animation_zoom_animation_set_from (AnimationZoomAnimation *animation,
+ AnimationBox box)
+{
+ LookupTypedInterfaceProp