[gnome-todo/gbsneto/animations: 3/7] widget: Add affine transformation proprties
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-todo/gbsneto/animations: 3/7] widget: Add affine transformation proprties
- Date: Wed, 12 Aug 2020 00:17:53 +0000 (UTC)
commit f1f82ac254b3ea2835987b78a92eb09d555e0dee
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Thu Aug 6 20:30:40 2020 -0300
widget: Add affine transformation proprties
This is the first step to achieve the same kind of features
that ClutterActor has.
src/gui/gtd-widget-private.h | 29 ++
src/gui/gtd-widget.c | 630 ++++++++++++++++++++++++++++++++++++++++++-
src/gui/gtd-widget.h | 39 +++
3 files changed, 696 insertions(+), 2 deletions(-)
---
diff --git a/src/gui/gtd-widget-private.h b/src/gui/gtd-widget-private.h
new file mode 100644
index 0000000..e8181ee
--- /dev/null
+++ b/src/gui/gtd-widget-private.h
@@ -0,0 +1,29 @@
+/* gtd-widget-private.h
+ *
+ * Copyright 2020 Georges Basile Stavracas Neto <georges stavracas gmail com>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "gtd-widget.h"
+
+G_BEGIN_DECLS
+
+void gtd_widget_update_pivot_for_geometry (GtdWidget *self,
+ const GtkAllocation *geometry);
+G_END_DECLS
diff --git a/src/gui/gtd-widget.c b/src/gui/gtd-widget.c
index 47625b7..fe227ba 100644
--- a/src/gui/gtd-widget.c
+++ b/src/gui/gtd-widget.c
@@ -18,13 +18,126 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
-#include "gtd-widget.h"
+#include "gtd-debug.h"
+#include "gtd-widget-private.h"
-G_DEFINE_TYPE (GtdWidget, gtd_widget, GTK_TYPE_WIDGET)
+#include <graphene-gobject.h>
+
+enum
+{
+ X,
+ Y,
+ Z,
+};
+
+typedef struct
+{
+ graphene_point3d_t pivot_point;
+ gfloat rotation[3];
+ gfloat scale[3];
+ graphene_point3d_t translation;
+
+ GtkAllocation geometry;
+ GskTransform *cached_transform;
+} GtdWidgetPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (GtdWidget, gtd_widget, GTK_TYPE_WIDGET)
+
+enum
+{
+ PROP_0,
+ PROP_PIVOT_POINT,
+ PROP_ROTATION_X,
+ PROP_ROTATION_Y,
+ PROP_ROTATION_Z,
+ PROP_SCALE_X,
+ PROP_SCALE_Y,
+ PROP_SCALE_Z,
+ PROP_TRANSLATION_X,
+ PROP_TRANSLATION_Y,
+ PROP_TRANSLATION_Z,
+ N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS] = { NULL, };
+
+
+/*
+ * Auxiliary methods
+ */
+
+static void
+invalidate_cached_transform (GtdWidget *self)
+{
+ GtdWidgetPrivate *priv = gtd_widget_get_instance_private (self);
+
+ g_clear_pointer (&priv->cached_transform, gsk_transform_unref);
+}
+
+static void
+calculate_transform (GtdWidget *self)
+{
+ GtdWidgetPrivate *priv = gtd_widget_get_instance_private (self);
+ graphene_point3d_t pivot;
+ GskTransform *transform;
+ gboolean pivot_is_zero;
+
+ transform = NULL;
+
+ /* Pivot point */
+ pivot_is_zero = graphene_point3d_equal (&priv->pivot_point, graphene_point3d_zero ());
+ pivot = GRAPHENE_POINT3D_INIT (priv->geometry.x + priv->geometry.width * priv->pivot_point.x,
+ priv->geometry.y + priv->geometry.height * priv->pivot_point.y,
+ priv->pivot_point.z);
+ if (!pivot_is_zero)
+ transform = gsk_transform_translate_3d (transform, &pivot);
+
+ /* Perspective */
+ transform = gsk_transform_perspective (transform,
+ 2 * MAX (priv->geometry.width, priv->geometry.height));
+
+ /* Rotation */
+ transform = gsk_transform_rotate_3d (transform, priv->rotation[X], graphene_vec3_x_axis ());
+ transform = gsk_transform_rotate_3d (transform, priv->rotation[Y], graphene_vec3_y_axis ());
+ transform = gsk_transform_rotate_3d (transform, priv->rotation[Z], graphene_vec3_z_axis ());
+
+ /* Scale */
+ if (G_APPROX_VALUE (priv->scale[Z], 1.f, FLT_EPSILON))
+ transform = gsk_transform_scale (transform, priv->scale[X], priv->scale[Y]);
+ else
+ transform = gsk_transform_scale_3d (transform, priv->scale[X], priv->scale[Y], priv->scale[Z]);
+
+ /* Translation */
+ if (G_APPROX_VALUE (priv->translation.z, 0.f, FLT_EPSILON))
+ {
+ transform = gsk_transform_translate (transform,
+ &GRAPHENE_POINT_INIT (priv->translation.x,
+ priv->translation.y));
+ }
+ else
+ {
+ transform = gsk_transform_translate_3d (transform, &priv->translation);
+ }
+
+ /* Rollback pivot point */
+ if (!pivot_is_zero)
+ transform = gsk_transform_translate_3d (transform,
+ &GRAPHENE_POINT3D_INIT (-pivot.x,
+ -pivot.y,
+ -pivot.z));
+
+ priv->cached_transform = transform;
+}
+
+
+/*
+ * GObject overrides
+ */
static void
gtd_widget_dispose (GObject *object)
{
+ GtdWidget *self = GTD_WIDGET (object);
GtkWidget *child = gtk_widget_get_first_child (GTK_WIDGET (object));
while (child)
@@ -35,9 +148,123 @@ gtd_widget_dispose (GObject *object)
child = next;
}
+ invalidate_cached_transform (self);
+
G_OBJECT_CLASS (gtd_widget_parent_class)->dispose (object);
}
+static void
+gtd_widget_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtdWidget *self = GTD_WIDGET (object);
+ GtdWidgetPrivate *priv = gtd_widget_get_instance_private (self);
+
+ switch (prop_id)
+ {
+ case PROP_PIVOT_POINT:
+ g_value_set_boxed (value, &priv->pivot_point);
+ break;
+
+ case PROP_ROTATION_X:
+ g_value_set_float (value, priv->rotation[X]);
+ break;
+
+ case PROP_ROTATION_Y:
+ g_value_set_float (value, priv->rotation[Y]);
+ break;
+
+ case PROP_ROTATION_Z:
+ g_value_set_float (value, priv->rotation[Z]);
+ break;
+
+ case PROP_SCALE_X:
+ g_value_set_float (value, priv->scale[X]);
+ break;
+
+ case PROP_SCALE_Y:
+ g_value_set_float (value, priv->scale[Y]);
+ break;
+
+ case PROP_SCALE_Z:
+ g_value_set_float (value, priv->scale[Z]);
+ break;
+
+ case PROP_TRANSLATION_X:
+ g_value_set_float (value, priv->translation.x);
+ break;
+
+ case PROP_TRANSLATION_Y:
+ g_value_set_float (value, priv->translation.y);
+ break;
+
+ case PROP_TRANSLATION_Z:
+ g_value_set_float (value, priv->translation.z);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gtd_widget_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtdWidget *self = GTD_WIDGET (object);
+ GtdWidgetPrivate *priv = gtd_widget_get_instance_private (self);
+
+ switch (prop_id)
+ {
+ case PROP_PIVOT_POINT:
+ gtd_widget_set_pivot_point (self, g_value_get_boxed (value));
+ break;
+
+ case PROP_ROTATION_X:
+ gtd_widget_set_rotation (self, g_value_get_float (value), priv->rotation[Y], priv->rotation[Z]);
+ break;
+
+ case PROP_ROTATION_Y:
+ gtd_widget_set_rotation (self, priv->rotation[X], g_value_get_float (value), priv->rotation[Z]);
+ break;
+
+ case PROP_ROTATION_Z:
+ gtd_widget_set_rotation (self, priv->rotation[X], priv->rotation[Y], g_value_get_float (value));
+ break;
+
+ case PROP_SCALE_X:
+ gtd_widget_set_scale (self, g_value_get_float (value), priv->scale[Y], priv->scale[Z]);
+ break;
+
+ case PROP_SCALE_Y:
+ gtd_widget_set_scale (self, priv->scale[X], g_value_get_float (value), priv->scale[Z]);
+ break;
+
+ case PROP_SCALE_Z:
+ gtd_widget_set_scale (self, priv->scale[X], priv->scale[Y], g_value_get_float (value));
+ break;
+
+ case PROP_TRANSLATION_X:
+ gtd_widget_set_translation (self, g_value_get_float (value), priv->translation.y, priv->translation.z);
+ break;
+
+ case PROP_TRANSLATION_Y:
+ gtd_widget_set_translation (self, priv->translation.x, g_value_get_float (value), priv->translation.z);
+ break;
+
+ case PROP_TRANSLATION_Z:
+ gtd_widget_set_translation (self, priv->translation.x, priv->translation.y, g_value_get_float (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
static void
gtd_widget_class_init (GtdWidgetClass *klass)
{
@@ -45,6 +272,118 @@ gtd_widget_class_init (GtdWidgetClass *klass)
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = gtd_widget_dispose;
+ object_class->get_property = gtd_widget_get_property;
+ object_class->set_property = gtd_widget_set_property;
+
+ /**
+ * GtdWidget:
+ */
+ properties[PROP_PIVOT_POINT] = g_param_spec_boxed ("pivot-point",
+ "Pivot point",
+ "Pivot point",
+ GRAPHENE_TYPE_POINT3D,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * GtdWidget:rotation-x
+ */
+ properties[PROP_ROTATION_X] = g_param_spec_float ("rotation-x",
+ "Rotation in the X axis",
+ "Rotation in the X axis",
+ -G_MAXFLOAT,
+ G_MAXFLOAT,
+ 0.f,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * GtdWidget:rotation-y
+ */
+ properties[PROP_ROTATION_Y] = g_param_spec_float ("rotation-y",
+ "Rotation in the Y axis",
+ "Rotation in the Y axis",
+ -G_MAXFLOAT,
+ G_MAXFLOAT,
+ 0.f,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * GtdWidget:rotation-z
+ */
+ properties[PROP_ROTATION_Z] = g_param_spec_float ("rotation-z",
+ "Rotation in the Z axis",
+ "Rotation in the Z axis",
+ -G_MAXFLOAT,
+ G_MAXFLOAT,
+ 0.f,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * GtdWidget:scale-x
+ */
+ properties[PROP_SCALE_X] = g_param_spec_float ("scale-x",
+ "Scale in the X axis",
+ "Scale in the X axis",
+ -G_MAXFLOAT,
+ G_MAXFLOAT,
+ 1.f,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * GtdWidget:scale-y
+ */
+ properties[PROP_SCALE_Y] = g_param_spec_float ("scale-y",
+ "Scale in the Y axis",
+ "Scale in the Y axis",
+ -G_MAXFLOAT,
+ G_MAXFLOAT,
+ 1.f,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * GtdWidget:scale-z
+ */
+ properties[PROP_SCALE_Z] = g_param_spec_float ("scale-z",
+ "Scale in the Z axis",
+ "Scale in the Z axis",
+ -G_MAXFLOAT,
+ G_MAXFLOAT,
+ 1.f,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * GtdWidget:translation-x
+ */
+ properties[PROP_TRANSLATION_X] = g_param_spec_float ("translation-x",
+ "Translation in the X axis",
+ "Translation in the X axis",
+ -G_MAXFLOAT,
+ G_MAXFLOAT,
+ 0.f,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * GtdWidget:translation-y
+ */
+ properties[PROP_TRANSLATION_Y] = g_param_spec_float ("translation-y",
+ "Translation in the Y axis",
+ "Translation in the Y axis",
+ -G_MAXFLOAT,
+ G_MAXFLOAT,
+ 0.f,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * GtdWidget:translation-z
+ */
+ properties[PROP_TRANSLATION_Z] = g_param_spec_float ("translation-z",
+ "Translation in the Z axis",
+ "Translation in the Z axis",
+ -G_MAXFLOAT,
+ G_MAXFLOAT,
+ 0.f,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
}
@@ -52,6 +391,13 @@ gtd_widget_class_init (GtdWidgetClass *klass)
static void
gtd_widget_init (GtdWidget *self)
{
+ GtdWidgetPrivate *priv = gtd_widget_get_instance_private (self);
+
+ priv->scale[X] = 1.f;
+ priv->scale[Y] = 1.f;
+ priv->scale[Z] = 1.f;
+
+ priv->pivot_point = GRAPHENE_POINT3D_INIT (0.5, 0.5, 0.f);
}
GtkWidget*
@@ -59,3 +405,283 @@ gtd_widget_new (void)
{
return g_object_new (GTD_TYPE_WIDGET, NULL);
}
+
+/**
+ */
+void
+gtd_widget_get_pivot_point (GtdWidget *self,
+ graphene_point3d_t *out_pivot_point)
+{
+ GtdWidgetPrivate *priv;
+
+ g_return_if_fail (GTD_IS_WIDGET (self));
+ g_return_if_fail (out_pivot_point != NULL);
+
+ priv = gtd_widget_get_instance_private (self);
+ *out_pivot_point = priv->pivot_point;
+}
+
+/**
+ */
+void
+gtd_widget_set_pivot_point (GtdWidget *self,
+ const graphene_point3d_t *pivot_point)
+{
+ GtdWidgetPrivate *priv;
+
+ GTD_ENTRY;
+
+ g_return_if_fail (GTD_IS_WIDGET (self));
+ g_return_if_fail (pivot_point != NULL);
+ g_return_if_fail (pivot_point->x >= 0.f && pivot_point->x <= 1.0);
+ g_return_if_fail (pivot_point->y >= 0.f && pivot_point->y <= 1.0);
+
+ priv = gtd_widget_get_instance_private (self);
+
+ if (graphene_point3d_equal (&priv->pivot_point, pivot_point))
+ GTD_RETURN ();
+
+ invalidate_cached_transform (self);
+ priv->pivot_point = *pivot_point;
+
+ gtk_widget_queue_resize (GTK_WIDGET (self));
+
+ GTD_EXIT;
+}
+
+/**
+ */
+void
+gtd_widget_get_rotation (GtdWidget *self,
+ gfloat *rotation_x,
+ gfloat *rotation_y,
+ gfloat *rotation_z)
+{
+ GtdWidgetPrivate *priv;
+
+ g_return_if_fail (GTD_IS_WIDGET (self));
+
+ priv = gtd_widget_get_instance_private (self);
+
+ if (rotation_x)
+ *rotation_x = priv->rotation[X];
+
+ if (rotation_y)
+ *rotation_y = priv->rotation[Y];
+
+ if (rotation_z)
+ *rotation_z = priv->rotation[Z];
+}
+
+/**
+ */
+void
+gtd_widget_set_rotation (GtdWidget *self,
+ gfloat rotation_x,
+ gfloat rotation_y,
+ gfloat rotation_z)
+{
+ GtdWidgetPrivate *priv;
+ gboolean changed[3];
+
+ GTD_ENTRY;
+
+ g_return_if_fail (GTD_IS_WIDGET (self));
+
+ priv = gtd_widget_get_instance_private (self);
+
+ changed[X] = !G_APPROX_VALUE (priv->rotation[X], rotation_x, FLT_EPSILON);
+ changed[Y] = !G_APPROX_VALUE (priv->rotation[Y], rotation_y, FLT_EPSILON);
+ changed[Z] = !G_APPROX_VALUE (priv->rotation[Z], rotation_z, FLT_EPSILON);
+
+ if (!changed[X] && !changed[Y] && !changed[Z])
+ GTD_RETURN ();
+
+ invalidate_cached_transform (self);
+
+ priv->rotation[X] = rotation_x;
+ priv->rotation[Y] = rotation_y;
+ priv->rotation[Z] = rotation_z;
+
+ if (changed[X])
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ROTATION_X]);
+
+ if (changed[Y])
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ROTATION_Y]);
+
+ if (changed[Z])
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ROTATION_Z]);
+
+ gtk_widget_queue_resize (GTK_WIDGET (self));
+
+ GTD_EXIT;
+}
+
+/**
+ */
+void
+gtd_widget_get_scale (GtdWidget *self,
+ gfloat *scale_x,
+ gfloat *scale_y,
+ gfloat *scale_z)
+{
+ GtdWidgetPrivate *priv;
+
+ g_return_if_fail (GTD_IS_WIDGET (self));
+
+ priv = gtd_widget_get_instance_private (self);
+
+ if (scale_x)
+ *scale_x = priv->scale[0];
+
+ if (scale_y)
+ *scale_y = priv->scale[1];
+
+ if (scale_z)
+ *scale_z = priv->scale[2];
+}
+
+/**
+ */
+void
+gtd_widget_set_scale (GtdWidget *self,
+ gfloat scale_x,
+ gfloat scale_y,
+ gfloat scale_z)
+{
+ GtdWidgetPrivate *priv;
+ gboolean changed[3];
+
+ GTD_ENTRY;
+
+ g_return_if_fail (GTD_IS_WIDGET (self));
+
+ priv = gtd_widget_get_instance_private (self);
+
+ changed[X] = !G_APPROX_VALUE (priv->scale[X], scale_x, FLT_EPSILON);
+ changed[Y] = !G_APPROX_VALUE (priv->scale[Y], scale_y, FLT_EPSILON);
+ changed[Z] = !G_APPROX_VALUE (priv->scale[Z], scale_z, FLT_EPSILON);
+
+ if (!changed[X] && !changed[Y] && !changed[Z])
+ GTD_RETURN ();
+
+ invalidate_cached_transform (self);
+
+ priv->scale[X] = scale_x;
+ priv->scale[Y] = scale_y;
+ priv->scale[Z] = scale_z;
+
+ if (changed[X])
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SCALE_X]);
+
+ if (changed[Y])
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SCALE_Y]);
+
+ if (changed[Z])
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SCALE_Z]);
+
+ gtk_widget_queue_resize (GTK_WIDGET (self));
+
+ GTD_EXIT;
+}
+
+/**
+ */
+void
+gtd_widget_get_translation (GtdWidget *self,
+ gfloat *translation_x,
+ gfloat *translation_y,
+ gfloat *translation_z)
+{
+ GtdWidgetPrivate *priv;
+
+ g_return_if_fail (GTD_IS_WIDGET (self));
+
+ priv = gtd_widget_get_instance_private (self);
+
+ if (translation_x)
+ *translation_x = priv->translation.x;
+
+ if (translation_y)
+ *translation_y = priv->translation.y;
+
+ if (translation_z)
+ *translation_z = priv->translation.z;
+}
+
+/**
+ */
+void
+gtd_widget_set_translation (GtdWidget *self,
+ gfloat translation_x,
+ gfloat translation_y,
+ gfloat translation_z)
+{
+ graphene_point3d_t old_translation, translation;
+ GtdWidgetPrivate *priv;
+
+ GTD_ENTRY;
+
+ g_return_if_fail (GTD_IS_WIDGET (self));
+
+ priv = gtd_widget_get_instance_private (self);
+ translation = GRAPHENE_POINT3D_INIT (translation_x, translation_y, translation_z);
+
+ if (graphene_point3d_equal (&priv->translation, &translation))
+ GTD_RETURN ();
+
+ old_translation = priv->translation;
+
+ invalidate_cached_transform (self);
+ priv->translation = translation;
+
+ if (!G_APPROX_VALUE (old_translation.x, translation.x, FLT_EPSILON))
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TRANSLATION_X]);
+
+ if (!G_APPROX_VALUE (old_translation.y, translation.y, FLT_EPSILON))
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TRANSLATION_Y]);
+
+ if (!G_APPROX_VALUE (old_translation.y, translation.y, FLT_EPSILON))
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TRANSLATION_Z]);
+
+ gtk_widget_queue_resize (GTK_WIDGET (self));
+
+ GTD_EXIT;
+}
+
+/**
+ */
+GskTransform*
+gtd_widget_apply_transform (GtdWidget *self,
+ GskTransform *transform)
+{
+ GtdWidgetPrivate *priv;
+
+ g_return_val_if_fail (GTD_IS_WIDGET (self), NULL);
+
+ priv = gtd_widget_get_instance_private (self);
+
+ if (!priv->cached_transform)
+ calculate_transform (self);
+
+ if (!transform)
+ return gsk_transform_ref (priv->cached_transform);
+
+ return gsk_transform_transform (transform, priv->cached_transform);
+}
+
+void
+gtd_widget_update_pivot_for_geometry (GtdWidget *self,
+ const GtkAllocation *geometry)
+{
+ GtdWidgetPrivate *priv = gtd_widget_get_instance_private (self);
+
+ if (priv->geometry.x != geometry->x ||
+ priv->geometry.y != geometry->y ||
+ priv->geometry.width != geometry->width ||
+ priv->geometry.height != geometry->height)
+ {
+ invalidate_cached_transform (self);
+ priv->geometry = *geometry;
+ }
+}
diff --git a/src/gui/gtd-widget.h b/src/gui/gtd-widget.h
index dff5e54..63d721e 100644
--- a/src/gui/gtd-widget.h
+++ b/src/gui/gtd-widget.h
@@ -34,4 +34,43 @@ struct _GtdWidgetClass
GtkWidget* gtd_widget_new (void);
+void gtd_widget_get_pivot_point (GtdWidget *self,
+ graphene_point3d_t *out_pivot_point);
+
+void gtd_widget_set_pivot_point (GtdWidget *self,
+ const graphene_point3d_t *pivot_point);
+
+void gtd_widget_get_rotation (GtdWidget *self,
+ gfloat *rotation_x,
+ gfloat *rotation_y,
+ gfloat *rotation_z);
+
+void gtd_widget_set_rotation (GtdWidget *self,
+ gfloat rotation_x,
+ gfloat rotation_y,
+ gfloat rotation_z);
+
+void gtd_widget_get_scale (GtdWidget *self,
+ gfloat *scale_x,
+ gfloat *scale_y,
+ gfloat *scale_z);
+
+void gtd_widget_set_scale (GtdWidget *self,
+ gfloat scale_x,
+ gfloat scale_y,
+ gfloat scale_z);
+
+void gtd_widget_get_translation (GtdWidget *self,
+ gfloat *translation_x,
+ gfloat *translation_y,
+ gfloat *translation_z);
+
+void gtd_widget_set_translation (GtdWidget *self,
+ gfloat translation_x,
+ gfloat translation_y,
+ gfloat translation_z);
+
+GskTransform* gtd_widget_apply_transform (GtdWidget *self,
+ GskTransform *transform);
+
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]